openvidu-livekit-tutorials/openvidu-js/web/openvidu-browser-2.23.0.js
2022-09-22 14:13:45 +02:00

13972 lines
1.8 MiB

(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){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
var R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
? R.apply
: function ReflectApply(target, receiver, args) {
return Function.prototype.apply.call(target, receiver, args);
}
var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target)
.concat(Object.getOwnPropertySymbols(target));
};
} else {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target);
};
}
function ProcessEmitWarning(warning) {
if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
return value !== value;
}
function EventEmitter() {
EventEmitter.init.call(this);
}
module.exports = EventEmitter;
module.exports.once = once;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
if (typeof listener !== 'function') {
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
}
defaultMaxListeners = arg;
}
});
EventEmitter.init = function() {
if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
}
this._maxListeners = n;
return this;
};
function _getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
var args = [];
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
var doError = (type === 'error');
var events = this._events;
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
var er;
if (args.length > 0)
er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
err.context = er;
throw err; // Unhandled 'error' event
}
var handler = events[type];
if (handler === undefined)
return false;
if (typeof handler === 'function') {
ReflectApply(handler, this, args);
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
checkListener(listener);
events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (existing === undefined) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
// If we've already got an array, just append.
} else if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
// Check for listener leak
m = _getMaxListeners(target);
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
// No error code for this since it is a Warning
// eslint-disable-next-line no-restricted-syntax
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' ' + String(type) + ' listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
ProcessEmitWarning(w);
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
if (arguments.length === 0)
return this.listener.call(this.target);
return this.listener.apply(this.target, arguments);
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = onceWrapper.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
checkListener(listener);
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
checkListener(listener);
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
checkListener(listener);
events = this._events;
if (events === undefined)
return this;
list = events[type];
if (list === undefined)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else {
spliceOne(list, position);
}
if (list.length === 1)
events[type] = list[0];
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (events === undefined)
return this;
// not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = Object.keys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (events === undefined)
return [];
var evlistener = events[type];
if (evlistener === undefined)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ?
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events !== undefined) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function once(emitter, name) {
return new Promise(function (resolve, reject) {
function errorListener(err) {
emitter.removeListener(name, resolver);
reject(err);
}
function resolver() {
if (typeof emitter.removeListener === 'function') {
emitter.removeListener('error', errorListener);
}
resolve([].slice.call(arguments));
};
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
if (name !== 'error') {
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
}
});
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
if (typeof emitter.on === 'function') {
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === 'function') {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen for `error` events here.
emitter.addEventListener(name, function wrapListener(arg) {
// IE does not have builtin `{ once: true }` support so we
// have to do it manually.
if (flags.once) {
emitter.removeEventListener(name, wrapListener);
}
listener(arg);
});
} else {
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}
}
},{}],2:[function(require,module,exports){
/* jshint node: true */
'use strict';
var normalice = require('normalice');
/**
# freeice
The `freeice` module is a simple way of getting random STUN or TURN server
for your WebRTC application. The list of servers (just STUN at this stage)
were sourced from this [gist](https://gist.github.com/zziuni/3741933).
## Example Use
The following demonstrates how you can use `freeice` with
[rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect):
<<< examples/quickconnect.js
As the `freeice` module generates ice servers in a list compliant with the
WebRTC spec you will be able to use it with raw `RTCPeerConnection`
constructors and other WebRTC libraries.
## Hey, don't use my STUN/TURN server!
If for some reason your free STUN or TURN server ends up in the
list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or
[turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json))
that is used in this module, you can feel
free to open an issue on this repository and those servers will be removed
within 24 hours (or sooner). This is the quickest and probably the most
polite way to have something removed (and provides us some visibility
if someone opens a pull request requesting that a server is added).
## Please add my server!
If you have a server that you wish to add to the list, that's awesome! I'm
sure I speak on behalf of a whole pile of WebRTC developers who say thanks.
To get it into the list, feel free to either open a pull request or if you
find that process a bit daunting then just create an issue requesting
the addition of the server (make sure you provide all the details, and if
you have a Terms of Service then including that in the PR/issue would be
awesome).
## I know of a free server, can I add it?
Sure, if you do your homework and make sure it is ok to use (I'm currently
in the process of reviewing the terms of those STUN servers included from
the original list). If it's ok to go, then please see the previous entry
for how to add it.
## Current List of Servers
* current as at the time of last `README.md` file generation
### STUN
<<< stun.json
### TURN
<<< turn.json
**/
var freeice = function(opts) {
// if a list of servers has been provided, then use it instead of defaults
var servers = {
stun: (opts || {}).stun || require('./stun.json'),
turn: (opts || {}).turn || require('./turn.json')
};
var stunCount = (opts || {}).stunCount || 2;
var turnCount = (opts || {}).turnCount || 0;
var selected;
function getServers(type, count) {
var out = [];
var input = [].concat(servers[type]);
var idx;
while (input.length && out.length < count) {
idx = (Math.random() * input.length) | 0;
out = out.concat(input.splice(idx, 1));
}
return out.map(function(url) {
//If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up
if ((typeof url !== 'string') && (! (url instanceof String))) {
return url;
} else {
return normalice(type + ':' + url);
}
});
}
// add stun servers
selected = [].concat(getServers('stun', stunCount));
if (turnCount) {
selected = selected.concat(getServers('turn', turnCount));
}
return selected;
};
module.exports = freeice;
},{"./stun.json":3,"./turn.json":4,"normalice":11}],3:[function(require,module,exports){
module.exports=[
"stun.l.google.com:19302",
"stun1.l.google.com:19302",
"stun2.l.google.com:19302",
"stun3.l.google.com:19302",
"stun4.l.google.com:19302",
"stun.ekiga.net",
"stun.ideasip.com",
"stun.schlund.de",
"stun.stunprotocol.org:3478",
"stun.voiparound.com",
"stun.voipbuster.com",
"stun.voipstunt.com",
"stun.voxgratia.org"
]
},{}],4:[function(require,module,exports){
module.exports=[]
},{}],5:[function(require,module,exports){
var WildEmitter = require('wildemitter');
function getMaxVolume (analyser, fftBins) {
var maxVolume = -Infinity;
analyser.getFloatFrequencyData(fftBins);
for(var i=4, ii=fftBins.length; i < ii; i++) {
if (fftBins[i] > maxVolume && fftBins[i] < 0) {
maxVolume = fftBins[i];
}
};
return maxVolume;
}
var audioContextType;
if (typeof window !== 'undefined') {
audioContextType = window.AudioContext || window.webkitAudioContext;
}
// use a single audio context due to hardware limits
var audioContext = null;
module.exports = function(stream, options) {
var harker = new WildEmitter();
// make it not break in non-supported browsers
if (!audioContextType) return harker;
//Config
var options = options || {},
smoothing = (options.smoothing || 0.1),
interval = (options.interval || 50),
threshold = options.threshold,
play = options.play,
history = options.history || 10,
running = true;
// Ensure that just a single AudioContext is internally created
audioContext = options.audioContext || audioContext || new audioContextType();
var sourceNode, fftBins, analyser;
analyser = audioContext.createAnalyser();
analyser.fftSize = 512;
analyser.smoothingTimeConstant = smoothing;
fftBins = new Float32Array(analyser.frequencyBinCount);
if (stream.jquery) stream = stream[0];
if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) {
//Audio Tag
sourceNode = audioContext.createMediaElementSource(stream);
if (typeof play === 'undefined') play = true;
threshold = threshold || -50;
} else {
//WebRTC Stream
sourceNode = audioContext.createMediaStreamSource(stream);
threshold = threshold || -50;
}
sourceNode.connect(analyser);
if (play) analyser.connect(audioContext.destination);
harker.speaking = false;
harker.suspend = function() {
return audioContext.suspend();
}
harker.resume = function() {
return audioContext.resume();
}
Object.defineProperty(harker, 'state', { get: function() {
return audioContext.state;
}});
audioContext.onstatechange = function() {
harker.emit('state_change', audioContext.state);
}
harker.setThreshold = function(t) {
threshold = t;
};
harker.setInterval = function(i) {
interval = i;
};
harker.stop = function() {
running = false;
harker.emit('volume_change', -100, threshold);
if (harker.speaking) {
harker.speaking = false;
harker.emit('stopped_speaking');
}
analyser.disconnect();
sourceNode.disconnect();
};
harker.speakingHistory = [];
for (var i = 0; i < history; i++) {
harker.speakingHistory.push(0);
}
// Poll the analyser node to determine if speaking
// and emit events if changed
var looper = function() {
setTimeout(function() {
//check if stop has been called
if(!running) {
return;
}
var currentVolume = getMaxVolume(analyser, fftBins);
harker.emit('volume_change', currentVolume, threshold);
var history = 0;
if (currentVolume > threshold && !harker.speaking) {
// trigger quickly, short history
for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) {
history += harker.speakingHistory[i];
}
if (history >= 2) {
harker.speaking = true;
harker.emit('speaking');
}
} else if (currentVolume < threshold && harker.speaking) {
for (var i = 0; i < harker.speakingHistory.length; i++) {
history += harker.speakingHistory[i];
}
if (history == 0) {
harker.speaking = false;
harker.emit('stopped_speaking');
}
}
harker.speakingHistory.shift();
harker.speakingHistory.push(0 + (currentVolume > threshold));
looper();
}, interval);
};
looper();
return harker;
}
},{"wildemitter":37}],6:[function(require,module,exports){
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
if (superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
})
}
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
if (superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
}
},{}],7:[function(require,module,exports){
/*
* JSNLog 2.30.0
* Open source under the MIT License.
* Copyright 2012-2017 Mattijs Perdeck All rights reserved.
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
function JL(loggerName) {
// If name is empty, return the root logger
if (!loggerName) {
return JL.__;
}
// Implements Array.reduce. JSNLog supports IE8+ and reduce is not supported in that browser.
// Same interface as the standard reduce, except that
if (!Array.prototype.reduce) {
Array.prototype.reduce = function (callback, initialValue) {
var previousValue = initialValue;
for (var i = 0; i < this.length; i++) {
previousValue = callback(previousValue, this[i], i, this);
}
return previousValue;
};
}
var accumulatedLoggerName = '';
var logger = ('.' + loggerName).split('.').reduce(function (prev, curr, idx, arr) {
// if loggername is a.b.c, than currentLogger will be set to the loggers
// root (prev: JL, curr: '')
// a (prev: JL.__, curr: 'a')
// a.b (prev: JL.__.__a, curr: 'b')
// a.b.c (prev: JL.__.__a.__a.b, curr: 'c')
// Note that when a new logger name is encountered (such as 'a.b.c'),
// a new logger object is created and added as a property to the parent ('a.b').
// The root logger is added as a property of the JL object itself.
// It is essential that the name of the property containing the child logger
// contains the full 'path' name of the child logger ('a.b.c') instead of
// just the bit after the last period ('c').
// This is because the parent inherits properties from its ancestors.
// So if the root has a child logger 'c' (stored in a property 'c' of the root logger),
// then logger 'a.b' has that same property 'c' through inheritance.
// The names of the logger properties start with __, so the root logger
// (which has name ''), has a nice property name '__'.
// accumulatedLoggerName evaluates false ('' is falsy) in first iteration when prev is the root logger.
// accumulatedLoggerName will be the logger name corresponding with the logger in currentLogger.
// Keep in mind that the currentLogger may not be defined yet, so can't get the name from
// the currentLogger object itself.
if (accumulatedLoggerName) {
accumulatedLoggerName += '.' + curr;
}
else {
accumulatedLoggerName = curr;
}
var currentLogger = prev['__' + accumulatedLoggerName];
// If the currentLogger (or the actual logger being sought) does not yet exist,
// create it now.
if (currentLogger === undefined) {
// Set the prototype of the Logger constructor function to the parent of the logger
// to be created. This way, __proto of the new logger object will point at the parent.
// When logger.level is evaluated and is not present, the JavaScript runtime will
// walk down the prototype chain to find the first ancestor with a level property.
//
// Note that prev at this point refers to the parent logger.
JL.Logger.prototype = prev;
currentLogger = new JL.Logger(accumulatedLoggerName);
prev['__' + accumulatedLoggerName] = currentLogger;
}
return currentLogger;
}, JL.__);
return logger;
}
(function (JL) {
// Initialise requestId to empty string. If you don't do this and the user
// does not set it via setOptions, then the JSNLog-RequestId header will
// have value "undefined", which doesn't look good in a log.
//
// Note that you always want to send a requestId as part of log requests,
// otherwise the server side component doesn't know this is a log request
// and may create a new request id for the log request, causing confusion
// in the log.
JL.requestId = '';
// Number uniquely identifying every log entry within the request.
JL.entryId = 0;
// Allow property injection of these classes, to enable unit testing
JL._createXMLHttpRequest = function () { return new XMLHttpRequest(); };
JL._getTime = function () { return (new Date).getTime(); };
JL._console = console;
// ----- private variables
JL._appenderNames = [];
/**
Copies the value of a property from one object to the other.
This is used to copy property values as part of setOption for loggers and appenders.
Because loggers inherit property values from their parents, it is important never to
create a property on a logger if the intent is to inherit from the parent.
Copying rules:
1) if the from property is undefined (for example, not mentioned in a JSON object), the
to property is not affected at all.
2) if the from property is null, the to property is deleted (so the logger will inherit from
its parent).
3) Otherwise, the from property is copied to the to property.
*/
function copyProperty(propertyName, from, to) {
if (from[propertyName] === undefined) {
return;
}
if (from[propertyName] === null) {
delete to[propertyName];
return;
}
to[propertyName] = from[propertyName];
}
/**
Returns true if a log should go ahead.
Does not check level.
@param filters
Filters that determine whether a log can go ahead.
*/
function allow(filters) {
// If enabled is not null or undefined, then if it is false, then return false
// Note that undefined==null (!)
if (!(JL.enabled == null)) {
if (!JL.enabled) {
return false;
}
}
// If the regex contains a bug, that will throw an exception.
// Ignore this, and pass the log item (better too much than too little).
try {
if (filters.userAgentRegex) {
if (!new RegExp(filters.userAgentRegex).test(navigator.userAgent)) {
return false;
}
}
}
catch (e) { }
try {
if (filters.ipRegex && JL.clientIP) {
if (!new RegExp(filters.ipRegex).test(JL.clientIP)) {
return false;
}
}
}
catch (e) { }
return true;
}
/**
Returns true if a log should go ahead, based on the message.
@param filters
Filters that determine whether a log can go ahead.
@param message
Message to be logged.
*/
function allowMessage(filters, message) {
// If the regex contains a bug, that will throw an exception.
// Ignore this, and pass the log item (better too much than too little).
try {
if (filters.disallow) {
if (new RegExp(filters.disallow).test(message)) {
return false;
}
}
}
catch (e) { }
return true;
}
// If logObject is a function, the function is evaluated (without parameters)
// and the result returned.
// Otherwise, logObject itself is returned.
function stringifyLogObjectFunction(logObject) {
if (typeof logObject == "function") {
if (logObject instanceof RegExp) {
return logObject.toString();
}
else {
return logObject();
}
}
return logObject;
}
var StringifiedLogObject = /** @class */ (function () {
// * msg -
// if the logObject is a scalar (after possible function evaluation), this is set to
// string representing the scalar. Otherwise it is left undefined.
// * meta -
// if the logObject is an object (after possible function evaluation), this is set to
// that object. Otherwise it is left undefined.
// * finalString -
// This is set to the string representation of logObject (after possible function evaluation),
// regardless of whether it is an scalar or an object. An object is stringified to a JSON string.
// Note that you can't call this field "final", because as some point this was a reserved
// JavaScript keyword and using final trips up some minifiers.
function StringifiedLogObject(msg, meta, finalString) {
this.msg = msg;
this.meta = meta;
this.finalString = finalString;
}
return StringifiedLogObject;
}());
// Takes a logObject, which can be
// * a scalar
// * an object
// * a parameterless function, which returns the scalar or object to log.
// Returns a stringifiedLogObject
function stringifyLogObject(logObject) {
// Note that this works if logObject is null.
// typeof null is object.
// JSON.stringify(null) returns "null".
var actualLogObject = stringifyLogObjectFunction(logObject);
var finalString;
// Note that typeof actualLogObject should not be "function", because that has
// been resolved with stringifyLogObjectFunction.
switch (typeof actualLogObject) {
case "string":
return new StringifiedLogObject(actualLogObject, null, actualLogObject);
case "number":
finalString = actualLogObject.toString();
return new StringifiedLogObject(finalString, null, finalString);
case "boolean":
finalString = actualLogObject.toString();
return new StringifiedLogObject(finalString, null, finalString);
case "undefined":
return new StringifiedLogObject("undefined", null, "undefined");
case "object":
if ((actualLogObject instanceof RegExp) ||
(actualLogObject instanceof String) ||
(actualLogObject instanceof Number) ||
(actualLogObject instanceof Boolean)) {
finalString = actualLogObject.toString();
return new StringifiedLogObject(finalString, null, finalString);
}
else {
if (typeof JL.serialize === 'function') {
finalString = JL.serialize.call(this, actualLogObject);
}
else {
finalString = JSON.stringify(actualLogObject);
}
// Set the msg field to "" instead of null. Some Winston transports
// assume that the msg field is not null.
return new StringifiedLogObject("", actualLogObject, finalString);
}
default:
return new StringifiedLogObject("unknown", null, "unknown");
}
}
function setOptions(options) {
copyProperty("enabled", options, this);
copyProperty("maxMessages", options, this);
copyProperty("defaultAjaxUrl", options, this);
copyProperty("clientIP", options, this);
copyProperty("requestId", options, this);
copyProperty("defaultBeforeSend", options, this);
copyProperty("serialize", options, this);
return this;
}
JL.setOptions = setOptions;
function getAllLevel() { return -2147483648; }
JL.getAllLevel = getAllLevel;
function getTraceLevel() { return 1000; }
JL.getTraceLevel = getTraceLevel;
function getDebugLevel() { return 2000; }
JL.getDebugLevel = getDebugLevel;
function getInfoLevel() { return 3000; }
JL.getInfoLevel = getInfoLevel;
function getWarnLevel() { return 4000; }
JL.getWarnLevel = getWarnLevel;
function getErrorLevel() { return 5000; }
JL.getErrorLevel = getErrorLevel;
function getFatalLevel() { return 6000; }
JL.getFatalLevel = getFatalLevel;
function getOffLevel() { return 2147483647; }
JL.getOffLevel = getOffLevel;
function levelToString(level) {
if (level <= 1000) {
return "trace";
}
if (level <= 2000) {
return "debug";
}
if (level <= 3000) {
return "info";
}
if (level <= 4000) {
return "warn";
}
if (level <= 5000) {
return "error";
}
return "fatal";
}
// ---------------------
var Exception = /** @class */ (function () {
// data replaces message. It takes not just strings, but also objects and functions, just like the log function.
// internally, the string representation is stored in the message property (inherited from Error)
//
// inner: inner exception. Can be null or undefined.
function Exception(data, inner) {
this.inner = inner;
this.name = "JL.Exception";
this.message = stringifyLogObject(data).finalString;
}
return Exception;
}());
JL.Exception = Exception;
// Derive Exception from Error (a Host object), so browsers
// are more likely to produce a stack trace for it in their console.
//
// Note that instanceof against an object created with this constructor
// will return true in these cases:
// <object> instanceof JL.Exception);
// <object> instanceof Error);
Exception.prototype = new Error();
// ---------------------
var LogItem = /** @class */ (function () {
// l: level
// m: message
// n: logger name
// t (timeStamp) is number of milliseconds since 1 January 1970 00:00:00 UTC
// u: number uniquely identifying this entry for this request.
//
// Keeping the property names really short, because they will be sent in the
// JSON payload to the server.
function LogItem(l, m, n, t, u) {
this.l = l;
this.m = m;
this.n = n;
this.t = t;
this.u = u;
}
return LogItem;
}());
JL.LogItem = LogItem;
function newLogItem(levelNbr, message, loggerName) {
JL.entryId++;
return new LogItem(levelNbr, message, loggerName, JL._getTime(), JL.entryId);
}
function clearTimer(timer) {
if (timer.id) {
clearTimeout(timer.id);
timer.id = null;
}
}
function setTimer(timer, timeoutMs, callback) {
var that = this;
if (!timer.id) {
timer.id = setTimeout(function () {
// use call to ensure that the this as used inside sendBatch when it runs is the
// same this at this point.
callback.call(that);
}, timeoutMs);
}
}
var Appender = /** @class */ (function () {
// sendLogItems takes an array of log items. It will be called when
// the appender has items to process (such as, send to the server).
// sendLogItems will call successCallback after the items have been successfully sent.
//
// Note that after sendLogItems returns, the appender may truncate
// the LogItem array, so the function has to copy the content of the array
// in some fashion (eg. serialize) before returning.
function Appender(appenderName, sendLogItems) {
this.appenderName = appenderName;
this.sendLogItems = sendLogItems;
this.level = JL.getTraceLevel();
// set to super high level, so if user increases level, level is unlikely to get
// above sendWithBufferLevel
this.sendWithBufferLevel = 2147483647;
this.storeInBufferLevel = -2147483648;
this.bufferSize = 0; // buffering switch off by default
this.batchSize = 1;
this.maxBatchSize = 20;
this.batchTimeout = 2147483647;
this.sendTimeout = 5000;
// Holds all log items with levels higher than storeInBufferLevel
// but lower than level. These items may never be sent.
this.buffer = [];
// Holds all items that we do want to send, until we have a full
// batch (as determined by batchSize).
this.batchBuffer = [];
// Holds the id of the timer implementing the batch timeout.
// Can be null.
// This is an object, so it can be passed to a method that updated the timer variable.
this.batchTimeoutTimer = { id: null };
// Holds the id of the timer implementing the send timeout.
// Can be null.
this.sendTimeoutTimer = { id: null };
// Number of log items that has been skipped due to batch buffer at max size,
// since appender creation or since creation of the last "skipped" warning log entry.
this.nbrLogItemsSkipped = 0;
// Will be 0 if no log request is outstanding at the moment.
// Otherwise the number of log items in the outstanding request.
this.nbrLogItemsBeingSent = 0;
var emptyNameErrorMessage = "Trying to create an appender without a name or with an empty name";
// This evaluates to true if appenderName is either null or undefined!
// Do not check here if the name is "", because that would stop you creating the
// default appender.
if (appenderName == undefined) {
throw emptyNameErrorMessage;
}
if (JL._appenderNames.indexOf(appenderName) != -1) {
// If user passed in "", that will now have been picked up as a duplicate
// because default appender also uses "".
if (!appenderName) {
throw emptyNameErrorMessage;
}
throw "Multiple appenders use the same name " + appenderName;
}
JL._appenderNames.push(appenderName);
}
Appender.prototype.addLogItemsToBuffer = function (logItems) {
// If the batch buffer has reached its maximum limit,
// skip the log item and increase the "skipped items" counter.
if (this.batchBuffer.length >= this.maxBatchSize) {
this.nbrLogItemsSkipped += logItems.length;
return;
}
// If maxMessages is not null or undefined, then decrease it by the batch size.
// This can result in a negative maxMessages.
// Note that undefined==null (!)
//
// Note that we may be sending more messages than the maxMessages limit allows,
// if we stored trace messages. Rationale is the buffer for trace messages is limited,
// and if we cut off at exactly maxMessages, we'd also loose the high severity message
// that caused the trace messages to be sent (unless we cater for this specifically, which
// is more complexity).
//
// If there are multiple appenders sending the same message, maxMessage will be decreased
// by each appender for the same message. This is:
// 1) only appenders know whether a message will actually be sent (based on storeInBufferLevel),
// so the loggers couldn't do this update;
// 2) if you have multiple appenders hitting the same server, this may be what you want.
//
// In most cases there is only 1 appender, so this then doesn't matter.
if (!(JL.maxMessages == null)) {
if (JL.maxMessages < 1) {
return;
}
JL.maxMessages -= logItems.length;
}
this.batchBuffer = this.batchBuffer.concat(logItems);
// If this is the first item in the buffer, set the timer
// to ensure it will be sent within the timeout period.
// If it is not the first item, leave the timer alone so to not to
// increase the timeout for the first item.
//
// To determine if this is the first item, look at the timer variable.
// Do not look at the buffer length, because we also put items in the buffer
// via a concat (bypassing this function).
//
// The setTimer method only sets the timer if it is not already running.
var that = this;
setTimer(this.batchTimeoutTimer, this.batchTimeout, function () {
that.sendBatch.call(that);
});
};
;
Appender.prototype.batchBufferHasOverdueMessages = function () {
for (var i = 0; i < this.batchBuffer.length; i++) {
var messageAgeMs = JL._getTime() - this.batchBuffer[i].t;
if (messageAgeMs > this.batchTimeout) {
return true;
}
}
return false;
};
// Returns true if no more message will ever be added to the batch buffer,
// but the batch buffer has messages now - so if there are not enough to make up a batch,
// and there is no batch timeout, then they will never be sent. This is especially important if
// maxMessages was reached while jsnlog.js was retrying sending messages to the server.
Appender.prototype.batchBufferHasStrandedMessage = function () {
return (!(JL.maxMessages == null)) && (JL.maxMessages < 1) && (this.batchBuffer.length > 0);
};
Appender.prototype.sendBatchIfComplete = function () {
if ((this.batchBuffer.length >= this.batchSize) ||
this.batchBufferHasOverdueMessages() ||
this.batchBufferHasStrandedMessage()) {
this.sendBatch();
}
};
Appender.prototype.onSendingEnded = function () {
clearTimer(this.sendTimeoutTimer);
this.nbrLogItemsBeingSent = 0;
this.sendBatchIfComplete();
};
Appender.prototype.setOptions = function (options) {
copyProperty("level", options, this);
copyProperty("ipRegex", options, this);
copyProperty("userAgentRegex", options, this);
copyProperty("disallow", options, this);
copyProperty("sendWithBufferLevel", options, this);
copyProperty("storeInBufferLevel", options, this);
copyProperty("bufferSize", options, this);
copyProperty("batchSize", options, this);
copyProperty("maxBatchSize", options, this);
copyProperty("batchTimeout", options, this);
copyProperty("sendTimeout", options, this);
if (this.bufferSize < this.buffer.length) {
this.buffer.length = this.bufferSize;
}
if (this.maxBatchSize < this.batchSize) {
throw new JL.Exception({
"message": "maxBatchSize cannot be smaller than batchSize",
"maxBatchSize": this.maxBatchSize,
"batchSize": this.batchSize
});
}
return this;
};
/**
Called by a logger to log a log item.
If in response to this call one or more log items need to be processed
(eg., sent to the server), this method calls this.sendLogItems
with an array with all items to be processed.
Note that the name and parameters of this function must match those of the log function of
a Winston transport object, so that users can use these transports as appenders.
That is why there are many parameters that are not actually used by this function.
level - string with the level ("trace", "debug", etc.) Only used by Winston transports.
msg - human readable message. Undefined if the log item is an object. Only used by Winston transports.
meta - log object. Always defined, because at least it contains the logger name. Only used by Winston transports.
callback - function that is called when the log item has been logged. Only used by Winston transports.
levelNbr - level as a number. Not used by Winston transports.
message - log item. If the user logged an object, this is the JSON string. Not used by Winston transports.
loggerName: name of the logger. Not used by Winston transports.
*/
Appender.prototype.log = function (level, msg, meta, callback, levelNbr, message, loggerName) {
var logItem;
if (!allow(this)) {
return;
}
if (!allowMessage(this, message)) {
return;
}
if (levelNbr < this.storeInBufferLevel) {
// Ignore the log item completely
return;
}
logItem = newLogItem(levelNbr, message, loggerName);
if (levelNbr < this.level) {
// Store in the hold buffer. Do not send.
if (this.bufferSize > 0) {
this.buffer.push(logItem);
// If we exceeded max buffer size, remove oldest item
if (this.buffer.length > this.bufferSize) {
this.buffer.shift();
}
}
return;
}
// Want to send the item
this.addLogItemsToBuffer([logItem]);
if (levelNbr >= this.sendWithBufferLevel) {
// Want to send the contents of the buffer.
//
// Send the buffer AFTER sending the high priority item.
// If you were to send the high priority item after the buffer,
// if we're close to maxMessages or maxBatchSize,
// then the trace messages in the buffer could crowd out the actual high priority item.
if (this.buffer.length) {
this.addLogItemsToBuffer(this.buffer);
this.buffer.length = 0;
}
}
this.sendBatchIfComplete();
};
;
// Processes the batch buffer
//
// Make this public, so it can be called from outside the library,
// when the page is unloaded.
Appender.prototype.sendBatch = function () {
// Do not clear the batch timer if you don't go ahead here because
// a send is already in progress. Otherwise the messages that were stopped from going out
// may get ignored because the batch timer never went off.
if (this.nbrLogItemsBeingSent > 0) {
return;
}
clearTimer(this.batchTimeoutTimer);
if (this.batchBuffer.length == 0) {
return;
}
// Decided at this point to send contents of the buffer
this.nbrLogItemsBeingSent = this.batchBuffer.length;
var that = this;
setTimer(this.sendTimeoutTimer, this.sendTimeout, function () {
that.onSendingEnded.call(that);
});
this.sendLogItems(this.batchBuffer, function () {
// Log entries have been successfully sent to server
// Remove the first (nbrLogItemsBeingSent) items in the batch buffer, because they are the ones
// that were sent.
that.batchBuffer.splice(0, that.nbrLogItemsBeingSent);
// If items had to be skipped, add a WARN message
if (that.nbrLogItemsSkipped > 0) {
that.batchBuffer.push(newLogItem(getWarnLevel(), "Lost " + that.nbrLogItemsSkipped + " messages. Either connection with the server was down or logging was disabled via the enabled option. Reduce lost messages by increasing the ajaxAppender option maxBatchSize.", that.appenderName));
that.nbrLogItemsSkipped = 0;
}
that.onSendingEnded.call(that);
});
};
return Appender;
}());
JL.Appender = Appender;
// ---------------------
var AjaxAppender = /** @class */ (function (_super) {
__extends(AjaxAppender, _super);
function AjaxAppender(appenderName) {
return _super.call(this, appenderName, AjaxAppender.prototype.sendLogItemsAjax) || this;
}
AjaxAppender.prototype.setOptions = function (options) {
copyProperty("url", options, this);
copyProperty("beforeSend", options, this);
_super.prototype.setOptions.call(this, options);
return this;
};
AjaxAppender.prototype.sendLogItemsAjax = function (logItems, successCallback) {
// JSON.stringify is only supported on IE8+
// Use try-catch in case we get an exception here.
//
// The "r" field is now obsolete. When writing a server side component,
// read the HTTP header "JSNLog-RequestId"
// to get the request id.
//
// The .Net server side component
// now uses the JSNLog-RequestId HTTP Header, because this allows it to
// detect whether the incoming request has a request id.
// If the request id were in the json payload, it would have to read the json
// from the stream, interfering with normal non-logging requests.
//
// To see what characters you can use in the HTTP header, visit:
// http://stackoverflow.com/questions/3561381/custom-http-headers-naming-conventions/3561399#3561399
//
// It needs this ability, so users of NLog can set a requestId variable in NLog
// before the server side component tries to log the client side log message
// through an NLog logger.
// Unlike Log4Net, NLog doesn't allow you to register an object whose ToString()
// is only called when it tries to log something, so the requestId has to be
// determined right at the start of request processing.
try {
// Do not send logs, if JL.enabled is set to false.
//
// Do not call successCallback here. After each timeout, jsnlog will retry sending the message.
// If jsnlog gets re-enabled, it will then log the number of messages logged.
// If it doesn't get re-enabled, amount of cpu cycles wasted is minimal.
if (!allow(this)) {
return;
}
// If a request is in progress, abort it.
// Otherwise, it may call the success callback, which will be very confusing.
// It may also stop the inflight request from resulting in a log at the server.
if (this.xhr && (this.xhr.readyState != 0) && (this.xhr.readyState != 4)) {
this.xhr.abort();
}
// Because a react-native XMLHttpRequest cannot be reused it needs to be recreated with each request
this.xhr = JL._createXMLHttpRequest();
// Only determine the url right before you send a log request.
// Do not set the url when constructing the appender.
//
// This is because the server side component sets defaultAjaxUrl
// in a call to setOptions, AFTER the JL object and the default appender
// have been created.
var ajaxUrl = "/jsnlog.logger";
// This evaluates to true if defaultAjaxUrl is null or undefined
if (!(JL.defaultAjaxUrl == null)) {
ajaxUrl = JL.defaultAjaxUrl;
}
if (this.url) {
ajaxUrl = this.url;
}
this.xhr.open('POST', ajaxUrl);
this.xhr.setRequestHeader('Content-Type', 'application/json');
this.xhr.setRequestHeader('JSNLog-RequestId', JL.requestId);
var that = this;
this.xhr.onreadystatechange = function () {
// On most browsers, if the request fails (eg. internet is gone),
// it will set xhr.readyState == 4 and xhr.status != 200 (0 if request could not be sent) immediately.
// However, Edge and IE will not change the readyState at all if the internet goes away while waiting
// for a response.
// Some servers will return a 204 (success, no content) when the JSNLog endpoint
// returns the empty response. So check on any code in the 2.. range, not just 200.
if ((that.xhr.readyState == 4) && (that.xhr.status >= 200 && that.xhr.status < 300)) {
successCallback();
}
};
var json = {
r: JL.requestId,
lg: logItems
};
// call beforeSend callback
// first try the callback on the appender
// then the global defaultBeforeSend callback
if (typeof this.beforeSend === 'function') {
this.beforeSend.call(this, this.xhr, json);
}
else if (typeof JL.defaultBeforeSend === 'function') {
JL.defaultBeforeSend.call(this, this.xhr, json);
}
var finalmsg = JSON.stringify(json);
this.xhr.send(finalmsg);
}
catch (e) { }
};
return AjaxAppender;
}(Appender));
JL.AjaxAppender = AjaxAppender;
// ---------------------
var ConsoleAppender = /** @class */ (function (_super) {
__extends(ConsoleAppender, _super);
function ConsoleAppender(appenderName) {
return _super.call(this, appenderName, ConsoleAppender.prototype.sendLogItemsConsole) || this;
}
ConsoleAppender.prototype.clog = function (logEntry) {
JL._console.log(logEntry);
};
ConsoleAppender.prototype.cerror = function (logEntry) {
if (JL._console.error) {
JL._console.error(logEntry);
}
else {
this.clog(logEntry);
}
};
ConsoleAppender.prototype.cwarn = function (logEntry) {
if (JL._console.warn) {
JL._console.warn(logEntry);
}
else {
this.clog(logEntry);
}
};
ConsoleAppender.prototype.cinfo = function (logEntry) {
if (JL._console.info) {
JL._console.info(logEntry);
}
else {
this.clog(logEntry);
}
};
// IE11 has a console.debug function. But its console doesn't have
// the option to show/hide debug messages (the same way Chrome and FF do),
// even though it does have such buttons for Error, Warn, Info.
//
// For now, this means that debug messages can not be hidden on IE.
// Live with this, seeing that it works fine on FF and Chrome, which
// will be much more popular with developers.
ConsoleAppender.prototype.cdebug = function (logEntry) {
if (JL._console.debug) {
JL._console.debug(logEntry);
}
else {
this.cinfo(logEntry);
}
};
ConsoleAppender.prototype.sendLogItemsConsole = function (logItems, successCallback) {
try {
// Do not send logs, if JL.enabled is set to false
//
// Do not call successCallback here. After each timeout, jsnlog will retry sending the message.
// If jsnlog gets re-enabled, it will then log the number of messages logged.
// If it doesn't get re-enabled, amount of cpu cycles wasted is minimal.
if (!allow(this)) {
return;
}
if (!JL._console) {
return;
}
var i;
for (i = 0; i < logItems.length; ++i) {
var li = logItems[i];
var msg = li.n + ": " + li.m;
// Only log the timestamp if we're on the server
// (window is undefined). On the browser, the user
// sees the log entry probably immediately, so in that case
// the timestamp is clutter.
if (typeof window === 'undefined') {
msg = new Date(li.t) + " | " + msg;
}
if (li.l <= JL.getDebugLevel()) {
this.cdebug(msg);
}
else if (li.l <= JL.getInfoLevel()) {
this.cinfo(msg);
}
else if (li.l <= JL.getWarnLevel()) {
this.cwarn(msg);
}
else {
this.cerror(msg);
}
}
}
catch (e) {
}
successCallback();
};
return ConsoleAppender;
}(Appender));
JL.ConsoleAppender = ConsoleAppender;
// --------------------
var Logger = /** @class */ (function () {
function Logger(loggerName) {
this.loggerName = loggerName;
// Create seenRexes, otherwise this logger will use the seenRexes
// of its parent via the prototype chain.
this.seenRegexes = [];
}
Logger.prototype.setOptions = function (options) {
copyProperty("level", options, this);
copyProperty("userAgentRegex", options, this);
copyProperty("disallow", options, this);
copyProperty("ipRegex", options, this);
copyProperty("appenders", options, this);
copyProperty("onceOnly", options, this);
// Reset seenRegexes, in case onceOnly has been changed.
this.seenRegexes = [];
return this;
};
// Turns an exception into an object that can be sent to the server.
Logger.prototype.buildExceptionObject = function (e) {
var excObject = {};
if (e.stack) {
excObject.stack = e.stack;
}
else {
excObject.e = e;
}
if (e.message) {
excObject.message = e.message;
}
if (e.name) {
excObject.name = e.name;
}
if (e.data) {
excObject.data = e.data;
}
if (e.inner) {
excObject.inner = this.buildExceptionObject(e.inner);
}
return excObject;
};
// Logs a log item.
// Parameter e contains an exception (or null or undefined).
//
// Reason that processing exceptions is done at this low level is that
// 1) no need to spend the cpu cycles if the logger is switched off
// 2) fatalException takes both a logObject and an exception, and the logObject
// may be a function that should only be executed if the logger is switched on.
//
// If an exception is passed in, the contents of logObject is attached to the exception
// object in a new property logData.
// The resulting exception object is than worked into a message to the server.
//
// If there is no exception, logObject itself is worked into the message to the server.
Logger.prototype.log = function (level, logObject, e) {
var i = 0;
var compositeMessage;
var excObject;
// If we can't find any appenders, do nothing
if (!this.appenders) {
return this;
}
if (((level >= this.level)) && allow(this)) {
if (e) {
excObject = this.buildExceptionObject(e);
excObject.logData = stringifyLogObjectFunction(logObject);
}
else {
excObject = logObject;
}
compositeMessage = stringifyLogObject(excObject);
if (allowMessage(this, compositeMessage.finalString)) {
// See whether message is a duplicate
if (this.onceOnly) {
i = this.onceOnly.length - 1;
while (i >= 0) {
if (new RegExp(this.onceOnly[i]).test(compositeMessage.finalString)) {
if (this.seenRegexes[i]) {
return this;
}
this.seenRegexes[i] = true;
}
i--;
}
}
// Pass message to all appenders
// Note that these appenders could be Winston transports
// https://github.com/flatiron/winston
compositeMessage.meta = compositeMessage.meta || {};
// Note that if the user is logging an object, compositeMessage.meta will hold a reference to that object.
// Do not add fields to compositeMessage.meta, otherwise the user's object will get that field out of the blue.
i = this.appenders.length - 1;
while (i >= 0) {
this.appenders[i].log(levelToString(level), compositeMessage.msg, compositeMessage.meta, function () { }, level, compositeMessage.finalString, this.loggerName);
i--;
}
}
}
return this;
};
Logger.prototype.trace = function (logObject) { return this.log(getTraceLevel(), logObject); };
Logger.prototype.debug = function (logObject) { return this.log(getDebugLevel(), logObject); };
Logger.prototype.info = function (logObject) { return this.log(getInfoLevel(), logObject); };
Logger.prototype.warn = function (logObject) { return this.log(getWarnLevel(), logObject); };
Logger.prototype.error = function (logObject) { return this.log(getErrorLevel(), logObject); };
Logger.prototype.fatal = function (logObject) { return this.log(getFatalLevel(), logObject); };
Logger.prototype.fatalException = function (logObject, e) { return this.log(getFatalLevel(), logObject, e); };
return Logger;
}());
JL.Logger = Logger;
function createAjaxAppender(appenderName) {
return new AjaxAppender(appenderName);
}
JL.createAjaxAppender = createAjaxAppender;
function createConsoleAppender(appenderName) {
return new ConsoleAppender(appenderName);
}
JL.createConsoleAppender = createConsoleAppender;
// -----------------------
// In the browser, the default appender is the AjaxAppender.
// Under nodejs (where there is no "window"), use the ConsoleAppender instead.
//
// Do NOT create an AjaxAppender object if you are not on a browser (that is, window is not defined).
// That would try to create an XmlHttpRequest object, which will crash outside a browser.
var defaultAppender;
if (typeof window !== 'undefined') {
defaultAppender = new AjaxAppender("");
}
else {
defaultAppender = new ConsoleAppender("");
}
// Create root logger
//
// Note that this is the parent of all other loggers.
// Logger "x" will be stored at
// JL.__.x
// Logger "x.y" at
// JL.__.x.y
JL.__ = new JL.Logger("");
JL.__.setOptions({
level: JL.getDebugLevel(),
appenders: [defaultAppender]
});
})(JL || (JL = {}));
if (typeof exports !== 'undefined') {
// Allows SystemJs to import jsnlog.js. See
// https://github.com/mperdeck/jsnlog.js/issues/56
exports.__esModule = true;
exports.JL = JL;
}
// Support AMD module format
var define;
if (typeof define == 'function' && define.amd) {
define('jsnlog', [], function () {
return JL;
});
}
// If the __jsnlog_configure global function has been
// created, call it now. This allows you to create a global function
// setting logger options etc. inline in the page before jsnlog.js
// has been loaded.
if (typeof __jsnlog_configure == 'function') {
__jsnlog_configure(JL);
}
// Create onerror handler to log uncaught exceptions to the server side log, but only if there
// is no such handler already.
// Must use "typeof window" here, because in NodeJs, window is not defined at all, so cannot refer to window in any way.
if (typeof window !== 'undefined' && !window.onerror) {
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
// Send object with all data to server side log, using severity fatal,
// from logger "onerrorLogger"
//
// Use errorMsg.message if available, so Angular 4 template errors will be logged.
// See https://github.com/mperdeck/jsnlog.js/pull/68
JL("onerrorLogger").fatalException({
"msg": "Uncaught Exception",
"errorMsg": errorMsg ? (errorMsg.message || errorMsg) : '',
"url": url,
"line number": lineNumber, "column": column
}, errorObj);
// Tell browser to run its own error handler as well
return false;
};
}
// Deal with unhandled exceptions thrown in promises
if (typeof window !== 'undefined' && !window.onunhandledrejection) {
window.onunhandledrejection = function (event) {
// Send object with all data to server side log, using severity fatal,
// from logger "onerrorLogger".
// Need to check both event.reason.message and event.message,
// because SystemJs wraps exceptions and throws a new object which doesn't have a reason property.
// See https://github.com/systemjs/systemjs/issues/1309
JL("onerrorLogger").fatalException({
"msg": "unhandledrejection",
"errorMsg": event.reason ? event.reason.message : event.message || null
}, event.reason);
};
}
},{}],8:[function(require,module,exports){
'use strict';
/**
* @param typeMap [Object] Map of MIME type -> Array[extensions]
* @param ...
*/
function Mime() {
this._types = Object.create(null);
this._extensions = Object.create(null);
for (let i = 0; i < arguments.length; i++) {
this.define(arguments[i]);
}
this.define = this.define.bind(this);
this.getType = this.getType.bind(this);
this.getExtension = this.getExtension.bind(this);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* If a type declares an extension that has already been defined, an error will
* be thrown. To suppress this error and force the extension to be associated
* with the new type, pass `force`=true. Alternatively, you may prefix the
* extension with "*" to map the type to extension, without mapping the
* extension to the type.
*
* e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
*
*
* @param map (Object) type definitions
* @param force (Boolean) if true, force overriding of existing definitions
*/
Mime.prototype.define = function(typeMap, force) {
for (let type in typeMap) {
let extensions = typeMap[type].map(function(t) {
return t.toLowerCase();
});
type = type.toLowerCase();
for (let i = 0; i < extensions.length; i++) {
const ext = extensions[i];
// '*' prefix = not the preferred type for this extension. So fixup the
// extension, and skip it.
if (ext[0] === '*') {
continue;
}
if (!force && (ext in this._types)) {
throw new Error(
'Attempt to change mapping for "' + ext +
'" extension from "' + this._types[ext] + '" to "' + type +
'". Pass `force=true` to allow this, otherwise remove "' + ext +
'" from the list of extensions for "' + type + '".'
);
}
this._types[ext] = type;
}
// Use first extension as default
if (force || !this._extensions[type]) {
const ext = extensions[0];
this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1);
}
}
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.getType = function(path) {
path = String(path);
let last = path.replace(/^.*[/\\]/, '').toLowerCase();
let ext = last.replace(/^.*\./, '').toLowerCase();
let hasPath = last.length < path.length;
let hasDot = ext.length < last.length - 1;
return (hasDot || !hasPath) && this._types[ext] || null;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.getExtension = function(type) {
type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
return type && this._extensions[type.toLowerCase()] || null;
};
module.exports = Mime;
},{}],9:[function(require,module,exports){
'use strict';
let Mime = require('./Mime');
module.exports = new Mime(require('./types/standard'));
},{"./Mime":8,"./types/standard":10}],10:[function(require,module,exports){
module.exports = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["es","ecma"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/express":["exp"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/trig":["trig"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/step+xml":["stpx"],"model/step+zip":["stpz"],"model/step-xml+zip":["stpxz"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]};
},{}],11:[function(require,module,exports){
/**
# normalice
Normalize an ice server configuration object (or plain old string) into a format
that is usable in all browsers supporting WebRTC. Primarily this module is designed
to help with the transition of the `url` attribute of the configuration object to
the `urls` attribute.
## Example Usage
<<< examples/simple.js
**/
var protocols = [
'stun:',
'turn:'
];
module.exports = function(input) {
var url = (input || {}).url || input;
var protocol;
var parts;
var output = {};
// if we don't have a string url, then allow the input to passthrough
if (typeof url != 'string' && (! (url instanceof String))) {
return input;
}
// trim the url string, and convert to an array
url = url.trim();
// if the protocol is not known, then passthrough
protocol = protocols[protocols.indexOf(url.slice(0, 5))];
if (! protocol) {
return input;
}
// now let's attack the remaining url parts
url = url.slice(5);
parts = url.split('@');
output.username = input.username;
output.credential = input.credential;
// if we have an authentication part, then set the credentials
if (parts.length > 1) {
url = parts[1];
parts = parts[0].split(':');
// add the output credential and username
output.username = parts[0];
output.credential = (input || {}).credential || parts[1] || '';
}
output.url = protocol + url;
output.urls = [ output.url ];
return output;
};
},{}],12:[function(require,module,exports){
(function (global){(function (){
/*!
* Platform.js v1.3.6
* Copyright 2014-2020 Benjamin Tan
* Copyright 2011-2013 John-David Dalton
* Available under MIT license
*/
;(function() {
'use strict';
/** Used to determine if values are of the language type `Object`. */
var objectTypes = {
'function': true,
'object': true
};
/** Used as a reference to the global object. */
var root = (objectTypes[typeof window] && window) || this;
/** Backup possible global object. */
var oldRoot = root;
/** Detect free variable `exports`. */
var freeExports = objectTypes[typeof exports] && exports;
/** Detect free variable `module`. */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
root = freeGlobal;
}
/**
* Used as the maximum length of an array-like object.
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
* for more details.
*/
var maxSafeInteger = Math.pow(2, 53) - 1;
/** Regular expression to detect Opera. */
var reOpera = /\bOpera/;
/** Possible global object. */
var thisBinding = this;
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check for own properties of an object. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to resolve the internal `[[Class]]` of values. */
var toString = objectProto.toString;
/*--------------------------------------------------------------------------*/
/**
* Capitalizes a string value.
*
* @private
* @param {string} string The string to capitalize.
* @returns {string} The capitalized string.
*/
function capitalize(string) {
string = String(string);
return string.charAt(0).toUpperCase() + string.slice(1);
}
/**
* A utility function to clean up the OS name.
*
* @private
* @param {string} os The OS name to clean up.
* @param {string} [pattern] A `RegExp` pattern matching the OS name.
* @param {string} [label] A label for the OS.
*/
function cleanupOS(os, pattern, label) {
// Platform tokens are defined at:
// http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
// http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
var data = {
'10.0': '10',
'6.4': '10 Technical Preview',
'6.3': '8.1',
'6.2': '8',
'6.1': 'Server 2008 R2 / 7',
'6.0': 'Server 2008 / Vista',
'5.2': 'Server 2003 / XP 64-bit',
'5.1': 'XP',
'5.01': '2000 SP1',
'5.0': '2000',
'4.0': 'NT',
'4.90': 'ME'
};
// Detect Windows version from platform tokens.
if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) &&
(data = data[/[\d.]+$/.exec(os)])) {
os = 'Windows ' + data;
}
// Correct character case and cleanup string.
os = String(os);
if (pattern && label) {
os = os.replace(RegExp(pattern, 'i'), label);
}
os = format(
os.replace(/ ce$/i, ' CE')
.replace(/\bhpw/i, 'web')
.replace(/\bMacintosh\b/, 'Mac OS')
.replace(/_PowerPC\b/i, ' OS')
.replace(/\b(OS X) [^ \d]+/i, '$1')
.replace(/\bMac (OS X)\b/, '$1')
.replace(/\/(\d)/, ' $1')
.replace(/_/g, '.')
.replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
.replace(/\bx86\.64\b/gi, 'x86_64')
.replace(/\b(Windows Phone) OS\b/, '$1')
.replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1')
.split(' on ')[0]
);
return os;
}
/**
* An iteration utility for arrays and objects.
*
* @private
* @param {Array|Object} object The object to iterate over.
* @param {Function} callback The function called per iteration.
*/
function each(object, callback) {
var index = -1,
length = object ? object.length : 0;
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
while (++index < length) {
callback(object[index], index, object);
}
} else {
forOwn(object, callback);
}
}
/**
* Trim and conditionally capitalize string values.
*
* @private
* @param {string} string The string to format.
* @returns {string} The formatted string.
*/
function format(string) {
string = trim(string);
return /^(?:webOS|i(?:OS|P))/.test(string)
? string
: capitalize(string);
}
/**
* Iterates over an object's own properties, executing the `callback` for each.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} callback The function executed per own property.
*/
function forOwn(object, callback) {
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
callback(object[key], key, object);
}
}
}
/**
* Gets the internal `[[Class]]` of a value.
*
* @private
* @param {*} value The value.
* @returns {string} The `[[Class]]`.
*/
function getClassOf(value) {
return value == null
? capitalize(value)
: toString.call(value).slice(8, -1);
}
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of "object", "function", or "unknown".
*
* @private
* @param {*} object The owner of the property.
* @param {string} property The property to check.
* @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/
function isHostType(object, property) {
var type = object != null ? typeof object[property] : 'number';
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
(type == 'object' ? !!object[property] : true);
}
/**
* Prepares a string for use in a `RegExp` by making hyphens and spaces optional.
*
* @private
* @param {string} string The string to qualify.
* @returns {string} The qualified string.
*/
function qualify(string) {
return String(string).replace(/([ -])(?!$)/g, '$1?');
}
/**
* A bare-bones `Array#reduce` like utility function.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
* @returns {*} The accumulated result.
*/
function reduce(array, callback) {
var accumulator = null;
each(array, function(value, index) {
accumulator = callback(accumulator, value, index, array);
});
return accumulator;
}
/**
* Removes leading and trailing whitespace from a string.
*
* @private
* @param {string} string The string to trim.
* @returns {string} The trimmed string.
*/
function trim(string) {
return String(string).replace(/^ +| +$/g, '');
}
/*--------------------------------------------------------------------------*/
/**
* Creates a new platform object.
*
* @memberOf platform
* @param {Object|string} [ua=navigator.userAgent] The user agent string or
* context object.
* @returns {Object} A platform object.
*/
function parse(ua) {
/** The environment context object. */
var context = root;
/** Used to flag when a custom context is provided. */
var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String';
// Juggle arguments.
if (isCustomContext) {
context = ua;
ua = null;
}
/** Browser navigator object. */
var nav = context.navigator || {};
/** Browser user agent string. */
var userAgent = nav.userAgent || '';
ua || (ua = userAgent);
/** Used to flag when `thisBinding` is the [ModuleScope]. */
var isModuleScope = isCustomContext || thisBinding == oldRoot;
/** Used to detect if browser is like Chrome. */
var likeChrome = isCustomContext
? !!nav.likeChrome
: /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString());
/** Internal `[[Class]]` value shortcuts. */
var objectClass = 'Object',
airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject',
enviroClass = isCustomContext ? objectClass : 'Environment',
javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java),
phantomClass = isCustomContext ? objectClass : 'RuntimeObject';
/** Detect Java environments. */
var java = /\bJava/.test(javaClass) && context.java;
/** Detect Rhino. */
var rhino = java && getClassOf(context.environment) == enviroClass;
/** A character to represent alpha. */
var alpha = java ? 'a' : '\u03b1';
/** A character to represent beta. */
var beta = java ? 'b' : '\u03b2';
/** Browser document object. */
var doc = context.document || {};
/**
* Detect Opera browser (Presto-based).
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
*/
var opera = context.operamini || context.opera;
/** Opera `[[Class]]`. */
var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera))
? operaClass
: (opera = null);
/*------------------------------------------------------------------------*/
/** Temporary variable used over the script's lifetime. */
var data;
/** The CPU architecture. */
var arch = ua;
/** Platform description array. */
var description = [];
/** Platform alpha/beta indicator. */
var prerelease = null;
/** A flag to indicate that environment features should be used to resolve the platform. */
var useFeatures = ua == userAgent;
/** The browser/environment version. */
var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();
/** A flag to indicate if the OS ends with "/ Version" */
var isSpecialCasedOS;
/* Detectable layout engines (order is important). */
var layout = getLayout([
{ 'label': 'EdgeHTML', 'pattern': 'Edge' },
'Trident',
{ 'label': 'WebKit', 'pattern': 'AppleWebKit' },
'iCab',
'Presto',
'NetFront',
'Tasman',
'KHTML',
'Gecko'
]);
/* Detectable browser names (order is important). */
var name = getName([
'Adobe AIR',
'Arora',
'Avant Browser',
'Breach',
'Camino',
'Electron',
'Epiphany',
'Fennec',
'Flock',
'Galeon',
'GreenBrowser',
'iCab',
'Iceweasel',
'K-Meleon',
'Konqueror',
'Lunascape',
'Maxthon',
{ 'label': 'Microsoft Edge', 'pattern': '(?:Edge|Edg|EdgA|EdgiOS)' },
'Midori',
'Nook Browser',
'PaleMoon',
'PhantomJS',
'Raven',
'Rekonq',
'RockMelt',
{ 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' },
'SeaMonkey',
{ 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Sleipnir',
'SlimBrowser',
{ 'label': 'SRWare Iron', 'pattern': 'Iron' },
'Sunrise',
'Swiftfox',
'Vivaldi',
'Waterfox',
'WebPositive',
{ 'label': 'Yandex Browser', 'pattern': 'YaBrowser' },
{ 'label': 'UC Browser', 'pattern': 'UCBrowser' },
'Opera Mini',
{ 'label': 'Opera Mini', 'pattern': 'OPiOS' },
'Opera',
{ 'label': 'Opera', 'pattern': 'OPR' },
'Chromium',
'Chrome',
{ 'label': 'Chrome', 'pattern': '(?:HeadlessChrome)' },
{ 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
{ 'label': 'Firefox for iOS', 'pattern': 'FxiOS' },
{ 'label': 'IE', 'pattern': 'IEMobile' },
{ 'label': 'IE', 'pattern': 'MSIE' },
'Safari'
]);
/* Detectable products (order is important). */
var product = getProduct([
{ 'label': 'BlackBerry', 'pattern': 'BB10' },
'BlackBerry',
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
{ 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
{ 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
{ 'label': 'Galaxy S5', 'pattern': 'SM-G900' },
{ 'label': 'Galaxy S6', 'pattern': 'SM-G920' },
{ 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' },
{ 'label': 'Galaxy S7', 'pattern': 'SM-G930' },
{ 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' },
'Google TV',
'Lumia',
'iPad',
'iPod',
'iPhone',
'Kindle',
{ 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Nexus',
'Nook',
'PlayBook',
'PlayStation Vita',
'PlayStation',
'TouchPad',
'Transformer',
{ 'label': 'Wii U', 'pattern': 'WiiU' },
'Wii',
'Xbox One',
{ 'label': 'Xbox 360', 'pattern': 'Xbox' },
'Xoom'
]);
/* Detectable manufacturers. */
var manufacturer = getManufacturer({
'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
'Alcatel': {},
'Archos': {},
'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
'Asus': { 'Transformer': 1 },
'Barnes & Noble': { 'Nook': 1 },
'BlackBerry': { 'PlayBook': 1 },
'Google': { 'Google TV': 1, 'Nexus': 1 },
'HP': { 'TouchPad': 1 },
'HTC': {},
'Huawei': {},
'Lenovo': {},
'LG': {},
'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
'Motorola': { 'Xoom': 1 },
'Nintendo': { 'Wii U': 1, 'Wii': 1 },
'Nokia': { 'Lumia': 1 },
'Oppo': {},
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 },
'Xiaomi': { 'Mi': 1, 'Redmi': 1 }
});
/* Detectable operating systems (order is important). */
var os = getOS([
'Windows Phone',
'KaiOS',
'Android',
'CentOS',
{ 'label': 'Chrome OS', 'pattern': 'CrOS' },
'Debian',
{ 'label': 'DragonFly BSD', 'pattern': 'DragonFly' },
'Fedora',
'FreeBSD',
'Gentoo',
'Haiku',
'Kubuntu',
'Linux Mint',
'OpenBSD',
'Red Hat',
'SuSE',
'Ubuntu',
'Xubuntu',
'Cygwin',
'Symbian OS',
'hpwOS',
'webOS ',
'webOS',
'Tablet OS',
'Tizen',
'Linux',
'Mac OS X',
'Macintosh',
'Mac',
'Windows 98;',
'Windows '
]);
/*------------------------------------------------------------------------*/
/**
* Picks the layout engine from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected layout engine.
*/
function getLayout(guesses) {
return reduce(guesses, function(result, guess) {
return result || RegExp('\\b' + (
guess.pattern || qualify(guess)
) + '\\b', 'i').exec(ua) && (guess.label || guess);
});
}
/**
* Picks the manufacturer from an array of guesses.
*
* @private
* @param {Array} guesses An object of guesses.
* @returns {null|string} The detected manufacturer.
*/
function getManufacturer(guesses) {
return reduce(guesses, function(result, value, key) {
// Lookup the manufacturer by product or scan the UA for the manufacturer.
return result || (
value[product] ||
value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
) && key;
});
}
/**
* Picks the browser name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected browser name.
*/
function getName(guesses) {
return reduce(guesses, function(result, guess) {
return result || RegExp('\\b' + (
guess.pattern || qualify(guess)
) + '\\b', 'i').exec(ua) && (guess.label || guess);
});
}
/**
* Picks the OS name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected OS name.
*/
function getOS(guesses) {
return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess);
if (!result && (result =
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
)) {
result = cleanupOS(result, pattern, guess.label || guess);
}
return result;
});
}
/**
* Picks the product name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected product name.
*/
function getProduct(guesses) {
return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess);
if (!result && (result =
RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) ||
RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
)) {
// Split by forward slash and append product version if needed.
if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
result[0] += ' ' + result[1];
}
// Correct character case and cleanup string.
guess = guess.label || guess;
result = format(result[0]
.replace(RegExp(pattern, 'i'), guess)
.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
.replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
}
return result;
});
}
/**
* Resolves the version using an array of UA patterns.
*
* @private
* @param {Array} patterns An array of UA patterns.
* @returns {null|string} The detected version.
*/
function getVersion(patterns) {
return reduce(patterns, function(result, pattern) {
return result || (RegExp(pattern +
'(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
});
}
/**
* Returns `platform.description` when the platform object is coerced to a string.
*
* @name toString
* @memberOf platform
* @returns {string} Returns `platform.description` if available, else an empty string.
*/
function toStringPlatform() {
return this.description || '';
}
/*------------------------------------------------------------------------*/
// Convert layout to an array so we can add extra details.
layout && (layout = [layout]);
// Detect Android products.
// Browsers on Android devices typically provide their product IDS after "Android;"
// up to "Build" or ") AppleWebKit".
// Example:
// "Mozilla/5.0 (Linux; Android 8.1.0; Moto G (5) Plus) AppleWebKit/537.36
// (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36"
if (/\bAndroid\b/.test(os) && !product &&
(data = /\bAndroid[^;]*;(.*?)(?:Build|\) AppleWebKit)\b/i.exec(ua))) {
product = trim(data[1])
// Replace any language codes (eg. "en-US").
.replace(/^[a-z]{2}-[a-z]{2};\s*/i, '')
|| null;
}
// Detect product names that contain their manufacturer's name.
if (manufacturer && !product) {
product = getProduct([manufacturer]);
} else if (manufacturer && product) {
product = product
.replace(RegExp('^(' + qualify(manufacturer) + ')[-_.\\s]', 'i'), manufacturer + ' ')
.replace(RegExp('^(' + qualify(manufacturer) + ')[-_.]?(\\w)', 'i'), manufacturer + ' $2');
}
// Clean up Google TV.
if ((data = /\bGoogle TV\b/.exec(product))) {
product = data[0];
}
// Detect simulators.
if (/\bSimulator\b/i.test(ua)) {
product = (product ? product + ' ' : '') + 'Simulator';
}
// Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS.
if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) {
description.push('running in Turbo/Uncompressed mode');
}
// Detect IE Mobile 11.
if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) {
data = parse(ua.replace(/like iPhone OS/, ''));
manufacturer = data.manufacturer;
product = data.product;
}
// Detect iOS.
else if (/^iP/.test(product)) {
name || (name = 'Safari');
os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
? ' ' + data[1].replace(/_/g, '.')
: '');
}
// Detect Kubuntu.
else if (name == 'Konqueror' && /^Linux\b/i.test(os)) {
os = 'Kubuntu';
}
// Detect Android browsers.
else if ((manufacturer && manufacturer != 'Google' &&
((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) ||
(/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) {
name = 'Android Browser';
os = /\bAndroid\b/.test(os) ? os : 'Android';
}
// Detect Silk desktop/accelerated modes.
else if (name == 'Silk') {
if (!/\bMobi/i.test(ua)) {
os = 'Android';
description.unshift('desktop mode');
}
if (/Accelerated *= *true/i.test(ua)) {
description.unshift('accelerated');
}
}
// Detect UC Browser speed mode.
else if (name == 'UC Browser' && /\bUCWEB\b/.test(ua)) {
description.push('speed mode');
}
// Detect PaleMoon identifying as Firefox.
else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) {
description.push('identifying as Firefox ' + data[1]);
}
// Detect Firefox OS and products running Firefox.
else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) {
os || (os = 'Firefox OS');
product || (product = data[1]);
}
// Detect false positives for Firefox/Safari.
else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) {
// Escape the `/` for Firefox 1.
if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
// Clear name of false positives.
name = null;
}
// Reassign a generic name.
if ((data = product || manufacturer || os) &&
(product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) {
name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser';
}
}
// Add Chrome version to description for Electron.
else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) {
description.push('Chromium ' + data);
}
// Detect non-Opera (Presto-based) versions (order is important).
if (!version) {
version = getVersion([
'(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|HeadlessChrome|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$)|UCBrowser|YaBrowser)',
'Version',
qualify(name),
'(?:Firefox|Minefield|NetFront)'
]);
}
// Detect stubborn layout engines.
if ((data =
layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' ||
/\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') ||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' ||
!layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') ||
layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront'
)) {
layout = [data];
}
// Detect Windows Phone 7 desktop mode.
if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
name += ' Mobile';
os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x');
description.unshift('desktop mode');
}
// Detect Windows Phone 8.x desktop mode.
else if (/\bWPDesktop\b/i.test(ua)) {
name = 'IE Mobile';
os = 'Windows Phone 8.x';
description.unshift('desktop mode');
version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]);
}
// Detect IE 11 identifying as other browsers.
else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) {
if (name) {
description.push('identifying as ' + name + (version ? ' ' + version : ''));
}
name = 'IE';
version = data[1];
}
// Leverage environment features.
if (useFeatures) {
// Detect server-side environments.
// Rhino has a global function while others have a global object.
if (isHostType(context, 'global')) {
if (java) {
data = java.lang.System;
arch = data.getProperty('os.arch');
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
}
if (rhino) {
try {
version = context.require('ringo/engine').version.join('.');
name = 'RingoJS';
} catch(e) {
if ((data = context.system) && data.global.system == context.system) {
name = 'Narwhal';
os || (os = data[0].os || null);
}
}
if (!name) {
name = 'Rhino';
}
}
else if (
typeof context.process == 'object' && !context.process.browser &&
(data = context.process)
) {
if (typeof data.versions == 'object') {
if (typeof data.versions.electron == 'string') {
description.push('Node ' + data.versions.node);
name = 'Electron';
version = data.versions.electron;
} else if (typeof data.versions.nw == 'string') {
description.push('Chromium ' + version, 'Node ' + data.versions.node);
name = 'NW.js';
version = data.versions.nw;
}
}
if (!name) {
name = 'Node.js';
arch = data.arch;
os = data.platform;
version = /[\d.]+/.exec(data.version);
version = version ? version[0] : null;
}
}
}
// Detect Adobe AIR.
else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
name = 'Adobe AIR';
os = data.flash.system.Capabilities.os;
}
// Detect PhantomJS.
else if (getClassOf((data = context.phantom)) == phantomClass) {
name = 'PhantomJS';
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
}
// Detect IE compatibility modes.
else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
// We're in compatibility mode when the Trident version + 4 doesn't
// equal the document mode.
version = [version, doc.documentMode];
if ((data = +data[1] + 4) != version[1]) {
description.push('IE ' + version[1] + ' mode');
layout && (layout[1] = '');
version[1] = data;
}
version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
}
// Detect IE 11 masking as other browsers.
else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) {
description.push('masking as ' + name + ' ' + version);
name = 'IE';
version = '11.0';
layout = ['Trident'];
os = 'Windows';
}
os = os && format(os);
}
// Detect prerelease phases.
if (version && (data =
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
/\bMinefield\b/i.test(ua) && 'a'
)) {
prerelease = /b/i.test(data) ? 'beta' : 'alpha';
version = version.replace(RegExp(data + '\\+?$'), '') +
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
}
// Detect Firefox Mobile.
if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS|KaiOS)\b/.test(os)) {
name = 'Firefox Mobile';
}
// Obscure Maxthon's unreliable version.
else if (name == 'Maxthon' && version) {
version = version.replace(/\.[\d.]+/, '.x');
}
// Detect Xbox 360 and Xbox One.
else if (/\bXbox\b/i.test(product)) {
if (product == 'Xbox 360') {
os = null;
}
if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) {
description.unshift('mobile mode');
}
}
// Add mobile postfix.
else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) &&
(os == 'Windows CE' || /Mobi/i.test(ua))) {
name += ' Mobile';
}
// Detect IE platform preview.
else if (name == 'IE' && useFeatures) {
try {
if (context.external === null) {
description.unshift('platform preview');
}
} catch(e) {
description.unshift('embedded');
}
}
// Detect BlackBerry OS version.
// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data =
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
version
)) {
data = [data, /BB10/.test(ua)];
os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
version = null;
}
// Detect Opera identifying/masking itself as another browser.
// http://www.opera.com/support/kb/view/843/
else if (this != forOwn && product != 'Wii' && (
(useFeatures && opera) ||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
(name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) ||
(name == 'IE' && (
(os && !/^Win/.test(os) && version > 5.5) ||
/\bWindows XP\b/.test(os) && version > 8 ||
version == 8 && !/\bTrident\b/.test(ua)
))
) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {
// When "identifying", the UA contains both Opera and the other browser's name.
data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
if (reOpera.test(name)) {
if (/\bIE\b/.test(data) && os == 'Mac OS') {
os = null;
}
data = 'identify' + data;
}
// When "masking", the UA contains only the other browser's name.
else {
data = 'mask' + data;
if (operaClass) {
name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
} else {
name = 'Opera';
}
if (/\bIE\b/.test(data)) {
os = null;
}
if (!useFeatures) {
version = null;
}
}
layout = ['Presto'];
description.push(data);
}
// Detect WebKit Nightly and approximate Chrome/Safari versions.
if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
// Correct build number for numeric comparison.
// (e.g. "532.5" becomes "532.05")
data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
// Nightly builds are postfixed with a "+".
if (name == 'Safari' && data[1].slice(-1) == '+') {
name = 'WebKit Nightly';
prerelease = 'alpha';
version = data[1].slice(0, -1);
}
// Clear incorrect browser versions.
else if (version == data[1] ||
version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
version = null;
}
// Use the full Chrome version when available.
data[1] = (/\b(?:Headless)?Chrome\/([\d.]+)/i.exec(ua) || 0)[1];
// Detect Blink layout engine.
if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') {
layout = ['Blink'];
}
// Detect JavaScriptCore.
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
if (!useFeatures || (!likeChrome && !data[1])) {
layout && (layout[1] = 'like Safari');
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : data < 602 ? 9 : data < 604 ? 10 : data < 606 ? 11 : data < 608 ? 12 : '12');
} else {
layout && (layout[1] = 'like Chrome');
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28');
}
// Add the postfix of ".x" or "+" for approximate versions.
layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'));
// Obscure version for some Safari 1-2 releases.
if (name == 'Safari' && (!version || parseInt(version) > 45)) {
version = data;
} else if (name == 'Chrome' && /\bHeadlessChrome/i.test(ua)) {
description.unshift('headless');
}
}
// Detect Opera desktop modes.
if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) {
name += ' ';
description.unshift('desktop mode');
if (data == 'zvav') {
name += 'Mini';
version = null;
} else {
name += 'Mobile';
}
os = os.replace(RegExp(' *' + data + '$'), '');
}
// Detect Chrome desktop mode.
else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) {
description.unshift('desktop mode');
name = 'Chrome Mobile';
version = null;
if (/\bOS X\b/.test(os)) {
manufacturer = 'Apple';
os = 'iOS 4.3+';
} else {
os = null;
}
}
// Newer versions of SRWare Iron uses the Chrome tag to indicate its version number.
else if (/\bSRWare Iron\b/.test(name) && !version) {
version = getVersion('Chrome');
}
// Strip incorrect OS versions.
if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
ua.indexOf('/' + data + '-') > -1) {
os = trim(os.replace(data, ''));
}
// Ensure OS does not include the browser name.
if (os && os.indexOf(name) != -1 && !RegExp(name + ' OS').test(os)) {
os = os.replace(RegExp(' *' + qualify(name) + ' *'), '');
}
// Add layout engine.
if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
/Browser|Lunascape|Maxthon/.test(name) ||
name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) ||
/^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|SRWare Iron|Vivaldi|Web)/.test(name) && layout[1])) {
// Don't add layout details to description if they are falsey.
(data = layout[layout.length - 1]) && description.push(data);
}
// Combine contextual information.
if (description.length) {
description = ['(' + description.join('; ') + ')'];
}
// Append manufacturer to description.
if (manufacturer && product && product.indexOf(manufacturer) < 0) {
description.push('on ' + manufacturer);
}
// Append product to description.
if (product) {
description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product);
}
// Parse the OS into an object.
if (os) {
data = / ([\d.+]+)$/.exec(os);
isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/';
os = {
'architecture': 32,
'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os,
'version': data ? data[1] : null,
'toString': function() {
var version = this.version;
return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
}
};
}
// Add browser/OS architecture.
if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
if (os) {
os.architecture = 64;
os.family = os.family.replace(RegExp(' *' + data), '');
}
if (
name && (/\bWOW64\b/i.test(ua) ||
(useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua)))
) {
description.unshift('32-bit');
}
}
// Chrome 39 and above on OS X is always 64-bit.
else if (
os && /^OS X/.test(os.family) &&
name == 'Chrome' && parseFloat(version) >= 39
) {
os.architecture = 64;
}
ua || (ua = null);
/*------------------------------------------------------------------------*/
/**
* The platform object.
*
* @name platform
* @type Object
*/
var platform = {};
/**
* The platform description.
*
* @memberOf platform
* @type string|null
*/
platform.description = ua;
/**
* The name of the browser's layout engine.
*
* The list of common layout engines include:
* "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit"
*
* @memberOf platform
* @type string|null
*/
platform.layout = layout && layout[0];
/**
* The name of the product's manufacturer.
*
* The list of manufacturers include:
* "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry",
* "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo",
* "Nokia", "Samsung" and "Sony"
*
* @memberOf platform
* @type string|null
*/
platform.manufacturer = manufacturer;
/**
* The name of the browser/environment.
*
* The list of common browser names include:
* "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE",
* "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk",
* "Opera Mini" and "Opera"
*
* Mobile versions of some browsers have "Mobile" appended to their name:
* eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile"
*
* @memberOf platform
* @type string|null
*/
platform.name = name;
/**
* The alpha/beta release indicator.
*
* @memberOf platform
* @type string|null
*/
platform.prerelease = prerelease;
/**
* The name of the product hosting the browser.
*
* The list of common products include:
*
* "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle",
* "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer"
*
* @memberOf platform
* @type string|null
*/
platform.product = product;
/**
* The browser's user agent string.
*
* @memberOf platform
* @type string|null
*/
platform.ua = ua;
/**
* The browser/environment version.
*
* @memberOf platform
* @type string|null
*/
platform.version = name && version;
/**
* The name of the operating system.
*
* @memberOf platform
* @type Object
*/
platform.os = os || {
/**
* The CPU architecture the OS is built for.
*
* @memberOf platform.os
* @type number|null
*/
'architecture': null,
/**
* The family of the OS.
*
* Common values include:
* "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista",
* "Windows XP", "OS X", "Linux", "Ubuntu", "Debian", "Fedora", "Red Hat",
* "SuSE", "Android", "iOS" and "Windows Phone"
*
* @memberOf platform.os
* @type string|null
*/
'family': null,
/**
* The version of the OS.
*
* @memberOf platform.os
* @type string|null
*/
'version': null,
/**
* Returns the OS string.
*
* @memberOf platform.os
* @returns {string} The OS string.
*/
'toString': function() { return 'null'; }
};
platform.parse = parse;
platform.toString = toStringPlatform;
if (platform.version) {
description.unshift(version);
}
if (platform.name) {
description.unshift(name);
}
if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) {
description.push(product ? '(' + os + ')' : 'on ' + os);
}
if (description.length) {
platform.description = description.join(' ');
}
return platform;
}
/*--------------------------------------------------------------------------*/
// Export platform.
var platform = parse();
// Some AMD build optimizers, like r.js, check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// Expose platform on the global object to prevent errors when platform is
// loaded by a script tag in the presence of an AMD loader.
// See http://requirejs.org/docs/errors.html#mismatch for more details.
root.platform = platform;
// Define as an anonymous module so platform can be aliased through path mapping.
define(function() {
return platform;
});
}
// Check for `exports` after `define` in case a build optimizer adds an `exports` object.
else if (freeExports && freeModule) {
// Export for CommonJS support.
forOwn(platform, function(value, key) {
freeExports[key] = value;
});
}
else {
// Export to the global object.
root.platform = platform;
}
}.call(this));
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],13:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],14:[function(require,module,exports){
const debug = require('../internal/debug')
const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
const { re, t } = require('../internal/re')
const parseOptions = require('../internal/parse-options')
const { compareIdentifiers } = require('../internal/identifiers')
class SemVer {
constructor (version, options) {
options = parseOptions(options)
if (version instanceof SemVer) {
if (version.loose === !!options.loose &&
version.includePrerelease === !!options.includePrerelease) {
return version
} else {
version = version.version
}
} else if (typeof version !== 'string') {
throw new TypeError(`Invalid Version: ${version}`)
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`
)
}
debug('SemVer', version, options)
this.options = options
this.loose = !!options.loose
// this isn't actually relevant for versions, but keep it so that we
// don't run into trouble passing this.options around.
this.includePrerelease = !!options.includePrerelease
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
if (!m) {
throw new TypeError(`Invalid Version: ${version}`)
}
this.raw = version
// these are actually numbers
this.major = +m[1]
this.minor = +m[2]
this.patch = +m[3]
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
throw new TypeError('Invalid major version')
}
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
throw new TypeError('Invalid minor version')
}
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
throw new TypeError('Invalid patch version')
}
// numberify any prerelease numeric ids
if (!m[4]) {
this.prerelease = []
} else {
this.prerelease = m[4].split('.').map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id
if (num >= 0 && num < MAX_SAFE_INTEGER) {
return num
}
}
return id
})
}
this.build = m[5] ? m[5].split('.') : []
this.format()
}
format () {
this.version = `${this.major}.${this.minor}.${this.patch}`
if (this.prerelease.length) {
this.version += `-${this.prerelease.join('.')}`
}
return this.version
}
toString () {
return this.version
}
compare (other) {
debug('SemVer.compare', this.version, this.options, other)
if (!(other instanceof SemVer)) {
if (typeof other === 'string' && other === this.version) {
return 0
}
other = new SemVer(other, this.options)
}
if (other.version === this.version) {
return 0
}
return this.compareMain(other) || this.comparePre(other)
}
compareMain (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
return (
compareIdentifiers(this.major, other.major) ||
compareIdentifiers(this.minor, other.minor) ||
compareIdentifiers(this.patch, other.patch)
)
}
comparePre (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
// NOT having a prerelease is > having one
if (this.prerelease.length && !other.prerelease.length) {
return -1
} else if (!this.prerelease.length && other.prerelease.length) {
return 1
} else if (!this.prerelease.length && !other.prerelease.length) {
return 0
}
let i = 0
do {
const a = this.prerelease[i]
const b = other.prerelease[i]
debug('prerelease compare', i, a, b)
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
compareBuild (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
let i = 0
do {
const a = this.build[i]
const b = other.build[i]
debug('prerelease compare', i, a, b)
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier) {
switch (release) {
case 'premajor':
this.prerelease.length = 0
this.patch = 0
this.minor = 0
this.major++
this.inc('pre', identifier)
break
case 'preminor':
this.prerelease.length = 0
this.patch = 0
this.minor++
this.inc('pre', identifier)
break
case 'prepatch':
// If this is already a prerelease, it will bump to the next version
// drop any prereleases that might already exist, since they are not
// relevant at this point.
this.prerelease.length = 0
this.inc('patch', identifier)
this.inc('pre', identifier)
break
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case 'prerelease':
if (this.prerelease.length === 0) {
this.inc('patch', identifier)
}
this.inc('pre', identifier)
break
case 'major':
// If this is a pre-major version, bump up to the same major version.
// Otherwise increment major.
// 1.0.0-5 bumps to 1.0.0
// 1.1.0 bumps to 2.0.0
if (
this.minor !== 0 ||
this.patch !== 0 ||
this.prerelease.length === 0
) {
this.major++
}
this.minor = 0
this.patch = 0
this.prerelease = []
break
case 'minor':
// If this is a pre-minor version, bump up to the same minor version.
// Otherwise increment minor.
// 1.2.0-5 bumps to 1.2.0
// 1.2.1 bumps to 1.3.0
if (this.patch !== 0 || this.prerelease.length === 0) {
this.minor++
}
this.patch = 0
this.prerelease = []
break
case 'patch':
// If this is not a pre-release version, it will increment the patch.
// If it is a pre-release it will bump up to the same patch version.
// 1.2.0-5 patches to 1.2.0
// 1.2.0 patches to 1.2.1
if (this.prerelease.length === 0) {
this.patch++
}
this.prerelease = []
break
// This probably shouldn't be used publicly.
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
case 'pre':
if (this.prerelease.length === 0) {
this.prerelease = [0]
} else {
let i = this.prerelease.length
while (--i >= 0) {
if (typeof this.prerelease[i] === 'number') {
this.prerelease[i]++
i = -2
}
}
if (i === -1) {
// didn't increment anything
this.prerelease.push(0)
}
}
if (identifier) {
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = [identifier, 0]
}
} else {
this.prerelease = [identifier, 0]
}
}
break
default:
throw new Error(`invalid increment argument: ${release}`)
}
this.format()
this.raw = this.version
return this
}
}
module.exports = SemVer
},{"../internal/constants":17,"../internal/debug":18,"../internal/identifiers":19,"../internal/parse-options":20,"../internal/re":21}],15:[function(require,module,exports){
const SemVer = require('../classes/semver')
const major = (a, loose) => new SemVer(a, loose).major
module.exports = major
},{"../classes/semver":14}],16:[function(require,module,exports){
const SemVer = require('../classes/semver')
const minor = (a, loose) => new SemVer(a, loose).minor
module.exports = minor
},{"../classes/semver":14}],17:[function(require,module,exports){
// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0'
const MAX_LENGTH = 256
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991
// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16
module.exports = {
SEMVER_SPEC_VERSION,
MAX_LENGTH,
MAX_SAFE_INTEGER,
MAX_SAFE_COMPONENT_LENGTH,
}
},{}],18:[function(require,module,exports){
(function (process){(function (){
const debug = (
typeof process === 'object' &&
process.env &&
process.env.NODE_DEBUG &&
/\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
: () => {}
module.exports = debug
}).call(this)}).call(this,require('_process'))
},{"_process":13}],19:[function(require,module,exports){
const numeric = /^[0-9]+$/
const compareIdentifiers = (a, b) => {
const anum = numeric.test(a)
const bnum = numeric.test(b)
if (anum && bnum) {
a = +a
b = +b
}
return a === b ? 0
: (anum && !bnum) ? -1
: (bnum && !anum) ? 1
: a < b ? -1
: 1
}
const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a)
module.exports = {
compareIdentifiers,
rcompareIdentifiers,
}
},{}],20:[function(require,module,exports){
// parse out just the options we care about so we always get a consistent
// obj with keys in a consistent order.
const opts = ['includePrerelease', 'loose', 'rtl']
const parseOptions = options =>
!options ? {}
: typeof options !== 'object' ? { loose: true }
: opts.filter(k => options[k]).reduce((o, k) => {
o[k] = true
return o
}, {})
module.exports = parseOptions
},{}],21:[function(require,module,exports){
const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants')
const debug = require('./debug')
exports = module.exports = {}
// The actual regexps go on exports.re
const re = exports.re = []
const src = exports.src = []
const t = exports.t = {}
let R = 0
const createToken = (name, value, isGlobal) => {
const index = R++
debug(name, index, value)
t[name] = index
src[index] = value
re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
}
// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.
// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*')
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+')
// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*')
// ## Main Version
// Three dot-separated numeric identifiers.
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})`)
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})`)
// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`)
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`)
// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`)
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`)
// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+')
// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`)
// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.
// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups. The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
src[t.BUILD]}?`)
createToken('FULL', `^${src[t.FULLPLAIN]}$`)
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
src[t.BUILD]}?`)
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`)
createToken('GTLT', '((?:<|>)?=?)')
// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`)
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`)
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:${src[t.PRERELEASE]})?${
src[t.BUILD]}?` +
`)?)?`)
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:${src[t.PRERELEASELOOSE]})?${
src[t.BUILD]}?` +
`)?)?`)
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`)
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`)
// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:$|[^\\d])`)
createToken('COERCERTL', src[t.COERCE], true)
// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)')
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true)
exports.tildeTrimReplace = '$1~'
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`)
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`)
// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)')
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true)
exports.caretTrimReplace = '$1^'
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`)
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`)
// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`)
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`)
// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true)
exports.comparatorTrimReplace = '$1$2$3'
// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAIN]})` +
`\\s*$`)
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAINLOOSE]})` +
`\\s*$`)
// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*')
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')
},{"./constants":17,"./debug":18}],22:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "v1", {
enumerable: true,
get: function () {
return _v.default;
}
});
Object.defineProperty(exports, "v3", {
enumerable: true,
get: function () {
return _v2.default;
}
});
Object.defineProperty(exports, "v4", {
enumerable: true,
get: function () {
return _v3.default;
}
});
Object.defineProperty(exports, "v5", {
enumerable: true,
get: function () {
return _v4.default;
}
});
Object.defineProperty(exports, "NIL", {
enumerable: true,
get: function () {
return _nil.default;
}
});
Object.defineProperty(exports, "version", {
enumerable: true,
get: function () {
return _version.default;
}
});
Object.defineProperty(exports, "validate", {
enumerable: true,
get: function () {
return _validate.default;
}
});
Object.defineProperty(exports, "stringify", {
enumerable: true,
get: function () {
return _stringify.default;
}
});
Object.defineProperty(exports, "parse", {
enumerable: true,
get: function () {
return _parse.default;
}
});
var _v = _interopRequireDefault(require("./v1.js"));
var _v2 = _interopRequireDefault(require("./v3.js"));
var _v3 = _interopRequireDefault(require("./v4.js"));
var _v4 = _interopRequireDefault(require("./v5.js"));
var _nil = _interopRequireDefault(require("./nil.js"));
var _version = _interopRequireDefault(require("./version.js"));
var _validate = _interopRequireDefault(require("./validate.js"));
var _stringify = _interopRequireDefault(require("./stringify.js"));
var _parse = _interopRequireDefault(require("./parse.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
},{"./nil.js":24,"./parse.js":25,"./stringify.js":29,"./v1.js":30,"./v3.js":31,"./v4.js":33,"./v5.js":34,"./validate.js":35,"./version.js":36}],23:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/*
* Browser-compatible JavaScript MD5
*
* Modification of JavaScript MD5
* https://github.com/blueimp/JavaScript-MD5
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*
* Based on
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
function md5(bytes) {
if (typeof bytes === 'string') {
const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
bytes = new Uint8Array(msg.length);
for (let i = 0; i < msg.length; ++i) {
bytes[i] = msg.charCodeAt(i);
}
}
return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8));
}
/*
* Convert an array of little-endian words to an array of bytes
*/
function md5ToHexEncodedArray(input) {
const output = [];
const length32 = input.length * 32;
const hexTab = '0123456789abcdef';
for (let i = 0; i < length32; i += 8) {
const x = input[i >> 5] >>> i % 32 & 0xff;
const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16);
output.push(hex);
}
return output;
}
/**
* Calculate output length with padding and bit length
*/
function getOutputLength(inputLength8) {
return (inputLength8 + 64 >>> 9 << 4) + 14 + 1;
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length.
*/
function wordsToMd5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << len % 32;
x[getOutputLength(len) - 1] = len;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for (let i = 0; i < x.length; i += 16) {
const olda = a;
const oldb = b;
const oldc = c;
const oldd = d;
a = md5ff(a, b, c, d, x[i], 7, -680876936);
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5gg(b, c, d, a, x[i], 20, -373897302);
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5hh(d, a, b, c, x[i], 11, -358537222);
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5ii(a, b, c, d, x[i], 6, -198630844);
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safeAdd(a, olda);
b = safeAdd(b, oldb);
c = safeAdd(c, oldc);
d = safeAdd(d, oldd);
}
return [a, b, c, d];
}
/*
* Convert an array bytes to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*/
function bytesToWords(input) {
if (input.length === 0) {
return [];
}
const length8 = input.length * 8;
const output = new Uint32Array(getOutputLength(length8));
for (let i = 0; i < length8; i += 8) {
output[i >> 5] |= (input[i / 8] & 0xff) << i % 32;
}
return output;
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safeAdd(x, y) {
const lsw = (x & 0xffff) + (y & 0xffff);
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return msw << 16 | lsw & 0xffff;
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bitRotateLeft(num, cnt) {
return num << cnt | num >>> 32 - cnt;
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5cmn(q, a, b, x, s, t) {
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
}
function md5ff(a, b, c, d, x, s, t) {
return md5cmn(b & c | ~b & d, a, b, x, s, t);
}
function md5gg(a, b, c, d, x, s, t) {
return md5cmn(b & d | c & ~d, a, b, x, s, t);
}
function md5hh(a, b, c, d, x, s, t) {
return md5cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5ii(a, b, c, d, x, s, t) {
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
}
var _default = md5;
exports.default = _default;
},{}],24:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = '00000000-0000-0000-0000-000000000000';
exports.default = _default;
},{}],25:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _validate = _interopRequireDefault(require("./validate.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function parse(uuid) {
if (!(0, _validate.default)(uuid)) {
throw TypeError('Invalid UUID');
}
let v;
const arr = new Uint8Array(16); // Parse ########-....-....-....-............
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
arr[1] = v >>> 16 & 0xff;
arr[2] = v >>> 8 & 0xff;
arr[3] = v & 0xff; // Parse ........-####-....-....-............
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
arr[5] = v & 0xff; // Parse ........-....-####-....-............
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
arr[7] = v & 0xff; // Parse ........-....-....-####-............
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
arr[9] = v & 0xff; // Parse ........-....-....-....-############
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
arr[11] = v / 0x100000000 & 0xff;
arr[12] = v >>> 24 & 0xff;
arr[13] = v >>> 16 & 0xff;
arr[14] = v >>> 8 & 0xff;
arr[15] = v & 0xff;
return arr;
}
var _default = parse;
exports.default = _default;
},{"./validate.js":35}],26:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
exports.default = _default;
},{}],27:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = rng;
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
let getRandomValues;
const rnds8 = new Uint8Array(16);
function rng() {
// lazy load so that environments that need to polyfill have a chance to do so
if (!getRandomValues) {
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
if (!getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
}
return getRandomValues(rnds8);
}
},{}],28:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
// Adapted from Chris Veness' SHA1 code at
// http://www.movable-type.co.uk/scripts/sha1.html
function f(s, x, y, z) {
switch (s) {
case 0:
return x & y ^ ~x & z;
case 1:
return x ^ y ^ z;
case 2:
return x & y ^ x & z ^ y & z;
case 3:
return x ^ y ^ z;
}
}
function ROTL(x, n) {
return x << n | x >>> 32 - n;
}
function sha1(bytes) {
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
if (typeof bytes === 'string') {
const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
bytes = [];
for (let i = 0; i < msg.length; ++i) {
bytes.push(msg.charCodeAt(i));
}
} else if (!Array.isArray(bytes)) {
// Convert Array-like to Array
bytes = Array.prototype.slice.call(bytes);
}
bytes.push(0x80);
const l = bytes.length / 4 + 2;
const N = Math.ceil(l / 16);
const M = new Array(N);
for (let i = 0; i < N; ++i) {
const arr = new Uint32Array(16);
for (let j = 0; j < 16; ++j) {
arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3];
}
M[i] = arr;
}
M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);
M[N - 1][14] = Math.floor(M[N - 1][14]);
M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;
for (let i = 0; i < N; ++i) {
const W = new Uint32Array(80);
for (let t = 0; t < 16; ++t) {
W[t] = M[i][t];
}
for (let t = 16; t < 80; ++t) {
W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
let a = H[0];
let b = H[1];
let c = H[2];
let d = H[3];
let e = H[4];
for (let t = 0; t < 80; ++t) {
const s = Math.floor(t / 20);
const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0;
e = d;
d = c;
c = ROTL(b, 30) >>> 0;
b = a;
a = T;
}
H[0] = H[0] + a >>> 0;
H[1] = H[1] + b >>> 0;
H[2] = H[2] + c >>> 0;
H[3] = H[3] + d >>> 0;
H[4] = H[4] + e >>> 0;
}
return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff];
}
var _default = sha1;
exports.default = _default;
},{}],29:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _validate = _interopRequireDefault(require("./validate.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).substr(1));
}
function stringify(arr, offset = 0) {
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
// of the following:
// - One or more input array values don't map to a hex octet (leading to
// "undefined" in the uuid)
// - Invalid input values for the RFC `version` or `variant` fields
if (!(0, _validate.default)(uuid)) {
throw TypeError('Stringified UUID is invalid');
}
return uuid;
}
var _default = stringify;
exports.default = _default;
},{"./validate.js":35}],30:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _rng = _interopRequireDefault(require("./rng.js"));
var _stringify = _interopRequireDefault(require("./stringify.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html
let _nodeId;
let _clockseq; // Previous uuid creation time
let _lastMSecs = 0;
let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
function v1(options, buf, offset) {
let i = buf && offset || 0;
const b = buf || new Array(16);
options = options || {};
let node = options.node || _nodeId;
let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
// specified. We do this lazily to minimize issues related to insufficient
// system entropy. See #189
if (node == null || clockseq == null) {
const seedBytes = options.random || (options.rng || _rng.default)();
if (node == null) {
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
}
if (clockseq == null) {
// Per 4.2.2, randomize (14 bit) clockseq
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
}
} // UUID timestamps are 100 nano-second units since the Gregorian epoch,
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
// cycle to simulate higher resolution clock
let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
if (dt < 0 && options.clockseq === undefined) {
clockseq = clockseq + 1 & 0x3fff;
} // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
// time interval
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
nsecs = 0;
} // Per 4.2.1.2 Throw error if too many uuids are requested
if (nsecs >= 10000) {
throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
}
_lastMSecs = msecs;
_lastNSecs = nsecs;
_clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
msecs += 12219292800000; // `time_low`
const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
b[i++] = tl >>> 24 & 0xff;
b[i++] = tl >>> 16 & 0xff;
b[i++] = tl >>> 8 & 0xff;
b[i++] = tl & 0xff; // `time_mid`
const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
b[i++] = tmh >>> 8 & 0xff;
b[i++] = tmh & 0xff; // `time_high_and_version`
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
b[i++] = clockseq & 0xff; // `node`
for (let n = 0; n < 6; ++n) {
b[i + n] = node[n];
}
return buf || (0, _stringify.default)(b);
}
var _default = v1;
exports.default = _default;
},{"./rng.js":27,"./stringify.js":29}],31:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _v = _interopRequireDefault(require("./v35.js"));
var _md = _interopRequireDefault(require("./md5.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const v3 = (0, _v.default)('v3', 0x30, _md.default);
var _default = v3;
exports.default = _default;
},{"./md5.js":23,"./v35.js":32}],32:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
exports.URL = exports.DNS = void 0;
var _stringify = _interopRequireDefault(require("./stringify.js"));
var _parse = _interopRequireDefault(require("./parse.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function stringToBytes(str) {
str = unescape(encodeURIComponent(str)); // UTF8 escape
const bytes = [];
for (let i = 0; i < str.length; ++i) {
bytes.push(str.charCodeAt(i));
}
return bytes;
}
const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
exports.DNS = DNS;
const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
exports.URL = URL;
function _default(name, version, hashfunc) {
function generateUUID(value, namespace, buf, offset) {
if (typeof value === 'string') {
value = stringToBytes(value);
}
if (typeof namespace === 'string') {
namespace = (0, _parse.default)(namespace);
}
if (namespace.length !== 16) {
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
} // Compute hash of namespace and value, Per 4.3
// Future: Use spread syntax when supported on all platforms, e.g. `bytes =
// hashfunc([...namespace, ... value])`
let bytes = new Uint8Array(16 + value.length);
bytes.set(namespace);
bytes.set(value, namespace.length);
bytes = hashfunc(bytes);
bytes[6] = bytes[6] & 0x0f | version;
bytes[8] = bytes[8] & 0x3f | 0x80;
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = bytes[i];
}
return buf;
}
return (0, _stringify.default)(bytes);
} // Function#name is not settable on some platforms (#270)
try {
generateUUID.name = name; // eslint-disable-next-line no-empty
} catch (err) {} // For CommonJS default export support
generateUUID.DNS = DNS;
generateUUID.URL = URL;
return generateUUID;
}
},{"./parse.js":25,"./stringify.js":29}],33:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _rng = _interopRequireDefault(require("./rng.js"));
var _stringify = _interopRequireDefault(require("./stringify.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function v4(options, buf, offset) {
options = options || {};
const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = rnds[6] & 0x0f | 0x40;
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return (0, _stringify.default)(rnds);
}
var _default = v4;
exports.default = _default;
},{"./rng.js":27,"./stringify.js":29}],34:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _v = _interopRequireDefault(require("./v35.js"));
var _sha = _interopRequireDefault(require("./sha1.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const v5 = (0, _v.default)('v5', 0x50, _sha.default);
var _default = v5;
exports.default = _default;
},{"./sha1.js":28,"./v35.js":32}],35:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _regex = _interopRequireDefault(require("./regex.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function validate(uuid) {
return typeof uuid === 'string' && _regex.default.test(uuid);
}
var _default = validate;
exports.default = _default;
},{"./regex.js":26}],36:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _validate = _interopRequireDefault(require("./validate.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function version(uuid) {
if (!(0, _validate.default)(uuid)) {
throw TypeError('Invalid UUID');
}
return parseInt(uuid.substr(14, 1), 16);
}
var _default = version;
exports.default = _default;
},{"./validate.js":35}],37:[function(require,module,exports){
/*
WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based
on @visionmedia's Emitter from UI Kit.
Why? I wanted it standalone.
I also wanted support for wildcard emitters like this:
emitter.on('*', function (eventName, other, event, payloads) {
});
emitter.on('somenamespace*', function (eventName, payloads) {
});
Please note that callbacks triggered by wildcard registered events also get
the event name as the first argument.
*/
module.exports = WildEmitter;
function WildEmitter() { }
WildEmitter.mixin = function (constructor) {
var prototype = constructor.prototype || constructor;
prototype.isWildEmitter= true;
// Listen on the given `event` with `fn`. Store a group name if present.
prototype.on = function (event, groupName, fn) {
this.callbacks = this.callbacks || {};
var hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
func._groupName = group;
(this.callbacks[event] = this.callbacks[event] || []).push(func);
return this;
};
// Adds an `event` listener that will be invoked a single
// time then automatically removed.
prototype.once = function (event, groupName, fn) {
var self = this,
hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
function on() {
self.off(event, on);
func.apply(this, arguments);
}
this.on(event, group, on);
return this;
};
// Unbinds an entire group
prototype.releaseGroup = function (groupName) {
this.callbacks = this.callbacks || {};
var item, i, len, handlers;
for (item in this.callbacks) {
handlers = this.callbacks[item];
for (i = 0, len = handlers.length; i < len; i++) {
if (handlers[i]._groupName === groupName) {
//console.log('removing');
// remove it and shorten the array we're looping through
handlers.splice(i, 1);
i--;
len--;
}
}
}
return this;
};
// Remove the given callback for `event` or all
// registered callbacks.
prototype.off = function (event, fn) {
this.callbacks = this.callbacks || {};
var callbacks = this.callbacks[event],
i;
if (!callbacks) return this;
// remove all handlers
if (arguments.length === 1) {
delete this.callbacks[event];
return this;
}
// remove specific handler
i = callbacks.indexOf(fn);
if (i !== -1) {
callbacks.splice(i, 1);
if (callbacks.length === 0) {
delete this.callbacks[event];
}
}
return this;
};
/// Emit `event` with the given args.
// also calls any `*` handlers
prototype.emit = function (event) {
this.callbacks = this.callbacks || {};
var args = [].slice.call(arguments, 1),
callbacks = this.callbacks[event],
specialCallbacks = this.getWildcardCallbacks(event),
i,
len,
item,
listeners;
if (callbacks) {
listeners = callbacks.slice();
for (i = 0, len = listeners.length; i < len; ++i) {
if (!listeners[i]) {
break;
}
listeners[i].apply(this, args);
}
}
if (specialCallbacks) {
len = specialCallbacks.length;
listeners = specialCallbacks.slice();
for (i = 0, len = listeners.length; i < len; ++i) {
if (!listeners[i]) {
break;
}
listeners[i].apply(this, [event].concat(args));
}
}
return this;
};
// Helper for for finding special wildcard event handlers that match the event
prototype.getWildcardCallbacks = function (eventName) {
this.callbacks = this.callbacks || {};
var item,
split,
result = [];
for (item in this.callbacks) {
split = item.split('*');
if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) {
result = result.concat(this.callbacks[item]);
}
}
return result;
};
};
WildEmitter.mixin(WildEmitter);
},{}],38:[function(require,module,exports){
/*!
* EventEmitter v5.2.9 - git.io/ee
* Unlicense - http://unlicense.org/
* Oliver Caldwell - https://oli.me.uk/
* @preserve
*/
;(function (exports) {
'use strict';
/**
* Class for managing events.
* Can be extended to provide event functionality in other classes.
*
* @class EventEmitter Manages event registering and emitting.
*/
function EventEmitter() {}
// Shortcuts to improve speed and size
var proto = EventEmitter.prototype;
var originalGlobalValue = exports.EventEmitter;
/**
* Finds the index of the listener for the event in its storage array.
*
* @param {Function[]} listeners Array of listeners to search through.
* @param {Function} listener Method to look for.
* @return {Number} Index of the specified listener, -1 if not found
* @api private
*/
function indexOfListener(listeners, listener) {
var i = listeners.length;
while (i--) {
if (listeners[i].listener === listener) {
return i;
}
}
return -1;
}
/**
* Alias a method while keeping the context correct, to allow for overwriting of target method.
*
* @param {String} name The name of the target method.
* @return {Function} The aliased method
* @api private
*/
function alias(name) {
return function aliasClosure() {
return this[name].apply(this, arguments);
};
}
/**
* Returns the listener array for the specified event.
* Will initialise the event object and listener arrays if required.
* Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
* Each property in the object response is an array of listener functions.
*
* @param {String|RegExp} evt Name of the event to return the listeners from.
* @return {Function[]|Object} All listener functions for the event.
*/
proto.getListeners = function getListeners(evt) {
var events = this._getEvents();
var response;
var key;
// Return a concatenated array of all matching events if
// the selector is a regular expression.
if (evt instanceof RegExp) {
response = {};
for (key in events) {
if (events.hasOwnProperty(key) && evt.test(key)) {
response[key] = events[key];
}
}
}
else {
response = events[evt] || (events[evt] = []);
}
return response;
};
/**
* Takes a list of listener objects and flattens it into a list of listener functions.
*
* @param {Object[]} listeners Raw listener objects.
* @return {Function[]} Just the listener functions.
*/
proto.flattenListeners = function flattenListeners(listeners) {
var flatListeners = [];
var i;
for (i = 0; i < listeners.length; i += 1) {
flatListeners.push(listeners[i].listener);
}
return flatListeners;
};
/**
* Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
*
* @param {String|RegExp} evt Name of the event to return the listeners from.
* @return {Object} All listener functions for an event in an object.
*/
proto.getListenersAsObject = function getListenersAsObject(evt) {
var listeners = this.getListeners(evt);
var response;
if (listeners instanceof Array) {
response = {};
response[evt] = listeners;
}
return response || listeners;
};
function isValidListener (listener) {
if (typeof listener === 'function' || listener instanceof RegExp) {
return true
} else if (listener && typeof listener === 'object') {
return isValidListener(listener.listener)
} else {
return false
}
}
/**
* Adds a listener function to the specified event.
* The listener will not be added if it is a duplicate.
* If the listener returns true then it will be removed after it is called.
* If you pass a regular expression as the event name then the listener will be added to all events that match it.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addListener = function addListener(evt, listener) {
if (!isValidListener(listener)) {
throw new TypeError('listener must be a function');
}
var listeners = this.getListenersAsObject(evt);
var listenerIsWrapped = typeof listener === 'object';
var key;
for (key in listeners) {
if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
listeners[key].push(listenerIsWrapped ? listener : {
listener: listener,
once: false
});
}
}
return this;
};
/**
* Alias of addListener
*/
proto.on = alias('addListener');
/**
* Semi-alias of addListener. It will add a listener that will be
* automatically removed after its first execution.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addOnceListener = function addOnceListener(evt, listener) {
return this.addListener(evt, {
listener: listener,
once: true
});
};
/**
* Alias of addOnceListener.
*/
proto.once = alias('addOnceListener');
/**
* Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
* You need to tell it what event names should be matched by a regex.
*
* @param {String} evt Name of the event to create.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.defineEvent = function defineEvent(evt) {
this.getListeners(evt);
return this;
};
/**
* Uses defineEvent to define multiple events.
*
* @param {String[]} evts An array of event names to define.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.defineEvents = function defineEvents(evts) {
for (var i = 0; i < evts.length; i += 1) {
this.defineEvent(evts[i]);
}
return this;
};
/**
* Removes a listener function from the specified event.
* When passed a regular expression as the event name, it will remove the listener from all events that match it.
*
* @param {String|RegExp} evt Name of the event to remove the listener from.
* @param {Function} listener Method to remove from the event.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeListener = function removeListener(evt, listener) {
var listeners = this.getListenersAsObject(evt);
var index;
var key;
for (key in listeners) {
if (listeners.hasOwnProperty(key)) {
index = indexOfListener(listeners[key], listener);
if (index !== -1) {
listeners[key].splice(index, 1);
}
}
}
return this;
};
/**
* Alias of removeListener
*/
proto.off = alias('removeListener');
/**
* Adds listeners in bulk using the manipulateListeners method.
* If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
* You can also pass it a regular expression to add the array of listeners to all events that match it.
* Yeah, this function does quite a bit. That's probably a bad thing.
*
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to add.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addListeners = function addListeners(evt, listeners) {
// Pass through to manipulateListeners
return this.manipulateListeners(false, evt, listeners);
};
/**
* Removes listeners in bulk using the manipulateListeners method.
* If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
* You can also pass it an event name and an array of listeners to be removed.
* You can also pass it a regular expression to remove the listeners from all events that match it.
*
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to remove.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeListeners = function removeListeners(evt, listeners) {
// Pass through to manipulateListeners
return this.manipulateListeners(true, evt, listeners);
};
/**
* Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
* The first argument will determine if the listeners are removed (true) or added (false).
* If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
* You can also pass it an event name and an array of listeners to be added/removed.
* You can also pass it a regular expression to manipulate the listeners of all events that match it.
*
* @param {Boolean} remove True if you want to remove listeners, false if you want to add.
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to add/remove.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
var i;
var value;
var single = remove ? this.removeListener : this.addListener;
var multiple = remove ? this.removeListeners : this.addListeners;
// If evt is an object then pass each of its properties to this method
if (typeof evt === 'object' && !(evt instanceof RegExp)) {
for (i in evt) {
if (evt.hasOwnProperty(i) && (value = evt[i])) {
// Pass the single listener straight through to the singular method
if (typeof value === 'function') {
single.call(this, i, value);
}
else {
// Otherwise pass back to the multiple function
multiple.call(this, i, value);
}
}
}
}
else {
// So evt must be a string
// And listeners must be an array of listeners
// Loop over it and pass each one to the multiple method
i = listeners.length;
while (i--) {
single.call(this, evt, listeners[i]);
}
}
return this;
};
/**
* Removes all listeners from a specified event.
* If you do not specify an event then all listeners will be removed.
* That means every event will be emptied.
* You can also pass a regex to remove all events that match it.
*
* @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeEvent = function removeEvent(evt) {
var type = typeof evt;
var events = this._getEvents();
var key;
// Remove different things depending on the state of evt
if (type === 'string') {
// Remove all listeners for the specified event
delete events[evt];
}
else if (evt instanceof RegExp) {
// Remove all events matching the regex.
for (key in events) {
if (events.hasOwnProperty(key) && evt.test(key)) {
delete events[key];
}
}
}
else {
// Remove all listeners in all events
delete this._events;
}
return this;
};
/**
* Alias of removeEvent.
*
* Added to mirror the node API.
*/
proto.removeAllListeners = alias('removeEvent');
/**
* Emits an event of your choice.
* When emitted, every listener attached to that event will be executed.
* If you pass the optional argument array then those arguments will be passed to every listener upon execution.
* Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
* So they will not arrive within the array on the other side, they will be separate.
* You can also pass a regular expression to emit to all events that match it.
*
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
* @param {Array} [args] Optional array of arguments to be passed to each listener.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.emitEvent = function emitEvent(evt, args) {
var listenersMap = this.getListenersAsObject(evt);
var listeners;
var listener;
var i;
var key;
var response;
for (key in listenersMap) {
if (listenersMap.hasOwnProperty(key)) {
listeners = listenersMap[key].slice(0);
for (i = 0; i < listeners.length; i++) {
// If the listener returns true then it shall be removed from the event
// The function is executed either with a basic call or an apply if there is an args array
listener = listeners[i];
if (listener.once === true) {
this.removeListener(evt, listener.listener);
}
response = listener.listener.apply(this, args || []);
if (response === this._getOnceReturnValue()) {
this.removeListener(evt, listener.listener);
}
}
}
}
return this;
};
/**
* Alias of emitEvent
*/
proto.trigger = alias('emitEvent');
/**
* Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
* As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
*
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
* @param {...*} Optional additional arguments to be passed to each listener.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.emit = function emit(evt) {
var args = Array.prototype.slice.call(arguments, 1);
return this.emitEvent(evt, args);
};
/**
* Sets the current value to check against when executing listeners. If a
* listeners return value matches the one set here then it will be removed
* after execution. This value defaults to true.
*
* @param {*} value The new value to check for when executing listeners.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.setOnceReturnValue = function setOnceReturnValue(value) {
this._onceReturnValue = value;
return this;
};
/**
* Fetches the current value to check against when executing listeners. If
* the listeners return value matches this one then it should be removed
* automatically. It will return true by default.
*
* @return {*|Boolean} The current value to check for or the default, true.
* @api private
*/
proto._getOnceReturnValue = function _getOnceReturnValue() {
if (this.hasOwnProperty('_onceReturnValue')) {
return this._onceReturnValue;
}
else {
return true;
}
};
/**
* Fetches the events object and creates one if required.
*
* @return {Object} The events storage object.
* @api private
*/
proto._getEvents = function _getEvents() {
return this._events || (this._events = {});
};
/**
* Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
*
* @return {Function} Non conflicting EventEmitter class.
*/
EventEmitter.noConflict = function noConflict() {
exports.EventEmitter = originalGlobalValue;
return EventEmitter;
};
// Expose the class either via AMD, CommonJS or the global object
if (typeof define === 'function' && define.amd) {
define(function () {
return EventEmitter;
});
}
else if (typeof module === 'object' && module.exports){
module.exports = EventEmitter;
}
else {
exports.EventEmitter = EventEmitter;
}
}(typeof window !== 'undefined' ? window : this || {}));
},{}],39:[function(require,module,exports){
module.exports={
"author": "OpenVidu",
"dependencies": {
"freeice": "2.2.2",
"hark": "1.2.3",
"jsnlog": "2.30.0",
"mime": "3.0.0",
"platform": "1.3.6",
"semver": "7.3.7",
"uuid": "8.3.2",
"wolfy87-eventemitter": "5.2.9",
"events": "3.3.0",
"inherits": "2.0.4"
},
"description": "OpenVidu Browser",
"devDependencies": {
"@types/node": "18.0.0",
"@types/platform": "1.3.4",
"browserify": "17.0.0",
"grunt": "1.5.3",
"grunt-cli": "1.4.3",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-sass": "2.0.0",
"grunt-contrib-uglify": "5.2.2",
"grunt-contrib-watch": "1.1.0",
"grunt-postcss": "0.9.0",
"grunt-string-replace": "1.3.3",
"grunt-ts": "6.0.0-beta.22",
"terser": "5.14.1",
"tsify": "5.0.4",
"tslint": "6.1.3",
"typedoc": "0.22.17",
"typescript": "4.5.4"
},
"license": "Apache-2.0",
"main": "lib/index.js",
"name": "openvidu-browser",
"repository": {
"type": "git",
"url": "git://github.com/OpenVidu/openvidu"
},
"scripts": {
"browserify": "VERSION=${VERSION:-dev}; mkdir -p static/js/ && cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v",
"browserify-prod": "VERSION=${VERSION:-dev}; mkdir -p static/js/ && cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/terser/bin/terser --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js",
"build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --target es5 --lib dom,es5,es2015.promise,scripthost && rm -rf ./ts4.4 && mkdir -p ./ts4.4/lib && cp -r ./lib ./ts4.4 && find ./ts4.4/lib -type f ! -iname '*.d.ts' -delete && ./config/replace_for_ts44.sh",
"docs": "./generate-docs.sh"
},
"types": "lib/index.d.ts",
"typesVersions": {
"<4.4": {
"*": [
"ts4.4/*"
]
}
},
"version": "2.23.0"
}
},{}],40:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var OpenVidu_1 = require("./OpenVidu/OpenVidu");
var jsnlog_1 = require("jsnlog");
if (typeof globalThis !== 'undefined') {
globalThis['OpenVidu'] = OpenVidu_1.OpenVidu;
}
jsnlog_1.JL.setOptions({ enabled: false });
},{"./OpenVidu/OpenVidu":45,"jsnlog":7}],41:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Connection = void 0;
var Stream_1 = require("./Stream");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var Connection = (function () {
function Connection(session, connectionOptions) {
this.session = session;
this.disposed = false;
var msg = "'Connection' created ";
if (!!connectionOptions.role) {
this.localOptions = connectionOptions;
this.connectionId = this.localOptions.id;
this.creationTime = this.localOptions.createdAt;
this.data = this.localOptions.metadata;
this.rpcSessionId = this.localOptions.sessionId;
this.role = this.localOptions.role;
this.record = this.localOptions.record;
msg += '(local)';
}
else {
this.remoteOptions = connectionOptions;
this.connectionId = this.remoteOptions.id;
this.creationTime = this.remoteOptions.createdAt;
if (this.remoteOptions.metadata) {
this.data = this.remoteOptions.metadata;
}
if (this.remoteOptions.streams) {
this.initRemoteStreams(this.remoteOptions.streams);
}
msg += "(remote) with 'connectionId' [" + this.remoteOptions.id + ']';
}
logger.info(msg);
}
Connection.prototype.sendIceCandidate = function (candidate) {
var _this = this;
logger.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + this.connectionId, candidate);
this.session.openvidu.sendRequest('onIceCandidate', {
endpointName: this.connectionId,
candidate: candidate.candidate,
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex
}, function (error, response) {
if (error) {
logger.error('Error sending ICE candidate: ' + JSON.stringify(error));
_this.session.emitEvent('exception', [
new ExceptionEvent_1.ExceptionEvent(_this.session, ExceptionEvent_1.ExceptionEventName.ICE_CANDIDATE_ERROR, _this.session, 'There was an unexpected error on the server-side processing an ICE candidate generated and sent by the client-side', error)
]);
}
});
};
Connection.prototype.initRemoteStreams = function (options) {
var _this = this;
options.forEach(function (opts) {
var streamOptions = {
id: opts.id,
createdAt: opts.createdAt,
connection: _this,
hasAudio: opts.hasAudio,
hasVideo: opts.hasVideo,
audioActive: opts.audioActive,
videoActive: opts.videoActive,
typeOfVideo: opts.typeOfVideo,
frameRate: opts.frameRate,
videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined,
filter: !!opts.filter ? opts.filter : undefined
};
var stream = new Stream_1.Stream(_this.session, streamOptions);
_this.addStream(stream);
});
logger.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts);
};
Connection.prototype.addStream = function (stream) {
stream.connection = this;
this.stream = stream;
};
Connection.prototype.removeStream = function (streamId) {
delete this.stream;
};
Connection.prototype.dispose = function () {
if (!!this.stream) {
delete this.stream;
}
this.disposed = true;
};
return Connection;
}());
exports.Connection = Connection;
},{"../OpenViduInternal/Events/ExceptionEvent":58,"../OpenViduInternal/Logger/OpenViduLogger":79,"./Stream":48}],42:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventDispatcher = void 0;
var EventEmitter = require("wolfy87-eventemitter");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var EventDispatcher = (function () {
function EventDispatcher() {
this.userHandlerArrowHandler = new WeakMap();
this.ee = new EventEmitter();
}
EventDispatcher.prototype.onAux = function (type, message, handler) {
var arrowHandler = function (event) {
if (event) {
logger.info(message, event);
}
else {
logger.info(message);
}
handler(event);
};
this.userHandlerArrowHandler.set(handler, arrowHandler);
this.ee.on(type, arrowHandler);
return this;
};
EventDispatcher.prototype.onceAux = function (type, message, handler) {
var _this = this;
var arrowHandler = function (event) {
if (event) {
logger.info(message, event);
}
else {
logger.info(message);
}
handler(event);
_this.userHandlerArrowHandler.delete(handler);
};
this.userHandlerArrowHandler.set(handler, arrowHandler);
this.ee.once(type, arrowHandler);
return this;
};
EventDispatcher.prototype.offAux = function (type, handler) {
if (!handler) {
this.ee.removeAllListeners(type);
}
else {
var arrowHandler = this.userHandlerArrowHandler.get(handler);
if (!!arrowHandler) {
this.ee.off(type, arrowHandler);
}
this.userHandlerArrowHandler.delete(handler);
}
return this;
};
return EventDispatcher;
}());
exports.EventDispatcher = EventDispatcher;
},{"../OpenViduInternal/Logger/OpenViduLogger":79,"wolfy87-eventemitter":38}],43:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Filter = void 0;
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var Filter = (function () {
function Filter(type, options) {
this.handlers = new Map();
this.type = type;
this.options = options;
}
Filter.prototype.execMethod = function (method, params) {
var _this = this;
return new Promise(function (resolve, reject) {
var _a;
logger.info('Executing filter method to stream ' + _this.stream.streamId);
var finalParams;
var successExecMethod = function (triggerEvent) {
logger.info('Filter method successfully executed on Stream ' + _this.stream.streamId);
var oldValue = Object.assign({}, _this.stream.filter);
_this.stream.filter.lastExecMethod = { method: method, params: finalParams };
if (triggerEvent) {
_this.stream.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')
]);
_this.stream.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')
]);
}
return resolve();
};
if (_this.type.startsWith('VB:')) {
if (typeof params === 'string') {
try {
params = JSON.parse(params);
}
catch (error) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'Wrong params syntax: ' + error));
}
}
finalParams = params;
if (method === 'update') {
if (!((_a = _this.stream.virtualBackgroundSinkElements) === null || _a === void 0 ? void 0 : _a.VB)) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'There is no Virtual Background filter applied'));
}
else {
_this.stream.virtualBackgroundSinkElements.VB.updateValues(params)
.then(function () { return successExecMethod(false); })
.catch(function (error) {
if (error.name === OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR) {
return reject(new OpenViduError_1.OpenViduError(error.name, error.message));
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'Error updating values on Virtual Background filter: ' + error));
}
});
}
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, "Unknown Virtual Background method \"".concat(method, "\"")));
}
}
else {
var stringParams = void 0;
if (typeof params !== 'string') {
try {
stringParams = JSON.stringify(params);
}
catch (error) {
var errorMsg = "'params' property must be a JSON formatted object";
logger.error(errorMsg);
return reject(errorMsg);
}
}
else {
stringParams = params;
}
finalParams = stringParams;
_this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) {
if (error) {
logger.error('Error executing filter method for Stream ' + _this.stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method"));
}
else {
return reject(error);
}
}
else {
return successExecMethod(true);
}
});
}
});
};
Filter.prototype.addEventListener = function (eventType, handler) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId);
_this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) {
if (error) {
logger.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener"));
}
else {
return reject(error);
}
}
else {
_this.handlers.set(eventType, handler);
logger.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId);
return resolve();
}
});
});
};
Filter.prototype.removeEventListener = function (eventType) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId);
_this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) {
if (error) {
logger.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener"));
}
else {
return reject(error);
}
}
else {
_this.handlers.delete(eventType);
logger.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId);
return resolve();
}
});
});
};
return Filter;
}());
exports.Filter = Filter;
},{"../OpenViduInternal/Enums/OpenViduError":52,"../OpenViduInternal/Events/StreamPropertyChangedEvent":67,"../OpenViduInternal/Logger/OpenViduLogger":79}],44:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalRecorder = void 0;
var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var Mime = require("mime/lite");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var LocalRecorder = (function () {
function LocalRecorder(stream) {
this.stream = stream;
this.chunks = [];
platform = Platform_1.PlatformUtils.getInstance();
this.connectionId = !!this.stream.connection ? this.stream.connection.connectionId : 'default-connection';
this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord';
this.state = LocalRecorderState_1.LocalRecorderState.READY;
}
LocalRecorder.prototype.record = function (options) {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (typeof options === 'string' || options instanceof String) {
return reject("When calling LocalRecorder.record(options) parameter 'options' cannot be a string. Must be an object like { mimeType: \"".concat(options, "\" }"));
}
if (typeof MediaRecorder === 'undefined') {
logger.error('MediaRecorder not supported on your device. See compatibility in https://caniuse.com/#search=MediaRecorder');
throw Error('MediaRecorder not supported on your device. See compatibility in https://caniuse.com/#search=MediaRecorder');
}
if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) {
throw Error("'LocalRecord.record()' needs 'LocalRecord.state' to be 'READY' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.clean()' or init a new LocalRecorder before");
}
logger.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'");
if (!options) {
options = { mimeType: 'video/webm' };
}
else if (!options.mimeType) {
options.mimeType = 'video/webm';
}
_this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options);
_this.mediaRecorder.start();
}
catch (err) {
return reject(err);
}
_this.mediaRecorder.ondataavailable = function (e) {
if (e.data.size > 0) {
_this.chunks.push(e.data);
}
};
_this.mediaRecorder.onerror = function (e) {
logger.error('MediaRecorder error: ', e);
};
_this.mediaRecorder.onstart = function () {
logger.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')');
};
_this.mediaRecorder.onstop = function () {
_this.onStopDefault();
};
_this.mediaRecorder.onpause = function () {
logger.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')');
};
_this.mediaRecorder.onresume = function () {
logger.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')');
};
_this.state = LocalRecorderState_1.LocalRecorderState.RECORDING;
return resolve();
});
};
LocalRecorder.prototype.stop = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("'LocalRecord.stop()' needs 'LocalRecord.state' to be 'RECORDING' or 'PAUSED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.start()' before");
}
_this.mediaRecorder.onstop = function () {
_this.onStopDefault();
return resolve();
};
_this.mediaRecorder.stop();
}
catch (e) {
return reject(e);
}
});
};
LocalRecorder.prototype.pause = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) {
return reject(Error("'LocalRecord.pause()' needs 'LocalRecord.state' to be 'RECORDING' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.start()' or 'LocalRecorder.resume()' before"));
}
_this.mediaRecorder.pause();
_this.state = LocalRecorderState_1.LocalRecorderState.PAUSED;
return resolve();
}
catch (error) {
return reject(error);
}
});
};
LocalRecorder.prototype.resume = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) {
throw Error("'LocalRecord.resume()' needs 'LocalRecord.state' to be 'PAUSED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.pause()' before");
}
_this.mediaRecorder.resume();
_this.state = LocalRecorderState_1.LocalRecorderState.RECORDING;
return resolve();
}
catch (error) {
return reject(error);
}
});
};
LocalRecorder.prototype.preview = function (parentElement) {
if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("'LocalRecord.preview()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
this.state +
"'). Call 'LocalRecorder.stop()' before");
}
this.videoPreview = document.createElement('video');
this.videoPreview.id = this.id;
this.videoPreview.autoplay = true;
if (platform.isSafariBrowser()) {
this.videoPreview.playsInline = true;
}
if (typeof parentElement === 'string') {
var parentElementDom = document.getElementById(parentElement);
if (parentElementDom) {
this.videoPreview = parentElementDom.appendChild(this.videoPreview);
}
}
else {
this.videoPreview = parentElement.appendChild(this.videoPreview);
}
this.videoPreview.src = this.videoPreviewSrc;
return this.videoPreview;
};
LocalRecorder.prototype.clean = function () {
var _this = this;
var f = function () {
delete _this.blob;
_this.chunks = [];
_this.state = LocalRecorderState_1.LocalRecorderState.READY;
};
if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) {
this.stop()
.then(function () { return f(); })
.catch(function () { return f(); });
}
else {
f();
}
};
LocalRecorder.prototype.download = function () {
if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("'LocalRecord.download()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
this.state +
"'). Call 'LocalRecorder.stop()' before");
}
else {
var a = document.createElement('a');
a.style.display = 'none';
document.body.appendChild(a);
var url = globalThis.URL.createObjectURL(this.blob);
a.href = url;
a.download = this.id + '.' + Mime.getExtension(this.blob.type);
a.click();
globalThis.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
};
LocalRecorder.prototype.getBlob = function () {
if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("Call 'LocalRecord.stop()' before getting Blob file");
}
else {
return this.blob;
}
};
LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
return reject(Error("'LocalRecord.uploadAsBinary()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.stop()' before"));
}
else {
var http_1 = new XMLHttpRequest();
http_1.open('POST', endpoint, true);
if (typeof headers === 'object') {
for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) {
var key = _a[_i];
http_1.setRequestHeader(key, headers[key]);
}
}
http_1.onreadystatechange = function () {
if (http_1.readyState === 4) {
if (http_1.status.toString().charAt(0) === '2') {
return resolve(http_1.responseText);
}
else {
return reject(http_1.status);
}
}
};
http_1.send(_this.blob);
}
});
};
LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
return reject(Error("'LocalRecord.uploadAsMultipartfile()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.stop()' before"));
}
else {
var http_2 = new XMLHttpRequest();
http_2.open('POST', endpoint, true);
if (typeof headers === 'object') {
for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) {
var key = _a[_i];
http_2.setRequestHeader(key, headers[key]);
}
}
var sendable = new FormData();
sendable.append('file', _this.blob, _this.id + '.' + Mime.getExtension(_this.blob.type));
http_2.onreadystatechange = function () {
if (http_2.readyState === 4) {
if (http_2.status.toString().charAt(0) === '2') {
return resolve(http_2.responseText);
}
else {
return reject(http_2.status);
}
}
};
http_2.send(sendable);
}
});
};
LocalRecorder.prototype.onStopDefault = function () {
logger.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')');
this.blob = new Blob(this.chunks, { type: this.mediaRecorder.mimeType });
this.chunks = [];
this.videoPreviewSrc = globalThis.URL.createObjectURL(this.blob);
this.state = LocalRecorderState_1.LocalRecorderState.FINISHED;
};
return LocalRecorder;
}());
exports.LocalRecorder = LocalRecorder;
},{"../OpenViduInternal/Enums/LocalRecorderState":51,"../OpenViduInternal/Logger/OpenViduLogger":79,"../OpenViduInternal/Utils/Platform":83,"mime/lite":9}],45:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenVidu = void 0;
var LocalRecorder_1 = require("./LocalRecorder");
var Publisher_1 = require("./Publisher");
var Session_1 = require("./Session");
var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto");
var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing");
var OpenViduLoggerConfiguration_1 = require("../OpenViduInternal/Logger/OpenViduLoggerConfiguration");
var EventEmitter = require("wolfy87-eventemitter");
var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc");
var packageJson = require('../../package.json');
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var OpenVidu = (function () {
function OpenVidu() {
var _this = this;
this.masterNodeHasCrashed = false;
this.publishers = [];
this.secret = '';
this.recorder = false;
this.life = -1;
this.advancedConfiguration = {};
this.webrtcStatsInterval = -1;
this.sendBrowserLogs = OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.disabled;
this.isAtLeastPro = false;
this.isEnterprise = false;
this.ee = new EventEmitter();
platform = Platform_1.PlatformUtils.getInstance();
this.libraryVersion = packageJson.version;
logger.info('OpenVidu initialized');
logger.info('Platform detected: ' + platform.getDescription());
logger.info('openvidu-browser version: ' + this.libraryVersion);
if (platform.isMobileDevice() || platform.isReactNative()) {
this.onOrientationChanged(function () {
_this.publishers.forEach(function (publisher) {
if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo) {
_this.sendNewVideoDimensionsIfRequired(publisher, 'deviceRotated', 75, 10);
}
});
});
}
}
OpenVidu.prototype.initSession = function () {
this.session = new Session_1.Session(this);
return this.session;
};
OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) {
var properties;
if (!!param2 && typeof param2 !== 'function') {
properties = param2;
properties = {
audioSource: typeof properties.audioSource !== 'undefined' ? properties.audioSource : undefined,
frameRate: typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack
? undefined
: typeof properties.frameRate !== 'undefined'
? properties.frameRate
: undefined,
insertMode: typeof properties.insertMode !== 'undefined'
? typeof properties.insertMode === 'string'
? VideoInsertMode_1.VideoInsertMode[properties.insertMode]
: properties.insertMode
: VideoInsertMode_1.VideoInsertMode.APPEND,
mirror: typeof properties.mirror !== 'undefined' ? properties.mirror : true,
publishAudio: typeof properties.publishAudio !== 'undefined' ? properties.publishAudio : true,
publishVideo: typeof properties.publishVideo !== 'undefined' ? properties.publishVideo : true,
resolution: typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack
? undefined
: typeof properties.resolution !== 'undefined'
? properties.resolution
: '640x480',
videoSource: typeof properties.videoSource !== 'undefined' ? properties.videoSource : undefined,
videoSimulcast: properties.videoSimulcast,
filter: properties.filter
};
}
else {
properties = {
insertMode: VideoInsertMode_1.VideoInsertMode.APPEND,
mirror: true,
publishAudio: true,
publishVideo: true,
resolution: '640x480'
};
}
var publisher = new Publisher_1.Publisher(targetElement, properties, this);
var completionHandler;
if (!!param2 && typeof param2 === 'function') {
completionHandler = param2;
}
else if (!!param3) {
completionHandler = param3;
}
publisher
.initialize()
.then(function () {
if (completionHandler !== undefined) {
completionHandler(undefined);
}
publisher.emitEvent('accessAllowed', []);
})
.catch(function (error) {
if (completionHandler !== undefined) {
completionHandler(error);
}
publisher.emitEvent('accessDenied', [error]);
});
this.publishers.push(publisher);
return publisher;
};
OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) {
var _this = this;
return new Promise(function (resolve, reject) {
var publisher;
var callback = function (error) {
if (!!error) {
return reject(error);
}
else {
return resolve(publisher);
}
};
if (!!properties) {
publisher = _this.initPublisher(targetElement, properties, callback);
}
else {
publisher = _this.initPublisher(targetElement, callback);
}
});
};
OpenVidu.prototype.initLocalRecorder = function (stream) {
return new LocalRecorder_1.LocalRecorder(stream);
};
OpenVidu.prototype.checkSystemRequirements = function () {
if (platform.isIPhoneOrIPad()) {
return (platform.isIOSWithSafari() ||
platform.isChromeMobileBrowser() ||
platform.isFirefoxMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isIonicIos());
}
return (platform.isChromeBrowser() ||
platform.isChromeMobileBrowser() ||
platform.isFirefoxBrowser() ||
platform.isFirefoxMobileBrowser() ||
platform.isOperaBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isEdgeBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isSamsungBrowser() ||
platform.isSafariBrowser() ||
platform.isAndroidBrowser() ||
platform.isElectron() ||
platform.isNodeJs());
};
OpenVidu.prototype.checkScreenSharingCapabilities = function () {
return platform.canScreenShare();
};
OpenVidu.prototype.getDevices = function () {
return new Promise(function (resolve, reject) {
navigator.mediaDevices
.enumerateDevices()
.then(function (deviceInfos) {
var _a;
var devices = [];
if (platform.isIonicAndroid() && typeof cordova != 'undefined' && ((_a = cordova === null || cordova === void 0 ? void 0 : cordova.plugins) === null || _a === void 0 ? void 0 : _a.EnumerateDevicesPlugin)) {
cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) {
var pluginAudioDevices = [];
var videoDevices = [];
var audioDevices = [];
pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; });
videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; });
audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; });
videoDevices.forEach(function (deviceInfo, index) {
if (!deviceInfo.label) {
var label = '';
if (index === 0) {
label = 'Front Camera';
}
else if (index === 1) {
label = 'Back Camera';
}
else {
label = 'Unknown Camera';
}
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: label
});
}
else {
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: deviceInfo.label
});
}
});
audioDevices.forEach(function (deviceInfo, index) {
if (!deviceInfo.label) {
var label = '';
switch (index) {
case 0:
label = 'Default';
break;
case 1:
var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0];
label = defaultMatch ? defaultMatch.label : 'Built-in Microphone';
break;
case 2:
var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0];
if (wiredMatch) {
label = wiredMatch.label;
}
else {
label = 'Headset earpiece';
}
break;
case 3:
var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0];
label = wirelessMatch ? wirelessMatch.label : 'Wireless';
break;
default:
label = 'Unknown Microphone';
break;
}
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: label
});
}
else {
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: deviceInfo.label
});
}
});
return resolve(devices);
});
}
else {
deviceInfos.forEach(function (deviceInfo) {
if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') {
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: deviceInfo.label
});
}
});
return resolve(devices);
}
})
.catch(function (error) {
logger.error('Error getting devices', error);
return reject(error);
});
});
};
OpenVidu.prototype.getUserMedia = function (options) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var askForAudioStreamOnly, myConstraints, mustAskForAudioTrackLater, mediaStream, error_1, errorName, errorMessage, constraintsAux, mediaStream, error_2, errorName, errorMessage, error_3;
var _this = this;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
askForAudioStreamOnly = function (previousMediaStream, constraints) { return __awaiter(_this, void 0, void 0, function () {
var definedAudioConstraint, constraintsAux, audioOnlyStream, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
definedAudioConstraint = constraints.audio === undefined ? true : constraints.audio;
constraintsAux = { audio: definedAudioConstraint, video: false };
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 2:
audioOnlyStream = _a.sent();
previousMediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]);
return [2, resolve(previousMediaStream)];
case 3:
error_4 = _a.sent();
previousMediaStream.getAudioTracks().forEach(function (track) {
track.stop();
});
previousMediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
return [2, reject(this.generateAudioDeviceError(error_4, constraintsAux))];
case 4: return [2];
}
});
}); };
_c.label = 1;
case 1:
_c.trys.push([1, 20, , 21]);
return [4, this.generateMediaConstraints(options)];
case 2:
myConstraints = _c.sent();
if (!((!!myConstraints.videoTrack && !!myConstraints.audioTrack) ||
(!!myConstraints.audioTrack && ((_a = myConstraints.constraints) === null || _a === void 0 ? void 0 : _a.video) === false) ||
(!!myConstraints.videoTrack && ((_b = myConstraints.constraints) === null || _b === void 0 ? void 0 : _b.audio) === false))) return [3, 3];
return [2, resolve(this.addAlreadyProvidedTracks(myConstraints, new MediaStream()))];
case 3:
if (!!myConstraints.videoTrack) {
delete myConstraints.constraints.video;
}
if (!!myConstraints.audioTrack) {
delete myConstraints.constraints.audio;
}
mustAskForAudioTrackLater = false;
if (!(typeof options.videoSource === 'string')) return [3, 12];
if (!(options.videoSource === 'screen' ||
options.videoSource === 'window' ||
(platform.isElectron() && options.videoSource.startsWith('screen:')))) return [3, 12];
mustAskForAudioTrackLater =
!myConstraints.audioTrack && options.audioSource !== null && options.audioSource !== false;
if (!(navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron())) return [3, 11];
_c.label = 4;
case 4:
_c.trys.push([4, 9, , 10]);
return [4, navigator.mediaDevices['getDisplayMedia']({ video: true })];
case 5:
mediaStream = _c.sent();
this.addAlreadyProvidedTracks(myConstraints, mediaStream);
if (!mustAskForAudioTrackLater) return [3, 7];
return [4, askForAudioStreamOnly(mediaStream, myConstraints.constraints)];
case 6:
_c.sent();
return [2];
case 7: return [2, resolve(mediaStream)];
case 8: return [3, 10];
case 9:
error_1 = _c.sent();
errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED;
errorMessage = error_1.toString();
return [2, reject(new OpenViduError_1.OpenViduError(errorName, errorMessage))];
case 10: return [3, 11];
case 11: return [3, 12];
case 12:
constraintsAux = mustAskForAudioTrackLater
? { video: myConstraints.constraints.video }
: myConstraints.constraints;
_c.label = 13;
case 13:
_c.trys.push([13, 18, , 19]);
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 14:
mediaStream = _c.sent();
this.addAlreadyProvidedTracks(myConstraints, mediaStream);
if (!mustAskForAudioTrackLater) return [3, 16];
return [4, askForAudioStreamOnly(mediaStream, myConstraints.constraints)];
case 15:
_c.sent();
return [3, 17];
case 16: return [2, resolve(mediaStream)];
case 17: return [3, 19];
case 18:
error_2 = _c.sent();
errorName = void 0;
errorMessage = error_2.toString();
if (!(options.videoSource === 'screen')) {
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED;
}
else {
errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED;
}
return [2, reject(new OpenViduError_1.OpenViduError(errorName, errorMessage))];
case 19: return [3, 21];
case 20:
error_3 = _c.sent();
reject(error_3);
return [3, 21];
case 21: return [2];
}
});
}); });
};
OpenVidu.prototype.enableProdMode = function () {
logger.enableProdMode();
};
OpenVidu.prototype.setAdvancedConfiguration = function (configuration) {
this.advancedConfiguration = configuration;
};
OpenVidu.prototype.onOrientationChanged = function (handler) {
globalThis.addEventListener('orientationchange', handler);
};
OpenVidu.prototype.sendNewVideoDimensionsIfRequired = function (publisher, reason, WAIT_INTERVAL, MAX_ATTEMPTS) {
var _this = this;
var _a, _b, _c, _d;
var attempts = 0;
var oldWidth = ((_b = (_a = publisher === null || publisher === void 0 ? void 0 : publisher.stream) === null || _a === void 0 ? void 0 : _a.videoDimensions) === null || _b === void 0 ? void 0 : _b.width) || 0;
var oldHeight = ((_d = (_c = publisher === null || publisher === void 0 ? void 0 : publisher.stream) === null || _c === void 0 ? void 0 : _c.videoDimensions) === null || _d === void 0 ? void 0 : _d.height) || 0;
var repeatUntilChangeOrMaxAttempts = setInterval(function () {
attempts++;
if (attempts > MAX_ATTEMPTS) {
clearTimeout(repeatUntilChangeOrMaxAttempts);
}
publisher.getVideoDimensions().then(function (newDimensions) {
if (newDimensions.width !== oldWidth || newDimensions.height !== oldHeight) {
clearTimeout(repeatUntilChangeOrMaxAttempts);
_this.sendVideoDimensionsChangedEvent(publisher, reason, oldWidth, oldHeight, newDimensions.width, newDimensions.height);
}
});
}, WAIT_INTERVAL);
};
OpenVidu.prototype.sendVideoDimensionsChangedEvent = function (publisher, reason, oldWidth, oldHeight, newWidth, newHeight) {
var _this = this;
publisher.stream.videoDimensions = {
width: newWidth || 0,
height: newHeight || 0
};
this.sendRequest('streamPropertyChanged', {
streamId: publisher.stream.streamId,
property: 'videoDimensions',
newValue: JSON.stringify(publisher.stream.videoDimensions),
reason: reason
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, reason)
]);
publisher.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, reason)
]);
_this.session.sendVideoData(publisher);
}
});
};
OpenVidu.prototype.sendTrackChangedEvent = function (publisher, reason, oldLabel, newLabel, propertyType) {
var _this = this;
var oldValue = { label: oldLabel };
var newValue = { label: newLabel };
if (publisher.stream.isLocalStreamPublished) {
this.sendRequest('streamPropertyChanged', {
streamId: publisher.stream.streamId,
property: propertyType,
newValue: JSON.stringify({ newLabel: newLabel }),
reason: reason
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, propertyType, newValue, oldValue, reason)
]);
publisher.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, propertyType, newValue, oldValue, reason)
]);
}
});
}
else {
this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(this.session, publisher.stream, propertyType, newValue, oldValue, reason)
]);
publisher.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, propertyType, newValue, oldValue, reason)
]);
}
};
OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) {
var _this = this;
return new Promise(function (resolve, reject) {
var myConstraints = {
audioTrack: undefined,
videoTrack: undefined,
constraints: {
audio: undefined,
video: undefined
}
};
var audioSource = publisherProperties.audioSource;
var videoSource = publisherProperties.videoSource;
if (audioSource === null || audioSource === false) {
myConstraints.constraints.audio = false;
}
if (videoSource === null || videoSource === false) {
myConstraints.constraints.video = false;
}
if (myConstraints.constraints.audio === false && myConstraints.constraints.video === false) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time"));
}
if (typeof MediaStreamTrack !== 'undefined' && audioSource instanceof MediaStreamTrack) {
myConstraints.audioTrack = audioSource;
}
if (typeof MediaStreamTrack !== 'undefined' && videoSource instanceof MediaStreamTrack) {
myConstraints.videoTrack = videoSource;
}
if (audioSource === undefined) {
myConstraints.constraints.audio = true;
}
if (videoSource === undefined) {
myConstraints.constraints.video = {
width: {
ideal: 640
},
height: {
ideal: 480
}
};
}
if (videoSource !== null && videoSource !== false) {
if (!!publisherProperties.resolution) {
var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x');
var idealWidth = Number(widthAndHeight[0]);
var idealHeight = Number(widthAndHeight[1]);
myConstraints.constraints.video = {
width: {
ideal: idealWidth
},
height: {
ideal: idealHeight
}
};
}
if (!!publisherProperties.frameRate) {
myConstraints.constraints.video.frameRate = { ideal: publisherProperties.frameRate };
}
}
_this.configureDeviceIdOrScreensharing(myConstraints, publisherProperties, resolve, reject);
return resolve(myConstraints);
});
};
OpenVidu.prototype.startWs = function (onConnectSucces) {
var config = {
heartbeat: 5000,
ws: {
uri: this.wsUri + '?sessionId=' + this.session.sessionId,
onconnected: onConnectSucces,
ondisconnect: this.disconnectCallback.bind(this),
onreconnecting: this.reconnectingCallback.bind(this),
onreconnected: this.reconnectedCallback.bind(this),
ismasternodecrashed: this.isMasterNodeCrashed.bind(this)
},
rpc: {
requestTimeout: 10000,
heartbeatRequestTimeout: 5000,
participantJoined: this.session.onParticipantJoined.bind(this.session),
participantPublished: this.session.onParticipantPublished.bind(this.session),
participantUnpublished: this.session.onParticipantUnpublished.bind(this.session),
participantLeft: this.session.onParticipantLeft.bind(this.session),
participantEvicted: this.session.onParticipantEvicted.bind(this.session),
recordingStarted: this.session.onRecordingStarted.bind(this.session),
recordingStopped: this.session.onRecordingStopped.bind(this.session),
sendMessage: this.session.onNewMessage.bind(this.session),
streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session),
connectionPropertyChanged: this.session.onConnectionPropertyChanged.bind(this.session),
networkQualityLevelChanged: this.session.onNetworkQualityLevelChangedChanged.bind(this.session),
filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session),
iceCandidate: this.session.recvIceCandidate.bind(this.session),
mediaError: this.session.onMediaError.bind(this.session),
masterNodeCrashedNotification: this.onMasterNodeCrashedNotification.bind(this),
forciblyReconnectSubscriber: this.session.onForciblyReconnectSubscriber.bind(this.session)
}
};
this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config);
};
OpenVidu.prototype.onMasterNodeCrashedNotification = function (response) {
console.error('Master Node has crashed');
this.masterNodeHasCrashed = true;
this.session.onLostConnection('nodeCrashed');
this.jsonRpcClient.close(4103, 'Master Node has crashed');
};
OpenVidu.prototype.getWsReadyState = function () {
return this.jsonRpcClient.getReadyState();
};
OpenVidu.prototype.closeWs = function () {
this.jsonRpcClient.close(4102, 'Connection closed by client');
};
OpenVidu.prototype.sendRequest = function (method, params, callback) {
var _a;
if (params && params instanceof Function) {
callback = params;
params = {};
}
logger.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}');
(_a = this.jsonRpcClient) === null || _a === void 0 ? void 0 : _a.send(method, params, callback);
};
OpenVidu.prototype.getWsUri = function () {
return this.wsUri;
};
OpenVidu.prototype.getSecret = function () {
return this.secret;
};
OpenVidu.prototype.getRecorder = function () {
return this.recorder;
};
OpenVidu.prototype.generateAudioDeviceError = function (error, constraints) {
if (error.name === 'Error') {
error.name = error.constructor.name;
}
var errorName, errorMessage;
switch (error.name.toLowerCase()) {
case 'notfounderror':
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage = error.toString();
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
case 'notallowederror':
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED;
errorMessage = error.toString();
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
case 'overconstrainederror':
if (error.constraint.toLowerCase() === 'deviceid') {
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage =
"Audio input device with deviceId '" +
constraints.audio.deviceId.exact +
"' not found";
}
else {
errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR;
errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'";
}
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
case 'notreadableerror':
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE;
errorMessage = error.toString();
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
default:
return new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_GENERIC_ERROR, error.toString());
}
};
OpenVidu.prototype.addAlreadyProvidedTracks = function (myConstraints, mediaStream, stream) {
if (!!myConstraints.videoTrack) {
mediaStream.addTrack(myConstraints.videoTrack);
if (!!stream) {
if (!!myConstraints.constraints.video) {
stream.lastVideoTrackConstraints = myConstraints.constraints.video;
}
else {
stream.lastVideoTrackConstraints = myConstraints.videoTrack.getConstraints();
}
}
}
if (!!myConstraints.audioTrack) {
mediaStream.addTrack(myConstraints.audioTrack);
}
return mediaStream;
};
OpenVidu.prototype.configureDeviceIdOrScreensharing = function (myConstraints, publisherProperties, resolve, reject) {
var _this = this;
var audioSource = publisherProperties.audioSource;
var videoSource = publisherProperties.videoSource;
if (typeof audioSource === 'string') {
myConstraints.constraints.audio = { deviceId: { exact: audioSource } };
}
if (typeof videoSource === 'string') {
if (!this.isScreenShare(videoSource)) {
this.setVideoSource(myConstraints, videoSource);
}
else {
if (!this.checkScreenSharingCapabilities()) {
var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera, Safari (>=13.0), Edge (>= 80) or Electron. Detected client: ' +
platform.getName() +
' ' +
platform.getVersion());
logger.error(error);
return reject(error);
}
else {
if (platform.isElectron()) {
var prefix = 'screen:';
var videoSourceString = videoSource;
var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length);
myConstraints.constraints.video = {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: electronScreenId
}
};
return resolve(myConstraints);
}
else {
if (!!this.advancedConfiguration.screenShareChromeExtension &&
!(platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) &&
!navigator.mediaDevices['getDisplayMedia']) {
screenSharing.getScreenConstraints(function (error, screenConstraints) {
if (!!error ||
(!!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen')) {
if (error === 'permission-denied' || error === 'PermissionDeniedError') {
var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
logger.error(error_5);
return reject(error_5);
}
else {
var extensionId = _this.advancedConfiguration
.screenShareChromeExtension.split('/')
.pop()
.trim();
screenSharing.getChromeExtensionStatus(extensionId, function (status) {
if (status === 'installed-disabled') {
var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
logger.error(error_6);
return reject(error_6);
}
if (status === 'not-installed') {
var error_7 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension);
logger.error(error_7);
return reject(error_7);
}
});
return;
}
}
else {
myConstraints.constraints.video = screenConstraints;
return resolve(myConstraints);
}
});
return;
}
else {
if (navigator.mediaDevices['getDisplayMedia']) {
return resolve(myConstraints);
}
else {
var firefoxString = platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()
? publisherProperties.videoSource
: undefined;
screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) {
if (!!error) {
if (error === 'not-installed') {
var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension
? _this.advancedConfiguration.screenShareChromeExtension
: 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold';
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl);
logger.error(err);
return reject(err);
}
else if (error === 'installed-disabled') {
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
logger.error(err);
return reject(err);
}
else if (error === 'permission-denied') {
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
logger.error(err);
return reject(err);
}
else {
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, 'Unknown error when accessing screen share');
logger.error(err);
logger.error(error);
return reject(err);
}
}
else {
myConstraints.constraints.video = screenConstraints.video;
return resolve(myConstraints);
}
});
return;
}
}
}
}
}
}
};
OpenVidu.prototype.setVideoSource = function (myConstraints, videoSource) {
if (!myConstraints.constraints.video) {
myConstraints.constraints.video = {};
}
myConstraints.constraints.video['deviceId'] = { exact: videoSource };
};
OpenVidu.prototype.disconnectCallback = function () {
logger.warn('Websocket connection lost');
if (this.isRoomAvailable()) {
this.session.onLostConnection('networkDisconnect');
}
else {
alert('Connection error. Please reload page.');
}
};
OpenVidu.prototype.reconnectingCallback = function () {
logger.warn('Websocket connection lost (reconnecting)');
if (!this.isRoomAvailable()) {
alert('Connection error. Please reload page.');
}
else {
this.session.emitEvent('reconnecting', []);
}
};
OpenVidu.prototype.reconnectWebsocketThroughRpcConnectMethod = function (rpcSessionId) {
var _this = this;
this.sendRequest('connect', { sessionId: rpcSessionId, reconnect: true }, function (error, response) {
if (!!error) {
if (_this.isMasterNodeCrashed()) {
logger.warn('Master Node has crashed!');
}
else {
logger.error(error);
var notifyLostConnection_1 = function (reason, errorMsg) {
logger.warn(errorMsg);
_this.session.onLostConnection(reason);
_this.jsonRpcClient.close(4101, 'Reconnection fault: ' + errorMsg);
};
var rpcSessionStatus = function () {
if (_this.life === -1) {
notifyLostConnection_1('networkDisconnect', 'WS successfully reconnected but the user was already evicted due to timeout');
}
else {
_this.sendRequest('sessionStatus', { sessionId: _this.session.sessionId }, function (error, response) {
if (error != null) {
console.error('Error checking session status', error);
}
else {
if (_this.life === response.life) {
notifyLostConnection_1('networkDisconnect', 'WS successfully reconnected but the user was already evicted due to timeout');
}
else {
notifyLostConnection_1('nodeCrashed', 'WS successfully reconnected to OpenVidu Server but your Master Node crashed');
}
}
});
}
};
if (error.code === 40007 && error.message === 'reconnection error') {
console.error('Invalid RPC sessionId. Client network disconnection or Master Node crash');
rpcSessionStatus();
}
else {
rpcSessionStatus();
}
}
}
else {
_this.jsonRpcClient.resetPing();
_this.session.onRecoveredConnection();
}
});
};
OpenVidu.prototype.reconnectedCallback = function () {
logger.warn('Websocket reconnected');
if (this.isRoomAvailable()) {
if (!!this.session.connection) {
this.reconnectWebsocketThroughRpcConnectMethod(this.session.connection.rpcSessionId);
}
else {
logger.warn('There was no previous connection when running reconnection callback');
var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this.session, 'networkDisconnect');
this.session.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]);
sessionDisconnectEvent.callDefaultBehavior();
}
}
else {
alert('Connection error. Please reload page.');
}
};
OpenVidu.prototype.isMasterNodeCrashed = function () {
return this.masterNodeHasCrashed;
};
OpenVidu.prototype.isRoomAvailable = function () {
if (this.session !== undefined && this.session instanceof Session_1.Session) {
return true;
}
else {
logger.warn('Session instance not found');
return false;
}
};
OpenVidu.prototype.isScreenShare = function (videoSource) {
return videoSource === 'screen' || videoSource === 'window' || (platform.isElectron() && videoSource.startsWith('screen:'));
};
return OpenVidu;
}());
exports.OpenVidu = OpenVidu;
},{"../../package.json":39,"../OpenViduInternal/Enums/OpenViduError":52,"../OpenViduInternal/Enums/VideoInsertMode":54,"../OpenViduInternal/Events/SessionDisconnectedEvent":63,"../OpenViduInternal/Events/StreamPropertyChangedEvent":67,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":74,"../OpenViduInternal/Logger/OpenViduLogger":79,"../OpenViduInternal/Logger/OpenViduLoggerConfiguration":80,"../OpenViduInternal/ScreenSharing/Screen-Capturing":82,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":81,"../OpenViduInternal/Utils/Platform":83,"./LocalRecorder":44,"./Publisher":46,"./Session":47,"wolfy87-eventemitter":38}],46:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Publisher = void 0;
var Session_1 = require("./Session");
var Stream_1 = require("./Stream");
var StreamManager_1 = require("./StreamManager");
var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var TypeOfVideo_1 = require("../OpenViduInternal/Enums/TypeOfVideo");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var Publisher = (function (_super) {
__extends(Publisher, _super);
function Publisher(targEl, properties, openvidu) {
var _this = _super.call(this, new Stream_1.Stream(!!openvidu.session ? openvidu.session : new Session_1.Session(openvidu), {
publisherProperties: properties,
mediaConstraints: {}
}), targEl) || this;
_this.accessAllowed = false;
_this.isSubscribedToRemote = false;
_this.accessDenied = false;
platform = Platform_1.PlatformUtils.getInstance();
_this.properties = properties;
_this.openvidu = openvidu;
_this.stream.ee.on('local-stream-destroyed', function (reason) {
_this.stream.isLocalStreamPublished = false;
var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason);
_this.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
});
return _this;
}
Publisher.prototype.publishAudio = function (enabled) {
var _this = this;
if (this.stream.audioActive !== enabled) {
var affectedMediaStream = this.stream.displayMyRemote()
? this.stream.localMediaStreamWhenSubscribedToRemote
: this.stream.getMediaStream();
affectedMediaStream.getAudioTracks().forEach(function (track) {
track.enabled = enabled;
});
if (!!this.session && !!this.stream.streamId) {
this.session.openvidu.sendRequest('streamPropertyChanged', {
streamId: this.stream.streamId,
property: 'audioActive',
newValue: enabled,
reason: 'publishAudio'
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', enabled, !enabled, 'publishAudio')
]);
_this.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', enabled, !enabled, 'publishAudio')
]);
_this.session.sendVideoData(_this.stream.streamManager);
}
});
}
this.stream.audioActive = enabled;
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its audio stream');
}
};
Publisher.prototype.publishVideo = function (enabled, resource) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var affectedMediaStream_1, mustRestartMediaStream_1, oldVideoTrack, replaceVideoTrack, mediaStream, error_1;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.stream.videoActive !== enabled)) return [3, 9];
affectedMediaStream_1 = this.stream.displayMyRemote()
? this.stream.localMediaStreamWhenSubscribedToRemote
: this.stream.getMediaStream();
mustRestartMediaStream_1 = false;
affectedMediaStream_1.getVideoTracks().forEach(function (track) {
track.enabled = enabled;
if (!enabled && resource === true) {
track.stop();
}
else if (enabled && track.readyState === 'ended') {
mustRestartMediaStream_1 = true;
}
});
if (!(!enabled && resource === true && !!this.stream.filter && this.stream.filter.type.startsWith('VB:'))) return [3, 2];
this.stream.lastVBFilter = this.stream.filter;
return [4, this.stream.removeFilterAux(true)];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (!mustRestartMediaStream_1) return [3, 8];
oldVideoTrack = affectedMediaStream_1.getVideoTracks()[0];
affectedMediaStream_1.removeTrack(oldVideoTrack);
replaceVideoTrack = function (tr) { return __awaiter(_this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
affectedMediaStream_1.addTrack(tr);
if (!this.stream.isLocalStreamPublished) return [3, 2];
return [4, this.replaceTrackInRtcRtpSender(tr)];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (!!this.stream.lastVBFilter) {
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
var options, lastExecMethod;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
options = this.stream.lastVBFilter.options;
lastExecMethod = this.stream.lastVBFilter.lastExecMethod;
if (!!lastExecMethod && lastExecMethod.method === 'update') {
options = Object.assign({}, options, lastExecMethod.params);
}
return [4, this.stream.applyFilter(this.stream.lastVBFilter.type, options)];
case 1:
_a.sent();
delete this.stream.lastVBFilter;
return [2];
}
});
}); }, 1);
}
return [2];
}
});
}); };
if (!(!!resource && resource instanceof MediaStreamTrack)) return [3, 4];
return [4, replaceVideoTrack(resource)];
case 3:
_a.sent();
return [3, 8];
case 4:
_a.trys.push([4, 7, , 8]);
return [4, navigator.mediaDevices.getUserMedia({
audio: false,
video: this.stream.lastVideoTrackConstraints
})];
case 5:
mediaStream = _a.sent();
return [4, replaceVideoTrack(mediaStream.getVideoTracks()[0])];
case 6:
_a.sent();
return [3, 8];
case 7:
error_1 = _a.sent();
return [2, reject(error_1)];
case 8:
if (!!this.session && !!this.stream.streamId) {
this.session.openvidu.sendRequest('streamPropertyChanged', {
streamId: this.stream.streamId,
property: 'videoActive',
newValue: enabled,
reason: 'publishVideo'
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
_this.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
_this.session.sendVideoData(_this.stream.streamManager);
}
});
}
this.stream.videoActive = enabled;
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its video stream');
return [2, resolve()];
case 9: return [2];
}
});
}); });
};
Publisher.prototype.subscribeToRemote = function (value) {
value = value !== undefined ? value : true;
this.isSubscribedToRemote = value;
this.stream.subscribeToMyRemote(value);
};
Publisher.prototype.on = function (type, handler) {
var _this = this;
_super.prototype.on.call(this, type, handler);
if (type === 'streamCreated') {
if (!!this.stream && this.stream.isLocalStreamPublished) {
this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]);
}
else {
this.stream.ee.on('stream-created-by-publisher', function () {
_this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]);
});
}
}
if (type === 'accessAllowed') {
if (this.accessAllowed) {
this.emitEvent('accessAllowed', []);
}
}
if (type === 'accessDenied') {
if (this.accessDenied) {
this.emitEvent('accessDenied', []);
}
}
return this;
};
Publisher.prototype.once = function (type, handler) {
var _this = this;
_super.prototype.once.call(this, type, handler);
if (type === 'streamCreated') {
if (!!this.stream && this.stream.isLocalStreamPublished) {
this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]);
}
else {
this.stream.ee.once('stream-created-by-publisher', function () {
_this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]);
});
}
}
if (type === 'accessAllowed') {
if (this.accessAllowed) {
this.emitEvent('accessAllowed', []);
}
}
if (type === 'accessDenied') {
if (this.accessDenied) {
this.emitEvent('accessDenied', []);
}
}
return this;
};
Publisher.prototype.off = function (type, handler) {
_super.prototype.off.call(this, type, handler);
return this;
};
Publisher.prototype.replaceTrack = function (track) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.replaceTrackAux(track, true)];
});
});
};
Publisher.prototype.initialize = function () {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var constraints, constraintsAux, timeForDialogEvent, startTime, errorCallback, successCallback, getMediaSuccess, getMediaError, myConstraints, outboundStreamOptions, definedAudioConstraint, mediaStream, mediaStream, error_2, error_3;
var _this = this;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
constraints = {};
constraintsAux = {};
timeForDialogEvent = 2000;
errorCallback = function (openViduError) {
_this.accessDenied = true;
_this.accessAllowed = false;
logger.error("Publisher initialization failed. ".concat(openViduError.name, ": ").concat(openViduError.message));
return reject(openViduError);
};
successCallback = function (mediaStream) {
var _a, _b;
_this.accessAllowed = true;
_this.accessDenied = false;
if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) {
mediaStream.removeTrack(mediaStream.getAudioTracks()[0]);
mediaStream.addTrack(_this.properties.audioSource);
}
if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) {
mediaStream.removeTrack(mediaStream.getVideoTracks()[0]);
mediaStream.addTrack(_this.properties.videoSource);
}
if (!!mediaStream.getAudioTracks()[0]) {
var enabled = _this.stream.audioActive !== undefined && _this.stream.audioActive !== null
? _this.stream.audioActive
: !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio;
mediaStream.getAudioTracks()[0].enabled = enabled;
}
if (!!mediaStream.getVideoTracks()[0]) {
var enabled = _this.stream.videoActive !== undefined && _this.stream.videoActive !== null
? _this.stream.videoActive
: !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo;
mediaStream.getVideoTracks()[0].enabled = enabled;
}
for (var _i = 0, _c = mediaStream.getAudioTracks(); _i < _c.length; _i++) {
var track = _c[_i];
if (!((_a = track.contentHint) === null || _a === void 0 ? void 0 : _a.length)) {
track.contentHint = '';
logger.info("Audio track Content Hint set: '".concat(track.contentHint, "'"));
}
}
for (var _d = 0, _e = mediaStream.getVideoTracks(); _d < _e.length; _d++) {
var track = _e[_d];
if (!((_b = track.contentHint) === null || _b === void 0 ? void 0 : _b.length)) {
switch (_this.stream.typeOfVideo) {
case TypeOfVideo_1.TypeOfVideo.SCREEN:
track.contentHint = 'detail';
break;
case TypeOfVideo_1.TypeOfVideo.CUSTOM:
logger.warn('CUSTOM type video track was provided without Content Hint!');
track.contentHint = 'motion';
break;
case TypeOfVideo_1.TypeOfVideo.CAMERA:
case TypeOfVideo_1.TypeOfVideo.IPCAM:
default:
track.contentHint = 'motion';
break;
}
logger.info("Video track Content Hint set: '".concat(track.contentHint, "'"));
}
}
_this.initializeVideoReference(mediaStream);
if (!_this.stream.displayMyRemote()) {
_this.stream.updateMediaStreamInVideos();
}
delete _this.firstVideoElement;
if (_this.stream.isSendVideo()) {
_this.getVideoDimensions().then(function (dimensions) {
_this.stream.videoDimensions = {
width: dimensions.width,
height: dimensions.height
};
if (_this.stream.isSendScreen()) {
_this.screenShareResizeInterval = setInterval(function () {
var settings = mediaStream.getVideoTracks()[0].getSettings();
var newWidth = settings.width;
var newHeight = settings.height;
var widthChanged = newWidth != null && newWidth !== _this.stream.videoDimensions.width;
var heightChanged = newHeight != null && newHeight !== _this.stream.videoDimensions.height;
if (_this.stream.isLocalStreamPublished && (widthChanged || heightChanged)) {
_this.openvidu.sendVideoDimensionsChangedEvent(_this, 'screenResized', _this.stream.videoDimensions.width, _this.stream.videoDimensions.height, newWidth || 0, newHeight || 0);
}
}, 650);
}
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
});
}
else {
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
}
return resolve();
};
getMediaSuccess = function (mediaStream, definedAudioConstraint) { return __awaiter(_this, void 0, void 0, function () {
var audioOnlyStream, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
if (!(this.stream.isSendScreen() && this.stream.isSendAudio())) return [3, 5];
constraintsAux.audio = definedAudioConstraint;
constraintsAux.video = false;
startTime = Date.now();
this.setPermissionDialogTimer(timeForDialogEvent);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 2:
audioOnlyStream = _a.sent();
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]);
successCallback(mediaStream);
return [3, 4];
case 3:
error_4 = _a.sent();
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
mediaStream.getAudioTracks().forEach(function (track) {
track.stop();
});
mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
errorCallback(this.openvidu.generateAudioDeviceError(error_4, constraints));
return [2];
case 4: return [3, 6];
case 5:
successCallback(mediaStream);
_a.label = 6;
case 6: return [2];
}
});
}); };
getMediaError = function (error) { return __awaiter(_this, void 0, void 0, function () {
var errorName, errorMessage, _a, mediaStream, error_5, mediaStream, error_6;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
logger.error("getMediaError: ".concat(error.toString()));
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
if (error.name === 'Error') {
error.name = error.constructor.name;
}
_a = error.name.toLowerCase();
switch (_a) {
case 'notfounderror': return [3, 1];
case 'notallowederror': return [3, 5];
case 'overconstrainederror': return [3, 6];
case 'aborterror': return [3, 10];
case 'notreadableerror': return [3, 10];
}
return [3, 11];
case 1:
_b.trys.push([1, 3, , 4]);
return [4, navigator.mediaDevices.getUserMedia({
audio: false,
video: constraints.video
})];
case 2:
mediaStream = _b.sent();
mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 4];
case 3:
error_5 = _b.sent();
errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND;
errorMessage = error_5.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 4];
case 4: return [3, 12];
case 5:
errorName = this.stream.isSendScreen()
? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED
: OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 12];
case 6:
_b.trys.push([6, 8, , 9]);
return [4, navigator.mediaDevices.getUserMedia({
audio: false,
video: constraints.video
})];
case 7:
mediaStream = _b.sent();
mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
if (error.constraint.toLowerCase() === 'deviceid') {
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage =
"Audio input device with deviceId '" +
constraints.audio.deviceId.exact +
"' not found";
}
else {
errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR;
errorMessage =
"Audio input device doesn't support the value passed for constraint '" + error.constraint + "'";
}
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 9];
case 8:
error_6 = _b.sent();
if (error_6.constraint.toLowerCase() === 'deviceid') {
errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND;
errorMessage =
"Video input device with deviceId '" +
constraints.video.deviceId.exact +
"' not found";
}
else {
errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR;
errorMessage =
"Video input device doesn't support the value passed for constraint '" + error_6.constraint + "'";
}
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 9];
case 9: return [3, 12];
case 10:
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 12];
case 11:
errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 12];
case 12: return [2];
}
});
}); };
_c.label = 1;
case 1:
_c.trys.push([1, 14, , 15]);
return [4, this.openvidu.generateMediaConstraints(this.properties)];
case 2:
myConstraints = _c.sent();
if (!((!!myConstraints.videoTrack && !!myConstraints.audioTrack) ||
(!!myConstraints.audioTrack && ((_a = myConstraints.constraints) === null || _a === void 0 ? void 0 : _a.video) === false) ||
(!!myConstraints.videoTrack && ((_b = myConstraints.constraints) === null || _b === void 0 ? void 0 : _b.audio) === false))) return [3, 3];
successCallback(this.openvidu.addAlreadyProvidedTracks(myConstraints, new MediaStream(), this.stream));
return [3, 13];
case 3:
constraints = myConstraints.constraints;
outboundStreamOptions = {
mediaConstraints: constraints,
publisherProperties: this.properties
};
this.stream.setOutboundStreamOptions(outboundStreamOptions);
definedAudioConstraint = constraints.audio === undefined ? true : constraints.audio;
constraintsAux.audio = this.stream.isSendScreen() ? false : definedAudioConstraint;
constraintsAux.video = constraints.video;
startTime = Date.now();
this.setPermissionDialogTimer(timeForDialogEvent);
_c.label = 4;
case 4:
_c.trys.push([4, 11, , 13]);
if (!(this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron())) return [3, 7];
return [4, navigator.mediaDevices['getDisplayMedia']({ video: true })];
case 5:
mediaStream = _c.sent();
this.openvidu.addAlreadyProvidedTracks(myConstraints, mediaStream);
return [4, getMediaSuccess(mediaStream, definedAudioConstraint)];
case 6:
_c.sent();
return [3, 10];
case 7:
this.stream.lastVideoTrackConstraints = constraintsAux.video;
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 8:
mediaStream = _c.sent();
this.openvidu.addAlreadyProvidedTracks(myConstraints, mediaStream, this.stream);
return [4, getMediaSuccess(mediaStream, definedAudioConstraint)];
case 9:
_c.sent();
_c.label = 10;
case 10: return [3, 13];
case 11:
error_2 = _c.sent();
return [4, getMediaError(error_2)];
case 12:
_c.sent();
return [3, 13];
case 13: return [3, 15];
case 14:
error_3 = _c.sent();
errorCallback(error_3);
return [3, 15];
case 15: return [2];
}
});
}); });
};
Publisher.prototype.replaceTrackAux = function (track, updateLastConstraints) {
return __awaiter(this, void 0, void 0, function () {
var trackOriginalEnabledValue, error_7;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
trackOriginalEnabledValue = track.enabled;
if (track.kind === 'video') {
track.enabled = this.stream.videoActive;
}
else if (track.kind === 'audio') {
track.enabled = this.stream.audioActive;
}
_a.label = 1;
case 1:
_a.trys.push([1, 5, , 6]);
if (!this.stream.isLocalStreamPublished) return [3, 3];
this.replaceTrackInMediaStream(track, updateLastConstraints);
return [4, this.replaceTrackInRtcRtpSender(track)];
case 2: return [2, _a.sent()];
case 3: return [2, this.replaceTrackInMediaStream(track, updateLastConstraints)];
case 4: return [3, 6];
case 5:
error_7 = _a.sent();
track.enabled = trackOriginalEnabledValue;
throw error_7;
case 6: return [2];
}
});
});
};
Publisher.prototype.getVideoDimensions = function () {
var _this = this;
return new Promise(function (resolve, reject) {
var requiresDomInsertion = platform.isIonicIos() || platform.isIOSWithSafari();
var loadedmetadataListener;
var resolveDimensions = function () {
var width;
var height;
if (typeof _this.stream.getMediaStream().getVideoTracks()[0].getSettings === 'function') {
var settings = _this.stream.getMediaStream().getVideoTracks()[0].getSettings();
width = settings.width || _this.videoReference.videoWidth;
height = settings.height || _this.videoReference.videoHeight;
}
else {
logger.warn('MediaStreamTrack does not have getSettings method on ' + platform.getDescription());
width = _this.videoReference.videoWidth;
height = _this.videoReference.videoHeight;
}
if (loadedmetadataListener != null) {
_this.videoReference.removeEventListener('loadedmetadata', loadedmetadataListener);
}
if (requiresDomInsertion) {
document.body.removeChild(_this.videoReference);
}
return resolve({ width: width, height: height });
};
if (_this.videoReference.readyState >= 1) {
resolveDimensions();
}
else {
loadedmetadataListener = function () {
if (!_this.videoReference.videoWidth) {
var interval_1 = setInterval(function () {
if (!!_this.videoReference.videoWidth) {
clearInterval(interval_1);
resolveDimensions();
}
}, 40);
}
else {
resolveDimensions();
}
};
_this.videoReference.addEventListener('loadedmetadata', loadedmetadataListener);
if (requiresDomInsertion) {
document.body.appendChild(_this.videoReference);
}
}
});
};
Publisher.prototype.reestablishStreamPlayingEvent = function () {
if (this.ee.getListeners('streamPlaying').length > 0) {
this.addPlayEventToFirstVideo();
}
};
Publisher.prototype.initializeVideoReference = function (mediaStream) {
this.videoReference = document.createElement('video');
this.videoReference.style.display = 'none';
this.videoReference.muted = true;
this.videoReference.autoplay = true;
this.videoReference.controls = false;
if (platform.isSafariBrowser() ||
(platform.isIPhoneOrIPad() &&
(platform.isChromeMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isFirefoxMobileBrowser()))) {
this.videoReference.playsInline = true;
}
this.stream.setMediaStream(mediaStream);
if (!!this.firstVideoElement) {
this.createVideoElement(this.firstVideoElement.targetElement, this.properties.insertMode);
}
this.videoReference.srcObject = this.stream.getMediaStream();
};
Publisher.prototype.replaceTrackInMediaStream = function (track, updateLastConstraints) {
var mediaStream = this.stream.displayMyRemote()
? this.stream.localMediaStreamWhenSubscribedToRemote
: this.stream.getMediaStream();
var removedTrack;
if (track.kind === 'video') {
removedTrack = mediaStream.getVideoTracks()[0];
if (updateLastConstraints) {
this.stream.lastVideoTrackConstraints = track.getConstraints();
}
}
else {
removedTrack = mediaStream.getAudioTracks()[0];
}
removedTrack.enabled = false;
removedTrack.stop();
mediaStream.removeTrack(removedTrack);
mediaStream.addTrack(track);
var trackInfo = {
oldLabel: (removedTrack === null || removedTrack === void 0 ? void 0 : removedTrack.label) || '',
newLabel: (track === null || track === void 0 ? void 0 : track.label) || ''
};
if (track.kind === 'video' && updateLastConstraints) {
this.openvidu.sendNewVideoDimensionsIfRequired(this, 'trackReplaced', 50, 30);
this.openvidu.sendTrackChangedEvent(this, 'trackReplaced', trackInfo.oldLabel, trackInfo.newLabel, 'videoActive');
if (this.stream.isLocalStreamPublished) {
this.session.sendVideoData(this.stream.streamManager, 5, true, 5);
}
}
else if (track.kind === 'audio' && updateLastConstraints) {
this.openvidu.sendTrackChangedEvent(this, 'trackReplaced', trackInfo.oldLabel, trackInfo.newLabel, 'audioActive');
}
if (track.kind === 'audio') {
this.stream.disableHarkSpeakingEvent(false);
this.stream.disableHarkStoppedSpeakingEvent(false);
this.stream.disableHarkVolumeChangeEvent(false);
this.stream.initHarkEvents();
}
};
Publisher.prototype.setPermissionDialogTimer = function (waitTime) {
var _this = this;
this.permissionDialogTimeout = setTimeout(function () {
_this.emitEvent('accessDialogOpened', []);
}, waitTime);
};
Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) {
clearTimeout(this.permissionDialogTimeout);
if (Date.now() - startTime > waitTime) {
this.emitEvent('accessDialogClosed', []);
}
};
Publisher.prototype.replaceTrackInRtcRtpSender = function (track) {
return __awaiter(this, void 0, void 0, function () {
var senders, sender;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
senders = this.stream.getRTCPeerConnection().getSenders();
if (track.kind === 'video') {
sender = senders.find(function (s) { return !!s.track && s.track.kind === 'video'; });
if (!sender) {
throw new Error("There's no replaceable track for that kind of MediaStreamTrack in this Publisher object");
}
}
else if (track.kind === 'audio') {
sender = senders.find(function (s) { return !!s.track && s.track.kind === 'audio'; });
if (!sender) {
throw new Error("There's no replaceable track for that kind of MediaStreamTrack in this Publisher object");
}
}
else {
throw new Error('Unknown track kind ' + track.kind);
}
return [4, sender.replaceTrack(track)];
case 1:
_a.sent();
return [2];
}
});
});
};
return Publisher;
}(StreamManager_1.StreamManager));
exports.Publisher = Publisher;
},{"../OpenViduInternal/Enums/OpenViduError":52,"../OpenViduInternal/Enums/TypeOfVideo":53,"../OpenViduInternal/Events/StreamEvent":65,"../OpenViduInternal/Events/StreamPropertyChangedEvent":67,"../OpenViduInternal/Logger/OpenViduLogger":79,"../OpenViduInternal/Utils/Platform":83,"./Session":47,"./Stream":48,"./StreamManager":49}],47:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Session = void 0;
var Connection_1 = require("./Connection");
var Filter_1 = require("./Filter");
var Subscriber_1 = require("./Subscriber");
var EventDispatcher_1 = require("./EventDispatcher");
var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent");
var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent");
var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent");
var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent");
var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent");
var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var ConnectionPropertyChangedEvent_1 = require("../OpenViduInternal/Events/ConnectionPropertyChangedEvent");
var NetworkQualityLevelChangedEvent_1 = require("../OpenViduInternal/Events/NetworkQualityLevelChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var semverMajor = require("semver/functions/major");
var semverMinor = require("semver/functions/minor");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var Session = (function (_super) {
__extends(Session, _super);
function Session(openvidu) {
var _this = _super.call(this) || this;
_this.streamManagers = [];
_this.remoteStreamsCreated = new Map();
_this.remoteConnections = new Map();
platform = Platform_1.PlatformUtils.getInstance();
_this.openvidu = openvidu;
return _this;
}
Session.prototype.connect = function (token, metadata) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.processToken(token);
if (_this.openvidu.checkSystemRequirements()) {
_this.options = {
sessionId: _this.sessionId,
participantId: token,
metadata: !!metadata ? _this.stringClientMetadata(metadata) : ''
};
_this.connectAux(token)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' +
platform.getName() +
' (version ' +
platform.getVersion() +
') for ' +
platform.getFamily() +
' is not supported in OpenVidu'));
}
});
};
Session.prototype.disconnect = function () {
this.leave(false, 'disconnect');
};
Session.prototype.subscribe = function (stream, targetElement, param3, param4) {
var properties = {};
if (!!param3 && typeof param3 !== 'function') {
properties = {
insertMode: typeof param3.insertMode !== 'undefined'
? typeof param3.insertMode === 'string'
? VideoInsertMode_1.VideoInsertMode[param3.insertMode]
: properties.insertMode
: VideoInsertMode_1.VideoInsertMode.APPEND,
subscribeToAudio: typeof param3.subscribeToAudio !== 'undefined' ? param3.subscribeToAudio : true,
subscribeToVideo: typeof param3.subscribeToVideo !== 'undefined' ? param3.subscribeToVideo : true
};
}
else {
properties = {
insertMode: VideoInsertMode_1.VideoInsertMode.APPEND,
subscribeToAudio: true,
subscribeToVideo: true
};
}
var completionHandler = undefined;
if (!!param3 && typeof param3 === 'function') {
completionHandler = param3;
}
else if (!!param4) {
completionHandler = param4;
}
if (!this.sessionConnected()) {
if (completionHandler !== undefined) {
completionHandler(this.notConnectedError());
}
throw this.notConnectedError();
}
logger.info('Subscribing to ' + stream.connection.connectionId);
stream
.subscribe()
.then(function () {
logger.info('Subscribed correctly to ' + stream.connection.connectionId);
if (completionHandler !== undefined) {
completionHandler(undefined);
}
})
.catch(function (error) {
if (completionHandler !== undefined) {
completionHandler(error);
}
});
var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties);
if (!!subscriber.targetElement) {
stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode);
}
return subscriber;
};
Session.prototype.subscribeAsync = function (stream, targetElement, properties) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
var subscriber;
var callback = function (error) {
if (!!error) {
return reject(error);
}
else {
return resolve(subscriber);
}
};
if (!!properties) {
subscriber = _this.subscribe(stream, targetElement, properties, callback);
}
else {
subscriber = _this.subscribe(stream, targetElement, callback);
}
});
};
Session.prototype.unsubscribe = function (subscriber) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
else {
var connectionId_1 = subscriber.stream.connection.connectionId;
logger.info('Unsubscribing from ' + connectionId_1);
_this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) {
if (error) {
logger.error('Error unsubscribing from ' + connectionId_1);
return reject(error);
}
else {
logger.info('Unsubscribed correctly from ' + connectionId_1);
subscriber.stream.streamManager.removeAllVideos();
subscriber.stream.disposeWebRtcPeer();
subscriber.stream.disposeMediaStream();
return resolve();
}
});
}
});
};
Session.prototype.publish = function (publisher) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
publisher.session = _this;
publisher.stream.session = _this;
if (!publisher.stream.publishedOnce) {
_this.connection.addStream(publisher.stream);
publisher.stream
.publish()
.then(function () {
_this.sendVideoData(publisher, 8, true, 5);
return resolve();
})
.catch(function (error) { return reject(error); });
}
else {
publisher
.initialize()
.then(function () {
_this.connection.addStream(publisher.stream);
publisher.reestablishStreamPlayingEvent();
publisher.stream
.publish()
.then(function () {
_this.sendVideoData(publisher, 8, true, 5);
return resolve();
})
.catch(function (error) { return reject(error); });
})
.catch(function (error) { return reject(error); });
}
});
};
Session.prototype.unpublish = function (publisher) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
throw _this.notConnectedError();
}
var stream = publisher.stream;
if (!stream.connection) {
return reject(new Error('The associated Connection object of this Publisher is null'));
}
else if (stream.connection !== _this.connection) {
return reject(new Error('The associated Connection object of this Publisher is not your local Connection. ' +
"Only moderators can force unpublish on remote Streams via 'forceUnpublish' method"));
}
else {
logger.info('Unpublishing local media (' + stream.connection.connectionId + ')');
_this.openvidu.sendRequest('unpublishVideo', function (error, response) {
if (error) {
return reject(error);
}
else {
logger.info('Media unpublished correctly');
stream.disposeWebRtcPeer();
if (stream.connection.stream == stream) {
delete stream.connection.stream;
}
var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish');
publisher.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
return resolve();
}
});
}
});
};
Session.prototype.forceDisconnect = function (connection) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
logger.info('Forcing disconnect for connection ' + connection.connectionId);
_this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) {
if (error) {
logger.error('Error forcing disconnect for Connection ' + connection.connectionId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection"));
}
else {
return reject(error);
}
}
else {
logger.info('Forcing disconnect correctly for Connection ' + connection.connectionId);
return resolve();
}
});
});
};
Session.prototype.forceUnpublish = function (stream) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
logger.info('Forcing unpublish for stream ' + stream.streamId);
_this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) {
if (error) {
logger.error('Error forcing unpublish for Stream ' + stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing"));
}
else {
return reject(error);
}
}
else {
logger.info('Forcing unpublish correctly for Stream ' + stream.streamId);
return resolve();
}
});
});
};
Session.prototype.signal = function (signal) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
var signalMessage = {};
if (signal.to && signal.to.length > 0) {
var connectionIds_1 = [];
signal.to.forEach(function (connection) {
if (!!connection.connectionId) {
connectionIds_1.push(connection.connectionId);
}
});
signalMessage['to'] = connectionIds_1;
}
else {
signalMessage['to'] = [];
}
signalMessage['data'] = signal.data ? signal.data : '';
var typeAux = signal.type ? signal.type : 'signal';
if (!!typeAux) {
if (typeAux.substring(0, 7) !== 'signal:') {
typeAux = 'signal:' + typeAux;
}
}
signalMessage['type'] = typeAux;
_this.openvidu.sendRequest('sendMessage', {
message: JSON.stringify(signalMessage)
}, function (error, response) {
if (!!error) {
return reject(error);
}
else {
return resolve();
}
});
});
};
Session.prototype.on = function (type, handler) {
var _a, _b, _c, _d;
_super.prototype.onAux.call(this, type, "Event '" + type + "' triggered by 'Session'", handler);
if (type === 'publisherStartSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableHarkSpeakingEvent();
}
});
if (!!((_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.hasAudio)) {
this.connection.stream.enableHarkSpeakingEvent();
}
}
if (type === 'publisherStopSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableHarkStoppedSpeakingEvent();
}
});
if (!!((_d = (_c = this.connection) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.hasAudio)) {
this.connection.stream.enableHarkStoppedSpeakingEvent();
}
}
return this;
};
Session.prototype.once = function (type, handler) {
var _a, _b, _c, _d;
_super.prototype.onceAux.call(this, type, "Event '" + type + "' triggered once by 'Session'", handler);
if (type === 'publisherStartSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableOnceHarkSpeakingEvent();
}
});
if (!!((_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.hasAudio)) {
this.connection.stream.enableOnceHarkSpeakingEvent();
}
}
if (type === 'publisherStopSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableOnceHarkStoppedSpeakingEvent();
}
});
if (!!((_d = (_c = this.connection) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.hasAudio)) {
this.connection.stream.enableOnceHarkStoppedSpeakingEvent();
}
}
return this;
};
Session.prototype.off = function (type, handler) {
var _this = this;
var _a, _b, _c, _d;
_super.prototype.offAux.call(this, type, handler);
if (type === 'publisherStartSpeaking') {
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false)) {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.streamManager)) {
if (!_this.anySpeechEventListenerEnabled('publisherStartSpeaking', false, remoteConnection.stream.streamManager)) {
remoteConnection.stream.disableHarkSpeakingEvent(false);
}
}
});
if (!!((_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.streamManager)) {
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false, this.connection.stream.streamManager)) {
this.connection.stream.disableHarkSpeakingEvent(false);
}
}
}
}
if (type === 'publisherStopSpeaking') {
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false)) {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.streamManager)) {
if (!_this.anySpeechEventListenerEnabled('publisherStopSpeaking', false, remoteConnection.stream.streamManager)) {
remoteConnection.stream.disableHarkStoppedSpeakingEvent(false);
}
}
});
if (!!((_d = (_c = this.connection) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.streamManager)) {
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false, this.connection.stream.streamManager)) {
this.connection.stream.disableHarkStoppedSpeakingEvent(false);
}
}
}
}
return this;
};
Session.prototype.onParticipantJoined = function (event) {
var _this = this;
this.getConnection(event.id, '')
.then(function (connection) {
logger.warn('Connection ' + connection.connectionId + ' already exists in connections list');
})
.catch(function (openViduError) {
var connection = new Connection_1.Connection(_this, event);
_this.remoteConnections.set(event.id, connection);
_this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]);
});
};
Session.prototype.onParticipantLeft = function (event) {
var _this = this;
this.getRemoteConnection(event.connectionId, 'onParticipantLeft')
.then(function (connection) {
if (!!connection.stream) {
var stream = connection.stream;
var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, event.reason);
_this.ee.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
_this.remoteStreamsCreated.delete(stream.streamId);
}
_this.remoteConnections.delete(connection.connectionId);
_this.ee.emitEvent('connectionDestroyed', [
new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, event.reason)
]);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
};
Session.prototype.onParticipantPublished = function (event) {
var _this = this;
var afterConnectionFound = function (connection) {
_this.remoteConnections.set(connection.connectionId, connection);
if (!_this.remoteStreamsCreated.get(connection.stream.streamId)) {
_this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]);
}
_this.remoteStreamsCreated.set(connection.stream.streamId, true);
};
var connection;
this.getRemoteConnection(event.id, 'onParticipantPublished')
.then(function (con) {
connection = con;
event.metadata = con.data;
connection.remoteOptions = event;
connection.initRemoteStreams(event.streams);
afterConnectionFound(connection);
})
.catch(function (openViduError) {
connection = new Connection_1.Connection(_this, event);
afterConnectionFound(connection);
});
};
Session.prototype.onParticipantUnpublished = function (event) {
var _this = this;
if (event.connectionId === this.connection.connectionId) {
this.stopPublisherStream(event.reason);
}
else {
this.getRemoteConnection(event.connectionId, 'onParticipantUnpublished')
.then(function (connection) {
var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, event.reason);
_this.ee.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
var streamId = connection.stream.streamId;
_this.remoteStreamsCreated.delete(streamId);
connection.removeStream(streamId);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
};
Session.prototype.onParticipantEvicted = function (event) {
if (event.connectionId === this.connection.connectionId) {
if (!!this.sessionId && !this.connection.disposed) {
this.leave(true, event.reason);
}
}
};
Session.prototype.onNewMessage = function (event) {
var _this = this;
logger.info('New signal: ' + JSON.stringify(event));
var strippedType = !!event.type ? event.type.replace(/^(signal:)/, '') : undefined;
if (!!event.from) {
this.getConnection(event.from, "Connection '" +
event.from +
"' unknown when 'onNewMessage'. Existing remote connections: " +
JSON.stringify(this.remoteConnections.keys()) +
'. Existing local connection: ' +
this.connection.connectionId)
.then(function (connection) {
_this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, strippedType, event.data, connection)]);
if (!!event.type && event.type !== 'signal') {
_this.ee.emitEvent(event.type, [new SignalEvent_1.SignalEvent(_this, strippedType, event.data, connection)]);
}
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
else {
this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(this, strippedType, event.data, undefined)]);
if (!!event.type && event.type !== 'signal') {
this.ee.emitEvent(event.type, [new SignalEvent_1.SignalEvent(this, strippedType, event.data, undefined)]);
}
}
};
Session.prototype.onStreamPropertyChanged = function (event) {
var _this = this;
var callback = function (connection) {
if (!!connection.stream && connection.stream.streamId === event.streamId) {
var stream = connection.stream;
var oldValue = void 0;
switch (event.property) {
case 'audioActive':
oldValue = stream.audioActive;
event.newValue = event.newValue === 'true';
stream.audioActive = event.newValue;
break;
case 'videoActive':
oldValue = stream.videoActive;
event.newValue = event.newValue === 'true';
stream.videoActive = event.newValue;
break;
case 'videoDimensions':
oldValue = stream.videoDimensions;
event.newValue = JSON.parse(JSON.parse(event.newValue));
stream.videoDimensions = event.newValue;
break;
case 'filter':
oldValue = stream.filter;
event.newValue = Object.keys(event.newValue).length > 0 ? event.newValue : undefined;
if (event.newValue !== undefined) {
stream.filter = new Filter_1.Filter(event.newValue.type, event.newValue.options);
stream.filter.stream = stream;
if (event.newValue.lastExecMethod) {
stream.filter.lastExecMethod = event.newValue.lastExecMethod;
}
}
else {
delete stream.filter;
}
event.newValue = stream.filter;
break;
}
_this.ee.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, event.property, event.newValue, oldValue, event.reason)
]);
if (!!stream.streamManager) {
stream.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, event.property, event.newValue, oldValue, event.reason)
]);
}
}
else {
logger.error("No stream with streamId '" +
event.streamId +
"' found for connection '" +
event.connectionId +
"' on 'streamPropertyChanged' event");
}
};
if (event.connectionId === this.connection.connectionId) {
callback(this.connection);
}
else {
this.getRemoteConnection(event.connectionId, 'onStreamPropertyChanged')
.then(function (connection) {
callback(connection);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
};
Session.prototype.onConnectionPropertyChanged = function (event) {
var oldValue;
switch (event.property) {
case 'role':
oldValue = this.connection.role.slice();
this.connection.role = event.newValue;
this.connection.localOptions.role = event.newValue;
break;
case 'record':
oldValue = this.connection.record;
event.newValue = event.newValue === 'true';
this.connection.record = event.newValue;
this.connection.localOptions.record = event.newValue;
break;
}
this.ee.emitEvent('connectionPropertyChanged', [
new ConnectionPropertyChangedEvent_1.ConnectionPropertyChangedEvent(this, this.connection, event.property, event.newValue, oldValue)
]);
};
Session.prototype.onNetworkQualityLevelChangedChanged = function (event) {
var _this = this;
if (event.connectionId === this.connection.connectionId) {
this.ee.emitEvent('networkQualityLevelChanged', [
new NetworkQualityLevelChangedEvent_1.NetworkQualityLevelChangedEvent(this, event.newValue, event.oldValue, this.connection)
]);
}
else {
this.getConnection(event.connectionId, 'Connection not found for connectionId ' + event.connectionId)
.then(function (connection) {
_this.ee.emitEvent('networkQualityLevelChanged', [
new NetworkQualityLevelChangedEvent_1.NetworkQualityLevelChangedEvent(_this, event.newValue, event.oldValue, connection)
]);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
};
Session.prototype.recvIceCandidate = function (event) {
var candidateInit = {
candidate: event.candidate,
sdpMLineIndex: event.sdpMLineIndex,
sdpMid: event.sdpMid
};
var iceCandidate = new RTCIceCandidate(candidateInit);
this.getConnection(event.senderConnectionId, 'Connection not found for connectionId ' +
event.senderConnectionId +
' owning endpoint ' +
event.endpointName +
'. Ice candidate will be ignored: ' +
iceCandidate)
.then(function (connection) {
var stream = connection.stream;
stream
.getWebRtcPeer()
.addIceCandidate(iceCandidate)
.catch(function (error) {
logger.error('Error adding candidate for ' + stream.streamId + ' stream of endpoint ' + event.endpointName + ': ' + error);
});
})
.catch(function (openViduError) {
logger.error(openViduError);
});
};
Session.prototype.onSessionClosed = function (msg) {
logger.info('Session closed: ' + JSON.stringify(msg));
var s = msg.sessionId;
if (s !== undefined) {
this.ee.emitEvent('session-closed', [
{
session: s
}
]);
}
else {
logger.warn('Session undefined on session closed', msg);
}
};
Session.prototype.onLostConnection = function (reason) {
logger.warn('Lost connection in Session ' + this.sessionId);
if (!!this.sessionId && !!this.connection && !this.connection.disposed) {
this.leave(true, reason);
}
};
Session.prototype.onRecoveredConnection = function () {
logger.info('Recovered connection in Session ' + this.sessionId);
this.reconnectBrokenStreams();
this.ee.emitEvent('reconnected', []);
};
Session.prototype.onMediaError = function (event) {
logger.error('Media error: ' + JSON.stringify(event));
var err = event.error;
if (err) {
this.ee.emitEvent('error-media', [
{
error: err
}
]);
}
else {
logger.warn('Received undefined media error:', event);
}
};
Session.prototype.onRecordingStarted = function (event) {
this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', event.id, event.name)]);
};
Session.prototype.onRecordingStopped = function (event) {
this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', event.id, event.name, event.reason)]);
};
Session.prototype.onFilterEventDispatched = function (event) {
var _this = this;
var connectionId = event.connectionId;
this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId).then(function (connection) {
logger.info("Filter event of type \"".concat(event.eventType, "\" dispatched"));
var stream = connection.stream;
if (!stream || !stream.filter) {
return logger.error("Filter event of type \"".concat(event.eventType, "\" dispatched for stream ").concat(stream.streamId, " but there is no ").concat(!stream ? 'stream' : 'filter', " defined"));
}
var eventHandler = stream.filter.handlers.get(event.eventType);
if (!eventHandler || typeof eventHandler !== 'function') {
var actualHandlers = Array.from(stream.filter.handlers.keys());
return logger.error("Filter event of type \"".concat(event.eventType, "\" not handled or not a function! Active filter events: ").concat(actualHandlers.join(',')));
}
else {
eventHandler.call(_this, new FilterEvent_1.FilterEvent(stream.filter, event.eventType, event.data));
}
});
};
Session.prototype.onForciblyReconnectSubscriber = function (event) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.getRemoteConnection(event.connectionId, 'onForciblyReconnectSubscriber')
.then(function (connection) {
if (!!connection.stream && connection.stream.streamId === event.streamId) {
var stream_1 = connection.stream;
if (stream_1.setupReconnectionEventEmitter(resolve, reject)) {
if (stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'] != null) {
stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'] = event;
return reject('Ongoing forced subscriber reconnection');
}
else {
stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'] = event;
var callback_1 = function () {
var eventAux = stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'];
delete stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'];
_this.onForciblyReconnectSubscriber(eventAux);
};
stream_1.reconnectionEventEmitter.once('success', function () {
callback_1();
});
stream_1.reconnectionEventEmitter.once('error', function () {
callback_1();
});
}
return;
}
stream_1
.completeWebRtcPeerReceive(true, true, event.sdpOffer)
.then(function () { return stream_1.finalResolveForSubscription(true, resolve); })
.catch(function (error) {
return stream_1.finalRejectForSubscription(true, "Error while forcibly reconnecting remote stream ".concat(event.streamId, ": ").concat(error.toString()), reject);
});
}
else {
var errMsg = "No stream with streamId '" +
event.streamId +
"' found for connection '" +
event.connectionId +
"' on 'streamPropertyChanged' event";
logger.error(errMsg);
return reject(errMsg);
}
})
.catch(function (openViduError) {
logger.error(openViduError);
return reject(openViduError);
});
});
};
Session.prototype.reconnectBrokenStreams = function () {
logger.info('Re-establishing media connections...');
var someReconnection = false;
if (!!this.connection.stream && this.connection.stream.streamIceConnectionStateBroken()) {
logger.warn('Re-establishing Publisher ' + this.connection.stream.streamId);
this.connection.stream.initWebRtcPeerSend(true);
someReconnection = true;
}
this.remoteConnections.forEach(function (remoteConnection) {
if (!!remoteConnection.stream && remoteConnection.stream.streamIceConnectionStateBroken()) {
logger.warn('Re-establishing Subscriber ' + remoteConnection.stream.streamId);
remoteConnection.stream.initWebRtcPeerReceive(true);
someReconnection = true;
}
});
if (!someReconnection) {
logger.info('There were no media streams in need of a reconnection');
}
};
Session.prototype.emitEvent = function (type, eventArray) {
this.ee.emitEvent(type, eventArray);
};
Session.prototype.leave = function (forced, reason) {
var _this = this;
forced = !!forced;
logger.info('Leaving Session (forced=' + forced + ')');
this.stopVideoDataIntervals();
if (!!this.connection) {
if (!this.connection.disposed && !forced) {
this.openvidu.sendRequest('leaveRoom', function (error, response) {
if (error) {
logger.error("leaveRoom error: ".concat(JSON.stringify(error)));
}
_this.openvidu.closeWs();
});
}
else {
this.openvidu.closeWs();
}
this.stopPublisherStream(reason);
if (!this.connection.disposed) {
var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason);
this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]);
sessionDisconnectEvent.callDefaultBehavior();
}
}
else {
logger.warn('You were not connected to the session ' + this.sessionId);
}
logger.flush();
};
Session.prototype.initializeParams = function (token) {
var joinParams = {
token: !!token ? token : '',
session: this.sessionId,
platform: !!platform.getDescription() ? platform.getDescription() : 'unknown',
sdkVersion: this.openvidu.libraryVersion,
metadata: !!this.options.metadata ? this.options.metadata : '',
secret: this.openvidu.getSecret(),
recorder: this.openvidu.getRecorder()
};
return joinParams;
};
Session.prototype.sendVideoData = function (streamManager, intervalSeconds, doInterval, maxLoops) {
var _this = this;
var _a, _b;
if (intervalSeconds === void 0) { intervalSeconds = 1; }
if (doInterval === void 0) { doInterval = false; }
if (maxLoops === void 0) { maxLoops = 1; }
if (platform.isChromeBrowser() ||
platform.isChromeMobileBrowser() ||
platform.isOperaBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isEdgeBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isElectron() ||
(platform.isSafariBrowser() && !platform.isIonicIos()) ||
platform.isAndroidBrowser() ||
platform.isSamsungBrowser() ||
platform.isIonicAndroid() ||
platform.isIOSWithSafari()) {
var obtainAndSendVideo_1 = function () { return __awaiter(_this, void 0, void 0, function () {
var pc, statsMap, arr_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
pc = streamManager.stream.getRTCPeerConnection();
if (!(pc.connectionState === 'connected')) return [3, 2];
return [4, pc.getStats()];
case 1:
statsMap = _a.sent();
arr_1 = [];
statsMap.forEach(function (stats) {
if ('frameWidth' in stats && 'frameHeight' in stats && arr_1.length === 0) {
arr_1.push(stats);
}
});
if (arr_1.length > 0) {
this.openvidu.sendRequest('videoData', {
height: arr_1[0].frameHeight,
width: arr_1[0].frameWidth,
videoActive: streamManager.stream.videoActive != null ? streamManager.stream.videoActive : false,
audioActive: streamManager.stream.audioActive != null ? streamManager.stream.audioActive : false
}, function (error, response) {
if (error) {
logger.error("Error sending 'videoData' event", error);
}
});
}
_a.label = 2;
case 2: return [2];
}
});
}); };
if (doInterval) {
var loops_1 = 1;
this.videoDataInterval = setInterval(function () {
if (loops_1 < maxLoops) {
loops_1++;
obtainAndSendVideo_1();
}
else {
clearInterval(_this.videoDataInterval);
}
}, intervalSeconds * 1000);
}
else {
this.videoDataTimeout = setTimeout(obtainAndSendVideo_1, intervalSeconds * 1000);
}
}
else if (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser() || platform.isIonicIos() || platform.isReactNative()) {
this.openvidu.sendRequest('videoData', {
height: ((_a = streamManager.stream.videoDimensions) === null || _a === void 0 ? void 0 : _a.height) || 0,
width: ((_b = streamManager.stream.videoDimensions) === null || _b === void 0 ? void 0 : _b.width) || 0,
videoActive: streamManager.stream.videoActive != null ? streamManager.stream.videoActive : false,
audioActive: streamManager.stream.audioActive != null ? streamManager.stream.audioActive : false
}, function (error, response) {
if (error) {
logger.error("Error sending 'videoData' event", error);
}
});
}
else {
logger.error('Browser ' +
platform.getName() +
' (version ' +
platform.getVersion() +
') for ' +
platform.getFamily() +
' is not supported in OpenVidu for Network Quality');
}
};
Session.prototype.sessionConnected = function () {
return this.connection != null;
};
Session.prototype.notConnectedError = function () {
return new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_NOT_CONNECTED, "There is no connection to the session. Method 'Session.connect' must be successfully completed first");
};
Session.prototype.anySpeechEventListenerEnabled = function (event, onlyOnce, streamManager) {
var handlersInSession = this.ee.getListeners(event);
if (onlyOnce) {
handlersInSession = handlersInSession.filter(function (h) { return h.once; });
}
var listenersInSession = handlersInSession.length;
if (listenersInSession > 0)
return true;
var listenersInStreamManager = 0;
if (!!streamManager) {
var handlersInStreamManager = streamManager.ee.getListeners(event);
if (onlyOnce) {
handlersInStreamManager = handlersInStreamManager.filter(function (h) { return h.once; });
}
listenersInStreamManager = handlersInStreamManager.length;
}
return listenersInStreamManager > 0;
};
Session.prototype.getTokenParams = function (token) {
var match = token.match(/^(wss?)\:\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
if (!!match) {
var url = {
protocol: match[1],
host: match[2],
hostname: match[3],
port: match[4],
pathname: match[5],
search: match[6],
hash: match[7]
};
var params = token.split('?');
var queryParams = decodeURI(params[1])
.split('&')
.map(function (param) { return param.split('='); })
.reduce(function (values, _a) {
var key = _a[0], value = _a[1];
values[key] = value;
return values;
}, {});
return {
sessionId: queryParams['sessionId'],
secret: queryParams['secret'],
recorder: queryParams['recorder'],
webrtcStatsInterval: queryParams['webrtcStatsInterval'],
sendBrowserLogs: queryParams['sendBrowserLogs'],
edition: queryParams['edition'],
wsUri: url.protocol + '://' + url.host + '/openvidu',
httpUri: 'https://' + url.host
};
}
else {
throw new Error("Token not valid: \"".concat(token, "\""));
}
};
Session.prototype.connectAux = function (token) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.openvidu.startWs(function (error) {
if (!!error) {
return reject(error);
}
else {
var joinParams = _this.initializeParams(token);
_this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) {
if (!!error) {
return reject(error);
}
else {
_this.processJoinRoomResponse(response, token);
_this.connection = new Connection_1.Connection(_this, response);
var events_1 = {
connections: new Array(),
streams: new Array()
};
var existingParticipants = response.value;
existingParticipants.forEach(function (remoteConnectionOptions) {
var connection = new Connection_1.Connection(_this, remoteConnectionOptions);
_this.remoteConnections.set(connection.connectionId, connection);
events_1.connections.push(connection);
if (!!connection.stream) {
_this.remoteStreamsCreated.set(connection.stream.streamId, true);
events_1.streams.push(connection.stream);
}
});
_this.ee.emitEvent('connectionCreated', [
new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')
]);
events_1.connections.forEach(function (connection) {
_this.ee.emitEvent('connectionCreated', [
new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')
]);
});
events_1.streams.forEach(function (stream) {
_this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]);
});
if (!!response.recordingId && !!response.recordingName) {
_this.ee.emitEvent('recordingStarted', [
new RecordingEvent_1.RecordingEvent(_this, 'recordingStarted', response.recordingId, response.recordingName)
]);
}
return resolve();
}
});
}
});
});
};
Session.prototype.stopPublisherStream = function (reason) {
if (!!this.connection.stream) {
this.connection.stream.disposeWebRtcPeer();
if (this.connection.stream.isLocalStreamPublished) {
this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]);
}
}
};
Session.prototype.stopVideoDataIntervals = function () {
clearInterval(this.videoDataInterval);
clearTimeout(this.videoDataTimeout);
};
Session.prototype.stringClientMetadata = function (metadata) {
if (typeof metadata !== 'string') {
return JSON.stringify(metadata);
}
else {
return metadata;
}
};
Session.prototype.getConnection = function (connectionId, errorMessage) {
var _this = this;
return new Promise(function (resolve, reject) {
var connection = _this.remoteConnections.get(connectionId);
if (!!connection) {
return resolve(connection);
}
else {
if (_this.connection.connectionId === connectionId) {
return resolve(_this.connection);
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage));
}
}
});
};
Session.prototype.getRemoteConnection = function (connectionId, operation) {
var _this = this;
return new Promise(function (resolve, reject) {
var connection = _this.remoteConnections.get(connectionId);
if (!!connection) {
return resolve(connection);
}
else {
var errorMessage = 'Remote connection ' +
connectionId +
" unknown when '" +
operation +
"'. " +
'Existing remote connections: ' +
JSON.stringify(_this.remoteConnections.keys());
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage));
}
});
};
Session.prototype.processToken = function (token) {
var tokenParams = this.getTokenParams(token);
this.sessionId = tokenParams.sessionId;
if (!!tokenParams.secret) {
this.openvidu.secret = tokenParams.secret;
}
if (!!tokenParams.recorder) {
this.openvidu.recorder = true;
}
if (!!tokenParams.webrtcStatsInterval) {
this.openvidu.webrtcStatsInterval = tokenParams.webrtcStatsInterval;
}
if (!!tokenParams.sendBrowserLogs) {
this.openvidu.sendBrowserLogs = tokenParams.sendBrowserLogs;
}
this.openvidu.isAtLeastPro = tokenParams.edition === 'pro' || tokenParams.edition === 'enterprise';
this.openvidu.isEnterprise = tokenParams.edition === 'enterprise';
this.openvidu.wsUri = tokenParams.wsUri;
this.openvidu.httpUri = tokenParams.httpUri;
};
Session.prototype.processJoinRoomResponse = function (opts, token) {
this.sessionId = opts.session;
if (opts.customIceServers != null && opts.customIceServers.length > 0) {
this.openvidu.iceServers = [];
for (var _i = 0, _a = opts.customIceServers; _i < _a.length; _i++) {
var iceServer = _a[_i];
var rtcIceServer = {
urls: [iceServer.url]
};
logger.log('STUN/TURN server IP: ' + iceServer.url);
if (iceServer.username != null && iceServer.credential != null) {
rtcIceServer.username = iceServer.username;
rtcIceServer.credential = iceServer.credential;
logger.log('TURN credentials [' + iceServer.username + ':' + iceServer.credential + ']');
}
this.openvidu.iceServers.push(rtcIceServer);
}
}
this.openvidu.role = opts.role;
this.openvidu.finalUserId = opts.finalUserId;
this.openvidu.mediaServer = opts.mediaServer;
this.openvidu.videoSimulcast = opts.videoSimulcast;
this.capabilities = {
subscribe: true,
publish: this.openvidu.role !== 'SUBSCRIBER',
forceUnpublish: this.openvidu.role === 'MODERATOR',
forceDisconnect: this.openvidu.role === 'MODERATOR'
};
logger.info('openvidu-server version: ' + opts.version);
if (opts.life != null) {
this.openvidu.life = opts.life;
}
var minorDifference = semverMinor(opts.version) - semverMinor(this.openvidu.libraryVersion);
if (semverMajor(opts.version) !== semverMajor(this.openvidu.libraryVersion) || !(minorDifference == 0 || minorDifference == 1)) {
logger.error("openvidu-browser (".concat(this.openvidu.libraryVersion, ") and openvidu-server (").concat(opts.version, ") versions are incompatible. ") +
'Errors are likely to occur. openvidu-browser SDK is only compatible with the same version or the immediately following minor version of an OpenVidu deployment');
}
else if (minorDifference == 1) {
logger.warn("openvidu-browser version ".concat(this.openvidu.libraryVersion, " does not match openvidu-server version ").concat(opts.version, ". ") +
"These versions are still compatible with each other, but openvidu-browser version must be updated as soon as possible to ".concat(semverMajor(opts.version), ".").concat(semverMinor(opts.version), ".x. ") +
"This client using openvidu-browser ".concat(this.openvidu.libraryVersion, " will become incompatible with the next release of openvidu-server"));
}
OpenViduLogger_1.OpenViduLogger.configureJSNLog(this.openvidu, token);
this.token = token;
};
return Session;
}(EventDispatcher_1.EventDispatcher));
exports.Session = Session;
},{"../OpenViduInternal/Enums/OpenViduError":52,"../OpenViduInternal/Enums/VideoInsertMode":54,"../OpenViduInternal/Events/ConnectionEvent":55,"../OpenViduInternal/Events/ConnectionPropertyChangedEvent":56,"../OpenViduInternal/Events/FilterEvent":59,"../OpenViduInternal/Events/NetworkQualityLevelChangedEvent":60,"../OpenViduInternal/Events/RecordingEvent":62,"../OpenViduInternal/Events/SessionDisconnectedEvent":63,"../OpenViduInternal/Events/SignalEvent":64,"../OpenViduInternal/Events/StreamEvent":65,"../OpenViduInternal/Events/StreamPropertyChangedEvent":67,"../OpenViduInternal/Logger/OpenViduLogger":79,"../OpenViduInternal/Utils/Platform":83,"./Connection":41,"./EventDispatcher":42,"./Filter":43,"./Subscriber":50,"semver/functions/major":15,"semver/functions/minor":16}],48:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Stream = void 0;
var Filter_1 = require("./Filter");
var Subscriber_1 = require("./Subscriber");
var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer");
var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent");
var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var TypeOfVideo_1 = require("../OpenViduInternal/Enums/TypeOfVideo");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var uuid_1 = require("uuid");
var hark = require("hark");
var EventEmitter = require("wolfy87-eventemitter");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var Stream = (function () {
function Stream(session, options) {
var _this = this;
this.isSubscribeToRemote = false;
this.isLocalStreamReadyToPublish = false;
this.isLocalStreamPublished = false;
this.publishedOnce = false;
this.harkSpeakingEnabled = false;
this.harkSpeakingEnabledOnce = false;
this.harkStoppedSpeakingEnabled = false;
this.harkStoppedSpeakingEnabledOnce = false;
this.harkVolumeChangeEnabled = false;
this.harkVolumeChangeEnabledOnce = false;
this.ee = new EventEmitter();
platform = Platform_1.PlatformUtils.getInstance();
this.session = session;
if (options.hasOwnProperty('id')) {
this.inboundStreamOpts = options;
this.streamId = this.inboundStreamOpts.id;
this.creationTime = this.inboundStreamOpts.createdAt;
this.hasAudio = this.inboundStreamOpts.hasAudio;
this.hasVideo = this.inboundStreamOpts.hasVideo;
if (this.hasAudio) {
this.audioActive = this.inboundStreamOpts.audioActive;
}
if (this.hasVideo) {
this.videoActive = this.inboundStreamOpts.videoActive;
this.typeOfVideo = !this.inboundStreamOpts.typeOfVideo ? undefined : this.inboundStreamOpts.typeOfVideo;
this.frameRate = this.inboundStreamOpts.frameRate === -1 ? undefined : this.inboundStreamOpts.frameRate;
this.videoDimensions = this.inboundStreamOpts.videoDimensions;
}
if (!!this.inboundStreamOpts.filter && Object.keys(this.inboundStreamOpts.filter).length > 0) {
if (!!this.inboundStreamOpts.filter.lastExecMethod &&
Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) {
delete this.inboundStreamOpts.filter.lastExecMethod;
}
this.filter = this.inboundStreamOpts.filter;
}
}
else {
this.outboundStreamOpts = options;
this.hasAudio = this.isSendAudio();
this.hasVideo = this.isSendVideo();
if (this.hasAudio) {
this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio;
}
if (this.hasVideo) {
this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo;
this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate;
if (typeof MediaStreamTrack !== 'undefined' &&
this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) {
this.typeOfVideo = TypeOfVideo_1.TypeOfVideo.CUSTOM;
}
else {
this.typeOfVideo = this.isSendScreen() ? TypeOfVideo_1.TypeOfVideo.SCREEN : TypeOfVideo_1.TypeOfVideo.CAMERA;
}
}
if (!!this.outboundStreamOpts.publisherProperties.filter) {
this.filter = this.outboundStreamOpts.publisherProperties.filter;
}
}
this.ee.on('mediastream-updated', function () {
var _a;
_this.streamManager.updateMediaStream(_this.mediaStream);
logger.debug('Video srcObject [' + ((_a = _this.mediaStream) === null || _a === void 0 ? void 0 : _a.id) + '] updated in stream [' + _this.streamId + ']');
});
}
Stream.prototype.reconnect = function () {
return this.reconnectStream('API');
};
Stream.prototype.applyFilter = function (type, options) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var resolveApplyFilter, openviduToken_1, tokenParams_1, afterScriptLoaded_1, script, optionsString;
var _this = this;
return __generator(this, function (_a) {
if (!!this.filter) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, 'There is already a filter applied to Stream ' + this.streamId))];
}
resolveApplyFilter = function (error, triggerEvent) {
if (error) {
logger.error('Error applying filter for Stream ' + _this.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter"));
}
else {
return reject(error);
}
}
else {
logger.info('Filter successfully applied on Stream ' + _this.streamId);
var oldValue = _this.filter;
_this.filter = new Filter_1.Filter(type, options);
_this.filter.stream = _this;
if (triggerEvent) {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
_this.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
}
return resolve(_this.filter);
}
};
if (type.startsWith('VB:')) {
if (!this.hasVideo) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'The Virtual Background filter requires a video track to be applied'))];
}
if (!this.mediaStream || this.streamManager.videos.length === 0) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'The StreamManager requires some video element to be attached to it in order to apply a Virtual Background filter'))];
}
if (!!this.session.token) {
openviduToken_1 = this.session.token;
}
else {
openviduToken_1 = options['token'];
}
if (!openviduToken_1) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'Virtual Background requires the client to be connected to a Session or to have a "token" property available in "options" parameter with a valid OpenVidu token'))];
}
tokenParams_1 = this.session.getTokenParams(openviduToken_1);
if (tokenParams_1.edition !== 'pro' && tokenParams_1.edition !== 'enterprise') {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'OpenVidu Virtual Background API is available from OpenVidu Pro edition onwards'))];
}
openviduToken_1 = encodeURIComponent(btoa(openviduToken_1));
logger.info('Applying Virtual Background to stream ' + this.streamId);
afterScriptLoaded_1 = function () { return __awaiter(_this, void 0, void 0, function () {
var id, mediaStreamClone, videoClone, VB, filteredVideo, _a, error_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 8, , 9]);
id = this.streamId + '_' + (0, uuid_1.v4)();
mediaStreamClone = this.mediaStream.clone();
videoClone = this.streamManager.videos[0].video.cloneNode(false);
videoClone.id = VirtualBackground.VirtualBackground.SOURCE_VIDEO_PREFIX + id;
videoClone.srcObject = mediaStreamClone;
videoClone.muted = true;
this.virtualBackgroundSourceElements = { videoClone: videoClone, mediaStreamClone: mediaStreamClone };
VirtualBackground.VirtualBackground.hideHtmlElement(videoClone, false);
VirtualBackground.VirtualBackground.appendHtmlElementToHiddenContainer(videoClone, id);
return [4, videoClone.play()];
case 1:
_b.sent();
VB = new VirtualBackground.VirtualBackground({
id: id,
openviduServerUrl: new URL(tokenParams_1.httpUri),
openviduToken: openviduToken_1,
inputVideo: videoClone,
inputResolution: '160x96',
outputFramerate: 24
});
filteredVideo = void 0;
_a = type;
switch (_a) {
case 'VB:blur': return [3, 2];
case 'VB:image': return [3, 4];
}
return [3, 6];
case 2: return [4, VB.backgroundBlur(options)];
case 3:
filteredVideo = _b.sent();
return [3, 7];
case 4: return [4, VB.backgroundImage(options)];
case 5:
filteredVideo = _b.sent();
return [3, 7];
case 6: throw new Error('Unknown Virtual Background filter: ' + type);
case 7:
this.virtualBackgroundSinkElements = { VB: VB, video: filteredVideo };
videoClone.style.display = 'none';
if (this.streamManager.remote) {
this.streamManager.replaceTrackInMediaStream(this.virtualBackgroundSinkElements.video.srcObject.getVideoTracks()[0], false);
}
else {
this.streamManager.replaceTrackAux(this.virtualBackgroundSinkElements.video.srcObject.getVideoTracks()[0], false);
}
resolveApplyFilter(undefined, false);
return [3, 9];
case 8:
error_1 = _b.sent();
if (error_1.name === OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR) {
resolveApplyFilter(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, error_1.message), false);
}
else {
resolveApplyFilter(error_1, false);
}
return [3, 9];
case 9: return [2];
}
});
}); };
if (typeof VirtualBackground === 'undefined') {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = tokenParams_1.httpUri + '/openvidu/virtual-background/openvidu-virtual-background.js?token=' + openviduToken_1;
script.onload = function () { return __awaiter(_this, void 0, void 0, function () {
var error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, afterScriptLoaded_1()];
case 1:
_a.sent();
resolve(new Filter_1.Filter(type, options));
return [3, 3];
case 2:
error_2 = _a.sent();
reject(error_2);
return [3, 3];
case 3: return [2];
}
});
}); };
document.body.appendChild(script);
}
else {
afterScriptLoaded_1()
.then(function () { return resolve(new Filter_1.Filter(type, options)); })
.catch(function (error) { return reject(error); });
}
}
else {
if (!this.session.sessionConnected()) {
return [2, reject(this.session.notConnectedError())];
}
logger.info('Applying server filter to stream ' + this.streamId);
options = options != null ? options : {};
optionsString = options;
if (typeof optionsString !== 'string') {
optionsString = JSON.stringify(optionsString);
}
this.session.openvidu.sendRequest('applyFilter', { streamId: this.streamId, type: type, options: optionsString }, function (error, response) {
resolveApplyFilter(error, true);
});
}
return [2];
});
}); });
};
Stream.prototype.removeFilter = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.removeFilterAux(false)];
case 1: return [2, _a.sent()];
}
});
});
};
Stream.prototype.getRTCPeerConnection = function () {
return this.webRtcPeer.pc;
};
Stream.prototype.getMediaStream = function () {
return this.mediaStream;
};
Stream.prototype.removeFilterAux = function (isDisposing) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var resolveRemoveFilter, mediaStreamClone, error_3;
var _this = this;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
resolveRemoveFilter = function (error, triggerEvent) {
if (error) {
delete _this.filter;
logger.error('Error removing filter for Stream ' + _this.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter"));
}
else {
return reject(error);
}
}
else {
logger.info('Filter successfully removed from Stream ' + _this.streamId);
var oldValue = _this.filter;
delete _this.filter;
if (triggerEvent) {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
_this.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
}
return resolve();
}
};
if (!!!this.filter) return [3, 11];
if (!((_a = this.filter) === null || _a === void 0 ? void 0 : _a.type.startsWith('VB:'))) return [3, 9];
_b.label = 1;
case 1:
_b.trys.push([1, 7, , 8]);
mediaStreamClone = this.virtualBackgroundSourceElements.mediaStreamClone;
if (!!isDisposing) return [3, 5];
if (!this.streamManager.remote) return [3, 2];
this.streamManager.replaceTrackInMediaStream(mediaStreamClone.getVideoTracks()[0], false);
return [3, 4];
case 2: return [4, this.streamManager.replaceTrackAux(mediaStreamClone.getVideoTracks()[0], false)];
case 3:
_b.sent();
_b.label = 4;
case 4: return [3, 6];
case 5:
mediaStreamClone.getTracks().forEach(function (track) { return track.stop(); });
_b.label = 6;
case 6:
this.virtualBackgroundSinkElements.VB.cleanUp();
delete this.virtualBackgroundSinkElements;
delete this.virtualBackgroundSourceElements;
return [2, resolveRemoveFilter(undefined, false)];
case 7:
error_3 = _b.sent();
return [2, resolveRemoveFilter(error_3, false)];
case 8: return [3, 10];
case 9:
if (!this.session.sessionConnected()) {
return [2, reject(this.session.notConnectedError())];
}
logger.info('Removing filter of stream ' + this.streamId);
this.session.openvidu.sendRequest('removeFilter', { streamId: this.streamId }, function (error, response) {
return resolveRemoveFilter(error, true);
});
_b.label = 10;
case 10: return [3, 12];
case 11: return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, 'Stream ' + this.streamId + ' has no filter applied'))];
case 12: return [2];
}
});
}); });
};
Stream.prototype.setMediaStream = function (mediaStream) {
this.mediaStream = mediaStream;
};
Stream.prototype.updateMediaStreamInVideos = function () {
this.ee.emitEvent('mediastream-updated', []);
};
Stream.prototype.getWebRtcPeer = function () {
return this.webRtcPeer;
};
Stream.prototype.subscribeToMyRemote = function (value) {
this.isSubscribeToRemote = value;
};
Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) {
this.outboundStreamOpts = outboundStreamOpts;
};
Stream.prototype.subscribe = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.initWebRtcPeerReceive(false)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
};
Stream.prototype.publish = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.isLocalStreamReadyToPublish) {
_this.initWebRtcPeerSend(false)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
else {
_this.ee.once('stream-ready-to-publish', function () {
_this.publish()
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
}
});
};
Stream.prototype.disposeWebRtcPeer = function () {
var webrtcId;
if (!!this.webRtcPeer) {
this.webRtcPeer.dispose();
webrtcId = this.webRtcPeer.getId();
}
this.stopWebRtcStats();
logger.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') +
'RTCPeerConnection with id [' +
webrtcId +
"] from 'Stream' with id [" +
this.streamId +
'] is now closed');
};
Stream.prototype.disposeMediaStream = function () {
return __awaiter(this, void 0, void 0, function () {
var error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(!!this.filter && this.filter.type.startsWith('VB:'))) return [3, 4];
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, this.removeFilterAux(true)];
case 2:
_a.sent();
console.debug("Success removing Virtual Background filter for stream ".concat(this.streamId));
return [3, 4];
case 3:
error_4 = _a.sent();
console.error("Error removing Virtual Background filter for stream ".concat(this.streamId), error_4);
return [3, 4];
case 4:
if (this.mediaStream) {
this.mediaStream.getAudioTracks().forEach(function (track) {
track.stop();
});
this.mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
delete this.mediaStream;
}
if (this.localMediaStreamWhenSubscribedToRemote) {
this.localMediaStreamWhenSubscribedToRemote.getAudioTracks().forEach(function (track) {
track.stop();
});
this.localMediaStreamWhenSubscribedToRemote.getVideoTracks().forEach(function (track) {
track.stop();
});
delete this.localMediaStreamWhenSubscribedToRemote;
}
if (!!this.speechEvent) {
if (!!this.speechEvent.stop) {
this.speechEvent.stop();
}
delete this.speechEvent;
}
logger.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed');
return [2];
}
});
});
};
Stream.prototype.displayMyRemote = function () {
return this.isSubscribeToRemote;
};
Stream.prototype.isSendAudio = function () {
return (!!this.outboundStreamOpts &&
this.outboundStreamOpts.publisherProperties.audioSource !== null &&
this.outboundStreamOpts.publisherProperties.audioSource !== false);
};
Stream.prototype.isSendVideo = function () {
return (!!this.outboundStreamOpts &&
this.outboundStreamOpts.publisherProperties.videoSource !== null &&
this.outboundStreamOpts.publisherProperties.videoSource !== false);
};
Stream.prototype.isSendScreen = function () {
var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen';
if (platform.isElectron()) {
screen =
typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' &&
this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:');
}
return !!this.outboundStreamOpts && screen;
};
Stream.prototype.enableHarkSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkSpeakingEnabled && !!this.speechEvent) {
this.harkSpeakingEnabled = true;
this.speechEvent.on('speaking', function () {
_this.session.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
_this.harkSpeakingEnabledOnce = false;
});
}
};
Stream.prototype.enableOnceHarkSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkSpeakingEnabledOnce && !!this.speechEvent) {
this.harkSpeakingEnabledOnce = true;
this.speechEvent.once('speaking', function () {
if (_this.harkSpeakingEnabledOnce) {
_this.session.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
}
_this.disableHarkSpeakingEvent(true);
});
}
};
Stream.prototype.disableHarkSpeakingEvent = function (disabledByOnce) {
if (!!this.speechEvent) {
this.harkSpeakingEnabledOnce = false;
if (disabledByOnce) {
if (this.harkSpeakingEnabled) {
return;
}
}
else {
this.harkSpeakingEnabled = false;
}
if (this.harkVolumeChangeEnabled ||
this.harkVolumeChangeEnabledOnce ||
this.harkStoppedSpeakingEnabled ||
this.harkStoppedSpeakingEnabledOnce) {
this.speechEvent.off('speaking');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
};
Stream.prototype.enableHarkStoppedSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkStoppedSpeakingEnabled && !!this.speechEvent) {
this.harkStoppedSpeakingEnabled = true;
this.speechEvent.on('stopped_speaking', function () {
_this.session.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
_this.harkStoppedSpeakingEnabledOnce = false;
});
}
};
Stream.prototype.enableOnceHarkStoppedSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkStoppedSpeakingEnabledOnce && !!this.speechEvent) {
this.harkStoppedSpeakingEnabledOnce = true;
this.speechEvent.once('stopped_speaking', function () {
if (_this.harkStoppedSpeakingEnabledOnce) {
_this.session.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
}
_this.disableHarkStoppedSpeakingEvent(true);
});
}
};
Stream.prototype.disableHarkStoppedSpeakingEvent = function (disabledByOnce) {
if (!!this.speechEvent) {
this.harkStoppedSpeakingEnabledOnce = false;
if (disabledByOnce) {
if (this.harkStoppedSpeakingEnabled) {
return;
}
}
else {
this.harkStoppedSpeakingEnabled = false;
}
if (this.harkVolumeChangeEnabled ||
this.harkVolumeChangeEnabledOnce ||
this.harkSpeakingEnabled ||
this.harkSpeakingEnabledOnce) {
this.speechEvent.off('stopped_speaking');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
};
Stream.prototype.enableHarkVolumeChangeEvent = function (force) {
var _this = this;
if (this.setHarkListenerIfNotExists()) {
if (!this.harkVolumeChangeEnabled || force) {
this.harkVolumeChangeEnabled = true;
this.speechEvent.on('volume_change', function (harkEvent) {
var oldValue = _this.speechEvent.oldVolumeValue;
var value = { newValue: harkEvent, oldValue: oldValue };
_this.speechEvent.oldVolumeValue = harkEvent;
_this.streamManager.emitEvent('streamAudioVolumeChange', [
new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)
]);
});
}
}
else {
this.harkVolumeChangeEnabled = true;
}
};
Stream.prototype.enableOnceHarkVolumeChangeEvent = function (force) {
var _this = this;
if (this.setHarkListenerIfNotExists()) {
if (!this.harkVolumeChangeEnabledOnce || force) {
this.harkVolumeChangeEnabledOnce = true;
this.speechEvent.once('volume_change', function (harkEvent) {
var oldValue = _this.speechEvent.oldVolumeValue;
var value = { newValue: harkEvent, oldValue: oldValue };
_this.speechEvent.oldVolumeValue = harkEvent;
_this.disableHarkVolumeChangeEvent(true);
_this.streamManager.emitEvent('streamAudioVolumeChange', [
new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)
]);
});
}
}
else {
this.harkVolumeChangeEnabledOnce = true;
}
};
Stream.prototype.disableHarkVolumeChangeEvent = function (disabledByOnce) {
if (!!this.speechEvent) {
this.harkVolumeChangeEnabledOnce = false;
if (disabledByOnce) {
if (this.harkVolumeChangeEnabled) {
return;
}
}
else {
this.harkVolumeChangeEnabled = false;
}
if (this.harkSpeakingEnabled ||
this.harkSpeakingEnabledOnce ||
this.harkStoppedSpeakingEnabled ||
this.harkStoppedSpeakingEnabledOnce) {
this.speechEvent.off('volume_change');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
};
Stream.prototype.isLocal = function () {
return !this.inboundStreamOpts && !!this.outboundStreamOpts;
};
Stream.prototype.getSelectedIceCandidate = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.webRtcStats
.getSelectedIceCandidateInfo()
.then(function (report) { return resolve(report); })
.catch(function (error) { return reject(error); });
});
};
Stream.prototype.getRemoteIceCandidateList = function () {
return this.webRtcPeer.remoteCandidatesQueue;
};
Stream.prototype.getLocalIceCandidateList = function () {
return this.webRtcPeer.localCandidatesQueue;
};
Stream.prototype.streamIceConnectionStateBroken = function () {
if (!this.getWebRtcPeer() || !this.getRTCPeerConnection()) {
return false;
}
if (this.isLocal() && !!this.session.openvidu.advancedConfiguration.forceMediaReconnectionAfterNetworkDrop) {
logger.warn("OpenVidu Browser advanced configuration option \"forceMediaReconnectionAfterNetworkDrop\" is enabled. Stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") will force a reconnection"));
return true;
}
var iceConnectionState = this.getRTCPeerConnection().iceConnectionState;
return iceConnectionState !== 'connected' && iceConnectionState !== 'completed';
};
Stream.prototype.setHarkListenerIfNotExists = function () {
if (!!this.mediaStream) {
if (!this.speechEvent) {
var harkOptions = !!this.harkOptions
? this.harkOptions
: this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {};
harkOptions.interval = typeof harkOptions.interval === 'number' ? harkOptions.interval : 100;
harkOptions.threshold = typeof harkOptions.threshold === 'number' ? harkOptions.threshold : -50;
this.speechEvent = hark(this.mediaStream, harkOptions);
}
return true;
}
return false;
};
Stream.prototype.setupReconnectionEventEmitter = function (resolve, reject) {
if (this.reconnectionEventEmitter == undefined) {
this.reconnectionEventEmitter = new EventEmitter();
return false;
}
else {
console.warn("Trying to reconnect stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") but an ongoing reconnection process is active. Waiting for response..."));
this.reconnectionEventEmitter.once('success', function () { return resolve(); });
this.reconnectionEventEmitter.once('error', function (error) { return reject(error); });
return true;
}
};
Stream.prototype.initWebRtcPeerSend = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
var _a;
if (reconnect) {
if (_this.setupReconnectionEventEmitter(resolve, reject)) {
return;
}
}
else {
_this.initHarkEvents();
}
var finalResolve = function () {
var _a;
if (reconnect) {
(_a = _this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('success');
delete _this.reconnectionEventEmitter;
}
return resolve();
};
var finalReject = function (error) {
var _a;
if (reconnect) {
(_a = _this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('error', [error]);
delete _this.reconnectionEventEmitter;
}
return reject(error);
};
var successOfferCallback = function (sdpOfferParam) {
logger.debug('Sending SDP offer to publish as ' + _this.streamId, sdpOfferParam);
var method = reconnect ? 'reconnectStream' : 'publishVideo';
var params;
if (reconnect) {
params = {
stream: _this.streamId,
sdpString: sdpOfferParam
};
}
else {
var typeOfVideo = void 0;
if (_this.isSendVideo()) {
typeOfVideo =
typeof MediaStreamTrack !== 'undefined' &&
_this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack
? TypeOfVideo_1.TypeOfVideo.CUSTOM
: _this.isSendScreen()
? TypeOfVideo_1.TypeOfVideo.SCREEN
: TypeOfVideo_1.TypeOfVideo.CAMERA;
}
params = {
doLoopback: _this.displayMyRemote() || false,
hasAudio: _this.isSendAudio(),
hasVideo: _this.isSendVideo(),
audioActive: _this.audioActive,
videoActive: _this.videoActive,
typeOfVideo: typeOfVideo,
frameRate: !!_this.frameRate ? _this.frameRate : -1,
videoDimensions: JSON.stringify(_this.videoDimensions),
filter: _this.outboundStreamOpts.publisherProperties.filter,
sdpOffer: sdpOfferParam
};
}
_this.session.openvidu.sendRequest(method, params, function (error, response) {
if (error) {
if (error.code === 401) {
finalReject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish"));
}
else {
finalReject('Error on publishVideo: ' + JSON.stringify(error));
}
}
else {
_this.webRtcPeer
.processRemoteAnswer(response.sdpAnswer)
.then(function () {
_this.streamId = response.id;
_this.creationTime = response.createdAt;
_this.isLocalStreamPublished = true;
_this.publishedOnce = true;
if (_this.displayMyRemote()) {
_this.localMediaStreamWhenSubscribedToRemote = _this.mediaStream;
_this.remotePeerSuccessfullyEstablished(reconnect);
}
if (reconnect) {
_this.ee.emitEvent('stream-reconnected-by-publisher', []);
}
else {
_this.ee.emitEvent('stream-created-by-publisher', []);
}
_this.initWebRtcStats();
logger.info("'Publisher' (" +
_this.streamId +
') successfully ' +
(reconnect ? 'reconnected' : 'published') +
' to session');
finalResolve();
})
.catch(function (error) {
finalReject(error);
});
}
});
};
var config = {
mediaConstraints: {
audio: _this.hasAudio,
video: _this.hasVideo
},
simulcast: (_a = _this.outboundStreamOpts.publisherProperties.videoSimulcast) !== null && _a !== void 0 ? _a : _this.session.openvidu.videoSimulcast,
onIceCandidate: _this.connection.sendIceCandidate.bind(_this.connection),
onIceConnectionStateException: function (exceptionName, message, data) {
_this.session.emitEvent('exception', [new ExceptionEvent_1.ExceptionEvent(_this.session, exceptionName, _this, message, data)]);
},
iceServers: _this.getIceServersConf(),
mediaStream: _this.mediaStream,
mediaServer: _this.session.openvidu.mediaServer,
typeOfVideo: _this.typeOfVideo ? TypeOfVideo_1.TypeOfVideo[_this.typeOfVideo] : undefined
};
if (_this.session.openvidu.mediaServer !== 'mediasoup') {
config.simulcast = false;
}
if (reconnect) {
_this.disposeWebRtcPeer();
}
if (_this.displayMyRemote()) {
_this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(config);
}
else {
_this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(config);
}
_this.webRtcPeer.addIceConnectionStateChangeListener('publisher of ' + _this.connection.connectionId);
_this.webRtcPeer
.createOffer()
.then(function (sdpOffer) {
_this.webRtcPeer
.processLocalOffer(sdpOffer)
.then(function () {
successOfferCallback(sdpOffer.sdp);
})
.catch(function (error) {
finalReject(new Error('(publish) SDP process local offer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
finalReject(new Error('(publish) SDP create offer error: ' + JSON.stringify(error)));
});
});
};
Stream.prototype.finalResolveForSubscription = function (reconnect, resolve) {
var _a;
logger.info("'Subscriber' (" + this.streamId + ') successfully ' + (reconnect ? 'reconnected' : 'subscribed'));
this.remotePeerSuccessfullyEstablished(reconnect);
this.initWebRtcStats();
if (reconnect) {
(_a = this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('success');
delete this.reconnectionEventEmitter;
}
return resolve();
};
Stream.prototype.finalRejectForSubscription = function (reconnect, error, reject) {
var _a;
logger.error("Error for 'Subscriber' (" +
this.streamId +
') while trying to ' +
(reconnect ? 'reconnect' : 'subscribe') +
': ' +
error.toString());
if (reconnect) {
(_a = this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('error', [error]);
delete this.reconnectionEventEmitter;
}
return reject(error);
};
Stream.prototype.initWebRtcPeerReceive = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
if (reconnect) {
if (_this.setupReconnectionEventEmitter(resolve, reject)) {
return;
}
}
if (_this.session.openvidu.mediaServer === 'mediasoup') {
_this.initWebRtcPeerReceiveFromServer(reconnect)
.then(function () { return _this.finalResolveForSubscription(reconnect, resolve); })
.catch(function (error) { return _this.finalRejectForSubscription(reconnect, error, reject); });
}
else {
_this.initWebRtcPeerReceiveFromClient(reconnect)
.then(function () { return _this.finalResolveForSubscription(reconnect, resolve); })
.catch(function (error) { return _this.finalRejectForSubscription(reconnect, error, reject); });
}
});
};
Stream.prototype.initWebRtcPeerReceiveFromClient = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.completeWebRtcPeerReceive(reconnect, false)
.then(function (response) {
_this.webRtcPeer
.processRemoteAnswer(response.sdpAnswer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
})
.catch(function (error) { return reject(error); });
});
};
Stream.prototype.initWebRtcPeerReceiveFromServer = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.session.openvidu.sendRequest('prepareReceiveVideoFrom', { sender: _this.streamId, reconnect: reconnect }, function (error, response) {
if (error) {
return reject(new Error('Error on prepareReceiveVideoFrom: ' + JSON.stringify(error)));
}
else {
_this.completeWebRtcPeerReceive(reconnect, false, response.sdpOffer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
});
});
};
Stream.prototype.completeWebRtcPeerReceive = function (reconnect, forciblyReconnect, sdpOfferByServer) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.debug("'Session.subscribe(Stream)' called");
var sendSdpToServer = function (sdpString) {
logger.debug("Sending local SDP ".concat(!!sdpOfferByServer ? 'answer' : 'offer', " to subscribe to ").concat(_this.streamId), sdpString);
var method = reconnect ? 'reconnectStream' : 'receiveVideoFrom';
var params = {};
params[reconnect ? 'stream' : 'sender'] = _this.streamId;
if (!!sdpOfferByServer) {
params[reconnect ? 'sdpString' : 'sdpAnswer'] = sdpString;
}
else {
params['sdpOffer'] = sdpString;
}
if (reconnect) {
params['forciblyReconnect'] = forciblyReconnect;
}
_this.session.openvidu.sendRequest(method, params, function (error, response) {
if (error) {
return reject(new Error('Error on ' + method + ' : ' + JSON.stringify(error)));
}
else {
return resolve(response);
}
});
};
var config = {
mediaConstraints: {
audio: _this.hasAudio,
video: _this.hasVideo
},
simulcast: false,
onIceCandidate: _this.connection.sendIceCandidate.bind(_this.connection),
onIceConnectionStateException: function (exceptionName, message, data) {
_this.session.emitEvent('exception', [new ExceptionEvent_1.ExceptionEvent(_this.session, exceptionName, _this, message, data)]);
},
iceServers: _this.getIceServersConf(),
mediaServer: _this.session.openvidu.mediaServer,
typeOfVideo: _this.typeOfVideo ? TypeOfVideo_1.TypeOfVideo[_this.typeOfVideo] : undefined
};
if (reconnect) {
_this.disposeWebRtcPeer();
}
_this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(config);
_this.webRtcPeer.addIceConnectionStateChangeListener(_this.streamId);
if (!!sdpOfferByServer) {
_this.webRtcPeer
.processRemoteOffer(sdpOfferByServer)
.then(function () {
_this.webRtcPeer
.createAnswer()
.then(function (sdpAnswer) {
_this.webRtcPeer
.processLocalAnswer(sdpAnswer)
.then(function () {
sendSdpToServer(sdpAnswer.sdp);
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP process local answer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP create answer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP process remote offer error: ' + JSON.stringify(error)));
});
}
else {
_this.webRtcPeer
.createOffer()
.then(function (sdpOffer) {
_this.webRtcPeer
.processLocalOffer(sdpOffer)
.then(function () {
sendSdpToServer(sdpOffer.sdp);
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP process local offer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP create offer error: ' + JSON.stringify(error)));
});
}
});
};
Stream.prototype.remotePeerSuccessfullyEstablished = function (reconnect) {
if (reconnect && this.mediaStream != null) {
this.disposeMediaStream();
}
this.mediaStream = new MediaStream();
var receiver;
for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) {
receiver = _a[_i];
if (!!receiver.track) {
this.mediaStream.addTrack(receiver.track);
}
}
logger.debug('Peer remote stream', this.mediaStream);
if (!!this.mediaStream) {
if (this.streamManager instanceof Subscriber_1.Subscriber) {
if (!!this.mediaStream.getAudioTracks()[0]) {
var enabled = reconnect ? this.audioActive : !!this.streamManager.properties.subscribeToAudio;
this.mediaStream.getAudioTracks()[0].enabled = enabled;
}
if (!!this.mediaStream.getVideoTracks()[0]) {
var enabled = reconnect ? this.videoActive : !!this.streamManager.properties.subscribeToVideo;
this.mediaStream.getVideoTracks()[0].enabled = enabled;
}
}
this.updateMediaStreamInVideos();
this.initHarkEvents();
}
};
Stream.prototype.initHarkEvents = function () {
if (!!this.mediaStream.getAudioTracks()[0]) {
if (this.session.anySpeechEventListenerEnabled('publisherStartSpeaking', true, this.streamManager)) {
this.enableOnceHarkSpeakingEvent();
}
if (this.session.anySpeechEventListenerEnabled('publisherStartSpeaking', false, this.streamManager)) {
this.enableHarkSpeakingEvent();
}
if (this.session.anySpeechEventListenerEnabled('publisherStopSpeaking', true, this.streamManager)) {
this.enableOnceHarkStoppedSpeakingEvent();
}
if (this.session.anySpeechEventListenerEnabled('publisherStopSpeaking', false, this.streamManager)) {
this.enableHarkStoppedSpeakingEvent();
}
if (this.harkVolumeChangeEnabledOnce) {
this.enableOnceHarkVolumeChangeEvent(true);
}
if (this.harkVolumeChangeEnabled) {
this.enableHarkVolumeChangeEvent(true);
}
}
};
Stream.prototype.onIceConnectionStateExceptionHandler = function (exceptionName, message, data) {
switch (exceptionName) {
case ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_FAILED:
this.onIceConnectionFailed();
break;
case ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_DISCONNECTED:
this.onIceConnectionDisconnected();
break;
}
this.session.emitEvent('exception', [new ExceptionEvent_1.ExceptionEvent(this.session, exceptionName, this, message, data)]);
};
Stream.prototype.onIceConnectionFailed = function () {
logger.log("[ICE_CONNECTION_FAILED] Handling ICE_CONNECTION_FAILED event. Reconnecting stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ")"));
this.reconnectStreamAndLogResultingIceConnectionState(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_FAILED);
};
Stream.prototype.onIceConnectionDisconnected = function () {
var _this = this;
logger.log("[ICE_CONNECTION_DISCONNECTED] Handling ICE_CONNECTION_DISCONNECTED event. Waiting for ICE to be restored and reconnect stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") if not possible"));
var timeout = this.session.openvidu.advancedConfiguration.iceConnectionDisconnectedExceptionTimeout || 4000;
this.awaitWebRtcPeerConnectionState(timeout).then(function (state) {
switch (state) {
case 'failed':
logger.warn("[ICE_CONNECTION_DISCONNECTED] ICE connection of stream ".concat(_this.streamId, " (").concat(_this.isLocal() ? 'Publisher' : 'Subscriber', ") is now failed after ICE_CONNECTION_DISCONNECTED"));
break;
case 'connected':
case 'completed':
logger.log("[ICE_CONNECTION_DISCONNECTED] ICE connection of stream ".concat(_this.streamId, " (").concat(_this.isLocal() ? 'Publisher' : 'Subscriber', ") automatically restored after ICE_CONNECTION_DISCONNECTED. Current ICE connection state: ").concat(state));
break;
case 'closed':
case 'checking':
case 'new':
case 'disconnected':
logger.warn("[ICE_CONNECTION_DISCONNECTED] ICE connection of stream ".concat(_this.streamId, " (").concat(_this.isLocal() ? 'Publisher' : 'Subscriber', ") couldn't be restored after ICE_CONNECTION_DISCONNECTED event. Current ICE connection state after ").concat(timeout, " ms: ").concat(state));
_this.reconnectStreamAndLogResultingIceConnectionState(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_DISCONNECTED);
break;
}
});
};
Stream.prototype.reconnectStreamAndLogResultingIceConnectionState = function (event) {
return __awaiter(this, void 0, void 0, function () {
var finalIceStateAfterReconnection, error_5;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.reconnectStreamAndReturnIceConnectionState(event)];
case 1:
finalIceStateAfterReconnection = _a.sent();
switch (finalIceStateAfterReconnection) {
case 'connected':
case 'completed':
logger.log("[".concat(event, "] Stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") successfully reconnected after ").concat(event, ". Current ICE connection state: ").concat(finalIceStateAfterReconnection));
break;
default:
logger.error("[".concat(event, "] Stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") failed to reconnect after ").concat(event, ". Current ICE connection state: ").concat(finalIceStateAfterReconnection));
break;
}
return [3, 3];
case 2:
error_5 = _a.sent();
logger.error("[".concat(event, "] Error reconnecting stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") after ").concat(event, ": ").concat(error_5));
return [3, 3];
case 3: return [2];
}
});
});
};
Stream.prototype.reconnectStreamAndReturnIceConnectionState = function (event) {
return __awaiter(this, void 0, void 0, function () {
var timeout, error_6;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
logger.log("[".concat(event, "] Reconnecting stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") after event ").concat(event));
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, this.reconnectStream(event)];
case 2:
_a.sent();
timeout = this.session.openvidu.advancedConfiguration.iceConnectionDisconnectedExceptionTimeout || 4000;
return [2, this.awaitWebRtcPeerConnectionState(timeout)];
case 3:
error_6 = _a.sent();
logger.warn("[".concat(event, "] Error reconnecting stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', "). Reason: ").concat(error_6));
return [2, this.awaitWebRtcPeerConnectionState(1)];
case 4: return [2];
}
});
});
};
Stream.prototype.reconnectStream = function (event) {
return __awaiter(this, void 0, void 0, function () {
var isWsConnected, errorMsg;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.isWebsocketConnected(event, 3000)];
case 1:
isWsConnected = _a.sent();
if (isWsConnected) {
logger.log("[".concat(event, "] Trying to reconnect stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") and the websocket is opened"));
if (this.isLocal()) {
return [2, this.initWebRtcPeerSend(true)];
}
else {
return [2, this.initWebRtcPeerReceive(true)];
}
}
else {
errorMsg = "[".concat(event, "] Trying to reconnect stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") but the websocket wasn't opened");
logger.error(errorMsg);
throw Error(errorMsg);
}
return [2];
}
});
});
};
Stream.prototype.isWebsocketConnected = function (event, msResponseTimeout) {
var _this = this;
return new Promise(function (resolve, reject) {
var wsReadyState = _this.session.openvidu.getWsReadyState();
if (wsReadyState === 1) {
var responseTimeout_1 = setTimeout(function () {
console.warn("[".concat(event, "] Websocket timeout of ").concat(msResponseTimeout, "ms"));
return resolve(false);
}, msResponseTimeout);
_this.session.openvidu.sendRequest('echo', {}, function (error, response) {
clearTimeout(responseTimeout_1);
if (!!error) {
console.warn("[".concat(event, "] Websocket 'echo' returned error: ").concat(error));
return resolve(false);
}
else {
return resolve(true);
}
});
}
else {
console.warn("[".concat(event, "] Websocket readyState is ").concat(wsReadyState));
return resolve(false);
}
});
};
Stream.prototype.awaitWebRtcPeerConnectionState = function (timeout) {
return __awaiter(this, void 0, void 0, function () {
var state, interval, intervals, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
state = this.getRTCPeerConnection().iceConnectionState;
interval = 150;
intervals = Math.ceil(timeout / interval);
i = 0;
_a.label = 1;
case 1:
if (!(i < intervals)) return [3, 4];
state = this.getRTCPeerConnection().iceConnectionState;
if (state === 'connected' || state === 'completed') {
return [3, 4];
}
return [4, new Promise(function (resolve) { return setTimeout(resolve, interval); })];
case 2:
_a.sent();
_a.label = 3;
case 3:
i++;
return [3, 1];
case 4: return [2, state];
}
});
});
};
Stream.prototype.initWebRtcStats = function () {
this.webRtcStats = new WebRtcStats_1.WebRtcStats(this);
this.webRtcStats.initWebRtcStats();
};
Stream.prototype.stopWebRtcStats = function () {
if (!!this.webRtcStats && this.webRtcStats.isEnabled()) {
this.webRtcStats.stopWebRtcStats();
}
};
Stream.prototype.getIceServersConf = function () {
var returnValue;
if (!!this.session.openvidu.advancedConfiguration.iceServers) {
returnValue =
this.session.openvidu.advancedConfiguration.iceServers === 'freeice'
? undefined
: this.session.openvidu.advancedConfiguration.iceServers;
}
else if (this.session.openvidu.iceServers) {
returnValue = this.session.openvidu.iceServers;
}
else {
returnValue = undefined;
}
return returnValue;
};
Stream.prototype.gatherStatsForPeer = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.isLocal()) {
_this.getRTCPeerConnection()
.getSenders()
.forEach(function (sender) {
return sender.getStats().then(function (response) {
response.forEach(function (report) {
if (_this.isReportWanted(report)) {
var finalReport = {};
finalReport['type'] = report.type;
finalReport['timestamp'] = report.timestamp;
finalReport['id'] = report.id;
if (report.type === 'outbound-rtp') {
finalReport['ssrc'] = report.ssrc;
finalReport['firCount'] = report.firCount;
finalReport['pliCount'] = report.pliCount;
finalReport['nackCount'] = report.nackCount;
finalReport['qpSum'] = report.qpSum;
if (!!report.kind) {
finalReport['mediaType'] = report.kind;
}
else if (!!report.mediaType) {
finalReport['mediaType'] = report.mediaType;
}
else {
finalReport['mediaType'] = report.id.indexOf('VideoStream') !== -1 ? 'video' : 'audio';
}
if (finalReport['mediaType'] === 'video') {
finalReport['framesEncoded'] = report.framesEncoded;
}
finalReport['packetsSent'] = report.packetsSent;
finalReport['bytesSent'] = report.bytesSent;
}
if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) {
finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate;
finalReport['rtt'] = report.currentRoundTripTime;
finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived;
}
if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') {
}
logger.log(finalReport);
}
});
});
});
}
else {
_this.getRTCPeerConnection()
.getReceivers()
.forEach(function (receiver) {
return receiver.getStats().then(function (response) {
response.forEach(function (report) {
if (_this.isReportWanted(report)) {
var finalReport = {};
finalReport['type'] = report.type;
finalReport['timestamp'] = report.timestamp;
finalReport['id'] = report.id;
if (report.type === 'inbound-rtp') {
finalReport['ssrc'] = report.ssrc;
finalReport['firCount'] = report.firCount;
finalReport['pliCount'] = report.pliCount;
finalReport['nackCount'] = report.nackCount;
finalReport['qpSum'] = report.qpSum;
if (!!report.kind) {
finalReport['mediaType'] = report.kind;
}
else if (!!report.mediaType) {
finalReport['mediaType'] = report.mediaType;
}
else {
finalReport['mediaType'] = report.id.indexOf('VideoStream') !== -1 ? 'video' : 'audio';
}
if (finalReport['mediaType'] === 'video') {
finalReport['framesDecoded'] = report.framesDecoded;
}
finalReport['packetsReceived'] = report.packetsReceived;
finalReport['packetsLost'] = report.packetsLost;
finalReport['jitter'] = report.jitter;
finalReport['bytesReceived'] = report.bytesReceived;
}
if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) {
finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate;
finalReport['rtt'] = report.currentRoundTripTime;
finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived;
}
if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') {
}
logger.log(finalReport);
}
});
});
});
}
});
};
Stream.prototype.isReportWanted = function (report) {
return ((report.type === 'inbound-rtp' && !this.isLocal()) ||
(report.type === 'outbound-rtp' && this.isLocal()) ||
(report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0));
};
return Stream;
}());
exports.Stream = Stream;
},{"../OpenViduInternal/Enums/OpenViduError":52,"../OpenViduInternal/Enums/TypeOfVideo":53,"../OpenViduInternal/Events/ExceptionEvent":58,"../OpenViduInternal/Events/PublisherSpeakingEvent":61,"../OpenViduInternal/Events/StreamManagerEvent":66,"../OpenViduInternal/Events/StreamPropertyChangedEvent":67,"../OpenViduInternal/Logger/OpenViduLogger":79,"../OpenViduInternal/Utils/Platform":83,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":84,"../OpenViduInternal/WebRtcStats/WebRtcStats":85,"./Filter":43,"./Subscriber":50,"hark":5,"uuid":22,"wolfy87-eventemitter":38}],49:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamManager = void 0;
var EventDispatcher_1 = require("./EventDispatcher");
var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent");
var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var StreamManager = (function (_super) {
__extends(StreamManager, _super);
function StreamManager(stream, targetElement) {
var _this = _super.call(this) || this;
_this.videos = [];
_this.lazyLaunchVideoElementCreatedEvent = false;
platform = Platform_1.PlatformUtils.getInstance();
_this.stream = stream;
_this.stream.streamManager = _this;
_this.remote = !_this.stream.isLocal();
if (!!targetElement) {
var targEl = void 0;
if (typeof targetElement === 'string') {
targEl = document.getElementById(targetElement);
}
else if (targetElement instanceof HTMLElement) {
targEl = targetElement;
}
if (!!targEl) {
_this.firstVideoElement = {
targetElement: targEl,
video: document.createElement('video'),
id: '',
canplayListenerAdded: false
};
if (platform.isSafariBrowser() ||
(platform.isIPhoneOrIPad() &&
(platform.isChromeMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isFirefoxMobileBrowser()))) {
_this.firstVideoElement.video.playsInline = true;
}
_this.targetElement = targEl;
_this.element = targEl;
}
}
_this.canPlayListener = function () {
_this.deactivateStreamPlayingEventExceptionTimeout();
_this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]);
};
return _this;
}
StreamManager.prototype.on = function (type, handler) {
_super.prototype.onAux.call(this, type, "Event '" + type + "' triggered by '" + (this.remote ? 'Subscriber' : 'Publisher') + "'", handler);
if (type === 'videoElementCreated') {
if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) {
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]);
this.lazyLaunchVideoElementCreatedEvent = false;
}
}
if (type === 'streamPlaying') {
if (this.videos[0] &&
this.videos[0].video &&
this.videos[0].video.currentTime > 0 &&
this.videos[0].video.paused === false &&
this.videos[0].video.ended === false &&
this.videos[0].video.readyState === 4) {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]);
}
}
if (this.stream.hasAudio) {
if (type === 'publisherStartSpeaking') {
this.stream.enableHarkSpeakingEvent();
}
if (type === 'publisherStopSpeaking') {
this.stream.enableHarkStoppedSpeakingEvent();
}
if (type === 'streamAudioVolumeChange') {
this.stream.enableHarkVolumeChangeEvent(false);
}
}
return this;
};
StreamManager.prototype.once = function (type, handler) {
_super.prototype.onceAux.call(this, type, "Event '" + type + "' triggered once by '" + (this.remote ? 'Subscriber' : 'Publisher') + "'", handler);
if (type === 'videoElementCreated') {
if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) {
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]);
}
}
if (type === 'streamPlaying') {
if (this.videos[0] &&
this.videos[0].video &&
this.videos[0].video.currentTime > 0 &&
this.videos[0].video.paused === false &&
this.videos[0].video.ended === false &&
this.videos[0].video.readyState === 4) {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]);
}
}
if (this.stream.hasAudio) {
if (type === 'publisherStartSpeaking') {
this.stream.enableOnceHarkSpeakingEvent();
}
if (type === 'publisherStopSpeaking') {
this.stream.enableOnceHarkStoppedSpeakingEvent();
}
if (type === 'streamAudioVolumeChange') {
this.stream.enableOnceHarkVolumeChangeEvent(false);
}
}
return this;
};
StreamManager.prototype.off = function (type, handler) {
_super.prototype.offAux.call(this, type, handler);
if (type === 'publisherStartSpeaking') {
var remainingStartSpeakingEventListeners = this.ee.getListeners(type).length + this.stream.session.ee.getListeners(type).length;
if (remainingStartSpeakingEventListeners === 0) {
this.stream.disableHarkSpeakingEvent(false);
}
}
if (type === 'publisherStopSpeaking') {
var remainingStopSpeakingEventListeners = this.ee.getListeners(type).length + this.stream.session.ee.getListeners(type).length;
if (remainingStopSpeakingEventListeners === 0) {
this.stream.disableHarkStoppedSpeakingEvent(false);
}
}
if (type === 'streamAudioVolumeChange') {
var remainingVolumeEventListeners = this.ee.getListeners(type).length;
if (remainingVolumeEventListeners === 0) {
this.stream.disableHarkVolumeChangeEvent(false);
}
}
return this;
};
StreamManager.prototype.addVideoElement = function (video) {
this.initializeVideoProperties(video);
if (!this.remote && this.stream.displayMyRemote()) {
if (video.srcObject !== this.stream.getMediaStream()) {
video.srcObject = this.stream.getMediaStream();
}
}
for (var _i = 0, _a = this.videos; _i < _a.length; _i++) {
var v = _a[_i];
if (v.video === video) {
return 0;
}
}
var returnNumber = 1;
for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) {
var streamManager = _c[_b];
if (streamManager.disassociateVideo(video)) {
returnNumber = -1;
break;
}
}
this.stream.session.streamManagers.forEach(function (streamManager) {
streamManager.disassociateVideo(video);
});
this.pushNewStreamManagerVideo({
video: video,
id: video.id,
canplayListenerAdded: false
});
logger.info('New video element associated to ', this);
return returnNumber;
};
StreamManager.prototype.createVideoElement = function (targetElement, insertMode) {
var targEl;
if (typeof targetElement === 'string') {
targEl = document.getElementById(targetElement);
if (!targEl) {
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
}
}
else if (targetElement instanceof HTMLElement) {
targEl = targetElement;
}
else {
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
}
var video = this.createVideo();
this.initializeVideoProperties(video);
var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND;
switch (insMode) {
case VideoInsertMode_1.VideoInsertMode.AFTER:
targEl.parentNode.insertBefore(video, targEl.nextSibling);
break;
case VideoInsertMode_1.VideoInsertMode.APPEND:
targEl.appendChild(video);
break;
case VideoInsertMode_1.VideoInsertMode.BEFORE:
targEl.parentNode.insertBefore(video, targEl);
break;
case VideoInsertMode_1.VideoInsertMode.PREPEND:
targEl.insertBefore(video, targEl.childNodes[0]);
break;
case VideoInsertMode_1.VideoInsertMode.REPLACE:
targEl.parentNode.replaceChild(video, targEl);
break;
default:
insMode = VideoInsertMode_1.VideoInsertMode.APPEND;
targEl.appendChild(video);
break;
}
var v = {
targetElement: targEl,
video: video,
insertMode: insMode,
id: video.id,
canplayListenerAdded: false
};
this.pushNewStreamManagerVideo(v);
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]);
this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement;
return video;
};
StreamManager.prototype.updatePublisherSpeakingEventsOptions = function (publisherSpeakingEventsOptions) {
var currentHarkOptions = !!this.stream.harkOptions
? this.stream.harkOptions
: this.stream.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {};
var newInterval = typeof publisherSpeakingEventsOptions.interval === 'number'
? publisherSpeakingEventsOptions.interval
: typeof currentHarkOptions.interval === 'number'
? currentHarkOptions.interval
: 100;
var newThreshold = typeof publisherSpeakingEventsOptions.threshold === 'number'
? publisherSpeakingEventsOptions.threshold
: typeof currentHarkOptions.threshold === 'number'
? currentHarkOptions.threshold
: -50;
this.stream.harkOptions = {
interval: newInterval,
threshold: newThreshold
};
if (!!this.stream.speechEvent) {
this.stream.speechEvent.setInterval(newInterval);
this.stream.speechEvent.setThreshold(newThreshold);
}
};
StreamManager.prototype.initializeVideoProperties = function (video) {
if (!(!this.remote && this.stream.displayMyRemote())) {
if (video.srcObject !== this.stream.getMediaStream()) {
video.srcObject = this.stream.getMediaStream();
}
}
video.autoplay = true;
video.controls = false;
if (platform.isSafariBrowser() ||
(platform.isIPhoneOrIPad() &&
(platform.isChromeMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isFirefoxMobileBrowser()))) {
video.playsInline = true;
}
if (!video.id) {
video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId;
if (!this.id && !!this.targetElement) {
this.id = video.id;
}
}
if (this.remote && this.isMirroredVideo(video)) {
this.removeMirrorVideo(video);
}
else if (!this.remote && !this.stream.displayMyRemote()) {
video.muted = true;
if (this.isMirroredVideo(video) && !this.stream.outboundStreamOpts.publisherProperties.mirror) {
this.removeMirrorVideo(video);
}
else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) {
this.mirrorVideo(video);
}
}
};
StreamManager.prototype.removeAllVideos = function () {
var _this = this;
for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) {
if (this.stream.session.streamManagers[i] === this) {
this.stream.session.streamManagers.splice(i, 1);
}
}
this.videos.forEach(function (streamManagerVideo) {
if (!!streamManagerVideo.video && !!streamManagerVideo.video.removeEventListener) {
streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener);
}
streamManagerVideo.canplayListenerAdded = false;
if (!!streamManagerVideo.targetElement) {
streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video);
_this.ee.emitEvent('videoElementDestroyed', [
new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')
]);
}
_this.removeSrcObject(streamManagerVideo);
_this.videos.filter(function (v) { return !v.targetElement; });
});
};
StreamManager.prototype.disassociateVideo = function (video) {
var disassociated = false;
for (var i = 0; i < this.videos.length; i++) {
if (this.videos[i].video === video) {
this.videos[i].video.removeEventListener('canplay', this.canPlayListener);
this.videos.splice(i, 1);
disassociated = true;
logger.info('Video element disassociated from ', this);
break;
}
}
return disassociated;
};
StreamManager.prototype.addPlayEventToFirstVideo = function () {
if (!!this.videos[0] && !!this.videos[0].video && !this.videos[0].canplayListenerAdded) {
this.activateStreamPlayingEventExceptionTimeout();
this.videos[0].video.addEventListener('canplay', this.canPlayListener);
this.videos[0].canplayListenerAdded = true;
}
};
StreamManager.prototype.updateMediaStream = function (mediaStream) {
this.videos.forEach(function (streamManagerVideo) {
streamManagerVideo.video.srcObject = mediaStream;
if (platform.isIonicIos()) {
var vParent = streamManagerVideo.video.parentElement;
var newVideo = streamManagerVideo.video;
vParent.replaceChild(newVideo, streamManagerVideo.video);
streamManagerVideo.video = newVideo;
}
});
};
StreamManager.prototype.emitEvent = function (type, eventArray) {
this.ee.emitEvent(type, eventArray);
};
StreamManager.prototype.createVideo = function () {
return document.createElement('video');
};
StreamManager.prototype.removeSrcObject = function (streamManagerVideo) {
streamManagerVideo.video.srcObject = null;
this.deactivateStreamPlayingEventExceptionTimeout();
};
StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) {
this.videos.push(streamManagerVideo);
this.addPlayEventToFirstVideo();
if (this.stream.session.streamManagers.indexOf(this) === -1) {
this.stream.session.streamManagers.push(this);
}
};
StreamManager.prototype.mirrorVideo = function (video) {
if (!platform.isIonicIos()) {
video.style.transform = 'rotateY(180deg)';
video.style.webkitTransform = 'rotateY(180deg)';
}
};
StreamManager.prototype.removeMirrorVideo = function (video) {
video.style.transform = 'unset';
video.style.webkitTransform = 'unset';
};
StreamManager.prototype.isMirroredVideo = function (video) {
return video.style.transform === 'rotateY(180deg)' || video.style.webkitTransform === 'rotateY(180deg)';
};
StreamManager.prototype.activateStreamPlayingEventExceptionTimeout = function () {
var _this = this;
if (!this.remote) {
return;
}
if (this.streamPlayingEventExceptionTimeout != null) {
return;
}
var msTimeout = this.stream.session.openvidu.advancedConfiguration.noStreamPlayingEventExceptionTimeout || 4000;
this.streamPlayingEventExceptionTimeout = setTimeout(function () {
var msg = 'StreamManager of Stream ' +
_this.stream.streamId +
' (' +
(_this.remote ? 'Subscriber' : 'Publisher') +
') did not trigger "streamPlaying" event in ' +
msTimeout +
' ms';
logger.warn(msg);
_this.stream.session.emitEvent('exception', [
new ExceptionEvent_1.ExceptionEvent(_this.stream.session, ExceptionEvent_1.ExceptionEventName.NO_STREAM_PLAYING_EVENT, _this, msg)
]);
delete _this.streamPlayingEventExceptionTimeout;
}, msTimeout);
};
StreamManager.prototype.deactivateStreamPlayingEventExceptionTimeout = function () {
clearTimeout(this.streamPlayingEventExceptionTimeout);
delete this.streamPlayingEventExceptionTimeout;
};
return StreamManager;
}(EventDispatcher_1.EventDispatcher));
exports.StreamManager = StreamManager;
},{"../OpenViduInternal/Enums/VideoInsertMode":54,"../OpenViduInternal/Events/ExceptionEvent":58,"../OpenViduInternal/Events/StreamManagerEvent":66,"../OpenViduInternal/Events/VideoElementEvent":68,"../OpenViduInternal/Logger/OpenViduLogger":79,"../OpenViduInternal/Utils/Platform":83,"./EventDispatcher":42}],50:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Subscriber = void 0;
var StreamManager_1 = require("./StreamManager");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var Subscriber = (function (_super) {
__extends(Subscriber, _super);
function Subscriber(stream, targEl, properties) {
var _this = _super.call(this, stream, targEl) || this;
_this.element = _this.targetElement;
_this.stream = stream;
_this.properties = properties;
return _this;
}
Subscriber.prototype.subscribeToAudio = function (value) {
this.stream
.getMediaStream()
.getAudioTracks()
.forEach(function (track) {
track.enabled = value;
});
this.stream.audioActive = value;
logger.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream');
return this;
};
Subscriber.prototype.subscribeToVideo = function (value) {
this.stream
.getMediaStream()
.getVideoTracks()
.forEach(function (track) {
track.enabled = value;
});
this.stream.videoActive = value;
logger.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream');
return this;
};
Subscriber.prototype.replaceTrackInMediaStream = function (track, updateLastConstraints) {
var mediaStream = this.stream.getMediaStream();
var removedTrack;
if (track.kind === 'video') {
removedTrack = mediaStream.getVideoTracks()[0];
if (updateLastConstraints) {
this.stream.lastVideoTrackConstraints = track.getConstraints();
}
}
else {
removedTrack = mediaStream.getAudioTracks()[0];
}
mediaStream.removeTrack(removedTrack);
removedTrack.stop();
mediaStream.addTrack(track);
};
return Subscriber;
}(StreamManager_1.StreamManager));
exports.Subscriber = Subscriber;
},{"../OpenViduInternal/Logger/OpenViduLogger":79,"./StreamManager":49}],51:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalRecorderState = void 0;
var LocalRecorderState;
(function (LocalRecorderState) {
LocalRecorderState["READY"] = "READY";
LocalRecorderState["RECORDING"] = "RECORDING";
LocalRecorderState["PAUSED"] = "PAUSED";
LocalRecorderState["FINISHED"] = "FINISHED";
})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {}));
},{}],52:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenViduError = exports.OpenViduErrorName = void 0;
var OpenViduErrorName;
(function (OpenViduErrorName) {
OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED";
OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED";
OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE";
OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED";
OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED";
OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED";
OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED";
OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND";
OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND";
OpenViduErrorName["INPUT_AUDIO_DEVICE_GENERIC_ERROR"] = "INPUT_AUDIO_DEVICE_GENERIC_ERROR";
OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET";
OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR";
OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED";
OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED";
OpenViduErrorName["VIRTUAL_BACKGROUND_ERROR"] = "VIRTUAL_BACKGROUND_ERROR";
OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR";
})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {}));
var OpenViduError = (function () {
function OpenViduError(name, message) {
this.name = name;
this.message = message;
}
return OpenViduError;
}());
exports.OpenViduError = OpenViduError;
},{}],53:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeOfVideo = void 0;
var TypeOfVideo;
(function (TypeOfVideo) {
TypeOfVideo["CAMERA"] = "CAMERA";
TypeOfVideo["SCREEN"] = "SCREEN";
TypeOfVideo["CUSTOM"] = "CUSTOM";
TypeOfVideo["IPCAM"] = "IPCAM";
})(TypeOfVideo = exports.TypeOfVideo || (exports.TypeOfVideo = {}));
},{}],54:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VideoInsertMode = void 0;
var VideoInsertMode;
(function (VideoInsertMode) {
VideoInsertMode["AFTER"] = "AFTER";
VideoInsertMode["APPEND"] = "APPEND";
VideoInsertMode["BEFORE"] = "BEFORE";
VideoInsertMode["PREPEND"] = "PREPEND";
VideoInsertMode["REPLACE"] = "REPLACE";
})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {}));
},{}],55:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionEvent = void 0;
var Event_1 = require("./Event");
var ConnectionEvent = (function (_super) {
__extends(ConnectionEvent, _super);
function ConnectionEvent(cancelable, target, type, connection, reason) {
var _this = _super.call(this, cancelable, target, type) || this;
_this.connection = connection;
_this.reason = reason;
return _this;
}
ConnectionEvent.prototype.callDefaultBehavior = function () { };
return ConnectionEvent;
}(Event_1.Event));
exports.ConnectionEvent = ConnectionEvent;
},{"./Event":57}],56:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionPropertyChangedEvent = void 0;
var Event_1 = require("./Event");
var ConnectionPropertyChangedEvent = (function (_super) {
__extends(ConnectionPropertyChangedEvent, _super);
function ConnectionPropertyChangedEvent(target, connection, changedProperty, newValue, oldValue) {
var _this = _super.call(this, false, target, 'connectionPropertyChanged') || this;
_this.connection = connection;
_this.changedProperty = changedProperty;
_this.newValue = newValue;
_this.oldValue = oldValue;
return _this;
}
ConnectionPropertyChangedEvent.prototype.callDefaultBehavior = function () { };
return ConnectionPropertyChangedEvent;
}(Event_1.Event));
exports.ConnectionPropertyChangedEvent = ConnectionPropertyChangedEvent;
},{"./Event":57}],57:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Event = void 0;
var Event = (function () {
function Event(cancelable, target, type) {
this.hasBeenPrevented = false;
this.cancelable = cancelable;
this.target = target;
this.type = type;
}
Event.prototype.isDefaultPrevented = function () {
return this.hasBeenPrevented;
};
Event.prototype.preventDefault = function () {
this.callDefaultBehavior = function () { };
this.hasBeenPrevented = true;
};
return Event;
}());
exports.Event = Event;
},{}],58:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExceptionEvent = exports.ExceptionEventName = void 0;
var Event_1 = require("./Event");
var ExceptionEventName;
(function (ExceptionEventName) {
ExceptionEventName["ICE_CANDIDATE_ERROR"] = "ICE_CANDIDATE_ERROR";
ExceptionEventName["ICE_CONNECTION_FAILED"] = "ICE_CONNECTION_FAILED";
ExceptionEventName["ICE_CONNECTION_DISCONNECTED"] = "ICE_CONNECTION_DISCONNECTED";
ExceptionEventName["NO_STREAM_PLAYING_EVENT"] = "NO_STREAM_PLAYING_EVENT";
})(ExceptionEventName = exports.ExceptionEventName || (exports.ExceptionEventName = {}));
var ExceptionEvent = (function (_super) {
__extends(ExceptionEvent, _super);
function ExceptionEvent(session, name, origin, message, data) {
var _this = _super.call(this, false, session, 'exception') || this;
_this.name = name;
_this.origin = origin;
_this.message = message;
_this.data = data;
return _this;
}
ExceptionEvent.prototype.callDefaultBehavior = function () { };
return ExceptionEvent;
}(Event_1.Event));
exports.ExceptionEvent = ExceptionEvent;
},{"./Event":57}],59:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FilterEvent = void 0;
var Event_1 = require("./Event");
var FilterEvent = (function (_super) {
__extends(FilterEvent, _super);
function FilterEvent(target, eventType, data) {
var _this = _super.call(this, false, target, eventType) || this;
_this.data = data;
return _this;
}
FilterEvent.prototype.callDefaultBehavior = function () { };
return FilterEvent;
}(Event_1.Event));
exports.FilterEvent = FilterEvent;
},{"./Event":57}],60:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkQualityLevelChangedEvent = void 0;
var Event_1 = require("./Event");
var NetworkQualityLevelChangedEvent = (function (_super) {
__extends(NetworkQualityLevelChangedEvent, _super);
function NetworkQualityLevelChangedEvent(target, newValue, oldValue, connection) {
var _this = _super.call(this, false, target, 'networkQualityLevelChanged') || this;
_this.newValue = newValue;
_this.oldValue = oldValue;
_this.connection = connection;
return _this;
}
NetworkQualityLevelChangedEvent.prototype.callDefaultBehavior = function () { };
return NetworkQualityLevelChangedEvent;
}(Event_1.Event));
exports.NetworkQualityLevelChangedEvent = NetworkQualityLevelChangedEvent;
},{"./Event":57}],61:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublisherSpeakingEvent = void 0;
var Event_1 = require("./Event");
var PublisherSpeakingEvent = (function (_super) {
__extends(PublisherSpeakingEvent, _super);
function PublisherSpeakingEvent(target, type, connection, streamId) {
var _this = _super.call(this, false, target, type) || this;
_this.type = type;
_this.connection = connection;
_this.streamId = streamId;
return _this;
}
PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { };
return PublisherSpeakingEvent;
}(Event_1.Event));
exports.PublisherSpeakingEvent = PublisherSpeakingEvent;
},{"./Event":57}],62:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.RecordingEvent = void 0;
var Event_1 = require("./Event");
var RecordingEvent = (function (_super) {
__extends(RecordingEvent, _super);
function RecordingEvent(target, type, id, name, reason) {
var _this = _super.call(this, false, target, type) || this;
_this.id = id;
if (name !== id) {
_this.name = name;
}
_this.reason = reason;
return _this;
}
RecordingEvent.prototype.callDefaultBehavior = function () { };
return RecordingEvent;
}(Event_1.Event));
exports.RecordingEvent = RecordingEvent;
},{"./Event":57}],63:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionDisconnectedEvent = void 0;
var Event_1 = require("./Event");
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var SessionDisconnectedEvent = (function (_super) {
__extends(SessionDisconnectedEvent, _super);
function SessionDisconnectedEvent(target, reason) {
var _this = _super.call(this, true, target, 'sessionDisconnected') || this;
_this.reason = reason;
return _this;
}
SessionDisconnectedEvent.prototype.callDefaultBehavior = function () {
logger.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'");
var session = this.target;
session.remoteConnections.forEach(function (remoteConnection) {
var _a, _b, _c, _d, _e, _f, _g, _h;
var connectionId = remoteConnection.connectionId;
if (!!((_a = session.remoteConnections.get(connectionId)) === null || _a === void 0 ? void 0 : _a.stream)) {
(_b = session.remoteConnections.get(connectionId)) === null || _b === void 0 ? void 0 : _b.stream.disposeWebRtcPeer();
(_c = session.remoteConnections.get(connectionId)) === null || _c === void 0 ? void 0 : _c.stream.disposeMediaStream();
if ((_d = session.remoteConnections.get(connectionId)) === null || _d === void 0 ? void 0 : _d.stream.streamManager) {
(_e = session.remoteConnections.get(connectionId)) === null || _e === void 0 ? void 0 : _e.stream.streamManager.removeAllVideos();
}
var streamId = (_g = (_f = session.remoteConnections.get(connectionId)) === null || _f === void 0 ? void 0 : _f.stream) === null || _g === void 0 ? void 0 : _g.streamId;
if (!!streamId) {
session.remoteStreamsCreated.delete(streamId);
}
(_h = session.remoteConnections.get(connectionId)) === null || _h === void 0 ? void 0 : _h.dispose();
}
session.remoteConnections.delete(connectionId);
});
};
return SessionDisconnectedEvent;
}(Event_1.Event));
exports.SessionDisconnectedEvent = SessionDisconnectedEvent;
},{"../Logger/OpenViduLogger":79,"./Event":57}],64:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignalEvent = void 0;
var Event_1 = require("./Event");
var SignalEvent = (function (_super) {
__extends(SignalEvent, _super);
function SignalEvent(target, type, data, from) {
var _this = _super.call(this, false, target, 'signal') || this;
if (!!type) {
_this.type = 'signal:' + type;
}
_this.data = data;
_this.from = from;
return _this;
}
SignalEvent.prototype.callDefaultBehavior = function () { };
return SignalEvent;
}(Event_1.Event));
exports.SignalEvent = SignalEvent;
},{"./Event":57}],65:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamEvent = void 0;
var Event_1 = require("./Event");
var Publisher_1 = require("../../OpenVidu/Publisher");
var Session_1 = require("../../OpenVidu/Session");
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var StreamEvent = (function (_super) {
__extends(StreamEvent, _super);
function StreamEvent(cancelable, target, type, stream, reason) {
var _this = _super.call(this, cancelable, target, type) || this;
_this.stream = stream;
_this.reason = reason;
return _this;
}
StreamEvent.prototype.callDefaultBehavior = function () {
if (this.type === 'streamDestroyed') {
if (this.target instanceof Session_1.Session) {
logger.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'");
this.stream.disposeWebRtcPeer();
}
else if (this.target instanceof Publisher_1.Publisher) {
logger.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'");
clearInterval(this.target.screenShareResizeInterval);
this.stream.isLocalStreamReadyToPublish = false;
var openviduPublishers = this.target.openvidu.publishers;
for (var i = 0; i < openviduPublishers.length; i++) {
if (openviduPublishers[i] === this.target) {
openviduPublishers.splice(i, 1);
break;
}
}
}
this.stream.disposeMediaStream();
if (this.stream.streamManager)
this.stream.streamManager.removeAllVideos();
this.stream.session.remoteStreamsCreated.delete(this.stream.streamId);
var remoteConnection = this.stream.session.remoteConnections.get(this.stream.connection.connectionId);
if (!!remoteConnection && !!remoteConnection.remoteOptions) {
var streamOptionsServer = remoteConnection.remoteOptions.streams;
for (var i = streamOptionsServer.length - 1; i >= 0; --i) {
if (streamOptionsServer[i].id === this.stream.streamId) {
streamOptionsServer.splice(i, 1);
}
}
}
}
};
return StreamEvent;
}(Event_1.Event));
exports.StreamEvent = StreamEvent;
},{"../../OpenVidu/Publisher":46,"../../OpenVidu/Session":47,"../Logger/OpenViduLogger":79,"./Event":57}],66:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamManagerEvent = void 0;
var Event_1 = require("./Event");
var StreamManagerEvent = (function (_super) {
__extends(StreamManagerEvent, _super);
function StreamManagerEvent(target, type, value) {
var _this = _super.call(this, false, target, type) || this;
_this.value = value;
return _this;
}
StreamManagerEvent.prototype.callDefaultBehavior = function () { };
return StreamManagerEvent;
}(Event_1.Event));
exports.StreamManagerEvent = StreamManagerEvent;
},{"./Event":57}],67:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamPropertyChangedEvent = void 0;
var Event_1 = require("./Event");
var StreamPropertyChangedEvent = (function (_super) {
__extends(StreamPropertyChangedEvent, _super);
function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) {
var _this = _super.call(this, false, target, 'streamPropertyChanged') || this;
_this.stream = stream;
_this.changedProperty = changedProperty;
_this.newValue = newValue;
_this.oldValue = oldValue;
_this.reason = reason;
return _this;
}
StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { };
return StreamPropertyChangedEvent;
}(Event_1.Event));
exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent;
},{"./Event":57}],68:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.VideoElementEvent = void 0;
var Event_1 = require("./Event");
var VideoElementEvent = (function (_super) {
__extends(VideoElementEvent, _super);
function VideoElementEvent(element, target, type) {
var _this = _super.call(this, false, target, type) || this;
_this.element = element;
return _this;
}
VideoElementEvent.prototype.callDefaultBehavior = function () { };
return VideoElementEvent;
}(Event_1.Event));
exports.VideoElementEvent = VideoElementEvent;
},{"./Event":57}],69:[function(require,module,exports){
function Mapper() {
var sources = {};
this.forEach = function (callback) {
for (var key in sources) {
var source = sources[key];
for (var key2 in source)
callback(source[key2]);
}
};
this.get = function (id, source) {
var ids = sources[source];
if (ids == undefined)
return undefined;
return ids[id];
};
this.remove = function (id, source) {
var ids = sources[source];
if (ids == undefined)
return;
delete ids[id];
for (var i in ids) {
return false;
}
delete sources[source];
};
this.set = function (value, id, source) {
if (value == undefined)
return this.remove(id, source);
var ids = sources[source];
if (ids == undefined)
sources[source] = ids = {};
ids[id] = value;
};
}
Mapper.prototype.pop = function (id, source) {
var value = this.get(id, source);
if (value == undefined)
return undefined;
this.remove(id, source);
return value;
};
module.exports = Mapper;
},{}],70:[function(require,module,exports){
var JsonRpcClient = require('./jsonrpcclient');
exports.JsonRpcClient = JsonRpcClient;
},{"./jsonrpcclient":71}],71:[function(require,module,exports){
var RpcBuilder = require('../');
var WebSocketWithReconnection = require('./transports/webSocketWithReconnection');
var OpenViduLogger = require('../../../Logger/OpenViduLogger').OpenViduLogger;
Date.now =
Date.now ||
function () {
return +new Date();
};
var PING_INTERVAL = 5000;
var RECONNECTING = 'RECONNECTING';
var CONNECTED = 'CONNECTED';
var DISCONNECTED = 'DISCONNECTED';
var Logger = OpenViduLogger.getInstance();
function JsonRpcClient(configuration) {
var self = this;
var wsConfig = configuration.ws;
var notReconnectIfNumLessThan = -1;
var pingNextNum = 0;
var enabledPings = true;
var pingPongStarted = false;
var pingInterval;
var status = DISCONNECTED;
var onreconnecting = wsConfig.onreconnecting;
var onreconnected = wsConfig.onreconnected;
var onconnected = wsConfig.onconnected;
var onerror = wsConfig.onerror;
configuration.rpc.pull = function (params, request) {
request.reply(null, 'push');
};
wsConfig.onreconnecting = function () {
Logger.debug('--------- ONRECONNECTING -----------');
if (status === RECONNECTING) {
Logger.error('Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it');
return;
}
stopPing();
status = RECONNECTING;
if (onreconnecting) {
onreconnecting();
}
};
wsConfig.onreconnected = function () {
Logger.debug('--------- ONRECONNECTED -----------');
if (status === CONNECTED) {
Logger.error('Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it');
return;
}
status = CONNECTED;
updateNotReconnectIfLessThan();
if (onreconnected) {
onreconnected();
}
};
wsConfig.onconnected = function () {
Logger.debug('--------- ONCONNECTED -----------');
if (status === CONNECTED) {
Logger.error('Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it');
return;
}
status = CONNECTED;
enabledPings = true;
usePing();
if (onconnected) {
onconnected();
}
};
wsConfig.onerror = function (error) {
Logger.debug('--------- ONERROR -----------');
status = DISCONNECTED;
stopPing();
if (onerror) {
onerror(error);
}
};
var ws = new WebSocketWithReconnection(wsConfig);
Logger.debug('Connecting websocket to URI: ' + wsConfig.uri);
var rpcBuilderOptions = {
request_timeout: configuration.rpc.requestTimeout,
ping_request_timeout: configuration.rpc.heartbeatRequestTimeout
};
var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) {
Logger.debug('Received request: ' + JSON.stringify(request));
try {
var func = configuration.rpc[request.method];
if (func === undefined) {
Logger.error('Method ' + request.method + ' not registered in client');
}
else {
func(request.params, request);
}
}
catch (err) {
Logger.error('Exception processing request: ' + JSON.stringify(request));
Logger.error(err);
}
});
this.send = function (method, params, callback) {
var requestTime = Date.now();
rpc.encode(method, params, function (error, result) {
if (error) {
try {
Logger.error('ERROR:' +
error.message +
' in Request: method:' +
method +
' params:' +
JSON.stringify(params) +
' request:' +
error.request);
if (error.data) {
Logger.error('ERROR DATA:' + JSON.stringify(error.data));
}
}
catch (e) { }
error.requestTime = requestTime;
}
if (callback) {
if (result != undefined && result.value !== 'pong') {
Logger.debug('Response: ' + JSON.stringify(result));
}
callback(error, result);
}
});
};
function updateNotReconnectIfLessThan() {
Logger.debug('notReconnectIfNumLessThan = ' + pingNextNum + ' (old=' + notReconnectIfNumLessThan + ')');
notReconnectIfNumLessThan = pingNextNum;
}
function sendPing() {
if (enabledPings) {
var params = null;
if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) {
params = {
interval: configuration.heartbeat || PING_INTERVAL
};
}
pingNextNum++;
self.send('ping', params, (function (pingNum) {
return function (error, result) {
if (error) {
Logger.debug('Error in ping request #' + pingNum + ' (' + error.message + ')');
if (pingNum > notReconnectIfNumLessThan) {
enabledPings = false;
updateNotReconnectIfLessThan();
Logger.debug('Server did not respond to ping message #' + pingNum + '. Reconnecting... ');
ws.reconnectWs();
}
}
};
})(pingNextNum));
}
else {
Logger.debug('Trying to send ping, but ping is not enabled');
}
}
function usePing() {
if (!pingPongStarted) {
Logger.debug('Starting ping (if configured)');
pingPongStarted = true;
if (configuration.heartbeat != undefined) {
pingInterval = setInterval(sendPing, configuration.heartbeat);
sendPing();
}
}
}
function stopPing() {
clearInterval(pingInterval);
pingPongStarted = false;
enabledPings = false;
pingNextNum = -1;
rpc.cancel();
}
this.close = function (code, reason) {
Logger.debug('Closing with code: ' + code + ' because: ' + reason);
if (pingInterval != undefined) {
Logger.debug('Clearing ping interval');
clearInterval(pingInterval);
}
pingPongStarted = false;
enabledPings = false;
ws.close(code, reason);
};
this.reconnect = function () {
ws.reconnectWs();
};
this.resetPing = function () {
enabledPings = true;
pingNextNum = 0;
usePing();
};
this.getReadyState = function () {
return ws.getReadyState();
};
}
module.exports = JsonRpcClient;
},{"../":74,"../../../Logger/OpenViduLogger":79,"./transports/webSocketWithReconnection":73}],72:[function(require,module,exports){
var WebSocketWithReconnection = require('./webSocketWithReconnection');
exports.WebSocketWithReconnection = WebSocketWithReconnection;
},{"./webSocketWithReconnection":73}],73:[function(require,module,exports){
'use strict';
var OpenViduLogger = require('../../../../Logger/OpenViduLogger').OpenViduLogger;
var Logger = OpenViduLogger.getInstance();
var MAX_RETRIES = 2000;
var RETRY_TIME_MS = 3000;
var CONNECTING = 0;
var OPEN = 1;
var CLOSING = 2;
var CLOSED = 3;
function WebSocketWithReconnection(config) {
var closing = false;
var registerMessageHandler;
var wsUri = config.uri;
var reconnecting = false;
var ws = new WebSocket(wsUri);
ws.onopen = function () {
Logger.debug('WebSocket connected to ' + wsUri);
if (config.onconnected) {
config.onconnected();
}
};
ws.onerror = function (error) {
Logger.error('Could not connect to ' + wsUri + ' (invoking onerror if defined)', error);
if (config.onerror) {
config.onerror(error);
}
};
var reconnectionOnClose = function () {
if (ws.readyState === CLOSED) {
if (closing) {
Logger.debug('Connection closed by user');
}
else {
if (config.ismasternodecrashed()) {
Logger.error('Master Node has crashed. Stopping reconnection process');
}
else {
Logger.debug('Connection closed unexpectedly. Reconnecting...');
reconnect(MAX_RETRIES, 1);
}
}
}
else {
Logger.debug('Close callback from previous websocket. Ignoring it');
}
};
ws.onclose = reconnectionOnClose;
function reconnect(maxRetries, numRetries) {
Logger.debug('reconnect (attempt #' + numRetries + ', max=' + maxRetries + ')');
if (numRetries === 1) {
if (reconnecting) {
Logger.warn('Trying to reconnect when already reconnecting... Ignoring this reconnection.');
return;
}
else {
reconnecting = true;
}
if (config.onreconnecting) {
config.onreconnecting();
}
}
reconnectAux(maxRetries, numRetries);
}
function addReconnectionQueryParamsIfMissing(uriString) {
var searchParams = new URLSearchParams(new URL(uriString).search);
if (!searchParams.has('reconnect')) {
uriString = Array.from(searchParams).length > 0 ? uriString + '&reconnect=true' : uriString + '?reconnect=true';
}
return uriString;
}
function reconnectAux(maxRetries, numRetries) {
Logger.debug('Reconnection attempt #' + numRetries);
ws.close(4104, 'Connection closed for reconnection');
wsUri = addReconnectionQueryParamsIfMissing(wsUri);
ws = new WebSocket(wsUri);
ws.onopen = function () {
Logger.debug('Reconnected to ' + wsUri + ' after ' + numRetries + ' attempts...');
reconnecting = false;
registerMessageHandler();
if (config.onreconnected()) {
config.onreconnected();
}
ws.onclose = reconnectionOnClose;
};
ws.onerror = function (error) {
Logger.warn('Reconnection error: ', error);
if (numRetries === maxRetries) {
if (config.ondisconnect) {
config.ondisconnect();
}
}
else {
setTimeout(function () {
reconnect(maxRetries, numRetries + 1);
}, RETRY_TIME_MS);
}
};
}
this.close = function (code, reason) {
closing = true;
ws.close(code, reason);
};
this.reconnectWs = function () {
Logger.debug('reconnectWs');
reconnect(MAX_RETRIES, 1);
};
this.send = function (message) {
ws.send(message);
};
this.addEventListener = function (type, callback) {
registerMessageHandler = function () {
ws.addEventListener(type, callback);
};
registerMessageHandler();
};
this.getReadyState = function () {
return ws.readyState;
};
}
module.exports = WebSocketWithReconnection;
},{"../../../../Logger/OpenViduLogger":79}],74:[function(require,module,exports){
var defineProperty_IE8 = false;
if (Object.defineProperty) {
try {
Object.defineProperty({}, 'x', {});
}
catch (e) {
defineProperty_IE8 = true;
}
}
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
var EventEmitter = require('events').EventEmitter;
var inherits = require('inherits');
var packers = require('./packers');
var Mapper = require('./Mapper');
var BASE_TIMEOUT = 5000;
function unifyResponseMethods(responseMethods) {
if (!responseMethods)
return {};
for (var key in responseMethods) {
var value = responseMethods[key];
if (typeof value == 'string')
responseMethods[key] = {
response: value
};
}
return responseMethods;
}
function unifyTransport(transport) {
if (!transport)
return;
if (transport instanceof Function)
return {
send: transport
};
if (transport.send instanceof Function)
return transport;
if (transport.postMessage instanceof Function) {
transport.send = transport.postMessage;
return transport;
}
if (transport.write instanceof Function) {
transport.send = transport.write;
return transport;
}
if (transport.onmessage !== undefined)
return;
if (transport.pause instanceof Function)
return;
throw new SyntaxError('Transport is not a function nor a valid object');
}
function RpcNotification(method, params) {
if (defineProperty_IE8) {
this.method = method;
this.params = params;
}
else {
Object.defineProperty(this, 'method', {
value: method,
enumerable: true
});
Object.defineProperty(this, 'params', {
value: params,
enumerable: true
});
}
}
function RpcBuilder(packer, options, transport, onRequest) {
var self = this;
if (!packer)
throw new SyntaxError('Packer is not defined');
if (!packer.pack || !packer.unpack)
throw new SyntaxError('Packer is invalid');
var responseMethods = unifyResponseMethods(packer.responseMethods);
if (options instanceof Function) {
if (transport != undefined)
throw new SyntaxError("There can't be parameters after onRequest");
onRequest = options;
transport = undefined;
options = undefined;
}
if (options && options.send instanceof Function) {
if (transport && !(transport instanceof Function))
throw new SyntaxError('Only a function can be after transport');
onRequest = transport;
transport = options;
options = undefined;
}
if (transport instanceof Function) {
if (onRequest != undefined)
throw new SyntaxError("There can't be parameters after onRequest");
onRequest = transport;
transport = undefined;
}
if (transport && transport.send instanceof Function)
if (onRequest && !(onRequest instanceof Function))
throw new SyntaxError('Only a function can be after transport');
options = options || {};
EventEmitter.call(this);
if (onRequest)
this.on('request', onRequest);
if (defineProperty_IE8)
this.peerID = options.peerID;
else
Object.defineProperty(this, 'peerID', {
value: options.peerID
});
var max_retries = options.max_retries || 0;
function transportMessage(event) {
self.decode(event.data || event);
}
this.getTransport = function () {
return transport;
};
this.setTransport = function (value) {
if (transport) {
if (transport.removeEventListener)
transport.removeEventListener('message', transportMessage);
else if (transport.removeListener)
transport.removeListener('data', transportMessage);
}
if (value) {
if (value.addEventListener)
value.addEventListener('message', transportMessage);
else if (value.addListener)
value.addListener('data', transportMessage);
}
transport = unifyTransport(value);
};
if (!defineProperty_IE8)
Object.defineProperty(this, 'transport', {
get: this.getTransport.bind(this),
set: this.setTransport.bind(this)
});
this.setTransport(transport);
var request_timeout = options.request_timeout || BASE_TIMEOUT;
var ping_request_timeout = options.ping_request_timeout || request_timeout;
var response_timeout = options.response_timeout || BASE_TIMEOUT;
var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT;
var requestID = 0;
var requests = new Mapper();
var responses = new Mapper();
var processedResponses = new Mapper();
var message2Key = {};
function storeResponse(message, id, dest) {
var response = {
message: message,
timeout: setTimeout(function () {
responses.remove(id, dest);
}, response_timeout)
};
responses.set(response, id, dest);
}
function storeProcessedResponse(ack, from) {
var timeout = setTimeout(function () {
processedResponses.remove(ack, from);
}, duplicates_timeout);
processedResponses.set(timeout, ack, from);
}
function RpcRequest(method, params, id, from, transport) {
RpcNotification.call(this, method, params);
this.getTransport = function () {
return transport;
};
this.setTransport = function (value) {
transport = unifyTransport(value);
};
if (!defineProperty_IE8)
Object.defineProperty(this, 'transport', {
get: this.getTransport.bind(this),
set: this.setTransport.bind(this)
});
var response = responses.get(id, from);
if (!(transport || self.getTransport())) {
if (defineProperty_IE8)
this.duplicated = Boolean(response);
else
Object.defineProperty(this, 'duplicated', {
value: Boolean(response)
});
}
var responseMethod = responseMethods[method];
this.pack = packer.pack.bind(packer, this, id);
this.reply = function (error, result, transport) {
if (error instanceof Function || (error && error.send instanceof Function)) {
if (result != undefined)
throw new SyntaxError("There can't be parameters after callback");
transport = error;
result = null;
error = undefined;
}
else if (result instanceof Function || (result && result.send instanceof Function)) {
if (transport != undefined)
throw new SyntaxError("There can't be parameters after callback");
transport = result;
result = null;
}
transport = unifyTransport(transport);
if (response)
clearTimeout(response.timeout);
if (from != undefined) {
if (error)
error.dest = from;
if (result)
result.dest = from;
}
var message;
if (error || result != undefined) {
if (self.peerID != undefined) {
if (error)
error.from = self.peerID;
else
result.from = self.peerID;
}
if (responseMethod) {
if (responseMethod.error == undefined && error)
message = {
error: error
};
else {
var method = error ? responseMethod.error : responseMethod.response;
message = {
method: method,
params: error || result
};
}
}
else
message = {
error: error,
result: result
};
message = packer.pack(message, id);
}
else if (response)
message = response.message;
else
message = packer.pack({
result: null
}, id);
storeResponse(message, id, from);
transport = transport || this.getTransport() || self.getTransport();
if (transport)
return transport.send(message);
return message;
};
}
inherits(RpcRequest, RpcNotification);
function cancel(message) {
var key = message2Key[message];
if (!key)
return;
delete message2Key[message];
var request = requests.pop(key.id, key.dest);
if (!request)
return;
clearTimeout(request.timeout);
storeProcessedResponse(key.id, key.dest);
}
this.cancel = function (message) {
if (message)
return cancel(message);
for (var message in message2Key)
cancel(message);
};
this.close = function () {
var transport = this.getTransport();
if (transport && transport.close)
transport.close(4003, 'Cancel request');
this.cancel();
processedResponses.forEach(clearTimeout);
responses.forEach(function (response) {
clearTimeout(response.timeout);
});
};
this.encode = function (method, params, dest, transport, callback) {
if (params instanceof Function) {
if (dest != undefined)
throw new SyntaxError("There can't be parameters after callback");
callback = params;
transport = undefined;
dest = undefined;
params = undefined;
}
else if (dest instanceof Function) {
if (transport != undefined)
throw new SyntaxError("There can't be parameters after callback");
callback = dest;
transport = undefined;
dest = undefined;
}
else if (transport instanceof Function) {
if (callback != undefined)
throw new SyntaxError("There can't be parameters after callback");
callback = transport;
transport = undefined;
}
if (self.peerID != undefined) {
params = params || {};
params.from = self.peerID;
}
if (dest != undefined) {
params = params || {};
params.dest = dest;
}
var message = {
method: method,
params: params
};
if (callback) {
var id = requestID++;
var retried = 0;
message = packer.pack(message, id);
function dispatchCallback(error, result) {
self.cancel(message);
callback(error, result);
}
var request = {
message: message,
callback: dispatchCallback,
responseMethods: responseMethods[method] || {}
};
var encode_transport = unifyTransport(transport);
function sendRequest(transport) {
var rt = method === 'ping' ? ping_request_timeout : request_timeout;
request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++));
message2Key[message] = {
id: id,
dest: dest
};
requests.set(request, id, dest);
transport = transport || encode_transport || self.getTransport();
if (transport)
return transport.send(message);
return message;
}
function retry(transport) {
transport = unifyTransport(transport);
console.warn(retried + ' retry for request message:', message);
var timeout = processedResponses.pop(id, dest);
clearTimeout(timeout);
return sendRequest(transport);
}
function timeout() {
if (retried < max_retries)
return retry(transport);
var error = new Error('Request has timed out');
error.request = message;
error.retry = retry;
dispatchCallback(error);
}
return sendRequest(transport);
}
message = packer.pack(message);
transport = transport || this.getTransport();
if (transport)
return transport.send(message);
return message;
};
this.decode = function (message, transport) {
if (!message)
throw new TypeError('Message is not defined');
try {
message = packer.unpack(message);
}
catch (e) {
return console.debug(e, message);
}
var id = message.id;
var ack = message.ack;
var method = message.method;
var params = message.params || {};
var from = params.from;
var dest = params.dest;
if (self.peerID != undefined && from == self.peerID)
return;
if (id == undefined && ack == undefined) {
var notification = new RpcNotification(method, params);
if (self.emit('request', notification))
return;
return notification;
}
function processRequest() {
transport = unifyTransport(transport) || self.getTransport();
if (transport) {
var response = responses.get(id, from);
if (response)
return transport.send(response.message);
}
var idAck = id != undefined ? id : ack;
var request = new RpcRequest(method, params, idAck, from, transport);
if (self.emit('request', request))
return;
return request;
}
function processResponse(request, error, result) {
request.callback(error, result);
}
function duplicatedResponse(timeout) {
console.warn('Response already processed', message);
clearTimeout(timeout);
storeProcessedResponse(ack, from);
}
if (method) {
if (dest == undefined || dest == self.peerID) {
var request = requests.get(ack, from);
if (request) {
var responseMethods = request.responseMethods;
if (method == responseMethods.error)
return processResponse(request, params);
if (method == responseMethods.response)
return processResponse(request, null, params);
return processRequest();
}
var processed = processedResponses.get(ack, from);
if (processed)
return duplicatedResponse(processed);
}
return processRequest();
}
var error = message.error;
var result = message.result;
if (error && error.dest && error.dest != self.peerID)
return;
if (result && result.dest && result.dest != self.peerID)
return;
var request = requests.get(ack, from);
if (!request) {
var processed = processedResponses.get(ack, from);
if (processed)
return duplicatedResponse(processed);
return console.warn('No callback was defined for this message', message);
}
processResponse(request, error, result);
};
}
inherits(RpcBuilder, EventEmitter);
RpcBuilder.RpcNotification = RpcNotification;
module.exports = RpcBuilder;
var clients = require('./clients');
var transports = require('./clients/transports');
RpcBuilder.clients = clients;
RpcBuilder.clients.transports = transports;
RpcBuilder.packers = packers;
},{"./Mapper":69,"./clients":70,"./clients/transports":72,"./packers":77,"events":1,"inherits":6}],75:[function(require,module,exports){
function pack(message, id) {
var result = {
jsonrpc: '2.0'
};
if (message.method) {
result.method = message.method;
if (message.params)
result.params = message.params;
if (id != undefined)
result.id = id;
}
else if (id != undefined) {
if (message.error) {
if (message.result !== undefined)
throw new TypeError('Both result and error are defined');
result.error = message.error;
}
else if (message.result !== undefined)
result.result = message.result;
else
throw new TypeError('No result or error is defined');
result.id = id;
}
return JSON.stringify(result);
}
function unpack(message) {
var result = message;
if (typeof message === 'string' || message instanceof String) {
result = JSON.parse(message);
}
var version = result.jsonrpc;
if (version !== '2.0')
throw new TypeError("Invalid JsonRPC version '" + version + "': " + message);
if (result.method == undefined) {
if (result.id == undefined)
throw new TypeError('Invalid message: ' + message);
var result_defined = result.result !== undefined;
var error_defined = result.error !== undefined;
if (result_defined && error_defined)
throw new TypeError('Both result and error are defined: ' + message);
if (!result_defined && !error_defined)
throw new TypeError('No result or error is defined: ' + message);
result.ack = result.id;
delete result.id;
}
return result;
}
exports.pack = pack;
exports.unpack = unpack;
},{}],76:[function(require,module,exports){
function pack(message) {
throw new TypeError('Not yet implemented');
}
function unpack(message) {
throw new TypeError('Not yet implemented');
}
exports.pack = pack;
exports.unpack = unpack;
},{}],77:[function(require,module,exports){
var JsonRPC = require('./JsonRPC');
var XmlRPC = require('./XmlRPC');
exports.JsonRPC = JsonRPC;
exports.XmlRPC = XmlRPC;
},{"./JsonRPC":75,"./XmlRPC":76}],78:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleLogger = void 0;
var ConsoleLogger = (function () {
function ConsoleLogger(console) {
this.logger = console;
(this.log = console.log),
(this.info = console.info),
(this.debug = console.debug),
(this.warn = console.warn),
(this.error = console.error);
}
return ConsoleLogger;
}());
exports.ConsoleLogger = ConsoleLogger;
},{}],79:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenViduLogger = void 0;
var jsnlog_1 = require("jsnlog");
var ConsoleLogger_1 = require("./ConsoleLogger");
var OpenViduLoggerConfiguration_1 = require("./OpenViduLoggerConfiguration");
var OpenViduLogger = (function () {
function OpenViduLogger() {
this.JSNLOG_URL = '/openvidu/elk/openvidu-browser-logs';
this.MAX_JSNLOG_BATCH_LOG_MESSAGES = 100;
this.MAX_MSECONDS_BATCH_MESSAGES = 5000;
this.MAX_LENGTH_STRING_JSON = 1000;
this.defaultConsoleLogger = new ConsoleLogger_1.ConsoleLogger(globalThis.console);
this.isProdMode = false;
this.isJSNLogSetup = false;
}
OpenViduLogger.configureJSNLog = function (openVidu, token) {
var _this = this;
try {
if (globalThis['LOG_JSNLOG_RESULTS'] ||
(this.instance &&
openVidu.isAtLeastPro &&
this.instance.isOpenViduBrowserLogsDebugActive(openVidu) &&
this.instance.canConfigureJSNLog(openVidu, this.instance))) {
if (openVidu.sendBrowserLogs === OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.debug_app) {
this.instance.replaceWindowConsole();
}
this.instance.isJSNLogSetup = false;
this.instance.info('Configuring JSNLogs.');
var finalUserId_1 = openVidu.finalUserId;
var sessionId_1 = openVidu.session.sessionId;
var beforeSendCallback = function (xhr) {
var parentReadyStateFunction = xhr.onreadystatechange;
xhr.onreadystatechange = function () {
if (_this.isInvalidResponse(xhr)) {
Object.defineProperty(xhr, 'readyState', { value: 4 });
Object.defineProperty(xhr, 'status', { value: 200 });
_this.instance.disableLogger();
}
parentReadyStateFunction();
};
xhr.setRequestHeader('Authorization', 'Basic ' + btoa("".concat(finalUserId_1, "%/%").concat(sessionId_1) + ':' + token));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('OV-Final-User-Id', finalUserId_1);
xhr.setRequestHeader('OV-Session-Id', sessionId_1);
xhr.setRequestHeader('OV-Token', token);
};
this.instance.currentAppender = jsnlog_1.JL.createAjaxAppender("appender-".concat(finalUserId_1, "-").concat(sessionId_1));
this.instance.currentAppender.setOptions({
beforeSend: beforeSendCallback,
maxBatchSize: 1000,
batchSize: this.instance.MAX_JSNLOG_BATCH_LOG_MESSAGES,
batchTimeout: this.instance.MAX_MSECONDS_BATCH_MESSAGES
});
var logSerializer = function (obj) {
var getCircularReplacer = function () {
var seen = new WeakSet();
return function (key, value) {
if (typeof value === 'object' && value != null) {
if (seen.has(value) || (globalThis.HTMLElement && value instanceof HTMLElement)) {
return;
}
seen.add(value);
}
return value;
};
};
var stringifyJson = JSON.stringify(obj, getCircularReplacer());
if (stringifyJson.length > _this.instance.MAX_LENGTH_STRING_JSON) {
stringifyJson = "".concat(stringifyJson.substring(0, _this.instance.MAX_LENGTH_STRING_JSON), "...");
}
if (globalThis['LOG_JSNLOG_RESULTS']) {
console.log(stringifyJson);
}
return stringifyJson;
};
jsnlog_1.JL.setOptions({
defaultAjaxUrl: openVidu.httpUri + this.instance.JSNLOG_URL,
serialize: logSerializer,
enabled: true
});
(0, jsnlog_1.JL)().setOptions({
appenders: [this.instance.currentAppender]
});
this.instance.isJSNLogSetup = true;
this.instance.loggingSessionId = sessionId_1;
this.instance.info('JSNLog configured.');
}
}
catch (e) {
console.error('Error configuring JSNLog: ');
console.error(e);
this.instance.disableLogger();
}
};
OpenViduLogger.getInstance = function () {
if (!OpenViduLogger.instance) {
OpenViduLogger.instance = new OpenViduLogger();
}
return OpenViduLogger.instance;
};
OpenViduLogger.isInvalidResponse = function (xhr) {
return xhr.status == 401 || xhr.status == 403 || xhr.status == 404 || xhr.status == 0;
};
OpenViduLogger.prototype.canConfigureJSNLog = function (openVidu, logger) {
return openVidu.session.sessionId != logger.loggingSessionId;
};
OpenViduLogger.prototype.isOpenViduBrowserLogsDebugActive = function (openVidu) {
return (openVidu.sendBrowserLogs === OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.debug ||
openVidu.sendBrowserLogs === OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.debug_app);
};
OpenViduLogger.prototype.getConsoleWithJSNLog = function () {
return (function (openViduLogger) {
return {
log: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.log.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
},
info: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.info.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
},
debug: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.debug.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
},
warn: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.warn.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().warn(arguments);
}
},
error: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.error.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().error(arguments);
}
}
};
})(this);
};
OpenViduLogger.prototype.replaceWindowConsole = function () {
globalThis.console = this.defaultConsoleLogger.logger;
globalThis.console.log = this.getConsoleWithJSNLog().log;
globalThis.console.info = this.getConsoleWithJSNLog().info;
globalThis.console.debug = this.getConsoleWithJSNLog().debug;
globalThis.console.warn = this.getConsoleWithJSNLog().warn;
globalThis.console.error = this.getConsoleWithJSNLog().error;
};
OpenViduLogger.prototype.disableLogger = function () {
jsnlog_1.JL.setOptions({ enabled: false });
this.isJSNLogSetup = false;
this.loggingSessionId = undefined;
this.currentAppender = undefined;
globalThis.console = this.defaultConsoleLogger.logger;
globalThis.console.log = this.defaultConsoleLogger.log;
globalThis.console.info = this.defaultConsoleLogger.info;
globalThis.console.debug = this.defaultConsoleLogger.debug;
globalThis.console.warn = this.defaultConsoleLogger.warn;
globalThis.console.error = this.defaultConsoleLogger.error;
};
OpenViduLogger.prototype.log = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this.isProdMode) {
this.defaultConsoleLogger.log.apply(this.defaultConsoleLogger.logger, arguments);
}
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
};
OpenViduLogger.prototype.debug = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this.isProdMode) {
this.defaultConsoleLogger.debug.apply(this.defaultConsoleLogger.logger, arguments);
}
};
OpenViduLogger.prototype.info = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this.isProdMode) {
this.defaultConsoleLogger.info.apply(this.defaultConsoleLogger.logger, arguments);
}
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
};
OpenViduLogger.prototype.warn = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
this.defaultConsoleLogger.warn.apply(this.defaultConsoleLogger.logger, arguments);
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().warn(arguments);
}
};
OpenViduLogger.prototype.error = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
this.defaultConsoleLogger.error.apply(this.defaultConsoleLogger.logger, arguments);
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().error(arguments);
}
};
OpenViduLogger.prototype.flush = function () {
if (this.isJSNLogSetup && this.currentAppender != null) {
this.currentAppender.sendBatch();
}
};
OpenViduLogger.prototype.enableProdMode = function () {
this.isProdMode = true;
};
return OpenViduLogger;
}());
exports.OpenViduLogger = OpenViduLogger;
},{"./ConsoleLogger":78,"./OpenViduLoggerConfiguration":80,"jsnlog":7}],80:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenViduLoggerConfiguration = void 0;
var OpenViduLoggerConfiguration;
(function (OpenViduLoggerConfiguration) {
OpenViduLoggerConfiguration["disabled"] = "disabled";
OpenViduLoggerConfiguration["debug"] = "debug";
OpenViduLoggerConfiguration["debug_app"] = "debug_app";
})(OpenViduLoggerConfiguration = exports.OpenViduLoggerConfiguration || (exports.OpenViduLoggerConfiguration = {}));
},{}],81:[function(require,module,exports){
globalThis.getScreenId = function (firefoxString, callback, custom_parameter) {
if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) {
callback({
video: true
});
return;
}
if (!!navigator.mozGetUserMedia) {
callback(null, 'firefox', {
video: {
mozMediaSource: firefoxString,
mediaSource: firefoxString
}
});
return;
}
globalThis.addEventListener('message', onIFrameCallback);
function onIFrameCallback(event) {
if (!event.data)
return;
if (event.data.chromeMediaSourceId) {
if (event.data.chromeMediaSourceId === 'PermissionDeniedError') {
callback('permission-denied');
}
else {
callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack));
}
globalThis.removeEventListener('message', onIFrameCallback);
}
if (event.data.chromeExtensionStatus) {
callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus));
globalThis.removeEventListener('message', onIFrameCallback);
}
}
if (!custom_parameter) {
setTimeout(postGetSourceIdMessage, 100);
}
else {
setTimeout(function () {
postGetSourceIdMessage(custom_parameter);
}, 100);
}
};
function getScreenConstraints(error, sourceId, canRequestAudioTrack) {
var screen_constraints = {
audio: false,
video: {
mandatory: {
chromeMediaSource: error ? 'screen' : 'desktop',
maxWidth: globalThis.screen.width > 1920 ? globalThis.screen.width : 1920,
maxHeight: globalThis.screen.height > 1080 ? globalThis.screen.height : 1080
},
optional: []
}
};
if (!!canRequestAudioTrack) {
screen_constraints.audio = {
mandatory: {
chromeMediaSource: error ? 'screen' : 'desktop'
},
optional: []
};
}
if (sourceId) {
screen_constraints.video.mandatory.chromeMediaSourceId = sourceId;
if (screen_constraints.audio && screen_constraints.audio.mandatory) {
screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId;
}
}
return screen_constraints;
}
function postGetSourceIdMessage(custom_parameter) {
if (!iframe) {
loadIFrame(function () {
postGetSourceIdMessage(custom_parameter);
});
return;
}
if (!iframe.isLoaded) {
setTimeout(function () {
postGetSourceIdMessage(custom_parameter);
}, 100);
return;
}
if (!custom_parameter) {
iframe.contentWindow.postMessage({
captureSourceId: true
}, '*');
}
else if (!!custom_parameter.forEach) {
iframe.contentWindow.postMessage({
captureCustomSourceId: custom_parameter
}, '*');
}
else {
iframe.contentWindow.postMessage({
captureSourceIdWithAudio: true
}, '*');
}
}
var iframe;
globalThis.getScreenConstraints = function (callback) {
loadIFrame(function () {
getScreenId(function (error, sourceId, screen_constraints) {
if (!screen_constraints) {
screen_constraints = {
video: true
};
}
callback(error, screen_constraints.video);
});
});
};
function loadIFrame(loadCallback) {
if (iframe) {
loadCallback();
return;
}
iframe = document.createElement('iframe');
iframe.onload = function () {
iframe.isLoaded = true;
loadCallback();
};
iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/';
iframe.style.display = 'none';
(document.body || document.documentElement).appendChild(iframe);
}
globalThis.getChromeExtensionStatus = function (callback) {
if (!!navigator.mozGetUserMedia) {
callback('installed-enabled');
return;
}
globalThis.addEventListener('message', onIFrameCallback);
function onIFrameCallback(event) {
if (!event.data)
return;
if (event.data.chromeExtensionStatus) {
callback(event.data.chromeExtensionStatus);
globalThis.removeEventListener('message', onIFrameCallback);
}
}
setTimeout(postGetChromeExtensionStatusMessage, 100);
};
function postGetChromeExtensionStatusMessage() {
if (!iframe) {
loadIFrame(postGetChromeExtensionStatusMessage);
return;
}
if (!iframe.isLoaded) {
setTimeout(postGetChromeExtensionStatusMessage, 100);
return;
}
iframe.contentWindow.postMessage({
getChromeExtensionStatus: true
}, '*');
}
exports.getScreenId = globalThis.getScreenId;
},{}],82:[function(require,module,exports){
var chromeMediaSource = 'screen';
var sourceId;
var screenCallback;
if (typeof window !== 'undefined' && typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined') {
var isFirefox = typeof window.InstallTrigger !== 'undefined';
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
var isChrome = !!window.chrome && !isOpera;
window.addEventListener('message', function (event) {
if (event.origin != window.location.origin) {
return;
}
onMessageCallback(event.data);
});
}
function onMessageCallback(data) {
if (data == 'PermissionDeniedError') {
if (screenCallback)
return screenCallback('PermissionDeniedError');
else
throw new Error('PermissionDeniedError');
}
if (data == 'rtcmulticonnection-extension-loaded') {
chromeMediaSource = 'desktop';
}
if (data.sourceId && screenCallback) {
screenCallback((sourceId = data.sourceId), data.canRequestAudioTrack === true);
}
}
function isChromeExtensionAvailable(callback) {
if (!callback)
return;
if (chromeMediaSource == 'desktop')
return callback(true);
window.postMessage('are-you-there', '*');
setTimeout(function () {
if (chromeMediaSource == 'screen') {
callback(false);
}
else
callback(true);
}, 2000);
}
function getSourceId(callback) {
if (!callback)
throw '"callback" parameter is mandatory.';
if (sourceId)
return callback(sourceId);
screenCallback = callback;
window.postMessage('get-sourceId', '*');
}
function getCustomSourceId(arr, callback) {
if (!arr || !arr.forEach)
throw '"arr" parameter is mandatory and it must be an array.';
if (!callback)
throw '"callback" parameter is mandatory.';
if (sourceId)
return callback(sourceId);
screenCallback = callback;
window.postMessage({
'get-custom-sourceId': arr
}, '*');
}
function getSourceIdWithAudio(callback) {
if (!callback)
throw '"callback" parameter is mandatory.';
if (sourceId)
return callback(sourceId);
screenCallback = callback;
window.postMessage('audio-plus-tab', '*');
}
function getChromeExtensionStatus(extensionid, callback) {
if (isFirefox)
return callback('not-chrome');
if (arguments.length != 2) {
callback = extensionid;
extensionid = 'lfcgfepafnobdloecchnfaclibenjold';
}
var image = document.createElement('img');
image.src = 'chrome-extension://' + extensionid + '/icon.png';
image.onload = function () {
chromeMediaSource = 'screen';
window.postMessage('are-you-there', '*');
setTimeout(function () {
if (chromeMediaSource == 'screen') {
callback('installed-disabled');
}
else
callback('installed-enabled');
}, 2000);
};
image.onerror = function () {
callback('not-installed');
};
}
function getScreenConstraintsWithAudio(callback) {
getScreenConstraints(callback, true);
}
function getScreenConstraints(callback, captureSourceIdWithAudio) {
sourceId = '';
var firefoxScreenConstraints = {
mozMediaSource: 'window',
mediaSource: 'window'
};
if (isFirefox)
return callback(null, firefoxScreenConstraints);
var screen_constraints = {
mandatory: {
chromeMediaSource: chromeMediaSource,
maxWidth: screen.width > 1920 ? screen.width : 1920,
maxHeight: screen.height > 1080 ? screen.height : 1080
},
optional: []
};
if (chromeMediaSource == 'desktop' && !sourceId) {
if (captureSourceIdWithAudio) {
getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) {
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
if (canRequestAudioTrack) {
screen_constraints.canRequestAudioTrack = true;
}
callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints);
});
}
else {
getSourceId(function (sourceId) {
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints);
});
}
return;
}
if (chromeMediaSource == 'desktop') {
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
}
callback(null, screen_constraints);
}
exports.getScreenConstraints = getScreenConstraints;
exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio;
exports.isChromeExtensionAvailable = isChromeExtensionAvailable;
exports.getChromeExtensionStatus = getChromeExtensionStatus;
exports.getSourceId = getSourceId;
},{}],83:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformUtils = void 0;
var platform = require("platform");
var PlatformUtils = (function () {
function PlatformUtils() {
}
PlatformUtils.getInstance = function () {
if (!this.instance) {
this.instance = new PlatformUtils();
}
return PlatformUtils.instance;
};
PlatformUtils.prototype.isChromeBrowser = function () {
return platform.name === 'Chrome';
};
PlatformUtils.prototype.isSafariBrowser = function () {
return platform.name === 'Safari';
};
PlatformUtils.prototype.isChromeMobileBrowser = function () {
return platform.name === 'Chrome Mobile';
};
PlatformUtils.prototype.isFirefoxBrowser = function () {
return platform.name === 'Firefox';
};
PlatformUtils.prototype.isFirefoxMobileBrowser = function () {
return platform.name === 'Firefox Mobile' || platform.name === 'Firefox for iOS';
};
PlatformUtils.prototype.isOperaBrowser = function () {
return platform.name === 'Opera';
};
PlatformUtils.prototype.isOperaMobileBrowser = function () {
return platform.name === 'Opera Mobile';
};
PlatformUtils.prototype.isEdgeBrowser = function () {
var version = (platform === null || platform === void 0 ? void 0 : platform.version) ? parseFloat(platform.version) : -1;
return platform.name === 'Microsoft Edge' && version >= 80;
};
PlatformUtils.prototype.isEdgeMobileBrowser = function () {
var _a, _b;
var version = (platform === null || platform === void 0 ? void 0 : platform.version) ? parseFloat(platform.version) : -1;
return platform.name === 'Microsoft Edge' && (((_a = platform.os) === null || _a === void 0 ? void 0 : _a.family) === 'Android' || ((_b = platform.os) === null || _b === void 0 ? void 0 : _b.family) === 'iOS') && version > 45;
};
PlatformUtils.prototype.isAndroidBrowser = function () {
return platform.name === 'Android Browser';
};
PlatformUtils.prototype.isElectron = function () {
return platform.name === 'Electron';
};
PlatformUtils.prototype.isNodeJs = function () {
return platform.name === 'Node.js';
};
PlatformUtils.prototype.isSamsungBrowser = function () {
return platform.name === 'Samsung Internet Mobile' || platform.name === 'Samsung Internet';
};
PlatformUtils.prototype.isIPhoneOrIPad = function () {
var userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
var isTouchable = 'ontouchend' in document;
var isIPad = /\b(\w*Macintosh\w*)\b/.test(userAgent) && isTouchable;
var isIPhone = /\b(\w*iPhone\w*)\b/.test(userAgent) && /\b(\w*Mobile\w*)\b/.test(userAgent) && isTouchable;
return isIPad || isIPhone;
};
PlatformUtils.prototype.isIOSWithSafari = function () {
var userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
return (this.isIPhoneOrIPad() &&
/\b(\w*Apple\w*)\b/.test(navigator.vendor) &&
/\b(\w*Safari\w*)\b/.test(userAgent) &&
!/\b(\w*CriOS\w*)\b/.test(userAgent) &&
!/\b(\w*FxiOS\w*)\b/.test(userAgent));
};
PlatformUtils.prototype.isIonicIos = function () {
return this.isIPhoneOrIPad() && platform.ua.indexOf('Safari') === -1;
};
PlatformUtils.prototype.isIonicAndroid = function () {
return platform.os.family === 'Android' && platform.name == 'Android Browser';
};
PlatformUtils.prototype.isMobileDevice = function () {
return platform.os.family === 'iOS' || platform.os.family === 'Android';
};
PlatformUtils.prototype.isReactNative = function () {
return false;
};
PlatformUtils.prototype.isChromium = function () {
return (this.isChromeBrowser() ||
this.isChromeMobileBrowser() ||
this.isOperaBrowser() ||
this.isOperaMobileBrowser() ||
this.isEdgeBrowser() ||
this.isEdgeMobileBrowser() ||
this.isSamsungBrowser() ||
this.isIonicAndroid() ||
this.isIonicIos() ||
this.isElectron());
};
PlatformUtils.prototype.canScreenShare = function () {
var version = (platform === null || platform === void 0 ? void 0 : platform.version) ? parseFloat(platform.version) : -1;
if (this.isMobileDevice()) {
return false;
}
return (this.isChromeBrowser() ||
this.isFirefoxBrowser() ||
this.isOperaBrowser() ||
this.isElectron() ||
this.isEdgeBrowser() ||
(this.isSafariBrowser() && version >= 13));
};
PlatformUtils.prototype.getName = function () {
return platform.name || '';
};
PlatformUtils.prototype.getVersion = function () {
return platform.version || '';
};
PlatformUtils.prototype.getFamily = function () {
return platform.os.family || '';
};
PlatformUtils.prototype.getDescription = function () {
return platform.description || '';
};
return PlatformUtils;
}());
exports.PlatformUtils = PlatformUtils;
},{"platform":12}],84:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebRtcPeerSendrecv = exports.WebRtcPeerSendonly = exports.WebRtcPeerRecvonly = exports.WebRtcPeer = void 0;
var freeice = require("freeice");
var uuid_1 = require("uuid");
var ExceptionEvent_1 = require("../Events/ExceptionEvent");
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var Platform_1 = require("../Utils/Platform");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var WebRtcPeer = (function () {
function WebRtcPeer(configuration) {
var _this = this;
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
this.iceCandidateList = [];
this.candidategatheringdone = false;
platform = Platform_1.PlatformUtils.getInstance();
this.configuration = __assign(__assign({}, configuration), { iceServers: !!configuration.iceServers && configuration.iceServers.length > 0 ? configuration.iceServers : freeice(), mediaStream: configuration.mediaStream !== undefined ? configuration.mediaStream : null, mode: !!configuration.mode ? configuration.mode : 'sendrecv', id: !!configuration.id ? configuration.id : this.generateUniqueId() });
logger.debug("[WebRtcPeer] configuration:\n".concat(JSON.stringify(this.configuration, null, 2)));
this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers });
this.pc.addEventListener('icecandidate', function (event) {
if (event.candidate !== null) {
var candidateInit = event.candidate;
var iceCandidate = new RTCIceCandidate(candidateInit);
_this.configuration.onIceCandidate(iceCandidate);
if (iceCandidate.candidate !== '') {
_this.localCandidatesQueue.push(iceCandidate);
}
}
});
this.pc.addEventListener('signalingstatechange', function () {
if (_this.pc.signalingState === 'stable') {
while (_this.iceCandidateList.length > 0) {
var candidate = _this.iceCandidateList.shift();
_this.pc.addIceCandidate(candidate);
}
}
});
}
WebRtcPeer.prototype.getId = function () {
return this.configuration.id;
};
WebRtcPeer.prototype.dispose = function () {
logger.debug('Disposing WebRtcPeer');
if (this.pc) {
if (this.pc.signalingState === 'closed') {
return;
}
this.pc.close();
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
}
};
WebRtcPeer.prototype.createOfferLegacy = function () {
if (!!this.configuration.mediaStream) {
this.deprecatedPeerConnectionTrackApi();
}
var hasAudio = this.configuration.mediaConstraints.audio;
var hasVideo = this.configuration.mediaConstraints.video;
var options = {
offerToReceiveAudio: this.configuration.mode !== 'sendonly' && hasAudio,
offerToReceiveVideo: this.configuration.mode !== 'sendonly' && hasVideo
};
logger.debug('[createOfferLegacy] RTCPeerConnection.createOffer() options:', JSON.stringify(options));
return this.pc.createOffer(options);
};
WebRtcPeer.prototype.createOffer = function () {
var _a, _b, _c, _d, _e, _f, _g, _h;
return __awaiter(this, void 0, void 0, function () {
var _i, _j, track, tcInit, trackSettings, trackConsts, trackWidth, trackHeight, trackPixels, maxLayers, l, layerDiv, encoding, tc, sendParams, needSetParams, error_1, message, _k, _l, kind, sdpOffer, error_2, message;
return __generator(this, function (_m) {
switch (_m.label) {
case 0:
if (!('addTransceiver' in this.pc)) {
logger.warn('[createOffer] Method RTCPeerConnection.addTransceiver() is NOT available; using LEGACY offerToReceive{Audio,Video}');
return [2, this.createOfferLegacy()];
}
else {
logger.debug('[createOffer] Method RTCPeerConnection.addTransceiver() is available; using it');
}
if (!(this.configuration.mode !== 'recvonly')) return [3, 7];
if (!this.configuration.mediaStream) {
throw new Error("[WebRtcPeer.createOffer] Direction is '".concat(this.configuration.mode, "', but no stream was configured to be sent"));
}
_i = 0, _j = this.configuration.mediaStream.getTracks();
_m.label = 1;
case 1:
if (!(_i < _j.length)) return [3, 6];
track = _j[_i];
tcInit = {
direction: this.configuration.mode,
streams: [this.configuration.mediaStream]
};
if (track.kind === 'video' && this.configuration.simulcast) {
trackSettings = track.getSettings();
trackConsts = track.getConstraints();
trackWidth = (_c = (_b = (_a = trackSettings.width) !== null && _a !== void 0 ? _a : trackConsts.width.ideal) !== null && _b !== void 0 ? _b : trackConsts.width) !== null && _c !== void 0 ? _c : 0;
trackHeight = (_f = (_e = (_d = trackSettings.height) !== null && _d !== void 0 ? _d : trackConsts.height.ideal) !== null && _e !== void 0 ? _e : trackConsts.height) !== null && _f !== void 0 ? _f : 0;
logger.info("[createOffer] Video track dimensions: ".concat(trackWidth, "x").concat(trackHeight));
trackPixels = trackWidth * trackHeight;
maxLayers = 0;
if (trackPixels >= 960 * 540) {
maxLayers = 3;
}
else if (trackPixels >= 480 * 270) {
maxLayers = 2;
}
else {
maxLayers = 1;
}
tcInit.sendEncodings = [];
for (l = 0; l < maxLayers; l++) {
layerDiv = Math.pow(2, (maxLayers - l - 1));
encoding = {
rid: 'rdiv' + layerDiv.toString(),
scalabilityMode: 'L1T1'
};
if (['detail', 'text'].includes(track.contentHint)) {
encoding.scaleResolutionDownBy = 1.0;
encoding.maxFramerate = Math.floor(30 / layerDiv);
}
else {
encoding.scaleResolutionDownBy = layerDiv;
}
tcInit.sendEncodings.push(encoding);
}
}
tc = this.pc.addTransceiver(track, tcInit);
if (!(track.kind === 'video')) return [3, 5];
sendParams = tc.sender.getParameters();
needSetParams = false;
if (!((_g = sendParams.degradationPreference) === null || _g === void 0 ? void 0 : _g.length)) {
if (['detail', 'text'].includes(track.contentHint)) {
sendParams.degradationPreference = 'maintain-resolution';
}
else {
sendParams.degradationPreference = 'balanced';
}
logger.info("[createOffer] Video sender Degradation Preference set: ".concat(sendParams.degradationPreference));
needSetParams = true;
}
if (this.configuration.simulcast) {
if (((_h = sendParams.encodings) === null || _h === void 0 ? void 0 : _h.length) !== tcInit.sendEncodings.length) {
sendParams.encodings = tcInit.sendEncodings;
needSetParams = true;
}
}
if (!needSetParams) return [3, 5];
logger.debug("[createOffer] Setting new RTCRtpSendParameters to video sender");
_m.label = 2;
case 2:
_m.trys.push([2, 4, , 5]);
return [4, tc.sender.setParameters(sendParams)];
case 3:
_m.sent();
return [3, 5];
case 4:
error_1 = _m.sent();
message = "[WebRtcPeer.createOffer] Cannot set RTCRtpSendParameters to video sender";
if (error_1 instanceof Error) {
message += ": ".concat(error_1.message);
}
throw new Error(message);
case 5:
_i++;
return [3, 1];
case 6: return [3, 8];
case 7:
for (_k = 0, _l = ['audio', 'video']; _k < _l.length; _k++) {
kind = _l[_k];
if (!this.configuration.mediaConstraints[kind]) {
continue;
}
this.configuration.mediaStream = new MediaStream();
this.pc.addTransceiver(kind, {
direction: this.configuration.mode,
streams: [this.configuration.mediaStream]
});
}
_m.label = 8;
case 8:
_m.trys.push([8, 10, , 11]);
return [4, this.pc.createOffer()];
case 9:
sdpOffer = _m.sent();
return [3, 11];
case 10:
error_2 = _m.sent();
message = "[WebRtcPeer.createOffer] Browser failed creating an SDP Offer";
if (error_2 instanceof Error) {
message += ": ".concat(error_2.message);
}
throw new Error(message);
case 11: return [2, sdpOffer];
}
});
});
};
WebRtcPeer.prototype.deprecatedPeerConnectionTrackApi = function () {
for (var _i = 0, _a = this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) {
var track = _a[_i];
this.pc.addTrack(track, this.configuration.mediaStream);
}
};
WebRtcPeer.prototype.createAnswer = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if ('getTransceivers' in _this.pc) {
logger.debug('[createAnswer] Method RTCPeerConnection.getTransceivers() is available; using it');
var _loop_1 = function (kind) {
if (!_this.configuration.mediaConstraints[kind]) {
return "continue";
}
var tc = _this.pc.getTransceivers().find(function (tc) { return tc.receiver.track.kind === kind; });
if (tc) {
tc.direction = _this.configuration.mode;
}
else {
return { value: reject(new Error("".concat(kind, " requested, but no transceiver was created from remote description"))) };
}
};
for (var _i = 0, _a = ['audio', 'video']; _i < _a.length; _i++) {
var kind = _a[_i];
var state_1 = _loop_1(kind);
if (typeof state_1 === "object")
return state_1.value;
}
_this.pc
.createAnswer()
.then(function (sdpAnswer) { return resolve(sdpAnswer); })
.catch(function (error) { return reject(error); });
}
else {
var offerAudio = void 0, offerVideo = true;
if (!!_this.configuration.mediaConstraints) {
offerAudio =
typeof _this.configuration.mediaConstraints.audio === 'boolean' ? _this.configuration.mediaConstraints.audio : true;
offerVideo =
typeof _this.configuration.mediaConstraints.video === 'boolean' ? _this.configuration.mediaConstraints.video : true;
var constraints = {
offerToReceiveAudio: offerAudio,
offerToReceiveVideo: offerVideo
};
_this.pc.createAnswer(constraints)
.then(function (sdpAnswer) { return resolve(sdpAnswer); })
.catch(function (error) { return reject(error); });
}
}
});
};
WebRtcPeer.prototype.processLocalOffer = function (offer) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.pc
.setLocalDescription(offer)
.then(function () {
var localDescription = _this.pc.localDescription;
if (!!localDescription) {
logger.debug('Local description set', localDescription.sdp);
return resolve();
}
else {
return reject('Local description is not defined');
}
})
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.processRemoteOffer = function (sdpOffer) {
var _this = this;
return new Promise(function (resolve, reject) {
var offer = {
type: 'offer',
sdp: sdpOffer
};
logger.debug('SDP offer received, setting remote description', offer);
if (_this.pc.signalingState === 'closed') {
return reject('RTCPeerConnection is closed when trying to set remote description');
}
_this.setRemoteDescription(offer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.processLocalAnswer = function (answer) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.debug('SDP answer created, setting local description');
if (_this.pc.signalingState === 'closed') {
return reject('RTCPeerConnection is closed when trying to set local description');
}
_this.pc
.setLocalDescription(answer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.processRemoteAnswer = function (sdpAnswer) {
var _this = this;
return new Promise(function (resolve, reject) {
var answer = {
type: 'answer',
sdp: sdpAnswer
};
logger.debug('SDP answer received, setting remote description');
if (_this.pc.signalingState === 'closed') {
return reject('RTCPeerConnection is closed when trying to set remote description');
}
_this.setRemoteDescription(answer)
.then(function () {
resolve();
})
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.setRemoteDescription = function (sdp) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.pc.setRemoteDescription(sdp)];
});
});
};
WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.debug('Remote ICE candidate received', iceCandidate);
_this.remoteCandidatesQueue.push(iceCandidate);
switch (_this.pc.signalingState) {
case 'closed':
reject(new Error('PeerConnection object is closed'));
break;
case 'stable':
if (!!_this.pc.remoteDescription) {
_this.pc
.addIceCandidate(iceCandidate)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
else {
_this.iceCandidateList.push(iceCandidate);
resolve();
}
break;
default:
_this.iceCandidateList.push(iceCandidate);
resolve();
}
});
};
WebRtcPeer.prototype.addIceConnectionStateChangeListener = function (otherId) {
var _this = this;
this.pc.addEventListener('iceconnectionstatechange', function () {
var iceConnectionState = _this.pc.iceConnectionState;
switch (iceConnectionState) {
case 'disconnected':
var msg1 = 'IceConnectionState of RTCPeerConnection ' +
_this.configuration.id +
' (' +
otherId +
') change to "disconnected". Possible network disconnection';
logger.warn(msg1);
_this.configuration.onIceConnectionStateException(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_DISCONNECTED, msg1);
break;
case 'failed':
var msg2 = 'IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') to "failed"';
logger.error(msg2);
_this.configuration.onIceConnectionStateException(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_FAILED, msg2);
break;
case 'closed':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "closed"');
break;
case 'new':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "new"');
break;
case 'checking':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "checking"');
break;
case 'connected':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "connected"');
break;
case 'completed':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "completed"');
break;
}
});
};
WebRtcPeer.prototype.generateUniqueId = function () {
return (0, uuid_1.v4)();
};
return WebRtcPeer;
}());
exports.WebRtcPeer = WebRtcPeer;
var WebRtcPeerRecvonly = (function (_super) {
__extends(WebRtcPeerRecvonly, _super);
function WebRtcPeerRecvonly(configuration) {
var _this = this;
configuration.mode = 'recvonly';
_this = _super.call(this, configuration) || this;
return _this;
}
return WebRtcPeerRecvonly;
}(WebRtcPeer));
exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly;
var WebRtcPeerSendonly = (function (_super) {
__extends(WebRtcPeerSendonly, _super);
function WebRtcPeerSendonly(configuration) {
var _this = this;
configuration.mode = 'sendonly';
_this = _super.call(this, configuration) || this;
return _this;
}
return WebRtcPeerSendonly;
}(WebRtcPeer));
exports.WebRtcPeerSendonly = WebRtcPeerSendonly;
var WebRtcPeerSendrecv = (function (_super) {
__extends(WebRtcPeerSendrecv, _super);
function WebRtcPeerSendrecv(configuration) {
var _this = this;
configuration.mode = 'sendrecv';
_this = _super.call(this, configuration) || this;
return _this;
}
return WebRtcPeerSendrecv;
}(WebRtcPeer));
exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;
},{"../Events/ExceptionEvent":58,"../Logger/OpenViduLogger":79,"../Utils/Platform":83,"freeice":2,"uuid":22}],85:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebRtcStats = void 0;
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var Platform_1 = require("../Utils/Platform");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var WebRtcStats = (function () {
function WebRtcStats(stream) {
this.stream = stream;
this.STATS_ITEM_NAME = 'webrtc-stats-config';
this.webRtcStatsEnabled = false;
this.statsInterval = 1;
platform = Platform_1.PlatformUtils.getInstance();
}
WebRtcStats.prototype.isEnabled = function () {
return this.webRtcStatsEnabled;
};
WebRtcStats.prototype.initWebRtcStats = function () {
var _this = this;
var webrtcObj = localStorage.getItem(this.STATS_ITEM_NAME);
if (!!webrtcObj) {
this.webRtcStatsEnabled = true;
var webrtcStatsConfig = JSON.parse(webrtcObj);
logger.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
logger.warn('localStorage item: ' + JSON.stringify(webrtcStatsConfig));
this.POST_URL = webrtcStatsConfig.httpEndpoint;
this.statsInterval = webrtcStatsConfig.interval;
this.webRtcStatsIntervalId = setInterval(function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.sendStatsToHttpEndpoint()];
case 1:
_a.sent();
return [2];
}
});
}); }, this.statsInterval * 1000);
}
else {
logger.debug('WebRtc stats not enabled');
}
};
WebRtcStats.prototype.getSelectedIceCandidateInfo = function () {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var statsReport, transportStat, candidatePairs, localCandidates, remoteCandidates, selectedCandidatePair, selectedCandidatePairId, length_1, iterator, i, candidatePair, localCandidateId, remoteCandidateId, finalLocalCandidate, candList, cand, _i, cand_1, c, finalRemoteCandidate, candList, cand, _a, cand_2, c;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4, this.stream.getRTCPeerConnection().getStats()];
case 1:
statsReport = _b.sent();
candidatePairs = new Map();
localCandidates = new Map();
remoteCandidates = new Map();
statsReport.forEach(function (stat) {
if (stat.type === 'transport' && (platform.isChromium() || platform.isSafariBrowser() || platform.isReactNative())) {
transportStat = stat;
}
switch (stat.type) {
case 'candidate-pair':
candidatePairs.set(stat.id, stat);
break;
case 'local-candidate':
localCandidates.set(stat.id, stat);
break;
case 'remote-candidate':
remoteCandidates.set(stat.id, stat);
break;
}
});
if (transportStat != null) {
selectedCandidatePairId = transportStat.selectedCandidatePairId;
selectedCandidatePair = candidatePairs.get(selectedCandidatePairId);
}
else {
length_1 = candidatePairs.size;
iterator = candidatePairs.values();
for (i = 0; i < length_1; i++) {
candidatePair = iterator.next().value;
if (candidatePair['selected']) {
selectedCandidatePair = candidatePair;
break;
}
}
}
localCandidateId = selectedCandidatePair.localCandidateId;
remoteCandidateId = selectedCandidatePair.remoteCandidateId;
finalLocalCandidate = localCandidates.get(localCandidateId);
if (!!finalLocalCandidate) {
candList = this.stream.getLocalIceCandidateList();
cand = candList.filter(function (c) {
return (!!c.candidate &&
(c.candidate.indexOf(finalLocalCandidate.ip) >= 0 || c.candidate.indexOf(finalLocalCandidate.address) >= 0) &&
c.candidate.indexOf(finalLocalCandidate.port) >= 0);
});
finalLocalCandidate.raw = [];
for (_i = 0, cand_1 = cand; _i < cand_1.length; _i++) {
c = cand_1[_i];
finalLocalCandidate.raw.push(c.candidate);
}
}
else {
finalLocalCandidate = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used';
}
finalRemoteCandidate = remoteCandidates.get(remoteCandidateId);
if (!!finalRemoteCandidate) {
candList = this.stream.getRemoteIceCandidateList();
cand = candList.filter(function (c) {
return (!!c.candidate &&
(c.candidate.indexOf(finalRemoteCandidate.ip) >= 0 || c.candidate.indexOf(finalRemoteCandidate.address) >= 0) &&
c.candidate.indexOf(finalRemoteCandidate.port) >= 0);
});
finalRemoteCandidate.raw = [];
for (_a = 0, cand_2 = cand; _a < cand_2.length; _a++) {
c = cand_2[_a];
finalRemoteCandidate.raw.push(c.candidate);
}
}
else {
finalRemoteCandidate = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used';
}
return [2, resolve({
localCandidate: finalLocalCandidate,
remoteCandidate: finalRemoteCandidate
})];
}
});
}); });
};
WebRtcStats.prototype.stopWebRtcStats = function () {
if (this.webRtcStatsEnabled) {
clearInterval(this.webRtcStatsIntervalId);
logger.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
}
};
WebRtcStats.prototype.sendStats = function (url, response) {
return __awaiter(this, void 0, void 0, function () {
var configuration, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
configuration = {
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(response),
method: 'POST'
};
return [4, fetch(url, configuration)];
case 1:
_a.sent();
return [3, 3];
case 2:
error_1 = _a.sent();
logger.error("sendStats error: ".concat(JSON.stringify(error_1)));
return [3, 3];
case 3: return [2];
}
});
});
};
WebRtcStats.prototype.sendStatsToHttpEndpoint = function () {
return __awaiter(this, void 0, void 0, function () {
var webrtcStats, response, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
return [4, this.getCommonStats()];
case 1:
webrtcStats = _a.sent();
response = this.generateJSONStatsResponse(webrtcStats);
return [4, this.sendStats(this.POST_URL, response)];
case 2:
_a.sent();
return [3, 4];
case 3:
error_2 = _a.sent();
logger.log(error_2);
return [3, 4];
case 4: return [2];
}
});
});
};
WebRtcStats.prototype.getCommonStats = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var statsReport, response_1, videoTrackStats_1, candidatePairStats_1, error_3;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.stream.getRTCPeerConnection().getStats()];
case 1:
statsReport = _a.sent();
response_1 = this.getWebRtcStatsResponseOutline();
videoTrackStats_1 = ['framesReceived', 'framesDropped', 'framesSent', 'frameHeight', 'frameWidth'];
candidatePairStats_1 = ['availableOutgoingBitrate', 'currentRoundTripTime'];
statsReport.forEach(function (stat) {
var mediaType = stat.mediaType != null ? stat.mediaType : stat.kind;
var addStat = function (direction, key) {
if (stat[key] != null && response_1[direction] != null) {
if (!mediaType && videoTrackStats_1.indexOf(key) > -1) {
mediaType = 'video';
}
if (direction != null && mediaType != null && key != null && response_1[direction][mediaType] != null) {
response_1[direction][mediaType][key] = Number(stat[key]);
}
else if (direction != null && key != null && candidatePairStats_1.includes(key)) {
response_1[direction][key] = Number(stat[key]);
}
}
};
switch (stat.type) {
case 'outbound-rtp':
addStat('outbound', 'bytesSent');
addStat('outbound', 'packetsSent');
addStat('outbound', 'framesEncoded');
addStat('outbound', 'nackCount');
addStat('outbound', 'firCount');
addStat('outbound', 'pliCount');
addStat('outbound', 'qpSum');
break;
case 'inbound-rtp':
addStat('inbound', 'bytesReceived');
addStat('inbound', 'packetsReceived');
addStat('inbound', 'packetsLost');
addStat('inbound', 'jitter');
addStat('inbound', 'framesDecoded');
addStat('inbound', 'nackCount');
addStat('inbound', 'firCount');
addStat('inbound', 'pliCount');
break;
case 'track':
addStat('inbound', 'jitterBufferDelay');
addStat('inbound', 'framesReceived');
addStat('outbound', 'framesDropped');
addStat('outbound', 'framesSent');
addStat(_this.stream.isLocal() ? 'outbound' : 'inbound', 'frameHeight');
addStat(_this.stream.isLocal() ? 'outbound' : 'inbound', 'frameWidth');
break;
case 'candidate-pair':
addStat('candidatepair', 'currentRoundTripTime');
addStat('candidatepair', 'availableOutgoingBitrate');
break;
}
});
if (!(response_1 === null || response_1 === void 0 ? void 0 : response_1.candidatepair) || Object.keys(response_1.candidatepair).length === 0) {
delete response_1.candidatepair;
}
return [2, resolve(response_1)];
case 2:
error_3 = _a.sent();
logger.error('Error getting common stats: ', error_3);
return [2, reject(error_3)];
case 3: return [2];
}
});
}); })];
});
});
};
WebRtcStats.prototype.generateJSONStatsResponse = function (stats) {
return {
'@timestamp': new Date().toISOString(),
participant_id: this.stream.connection.data,
session_id: this.stream.session.sessionId,
platform: platform.getName(),
platform_description: platform.getDescription(),
stream: 'webRTC',
webrtc_stats: stats
};
};
WebRtcStats.prototype.getWebRtcStatsResponseOutline = function () {
if (this.stream.isLocal()) {
return {
outbound: {
audio: {},
video: {}
},
candidatepair: {}
};
}
else {
return {
inbound: {
audio: {},
video: {}
}
};
}
};
return WebRtcStats;
}());
exports.WebRtcStats = WebRtcStats;
},{"../Logger/OpenViduLogger":79,"../Utils/Platform":83}]},{},[40])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2pzbmxvZy9qc25sb2cuanMiLCIuLi9ub2RlX21vZHVsZXMvbWltZS9NaW1lLmpzIiwiLi4vbm9kZV9tb2R1bGVzL21pbWUvbGl0ZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9taW1lL3R5cGVzL3N0YW5kYXJkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2NsYXNzZXMvc2VtdmVyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3NlbXZlci9mdW5jdGlvbnMvbWFqb3IuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2Z1bmN0aW9ucy9taW5vci5qcyIsIi4uL25vZGVfbW9kdWxlcy9zZW12ZXIvaW50ZXJuYWwvY29uc3RhbnRzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3NlbXZlci9pbnRlcm5hbC9kZWJ1Zy5qcyIsIi4uL25vZGVfbW9kdWxlcy9zZW12ZXIvaW50ZXJuYWwvaWRlbnRpZmllcnMuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2ludGVybmFsL3BhcnNlLW9wdGlvbnMuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2ludGVybmFsL3JlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvbWQ1LWJyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L25pbC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvcGFyc2UuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3JlZ2V4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9ybmctYnJvd3Nlci5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3Qvc2hhMS1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9zdHJpbmdpZnkuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3YxLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92My5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdjM1LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdjUuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3ZhbGlkYXRlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92ZXJzaW9uLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3dpbGRlbWl0dGVyL3dpbGRlbWl0dGVyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3dvbGZ5ODctZXZlbnRlbWl0dGVyL0V2ZW50RW1pdHRlci5qcyIsIi4uL3BhY2thZ2UuanNvbiIsIk1haW4udHMiLCJPcGVuVmlkdS9Db25uZWN0aW9uLnRzIiwiT3BlblZpZHUvRXZlbnREaXNwYXRjaGVyLnRzIiwiT3BlblZpZHUvRmlsdGVyLnRzIiwiT3BlblZpZHUvTG9jYWxSZWNvcmRlci50cyIsIk9wZW5WaWR1L09wZW5WaWR1LnRzIiwiT3BlblZpZHUvUHVibGlzaGVyLnRzIiwiT3BlblZpZHUvU2Vzc2lvbi50cyIsIk9wZW5WaWR1L1N0cmVhbS50cyIsIk9wZW5WaWR1L1N0cmVhbU1hbmFnZXIudHMiLCJPcGVuVmlkdS9TdWJzY3JpYmVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9Mb2NhbFJlY29yZGVyU3RhdGUudHMiLCJPcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3IudHMiLCJPcGVuVmlkdUludGVybmFsL0VudW1zL1R5cGVPZlZpZGVvLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V4Y2VwdGlvbkV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9OZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL0NvbnNvbGVMb2dnZXIudHMiLCJPcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi50cyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvVXRpbHMvUGxhdGZvcm0udHMiLCJPcGVuVmlkdUludGVybmFsL1dlYlJ0Y1BlZXIvV2ViUnRjUGVlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjU3RhdHMvV2ViUnRjU3RhdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzV1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9SQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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LDhCQUE4QixFQUFFLE9BQUssQ0FBQyxDQUFDO29DQUNwRCxXQUFPLE1BQU0sQ0FBQyxPQUFLLENBQUMsRUFBQzs7Ozt5QkFFNUIsQ0FBQyxFQUFDOzs7S0FDTjtJQUVPLCtDQUF5QixHQUFqQyxVQUFrQyxLQUFtQjtRQUNqRCxPQUFPO1lBQ0gsWUFBWSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1lBQ3RDLGNBQWMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJO1lBQzNDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTO1lBQ3pDLFFBQVEsRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQzVCLG9CQUFvQixFQUFFLFFBQVEsQ0FBQyxjQUFjLEVBQUU7WUFDL0MsTUFBTSxFQUFFLFFBQVE7WUFDaEIsWUFBWSxFQUFFLEtBQUs7U0FDdEIsQ0FBQztJQUNOLENBQUM7SUFFTyxtREFBNkIsR0FBckM7UUFDSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDdkIsT0FBTztnQkFDSCxRQUFRLEVBQUU7b0JBQ04sS0FBSyxFQUFFLEVBQUU7b0JBQ1QsS0FBSyxFQUFFLEVBQUU7aUJBQ1o7Z0JBQ0QsYUFBYSxFQUFFLEVBQUU7YUFDcEIsQ0FBQztTQUNMO2FBQU07WUFDSCxPQUFPO2dCQUNILE9BQU8sRUFBRTtvQkFDTCxLQUFLLEVBQUUsRUFBRTtvQkFDVCxLQUFLLEVBQUUsRUFBRTtpQkFDWjthQUNKLENBQUM7U0FDTDtJQUNMLENBQUM7SUFDTCxrQkFBQztBQUFELENBdFdBLEFBc1dDLElBQUE7QUF0V1ksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIG5vcm1hbGljZSA9IHJlcXVpcmUoJ25vcm1hbGljZScpO1xuXG4vKipcbiAgIyBmcmVlaWNlXG5cbiAgVGhlIGBmcmVlaWNlYCBtb2R1bGUgaXMgYSBzaW1wbGUgd2F5IG9mIGdldHRpbmcgcmFuZG9tIFNUVU4gb3IgVFVSTiBzZXJ2ZXJcbiAgZm9yIHlvdXIgV2ViUlRDIGFwcGxpY2F0aW9uLiAgVGhlIGxpc3Qgb2Ygc2VydmVycyAoanVzdCBTVFVOIGF0IHRoaXMgc3RhZ2UpXG4gIHdlcmUgc291cmNlZCBmcm9tIHRoaXMgW2dpc3RdKGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL3p6aXVuaS8zNzQxOTMzKS5cblxuICAjIyBFeGFtcGxlIFVzZVxuXG4gIFRoZSBmb2xsb3dpbmcgZGVtb25zdHJhdGVzIGhvdyB5b3UgY2FuIHVzZSBgZnJlZWljZWAgd2l0aFxuICBbcnRjLXF1aWNrY29ubmVjdF0oaHR0cHM6Ly9naXRodWIuY29tL3J0Yy1pby9ydGMtcXVpY2tjb25uZWN0KTpcblxuICA8PDwgZXhhbXBsZXMvcXVpY2tjb25uZWN0LmpzXG5cbiAgQXMgdGhlIGBmcmVlaWNlYCBtb2R1bGUgZ2VuZXJhdGVzIGljZSBzZXJ2ZXJzIGluIGEgbGlzdCBjb21wbGlhbnQgd2l0aCB0aGVcbiAgV2ViUlRDIHNwZWMgeW91IHdpbGwgYmUgYWJsZSB0byB1c2UgaXQgd2l0aCByYXcgYFJUQ1BlZXJDb25uZWN0aW9uYFxuICBjb25zdHJ1Y3RvcnMgYW5kIG90aGVyIFdlYlJUQyBsaWJyYXJpZXMuXG5cbiAgIyMgSGV5LCBkb24ndCB1c2UgbXkgU1RVTi9UVVJOIHNlcnZlciFcblxuICBJZiBmb3Igc29tZSByZWFzb24geW91ciBmcmVlIFNUVU4gb3IgVFVSTiBzZXJ2ZXIgZW5kcyB1cCBpbiB0aGVcbiAgbGlzdCBvZiBzZXJ2ZXJzIChbc3R1bl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3N0dW4uanNvbikgb3JcbiAgW3R1cm5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci90dXJuLmpzb24pKVxuICB0aGF0IGlzIHVzZWQgaW4gdGhpcyBtb2R1bGUsIHlvdSBjYW4gZmVlbFxuICBmcmVlIHRvIG9wZW4gYW4gaXNzdWUgb24gdGhpcyByZXBvc2l0b3J5IGFuZCB0aG9zZSBzZXJ2ZXJzIHdpbGwgYmUgcmVtb3ZlZFxuICB3aXRoaW4gMjQgaG91cnMgKG9yIHNvb25lcikuICBUaGlzIGlzIHRoZSBxdWlja2VzdCBhbmQgcHJvYmFibHkgdGhlIG1vc3RcbiAgcG9saXRlIHdheSB0byBoYXZlIHNvbWV0aGluZyByZW1vdmVkIChhbmQgcHJvdmlkZXMgdXMgc29tZSB2aXNpYmlsaXR5XG4gIGlmIHNvbWVvbmUgb3BlbnMgYSBwdWxsIHJlcXVlc3QgcmVxdWVzdGluZyB0aGF0IGEgc2VydmVyIGlzIGFkZGVkKS5cblxuICAjIyBQbGVhc2UgYWRkIG15IHNlcnZlciFcblxuICBJZiB5b3UgaGF2ZSBhIHNlcnZlciB0aGF0IHlvdSB3aXNoIHRvIGFkZCB0byB0aGUgbGlzdCwgdGhhdCdzIGF3ZXNvbWUhIEknbVxuICBzdXJlIEkgc3BlYWsgb24gYmVoYWxmIG9mIGEgd2hvbGUgcGlsZSBvZiBXZWJSVEMgZGV2ZWxvcGVycyB3aG8gc2F5IHRoYW5rcy5cbiAgVG8gZ2V0IGl0IGludG8gdGhlIGxpc3QsIGZlZWwgZnJlZSB0byBlaXRoZXIgb3BlbiBhIHB1bGwgcmVxdWVzdCBvciBpZiB5b3VcbiAgZmluZCB0aGF0IHByb2Nlc3MgYSBiaXQgZGF1bnRpbmcgdGhlbiBqdXN0IGNyZWF0ZSBhbiBpc3N1ZSByZXF1ZXN0aW5nXG4gIHRoZSBhZGRpdGlvbiBvZiB0aGUgc2VydmVyIChtYWtlIHN1cmUgeW91IHByb3ZpZGUgYWxsIHRoZSBkZXRhaWxzLCBhbmQgaWZcbiAgeW91IGhhdmUgYSBUZXJtcyBvZiBTZXJ2aWNlIHRoZW4gaW5jbHVkaW5nIHRoYXQgaW4gdGhlIFBSL2lzc3VlIHdvdWxkIGJlXG4gIGF3ZXNvbWUpLlxuXG4gICMjIEkga25vdyBvZiBhIGZyZWUgc2VydmVyLCBjYW4gSSBhZGQgaXQ/XG5cbiAgU3VyZSwgaWYgeW91IGRvIHlvdXIgaG9tZXdvcmsgYW5kIG1ha2Ugc3VyZSBpdCBpcyBvayB0byB1c2UgKEknbSBjdXJyZW50bHlcbiAgaW4gdGhlIHByb2Nlc3Mgb2YgcmV2aWV3aW5nIHRoZSB0ZXJtcyBvZiB0aG9zZSBTVFVOIHNlcnZlcnMgaW5jbHVkZWQgZnJvbVxuICB0aGUgb3JpZ2luYWwgbGlzdCkuICBJZiBpdCdzIG9rIHRvIGdvLCB0aGVuIHBsZWFzZSBzZWUgdGhlIHByZXZpb3VzIGVudHJ5XG4gIGZvciBob3cgdG8gYWRkIGl0LlxuXG4gICMjIEN1cnJlbnQgTGlzdCBvZiBTZXJ2ZXJzXG5cbiAgKiBjdXJyZW50IGFzIGF0IHRoZSB0aW1lIG9mIGxhc3QgYFJFQURNRS5tZGAgZmlsZSBnZW5lcmF0aW9uXG5cbiAgIyMjIFNUVU5cblxuICA8PDwgc3R1bi5qc29uXG5cbiAgIyMjIFRVUk5cblxuICA8PDwgdHVybi5qc29uXG5cbioqL1xuXG52YXIgZnJlZWljZSA9IGZ1bmN0aW9uKG9wdHMpIHtcbiAgLy8gaWYgYSBsaXN0IG9mIHNlcnZlcnMgaGFzIGJlZW4gcHJvdmlkZWQsIHRoZW4gdXNlIGl0IGluc3RlYWQgb2YgZGVmYXVsdHNcbiAgdmFyIHNlcnZlcnMgPSB7XG4gICAgc3R1bjogKG9wdHMgfHwge30pLnN0dW4gfHwgcmVxdWlyZSgnLi9zdHVuLmpzb24nKSxcbiAgICB0dXJuOiAob3B0cyB8fCB7fSkudHVybiB8fCByZXF1aXJlKCcuL3R1cm4uanNvbicpXG4gIH07XG5cbiAgdmFyIHN0dW5Db3VudCA9IChvcHRzIHx8IHt9KS5zdHVuQ291bnQgfHwgMjtcbiAgdmFyIHR1cm5Db3VudCA9IChvcHRzIHx8IHt9KS50dXJuQ291bnQgfHwgMDtcbiAgdmFyIHNlbGVjdGVkO1xuXG4gIGZ1bmN0aW9uIGdldFNlcnZlcnModHlwZSwgY291bnQpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIGlucHV0ID0gW10uY29uY2F0KHNlcnZlcnNbdHlwZV0pO1xuICAgIHZhciBpZHg7XG5cbiAgICB3aGlsZSAoaW5wdXQubGVuZ3RoICYmIG91dC5sZW5ndGggPCBjb3VudCkge1xuICAgICAgaWR4ID0gKE1hdGgucmFuZG9tKCkgKiBpbnB1dC5sZW5ndGgpIHwgMDtcbiAgICAgIG91dCA9IG91dC5jb25jYXQoaW5wdXQuc3BsaWNlKGlkeCwgMSkpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQubWFwKGZ1bmN0aW9uKHVybCkge1xuICAgICAgICAvL0lmIGl0J3MgYSBub3QgYSBzdHJpbmcsIGRvbid0IHRyeSB0byBcIm5vcm1hbGljZVwiIGl0IG90aGVyd2lzZSB1c2luZyB0eXBlOnVybCB3aWxsIHNjcmV3IGl0IHVwXG4gICAgICAgIGlmICgodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpICYmICghICh1cmwgaW5zdGFuY2VvZiBTdHJpbmcpKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVybDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBub3JtYWxpY2UodHlwZSArICc6JyArIHVybCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIGFkZCBzdHVuIHNlcnZlcnNcbiAgc2VsZWN0ZWQgPSBbXS5jb25jYXQoZ2V0U2VydmVycygnc3R1bicsIHN0dW5Db3VudCkpO1xuXG4gIGlmICh0dXJuQ291bnQpIHtcbiAgICBzZWxlY3RlZCA9IHNlbGVjdGVkLmNvbmNhdChnZXRTZXJ2ZXJzKCd0dXJuJywgdHVybkNvdW50KSk7XG4gIH1cblxuICByZXR1cm4gc2VsZWN0ZWQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZyZWVpY2U7IiwibW9kdWxlLmV4cG9ydHM9W1xuICBcInN0dW4ubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjEubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjIubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjMubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjQubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bi5la2lnYS5uZXRcIixcbiAgXCJzdHVuLmlkZWFzaXAuY29tXCIsXG4gIFwic3R1bi5zY2hsdW5kLmRlXCIsXG4gIFwic3R1bi5zdHVucHJvdG9jb2wub3JnOjM0NzhcIixcbiAgXCJzdHVuLnZvaXBhcm91bmQuY29tXCIsXG4gIFwic3R1bi52b2lwYnVzdGVyLmNvbVwiLFxuICBcInN0dW4udm9pcHN0dW50LmNvbVwiLFxuICBcInN0dW4udm94Z3JhdGlhLm9yZ1wiXG5dXG4iLCJtb2R1bGUuZXhwb3J0cz1bXVxuIiwidmFyIFdpbGRFbWl0dGVyID0gcmVxdWlyZSgnd2lsZGVtaXR0ZXInKTtcblxuZnVuY3Rpb24gZ2V0TWF4Vm9sdW1lIChhbmFseXNlciwgZmZ0Qmlucykge1xuICB2YXIgbWF4Vm9sdW1lID0gLUluZmluaXR5O1xuICBhbmFseXNlci5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoZmZ0Qmlucyk7XG5cbiAgZm9yKHZhciBpPTQsIGlpPWZmdEJpbnMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgIGlmIChmZnRCaW5zW2ldID4gbWF4Vm9sdW1lICYmIGZmdEJpbnNbaV0gPCAwKSB7XG4gICAgICBtYXhWb2x1bWUgPSBmZnRCaW5zW2ldO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gbWF4Vm9sdW1lO1xufVxuXG5cbnZhciBhdWRpb0NvbnRleHRUeXBlO1xuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gIGF1ZGlvQ29udGV4dFR5cGUgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG59XG4vLyB1c2UgYSBzaW5nbGUgYXVkaW8gY29udGV4dCBkdWUgdG8gaGFyZHdhcmUgbGltaXRzXG52YXIgYXVkaW9Db250ZXh0ID0gbnVsbDtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc3RyZWFtLCBvcHRpb25zKSB7XG4gIHZhciBoYXJrZXIgPSBuZXcgV2lsZEVtaXR0ZXIoKTtcblxuICAvLyBtYWtlIGl0IG5vdCBicmVhayBpbiBub24tc3VwcG9ydGVkIGJyb3dzZXJzXG4gIGlmICghYXVkaW9Db250ZXh0VHlwZSkgcmV0dXJuIGhhcmtlcjtcblxuICAvL0NvbmZpZ1xuICB2YXIgb3B0aW9ucyA9IG9wdGlvbnMgfHwge30sXG4gICAgICBzbW9vdGhpbmcgPSAob3B0aW9ucy5zbW9vdGhpbmcgfHwgMC4xKSxcbiAgICAgIGludGVydmFsID0gKG9wdGlvbnMuaW50ZXJ2YWwgfHwgNTApLFxuICAgICAgdGhyZXNob2xkID0gb3B0aW9ucy50aHJlc2hvbGQsXG4gICAgICBwbGF5ID0gb3B0aW9ucy5wbGF5LFxuICAgICAgaGlzdG9yeSA9IG9wdGlvbnMuaGlzdG9yeSB8fCAxMCxcbiAgICAgIHJ1bm5pbmcgPSB0cnVlO1xuXG4gIC8vIEVuc3VyZSB0aGF0IGp1c3QgYSBzaW5nbGUgQXVkaW9Db250ZXh0IGlzIGludGVybmFsbHkgY3JlYXRlZFxuICBhdWRpb0NvbnRleHQgPSBvcHRpb25zLmF1ZGlvQ29udGV4dCB8fCBhdWRpb0NvbnRleHQgfHwgbmV3IGF1ZGlvQ29udGV4dFR5cGUoKTtcblxuICB2YXIgc291cmNlTm9kZSwgZmZ0QmlucywgYW5hbHlzZXI7XG5cbiAgYW5hbHlzZXIgPSBhdWRpb0NvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgYW5hbHlzZXIuZmZ0U2l6ZSA9IDUxMjtcbiAgYW5hbHlzZXIuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gc21vb3RoaW5nO1xuICBmZnRCaW5zID0gbmV3IEZsb2F0MzJBcnJheShhbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudCk7XG5cbiAgaWYgKHN0cmVhbS5qcXVlcnkpIHN0cmVhbSA9IHN0cmVhbVswXTtcbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxBdWRpb0VsZW1lbnQgfHwgc3RyZWFtIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudCkge1xuICAgIC8vQXVkaW8gVGFnXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2Uoc3RyZWFtKTtcbiAgICBpZiAodHlwZW9mIHBsYXkgPT09ICd1bmRlZmluZWQnKSBwbGF5ID0gdHJ1ZTtcbiAgICB0aHJlc2hvbGQgPSB0aHJlc2hvbGQgfHwgLTUwO1xuICB9IGVsc2Uge1xuICAgIC8vV2ViUlRDIFN0cmVhbVxuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICB0aHJlc2hvbGQgPSB0aHJlc2hvbGQgfHwgLTUwO1xuICB9XG5cbiAgc291cmNlTm9kZS5jb25uZWN0KGFuYWx5c2VyKTtcbiAgaWYgKHBsYXkpIGFuYWx5c2VyLmNvbm5lY3QoYXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcblxuICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcblxuICBoYXJrZXIuc3VzcGVuZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3VzcGVuZCgpO1xuICB9XG4gIGhhcmtlci5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnJlc3VtZSgpO1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShoYXJrZXIsICdzdGF0ZScsIHsgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN0YXRlO1xuICB9fSk7XG4gIGF1ZGlvQ29udGV4dC5vbnN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG4gICAgaGFya2VyLmVtaXQoJ3N0YXRlX2NoYW5nZScsIGF1ZGlvQ29udGV4dC5zdGF0ZSk7XG4gIH1cblxuICBoYXJrZXIuc2V0VGhyZXNob2xkID0gZnVuY3Rpb24odCkge1xuICAgIHRocmVzaG9sZCA9IHQ7XG4gIH07XG5cbiAgaGFya2VyLnNldEludGVydmFsID0gZnVuY3Rpb24oaSkge1xuICAgIGludGVydmFsID0gaTtcbiAgfTtcblxuICBoYXJrZXIuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgIHJ1bm5pbmcgPSBmYWxzZTtcbiAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIC0xMDAsIHRocmVzaG9sZCk7XG4gICAgaWYgKGhhcmtlci5zcGVha2luZykge1xuICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgIH1cbiAgICBhbmFseXNlci5kaXNjb25uZWN0KCk7XG4gICAgc291cmNlTm9kZS5kaXNjb25uZWN0KCk7XG4gIH07XG4gIGhhcmtlci5zcGVha2luZ0hpc3RvcnkgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBoaXN0b3J5OyBpKyspIHtcbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3RvcnkucHVzaCgwKTtcbiAgfVxuXG4gIC8vIFBvbGwgdGhlIGFuYWx5c2VyIG5vZGUgdG8gZGV0ZXJtaW5lIGlmIHNwZWFraW5nXG4gIC8vIGFuZCBlbWl0IGV2ZW50cyBpZiBjaGFuZ2VkXG4gIHZhciBsb29wZXIgPSBmdW5jdGlvbigpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXG4gICAgICAvL2NoZWNrIGlmIHN0b3AgaGFzIGJlZW4gY2FsbGVkXG4gICAgICBpZighcnVubmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBjdXJyZW50Vm9sdW1lID0gZ2V0TWF4Vm9sdW1lKGFuYWx5c2VyLCBmZnRCaW5zKTtcblxuICAgICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCBjdXJyZW50Vm9sdW1lLCB0aHJlc2hvbGQpO1xuXG4gICAgICB2YXIgaGlzdG9yeSA9IDA7XG4gICAgICBpZiAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCAmJiAhaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIC8vIHRyaWdnZXIgcXVpY2tseSwgc2hvcnQgaGlzdG9yeVxuICAgICAgICBmb3IgKHZhciBpID0gaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGggLSAzOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA+PSAyKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gdHJ1ZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Vm9sdW1lIDwgdGhyZXNob2xkICYmIGhhcmtlci5zcGVha2luZykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPT0gMCkge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3Rvcnkuc2hpZnQoKTtcbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3RvcnkucHVzaCgwICsgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQpKTtcblxuICAgICAgbG9vcGVyKCk7XG4gICAgfSwgaW50ZXJ2YWwpO1xuICB9O1xuICBsb29wZXIoKTtcblxuICByZXR1cm4gaGFya2VyO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIiwiLyogXHJcbiAqIEpTTkxvZyAyLjMwLjBcclxuICogT3BlbiBzb3VyY2UgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxyXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE3IE1hdHRpanMgUGVyZGVjayBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKi9cclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuZnVuY3Rpb24gSkwobG9nZ2VyTmFtZSkge1xyXG4gICAgLy8gSWYgbmFtZSBpcyBlbXB0eSwgcmV0dXJuIHRoZSByb290IGxvZ2dlclxyXG4gICAgaWYgKCFsb2dnZXJOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIEpMLl9fO1xyXG4gICAgfVxyXG4gICAgLy8gSW1wbGVtZW50cyBBcnJheS5yZWR1Y2UuIEpTTkxvZyBzdXBwb3J0cyBJRTgrIGFuZCByZWR1Y2UgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGF0IGJyb3dzZXIuXHJcbiAgICAvLyBTYW1lIGludGVyZmFjZSBhcyB0aGUgc3RhbmRhcmQgcmVkdWNlLCBleGNlcHQgdGhhdCBcclxuICAgIGlmICghQXJyYXkucHJvdG90eXBlLnJlZHVjZSkge1xyXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGluaXRpYWxWYWx1ZSkge1xyXG4gICAgICAgICAgICB2YXIgcHJldmlvdXNWYWx1ZSA9IGluaXRpYWxWYWx1ZTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbHVlID0gY2FsbGJhY2socHJldmlvdXNWYWx1ZSwgdGhpc1tpXSwgaSwgdGhpcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHByZXZpb3VzVmFsdWU7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHZhciBhY2N1bXVsYXRlZExvZ2dlck5hbWUgPSAnJztcclxuICAgIHZhciBsb2dnZXIgPSAoJy4nICsgbG9nZ2VyTmFtZSkuc3BsaXQoJy4nKS5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cnIsIGlkeCwgYXJyKSB7XHJcbiAgICAgICAgLy8gaWYgbG9nZ2VybmFtZSBpcyBhLmIuYywgdGhhbiBjdXJyZW50TG9nZ2VyIHdpbGwgYmUgc2V0IHRvIHRoZSBsb2dnZXJzXHJcbiAgICAgICAgLy8gcm9vdCAgIChwcmV2OiBKTCwgY3VycjogJycpXHJcbiAgICAgICAgLy8gYSAgICAgIChwcmV2OiBKTC5fXywgY3VycjogJ2EnKVxyXG4gICAgICAgIC8vIGEuYiAgICAocHJldjogSkwuX18uX19hLCBjdXJyOiAnYicpXHJcbiAgICAgICAgLy8gYS5iLmMgIChwcmV2OiBKTC5fXy5fX2EuX19hLmIsIGN1cnI6ICdjJylcclxuICAgICAgICAvLyBOb3RlIHRoYXQgd2hlbiBhIG5ldyBsb2dnZXIgbmFtZSBpcyBlbmNvdW50ZXJlZCAoc3VjaCBhcyAnYS5iLmMnKSxcclxuICAgICAgICAvLyBhIG5ldyBsb2dnZXIgb2JqZWN0IGlzIGNyZWF0ZWQgYW5kIGFkZGVkIGFzIGEgcHJvcGVydHkgdG8gdGhlIHBhcmVudCAoJ2EuYicpLlxyXG4gICAgICAgIC8vIFRoZSByb290IGxvZ2dlciBpcyBhZGRlZCBhcyBhIHByb3BlcnR5IG9mIHRoZSBKTCBvYmplY3QgaXRzZWxmLlxyXG4gICAgICAgIC8vIEl0IGlzIGVzc2VudGlhbCB0aGF0IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSBjb250YWluaW5nIHRoZSBjaGlsZCBsb2dnZXJcclxuICAgICAgICAvLyBjb250YWlucyB0aGUgZnVsbCAncGF0aCcgbmFtZSBvZiB0aGUgY2hpbGQgbG9nZ2VyICgnYS5iLmMnKSBpbnN0ZWFkIG9mXHJcbiAgICAgICAgLy8ganVzdCB0aGUgYml0IGFmdGVyIHRoZSBsYXN0IHBlcmlvZCAoJ2MnKS5cclxuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlIHBhcmVudCBpbmhlcml0cyBwcm9wZXJ0aWVzIGZyb20gaXRzIGFuY2VzdG9ycy5cclxuICAgICAgICAvLyBTbyBpZiB0aGUgcm9vdCBoYXMgYSBjaGlsZCBsb2dnZXIgJ2MnIChzdG9yZWQgaW4gYSBwcm9wZXJ0eSAnYycgb2YgdGhlIHJvb3QgbG9nZ2VyKSxcclxuICAgICAgICAvLyB0aGVuIGxvZ2dlciAnYS5iJyBoYXMgdGhhdCBzYW1lIHByb3BlcnR5ICdjJyB0aHJvdWdoIGluaGVyaXRhbmNlLlxyXG4gICAgICAgIC8vIFRoZSBuYW1lcyBvZiB0aGUgbG9nZ2VyIHByb3BlcnRpZXMgc3RhcnQgd2l0aCBfXywgc28gdGhlIHJvb3QgbG9nZ2VyIFxyXG4gICAgICAgIC8vICh3aGljaCBoYXMgbmFtZSAnJyksIGhhcyBhIG5pY2UgcHJvcGVydHkgbmFtZSAnX18nLiAgICAgICAgICAgICAgXHJcbiAgICAgICAgLy8gYWNjdW11bGF0ZWRMb2dnZXJOYW1lIGV2YWx1YXRlcyBmYWxzZSAoJycgaXMgZmFsc3kpIGluIGZpcnN0IGl0ZXJhdGlvbiB3aGVuIHByZXYgaXMgdGhlIHJvb3QgbG9nZ2VyLlxyXG4gICAgICAgIC8vIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSB3aWxsIGJlIHRoZSBsb2dnZXIgbmFtZSBjb3JyZXNwb25kaW5nIHdpdGggdGhlIGxvZ2dlciBpbiBjdXJyZW50TG9nZ2VyLlxyXG4gICAgICAgIC8vIEtlZXAgaW4gbWluZCB0aGF0IHRoZSBjdXJyZW50TG9nZ2VyIG1heSBub3QgYmUgZGVmaW5lZCB5ZXQsIHNvIGNhbid0IGdldCB0aGUgbmFtZSBmcm9tXHJcbiAgICAgICAgLy8gdGhlIGN1cnJlbnRMb2dnZXIgb2JqZWN0IGl0c2VsZi4gXHJcbiAgICAgICAgaWYgKGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSkge1xyXG4gICAgICAgICAgICBhY2N1bXVsYXRlZExvZ2dlck5hbWUgKz0gJy4nICsgY3VycjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSA9IGN1cnI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjdXJyZW50TG9nZ2VyID0gcHJldlsnX18nICsgYWNjdW11bGF0ZWRMb2dnZXJOYW1lXTtcclxuICAgICAgICAvLyBJZiB0aGUgY3VycmVudExvZ2dlciAob3IgdGhlIGFjdHVhbCBsb2dnZXIgYmVpbmcgc291Z2h0KSBkb2VzIG5vdCB5ZXQgZXhpc3QsIFxyXG4gICAgICAgIC8vIGNyZWF0ZSBpdCBub3cuXHJcbiAgICAgICAgaWYgKGN1cnJlbnRMb2dnZXIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAvLyBTZXQgdGhlIHByb3RvdHlwZSBvZiB0aGUgTG9nZ2VyIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIHRoZSBwYXJlbnQgb2YgdGhlIGxvZ2dlclxyXG4gICAgICAgICAgICAvLyB0byBiZSBjcmVhdGVkLiBUaGlzIHdheSwgX19wcm90byBvZiB0aGUgbmV3IGxvZ2dlciBvYmplY3Qgd2lsbCBwb2ludCBhdCB0aGUgcGFyZW50LlxyXG4gICAgICAgICAgICAvLyBXaGVuIGxvZ2dlci5sZXZlbCBpcyBldmFsdWF0ZWQgYW5kIGlzIG5vdCBwcmVzZW50LCB0aGUgSmF2YVNjcmlwdCBydW50aW1lIHdpbGwgXHJcbiAgICAgICAgICAgIC8vIHdhbGsgZG93biB0aGUgcHJvdG90eXBlIGNoYWluIHRvIGZpbmQgdGhlIGZpcnN0IGFuY2VzdG9yIHdpdGggYSBsZXZlbCBwcm9wZXJ0eS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHByZXYgYXQgdGhpcyBwb2ludCByZWZlcnMgdG8gdGhlIHBhcmVudCBsb2dnZXIuXHJcbiAgICAgICAgICAgIEpMLkxvZ2dlci5wcm90b3R5cGUgPSBwcmV2O1xyXG4gICAgICAgICAgICBjdXJyZW50TG9nZ2VyID0gbmV3IEpMLkxvZ2dlcihhY2N1bXVsYXRlZExvZ2dlck5hbWUpO1xyXG4gICAgICAgICAgICBwcmV2WydfXycgKyBhY2N1bXVsYXRlZExvZ2dlck5hbWVdID0gY3VycmVudExvZ2dlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRMb2dnZXI7XHJcbiAgICB9LCBKTC5fXyk7XHJcbiAgICByZXR1cm4gbG9nZ2VyO1xyXG59XHJcbihmdW5jdGlvbiAoSkwpIHtcclxuICAgIC8vIEluaXRpYWxpc2UgcmVxdWVzdElkIHRvIGVtcHR5IHN0cmluZy4gSWYgeW91IGRvbid0IGRvIHRoaXMgYW5kIHRoZSB1c2VyXHJcbiAgICAvLyBkb2VzIG5vdCBzZXQgaXQgdmlhIHNldE9wdGlvbnMsIHRoZW4gdGhlIEpTTkxvZy1SZXF1ZXN0SWQgaGVhZGVyIHdpbGxcclxuICAgIC8vIGhhdmUgdmFsdWUgXCJ1bmRlZmluZWRcIiwgd2hpY2ggZG9lc24ndCBsb29rIGdvb2QgaW4gYSBsb2cuXHJcbiAgICAvL1xyXG4gICAgLy8gTm90ZSB0aGF0IHlvdSBhbHdheXMgd2FudCB0byBzZW5kIGEgcmVxdWVzdElkIGFzIHBhcnQgb2YgbG9nIHJlcXVlc3RzLFxyXG4gICAgLy8gb3RoZXJ3aXNlIHRoZSBzZXJ2ZXIgc2lkZSBjb21wb25lbnQgZG9lc24ndCBrbm93IHRoaXMgaXMgYSBsb2cgcmVxdWVzdFxyXG4gICAgLy8gYW5kIG1heSBjcmVhdGUgYSBuZXcgcmVxdWVzdCBpZCBmb3IgdGhlIGxvZyByZXF1ZXN0LCBjYXVzaW5nIGNvbmZ1c2lvblxyXG4gICAgLy8gaW4gdGhlIGxvZy5cclxuICAgIEpMLnJlcXVlc3RJZCA9ICcnO1xyXG4gICAgLy8gTnVtYmVyIHVuaXF1ZWx5IGlkZW50aWZ5aW5nIGV2ZXJ5IGxvZyBlbnRyeSB3aXRoaW4gdGhlIHJlcXVlc3QuXHJcbiAgICBKTC5lbnRyeUlkID0gMDtcclxuICAgIC8vIEFsbG93IHByb3BlcnR5IGluamVjdGlvbiBvZiB0aGVzZSBjbGFzc2VzLCB0byBlbmFibGUgdW5pdCB0ZXN0aW5nXHJcbiAgICBKTC5fY3JlYXRlWE1MSHR0cFJlcXVlc3QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTsgfTtcclxuICAgIEpMLl9nZXRUaW1lID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKG5ldyBEYXRlKS5nZXRUaW1lKCk7IH07XHJcbiAgICBKTC5fY29uc29sZSA9IGNvbnNvbGU7XHJcbiAgICAvLyAtLS0tLSBwcml2YXRlIHZhcmlhYmxlc1xyXG4gICAgSkwuX2FwcGVuZGVyTmFtZXMgPSBbXTtcclxuICAgIC8qKlxyXG4gICAgQ29waWVzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGZyb20gb25lIG9iamVjdCB0byB0aGUgb3RoZXIuXHJcbiAgICBUaGlzIGlzIHVzZWQgdG8gY29weSBwcm9wZXJ0eSB2YWx1ZXMgYXMgcGFydCBvZiBzZXRPcHRpb24gZm9yIGxvZ2dlcnMgYW5kIGFwcGVuZGVycy5cclxuXHJcbiAgICBCZWNhdXNlIGxvZ2dlcnMgaW5oZXJpdCBwcm9wZXJ0eSB2YWx1ZXMgZnJvbSB0aGVpciBwYXJlbnRzLCBpdCBpcyBpbXBvcnRhbnQgbmV2ZXIgdG9cclxuICAgIGNyZWF0ZSBhIHByb3BlcnR5IG9uIGEgbG9nZ2VyIGlmIHRoZSBpbnRlbnQgaXMgdG8gaW5oZXJpdCBmcm9tIHRoZSBwYXJlbnQuXHJcblxyXG4gICAgQ29weWluZyBydWxlczpcclxuICAgIDEpIGlmIHRoZSBmcm9tIHByb3BlcnR5IGlzIHVuZGVmaW5lZCAoZm9yIGV4YW1wbGUsIG5vdCBtZW50aW9uZWQgaW4gYSBKU09OIG9iamVjdCksIHRoZVxyXG4gICAgICAgdG8gcHJvcGVydHkgaXMgbm90IGFmZmVjdGVkIGF0IGFsbC5cclxuICAgIDIpIGlmIHRoZSBmcm9tIHByb3BlcnR5IGlzIG51bGwsIHRoZSB0byBwcm9wZXJ0eSBpcyBkZWxldGVkIChzbyB0aGUgbG9nZ2VyIHdpbGwgaW5oZXJpdCBmcm9tXHJcbiAgICAgICBpdHMgcGFyZW50KS5cclxuICAgIDMpIE90aGVyd2lzZSwgdGhlIGZyb20gcHJvcGVydHkgaXMgY29waWVkIHRvIHRoZSB0byBwcm9wZXJ0eS5cclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBjb3B5UHJvcGVydHkocHJvcGVydHlOYW1lLCBmcm9tLCB0bykge1xyXG4gICAgICAgIGlmIChmcm9tW3Byb3BlcnR5TmFtZV0gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChmcm9tW3Byb3BlcnR5TmFtZV0gPT09IG51bGwpIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRvW3Byb3BlcnR5TmFtZV07XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdG9bcHJvcGVydHlOYW1lXSA9IGZyb21bcHJvcGVydHlOYW1lXTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgUmV0dXJucyB0cnVlIGlmIGEgbG9nIHNob3VsZCBnbyBhaGVhZC5cclxuICAgIERvZXMgbm90IGNoZWNrIGxldmVsLlxyXG5cclxuICAgIEBwYXJhbSBmaWx0ZXJzXHJcbiAgICAgICAgRmlsdGVycyB0aGF0IGRldGVybWluZSB3aGV0aGVyIGEgbG9nIGNhbiBnbyBhaGVhZC5cclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBhbGxvdyhmaWx0ZXJzKSB7XHJcbiAgICAgICAgLy8gSWYgZW5hYmxlZCBpcyBub3QgbnVsbCBvciB1bmRlZmluZWQsIHRoZW4gaWYgaXQgaXMgZmFsc2UsIHRoZW4gcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgLy8gTm90ZSB0aGF0IHVuZGVmaW5lZD09bnVsbCAoISlcclxuICAgICAgICBpZiAoIShKTC5lbmFibGVkID09IG51bGwpKSB7XHJcbiAgICAgICAgICAgIGlmICghSkwuZW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIElmIHRoZSByZWdleCBjb250YWlucyBhIGJ1ZywgdGhhdCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi5cclxuICAgICAgICAvLyBJZ25vcmUgdGhpcywgYW5kIHBhc3MgdGhlIGxvZyBpdGVtIChiZXR0ZXIgdG9vIG11Y2ggdGhhbiB0b28gbGl0dGxlKS5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZmlsdGVycy51c2VyQWdlbnRSZWdleCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuZXcgUmVnRXhwKGZpbHRlcnMudXNlckFnZW50UmVnZXgpLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXJzLmlwUmVnZXggJiYgSkwuY2xpZW50SVApIHtcclxuICAgICAgICAgICAgICAgIGlmICghbmV3IFJlZ0V4cChmaWx0ZXJzLmlwUmVnZXgpLnRlc3QoSkwuY2xpZW50SVApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7IH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgUmV0dXJucyB0cnVlIGlmIGEgbG9nIHNob3VsZCBnbyBhaGVhZCwgYmFzZWQgb24gdGhlIG1lc3NhZ2UuXHJcblxyXG4gICAgQHBhcmFtIGZpbHRlcnNcclxuICAgICAgICBGaWx0ZXJzIHRoYXQgZGV0ZXJtaW5lIHdoZXRoZXIgYSBsb2cgY2FuIGdvIGFoZWFkLlxyXG5cclxuICAgIEBwYXJhbSBtZXNzYWdlXHJcbiAgICAgICAgTWVzc2FnZSB0byBiZSBsb2dnZWQuXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gYWxsb3dNZXNzYWdlKGZpbHRlcnMsIG1lc3NhZ2UpIHtcclxuICAgICAgICAvLyBJZiB0aGUgcmVnZXggY29udGFpbnMgYSBidWcsIHRoYXQgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24uXHJcbiAgICAgICAgLy8gSWdub3JlIHRoaXMsIGFuZCBwYXNzIHRoZSBsb2cgaXRlbSAoYmV0dGVyIHRvbyBtdWNoIHRoYW4gdG9vIGxpdHRsZSkuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGZpbHRlcnMuZGlzYWxsb3cpIHtcclxuICAgICAgICAgICAgICAgIGlmIChuZXcgUmVnRXhwKGZpbHRlcnMuZGlzYWxsb3cpLnRlc3QobWVzc2FnZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgLy8gSWYgbG9nT2JqZWN0IGlzIGEgZnVuY3Rpb24sIHRoZSBmdW5jdGlvbiBpcyBldmFsdWF0ZWQgKHdpdGhvdXQgcGFyYW1ldGVycylcclxuICAgIC8vIGFuZCB0aGUgcmVzdWx0IHJldHVybmVkLlxyXG4gICAgLy8gT3RoZXJ3aXNlLCBsb2dPYmplY3QgaXRzZWxmIGlzIHJldHVybmVkLlxyXG4gICAgZnVuY3Rpb24gc3RyaW5naWZ5TG9nT2JqZWN0RnVuY3Rpb24obG9nT2JqZWN0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBsb2dPYmplY3QgPT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICAgIGlmIChsb2dPYmplY3QgaW5zdGFuY2VvZiBSZWdFeHApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2dPYmplY3QudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2dPYmplY3QoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbG9nT2JqZWN0O1xyXG4gICAgfVxyXG4gICAgdmFyIFN0cmluZ2lmaWVkTG9nT2JqZWN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vICogbXNnIC0gXHJcbiAgICAgICAgLy8gICAgICBpZiB0aGUgbG9nT2JqZWN0IGlzIGEgc2NhbGFyIChhZnRlciBwb3NzaWJsZSBmdW5jdGlvbiBldmFsdWF0aW9uKSwgdGhpcyBpcyBzZXQgdG9cclxuICAgICAgICAvLyAgICAgIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHNjYWxhci4gT3RoZXJ3aXNlIGl0IGlzIGxlZnQgdW5kZWZpbmVkLlxyXG4gICAgICAgIC8vICogbWV0YSAtXHJcbiAgICAgICAgLy8gICAgICBpZiB0aGUgbG9nT2JqZWN0IGlzIGFuIG9iamVjdCAoYWZ0ZXIgcG9zc2libGUgZnVuY3Rpb24gZXZhbHVhdGlvbiksIHRoaXMgaXMgc2V0IHRvXHJcbiAgICAgICAgLy8gICAgICB0aGF0IG9iamVjdC4gT3RoZXJ3aXNlIGl0IGlzIGxlZnQgdW5kZWZpbmVkLlxyXG4gICAgICAgIC8vICogZmluYWxTdHJpbmcgLVxyXG4gICAgICAgIC8vICAgICAgVGhpcyBpcyBzZXQgdG8gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBsb2dPYmplY3QgKGFmdGVyIHBvc3NpYmxlIGZ1bmN0aW9uIGV2YWx1YXRpb24pLFxyXG4gICAgICAgIC8vICAgICAgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIGl0IGlzIGFuIHNjYWxhciBvciBhbiBvYmplY3QuIEFuIG9iamVjdCBpcyBzdHJpbmdpZmllZCB0byBhIEpTT04gc3RyaW5nLlxyXG4gICAgICAgIC8vICAgICAgTm90ZSB0aGF0IHlvdSBjYW4ndCBjYWxsIHRoaXMgZmllbGQgXCJmaW5hbFwiLCBiZWNhdXNlIGFzIHNvbWUgcG9pbnQgdGhpcyB3YXMgYSByZXNlcnZlZFxyXG4gICAgICAgIC8vICAgICAgSmF2YVNjcmlwdCBrZXl3b3JkIGFuZCB1c2luZyBmaW5hbCB0cmlwcyB1cCBzb21lIG1pbmlmaWVycy5cclxuICAgICAgICBmdW5jdGlvbiBTdHJpbmdpZmllZExvZ09iamVjdChtc2csIG1ldGEsIGZpbmFsU3RyaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMubXNnID0gbXNnO1xyXG4gICAgICAgICAgICB0aGlzLm1ldGEgPSBtZXRhO1xyXG4gICAgICAgICAgICB0aGlzLmZpbmFsU3RyaW5nID0gZmluYWxTdHJpbmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBTdHJpbmdpZmllZExvZ09iamVjdDtcclxuICAgIH0oKSk7XHJcbiAgICAvLyBUYWtlcyBhIGxvZ09iamVjdCwgd2hpY2ggY2FuIGJlIFxyXG4gICAgLy8gKiBhIHNjYWxhclxyXG4gICAgLy8gKiBhbiBvYmplY3RcclxuICAgIC8vICogYSBwYXJhbWV0ZXJsZXNzIGZ1bmN0aW9uLCB3aGljaCByZXR1cm5zIHRoZSBzY2FsYXIgb3Igb2JqZWN0IHRvIGxvZy5cclxuICAgIC8vIFJldHVybnMgYSBzdHJpbmdpZmllZExvZ09iamVjdFxyXG4gICAgZnVuY3Rpb24gc3RyaW5naWZ5TG9nT2JqZWN0KGxvZ09iamVjdCkge1xyXG4gICAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIHdvcmtzIGlmIGxvZ09iamVjdCBpcyBudWxsLlxyXG4gICAgICAgIC8vIHR5cGVvZiBudWxsIGlzIG9iamVjdC5cclxuICAgICAgICAvLyBKU09OLnN0cmluZ2lmeShudWxsKSByZXR1cm5zIFwibnVsbFwiLlxyXG4gICAgICAgIHZhciBhY3R1YWxMb2dPYmplY3QgPSBzdHJpbmdpZnlMb2dPYmplY3RGdW5jdGlvbihsb2dPYmplY3QpO1xyXG4gICAgICAgIHZhciBmaW5hbFN0cmluZztcclxuICAgICAgICAvLyBOb3RlIHRoYXQgdHlwZW9mIGFjdHVhbExvZ09iamVjdCBzaG91bGQgbm90IGJlIFwiZnVuY3Rpb25cIiwgYmVjYXVzZSB0aGF0IGhhcyBcclxuICAgICAgICAvLyBiZWVuIHJlc29sdmVkIHdpdGggc3RyaW5naWZ5TG9nT2JqZWN0RnVuY3Rpb24uXHJcbiAgICAgICAgc3dpdGNoICh0eXBlb2YgYWN0dWFsTG9nT2JqZWN0KSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoYWN0dWFsTG9nT2JqZWN0LCBudWxsLCBhY3R1YWxMb2dPYmplY3QpO1xyXG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XHJcbiAgICAgICAgICAgICAgICBmaW5hbFN0cmluZyA9IGFjdHVhbExvZ09iamVjdC50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChmaW5hbFN0cmluZywgbnVsbCwgZmluYWxTdHJpbmcpO1xyXG4gICAgICAgICAgICBjYXNlIFwiYm9vbGVhblwiOlxyXG4gICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBhY3R1YWxMb2dPYmplY3QudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoZmluYWxTdHJpbmcsIG51bGwsIGZpbmFsU3RyaW5nKTtcclxuICAgICAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChcInVuZGVmaW5lZFwiLCBudWxsLCBcInVuZGVmaW5lZFwiKTtcclxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxyXG4gICAgICAgICAgICAgICAgaWYgKChhY3R1YWxMb2dPYmplY3QgaW5zdGFuY2VvZiBSZWdFeHApIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKGFjdHVhbExvZ09iamVjdCBpbnN0YW5jZW9mIFN0cmluZykgfHxcclxuICAgICAgICAgICAgICAgICAgICAoYWN0dWFsTG9nT2JqZWN0IGluc3RhbmNlb2YgTnVtYmVyKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgIChhY3R1YWxMb2dPYmplY3QgaW5zdGFuY2VvZiBCb29sZWFuKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU3RyaW5nID0gYWN0dWFsTG9nT2JqZWN0LnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChmaW5hbFN0cmluZywgbnVsbCwgZmluYWxTdHJpbmcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBKTC5zZXJpYWxpemUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBKTC5zZXJpYWxpemUuY2FsbCh0aGlzLCBhY3R1YWxMb2dPYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShhY3R1YWxMb2dPYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIG1zZyBmaWVsZCB0byBcIlwiIGluc3RlYWQgb2YgbnVsbC4gU29tZSBXaW5zdG9uIHRyYW5zcG9ydHNcclxuICAgICAgICAgICAgICAgICAgICAvLyBhc3N1bWUgdGhhdCB0aGUgbXNnIGZpZWxkIGlzIG5vdCBudWxsLlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoXCJcIiwgYWN0dWFsTG9nT2JqZWN0LCBmaW5hbFN0cmluZyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ2lmaWVkTG9nT2JqZWN0KFwidW5rbm93blwiLCBudWxsLCBcInVua25vd25cIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gc2V0T3B0aW9ucyhvcHRpb25zKSB7XHJcbiAgICAgICAgY29weVByb3BlcnR5KFwiZW5hYmxlZFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJtYXhNZXNzYWdlc1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJkZWZhdWx0QWpheFVybFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJjbGllbnRJUFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJyZXF1ZXN0SWRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgY29weVByb3BlcnR5KFwiZGVmYXVsdEJlZm9yZVNlbmRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgY29weVByb3BlcnR5KFwic2VyaWFsaXplXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG4gICAgSkwuc2V0T3B0aW9ucyA9IHNldE9wdGlvbnM7XHJcbiAgICBmdW5jdGlvbiBnZXRBbGxMZXZlbCgpIHsgcmV0dXJuIC0yMTQ3NDgzNjQ4OyB9XHJcbiAgICBKTC5nZXRBbGxMZXZlbCA9IGdldEFsbExldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0VHJhY2VMZXZlbCgpIHsgcmV0dXJuIDEwMDA7IH1cclxuICAgIEpMLmdldFRyYWNlTGV2ZWwgPSBnZXRUcmFjZUxldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0RGVidWdMZXZlbCgpIHsgcmV0dXJuIDIwMDA7IH1cclxuICAgIEpMLmdldERlYnVnTGV2ZWwgPSBnZXREZWJ1Z0xldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0SW5mb0xldmVsKCkgeyByZXR1cm4gMzAwMDsgfVxyXG4gICAgSkwuZ2V0SW5mb0xldmVsID0gZ2V0SW5mb0xldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0V2FybkxldmVsKCkgeyByZXR1cm4gNDAwMDsgfVxyXG4gICAgSkwuZ2V0V2FybkxldmVsID0gZ2V0V2FybkxldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0RXJyb3JMZXZlbCgpIHsgcmV0dXJuIDUwMDA7IH1cclxuICAgIEpMLmdldEVycm9yTGV2ZWwgPSBnZXRFcnJvckxldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0RmF0YWxMZXZlbCgpIHsgcmV0dXJuIDYwMDA7IH1cclxuICAgIEpMLmdldEZhdGFsTGV2ZWwgPSBnZXRGYXRhbExldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0T2ZmTGV2ZWwoKSB7IHJldHVybiAyMTQ3NDgzNjQ3OyB9XHJcbiAgICBKTC5nZXRPZmZMZXZlbCA9IGdldE9mZkxldmVsO1xyXG4gICAgZnVuY3Rpb24gbGV2ZWxUb1N0cmluZyhsZXZlbCkge1xyXG4gICAgICAgIGlmIChsZXZlbCA8PSAxMDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcInRyYWNlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsZXZlbCA8PSAyMDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImRlYnVnXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsZXZlbCA8PSAzMDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImluZm9cIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxldmVsIDw9IDQwMDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwid2FyblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobGV2ZWwgPD0gNTAwMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gXCJlcnJvclwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXCJmYXRhbFwiO1xyXG4gICAgfVxyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgRXhjZXB0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIGRhdGEgcmVwbGFjZXMgbWVzc2FnZS4gSXQgdGFrZXMgbm90IGp1c3Qgc3RyaW5ncywgYnV0IGFsc28gb2JqZWN0cyBhbmQgZnVuY3Rpb25zLCBqdXN0IGxpa2UgdGhlIGxvZyBmdW5jdGlvbi5cclxuICAgICAgICAvLyBpbnRlcm5hbGx5LCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlzIHN0b3JlZCBpbiB0aGUgbWVzc2FnZSBwcm9wZXJ0eSAoaW5oZXJpdGVkIGZyb20gRXJyb3IpXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBpbm5lcjogaW5uZXIgZXhjZXB0aW9uLiBDYW4gYmUgbnVsbCBvciB1bmRlZmluZWQuIFxyXG4gICAgICAgIGZ1bmN0aW9uIEV4Y2VwdGlvbihkYXRhLCBpbm5lcikge1xyXG4gICAgICAgICAgICB0aGlzLmlubmVyID0gaW5uZXI7XHJcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IFwiSkwuRXhjZXB0aW9uXCI7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IHN0cmluZ2lmeUxvZ09iamVjdChkYXRhKS5maW5hbFN0cmluZztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIEV4Y2VwdGlvbjtcclxuICAgIH0oKSk7XHJcbiAgICBKTC5FeGNlcHRpb24gPSBFeGNlcHRpb247XHJcbiAgICAvLyBEZXJpdmUgRXhjZXB0aW9uIGZyb20gRXJyb3IgKGEgSG9zdCBvYmplY3QpLCBzbyBicm93c2Vyc1xyXG4gICAgLy8gYXJlIG1vcmUgbGlrZWx5IHRvIHByb2R1Y2UgYSBzdGFjayB0cmFjZSBmb3IgaXQgaW4gdGhlaXIgY29uc29sZS5cclxuICAgIC8vXHJcbiAgICAvLyBOb3RlIHRoYXQgaW5zdGFuY2VvZiBhZ2FpbnN0IGFuIG9iamVjdCBjcmVhdGVkIHdpdGggdGhpcyBjb25zdHJ1Y3RvclxyXG4gICAgLy8gd2lsbCByZXR1cm4gdHJ1ZSBpbiB0aGVzZSBjYXNlczpcclxuICAgIC8vIDxvYmplY3Q+IGluc3RhbmNlb2YgSkwuRXhjZXB0aW9uKTtcclxuICAgIC8vIDxvYmplY3Q+IGluc3RhbmNlb2YgRXJyb3IpO1xyXG4gICAgRXhjZXB0aW9uLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpO1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgTG9nSXRlbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBsOiBsZXZlbFxyXG4gICAgICAgIC8vIG06IG1lc3NhZ2VcclxuICAgICAgICAvLyBuOiBsb2dnZXIgbmFtZVxyXG4gICAgICAgIC8vIHQgKHRpbWVTdGFtcCkgaXMgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSAxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVENcclxuICAgICAgICAvLyB1OiBudW1iZXIgdW5pcXVlbHkgaWRlbnRpZnlpbmcgdGhpcyBlbnRyeSBmb3IgdGhpcyByZXF1ZXN0LlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gS2VlcGluZyB0aGUgcHJvcGVydHkgbmFtZXMgcmVhbGx5IHNob3J0LCBiZWNhdXNlIHRoZXkgd2lsbCBiZSBzZW50IGluIHRoZVxyXG4gICAgICAgIC8vIEpTT04gcGF5bG9hZCB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIGZ1bmN0aW9uIExvZ0l0ZW0obCwgbSwgbiwgdCwgdSkge1xyXG4gICAgICAgICAgICB0aGlzLmwgPSBsO1xyXG4gICAgICAgICAgICB0aGlzLm0gPSBtO1xyXG4gICAgICAgICAgICB0aGlzLm4gPSBuO1xyXG4gICAgICAgICAgICB0aGlzLnQgPSB0O1xyXG4gICAgICAgICAgICB0aGlzLnUgPSB1O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gTG9nSXRlbTtcclxuICAgIH0oKSk7XHJcbiAgICBKTC5Mb2dJdGVtID0gTG9nSXRlbTtcclxuICAgIGZ1bmN0aW9uIG5ld0xvZ0l0ZW0obGV2ZWxOYnIsIG1lc3NhZ2UsIGxvZ2dlck5hbWUpIHtcclxuICAgICAgICBKTC5lbnRyeUlkKys7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBMb2dJdGVtKGxldmVsTmJyLCBtZXNzYWdlLCBsb2dnZXJOYW1lLCBKTC5fZ2V0VGltZSgpLCBKTC5lbnRyeUlkKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGNsZWFyVGltZXIodGltZXIpIHtcclxuICAgICAgICBpZiAodGltZXIuaWQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyLmlkKTtcclxuICAgICAgICAgICAgdGltZXIuaWQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHNldFRpbWVyKHRpbWVyLCB0aW1lb3V0TXMsIGNhbGxiYWNrKSB7XHJcbiAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xyXG4gICAgICAgIGlmICghdGltZXIuaWQpIHtcclxuICAgICAgICAgICAgdGltZXIuaWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIC8vIHVzZSBjYWxsIHRvIGVuc3VyZSB0aGF0IHRoZSB0aGlzIGFzIHVzZWQgaW5zaWRlIHNlbmRCYXRjaCB3aGVuIGl0IHJ1bnMgaXMgdGhlXHJcbiAgICAgICAgICAgICAgICAvLyBzYW1lIHRoaXMgYXQgdGhpcyBwb2ludC5cclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhhdCk7XHJcbiAgICAgICAgICAgIH0sIHRpbWVvdXRNcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdmFyIEFwcGVuZGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIHNlbmRMb2dJdGVtcyB0YWtlcyBhbiBhcnJheSBvZiBsb2cgaXRlbXMuIEl0IHdpbGwgYmUgY2FsbGVkIHdoZW5cclxuICAgICAgICAvLyB0aGUgYXBwZW5kZXIgaGFzIGl0ZW1zIHRvIHByb2Nlc3MgKHN1Y2ggYXMsIHNlbmQgdG8gdGhlIHNlcnZlcikuXHJcbiAgICAgICAgLy8gc2VuZExvZ0l0ZW1zIHdpbGwgY2FsbCBzdWNjZXNzQ2FsbGJhY2sgYWZ0ZXIgdGhlIGl0ZW1zIGhhdmUgYmVlbiBzdWNjZXNzZnVsbHkgc2VudC5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIE5vdGUgdGhhdCBhZnRlciBzZW5kTG9nSXRlbXMgcmV0dXJucywgdGhlIGFwcGVuZGVyIG1heSB0cnVuY2F0ZVxyXG4gICAgICAgIC8vIHRoZSBMb2dJdGVtIGFycmF5LCBzbyB0aGUgZnVuY3Rpb24gaGFzIHRvIGNvcHkgdGhlIGNvbnRlbnQgb2YgdGhlIGFycmF5XHJcbiAgICAgICAgLy8gaW4gc29tZSBmYXNoaW9uIChlZy4gc2VyaWFsaXplKSBiZWZvcmUgcmV0dXJuaW5nLlxyXG4gICAgICAgIGZ1bmN0aW9uIEFwcGVuZGVyKGFwcGVuZGVyTmFtZSwgc2VuZExvZ0l0ZW1zKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kZXJOYW1lID0gYXBwZW5kZXJOYW1lO1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRMb2dJdGVtcyA9IHNlbmRMb2dJdGVtcztcclxuICAgICAgICAgICAgdGhpcy5sZXZlbCA9IEpMLmdldFRyYWNlTGV2ZWwoKTtcclxuICAgICAgICAgICAgLy8gc2V0IHRvIHN1cGVyIGhpZ2ggbGV2ZWwsIHNvIGlmIHVzZXIgaW5jcmVhc2VzIGxldmVsLCBsZXZlbCBpcyB1bmxpa2VseSB0byBnZXQgXHJcbiAgICAgICAgICAgIC8vIGFib3ZlIHNlbmRXaXRoQnVmZmVyTGV2ZWxcclxuICAgICAgICAgICAgdGhpcy5zZW5kV2l0aEJ1ZmZlckxldmVsID0gMjE0NzQ4MzY0NztcclxuICAgICAgICAgICAgdGhpcy5zdG9yZUluQnVmZmVyTGV2ZWwgPSAtMjE0NzQ4MzY0ODtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXJTaXplID0gMDsgLy8gYnVmZmVyaW5nIHN3aXRjaCBvZmYgYnkgZGVmYXVsdFxyXG4gICAgICAgICAgICB0aGlzLmJhdGNoU2l6ZSA9IDE7XHJcbiAgICAgICAgICAgIHRoaXMubWF4QmF0Y2hTaXplID0gMjA7XHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hUaW1lb3V0ID0gMjE0NzQ4MzY0NztcclxuICAgICAgICAgICAgdGhpcy5zZW5kVGltZW91dCA9IDUwMDA7XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIGFsbCBsb2cgaXRlbXMgd2l0aCBsZXZlbHMgaGlnaGVyIHRoYW4gc3RvcmVJbkJ1ZmZlckxldmVsIFxyXG4gICAgICAgICAgICAvLyBidXQgbG93ZXIgdGhhbiBsZXZlbC4gVGhlc2UgaXRlbXMgbWF5IG5ldmVyIGJlIHNlbnQuXHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gW107XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIGFsbCBpdGVtcyB0aGF0IHdlIGRvIHdhbnQgdG8gc2VuZCwgdW50aWwgd2UgaGF2ZSBhIGZ1bGxcclxuICAgICAgICAgICAgLy8gYmF0Y2ggKGFzIGRldGVybWluZWQgYnkgYmF0Y2hTaXplKS5cclxuICAgICAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdO1xyXG4gICAgICAgICAgICAvLyBIb2xkcyB0aGUgaWQgb2YgdGhlIHRpbWVyIGltcGxlbWVudGluZyB0aGUgYmF0Y2ggdGltZW91dC5cclxuICAgICAgICAgICAgLy8gQ2FuIGJlIG51bGwuXHJcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gb2JqZWN0LCBzbyBpdCBjYW4gYmUgcGFzc2VkIHRvIGEgbWV0aG9kIHRoYXQgdXBkYXRlZCB0aGUgdGltZXIgdmFyaWFibGUuXHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hUaW1lb3V0VGltZXIgPSB7IGlkOiBudWxsIH07XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIHRoZSBpZCBvZiB0aGUgdGltZXIgaW1wbGVtZW50aW5nIHRoZSBzZW5kIHRpbWVvdXQuXHJcbiAgICAgICAgICAgIC8vIENhbiBiZSBudWxsLlxyXG4gICAgICAgICAgICB0aGlzLnNlbmRUaW1lb3V0VGltZXIgPSB7IGlkOiBudWxsIH07XHJcbiAgICAgICAgICAgIC8vIE51bWJlciBvZiBsb2cgaXRlbXMgdGhhdCBoYXMgYmVlbiBza2lwcGVkIGR1ZSB0byBiYXRjaCBidWZmZXIgYXQgbWF4IHNpemUsXHJcbiAgICAgICAgICAgIC8vIHNpbmNlIGFwcGVuZGVyIGNyZWF0aW9uIG9yIHNpbmNlIGNyZWF0aW9uIG9mIHRoZSBsYXN0IFwic2tpcHBlZFwiIHdhcm5pbmcgbG9nIGVudHJ5LlxyXG4gICAgICAgICAgICB0aGlzLm5ickxvZ0l0ZW1zU2tpcHBlZCA9IDA7XHJcbiAgICAgICAgICAgIC8vIFdpbGwgYmUgMCBpZiBubyBsb2cgcmVxdWVzdCBpcyBvdXRzdGFuZGluZyBhdCB0aGUgbW9tZW50LlxyXG4gICAgICAgICAgICAvLyBPdGhlcndpc2UgdGhlIG51bWJlciBvZiBsb2cgaXRlbXMgaW4gdGhlIG91dHN0YW5kaW5nIHJlcXVlc3QuXHJcbiAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNCZWluZ1NlbnQgPSAwO1xyXG4gICAgICAgICAgICB2YXIgZW1wdHlOYW1lRXJyb3JNZXNzYWdlID0gXCJUcnlpbmcgdG8gY3JlYXRlIGFuIGFwcGVuZGVyIHdpdGhvdXQgYSBuYW1lIG9yIHdpdGggYW4gZW1wdHkgbmFtZVwiO1xyXG4gICAgICAgICAgICAvLyBUaGlzIGV2YWx1YXRlcyB0byB0cnVlIGlmIGFwcGVuZGVyTmFtZSBpcyBlaXRoZXIgbnVsbCBvciB1bmRlZmluZWQhXHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBjaGVjayBoZXJlIGlmIHRoZSBuYW1lIGlzIFwiXCIsIGJlY2F1c2UgdGhhdCB3b3VsZCBzdG9wIHlvdSBjcmVhdGluZyB0aGUgXHJcbiAgICAgICAgICAgIC8vIGRlZmF1bHQgYXBwZW5kZXIuXHJcbiAgICAgICAgICAgIGlmIChhcHBlbmRlck5hbWUgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlbXB0eU5hbWVFcnJvck1lc3NhZ2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKEpMLl9hcHBlbmRlck5hbWVzLmluZGV4T2YoYXBwZW5kZXJOYW1lKSAhPSAtMSkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdXNlciBwYXNzZWQgaW4gXCJcIiwgdGhhdCB3aWxsIG5vdyBoYXZlIGJlZW4gcGlja2VkIHVwIGFzIGEgZHVwbGljYXRlXHJcbiAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGRlZmF1bHQgYXBwZW5kZXIgYWxzbyB1c2VzIFwiXCIuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWFwcGVuZGVyTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVtcHR5TmFtZUVycm9yTWVzc2FnZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRocm93IFwiTXVsdGlwbGUgYXBwZW5kZXJzIHVzZSB0aGUgc2FtZSBuYW1lIFwiICsgYXBwZW5kZXJOYW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIEpMLl9hcHBlbmRlck5hbWVzLnB1c2goYXBwZW5kZXJOYW1lKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLmFkZExvZ0l0ZW1zVG9CdWZmZXIgPSBmdW5jdGlvbiAobG9nSXRlbXMpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGJhdGNoIGJ1ZmZlciBoYXMgcmVhY2hlZCBpdHMgbWF4aW11bSBsaW1pdCwgXHJcbiAgICAgICAgICAgIC8vIHNraXAgdGhlIGxvZyBpdGVtIGFuZCBpbmNyZWFzZSB0aGUgXCJza2lwcGVkIGl0ZW1zXCIgY291bnRlci5cclxuICAgICAgICAgICAgaWYgKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID49IHRoaXMubWF4QmF0Y2hTaXplKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5ickxvZ0l0ZW1zU2tpcHBlZCArPSBsb2dJdGVtcy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gSWYgbWF4TWVzc2FnZXMgaXMgbm90IG51bGwgb3IgdW5kZWZpbmVkLCB0aGVuIGRlY3JlYXNlIGl0IGJ5IHRoZSBiYXRjaCBzaXplLlxyXG4gICAgICAgICAgICAvLyBUaGlzIGNhbiByZXN1bHQgaW4gYSBuZWdhdGl2ZSBtYXhNZXNzYWdlcy5cclxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHVuZGVmaW5lZD09bnVsbCAoISlcclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHdlIG1heSBiZSBzZW5kaW5nIG1vcmUgbWVzc2FnZXMgdGhhbiB0aGUgbWF4TWVzc2FnZXMgbGltaXQgYWxsb3dzLFxyXG4gICAgICAgICAgICAvLyBpZiB3ZSBzdG9yZWQgdHJhY2UgbWVzc2FnZXMuIFJhdGlvbmFsZSBpcyB0aGUgYnVmZmVyIGZvciB0cmFjZSBtZXNzYWdlcyBpcyBsaW1pdGVkLFxyXG4gICAgICAgICAgICAvLyBhbmQgaWYgd2UgY3V0IG9mZiBhdCBleGFjdGx5IG1heE1lc3NhZ2VzLCB3ZSdkIGFsc28gbG9vc2UgdGhlIGhpZ2ggc2V2ZXJpdHkgbWVzc2FnZVxyXG4gICAgICAgICAgICAvLyB0aGF0IGNhdXNlZCB0aGUgdHJhY2UgbWVzc2FnZXMgdG8gYmUgc2VudCAodW5sZXNzIHdlIGNhdGVyIGZvciB0aGlzIHNwZWNpZmljYWxseSwgd2hpY2hcclxuICAgICAgICAgICAgLy8gaXMgbW9yZSBjb21wbGV4aXR5KS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGFwcGVuZGVycyBzZW5kaW5nIHRoZSBzYW1lIG1lc3NhZ2UsIG1heE1lc3NhZ2Ugd2lsbCBiZSBkZWNyZWFzZWRcclxuICAgICAgICAgICAgLy8gYnkgZWFjaCBhcHBlbmRlciBmb3IgdGhlIHNhbWUgbWVzc2FnZS4gVGhpcyBpczpcclxuICAgICAgICAgICAgLy8gMSkgb25seSBhcHBlbmRlcnMga25vdyB3aGV0aGVyIGEgbWVzc2FnZSB3aWxsIGFjdHVhbGx5IGJlIHNlbnQgKGJhc2VkIG9uIHN0b3JlSW5CdWZmZXJMZXZlbCksXHJcbiAgICAgICAgICAgIC8vICAgIHNvIHRoZSBsb2dnZXJzIGNvdWxkbid0IGRvIHRoaXMgdXBkYXRlO1xyXG4gICAgICAgICAgICAvLyAyKSBpZiB5b3UgaGF2ZSBtdWx0aXBsZSBhcHBlbmRlcnMgaGl0dGluZyB0aGUgc2FtZSBzZXJ2ZXIsIHRoaXMgbWF5IGJlIHdoYXQgeW91IHdhbnQuXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIEluIG1vc3QgY2FzZXMgdGhlcmUgaXMgb25seSAxIGFwcGVuZGVyLCBzbyB0aGlzIHRoZW4gZG9lc24ndCBtYXR0ZXIuXHJcbiAgICAgICAgICAgIGlmICghKEpMLm1heE1lc3NhZ2VzID09IG51bGwpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoSkwubWF4TWVzc2FnZXMgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgSkwubWF4TWVzc2FnZXMgLT0gbG9nSXRlbXMubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hCdWZmZXIgPSB0aGlzLmJhdGNoQnVmZmVyLmNvbmNhdChsb2dJdGVtcyk7XHJcbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIGJ1ZmZlciwgc2V0IHRoZSB0aW1lclxyXG4gICAgICAgICAgICAvLyB0byBlbnN1cmUgaXQgd2lsbCBiZSBzZW50IHdpdGhpbiB0aGUgdGltZW91dCBwZXJpb2QuXHJcbiAgICAgICAgICAgIC8vIElmIGl0IGlzIG5vdCB0aGUgZmlyc3QgaXRlbSwgbGVhdmUgdGhlIHRpbWVyIGFsb25lIHNvIHRvIG5vdCB0byBcclxuICAgICAgICAgICAgLy8gaW5jcmVhc2UgdGhlIHRpbWVvdXQgZm9yIHRoZSBmaXJzdCBpdGVtLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBUbyBkZXRlcm1pbmUgaWYgdGhpcyBpcyB0aGUgZmlyc3QgaXRlbSwgbG9vayBhdCB0aGUgdGltZXIgdmFyaWFibGUuXHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBsb29rIGF0IHRoZSBidWZmZXIgbGVuZ3RoLCBiZWNhdXNlIHdlIGFsc28gcHV0IGl0ZW1zIGluIHRoZSBidWZmZXJcclxuICAgICAgICAgICAgLy8gdmlhIGEgY29uY2F0IChieXBhc3NpbmcgdGhpcyBmdW5jdGlvbikuXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIFRoZSBzZXRUaW1lciBtZXRob2Qgb25seSBzZXRzIHRoZSB0aW1lciBpZiBpdCBpcyBub3QgYWxyZWFkeSBydW5uaW5nLlxyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XHJcbiAgICAgICAgICAgIHNldFRpbWVyKHRoaXMuYmF0Y2hUaW1lb3V0VGltZXIsIHRoaXMuYmF0Y2hUaW1lb3V0LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGF0LnNlbmRCYXRjaC5jYWxsKHRoYXQpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIDtcclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUuYmF0Y2hCdWZmZXJIYXNPdmVyZHVlTWVzc2FnZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2VBZ2VNcyA9IEpMLl9nZXRUaW1lKCkgLSB0aGlzLmJhdGNoQnVmZmVyW2ldLnQ7XHJcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZUFnZU1zID4gdGhpcy5iYXRjaFRpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgbm8gbW9yZSBtZXNzYWdlIHdpbGwgZXZlciBiZSBhZGRlZCB0byB0aGUgYmF0Y2ggYnVmZmVyLFxyXG4gICAgICAgIC8vIGJ1dCB0aGUgYmF0Y2ggYnVmZmVyIGhhcyBtZXNzYWdlcyBub3cgLSBzbyBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCB0byBtYWtlIHVwIGEgYmF0Y2gsXHJcbiAgICAgICAgLy8gYW5kIHRoZXJlIGlzIG5vIGJhdGNoIHRpbWVvdXQsIHRoZW4gdGhleSB3aWxsIG5ldmVyIGJlIHNlbnQuIFRoaXMgaXMgZXNwZWNpYWxseSBpbXBvcnRhbnQgaWYgXHJcbiAgICAgICAgLy8gbWF4TWVzc2FnZXMgd2FzIHJlYWNoZWQgd2hpbGUganNubG9nLmpzIHdhcyByZXRyeWluZyBzZW5kaW5nIG1lc3NhZ2VzIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLmJhdGNoQnVmZmVySGFzU3RyYW5kZWRNZXNzYWdlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gKCEoSkwubWF4TWVzc2FnZXMgPT0gbnVsbCkpICYmIChKTC5tYXhNZXNzYWdlcyA8IDEpICYmICh0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aCA+IDApO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLnNlbmRCYXRjaElmQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICgodGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGggPj0gdGhpcy5iYXRjaFNpemUpIHx8XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJhdGNoQnVmZmVySGFzT3ZlcmR1ZU1lc3NhZ2VzKCkgfHxcclxuICAgICAgICAgICAgICAgIHRoaXMuYmF0Y2hCdWZmZXJIYXNTdHJhbmRlZE1lc3NhZ2UoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kQmF0Y2goKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLm9uU2VuZGluZ0VuZGVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVyKHRoaXMuc2VuZFRpbWVvdXRUaW1lcik7XHJcbiAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNCZWluZ1NlbnQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRCYXRjaElmQ29tcGxldGUoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIEFwcGVuZGVyLnByb3RvdHlwZS5zZXRPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwibGV2ZWxcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImlwUmVnZXhcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcInVzZXJBZ2VudFJlZ2V4XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJkaXNhbGxvd1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwic2VuZFdpdGhCdWZmZXJMZXZlbFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwic3RvcmVJbkJ1ZmZlckxldmVsXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJidWZmZXJTaXplXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJiYXRjaFNpemVcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcIm1heEJhdGNoU2l6ZVwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiYmF0Y2hUaW1lb3V0XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJzZW5kVGltZW91dFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYnVmZmVyU2l6ZSA8IHRoaXMuYnVmZmVyLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5idWZmZXIubGVuZ3RoID0gdGhpcy5idWZmZXJTaXplO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1heEJhdGNoU2l6ZSA8IHRoaXMuYmF0Y2hTaXplKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSkwuRXhjZXB0aW9uKHtcclxuICAgICAgICAgICAgICAgICAgICBcIm1lc3NhZ2VcIjogXCJtYXhCYXRjaFNpemUgY2Fubm90IGJlIHNtYWxsZXIgdGhhbiBiYXRjaFNpemVcIixcclxuICAgICAgICAgICAgICAgICAgICBcIm1heEJhdGNoU2l6ZVwiOiB0aGlzLm1heEJhdGNoU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICBcImJhdGNoU2l6ZVwiOiB0aGlzLmJhdGNoU2l6ZVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICBDYWxsZWQgYnkgYSBsb2dnZXIgdG8gbG9nIGEgbG9nIGl0ZW0uXHJcbiAgICAgICAgSWYgaW4gcmVzcG9uc2UgdG8gdGhpcyBjYWxsIG9uZSBvciBtb3JlIGxvZyBpdGVtcyBuZWVkIHRvIGJlIHByb2Nlc3NlZFxyXG4gICAgICAgIChlZy4sIHNlbnQgdG8gdGhlIHNlcnZlciksIHRoaXMgbWV0aG9kIGNhbGxzIHRoaXMuc2VuZExvZ0l0ZW1zXHJcbiAgICAgICAgd2l0aCBhbiBhcnJheSB3aXRoIGFsbCBpdGVtcyB0byBiZSBwcm9jZXNzZWQuXHJcblxyXG4gICAgICAgIE5vdGUgdGhhdCB0aGUgbmFtZSBhbmQgcGFyYW1ldGVycyBvZiB0aGlzIGZ1bmN0aW9uIG11c3QgbWF0Y2ggdGhvc2Ugb2YgdGhlIGxvZyBmdW5jdGlvbiBvZlxyXG4gICAgICAgIGEgV2luc3RvbiB0cmFuc3BvcnQgb2JqZWN0LCBzbyB0aGF0IHVzZXJzIGNhbiB1c2UgdGhlc2UgdHJhbnNwb3J0cyBhcyBhcHBlbmRlcnMuXHJcbiAgICAgICAgVGhhdCBpcyB3aHkgdGhlcmUgYXJlIG1hbnkgcGFyYW1ldGVycyB0aGF0IGFyZSBub3QgYWN0dWFsbHkgdXNlZCBieSB0aGlzIGZ1bmN0aW9uLlxyXG5cclxuICAgICAgICBsZXZlbCAtIHN0cmluZyB3aXRoIHRoZSBsZXZlbCAoXCJ0cmFjZVwiLCBcImRlYnVnXCIsIGV0Yy4pIE9ubHkgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgbXNnIC0gaHVtYW4gcmVhZGFibGUgbWVzc2FnZS4gVW5kZWZpbmVkIGlmIHRoZSBsb2cgaXRlbSBpcyBhbiBvYmplY3QuIE9ubHkgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgbWV0YSAtIGxvZyBvYmplY3QuIEFsd2F5cyBkZWZpbmVkLCBiZWNhdXNlIGF0IGxlYXN0IGl0IGNvbnRhaW5zIHRoZSBsb2dnZXIgbmFtZS4gT25seSB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBjYWxsYmFjayAtIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGxvZyBpdGVtIGhhcyBiZWVuIGxvZ2dlZC4gT25seSB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBsZXZlbE5iciAtIGxldmVsIGFzIGEgbnVtYmVyLiBOb3QgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgbWVzc2FnZSAtIGxvZyBpdGVtLiBJZiB0aGUgdXNlciBsb2dnZWQgYW4gb2JqZWN0LCB0aGlzIGlzIHRoZSBKU09OIHN0cmluZy4gIE5vdCB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBsb2dnZXJOYW1lOiBuYW1lIG9mIHRoZSBsb2dnZXIuICBOb3QgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgKi9cclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUubG9nID0gZnVuY3Rpb24gKGxldmVsLCBtc2csIG1ldGEsIGNhbGxiYWNrLCBsZXZlbE5iciwgbWVzc2FnZSwgbG9nZ2VyTmFtZSkge1xyXG4gICAgICAgICAgICB2YXIgbG9nSXRlbTtcclxuICAgICAgICAgICAgaWYgKCFhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghYWxsb3dNZXNzYWdlKHRoaXMsIG1lc3NhZ2UpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGxldmVsTmJyIDwgdGhpcy5zdG9yZUluQnVmZmVyTGV2ZWwpIHtcclxuICAgICAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgbG9nIGl0ZW0gY29tcGxldGVseVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxvZ0l0ZW0gPSBuZXdMb2dJdGVtKGxldmVsTmJyLCBtZXNzYWdlLCBsb2dnZXJOYW1lKTtcclxuICAgICAgICAgICAgaWYgKGxldmVsTmJyIDwgdGhpcy5sZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgLy8gU3RvcmUgaW4gdGhlIGhvbGQgYnVmZmVyLiBEbyBub3Qgc2VuZC5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1ZmZlclNpemUgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIucHVzaChsb2dJdGVtKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBleGNlZWRlZCBtYXggYnVmZmVyIHNpemUsIHJlbW92ZSBvbGRlc3QgaXRlbVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggPiB0aGlzLmJ1ZmZlclNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gV2FudCB0byBzZW5kIHRoZSBpdGVtXHJcbiAgICAgICAgICAgIHRoaXMuYWRkTG9nSXRlbXNUb0J1ZmZlcihbbG9nSXRlbV0pO1xyXG4gICAgICAgICAgICBpZiAobGV2ZWxOYnIgPj0gdGhpcy5zZW5kV2l0aEJ1ZmZlckxldmVsKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXYW50IHRvIHNlbmQgdGhlIGNvbnRlbnRzIG9mIHRoZSBidWZmZXIuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gU2VuZCB0aGUgYnVmZmVyIEFGVEVSIHNlbmRpbmcgdGhlIGhpZ2ggcHJpb3JpdHkgaXRlbS5cclxuICAgICAgICAgICAgICAgIC8vIElmIHlvdSB3ZXJlIHRvIHNlbmQgdGhlIGhpZ2ggcHJpb3JpdHkgaXRlbSBhZnRlciB0aGUgYnVmZmVyLFxyXG4gICAgICAgICAgICAgICAgLy8gaWYgd2UncmUgY2xvc2UgdG8gbWF4TWVzc2FnZXMgb3IgbWF4QmF0Y2hTaXplLFxyXG4gICAgICAgICAgICAgICAgLy8gdGhlbiB0aGUgdHJhY2UgbWVzc2FnZXMgaW4gdGhlIGJ1ZmZlciBjb3VsZCBjcm93ZCBvdXQgdGhlIGFjdHVhbCBoaWdoIHByaW9yaXR5IGl0ZW0uXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRMb2dJdGVtc1RvQnVmZmVyKHRoaXMuYnVmZmVyKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlci5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc2VuZEJhdGNoSWZDb21wbGV0ZSgpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgO1xyXG4gICAgICAgIC8vIFByb2Nlc3NlcyB0aGUgYmF0Y2ggYnVmZmVyXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBNYWtlIHRoaXMgcHVibGljLCBzbyBpdCBjYW4gYmUgY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgbGlicmFyeSxcclxuICAgICAgICAvLyB3aGVuIHRoZSBwYWdlIGlzIHVubG9hZGVkLlxyXG4gICAgICAgIEFwcGVuZGVyLnByb3RvdHlwZS5zZW5kQmF0Y2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBjbGVhciB0aGUgYmF0Y2ggdGltZXIgaWYgeW91IGRvbid0IGdvIGFoZWFkIGhlcmUgYmVjYXVzZVxyXG4gICAgICAgICAgICAvLyBhIHNlbmQgaXMgYWxyZWFkeSBpbiBwcm9ncmVzcy4gT3RoZXJ3aXNlIHRoZSBtZXNzYWdlcyB0aGF0IHdlcmUgc3RvcHBlZCBmcm9tIGdvaW5nIG91dFxyXG4gICAgICAgICAgICAvLyBtYXkgZ2V0IGlnbm9yZWQgYmVjYXVzZSB0aGUgYmF0Y2ggdGltZXIgbmV2ZXIgd2VudCBvZmYuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm5ickxvZ0l0ZW1zQmVpbmdTZW50ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNsZWFyVGltZXIodGhpcy5iYXRjaFRpbWVvdXRUaW1lcik7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gRGVjaWRlZCBhdCB0aGlzIHBvaW50IHRvIHNlbmQgY29udGVudHMgb2YgdGhlIGJ1ZmZlclxyXG4gICAgICAgICAgICB0aGlzLm5ickxvZ0l0ZW1zQmVpbmdTZW50ID0gdGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGg7XHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgICAgICAgICAgc2V0VGltZXIodGhpcy5zZW5kVGltZW91dFRpbWVyLCB0aGlzLnNlbmRUaW1lb3V0LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGF0Lm9uU2VuZGluZ0VuZGVkLmNhbGwodGhhdCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRMb2dJdGVtcyh0aGlzLmJhdGNoQnVmZmVyLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBMb2cgZW50cmllcyBoYXZlIGJlZW4gc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gc2VydmVyXHJcbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGZpcnN0IChuYnJMb2dJdGVtc0JlaW5nU2VudCkgaXRlbXMgaW4gdGhlIGJhdGNoIGJ1ZmZlciwgYmVjYXVzZSB0aGV5IGFyZSB0aGUgb25lc1xyXG4gICAgICAgICAgICAgICAgLy8gdGhhdCB3ZXJlIHNlbnQuXHJcbiAgICAgICAgICAgICAgICB0aGF0LmJhdGNoQnVmZmVyLnNwbGljZSgwLCB0aGF0Lm5ickxvZ0l0ZW1zQmVpbmdTZW50KTtcclxuICAgICAgICAgICAgICAgIC8vIElmIGl0ZW1zIGhhZCB0byBiZSBza2lwcGVkLCBhZGQgYSBXQVJOIG1lc3NhZ2VcclxuICAgICAgICAgICAgICAgIGlmICh0aGF0Lm5ickxvZ0l0ZW1zU2tpcHBlZCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGF0LmJhdGNoQnVmZmVyLnB1c2gobmV3TG9nSXRlbShnZXRXYXJuTGV2ZWwoKSwgXCJMb3N0IFwiICsgdGhhdC5uYnJMb2dJdGVtc1NraXBwZWQgKyBcIiBtZXNzYWdlcy4gRWl0aGVyIGNvbm5lY3Rpb24gd2l0aCB0aGUgc2VydmVyIHdhcyBkb3duIG9yIGxvZ2dpbmcgd2FzIGRpc2FibGVkIHZpYSB0aGUgZW5hYmxlZCBvcHRpb24uIFJlZHVjZSBsb3N0IG1lc3NhZ2VzIGJ5IGluY3JlYXNpbmcgdGhlIGFqYXhBcHBlbmRlciBvcHRpb24gbWF4QmF0Y2hTaXplLlwiLCB0aGF0LmFwcGVuZGVyTmFtZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQubmJyTG9nSXRlbXNTa2lwcGVkID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoYXQub25TZW5kaW5nRW5kZWQuY2FsbCh0aGF0KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gQXBwZW5kZXI7XHJcbiAgICB9KCkpO1xyXG4gICAgSkwuQXBwZW5kZXIgPSBBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdmFyIEFqYXhBcHBlbmRlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBfX2V4dGVuZHMoQWpheEFwcGVuZGVyLCBfc3VwZXIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIEFqYXhBcHBlbmRlcihhcHBlbmRlck5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIGFwcGVuZGVyTmFtZSwgQWpheEFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNBamF4KSB8fCB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBBamF4QXBwZW5kZXIucHJvdG90eXBlLnNldE9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJ1cmxcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImJlZm9yZVNlbmRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2V0T3B0aW9ucy5jYWxsKHRoaXMsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG4gICAgICAgIEFqYXhBcHBlbmRlci5wcm90b3R5cGUuc2VuZExvZ0l0ZW1zQWpheCA9IGZ1bmN0aW9uIChsb2dJdGVtcywgc3VjY2Vzc0NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIC8vIEpTT04uc3RyaW5naWZ5IGlzIG9ubHkgc3VwcG9ydGVkIG9uIElFOCtcclxuICAgICAgICAgICAgLy8gVXNlIHRyeS1jYXRjaCBpbiBjYXNlIHdlIGdldCBhbiBleGNlcHRpb24gaGVyZS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gVGhlIFwiclwiIGZpZWxkIGlzIG5vdyBvYnNvbGV0ZS4gV2hlbiB3cml0aW5nIGEgc2VydmVyIHNpZGUgY29tcG9uZW50LCBcclxuICAgICAgICAgICAgLy8gcmVhZCB0aGUgSFRUUCBoZWFkZXIgXCJKU05Mb2ctUmVxdWVzdElkXCJcclxuICAgICAgICAgICAgLy8gdG8gZ2V0IHRoZSByZXF1ZXN0IGlkLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBUaGUgLk5ldCBzZXJ2ZXIgc2lkZSBjb21wb25lbnRcclxuICAgICAgICAgICAgLy8gbm93IHVzZXMgdGhlIEpTTkxvZy1SZXF1ZXN0SWQgSFRUUCBIZWFkZXIsIGJlY2F1c2UgdGhpcyBhbGxvd3MgaXQgdG9cclxuICAgICAgICAgICAgLy8gZGV0ZWN0IHdoZXRoZXIgdGhlIGluY29taW5nIHJlcXVlc3QgaGFzIGEgcmVxdWVzdCBpZC5cclxuICAgICAgICAgICAgLy8gSWYgdGhlIHJlcXVlc3QgaWQgd2VyZSBpbiB0aGUganNvbiBwYXlsb2FkLCBpdCB3b3VsZCBoYXZlIHRvIHJlYWQgdGhlIGpzb25cclxuICAgICAgICAgICAgLy8gZnJvbSB0aGUgc3RyZWFtLCBpbnRlcmZlcmluZyB3aXRoIG5vcm1hbCBub24tbG9nZ2luZyByZXF1ZXN0cy5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gVG8gc2VlIHdoYXQgY2hhcmFjdGVycyB5b3UgY2FuIHVzZSBpbiB0aGUgSFRUUCBoZWFkZXIsIHZpc2l0OlxyXG4gICAgICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM1NjEzODEvY3VzdG9tLWh0dHAtaGVhZGVycy1uYW1pbmctY29udmVudGlvbnMvMzU2MTM5OSMzNTYxMzk5XHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIEl0IG5lZWRzIHRoaXMgYWJpbGl0eSwgc28gdXNlcnMgb2YgTkxvZyBjYW4gc2V0IGEgcmVxdWVzdElkIHZhcmlhYmxlIGluIE5Mb2dcclxuICAgICAgICAgICAgLy8gYmVmb3JlIHRoZSBzZXJ2ZXIgc2lkZSBjb21wb25lbnQgdHJpZXMgdG8gbG9nIHRoZSBjbGllbnQgc2lkZSBsb2cgbWVzc2FnZVxyXG4gICAgICAgICAgICAvLyB0aHJvdWdoIGFuIE5Mb2cgbG9nZ2VyLlxyXG4gICAgICAgICAgICAvLyBVbmxpa2UgTG9nNE5ldCwgTkxvZyBkb2Vzbid0IGFsbG93IHlvdSB0byByZWdpc3RlciBhbiBvYmplY3Qgd2hvc2UgVG9TdHJpbmcoKVxyXG4gICAgICAgICAgICAvLyBpcyBvbmx5IGNhbGxlZCB3aGVuIGl0IHRyaWVzIHRvIGxvZyBzb21ldGhpbmcsIHNvIHRoZSByZXF1ZXN0SWQgaGFzIHRvIGJlIFxyXG4gICAgICAgICAgICAvLyBkZXRlcm1pbmVkIHJpZ2h0IGF0IHRoZSBzdGFydCBvZiByZXF1ZXN0IHByb2Nlc3NpbmcuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3Qgc2VuZCBsb2dzLCBpZiBKTC5lbmFibGVkIGlzIHNldCB0byBmYWxzZS5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgY2FsbCBzdWNjZXNzQ2FsbGJhY2sgaGVyZS4gQWZ0ZXIgZWFjaCB0aW1lb3V0LCBqc25sb2cgd2lsbCByZXRyeSBzZW5kaW5nIHRoZSBtZXNzYWdlLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYganNubG9nIGdldHMgcmUtZW5hYmxlZCwgaXQgd2lsbCB0aGVuIGxvZyB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzIGxvZ2dlZC5cclxuICAgICAgICAgICAgICAgIC8vIElmIGl0IGRvZXNuJ3QgZ2V0IHJlLWVuYWJsZWQsIGFtb3VudCBvZiBjcHUgY3ljbGVzIHdhc3RlZCBpcyBtaW5pbWFsLlxyXG4gICAgICAgICAgICAgICAgaWYgKCFhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIElmIGEgcmVxdWVzdCBpcyBpbiBwcm9ncmVzcywgYWJvcnQgaXQuXHJcbiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIGl0IG1heSBjYWxsIHRoZSBzdWNjZXNzIGNhbGxiYWNrLCB3aGljaCB3aWxsIGJlIHZlcnkgY29uZnVzaW5nLlxyXG4gICAgICAgICAgICAgICAgLy8gSXQgbWF5IGFsc28gc3RvcCB0aGUgaW5mbGlnaHQgcmVxdWVzdCBmcm9tIHJlc3VsdGluZyBpbiBhIGxvZyBhdCB0aGUgc2VydmVyLlxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMueGhyICYmICh0aGlzLnhoci5yZWFkeVN0YXRlICE9IDApICYmICh0aGlzLnhoci5yZWFkeVN0YXRlICE9IDQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy54aHIuYWJvcnQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgYSByZWFjdC1uYXRpdmUgWE1MSHR0cFJlcXVlc3QgY2Fubm90IGJlIHJldXNlZCBpdCBuZWVkcyB0byBiZSByZWNyZWF0ZWQgd2l0aCBlYWNoIHJlcXVlc3RcclxuICAgICAgICAgICAgICAgIHRoaXMueGhyID0gSkwuX2NyZWF0ZVhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGRldGVybWluZSB0aGUgdXJsIHJpZ2h0IGJlZm9yZSB5b3Ugc2VuZCBhIGxvZyByZXF1ZXN0LlxyXG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IHNldCB0aGUgdXJsIHdoZW4gY29uc3RydWN0aW5nIHRoZSBhcHBlbmRlci5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlIHNlcnZlciBzaWRlIGNvbXBvbmVudCBzZXRzIGRlZmF1bHRBamF4VXJsXHJcbiAgICAgICAgICAgICAgICAvLyBpbiBhIGNhbGwgdG8gc2V0T3B0aW9ucywgQUZURVIgdGhlIEpMIG9iamVjdCBhbmQgdGhlIGRlZmF1bHQgYXBwZW5kZXJcclxuICAgICAgICAgICAgICAgIC8vIGhhdmUgYmVlbiBjcmVhdGVkLiBcclxuICAgICAgICAgICAgICAgIHZhciBhamF4VXJsID0gXCIvanNubG9nLmxvZ2dlclwiO1xyXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBldmFsdWF0ZXMgdG8gdHJ1ZSBpZiBkZWZhdWx0QWpheFVybCBpcyBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKCEoSkwuZGVmYXVsdEFqYXhVcmwgPT0gbnVsbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBhamF4VXJsID0gSkwuZGVmYXVsdEFqYXhVcmw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51cmwpIHtcclxuICAgICAgICAgICAgICAgICAgICBhamF4VXJsID0gdGhpcy51cmw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5vcGVuKCdQT1NUJywgYWpheFVybCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcignSlNOTG9nLVJlcXVlc3RJZCcsIEpMLnJlcXVlc3RJZCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT24gbW9zdCBicm93c2VycywgaWYgdGhlIHJlcXVlc3QgZmFpbHMgKGVnLiBpbnRlcm5ldCBpcyBnb25lKSxcclxuICAgICAgICAgICAgICAgICAgICAvLyBpdCB3aWxsIHNldCB4aHIucmVhZHlTdGF0ZSA9PSA0IGFuZCB4aHIuc3RhdHVzICE9IDIwMCAoMCBpZiByZXF1ZXN0IGNvdWxkIG5vdCBiZSBzZW50KSBpbW1lZGlhdGVseS5cclxuICAgICAgICAgICAgICAgICAgICAvLyBIb3dldmVyLCBFZGdlIGFuZCBJRSB3aWxsIG5vdCBjaGFuZ2UgdGhlIHJlYWR5U3RhdGUgYXQgYWxsIGlmIHRoZSBpbnRlcm5ldCBnb2VzIGF3YXkgd2hpbGUgd2FpdGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGZvciBhIHJlc3BvbnNlLlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNvbWUgc2VydmVycyB3aWxsIHJldHVybiBhIDIwNCAoc3VjY2Vzcywgbm8gY29udGVudCkgd2hlbiB0aGUgSlNOTG9nIGVuZHBvaW50XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJucyB0aGUgZW1wdHkgcmVzcG9uc2UuIFNvIGNoZWNrIG9uIGFueSBjb2RlIGluIHRoZSAyLi4gcmFuZ2UsIG5vdCBqdXN0IDIwMC5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHRoYXQueGhyLnJlYWR5U3RhdGUgPT0gNCkgJiYgKHRoYXQueGhyLnN0YXR1cyA+PSAyMDAgJiYgdGhhdC54aHIuc3RhdHVzIDwgMzAwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGpzb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcjogSkwucmVxdWVzdElkLFxyXG4gICAgICAgICAgICAgICAgICAgIGxnOiBsb2dJdGVtc1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIC8vIGNhbGwgYmVmb3JlU2VuZCBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgLy8gZmlyc3QgdHJ5IHRoZSBjYWxsYmFjayBvbiB0aGUgYXBwZW5kZXJcclxuICAgICAgICAgICAgICAgIC8vIHRoZW4gdGhlIGdsb2JhbCBkZWZhdWx0QmVmb3JlU2VuZCBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmJlZm9yZVNlbmQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJlZm9yZVNlbmQuY2FsbCh0aGlzLCB0aGlzLnhociwganNvbik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgSkwuZGVmYXVsdEJlZm9yZVNlbmQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICBKTC5kZWZhdWx0QmVmb3JlU2VuZC5jYWxsKHRoaXMsIHRoaXMueGhyLCBqc29uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBmaW5hbG1zZyA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy54aHIuc2VuZChmaW5hbG1zZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIEFqYXhBcHBlbmRlcjtcclxuICAgIH0oQXBwZW5kZXIpKTtcclxuICAgIEpMLkFqYXhBcHBlbmRlciA9IEFqYXhBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdmFyIENvbnNvbGVBcHBlbmRlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBfX2V4dGVuZHMoQ29uc29sZUFwcGVuZGVyLCBfc3VwZXIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIENvbnNvbGVBcHBlbmRlcihhcHBlbmRlck5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIGFwcGVuZGVyTmFtZSwgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNDb25zb2xlKSB8fCB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLmNsb2cgPSBmdW5jdGlvbiAobG9nRW50cnkpIHtcclxuICAgICAgICAgICAgSkwuX2NvbnNvbGUubG9nKGxvZ0VudHJ5KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIENvbnNvbGVBcHBlbmRlci5wcm90b3R5cGUuY2Vycm9yID0gZnVuY3Rpb24gKGxvZ0VudHJ5KSB7XHJcbiAgICAgICAgICAgIGlmIChKTC5fY29uc29sZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgSkwuX2NvbnNvbGUuZXJyb3IobG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9nKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5jd2FybiA9IGZ1bmN0aW9uIChsb2dFbnRyeSkge1xyXG4gICAgICAgICAgICBpZiAoSkwuX2NvbnNvbGUud2Fybikge1xyXG4gICAgICAgICAgICAgICAgSkwuX2NvbnNvbGUud2Fybihsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb2cobG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLmNpbmZvID0gZnVuY3Rpb24gKGxvZ0VudHJ5KSB7XHJcbiAgICAgICAgICAgIGlmIChKTC5fY29uc29sZS5pbmZvKSB7XHJcbiAgICAgICAgICAgICAgICBKTC5fY29uc29sZS5pbmZvKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xvZyhsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIElFMTEgaGFzIGEgY29uc29sZS5kZWJ1ZyBmdW5jdGlvbi4gQnV0IGl0cyBjb25zb2xlIGRvZXNuJ3QgaGF2ZSBcclxuICAgICAgICAvLyB0aGUgb3B0aW9uIHRvIHNob3cvaGlkZSBkZWJ1ZyBtZXNzYWdlcyAodGhlIHNhbWUgd2F5IENocm9tZSBhbmQgRkYgZG8pLFxyXG4gICAgICAgIC8vIGV2ZW4gdGhvdWdoIGl0IGRvZXMgaGF2ZSBzdWNoIGJ1dHRvbnMgZm9yIEVycm9yLCBXYXJuLCBJbmZvLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gRm9yIG5vdywgdGhpcyBtZWFucyB0aGF0IGRlYnVnIG1lc3NhZ2VzIGNhbiBub3QgYmUgaGlkZGVuIG9uIElFLlxyXG4gICAgICAgIC8vIExpdmUgd2l0aCB0aGlzLCBzZWVpbmcgdGhhdCBpdCB3b3JrcyBmaW5lIG9uIEZGIGFuZCBDaHJvbWUsIHdoaWNoXHJcbiAgICAgICAgLy8gd2lsbCBiZSBtdWNoIG1vcmUgcG9wdWxhciB3aXRoIGRldmVsb3BlcnMuXHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5jZGVidWcgPSBmdW5jdGlvbiAobG9nRW50cnkpIHtcclxuICAgICAgICAgICAgaWYgKEpMLl9jb25zb2xlLmRlYnVnKSB7XHJcbiAgICAgICAgICAgICAgICBKTC5fY29uc29sZS5kZWJ1Zyhsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNpbmZvKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNDb25zb2xlID0gZnVuY3Rpb24gKGxvZ0l0ZW1zLCBzdWNjZXNzQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIC8vIERvIG5vdCBzZW5kIGxvZ3MsIGlmIEpMLmVuYWJsZWQgaXMgc2V0IHRvIGZhbHNlXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IGNhbGwgc3VjY2Vzc0NhbGxiYWNrIGhlcmUuIEFmdGVyIGVhY2ggdGltZW91dCwganNubG9nIHdpbGwgcmV0cnkgc2VuZGluZyB0aGUgbWVzc2FnZS5cclxuICAgICAgICAgICAgICAgIC8vIElmIGpzbmxvZyBnZXRzIHJlLWVuYWJsZWQsIGl0IHdpbGwgdGhlbiBsb2cgdGhlIG51bWJlciBvZiBtZXNzYWdlcyBsb2dnZWQuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiBpdCBkb2Vzbid0IGdldCByZS1lbmFibGVkLCBhbW91bnQgb2YgY3B1IGN5Y2xlcyB3YXN0ZWQgaXMgbWluaW1hbC5cclxuICAgICAgICAgICAgICAgIGlmICghYWxsb3codGhpcykpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIUpMLl9jb25zb2xlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbG9nSXRlbXMubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbGkgPSBsb2dJdGVtc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gbGkubiArIFwiOiBcIiArIGxpLm07XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBsb2cgdGhlIHRpbWVzdGFtcCBpZiB3ZSdyZSBvbiB0aGUgc2VydmVyXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKHdpbmRvdyBpcyB1bmRlZmluZWQpLiBPbiB0aGUgYnJvd3NlciwgdGhlIHVzZXJcclxuICAgICAgICAgICAgICAgICAgICAvLyBzZWVzIHRoZSBsb2cgZW50cnkgcHJvYmFibHkgaW1tZWRpYXRlbHksIHNvIGluIHRoYXQgY2FzZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSB0aW1lc3RhbXAgaXMgY2x1dHRlci5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbXNnID0gbmV3IERhdGUobGkudCkgKyBcIiB8IFwiICsgbXNnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAobGkubCA8PSBKTC5nZXREZWJ1Z0xldmVsKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jZGVidWcobXNnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobGkubCA8PSBKTC5nZXRJbmZvTGV2ZWwoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNpbmZvKG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxpLmwgPD0gSkwuZ2V0V2FybkxldmVsKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jd2Fybihtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jZXJyb3IobXNnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBDb25zb2xlQXBwZW5kZXI7XHJcbiAgICB9KEFwcGVuZGVyKSk7XHJcbiAgICBKTC5Db25zb2xlQXBwZW5kZXIgPSBDb25zb2xlQXBwZW5kZXI7XHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdmFyIExvZ2dlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmdW5jdGlvbiBMb2dnZXIobG9nZ2VyTmFtZSkge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlck5hbWUgPSBsb2dnZXJOYW1lO1xyXG4gICAgICAgICAgICAvLyBDcmVhdGUgc2VlblJleGVzLCBvdGhlcndpc2UgdGhpcyBsb2dnZXIgd2lsbCB1c2UgdGhlIHNlZW5SZXhlc1xyXG4gICAgICAgICAgICAvLyBvZiBpdHMgcGFyZW50IHZpYSB0aGUgcHJvdG90eXBlIGNoYWluLlxyXG4gICAgICAgICAgICB0aGlzLnNlZW5SZWdleGVzID0gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImxldmVsXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJ1c2VyQWdlbnRSZWdleFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiZGlzYWxsb3dcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImlwUmVnZXhcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImFwcGVuZGVyc1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwib25jZU9ubHlcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIC8vIFJlc2V0IHNlZW5SZWdleGVzLCBpbiBjYXNlIG9uY2VPbmx5IGhhcyBiZWVuIGNoYW5nZWQuXHJcbiAgICAgICAgICAgIHRoaXMuc2VlblJlZ2V4ZXMgPSBbXTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBUdXJucyBhbiBleGNlcHRpb24gaW50byBhbiBvYmplY3QgdGhhdCBjYW4gYmUgc2VudCB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuYnVpbGRFeGNlcHRpb25PYmplY3QgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICB2YXIgZXhjT2JqZWN0ID0ge307XHJcbiAgICAgICAgICAgIGlmIChlLnN0YWNrKSB7XHJcbiAgICAgICAgICAgICAgICBleGNPYmplY3Quc3RhY2sgPSBlLnN0YWNrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXhjT2JqZWN0LmUgPSBlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5tZXNzYWdlID0gZS5tZXNzYWdlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5uYW1lID0gZS5uYW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLmRhdGEpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5kYXRhID0gZS5kYXRhO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLmlubmVyKSB7XHJcbiAgICAgICAgICAgICAgICBleGNPYmplY3QuaW5uZXIgPSB0aGlzLmJ1aWxkRXhjZXB0aW9uT2JqZWN0KGUuaW5uZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBleGNPYmplY3Q7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBMb2dzIGEgbG9nIGl0ZW0uXHJcbiAgICAgICAgLy8gUGFyYW1ldGVyIGUgY29udGFpbnMgYW4gZXhjZXB0aW9uIChvciBudWxsIG9yIHVuZGVmaW5lZCkuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBSZWFzb24gdGhhdCBwcm9jZXNzaW5nIGV4Y2VwdGlvbnMgaXMgZG9uZSBhdCB0aGlzIGxvdyBsZXZlbCBpcyB0aGF0XHJcbiAgICAgICAgLy8gMSkgbm8gbmVlZCB0byBzcGVuZCB0aGUgY3B1IGN5Y2xlcyBpZiB0aGUgbG9nZ2VyIGlzIHN3aXRjaGVkIG9mZlxyXG4gICAgICAgIC8vIDIpIGZhdGFsRXhjZXB0aW9uIHRha2VzIGJvdGggYSBsb2dPYmplY3QgYW5kIGFuIGV4Y2VwdGlvbiwgYW5kIHRoZSBsb2dPYmplY3RcclxuICAgICAgICAvLyAgICBtYXkgYmUgYSBmdW5jdGlvbiB0aGF0IHNob3VsZCBvbmx5IGJlIGV4ZWN1dGVkIGlmIHRoZSBsb2dnZXIgaXMgc3dpdGNoZWQgb24uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgcGFzc2VkIGluLCB0aGUgY29udGVudHMgb2YgbG9nT2JqZWN0IGlzIGF0dGFjaGVkIHRvIHRoZSBleGNlcHRpb25cclxuICAgICAgICAvLyBvYmplY3QgaW4gYSBuZXcgcHJvcGVydHkgbG9nRGF0YS5cclxuICAgICAgICAvLyBUaGUgcmVzdWx0aW5nIGV4Y2VwdGlvbiBvYmplY3QgaXMgdGhhbiB3b3JrZWQgaW50byBhIG1lc3NhZ2UgdG8gdGhlIHNlcnZlci5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGV4Y2VwdGlvbiwgbG9nT2JqZWN0IGl0c2VsZiBpcyB3b3JrZWQgaW50byB0aGUgbWVzc2FnZSB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUubG9nID0gZnVuY3Rpb24gKGxldmVsLCBsb2dPYmplY3QsIGUpIHtcclxuICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICB2YXIgY29tcG9zaXRlTWVzc2FnZTtcclxuICAgICAgICAgICAgdmFyIGV4Y09iamVjdDtcclxuICAgICAgICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCBhbnkgYXBwZW5kZXJzLCBkbyBub3RoaW5nXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5hcHBlbmRlcnMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgoKGxldmVsID49IHRoaXMubGV2ZWwpKSAmJiBhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBleGNPYmplY3QgPSB0aGlzLmJ1aWxkRXhjZXB0aW9uT2JqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGV4Y09iamVjdC5sb2dEYXRhID0gc3RyaW5naWZ5TG9nT2JqZWN0RnVuY3Rpb24obG9nT2JqZWN0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4Y09iamVjdCA9IGxvZ09iamVjdDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbXBvc2l0ZU1lc3NhZ2UgPSBzdHJpbmdpZnlMb2dPYmplY3QoZXhjT2JqZWN0KTtcclxuICAgICAgICAgICAgICAgIGlmIChhbGxvd01lc3NhZ2UodGhpcywgY29tcG9zaXRlTWVzc2FnZS5maW5hbFN0cmluZykpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTZWUgd2hldGhlciBtZXNzYWdlIGlzIGEgZHVwbGljYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25jZU9ubHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaSA9IHRoaXMub25jZU9ubHkubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkgPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAodGhpcy5vbmNlT25seVtpXSkudGVzdChjb21wb3NpdGVNZXNzYWdlLmZpbmFsU3RyaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNlZW5SZWdleGVzW2ldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlZW5SZWdleGVzW2ldID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIG1lc3NhZ2UgdG8gYWxsIGFwcGVuZGVyc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBhcHBlbmRlcnMgY291bGQgYmUgV2luc3RvbiB0cmFuc3BvcnRzXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZsYXRpcm9uL3dpbnN0b25cclxuICAgICAgICAgICAgICAgICAgICBjb21wb3NpdGVNZXNzYWdlLm1ldGEgPSBjb21wb3NpdGVNZXNzYWdlLm1ldGEgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGlmIHRoZSB1c2VyIGlzIGxvZ2dpbmcgYW4gb2JqZWN0LCBjb21wb3NpdGVNZXNzYWdlLm1ldGEgd2lsbCBob2xkIGEgcmVmZXJlbmNlIHRvIHRoYXQgb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBhZGQgZmllbGRzIHRvIGNvbXBvc2l0ZU1lc3NhZ2UubWV0YSwgb3RoZXJ3aXNlIHRoZSB1c2VyJ3Mgb2JqZWN0IHdpbGwgZ2V0IHRoYXQgZmllbGQgb3V0IG9mIHRoZSBibHVlLlxyXG4gICAgICAgICAgICAgICAgICAgIGkgPSB0aGlzLmFwcGVuZGVycy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChpID49IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRlcnNbaV0ubG9nKGxldmVsVG9TdHJpbmcobGV2ZWwpLCBjb21wb3NpdGVNZXNzYWdlLm1zZywgY29tcG9zaXRlTWVzc2FnZS5tZXRhLCBmdW5jdGlvbiAoKSB7IH0sIGxldmVsLCBjb21wb3NpdGVNZXNzYWdlLmZpbmFsU3RyaW5nLCB0aGlzLmxvZ2dlck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpLS07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS50cmFjZSA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldFRyYWNlTGV2ZWwoKSwgbG9nT2JqZWN0KTsgfTtcclxuICAgICAgICBMb2dnZXIucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24gKGxvZ09iamVjdCkgeyByZXR1cm4gdGhpcy5sb2coZ2V0RGVidWdMZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuaW5mbyA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldEluZm9MZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUud2FybiA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldFdhcm5MZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuZXJyb3IgPSBmdW5jdGlvbiAobG9nT2JqZWN0KSB7IHJldHVybiB0aGlzLmxvZyhnZXRFcnJvckxldmVsKCksIGxvZ09iamVjdCk7IH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5mYXRhbCA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldEZhdGFsTGV2ZWwoKSwgbG9nT2JqZWN0KTsgfTtcclxuICAgICAgICBMb2dnZXIucHJvdG90eXBlLmZhdGFsRXhjZXB0aW9uID0gZnVuY3Rpb24gKGxvZ09iamVjdCwgZSkgeyByZXR1cm4gdGhpcy5sb2coZ2V0RmF0YWxMZXZlbCgpLCBsb2dPYmplY3QsIGUpOyB9O1xyXG4gICAgICAgIHJldHVybiBMb2dnZXI7XHJcbiAgICB9KCkpO1xyXG4gICAgSkwuTG9nZ2VyID0gTG9nZ2VyO1xyXG4gICAgZnVuY3Rpb24gY3JlYXRlQWpheEFwcGVuZGVyKGFwcGVuZGVyTmFtZSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQWpheEFwcGVuZGVyKGFwcGVuZGVyTmFtZSk7XHJcbiAgICB9XHJcbiAgICBKTC5jcmVhdGVBamF4QXBwZW5kZXIgPSBjcmVhdGVBamF4QXBwZW5kZXI7XHJcbiAgICBmdW5jdGlvbiBjcmVhdGVDb25zb2xlQXBwZW5kZXIoYXBwZW5kZXJOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBDb25zb2xlQXBwZW5kZXIoYXBwZW5kZXJOYW1lKTtcclxuICAgIH1cclxuICAgIEpMLmNyZWF0ZUNvbnNvbGVBcHBlbmRlciA9IGNyZWF0ZUNvbnNvbGVBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAvLyBJbiB0aGUgYnJvd3NlciwgdGhlIGRlZmF1bHQgYXBwZW5kZXIgaXMgdGhlIEFqYXhBcHBlbmRlci5cclxuICAgIC8vIFVuZGVyIG5vZGVqcyAod2hlcmUgdGhlcmUgaXMgbm8gXCJ3aW5kb3dcIiksIHVzZSB0aGUgQ29uc29sZUFwcGVuZGVyIGluc3RlYWQuXHJcbiAgICAvLyBcclxuICAgIC8vIERvIE5PVCBjcmVhdGUgYW4gQWpheEFwcGVuZGVyIG9iamVjdCBpZiB5b3UgYXJlIG5vdCBvbiBhIGJyb3dzZXIgKHRoYXQgaXMsIHdpbmRvdyBpcyBub3QgZGVmaW5lZCkuXHJcbiAgICAvLyBUaGF0IHdvdWxkIHRyeSB0byBjcmVhdGUgYW4gWG1sSHR0cFJlcXVlc3Qgb2JqZWN0LCB3aGljaCB3aWxsIGNyYXNoIG91dHNpZGUgYSBicm93c2VyLlxyXG4gICAgdmFyIGRlZmF1bHRBcHBlbmRlcjtcclxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIGRlZmF1bHRBcHBlbmRlciA9IG5ldyBBamF4QXBwZW5kZXIoXCJcIik7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBkZWZhdWx0QXBwZW5kZXIgPSBuZXcgQ29uc29sZUFwcGVuZGVyKFwiXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gQ3JlYXRlIHJvb3QgbG9nZ2VyXHJcbiAgICAvL1xyXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgdGhlIHBhcmVudCBvZiBhbGwgb3RoZXIgbG9nZ2Vycy5cclxuICAgIC8vIExvZ2dlciBcInhcIiB3aWxsIGJlIHN0b3JlZCBhdFxyXG4gICAgLy8gSkwuX18ueFxyXG4gICAgLy8gTG9nZ2VyIFwieC55XCIgYXRcclxuICAgIC8vIEpMLl9fLngueVxyXG4gICAgSkwuX18gPSBuZXcgSkwuTG9nZ2VyKFwiXCIpO1xyXG4gICAgSkwuX18uc2V0T3B0aW9ucyh7XHJcbiAgICAgICAgbGV2ZWw6IEpMLmdldERlYnVnTGV2ZWwoKSxcclxuICAgICAgICBhcHBlbmRlcnM6IFtkZWZhdWx0QXBwZW5kZXJdXHJcbiAgICB9KTtcclxufSkoSkwgfHwgKEpMID0ge30pKTtcclxuaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgLy8gQWxsb3dzIFN5c3RlbUpzIHRvIGltcG9ydCBqc25sb2cuanMuIFNlZVxyXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21wZXJkZWNrL2pzbmxvZy5qcy9pc3N1ZXMvNTZcclxuICAgIGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XHJcbiAgICBleHBvcnRzLkpMID0gSkw7XHJcbn1cclxuLy8gU3VwcG9ydCBBTUQgbW9kdWxlIGZvcm1hdFxyXG52YXIgZGVmaW5lO1xyXG5pZiAodHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcclxuICAgIGRlZmluZSgnanNubG9nJywgW10sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gSkw7XHJcbiAgICB9KTtcclxufVxyXG4vLyBJZiB0aGUgX19qc25sb2dfY29uZmlndXJlIGdsb2JhbCBmdW5jdGlvbiBoYXMgYmVlblxyXG4vLyBjcmVhdGVkLCBjYWxsIGl0IG5vdy4gVGhpcyBhbGxvd3MgeW91IHRvIGNyZWF0ZSBhIGdsb2JhbCBmdW5jdGlvblxyXG4vLyBzZXR0aW5nIGxvZ2dlciBvcHRpb25zIGV0Yy4gaW5saW5lIGluIHRoZSBwYWdlIGJlZm9yZSBqc25sb2cuanNcclxuLy8gaGFzIGJlZW4gbG9hZGVkLlxyXG5pZiAodHlwZW9mIF9fanNubG9nX2NvbmZpZ3VyZSA9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICBfX2pzbmxvZ19jb25maWd1cmUoSkwpO1xyXG59XHJcbi8vIENyZWF0ZSBvbmVycm9yIGhhbmRsZXIgdG8gbG9nIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgdG8gdGhlIHNlcnZlciBzaWRlIGxvZywgYnV0IG9ubHkgaWYgdGhlcmUgXHJcbi8vIGlzIG5vIHN1Y2ggaGFuZGxlciBhbHJlYWR5LlxyXG4vLyBNdXN0IHVzZSBcInR5cGVvZiB3aW5kb3dcIiBoZXJlLCBiZWNhdXNlIGluIE5vZGVKcywgd2luZG93IGlzIG5vdCBkZWZpbmVkIGF0IGFsbCwgc28gY2Fubm90IHJlZmVyIHRvIHdpbmRvdyBpbiBhbnkgd2F5LlxyXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXdpbmRvdy5vbmVycm9yKSB7XHJcbiAgICB3aW5kb3cub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvck1zZywgdXJsLCBsaW5lTnVtYmVyLCBjb2x1bW4sIGVycm9yT2JqKSB7XHJcbiAgICAgICAgLy8gU2VuZCBvYmplY3Qgd2l0aCBhbGwgZGF0YSB0byBzZXJ2ZXIgc2lkZSBsb2csIHVzaW5nIHNldmVyaXR5IGZhdGFsLCBcclxuICAgICAgICAvLyBmcm9tIGxvZ2dlciBcIm9uZXJyb3JMb2dnZXJcIlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gVXNlIGVycm9yTXNnLm1lc3NhZ2UgaWYgYXZhaWxhYmxlLCBzbyBBbmd1bGFyIDQgdGVtcGxhdGUgZXJyb3JzIHdpbGwgYmUgbG9nZ2VkLlxyXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbXBlcmRlY2svanNubG9nLmpzL3B1bGwvNjhcclxuICAgICAgICBKTChcIm9uZXJyb3JMb2dnZXJcIikuZmF0YWxFeGNlcHRpb24oe1xyXG4gICAgICAgICAgICBcIm1zZ1wiOiBcIlVuY2F1Z2h0IEV4Y2VwdGlvblwiLFxyXG4gICAgICAgICAgICBcImVycm9yTXNnXCI6IGVycm9yTXNnID8gKGVycm9yTXNnLm1lc3NhZ2UgfHwgZXJyb3JNc2cpIDogJycsXHJcbiAgICAgICAgICAgIFwidXJsXCI6IHVybCxcclxuICAgICAgICAgICAgXCJsaW5lIG51bWJlclwiOiBsaW5lTnVtYmVyLCBcImNvbHVtblwiOiBjb2x1bW5cclxuICAgICAgICB9LCBlcnJvck9iaik7XHJcbiAgICAgICAgLy8gVGVsbCBicm93c2VyIHRvIHJ1biBpdHMgb3duIGVycm9yIGhhbmRsZXIgYXMgd2VsbCAgIFxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbn1cclxuLy8gRGVhbCB3aXRoIHVuaGFuZGxlZCBleGNlcHRpb25zIHRocm93biBpbiBwcm9taXNlc1xyXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXdpbmRvdy5vbnVuaGFuZGxlZHJlamVjdGlvbikge1xyXG4gICAgd2luZG93Lm9udW5oYW5kbGVkcmVqZWN0aW9uID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgLy8gU2VuZCBvYmplY3Qgd2l0aCBhbGwgZGF0YSB0byBzZXJ2ZXIgc2lkZSBsb2csIHVzaW5nIHNldmVyaXR5IGZhdGFsLCBcclxuICAgICAgICAvLyBmcm9tIGxvZ2dlciBcIm9uZXJyb3JMb2dnZXJcIi5cclxuICAgICAgICAvLyBOZWVkIHRvIGNoZWNrIGJvdGggZXZlbnQucmVhc29uLm1lc3NhZ2UgYW5kIGV2ZW50Lm1lc3NhZ2UsXHJcbiAgICAgICAgLy8gYmVjYXVzZSBTeXN0ZW1KcyB3cmFwcyBleGNlcHRpb25zIGFuZCB0aHJvd3MgYSBuZXcgb2JqZWN0IHdoaWNoIGRvZXNuJ3QgaGF2ZSBhIHJlYXNvbiBwcm9wZXJ0eS5cclxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N5c3RlbWpzL3N5c3RlbWpzL2lzc3Vlcy8xMzA5XHJcbiAgICAgICAgSkwoXCJvbmVycm9yTG9nZ2VyXCIpLmZhdGFsRXhjZXB0aW9uKHtcclxuICAgICAgICAgICAgXCJtc2dcIjogXCJ1bmhhbmRsZWRyZWplY3Rpb25cIixcclxuICAgICAgICAgICAgXCJlcnJvck1zZ1wiOiBldmVudC5yZWFzb24gPyBldmVudC5yZWFzb24ubWVzc2FnZSA6IGV2ZW50Lm1lc3NhZ2UgfHwgbnVsbFxyXG4gICAgICAgIH0sIGV2ZW50LnJlYXNvbik7XHJcbiAgICB9O1xyXG59XHJcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBAcGFyYW0gdHlwZU1hcCBbT2JqZWN0XSBNYXAgb2YgTUlNRSB0eXBlIC0+IEFycmF5W2V4dGVuc2lvbnNdXG4gKiBAcGFyYW0gLi4uXG4gKi9cbmZ1bmN0aW9uIE1pbWUoKSB7XG4gIHRoaXMuX3R5cGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgdGhpcy5fZXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLmRlZmluZShhcmd1bWVudHNbaV0pO1xuICB9XG5cbiAgdGhpcy5kZWZpbmUgPSB0aGlzLmRlZmluZS5iaW5kKHRoaXMpO1xuICB0aGlzLmdldFR5cGUgPSB0aGlzLmdldFR5cGUuYmluZCh0aGlzKTtcbiAgdGhpcy5nZXRFeHRlbnNpb24gPSB0aGlzLmdldEV4dGVuc2lvbi5iaW5kKHRoaXMpO1xufVxuXG4vKipcbiAqIERlZmluZSBtaW1ldHlwZSAtPiBleHRlbnNpb24gbWFwcGluZ3MuICBFYWNoIGtleSBpcyBhIG1pbWUtdHlwZSB0aGF0IG1hcHNcbiAqIHRvIGFuIGFycmF5IG9mIGV4dGVuc2lvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0eXBlLiAgVGhlIGZpcnN0IGV4dGVuc2lvbiBpc1xuICogdXNlZCBhcyB0aGUgZGVmYXVsdCBleHRlbnNpb24gZm9yIHRoZSB0eXBlLlxuICpcbiAqIGUuZy4gbWltZS5kZWZpbmUoeydhdWRpby9vZ2cnLCBbJ29nYScsICdvZ2cnLCAnc3B4J119KTtcbiAqXG4gKiBJZiBhIHR5cGUgZGVjbGFyZXMgYW4gZXh0ZW5zaW9uIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkLCBhbiBlcnJvciB3aWxsXG4gKiBiZSB0aHJvd24uICBUbyBzdXBwcmVzcyB0aGlzIGVycm9yIGFuZCBmb3JjZSB0aGUgZXh0ZW5zaW9uIHRvIGJlIGFzc29jaWF0ZWRcbiAqIHdpdGggdGhlIG5ldyB0eXBlLCBwYXNzIGBmb3JjZWA9dHJ1ZS4gIEFsdGVybmF0aXZlbHksIHlvdSBtYXkgcHJlZml4IHRoZVxuICogZXh0ZW5zaW9uIHdpdGggXCIqXCIgdG8gbWFwIHRoZSB0eXBlIHRvIGV4dGVuc2lvbiwgd2l0aG91dCBtYXBwaW5nIHRoZVxuICogZXh0ZW5zaW9uIHRvIHRoZSB0eXBlLlxuICpcbiAqIGUuZy4gbWltZS5kZWZpbmUoeydhdWRpby93YXYnLCBbJ3dhdiddfSwgeydhdWRpby94LXdhdicsIFsnKndhdiddfSk7XG4gKlxuICpcbiAqIEBwYXJhbSBtYXAgKE9iamVjdCkgdHlwZSBkZWZpbml0aW9uc1xuICogQHBhcmFtIGZvcmNlIChCb29sZWFuKSBpZiB0cnVlLCBmb3JjZSBvdmVycmlkaW5nIG9mIGV4aXN0aW5nIGRlZmluaXRpb25zXG4gKi9cbk1pbWUucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uKHR5cGVNYXAsIGZvcmNlKSB7XG4gIGZvciAobGV0IHR5cGUgaW4gdHlwZU1hcCkge1xuICAgIGxldCBleHRlbnNpb25zID0gdHlwZU1hcFt0eXBlXS5tYXAoZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIHQudG9Mb3dlckNhc2UoKTtcbiAgICB9KTtcbiAgICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHRlbnNpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHQgPSBleHRlbnNpb25zW2ldO1xuXG4gICAgICAvLyAnKicgcHJlZml4ID0gbm90IHRoZSBwcmVmZXJyZWQgdHlwZSBmb3IgdGhpcyBleHRlbnNpb24uICBTbyBmaXh1cCB0aGVcbiAgICAgIC8vIGV4dGVuc2lvbiwgYW5kIHNraXAgaXQuXG4gICAgICBpZiAoZXh0WzBdID09PSAnKicpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICghZm9yY2UgJiYgKGV4dCBpbiB0aGlzLl90eXBlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdBdHRlbXB0IHRvIGNoYW5nZSBtYXBwaW5nIGZvciBcIicgKyBleHQgK1xuICAgICAgICAgICdcIiBleHRlbnNpb24gZnJvbSBcIicgKyB0aGlzLl90eXBlc1tleHRdICsgJ1wiIHRvIFwiJyArIHR5cGUgK1xuICAgICAgICAgICdcIi4gUGFzcyBgZm9yY2U9dHJ1ZWAgdG8gYWxsb3cgdGhpcywgb3RoZXJ3aXNlIHJlbW92ZSBcIicgKyBleHQgK1xuICAgICAgICAgICdcIiBmcm9tIHRoZSBsaXN0IG9mIGV4dGVuc2lvbnMgZm9yIFwiJyArIHR5cGUgKyAnXCIuJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl90eXBlc1tleHRdID0gdHlwZTtcbiAgICB9XG5cbiAgICAvLyBVc2UgZmlyc3QgZXh0ZW5zaW9uIGFzIGRlZmF1bHRcbiAgICBpZiAoZm9yY2UgfHwgIXRoaXMuX2V4dGVuc2lvbnNbdHlwZV0pIHtcbiAgICAgIGNvbnN0IGV4dCA9IGV4dGVuc2lvbnNbMF07XG4gICAgICB0aGlzLl9leHRlbnNpb25zW3R5cGVdID0gKGV4dFswXSAhPT0gJyonKSA/IGV4dCA6IGV4dC5zdWJzdHIoMSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIExvb2t1cCBhIG1pbWUgdHlwZSBiYXNlZCBvbiBleHRlbnNpb25cbiAqL1xuTWltZS5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcGF0aCA9IFN0cmluZyhwYXRoKTtcbiAgbGV0IGxhc3QgPSBwYXRoLnJlcGxhY2UoL14uKlsvXFxcXF0vLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgbGV0IGV4dCA9IGxhc3QucmVwbGFjZSgvXi4qXFwuLywgJycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgbGV0IGhhc1BhdGggPSBsYXN0Lmxlbmd0aCA8IHBhdGgubGVuZ3RoO1xuICBsZXQgaGFzRG90ID0gZXh0Lmxlbmd0aCA8IGxhc3QubGVuZ3RoIC0gMTtcblxuICByZXR1cm4gKGhhc0RvdCB8fCAhaGFzUGF0aCkgJiYgdGhpcy5fdHlwZXNbZXh0XSB8fCBudWxsO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gZmlsZSBleHRlbnNpb24gYXNzb2NpYXRlZCB3aXRoIGEgbWltZSB0eXBlXG4gKi9cbk1pbWUucHJvdG90eXBlLmdldEV4dGVuc2lvbiA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdHlwZSA9IC9eXFxzKihbXjtcXHNdKikvLnRlc3QodHlwZSkgJiYgUmVnRXhwLiQxO1xuICByZXR1cm4gdHlwZSAmJiB0aGlzLl9leHRlbnNpb25zW3R5cGUudG9Mb3dlckNhc2UoKV0gfHwgbnVsbDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWltZTtcbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IE1pbWUgPSByZXF1aXJlKCcuL01pbWUnKTtcbm1vZHVsZS5leHBvcnRzID0gbmV3IE1pbWUocmVxdWlyZSgnLi90eXBlcy9zdGFuZGFyZCcpKTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1wiYXBwbGljYXRpb24vYW5kcmV3LWluc2V0XCI6W1wiZXpcIl0sXCJhcHBsaWNhdGlvbi9hcHBsaXh3YXJlXCI6W1wiYXdcIl0sXCJhcHBsaWNhdGlvbi9hdG9tK3htbFwiOltcImF0b21cIl0sXCJhcHBsaWNhdGlvbi9hdG9tY2F0K3htbFwiOltcImF0b21jYXRcIl0sXCJhcHBsaWNhdGlvbi9hdG9tZGVsZXRlZCt4bWxcIjpbXCJhdG9tZGVsZXRlZFwiXSxcImFwcGxpY2F0aW9uL2F0b21zdmMreG1sXCI6W1wiYXRvbXN2Y1wiXSxcImFwcGxpY2F0aW9uL2F0c2MtZHdkK3htbFwiOltcImR3ZFwiXSxcImFwcGxpY2F0aW9uL2F0c2MtaGVsZCt4bWxcIjpbXCJoZWxkXCJdLFwiYXBwbGljYXRpb24vYXRzYy1yc2F0K3htbFwiOltcInJzYXRcIl0sXCJhcHBsaWNhdGlvbi9iZG9jXCI6W1wiYmRvY1wiXSxcImFwcGxpY2F0aW9uL2NhbGVuZGFyK3htbFwiOltcInhjc1wiXSxcImFwcGxpY2F0aW9uL2NjeG1sK3htbFwiOltcImNjeG1sXCJdLFwiYXBwbGljYXRpb24vY2RmeCt4bWxcIjpbXCJjZGZ4XCJdLFwiYXBwbGljYXRpb24vY2RtaS1jYXBhYmlsaXR5XCI6W1wiY2RtaWFcIl0sXCJhcHBsaWNhdGlvbi9jZG1pLWNvbnRhaW5lclwiOltcImNkbWljXCJdLFwiYXBwbGljYXRpb24vY2RtaS1kb21haW5cIjpbXCJjZG1pZFwiXSxcImFwcGxpY2F0aW9uL2NkbWktb2JqZWN0XCI6W1wiY2RtaW9cIl0sXCJhcHBsaWNhdGlvbi9jZG1pLXF1ZXVlXCI6W1wiY2RtaXFcIl0sXCJhcHBsaWNhdGlvbi9jdS1zZWVtZVwiOltcImN1XCJdLFwiYXBwbGljYXRpb24vZGFzaCt4bWxcIjpbXCJtcGRcIl0sXCJhcHBsaWNhdGlvbi9kYXZtb3VudCt4bWxcIjpbXCJkYXZtb3VudFwiXSxcImFwcGxpY2F0aW9uL2RvY2Jvb2sreG1sXCI6W1wiZGJrXCJdLFwiYXBwbGljYXRpb24vZHNzYytkZXJcIjpbXCJkc3NjXCJdLFwiYXBwbGljYXRpb24vZHNzYyt4bWxcIjpbXCJ4ZHNzY1wiXSxcImFwcGxpY2F0aW9uL2VjbWFzY3JpcHRcIjpbXCJlc1wiLFwiZWNtYVwiXSxcImFwcGxpY2F0aW9uL2VtbWEreG1sXCI6W1wiZW1tYVwiXSxcImFwcGxpY2F0aW9uL2Vtb3Rpb25tbCt4bWxcIjpbXCJlbW90aW9ubWxcIl0sXCJhcHBsaWNhdGlvbi9lcHViK3ppcFwiOltcImVwdWJcIl0sXCJhcHBsaWNhdGlvbi9leGlcIjpbXCJleGlcIl0sXCJhcHBsaWNhdGlvbi9leHByZXNzXCI6W1wiZXhwXCJdLFwiYXBwbGljYXRpb24vZmR0K3htbFwiOltcImZkdFwiXSxcImFwcGxpY2F0aW9uL2ZvbnQtdGRwZnJcIjpbXCJwZnJcIl0sXCJhcHBsaWNhdGlvbi9nZW8ranNvblwiOltcImdlb2pzb25cIl0sXCJhcHBsaWNhdGlvbi9nbWwreG1sXCI6W1wiZ21sXCJdLFwiYXBwbGljYXRpb24vZ3B4K3htbFwiOltcImdweFwiXSxcImFwcGxpY2F0aW9uL2d4ZlwiOltcImd4ZlwiXSxcImFwcGxpY2F0aW9uL2d6aXBcIjpbXCJnelwiXSxcImFwcGxpY2F0aW9uL2hqc29uXCI6W1wiaGpzb25cIl0sXCJhcHBsaWNhdGlvbi9oeXBlcnN0dWRpb1wiOltcInN0a1wiXSxcImFwcGxpY2F0aW9uL2lua21sK3htbFwiOltcImlua1wiLFwiaW5rbWxcIl0sXCJhcHBsaWNhdGlvbi9pcGZpeFwiOltcImlwZml4XCJdLFwiYXBwbGljYXRpb24vaXRzK3htbFwiOltcIml0c1wiXSxcImFwcGxpY2F0aW9uL2phdmEtYXJjaGl2ZVwiOltcImphclwiLFwid2FyXCIsXCJlYXJcIl0sXCJhcHBsaWNhdGlvbi9qYXZhLXNlcmlhbGl6ZWQtb2JqZWN0XCI6W1wic2VyXCJdLFwiYXBwbGljYXRpb24vamF2YS12bVwiOltcImNsYXNzXCJdLFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiOltcImpzXCIsXCJtanNcIl0sXCJhcHBsaWNhdGlvbi9qc29uXCI6W1wianNvblwiLFwibWFwXCJdLFwiYXBwbGljYXRpb24vanNvbjVcIjpbXCJqc29uNVwiXSxcImFwcGxpY2F0aW9uL2pzb25tbCtqc29uXCI6W1wianNvbm1sXCJdLFwiYXBwbGljYXRpb24vbGQranNvblwiOltcImpzb25sZFwiXSxcImFwcGxpY2F0aW9uL2xncit4bWxcIjpbXCJsZ3JcIl0sXCJhcHBsaWNhdGlvbi9sb3N0K3htbFwiOltcImxvc3R4bWxcIl0sXCJhcHBsaWNhdGlvbi9tYWMtYmluaGV4NDBcIjpbXCJocXhcIl0sXCJhcHBsaWNhdGlvbi9tYWMtY29tcGFjdHByb1wiOltcImNwdFwiXSxcImFwcGxpY2F0aW9uL21hZHMreG1sXCI6W1wibWFkc1wiXSxcImFwcGxpY2F0aW9uL21hbmlmZXN0K2pzb25cIjpbXCJ3ZWJtYW5pZmVzdFwiXSxcImFwcGxpY2F0aW9uL21hcmNcIjpbXCJtcmNcIl0sXCJhcHBsaWNhdGlvbi9tYXJjeG1sK3htbFwiOltcIm1yY3hcIl0sXCJhcHBsaWNhdGlvbi9tYXRoZW1hdGljYVwiOltcIm1hXCIsXCJuYlwiLFwibWJcIl0sXCJhcHBsaWNhdGlvbi9tYXRobWwreG1sXCI6W1wibWF0aG1sXCJdLFwiYXBwbGljYXRpb24vbWJveFwiOltcIm1ib3hcIl0sXCJhcHBsaWNhdGlvbi9tZWRpYXNlcnZlcmNvbnRyb2wreG1sXCI6W1wibXNjbWxcIl0sXCJhcHBsaWNhdGlvbi9tZXRhbGluayt4bWxcIjpbXCJtZXRhbGlua1wiXSxcImFwcGxpY2F0aW9uL21ldGFsaW5rNCt4bWxcIjpbXCJtZXRhNFwiXSxcImFwcGxpY2F0aW9uL21ldHMreG1sXCI6W1wibWV0c1wiXSxcImFwcGxpY2F0aW9uL21tdC1hZWkreG1sXCI6W1wibWFlaVwiXSxcImFwcGxpY2F0aW9uL21tdC11c2QreG1sXCI6W1wibXVzZFwiXSxcImFwcGxpY2F0aW9uL21vZHMreG1sXCI6W1wibW9kc1wiXSxcImFwcGxpY2F0aW9uL21wMjFcIjpbXCJtMjFcIixcIm1wMjFcIl0sXCJhcHBsaWNhdGlvbi9tcDRcIjpbXCJtcDRzXCIsXCJtNHBcIl0sXCJhcHBsaWNhdGlvbi9tc3dvcmRcIjpbXCJkb2NcIixcImRvdFwiXSxcImFwcGxpY2F0aW9uL214ZlwiOltcIm14ZlwiXSxcImFwcGxpY2F0aW9uL24tcXVhZHNcIjpbXCJucVwiXSxcImFwcGxpY2F0aW9uL24tdHJpcGxlc1wiOltcIm50XCJdLFwiYXBwbGljYXRpb24vbm9kZVwiOltcImNqc1wiXSxcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiOltcImJpblwiLFwiZG1zXCIsXCJscmZcIixcIm1hclwiLFwic29cIixcImRpc3RcIixcImRpc3R6XCIsXCJwa2dcIixcImJwa1wiLFwiZHVtcFwiLFwiZWxjXCIsXCJkZXBsb3lcIixcImV4ZVwiLFwiZGxsXCIsXCJkZWJcIixcImRtZ1wiLFwiaXNvXCIsXCJpbWdcIixcIm1zaVwiLFwibXNwXCIsXCJtc21cIixcImJ1ZmZlclwiXSxcImFwcGxpY2F0aW9uL29kYVwiOltcIm9kYVwiXSxcImFwcGxpY2F0aW9uL29lYnBzLXBhY2thZ2UreG1sXCI6W1wib3BmXCJdLFwiYXBwbGljYXRpb24vb2dnXCI6W1wib2d4XCJdLFwiYXBwbGljYXRpb24vb21kb2MreG1sXCI6W1wib21kb2NcIl0sXCJhcHBsaWNhdGlvbi9vbmVub3RlXCI6W1wib25ldG9jXCIsXCJvbmV0b2MyXCIsXCJvbmV0bXBcIixcIm9uZXBrZ1wiXSxcImFwcGxpY2F0aW9uL294cHNcIjpbXCJveHBzXCJdLFwiYXBwbGljYXRpb24vcDJwLW92ZXJsYXkreG1sXCI6W1wicmVsb1wiXSxcImFwcGxpY2F0aW9uL3BhdGNoLW9wcy1lcnJvcit4bWxcIjpbXCJ4ZXJcIl0sXCJhcHBsaWNhdGlvbi9wZGZcIjpbXCJwZGZcIl0sXCJhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkXCI6W1wicGdwXCJdLFwiYXBwbGljYXRpb24vcGdwLXNpZ25hdHVyZVwiOltcImFzY1wiLFwic2lnXCJdLFwiYXBwbGljYXRpb24vcGljcy1ydWxlc1wiOltcInByZlwiXSxcImFwcGxpY2F0aW9uL3BrY3MxMFwiOltcInAxMFwiXSxcImFwcGxpY2F0aW9uL3BrY3M3LW1pbWVcIjpbXCJwN21cIixcInA3Y1wiXSxcImFwcGxpY2F0aW9uL3BrY3M3LXNpZ25hdHVyZVwiOltcInA3c1wiXSxcImFwcGxpY2F0aW9uL3BrY3M4XCI6W1wicDhcIl0sXCJhcHBsaWNhdGlvbi9wa2l4LWF0dHItY2VydFwiOltcImFjXCJdLFwiYXBwbGljYXRpb24vcGtpeC1jZXJ0XCI6W1wiY2VyXCJdLFwiYXBwbGljYXRpb24vcGtpeC1jcmxcIjpbXCJjcmxcIl0sXCJhcHBsaWNhdGlvbi9wa2l4LXBraXBhdGhcIjpbXCJwa2lwYXRoXCJdLFwiYXBwbGljYXRpb24vcGtpeGNtcFwiOltcInBraVwiXSxcImFwcGxpY2F0aW9uL3Bscyt4bWxcIjpbXCJwbHNcIl0sXCJhcHBsaWNhdGlvbi9wb3N0c2NyaXB0XCI6W1wiYWlcIixcImVwc1wiLFwicHNcIl0sXCJhcHBsaWNhdGlvbi9wcm92ZW5hbmNlK3htbFwiOltcInByb3Z4XCJdLFwiYXBwbGljYXRpb24vcHNrYyt4bWxcIjpbXCJwc2tjeG1sXCJdLFwiYXBwbGljYXRpb24vcmFtbCt5YW1sXCI6W1wicmFtbFwiXSxcImFwcGxpY2F0aW9uL3JkZit4bWxcIjpbXCJyZGZcIixcIm93bFwiXSxcImFwcGxpY2F0aW9uL3JlZ2luZm8reG1sXCI6W1wicmlmXCJdLFwiYXBwbGljYXRpb24vcmVsYXgtbmctY29tcGFjdC1zeW50YXhcIjpbXCJybmNcIl0sXCJhcHBsaWNhdGlvbi9yZXNvdXJjZS1saXN0cyt4bWxcIjpbXCJybFwiXSxcImFwcGxpY2F0aW9uL3Jlc291cmNlLWxpc3RzLWRpZmYreG1sXCI6W1wicmxkXCJdLFwiYXBwbGljYXRpb24vcmxzLXNlcnZpY2VzK3htbFwiOltcInJzXCJdLFwiYXBwbGljYXRpb24vcm91dGUtYXBkK3htbFwiOltcInJhcGRcIl0sXCJhcHBsaWNhdGlvbi9yb3V0ZS1zLXRzaWQreG1sXCI6W1wic2xzXCJdLFwiYXBwbGljYXRpb24vcm91dGUtdXNkK3htbFwiOltcInJ1c2RcIl0sXCJhcHBsaWNhdGlvbi9ycGtpLWdob3N0YnVzdGVyc1wiOltcImdiclwiXSxcImFwcGxpY2F0aW9uL3Jwa2ktbWFuaWZlc3RcIjpbXCJtZnRcIl0sXCJhcHBsaWNhdGlvbi9ycGtpLXJvYVwiOltcInJvYVwiXSxcImFwcGxpY2F0aW9uL3JzZCt4bWxcIjpbXCJyc2RcIl0sXCJhcHBsaWNhdGlvbi9yc3MreG1sXCI6W1wicnNzXCJdLFwiYXBwbGljYXRpb24vcnRmXCI6W1wicnRmXCJdLFwiYXBwbGljYXRpb24vc2JtbCt4bWxcIjpbXCJzYm1sXCJdLFwiYXBwbGljYXRpb24vc2N2cC1jdi1yZXF1ZXN0XCI6W1wic2NxXCJdLFwiYXBwbGljYXRpb24vc2N2cC1jdi1yZXNwb25zZVwiOltcInNjc1wiXSxcImFwcGxpY2F0aW9uL3NjdnAtdnAtcmVxdWVzdFwiOltcInNwcVwiXSxcImFwcGxpY2F0aW9uL3NjdnAtdnAtcmVzcG9uc2VcIjpbXCJzcHBcIl0sXCJhcHBsaWNhdGlvbi9zZHBcIjpbXCJzZHBcIl0sXCJhcHBsaWNhdGlvbi9zZW5tbCt4bWxcIjpbXCJzZW5tbHhcIl0sXCJhcHBsaWNhdGlvbi9zZW5zbWwreG1sXCI6W1wic2Vuc21seFwiXSxcImFwcGxpY2F0aW9uL3NldC1wYXltZW50LWluaXRpYXRpb25cIjpbXCJzZXRwYXlcIl0sXCJhcHBsaWNhdGlvbi9zZXQtcmVnaXN0cmF0aW9uLWluaXRpYXRpb25cIjpbXCJzZXRyZWdcIl0sXCJhcHBsaWNhdGlvbi9zaGYreG1sXCI6W1wic2hmXCJdLFwiYXBwbGljYXRpb24vc2lldmVcIjpbXCJzaXZcIixcInNpZXZlXCJdLFwiYXBwbGljYXRpb24vc21pbCt4bWxcIjpbXCJzbWlcIixcInNtaWxcIl0sXCJhcHBsaWNhdGlvbi9zcGFycWwtcXVlcnlcIjpbXCJycVwiXSxcImFwcGxpY2F0aW9uL3NwYXJxbC1yZXN1bHRzK3htbFwiOltcInNyeFwiXSxcImFwcGxpY2F0aW9uL3NyZ3NcIjpbXCJncmFtXCJdLFwiYXBwbGljYXRpb24vc3Jncyt4bWxcIjpbXCJncnhtbFwiXSxcImFwcGxpY2F0aW9uL3NydSt4bWxcIjpbXCJzcnVcIl0sXCJhcHBsaWNhdGlvbi9zc2RsK3htbFwiOltcInNzZGxcIl0sXCJhcHBsaWNhdGlvbi9zc21sK3htbFwiOltcInNzbWxcIl0sXCJhcHBsaWNhdGlvbi9zd2lkK3htbFwiOltcInN3aWR0YWdcIl0sXCJhcHBsaWNhdGlvbi90ZWkreG1sXCI6W1widGVpXCIsXCJ0ZWljb3JwdXNcIl0sXCJhcHBsaWNhdGlvbi90aHJhdWQreG1sXCI6W1widGZpXCJdLFwiYXBwbGljYXRpb24vdGltZXN0YW1wZWQtZGF0YVwiOltcInRzZFwiXSxcImFwcGxpY2F0aW9uL3RvbWxcIjpbXCJ0b21sXCJdLFwiYXBwbGljYXRpb24vdHJpZ1wiOltcInRyaWdcIl0sXCJhcHBsaWNhdGlvbi90dG1sK3htbFwiOltcInR0bWxcIl0sXCJhcHBsaWNhdGlvbi91Ympzb25cIjpbXCJ1YmpcIl0sXCJhcHBsaWNhdGlvbi91cmMtcmVzc2hlZXQreG1sXCI6W1wicnNoZWV0XCJdLFwiYXBwbGljYXRpb24vdXJjLXRhcmdldGRlc2MreG1sXCI6W1widGRcIl0sXCJhcHBsaWNhdGlvbi92b2ljZXhtbCt4bWxcIjpbXCJ2eG1sXCJdLFwiYXBwbGljYXRpb24vd2FzbVwiOltcIndhc21cIl0sXCJhcHBsaWNhdGlvbi93aWRnZXRcIjpbXCJ3Z3RcIl0sXCJhcHBsaWNhdGlvbi93aW5obHBcIjpbXCJobHBcIl0sXCJhcHBsaWNhdGlvbi93c2RsK3htbFwiOltcIndzZGxcIl0sXCJhcHBsaWNhdGlvbi93c3BvbGljeSt4bWxcIjpbXCJ3c3BvbGljeVwiXSxcImFwcGxpY2F0aW9uL3hhbWwreG1sXCI6W1wieGFtbFwiXSxcImFwcGxpY2F0aW9uL3hjYXAtYXR0K3htbFwiOltcInhhdlwiXSxcImFwcGxpY2F0aW9uL3hjYXAtY2Fwcyt4bWxcIjpbXCJ4Y2FcIl0sXCJhcHBsaWNhdGlvbi94Y2FwLWRpZmYreG1sXCI6W1wieGRmXCJdLFwiYXBwbGljYXRpb24veGNhcC1lbCt4bWxcIjpbXCJ4ZWxcIl0sXCJhcHBsaWNhdGlvbi94Y2FwLW5zK3htbFwiOltcInhuc1wiXSxcImFwcGxpY2F0aW9uL3hlbmMreG1sXCI6W1wieGVuY1wiXSxcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiOltcInhodG1sXCIsXCJ4aHRcIl0sXCJhcHBsaWNhdGlvbi94bGlmZit4bWxcIjpbXCJ4bGZcIl0sXCJhcHBsaWNhdGlvbi94bWxcIjpbXCJ4bWxcIixcInhzbFwiLFwieHNkXCIsXCJybmdcIl0sXCJhcHBsaWNhdGlvbi94bWwtZHRkXCI6W1wiZHRkXCJdLFwiYXBwbGljYXRpb24veG9wK3htbFwiOltcInhvcFwiXSxcImFwcGxpY2F0aW9uL3hwcm9jK3htbFwiOltcInhwbFwiXSxcImFwcGxpY2F0aW9uL3hzbHQreG1sXCI6W1wiKnhzbFwiLFwieHNsdFwiXSxcImFwcGxpY2F0aW9uL3hzcGYreG1sXCI6W1wieHNwZlwiXSxcImFwcGxpY2F0aW9uL3h2K3htbFwiOltcIm14bWxcIixcInhodm1sXCIsXCJ4dm1sXCIsXCJ4dm1cIl0sXCJhcHBsaWNhdGlvbi95YW5nXCI6W1wieWFuZ1wiXSxcImFwcGxpY2F0aW9uL3lpbit4bWxcIjpbXCJ5aW5cIl0sXCJhcHBsaWNhdGlvbi96aXBcIjpbXCJ6aXBcIl0sXCJhdWRpby8zZ3BwXCI6W1wiKjNncHBcIl0sXCJhdWRpby9hZHBjbVwiOltcImFkcFwiXSxcImF1ZGlvL2FtclwiOltcImFtclwiXSxcImF1ZGlvL2Jhc2ljXCI6W1wiYXVcIixcInNuZFwiXSxcImF1ZGlvL21pZGlcIjpbXCJtaWRcIixcIm1pZGlcIixcImthclwiLFwicm1pXCJdLFwiYXVkaW8vbW9iaWxlLXhtZlwiOltcIm14bWZcIl0sXCJhdWRpby9tcDNcIjpbXCIqbXAzXCJdLFwiYXVkaW8vbXA0XCI6W1wibTRhXCIsXCJtcDRhXCJdLFwiYXVkaW8vbXBlZ1wiOltcIm1wZ2FcIixcIm1wMlwiLFwibXAyYVwiLFwibXAzXCIsXCJtMmFcIixcIm0zYVwiXSxcImF1ZGlvL29nZ1wiOltcIm9nYVwiLFwib2dnXCIsXCJzcHhcIixcIm9wdXNcIl0sXCJhdWRpby9zM21cIjpbXCJzM21cIl0sXCJhdWRpby9zaWxrXCI6W1wic2lsXCJdLFwiYXVkaW8vd2F2XCI6W1wid2F2XCJdLFwiYXVkaW8vd2F2ZVwiOltcIip3YXZcIl0sXCJhdWRpby93ZWJtXCI6W1wid2ViYVwiXSxcImF1ZGlvL3htXCI6W1wieG1cIl0sXCJmb250L2NvbGxlY3Rpb25cIjpbXCJ0dGNcIl0sXCJmb250L290ZlwiOltcIm90ZlwiXSxcImZvbnQvdHRmXCI6W1widHRmXCJdLFwiZm9udC93b2ZmXCI6W1wid29mZlwiXSxcImZvbnQvd29mZjJcIjpbXCJ3b2ZmMlwiXSxcImltYWdlL2FjZXNcIjpbXCJleHJcIl0sXCJpbWFnZS9hcG5nXCI6W1wiYXBuZ1wiXSxcImltYWdlL2F2aWZcIjpbXCJhdmlmXCJdLFwiaW1hZ2UvYm1wXCI6W1wiYm1wXCJdLFwiaW1hZ2UvY2dtXCI6W1wiY2dtXCJdLFwiaW1hZ2UvZGljb20tcmxlXCI6W1wiZHJsZVwiXSxcImltYWdlL2VtZlwiOltcImVtZlwiXSxcImltYWdlL2ZpdHNcIjpbXCJmaXRzXCJdLFwiaW1hZ2UvZzNmYXhcIjpbXCJnM1wiXSxcImltYWdlL2dpZlwiOltcImdpZlwiXSxcImltYWdlL2hlaWNcIjpbXCJoZWljXCJdLFwiaW1hZ2UvaGVpYy1zZXF1ZW5jZVwiOltcImhlaWNzXCJdLFwiaW1hZ2UvaGVpZlwiOltcImhlaWZcIl0sXCJpbWFnZS9oZWlmLXNlcXVlbmNlXCI6W1wiaGVpZnNcIl0sXCJpbWFnZS9oZWoya1wiOltcImhlajJcIl0sXCJpbWFnZS9oc2oyXCI6W1wiaHNqMlwiXSxcImltYWdlL2llZlwiOltcImllZlwiXSxcImltYWdlL2psc1wiOltcImpsc1wiXSxcImltYWdlL2pwMlwiOltcImpwMlwiLFwianBnMlwiXSxcImltYWdlL2pwZWdcIjpbXCJqcGVnXCIsXCJqcGdcIixcImpwZVwiXSxcImltYWdlL2pwaFwiOltcImpwaFwiXSxcImltYWdlL2pwaGNcIjpbXCJqaGNcIl0sXCJpbWFnZS9qcG1cIjpbXCJqcG1cIl0sXCJpbWFnZS9qcHhcIjpbXCJqcHhcIixcImpwZlwiXSxcImltYWdlL2p4clwiOltcImp4clwiXSxcImltYWdlL2p4cmFcIjpbXCJqeHJhXCJdLFwiaW1hZ2Uvanhyc1wiOltcImp4cnNcIl0sXCJpbWFnZS9qeHNcIjpbXCJqeHNcIl0sXCJpbWFnZS9qeHNjXCI6W1wianhzY1wiXSxcImltYWdlL2p4c2lcIjpbXCJqeHNpXCJdLFwiaW1hZ2Uvanhzc1wiOltcImp4c3NcIl0sXCJpbWFnZS9rdHhcIjpbXCJrdHhcIl0sXCJpbWFnZS9rdHgyXCI6W1wia3R4MlwiXSxcImltYWdlL3BuZ1wiOltcInBuZ1wiXSxcImltYWdlL3NnaVwiOltcInNnaVwiXSxcImltYWdlL3N2Zyt4bWxcIjpbXCJzdmdcIixcInN2Z3pcIl0sXCJpbWFnZS90MzhcIjpbXCJ0MzhcIl0sXCJpbWFnZS90aWZmXCI6W1widGlmXCIsXCJ0aWZmXCJdLFwiaW1hZ2UvdGlmZi1meFwiOltcInRmeFwiXSxcImltYWdlL3dlYnBcIjpbXCJ3ZWJwXCJdLFwiaW1hZ2Uvd21mXCI6W1wid21mXCJdLFwibWVzc2FnZS9kaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIjpbXCJkaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIl0sXCJtZXNzYWdlL2dsb2JhbFwiOltcInU4bXNnXCJdLFwibWVzc2FnZS9nbG9iYWwtZGVsaXZlcnktc3RhdHVzXCI6W1widThkc25cIl0sXCJtZXNzYWdlL2dsb2JhbC1kaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIjpbXCJ1OG1kblwiXSxcIm1lc3NhZ2UvZ2xvYmFsLWhlYWRlcnNcIjpbXCJ1OGhkclwiXSxcIm1lc3NhZ2UvcmZjODIyXCI6W1wiZW1sXCIsXCJtaW1lXCJdLFwibW9kZWwvM21mXCI6W1wiM21mXCJdLFwibW9kZWwvZ2x0Zitqc29uXCI6W1wiZ2x0ZlwiXSxcIm1vZGVsL2dsdGYtYmluYXJ5XCI6W1wiZ2xiXCJdLFwibW9kZWwvaWdlc1wiOltcImlnc1wiLFwiaWdlc1wiXSxcIm1vZGVsL21lc2hcIjpbXCJtc2hcIixcIm1lc2hcIixcInNpbG9cIl0sXCJtb2RlbC9tdGxcIjpbXCJtdGxcIl0sXCJtb2RlbC9vYmpcIjpbXCJvYmpcIl0sXCJtb2RlbC9zdGVwK3htbFwiOltcInN0cHhcIl0sXCJtb2RlbC9zdGVwK3ppcFwiOltcInN0cHpcIl0sXCJtb2RlbC9zdGVwLXhtbCt6aXBcIjpbXCJzdHB4elwiXSxcIm1vZGVsL3N0bFwiOltcInN0bFwiXSxcIm1vZGVsL3ZybWxcIjpbXCJ3cmxcIixcInZybWxcIl0sXCJtb2RlbC94M2QrYmluYXJ5XCI6W1wiKngzZGJcIixcIngzZGJ6XCJdLFwibW9kZWwveDNkK2Zhc3RpbmZvc2V0XCI6W1wieDNkYlwiXSxcIm1vZGVsL3gzZCt2cm1sXCI6W1wiKngzZHZcIixcIngzZHZ6XCJdLFwibW9kZWwveDNkK3htbFwiOltcIngzZFwiLFwieDNkelwiXSxcIm1vZGVsL3gzZC12cm1sXCI6W1wieDNkdlwiXSxcInRleHQvY2FjaGUtbWFuaWZlc3RcIjpbXCJhcHBjYWNoZVwiLFwibWFuaWZlc3RcIl0sXCJ0ZXh0L2NhbGVuZGFyXCI6W1wiaWNzXCIsXCJpZmJcIl0sXCJ0ZXh0L2NvZmZlZXNjcmlwdFwiOltcImNvZmZlZVwiLFwibGl0Y29mZmVlXCJdLFwidGV4dC9jc3NcIjpbXCJjc3NcIl0sXCJ0ZXh0L2NzdlwiOltcImNzdlwiXSxcInRleHQvaHRtbFwiOltcImh0bWxcIixcImh0bVwiLFwic2h0bWxcIl0sXCJ0ZXh0L2phZGVcIjpbXCJqYWRlXCJdLFwidGV4dC9qc3hcIjpbXCJqc3hcIl0sXCJ0ZXh0L2xlc3NcIjpbXCJsZXNzXCJdLFwidGV4dC9tYXJrZG93blwiOltcIm1hcmtkb3duXCIsXCJtZFwiXSxcInRleHQvbWF0aG1sXCI6W1wibW1sXCJdLFwidGV4dC9tZHhcIjpbXCJtZHhcIl0sXCJ0ZXh0L24zXCI6W1wibjNcIl0sXCJ0ZXh0L3BsYWluXCI6W1widHh0XCIsXCJ0ZXh0XCIsXCJjb25mXCIsXCJkZWZcIixcImxpc3RcIixcImxvZ1wiLFwiaW5cIixcImluaVwiXSxcInRleHQvcmljaHRleHRcIjpbXCJydHhcIl0sXCJ0ZXh0L3J0ZlwiOltcIipydGZcIl0sXCJ0ZXh0L3NnbWxcIjpbXCJzZ21sXCIsXCJzZ21cIl0sXCJ0ZXh0L3NoZXhcIjpbXCJzaGV4XCJdLFwidGV4dC9zbGltXCI6W1wic2xpbVwiLFwic2xtXCJdLFwidGV4dC9zcGR4XCI6W1wic3BkeFwiXSxcInRleHQvc3R5bHVzXCI6W1wic3R5bHVzXCIsXCJzdHlsXCJdLFwidGV4dC90YWItc2VwYXJhdGVkLXZhbHVlc1wiOltcInRzdlwiXSxcInRleHQvdHJvZmZcIjpbXCJ0XCIsXCJ0clwiLFwicm9mZlwiLFwibWFuXCIsXCJtZVwiLFwibXNcIl0sXCJ0ZXh0L3R1cnRsZVwiOltcInR0bFwiXSxcInRleHQvdXJpLWxpc3RcIjpbXCJ1cmlcIixcInVyaXNcIixcInVybHNcIl0sXCJ0ZXh0L3ZjYXJkXCI6W1widmNhcmRcIl0sXCJ0ZXh0L3Z0dFwiOltcInZ0dFwiXSxcInRleHQveG1sXCI6W1wiKnhtbFwiXSxcInRleHQveWFtbFwiOltcInlhbWxcIixcInltbFwiXSxcInZpZGVvLzNncHBcIjpbXCIzZ3BcIixcIjNncHBcIl0sXCJ2aWRlby8zZ3BwMlwiOltcIjNnMlwiXSxcInZpZGVvL2gyNjFcIjpbXCJoMjYxXCJdLFwidmlkZW8vaDI2M1wiOltcImgyNjNcIl0sXCJ2aWRlby9oMjY0XCI6W1wiaDI2NFwiXSxcInZpZGVvL2lzby5zZWdtZW50XCI6W1wibTRzXCJdLFwidmlkZW8vanBlZ1wiOltcImpwZ3ZcIl0sXCJ2aWRlby9qcG1cIjpbXCIqanBtXCIsXCJqcGdtXCJdLFwidmlkZW8vbWoyXCI6W1wibWoyXCIsXCJtanAyXCJdLFwidmlkZW8vbXAydFwiOltcInRzXCJdLFwidmlkZW8vbXA0XCI6W1wibXA0XCIsXCJtcDR2XCIsXCJtcGc0XCJdLFwidmlkZW8vbXBlZ1wiOltcIm1wZWdcIixcIm1wZ1wiLFwibXBlXCIsXCJtMXZcIixcIm0ydlwiXSxcInZpZGVvL29nZ1wiOltcIm9ndlwiXSxcInZpZGVvL3F1aWNrdGltZVwiOltcInF0XCIsXCJtb3ZcIl0sXCJ2aWRlby93ZWJtXCI6W1wid2VibVwiXX07IiwiLyoqXG4gICMgbm9ybWFsaWNlXG5cbiAgTm9ybWFsaXplIGFuIGljZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiBvYmplY3QgKG9yIHBsYWluIG9sZCBzdHJpbmcpIGludG8gYSBmb3JtYXRcbiAgdGhhdCBpcyB1c2FibGUgaW4gYWxsIGJyb3dzZXJzIHN1cHBvcnRpbmcgV2ViUlRDLiAgUHJpbWFyaWx5IHRoaXMgbW9kdWxlIGlzIGRlc2lnbmVkXG4gIHRvIGhlbHAgd2l0aCB0aGUgdHJhbnNpdGlvbiBvZiB0aGUgYHVybGAgYXR0cmlidXRlIG9mIHRoZSBjb25maWd1cmF0aW9uIG9iamVjdCB0b1xuICB0aGUgYHVybHNgIGF0dHJpYnV0ZS5cblxuICAjIyBFeGFtcGxlIFVzYWdlXG5cbiAgPDw8IGV4YW1wbGVzL3NpbXBsZS5qc1xuXG4qKi9cblxudmFyIHByb3RvY29scyA9IFtcbiAgJ3N0dW46JyxcbiAgJ3R1cm46J1xuXTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpbnB1dCkge1xuICB2YXIgdXJsID0gKGlucHV0IHx8IHt9KS51cmwgfHwgaW5wdXQ7XG4gIHZhciBwcm90b2NvbDtcbiAgdmFyIHBhcnRzO1xuICB2YXIgb3V0cHV0ID0ge307XG5cbiAgLy8gaWYgd2UgZG9uJ3QgaGF2ZSBhIHN0cmluZyB1cmwsIHRoZW4gYWxsb3cgdGhlIGlucHV0IHRvIHBhc3N0aHJvdWdoXG4gIGlmICh0eXBlb2YgdXJsICE9ICdzdHJpbmcnICYmICghICh1cmwgaW5zdGFuY2VvZiBTdHJpbmcpKSkge1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuXG4gIC8vIHRyaW0gdGhlIHVybCBzdHJpbmcsIGFuZCBjb252ZXJ0IHRvIGFuIGFycmF5XG4gIHVybCA9IHVybC50cmltKCk7XG5cbiAgLy8gaWYgdGhlIHByb3RvY29sIGlzIG5vdCBrbm93biwgdGhlbiBwYXNzdGhyb3VnaFxuICBwcm90b2NvbCA9IHByb3RvY29sc1twcm90b2NvbHMuaW5kZXhPZih1cmwuc2xpY2UoMCwgNSkpXTtcbiAgaWYgKCEgcHJvdG9jb2wpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyBub3cgbGV0J3MgYXR0YWNrIHRoZSByZW1haW5pbmcgdXJsIHBhcnRzXG4gIHVybCA9IHVybC5zbGljZSg1KTtcbiAgcGFydHMgPSB1cmwuc3BsaXQoJ0AnKTtcblxuICBvdXRwdXQudXNlcm5hbWUgPSBpbnB1dC51c2VybmFtZTtcbiAgb3V0cHV0LmNyZWRlbnRpYWwgPSBpbnB1dC5jcmVkZW50aWFsO1xuICAvLyBpZiB3ZSBoYXZlIGFuIGF1dGhlbnRpY2F0aW9uIHBhcnQsIHRoZW4gc2V0IHRoZSBjcmVkZW50aWFsc1xuICBpZiAocGFydHMubGVuZ3RoID4gMSkge1xuICAgIHVybCA9IHBhcnRzWzFdO1xuICAgIHBhcnRzID0gcGFydHNbMF0uc3BsaXQoJzonKTtcblxuICAgIC8vIGFkZCB0aGUgb3V0cHV0IGNyZWRlbnRpYWwgYW5kIHVzZXJuYW1lXG4gICAgb3V0cHV0LnVzZXJuYW1lID0gcGFydHNbMF07XG4gICAgb3V0cHV0LmNyZWRlbnRpYWwgPSAoaW5wdXQgfHwge30pLmNyZWRlbnRpYWwgfHwgcGFydHNbMV0gfHwgJyc7XG4gIH1cblxuICBvdXRwdXQudXJsID0gcHJvdG9jb2wgKyB1cmw7XG4gIG91dHB1dC51cmxzID0gWyBvdXRwdXQudXJsIF07XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG4iLCIvKiFcbiAqIFBsYXRmb3JtLmpzIHYxLjMuNlxuICogQ29weXJpZ2h0IDIwMTQtMjAyMCBCZW5qYW1pbiBUYW5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b25cbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZVxuICovXG47KGZ1bmN0aW9uKCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHZhbHVlcyBhcmUgb2YgdGhlIGxhbmd1YWdlIHR5cGUgYE9iamVjdGAuICovXG4gIHZhciBvYmplY3RUeXBlcyA9IHtcbiAgICAnZnVuY3Rpb24nOiB0cnVlLFxuICAgICdvYmplY3QnOiB0cnVlXG4gIH07XG5cbiAgLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciByb290ID0gKG9iamVjdFR5cGVzW3R5cGVvZiB3aW5kb3ddICYmIHdpbmRvdykgfHwgdGhpcztcblxuICAvKiogQmFja3VwIHBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciBvbGRSb290ID0gcm9vdDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xuICB2YXIgZnJlZUV4cG9ydHMgPSBvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0c10gJiYgZXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG4gIHZhciBmcmVlTW9kdWxlID0gb2JqZWN0VHlwZXNbdHlwZW9mIG1vZHVsZV0gJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMgb3IgQnJvd3NlcmlmaWVkIGNvZGUgYW5kIHVzZSBpdCBhcyBgcm9vdGAuICovXG4gIHZhciBmcmVlR2xvYmFsID0gZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSAmJiB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcbiAgaWYgKGZyZWVHbG9iYWwgJiYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwuc2VsZiA9PT0gZnJlZUdsb2JhbCkpIHtcbiAgICByb290ID0gZnJlZUdsb2JhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGFzIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbiBhcnJheS1saWtlIG9iamVjdC5cbiAgICogU2VlIHRoZSBbRVM2IHNwZWNdKGh0dHA6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLXRvbGVuZ3RoKVxuICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgKi9cbiAgdmFyIG1heFNhZmVJbnRlZ2VyID0gTWF0aC5wb3coMiwgNTMpIC0gMTtcblxuICAvKiogUmVndWxhciBleHByZXNzaW9uIHRvIGRldGVjdCBPcGVyYS4gKi9cbiAgdmFyIHJlT3BlcmEgPSAvXFxiT3BlcmEvO1xuXG4gIC8qKiBQb3NzaWJsZSBnbG9iYWwgb2JqZWN0LiAqL1xuICB2YXIgdGhpc0JpbmRpbmcgPSB0aGlzO1xuXG4gIC8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG4gIHZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbiAgLyoqIFVzZWQgdG8gY2hlY2sgZm9yIG93biBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdC4gKi9cbiAgdmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgaW50ZXJuYWwgYFtbQ2xhc3NdXWAgb2YgdmFsdWVzLiAqL1xuICB2YXIgdG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ2FwaXRhbGl6ZXMgYSBzdHJpbmcgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjYXBpdGFsaXplLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY2FwaXRhbGl6ZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gY2FwaXRhbGl6ZShzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSBTdHJpbmcoc3RyaW5nKTtcbiAgICByZXR1cm4gc3RyaW5nLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyaW5nLnNsaWNlKDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgdXRpbGl0eSBmdW5jdGlvbiB0byBjbGVhbiB1cCB0aGUgT1MgbmFtZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9zIFRoZSBPUyBuYW1lIHRvIGNsZWFuIHVwLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhdHRlcm5dIEEgYFJlZ0V4cGAgcGF0dGVybiBtYXRjaGluZyB0aGUgT1MgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsYWJlbF0gQSBsYWJlbCBmb3IgdGhlIE9TLlxuICAgKi9cbiAgZnVuY3Rpb24gY2xlYW51cE9TKG9zLCBwYXR0ZXJuLCBsYWJlbCkge1xuICAgIC8vIFBsYXRmb3JtIHRva2VucyBhcmUgZGVmaW5lZCBhdDpcbiAgICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1Mzc1MDMoVlMuODUpLmFzcHhcbiAgICAvLyBodHRwOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDA4MTEyMjA1Mzk1MC9odHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1Mzc1MDMoVlMuODUpLmFzcHhcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgICcxMC4wJzogJzEwJyxcbiAgICAgICc2LjQnOiAgJzEwIFRlY2huaWNhbCBQcmV2aWV3JyxcbiAgICAgICc2LjMnOiAgJzguMScsXG4gICAgICAnNi4yJzogICc4JyxcbiAgICAgICc2LjEnOiAgJ1NlcnZlciAyMDA4IFIyIC8gNycsXG4gICAgICAnNi4wJzogICdTZXJ2ZXIgMjAwOCAvIFZpc3RhJyxcbiAgICAgICc1LjInOiAgJ1NlcnZlciAyMDAzIC8gWFAgNjQtYml0JyxcbiAgICAgICc1LjEnOiAgJ1hQJyxcbiAgICAgICc1LjAxJzogJzIwMDAgU1AxJyxcbiAgICAgICc1LjAnOiAgJzIwMDAnLFxuICAgICAgJzQuMCc6ICAnTlQnLFxuICAgICAgJzQuOTAnOiAnTUUnXG4gICAgfTtcbiAgICAvLyBEZXRlY3QgV2luZG93cyB2ZXJzaW9uIGZyb20gcGxhdGZvcm0gdG9rZW5zLlxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsICYmIC9eV2luL2kudGVzdChvcykgJiYgIS9eV2luZG93cyBQaG9uZSAvaS50ZXN0KG9zKSAmJlxuICAgICAgICAoZGF0YSA9IGRhdGFbL1tcXGQuXSskLy5leGVjKG9zKV0pKSB7XG4gICAgICBvcyA9ICdXaW5kb3dzICcgKyBkYXRhO1xuICAgIH1cbiAgICAvLyBDb3JyZWN0IGNoYXJhY3RlciBjYXNlIGFuZCBjbGVhbnVwIHN0cmluZy5cbiAgICBvcyA9IFN0cmluZyhvcyk7XG5cbiAgICBpZiAocGF0dGVybiAmJiBsYWJlbCkge1xuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cChwYXR0ZXJuLCAnaScpLCBsYWJlbCk7XG4gICAgfVxuXG4gICAgb3MgPSBmb3JtYXQoXG4gICAgICBvcy5yZXBsYWNlKC8gY2UkL2ksICcgQ0UnKVxuICAgICAgICAucmVwbGFjZSgvXFxiaHB3L2ksICd3ZWInKVxuICAgICAgICAucmVwbGFjZSgvXFxiTWFjaW50b3NoXFxiLywgJ01hYyBPUycpXG4gICAgICAgIC5yZXBsYWNlKC9fUG93ZXJQQ1xcYi9pLCAnIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihPUyBYKSBbXiBcXGRdKy9pLCAnJDEnKVxuICAgICAgICAucmVwbGFjZSgvXFxiTWFjIChPUyBYKVxcYi8sICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXC8oXFxkKS8sICcgJDEnKVxuICAgICAgICAucmVwbGFjZSgvXy9nLCAnLicpXG4gICAgICAgIC5yZXBsYWNlKC8oPzogQmVQQ3xbIC5dKmZjWyBcXGQuXSspJC9pLCAnJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYng4NlxcLjY0XFxiL2dpLCAneDg2XzY0JylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihXaW5kb3dzIFBob25lKSBPU1xcYi8sICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGIoQ2hyb21lIE9TIFxcdyspIFtcXGQuXStcXGIvLCAnJDEnKVxuICAgICAgICAuc3BsaXQoJyBvbiAnKVswXVxuICAgICk7XG5cbiAgICByZXR1cm4gb3M7XG4gIH1cblxuICAvKipcbiAgICogQW4gaXRlcmF0aW9uIHV0aWxpdHkgZm9yIGFycmF5cyBhbmQgb2JqZWN0cy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gZWFjaChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG9iamVjdCA/IG9iamVjdC5sZW5ndGggOiAwO1xuXG4gICAgaWYgKHR5cGVvZiBsZW5ndGggPT0gJ251bWJlcicgJiYgbGVuZ3RoID4gLTEgJiYgbGVuZ3RoIDw9IG1heFNhZmVJbnRlZ2VyKSB7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjYWxsYmFjayhvYmplY3RbaW5kZXhdLCBpbmRleCwgb2JqZWN0KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yT3duKG9iamVjdCwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmltIGFuZCBjb25kaXRpb25hbGx5IGNhcGl0YWxpemUgc3RyaW5nIHZhbHVlcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGZvcm1hdC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGZvcm1hdHRlZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBmb3JtYXQoc3RyaW5nKSB7XG4gICAgc3RyaW5nID0gdHJpbShzdHJpbmcpO1xuICAgIHJldHVybiAvXig/OndlYk9TfGkoPzpPU3xQKSkvLnRlc3Qoc3RyaW5nKVxuICAgICAgPyBzdHJpbmdcbiAgICAgIDogY2FwaXRhbGl6ZShzdHJpbmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGVzIG92ZXIgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMsIGV4ZWN1dGluZyB0aGUgYGNhbGxiYWNrYCBmb3IgZWFjaC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGV4ZWN1dGVkIHBlciBvd24gcHJvcGVydHkuXG4gICAqL1xuICBmdW5jdGlvbiBmb3JPd24ob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgICBjYWxsYmFjayhvYmplY3Rba2V5XSwga2V5LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiBhIHZhbHVlLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGBbW0NsYXNzXV1gLlxuICAgKi9cbiAgZnVuY3Rpb24gZ2V0Q2xhc3NPZih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PSBudWxsXG4gICAgICA/IGNhcGl0YWxpemUodmFsdWUpXG4gICAgICA6IHRvU3RyaW5nLmNhbGwodmFsdWUpLnNsaWNlKDgsIC0xKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb3N0IG9iamVjdHMgY2FuIHJldHVybiB0eXBlIHZhbHVlcyB0aGF0IGFyZSBkaWZmZXJlbnQgZnJvbSB0aGVpciBhY3R1YWxcbiAgICogZGF0YSB0eXBlLiBUaGUgb2JqZWN0cyB3ZSBhcmUgY29uY2VybmVkIHdpdGggdXN1YWxseSByZXR1cm4gbm9uLXByaW1pdGl2ZVxuICAgKiB0eXBlcyBvZiBcIm9iamVjdFwiLCBcImZ1bmN0aW9uXCIsIG9yIFwidW5rbm93blwiLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgb3duZXIgb2YgdGhlIHByb3BlcnR5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHkgVGhlIHByb3BlcnR5IHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3BlcnR5IHZhbHVlIGlzIGEgbm9uLXByaW1pdGl2ZSwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaXNIb3N0VHlwZShvYmplY3QsIHByb3BlcnR5KSB7XG4gICAgdmFyIHR5cGUgPSBvYmplY3QgIT0gbnVsbCA/IHR5cGVvZiBvYmplY3RbcHJvcGVydHldIDogJ251bWJlcic7XG4gICAgcmV0dXJuICEvXig/OmJvb2xlYW58bnVtYmVyfHN0cmluZ3x1bmRlZmluZWQpJC8udGVzdCh0eXBlKSAmJlxuICAgICAgKHR5cGUgPT0gJ29iamVjdCcgPyAhIW9iamVjdFtwcm9wZXJ0eV0gOiB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVwYXJlcyBhIHN0cmluZyBmb3IgdXNlIGluIGEgYFJlZ0V4cGAgYnkgbWFraW5nIGh5cGhlbnMgYW5kIHNwYWNlcyBvcHRpb25hbC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHF1YWxpZnkuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBxdWFsaWZpZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gcXVhbGlmeShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvKFsgLV0pKD8hJCkvZywgJyQxPycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgYmFyZS1ib25lcyBgQXJyYXkjcmVkdWNlYCBsaWtlIHV0aWxpdHkgZnVuY3Rpb24uXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiBjYWxsZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMgeyp9IFRoZSBhY2N1bXVsYXRlZCByZXN1bHQuXG4gICAqL1xuICBmdW5jdGlvbiByZWR1Y2UoYXJyYXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIGFjY3VtdWxhdG9yID0gbnVsbDtcbiAgICBlYWNoKGFycmF5LCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gY2FsbGJhY2soYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgYXJyYXkpO1xuICAgIH0pO1xuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBhIHN0cmluZy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0cmltbWVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIHRyaW0oc3RyaW5nKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzdHJpbmcpLnJlcGxhY2UoL14gK3wgKyQvZywgJycpO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgcGxhdGZvcm0gb2JqZWN0LlxuICAgKlxuICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICogQHBhcmFtIHtPYmplY3R8c3RyaW5nfSBbdWE9bmF2aWdhdG9yLnVzZXJBZ2VudF0gVGhlIHVzZXIgYWdlbnQgc3RyaW5nIG9yXG4gICAqICBjb250ZXh0IG9iamVjdC5cbiAgICogQHJldHVybnMge09iamVjdH0gQSBwbGF0Zm9ybSBvYmplY3QuXG4gICAqL1xuICBmdW5jdGlvbiBwYXJzZSh1YSkge1xuXG4gICAgLyoqIFRoZSBlbnZpcm9ubWVudCBjb250ZXh0IG9iamVjdC4gKi9cbiAgICB2YXIgY29udGV4dCA9IHJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBmbGFnIHdoZW4gYSBjdXN0b20gY29udGV4dCBpcyBwcm92aWRlZC4gKi9cbiAgICB2YXIgaXNDdXN0b21Db250ZXh0ID0gdWEgJiYgdHlwZW9mIHVhID09ICdvYmplY3QnICYmIGdldENsYXNzT2YodWEpICE9ICdTdHJpbmcnO1xuXG4gICAgLy8gSnVnZ2xlIGFyZ3VtZW50cy5cbiAgICBpZiAoaXNDdXN0b21Db250ZXh0KSB7XG4gICAgICBjb250ZXh0ID0gdWE7XG4gICAgICB1YSA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqIEJyb3dzZXIgbmF2aWdhdG9yIG9iamVjdC4gKi9cbiAgICB2YXIgbmF2ID0gY29udGV4dC5uYXZpZ2F0b3IgfHwge307XG5cbiAgICAvKiogQnJvd3NlciB1c2VyIGFnZW50IHN0cmluZy4gKi9cbiAgICB2YXIgdXNlckFnZW50ID0gbmF2LnVzZXJBZ2VudCB8fCAnJztcblxuICAgIHVhIHx8ICh1YSA9IHVzZXJBZ2VudCk7XG5cbiAgICAvKiogVXNlZCB0byBmbGFnIHdoZW4gYHRoaXNCaW5kaW5nYCBpcyB0aGUgW01vZHVsZVNjb3BlXS4gKi9cbiAgICB2YXIgaXNNb2R1bGVTY29wZSA9IGlzQ3VzdG9tQ29udGV4dCB8fCB0aGlzQmluZGluZyA9PSBvbGRSb290O1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGJyb3dzZXIgaXMgbGlrZSBDaHJvbWUuICovXG4gICAgdmFyIGxpa2VDaHJvbWUgPSBpc0N1c3RvbUNvbnRleHRcbiAgICAgID8gISFuYXYubGlrZUNocm9tZVxuICAgICAgOiAvXFxiQ2hyb21lXFxiLy50ZXN0KHVhKSAmJiAhL2ludGVybmFsfFxcbi9pLnRlc3QodG9TdHJpbmcudG9TdHJpbmcoKSk7XG5cbiAgICAvKiogSW50ZXJuYWwgYFtbQ2xhc3NdXWAgdmFsdWUgc2hvcnRjdXRzLiAqL1xuICAgIHZhciBvYmplY3RDbGFzcyA9ICdPYmplY3QnLFxuICAgICAgICBhaXJSdW50aW1lQ2xhc3MgPSBpc0N1c3RvbUNvbnRleHQgPyBvYmplY3RDbGFzcyA6ICdTY3JpcHRCcmlkZ2luZ1Byb3h5T2JqZWN0JyxcbiAgICAgICAgZW52aXJvQ2xhc3MgPSBpc0N1c3RvbUNvbnRleHQgPyBvYmplY3RDbGFzcyA6ICdFbnZpcm9ubWVudCcsXG4gICAgICAgIGphdmFDbGFzcyA9IChpc0N1c3RvbUNvbnRleHQgJiYgY29udGV4dC5qYXZhKSA/ICdKYXZhUGFja2FnZScgOiBnZXRDbGFzc09mKGNvbnRleHQuamF2YSksXG4gICAgICAgIHBoYW50b21DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1J1bnRpbWVPYmplY3QnO1xuXG4gICAgLyoqIERldGVjdCBKYXZhIGVudmlyb25tZW50cy4gKi9cbiAgICB2YXIgamF2YSA9IC9cXGJKYXZhLy50ZXN0KGphdmFDbGFzcykgJiYgY29udGV4dC5qYXZhO1xuXG4gICAgLyoqIERldGVjdCBSaGluby4gKi9cbiAgICB2YXIgcmhpbm8gPSBqYXZhICYmIGdldENsYXNzT2YoY29udGV4dC5lbnZpcm9ubWVudCkgPT0gZW52aXJvQ2xhc3M7XG5cbiAgICAvKiogQSBjaGFyYWN0ZXIgdG8gcmVwcmVzZW50IGFscGhhLiAqL1xuICAgIHZhciBhbHBoYSA9IGphdmEgPyAnYScgOiAnXFx1MDNiMSc7XG5cbiAgICAvKiogQSBjaGFyYWN0ZXIgdG8gcmVwcmVzZW50IGJldGEuICovXG4gICAgdmFyIGJldGEgPSBqYXZhID8gJ2InIDogJ1xcdTAzYjInO1xuXG4gICAgLyoqIEJyb3dzZXIgZG9jdW1lbnQgb2JqZWN0LiAqL1xuICAgIHZhciBkb2MgPSBjb250ZXh0LmRvY3VtZW50IHx8IHt9O1xuXG4gICAgLyoqXG4gICAgICogRGV0ZWN0IE9wZXJhIGJyb3dzZXIgKFByZXN0by1iYXNlZCkuXG4gICAgICogaHR0cDovL3d3dy5ob3d0b2NyZWF0ZS5jby51ay9vcGVyYVN0dWZmL29wZXJhT2JqZWN0Lmh0bWxcbiAgICAgKiBodHRwOi8vZGV2Lm9wZXJhLmNvbS9hcnRpY2xlcy92aWV3L29wZXJhLW1pbmktd2ViLWNvbnRlbnQtYXV0aG9yaW5nLWd1aWRlbGluZXMvI29wZXJhbWluaVxuICAgICAqL1xuICAgIHZhciBvcGVyYSA9IGNvbnRleHQub3BlcmFtaW5pIHx8IGNvbnRleHQub3BlcmE7XG5cbiAgICAvKiogT3BlcmEgYFtbQ2xhc3NdXWAuICovXG4gICAgdmFyIG9wZXJhQ2xhc3MgPSByZU9wZXJhLnRlc3Qob3BlcmFDbGFzcyA9IChpc0N1c3RvbUNvbnRleHQgJiYgb3BlcmEpID8gb3BlcmFbJ1tbQ2xhc3NdXSddIDogZ2V0Q2xhc3NPZihvcGVyYSkpXG4gICAgICA/IG9wZXJhQ2xhc3NcbiAgICAgIDogKG9wZXJhID0gbnVsbCk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKiogVGVtcG9yYXJ5IHZhcmlhYmxlIHVzZWQgb3ZlciB0aGUgc2NyaXB0J3MgbGlmZXRpbWUuICovXG4gICAgdmFyIGRhdGE7XG5cbiAgICAvKiogVGhlIENQVSBhcmNoaXRlY3R1cmUuICovXG4gICAgdmFyIGFyY2ggPSB1YTtcblxuICAgIC8qKiBQbGF0Zm9ybSBkZXNjcmlwdGlvbiBhcnJheS4gKi9cbiAgICB2YXIgZGVzY3JpcHRpb24gPSBbXTtcblxuICAgIC8qKiBQbGF0Zm9ybSBhbHBoYS9iZXRhIGluZGljYXRvci4gKi9cbiAgICB2YXIgcHJlcmVsZWFzZSA9IG51bGw7XG5cbiAgICAvKiogQSBmbGFnIHRvIGluZGljYXRlIHRoYXQgZW52aXJvbm1lbnQgZmVhdHVyZXMgc2hvdWxkIGJlIHVzZWQgdG8gcmVzb2x2ZSB0aGUgcGxhdGZvcm0uICovXG4gICAgdmFyIHVzZUZlYXR1cmVzID0gdWEgPT0gdXNlckFnZW50O1xuXG4gICAgLyoqIFRoZSBicm93c2VyL2Vudmlyb25tZW50IHZlcnNpb24uICovXG4gICAgdmFyIHZlcnNpb24gPSB1c2VGZWF0dXJlcyAmJiBvcGVyYSAmJiB0eXBlb2Ygb3BlcmEudmVyc2lvbiA9PSAnZnVuY3Rpb24nICYmIG9wZXJhLnZlcnNpb24oKTtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgaWYgdGhlIE9TIGVuZHMgd2l0aCBcIi8gVmVyc2lvblwiICovXG4gICAgdmFyIGlzU3BlY2lhbENhc2VkT1M7XG5cbiAgICAvKiBEZXRlY3RhYmxlIGxheW91dCBlbmdpbmVzIChvcmRlciBpcyBpbXBvcnRhbnQpLiAqL1xuICAgIHZhciBsYXlvdXQgPSBnZXRMYXlvdXQoW1xuICAgICAgeyAnbGFiZWwnOiAnRWRnZUhUTUwnLCAncGF0dGVybic6ICdFZGdlJyB9LFxuICAgICAgJ1RyaWRlbnQnLFxuICAgICAgeyAnbGFiZWwnOiAnV2ViS2l0JywgJ3BhdHRlcm4nOiAnQXBwbGVXZWJLaXQnIH0sXG4gICAgICAnaUNhYicsXG4gICAgICAnUHJlc3RvJyxcbiAgICAgICdOZXRGcm9udCcsXG4gICAgICAnVGFzbWFuJyxcbiAgICAgICdLSFRNTCcsXG4gICAgICAnR2Vja28nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIGJyb3dzZXIgbmFtZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIG5hbWUgPSBnZXROYW1lKFtcbiAgICAgICdBZG9iZSBBSVInLFxuICAgICAgJ0Fyb3JhJyxcbiAgICAgICdBdmFudCBCcm93c2VyJyxcbiAgICAgICdCcmVhY2gnLFxuICAgICAgJ0NhbWlubycsXG4gICAgICAnRWxlY3Ryb24nLFxuICAgICAgJ0VwaXBoYW55JyxcbiAgICAgICdGZW5uZWMnLFxuICAgICAgJ0Zsb2NrJyxcbiAgICAgICdHYWxlb24nLFxuICAgICAgJ0dyZWVuQnJvd3NlcicsXG4gICAgICAnaUNhYicsXG4gICAgICAnSWNld2Vhc2VsJyxcbiAgICAgICdLLU1lbGVvbicsXG4gICAgICAnS29ucXVlcm9yJyxcbiAgICAgICdMdW5hc2NhcGUnLFxuICAgICAgJ01heHRob24nLFxuICAgICAgeyAnbGFiZWwnOiAnTWljcm9zb2Z0IEVkZ2UnLCAncGF0dGVybic6ICcoPzpFZGdlfEVkZ3xFZGdBfEVkZ2lPUyknIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdWaXZhbGRpJyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWWFuZGV4IEJyb3dzZXInLCAncGF0dGVybic6ICdZYUJyb3dzZXInIH0sXG4gICAgICB7ICdsYWJlbCc6ICdVQyBCcm93c2VyJywgJ3BhdHRlcm4nOiAnVUNCcm93c2VyJyB9LFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9taXVtJyxcbiAgICAgICdDaHJvbWUnLFxuICAgICAgeyAnbGFiZWwnOiAnQ2hyb21lJywgJ3BhdHRlcm4nOiAnKD86SGVhZGxlc3NDaHJvbWUpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnQ2hyb21lIE1vYmlsZScsICdwYXR0ZXJuJzogJyg/OkNyaU9TfENyTW8pJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCcsICdwYXR0ZXJuJzogJyg/OkZpcmVmb3h8TWluZWZpZWxkKScgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0ZpcmVmb3ggZm9yIGlPUycsICdwYXR0ZXJuJzogJ0Z4aU9TJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdJRU1vYmlsZScgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0lFJywgJ3BhdHRlcm4nOiAnTVNJRScgfSxcbiAgICAgICdTYWZhcmknXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIHByb2R1Y3RzIChvcmRlciBpcyBpbXBvcnRhbnQpLiAqL1xuICAgIHZhciBwcm9kdWN0ID0gZ2V0UHJvZHVjdChbXG4gICAgICB7ICdsYWJlbCc6ICdCbGFja0JlcnJ5JywgJ3BhdHRlcm4nOiAnQkIxMCcgfSxcbiAgICAgICdCbGFja0JlcnJ5JyxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTJywgJ3BhdHRlcm4nOiAnR1QtSTkwMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzInLCAncGF0dGVybic6ICdHVC1JOTEwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMycsICdwYXR0ZXJuJzogJ0dULUk5MzAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM0JywgJ3BhdHRlcm4nOiAnR1QtSTk1MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzUnLCAncGF0dGVybic6ICdTTS1HOTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2JywgJ3BhdHRlcm4nOiAnU00tRzkyMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNiBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkyNScgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNycsICdwYXR0ZXJuJzogJ1NNLUc5MzAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzcgRWRnZScsICdwYXR0ZXJuJzogJ1NNLUc5MzUnIH0sXG4gICAgICAnR29vZ2xlIFRWJyxcbiAgICAgICdMdW1pYScsXG4gICAgICAnaVBhZCcsXG4gICAgICAnaVBvZCcsXG4gICAgICAnaVBob25lJyxcbiAgICAgICdLaW5kbGUnLFxuICAgICAgeyAnbGFiZWwnOiAnS2luZGxlIEZpcmUnLCAncGF0dGVybic6ICcoPzpDbG91ZDl8U2lsay1BY2NlbGVyYXRlZCknIH0sXG4gICAgICAnTmV4dXMnLFxuICAgICAgJ05vb2snLFxuICAgICAgJ1BsYXlCb29rJyxcbiAgICAgICdQbGF5U3RhdGlvbiBWaXRhJyxcbiAgICAgICdQbGF5U3RhdGlvbicsXG4gICAgICAnVG91Y2hQYWQnLFxuICAgICAgJ1RyYW5zZm9ybWVyJyxcbiAgICAgIHsgJ2xhYmVsJzogJ1dpaSBVJywgJ3BhdHRlcm4nOiAnV2lpVScgfSxcbiAgICAgICdXaWknLFxuICAgICAgJ1hib3ggT25lJyxcbiAgICAgIHsgJ2xhYmVsJzogJ1hib3ggMzYwJywgJ3BhdHRlcm4nOiAnWGJveCcgfSxcbiAgICAgICdYb29tJ1xuICAgIF0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBtYW51ZmFjdHVyZXJzLiAqL1xuICAgIHZhciBtYW51ZmFjdHVyZXIgPSBnZXRNYW51ZmFjdHVyZXIoe1xuICAgICAgJ0FwcGxlJzogeyAnaVBhZCc6IDEsICdpUGhvbmUnOiAxLCAnaVBvZCc6IDEgfSxcbiAgICAgICdBbGNhdGVsJzoge30sXG4gICAgICAnQXJjaG9zJzoge30sXG4gICAgICAnQW1hem9uJzogeyAnS2luZGxlJzogMSwgJ0tpbmRsZSBGaXJlJzogMSB9LFxuICAgICAgJ0FzdXMnOiB7ICdUcmFuc2Zvcm1lcic6IDEgfSxcbiAgICAgICdCYXJuZXMgJiBOb2JsZSc6IHsgJ05vb2snOiAxIH0sXG4gICAgICAnQmxhY2tCZXJyeSc6IHsgJ1BsYXlCb29rJzogMSB9LFxuICAgICAgJ0dvb2dsZSc6IHsgJ0dvb2dsZSBUVic6IDEsICdOZXh1cyc6IDEgfSxcbiAgICAgICdIUCc6IHsgJ1RvdWNoUGFkJzogMSB9LFxuICAgICAgJ0hUQyc6IHt9LFxuICAgICAgJ0h1YXdlaSc6IHt9LFxuICAgICAgJ0xlbm92byc6IHt9LFxuICAgICAgJ0xHJzoge30sXG4gICAgICAnTWljcm9zb2Z0JzogeyAnWGJveCc6IDEsICdYYm94IE9uZSc6IDEgfSxcbiAgICAgICdNb3Rvcm9sYSc6IHsgJ1hvb20nOiAxIH0sXG4gICAgICAnTmludGVuZG8nOiB7ICdXaWkgVSc6IDEsICAnV2lpJzogMSB9LFxuICAgICAgJ05va2lhJzogeyAnTHVtaWEnOiAxIH0sXG4gICAgICAnT3Bwbyc6IHt9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfSxcbiAgICAgICdYaWFvbWknOiB7ICdNaSc6IDEsICdSZWRtaSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnS2FpT1MnLFxuICAgICAgJ0FuZHJvaWQnLFxuICAgICAgJ0NlbnRPUycsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgT1MnLCAncGF0dGVybic6ICdDck9TJyB9LFxuICAgICAgJ0RlYmlhbicsXG4gICAgICB7ICdsYWJlbCc6ICdEcmFnb25GbHkgQlNEJywgJ3BhdHRlcm4nOiAnRHJhZ29uRmx5JyB9LFxuICAgICAgJ0ZlZG9yYScsXG4gICAgICAnRnJlZUJTRCcsXG4gICAgICAnR2VudG9vJyxcbiAgICAgICdIYWlrdScsXG4gICAgICAnS3VidW50dScsXG4gICAgICAnTGludXggTWludCcsXG4gICAgICAnT3BlbkJTRCcsXG4gICAgICAnUmVkIEhhdCcsXG4gICAgICAnU3VTRScsXG4gICAgICAnVWJ1bnR1JyxcbiAgICAgICdYdWJ1bnR1JyxcbiAgICAgICdDeWd3aW4nLFxuICAgICAgJ1N5bWJpYW4gT1MnLFxuICAgICAgJ2hwd09TJyxcbiAgICAgICd3ZWJPUyAnLFxuICAgICAgJ3dlYk9TJyxcbiAgICAgICdUYWJsZXQgT1MnLFxuICAgICAgJ1RpemVuJyxcbiAgICAgICdMaW51eCcsXG4gICAgICAnTWFjIE9TIFgnLFxuICAgICAgJ01hY2ludG9zaCcsXG4gICAgICAnTWFjJyxcbiAgICAgICdXaW5kb3dzIDk4OycsXG4gICAgICAnV2luZG93cyAnXG4gICAgXSk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgbGF5b3V0IGVuZ2luZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBsYXlvdXQgZW5naW5lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldExheW91dChndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBSZWdFeHAoJ1xcXFxiJyArIChcbiAgICAgICAgICBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpXG4gICAgICAgICkgKyAnXFxcXGInLCAnaScpLmV4ZWModWEpICYmIChndWVzcy5sYWJlbCB8fCBndWVzcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgbWFudWZhY3R1cmVyIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBvYmplY3Qgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBtYW51ZmFjdHVyZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TWFudWZhY3R1cmVyKGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICAgIC8vIExvb2t1cCB0aGUgbWFudWZhY3R1cmVyIGJ5IHByb2R1Y3Qgb3Igc2NhbiB0aGUgVUEgZm9yIHRoZSBtYW51ZmFjdHVyZXIuXG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgKFxuICAgICAgICAgIHZhbHVlW3Byb2R1Y3RdIHx8XG4gICAgICAgICAgdmFsdWVbL15bYS16XSsoPzogK1thLXpdK1xcYikqL2kuZXhlYyhwcm9kdWN0KV0gfHxcbiAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHF1YWxpZnkoa2V5KSArICcoPzpcXFxcYnxcXFxcdypcXFxcZCknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICkgJiYga2V5O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGJyb3dzZXIgbmFtZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBicm93c2VyIG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TmFtZShndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBSZWdFeHAoJ1xcXFxiJyArIChcbiAgICAgICAgICBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpXG4gICAgICAgICkgKyAnXFxcXGInLCAnaScpLmV4ZWModWEpICYmIChndWVzcy5sYWJlbCB8fCBndWVzcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgT1MgbmFtZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBPUyBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE9TKGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnKD86L1tcXFxcZC5dK3xbIFxcXFx3Ll0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICByZXN1bHQgPSBjbGVhbnVwT1MocmVzdWx0LCBwYXR0ZXJuLCBndWVzcy5sYWJlbCB8fCBndWVzcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBwcm9kdWN0IG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgcHJvZHVjdCBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFByb2R1Y3QoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHZhciBwYXR0ZXJuID0gZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgKHJlc3VsdCA9XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcgKlxcXFxkK1suXFxcXHdfXSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcgKlxcXFx3Ky1bXFxcXHddKicsICdpJykuZXhlYyh1YSkgfHxcbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/OjsgKig/OlthLXpdK1tfLV0pP1thLXpdK1xcXFxkK3xbXiAoKTstXSopJywgJ2knKS5leGVjKHVhKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIC8vIFNwbGl0IGJ5IGZvcndhcmQgc2xhc2ggYW5kIGFwcGVuZCBwcm9kdWN0IHZlcnNpb24gaWYgbmVlZGVkLlxuICAgICAgICAgIGlmICgocmVzdWx0ID0gU3RyaW5nKChndWVzcy5sYWJlbCAmJiAhUmVnRXhwKHBhdHRlcm4sICdpJykudGVzdChndWVzcy5sYWJlbCkpID8gZ3Vlc3MubGFiZWwgOiByZXN1bHQpLnNwbGl0KCcvJykpWzFdICYmICEvW1xcZC5dKy8udGVzdChyZXN1bHRbMF0pKSB7XG4gICAgICAgICAgICByZXN1bHRbMF0gKz0gJyAnICsgcmVzdWx0WzFdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBDb3JyZWN0IGNoYXJhY3RlciBjYXNlIGFuZCBjbGVhbnVwIHN0cmluZy5cbiAgICAgICAgICBndWVzcyA9IGd1ZXNzLmxhYmVsIHx8IGd1ZXNzO1xuICAgICAgICAgIHJlc3VsdCA9IGZvcm1hdChyZXN1bHRbMF1cbiAgICAgICAgICAgIC5yZXBsYWNlKFJlZ0V4cChwYXR0ZXJuLCAnaScpLCBndWVzcylcbiAgICAgICAgICAgIC5yZXBsYWNlKFJlZ0V4cCgnOyAqKD86JyArIGd1ZXNzICsgJ1tfLV0pPycsICdpJyksICcgJylcbiAgICAgICAgICAgIC5yZXBsYWNlKFJlZ0V4cCgnKCcgKyBndWVzcyArICcpWy1fLl0/KFxcXFx3KScsICdpJyksICckMSAkMicpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzb2x2ZXMgdGhlIHZlcnNpb24gdXNpbmcgYW4gYXJyYXkgb2YgVUEgcGF0dGVybnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhdHRlcm5zIEFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHZlcnNpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0VmVyc2lvbihwYXR0ZXJucykge1xuICAgICAgcmV0dXJuIHJlZHVjZShwYXR0ZXJucywgZnVuY3Rpb24ocmVzdWx0LCBwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgKFJlZ0V4cChwYXR0ZXJuICtcbiAgICAgICAgICAnKD86LVtcXFxcZC5dKy98KD86IGZvciBbXFxcXHctXSspP1sgLy1dKShbXFxcXGQuXStbXiAoKTsvXy1dKiknLCAnaScpLmV4ZWModWEpIHx8IDApWzFdIHx8IG51bGw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgd2hlbiB0aGUgcGxhdGZvcm0gb2JqZWN0IGlzIGNvZXJjZWQgdG8gYSBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbmFtZSB0b1N0cmluZ1xuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgYHBsYXRmb3JtLmRlc2NyaXB0aW9uYCBpZiBhdmFpbGFibGUsIGVsc2UgYW4gZW1wdHkgc3RyaW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU3RyaW5nUGxhdGZvcm0oKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZXNjcmlwdGlvbiB8fCAnJztcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvLyBDb252ZXJ0IGxheW91dCB0byBhbiBhcnJheSBzbyB3ZSBjYW4gYWRkIGV4dHJhIGRldGFpbHMuXG4gICAgbGF5b3V0ICYmIChsYXlvdXQgPSBbbGF5b3V0XSk7XG5cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBwcm9kdWN0cy5cbiAgICAvLyBCcm93c2VycyBvbiBBbmRyb2lkIGRldmljZXMgdHlwaWNhbGx5IHByb3ZpZGUgdGhlaXIgcHJvZHVjdCBJRFMgYWZ0ZXIgXCJBbmRyb2lkO1wiXG4gICAgLy8gdXAgdG8gXCJCdWlsZFwiIG9yIFwiKSBBcHBsZVdlYktpdFwiLlxuICAgIC8vIEV4YW1wbGU6XG4gICAgLy8gXCJNb3ppbGxhLzUuMCAoTGludXg7IEFuZHJvaWQgOC4xLjA7IE1vdG8gRyAoNSkgUGx1cykgQXBwbGVXZWJLaXQvNTM3LjM2XG4gICAgLy8gKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNzAuMC4zNTM4LjgwIE1vYmlsZSBTYWZhcmkvNTM3LjM2XCJcbiAgICBpZiAoL1xcYkFuZHJvaWRcXGIvLnRlc3Qob3MpICYmICFwcm9kdWN0ICYmXG4gICAgICAgIChkYXRhID0gL1xcYkFuZHJvaWRbXjtdKjsoLio/KSg/OkJ1aWxkfFxcKSBBcHBsZVdlYktpdClcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIHByb2R1Y3QgPSB0cmltKGRhdGFbMV0pXG4gICAgICAgIC8vIFJlcGxhY2UgYW55IGxhbmd1YWdlIGNvZGVzIChlZy4gXCJlbi1VU1wiKS5cbiAgICAgICAgLnJlcGxhY2UoL15bYS16XXsyfS1bYS16XXsyfTtcXHMqL2ksICcnKVxuICAgICAgICB8fCBudWxsO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJvZHVjdCBuYW1lcyB0aGF0IGNvbnRhaW4gdGhlaXIgbWFudWZhY3R1cmVyJ3MgbmFtZS5cbiAgICBpZiAobWFudWZhY3R1cmVyICYmICFwcm9kdWN0KSB7XG4gICAgICBwcm9kdWN0ID0gZ2V0UHJvZHVjdChbbWFudWZhY3R1cmVyXSk7XG4gICAgfSBlbHNlIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IHByb2R1Y3RcbiAgICAgICAgLnJlcGxhY2UoUmVnRXhwKCdeKCcgKyBxdWFsaWZ5KG1hbnVmYWN0dXJlcikgKyAnKVstXy5cXFxcc10nLCAnaScpLCBtYW51ZmFjdHVyZXIgKyAnICcpXG4gICAgICAgIC5yZXBsYWNlKFJlZ0V4cCgnXignICsgcXVhbGlmeShtYW51ZmFjdHVyZXIpICsgJylbLV8uXT8oXFxcXHcpJywgJ2knKSwgbWFudWZhY3R1cmVyICsgJyAkMicpO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAvXkxpbnV4XFxiL2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgVUMgQnJvd3NlciBzcGVlZCBtb2RlLlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ1VDIEJyb3dzZXInICYmIC9cXGJVQ1dFQlxcYi8udGVzdCh1YSkpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ3NwZWVkIG1vZGUnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFBhbGVNb29uIGlkZW50aWZ5aW5nIGFzIEZpcmVmb3guXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnUGFsZU1vb24nICYmIChkYXRhID0gL1xcYkZpcmVmb3hcXC8oW1xcZC5dKylcXGIvLmV4ZWModWEpKSkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgnaWRlbnRpZnlpbmcgYXMgRmlyZWZveCAnICsgZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBGaXJlZm94IE9TIGFuZCBwcm9kdWN0cyBydW5uaW5nIEZpcmVmb3guXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnRmlyZWZveCcgJiYgKGRhdGEgPSAvXFxiKE1vYmlsZXxUYWJsZXR8VFYpXFxiL2kuZXhlYyh1YSkpKSB7XG4gICAgICBvcyB8fCAob3MgPSAnRmlyZWZveCBPUycpO1xuICAgICAgcHJvZHVjdCB8fCAocHJvZHVjdCA9IGRhdGFbMV0pO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgZmFsc2UgcG9zaXRpdmVzIGZvciBGaXJlZm94L1NhZmFyaS5cbiAgICBlbHNlIGlmICghbmFtZSB8fCAoZGF0YSA9ICEvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgL1xcYig/OkZpcmVmb3h8U2FmYXJpKVxcYi8uZXhlYyhuYW1lKSkpIHtcbiAgICAgIC8vIEVzY2FwZSB0aGUgYC9gIGZvciBGaXJlZm94IDEuXG4gICAgICBpZiAobmFtZSAmJiAhcHJvZHVjdCAmJiAvW1xcLyxdfF5bXihdKz9cXCkvLnRlc3QodWEuc2xpY2UodWEuaW5kZXhPZihkYXRhICsgJy8nKSArIDgpKSkge1xuICAgICAgICAvLyBDbGVhciBuYW1lIG9mIGZhbHNlIHBvc2l0aXZlcy5cbiAgICAgICAgbmFtZSA9IG51bGw7XG4gICAgICB9XG4gICAgICAvLyBSZWFzc2lnbiBhIGdlbmVyaWMgbmFtZS5cbiAgICAgIGlmICgoZGF0YSA9IHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IG9zKSAmJlxuICAgICAgICAgIChwcm9kdWN0IHx8IG1hbnVmYWN0dXJlciB8fCAvXFxiKD86QW5kcm9pZHxTeW1iaWFuIE9TfFRhYmxldCBPU3x3ZWJPUylcXGIvLnRlc3Qob3MpKSkge1xuICAgICAgICBuYW1lID0gL1thLXpdKyg/OiBIYXQpPy9pLmV4ZWMoL1xcYkFuZHJvaWRcXGIvLnRlc3Qob3MpID8gb3MgOiBkYXRhKSArICcgQnJvd3Nlcic7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEFkZCBDaHJvbWUgdmVyc2lvbiB0byBkZXNjcmlwdGlvbiBmb3IgRWxlY3Ryb24uXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnRWxlY3Ryb24nICYmIChkYXRhID0gKC9cXGJDaHJvbWVcXC8oW1xcZC5dKylcXGIvLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgnQ2hyb21pdW0gJyArIGRhdGEpO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgbm9uLU9wZXJhIChQcmVzdG8tYmFzZWQpIHZlcnNpb25zIChvcmRlciBpcyBpbXBvcnRhbnQpLlxuICAgIGlmICghdmVyc2lvbikge1xuICAgICAgdmVyc2lvbiA9IGdldFZlcnNpb24oW1xuICAgICAgICAnKD86Q2xvdWQ5fENyaU9TfENyTW98RWRnZXxFZGd8RWRnQXxFZGdpT1N8RnhpT1N8SGVhZGxlc3NDaHJvbWV8SUVNb2JpbGV8SXJvbnxPcGVyYSA/TWluaXxPUGlPU3xPUFJ8UmF2ZW58U2Ftc3VuZ0Jyb3dzZXJ8U2lsayg/IS9bXFxcXGQuXSskKXxVQ0Jyb3dzZXJ8WWFCcm93c2VyKScsXG4gICAgICAgICdWZXJzaW9uJyxcbiAgICAgICAgcXVhbGlmeShuYW1lKSxcbiAgICAgICAgJyg/OkZpcmVmb3h8TWluZWZpZWxkfE5ldEZyb250KSdcbiAgICAgIF0pO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc3R1YmJvcm4gbGF5b3V0IGVuZ2luZXMuXG4gICAgaWYgKChkYXRhID1cbiAgICAgICAgICBsYXlvdXQgPT0gJ2lDYWInICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPiAzICYmICdXZWJLaXQnIHx8XG4gICAgICAgICAgL1xcYk9wZXJhXFxiLy50ZXN0KG5hbWUpICYmICgvXFxiT1BSXFxiLy50ZXN0KHVhKSA/ICdCbGluaycgOiAnUHJlc3RvJykgfHxcbiAgICAgICAgICAvXFxiKD86TWlkb3JpfE5vb2t8U2FmYXJpKVxcYi9pLnRlc3QodWEpICYmICEvXig/OlRyaWRlbnR8RWRnZUhUTUwpJC8udGVzdChsYXlvdXQpICYmICdXZWJLaXQnIHx8XG4gICAgICAgICAgIWxheW91dCAmJiAvXFxiTVNJRVxcYi9pLnRlc3QodWEpICYmIChvcyA9PSAnTWFjIE9TJyA/ICdUYXNtYW4nIDogJ1RyaWRlbnQnKSB8fFxuICAgICAgICAgIGxheW91dCA9PSAnV2ViS2l0JyAmJiAvXFxiUGxheVN0YXRpb25cXGIoPyEgVml0YVxcYikvaS50ZXN0KG5hbWUpICYmICdOZXRGcm9udCdcbiAgICAgICAgKSkge1xuICAgICAgbGF5b3V0ID0gW2RhdGFdO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA3IGRlc2t0b3AgbW9kZS5cbiAgICBpZiAobmFtZSA9PSAnSUUnICYmIChkYXRhID0gKC87ICooPzpYQkxXUHxadW5lV1ApKFxcZCspL2kuZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBuYW1lICs9ICcgTW9iaWxlJztcbiAgICAgIG9zID0gJ1dpbmRvd3MgUGhvbmUgJyArICgvXFwrJC8udGVzdChkYXRhKSA/IGRhdGEgOiBkYXRhICsgJy54Jyk7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFdpbmRvd3MgUGhvbmUgOC54IGRlc2t0b3AgbW9kZS5cbiAgICBlbHNlIGlmICgvXFxiV1BEZXNrdG9wXFxiL2kudGVzdCh1YSkpIHtcbiAgICAgIG5hbWUgPSAnSUUgTW9iaWxlJztcbiAgICAgIG9zID0gJ1dpbmRvd3MgUGhvbmUgOC54JztcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgICAgdmVyc2lvbiB8fCAodmVyc2lvbiA9ICgvXFxicnY6KFtcXGQuXSspLy5leGVjKHVhKSB8fCAwKVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSAxMSBpZGVudGlmeWluZyBhcyBvdGhlciBicm93c2Vycy5cbiAgICBlbHNlIGlmIChuYW1lICE9ICdJRScgJiYgbGF5b3V0ID09ICdUcmlkZW50JyAmJiAoZGF0YSA9IC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpKSkge1xuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnaWRlbnRpZnlpbmcgYXMgJyArIG5hbWUgKyAodmVyc2lvbiA/ICcgJyArIHZlcnNpb24gOiAnJykpO1xuICAgICAgfVxuICAgICAgbmFtZSA9ICdJRSc7XG4gICAgICB2ZXJzaW9uID0gZGF0YVsxXTtcbiAgICB9XG4gICAgLy8gTGV2ZXJhZ2UgZW52aXJvbm1lbnQgZmVhdHVyZXMuXG4gICAgaWYgKHVzZUZlYXR1cmVzKSB7XG4gICAgICAvLyBEZXRlY3Qgc2VydmVyLXNpZGUgZW52aXJvbm1lbnRzLlxuICAgICAgLy8gUmhpbm8gaGFzIGEgZ2xvYmFsIGZ1bmN0aW9uIHdoaWxlIG90aGVycyBoYXZlIGEgZ2xvYmFsIG9iamVjdC5cbiAgICAgIGlmIChpc0hvc3RUeXBlKGNvbnRleHQsICdnbG9iYWwnKSkge1xuICAgICAgICBpZiAoamF2YSkge1xuICAgICAgICAgIGRhdGEgPSBqYXZhLmxhbmcuU3lzdGVtO1xuICAgICAgICAgIGFyY2ggPSBkYXRhLmdldFByb3BlcnR5KCdvcy5hcmNoJyk7XG4gICAgICAgICAgb3MgPSBvcyB8fCBkYXRhLmdldFByb3BlcnR5KCdvcy5uYW1lJykgKyAnICcgKyBkYXRhLmdldFByb3BlcnR5KCdvcy52ZXJzaW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJoaW5vKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZlcnNpb24gPSBjb250ZXh0LnJlcXVpcmUoJ3JpbmdvL2VuZ2luZScpLnZlcnNpb24uam9pbignLicpO1xuICAgICAgICAgICAgbmFtZSA9ICdSaW5nb0pTJztcbiAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIGlmICgoZGF0YSA9IGNvbnRleHQuc3lzdGVtKSAmJiBkYXRhLmdsb2JhbC5zeXN0ZW0gPT0gY29udGV4dC5zeXN0ZW0pIHtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOYXJ3aGFsJztcbiAgICAgICAgICAgICAgb3MgfHwgKG9zID0gZGF0YVswXS5vcyB8fCBudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgICAgICBuYW1lID0gJ1JoaW5vJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgdHlwZW9mIGNvbnRleHQucHJvY2VzcyA9PSAnb2JqZWN0JyAmJiAhY29udGV4dC5wcm9jZXNzLmJyb3dzZXIgJiZcbiAgICAgICAgICAoZGF0YSA9IGNvbnRleHQucHJvY2VzcylcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zID09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMuZWxlY3Ryb24gPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdFbGVjdHJvbic7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLmVsZWN0cm9uO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5udyA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgdmVyc2lvbiwgJ05vZGUgJyArIGRhdGEudmVyc2lvbnMubm9kZSk7XG4gICAgICAgICAgICAgIG5hbWUgPSAnTlcuanMnO1xuICAgICAgICAgICAgICB2ZXJzaW9uID0gZGF0YS52ZXJzaW9ucy5udztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgICAgICBuYW1lID0gJ05vZGUuanMnO1xuICAgICAgICAgICAgYXJjaCA9IGRhdGEuYXJjaDtcbiAgICAgICAgICAgIG9zID0gZGF0YS5wbGF0Zm9ybTtcbiAgICAgICAgICAgIHZlcnNpb24gPSAvW1xcZC5dKy8uZXhlYyhkYXRhLnZlcnNpb24pO1xuICAgICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb24gPyB2ZXJzaW9uWzBdIDogbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBBZG9iZSBBSVIuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5ydW50aW1lKSkgPT0gYWlyUnVudGltZUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnQWRvYmUgQUlSJztcbiAgICAgICAgb3MgPSBkYXRhLmZsYXNoLnN5c3RlbS5DYXBhYmlsaXRpZXMub3M7XG4gICAgICB9XG4gICAgICAvLyBEZXRlY3QgUGhhbnRvbUpTLlxuICAgICAgZWxzZSBpZiAoZ2V0Q2xhc3NPZigoZGF0YSA9IGNvbnRleHQucGhhbnRvbSkpID09IHBoYW50b21DbGFzcykge1xuICAgICAgICBuYW1lID0gJ1BoYW50b21KUyc7XG4gICAgICAgIHZlcnNpb24gPSAoZGF0YSA9IGRhdGEudmVyc2lvbiB8fCBudWxsKSAmJiAoZGF0YS5tYWpvciArICcuJyArIGRhdGEubWlub3IgKyAnLicgKyBkYXRhLnBhdGNoKTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSBjb21wYXRpYmlsaXR5IG1vZGVzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgKGRhdGEgPSAvXFxiVHJpZGVudFxcLyhcXGQrKS9pLmV4ZWModWEpKSkge1xuICAgICAgICAvLyBXZSdyZSBpbiBjb21wYXRpYmlsaXR5IG1vZGUgd2hlbiB0aGUgVHJpZGVudCB2ZXJzaW9uICsgNCBkb2Vzbid0XG4gICAgICAgIC8vIGVxdWFsIHRoZSBkb2N1bWVudCBtb2RlLlxuICAgICAgICB2ZXJzaW9uID0gW3ZlcnNpb24sIGRvYy5kb2N1bWVudE1vZGVdO1xuICAgICAgICBpZiAoKGRhdGEgPSArZGF0YVsxXSArIDQpICE9IHZlcnNpb25bMV0pIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdJRSAnICsgdmVyc2lvblsxXSArICcgbW9kZScpO1xuICAgICAgICAgIGxheW91dCAmJiAobGF5b3V0WzFdID0gJycpO1xuICAgICAgICAgIHZlcnNpb25bMV0gPSBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIHZlcnNpb24gPSBuYW1lID09ICdJRScgPyBTdHJpbmcodmVyc2lvblsxXS50b0ZpeGVkKDEpKSA6IHZlcnNpb25bMF07XG4gICAgICB9XG4gICAgICAvLyBEZXRlY3QgSUUgMTEgbWFza2luZyBhcyBvdGhlciBicm93c2Vycy5cbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBkb2MuZG9jdW1lbnRNb2RlID09ICdudW1iZXInICYmIC9eKD86Q2hyb21lfEZpcmVmb3gpXFxiLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ21hc2tpbmcgYXMgJyArIG5hbWUgKyAnICcgKyB2ZXJzaW9uKTtcbiAgICAgICAgbmFtZSA9ICdJRSc7XG4gICAgICAgIHZlcnNpb24gPSAnMTEuMCc7XG4gICAgICAgIGxheW91dCA9IFsnVHJpZGVudCddO1xuICAgICAgICBvcyA9ICdXaW5kb3dzJztcbiAgICAgIH1cbiAgICAgIG9zID0gb3MgJiYgZm9ybWF0KG9zKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IHByZXJlbGVhc2UgcGhhc2VzLlxuICAgIGlmICh2ZXJzaW9uICYmIChkYXRhID1cbiAgICAgICAgICAvKD86W2FiXXxkcHxwcmV8W2FiXVxcZCtwcmUpKD86XFxkK1xcKz8pPyQvaS5leGVjKHZlcnNpb24pIHx8XG4gICAgICAgICAgLyg/OmFscGhhfGJldGEpKD86ID9cXGQpPy9pLmV4ZWModWEgKyAnOycgKyAodXNlRmVhdHVyZXMgJiYgbmF2LmFwcE1pbm9yVmVyc2lvbikpIHx8XG4gICAgICAgICAgL1xcYk1pbmVmaWVsZFxcYi9pLnRlc3QodWEpICYmICdhJ1xuICAgICAgICApKSB7XG4gICAgICBwcmVyZWxlYXNlID0gL2IvaS50ZXN0KGRhdGEpID8gJ2JldGEnIDogJ2FscGhhJztcbiAgICAgIHZlcnNpb24gPSB2ZXJzaW9uLnJlcGxhY2UoUmVnRXhwKGRhdGEgKyAnXFxcXCs/JCcpLCAnJykgK1xuICAgICAgICAocHJlcmVsZWFzZSA9PSAnYmV0YScgPyBiZXRhIDogYWxwaGEpICsgKC9cXGQrXFwrPy8uZXhlYyhkYXRhKSB8fCAnJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBGaXJlZm94IE1vYmlsZS5cbiAgICBpZiAobmFtZSA9PSAnRmVubmVjJyB8fCBuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiKD86QW5kcm9pZHxGaXJlZm94IE9TfEthaU9TKVxcYi8udGVzdChvcykpIHtcbiAgICAgIG5hbWUgPSAnRmlyZWZveCBNb2JpbGUnO1xuICAgIH1cbiAgICAvLyBPYnNjdXJlIE1heHRob24ncyB1bnJlbGlhYmxlIHZlcnNpb24uXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnTWF4dGhvbicgJiYgdmVyc2lvbikge1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZSgvXFwuW1xcZC5dKy8sICcueCcpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgWGJveCAzNjAgYW5kIFhib3ggT25lLlxuICAgIGVsc2UgaWYgKC9cXGJYYm94XFxiL2kudGVzdChwcm9kdWN0KSkge1xuICAgICAgaWYgKHByb2R1Y3QgPT0gJ1hib3ggMzYwJykge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnICYmIC9cXGJJRU1vYmlsZVxcYi8udGVzdCh1YSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnbW9iaWxlIG1vZGUnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIG1vYmlsZSBwb3N0Zml4LlxuICAgIGVsc2UgaWYgKCgvXig/OkNocm9tZXxJRXxPcGVyYSkkLy50ZXN0KG5hbWUpIHx8IG5hbWUgJiYgIXByb2R1Y3QgJiYgIS9Ccm93c2VyfE1vYmkvLnRlc3QobmFtZSkpICYmXG4gICAgICAgIChvcyA9PSAnV2luZG93cyBDRScgfHwgL01vYmkvaS50ZXN0KHVhKSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgSUUgcGxhdGZvcm0gcHJldmlldy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdJRScgJiYgdXNlRmVhdHVyZXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChjb250ZXh0LmV4dGVybmFsID09PSBudWxsKSB7XG4gICAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgncGxhdGZvcm0gcHJldmlldycpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZW1iZWRkZWQnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gRGV0ZWN0IEJsYWNrQmVycnkgT1MgdmVyc2lvbi5cbiAgICAvLyBodHRwOi8vZG9jcy5ibGFja2JlcnJ5LmNvbS9lbi9kZXZlbG9wZXJzL2RlbGl2ZXJhYmxlcy8xODE2OS9IVFRQX2hlYWRlcnNfc2VudF9ieV9CQl9Ccm93c2VyXzEyMzQ5MTFfMTEuanNwXG4gICAgZWxzZSBpZiAoKC9cXGJCbGFja0JlcnJ5XFxiLy50ZXN0KHByb2R1Y3QpIHx8IC9cXGJCQjEwXFxiLy50ZXN0KHVhKSkgJiYgKGRhdGEgPVxuICAgICAgICAgIChSZWdFeHAocHJvZHVjdC5yZXBsYWNlKC8gKy9nLCAnIConKSArICcvKFsuXFxcXGRdKyknLCAnaScpLmV4ZWModWEpIHx8IDApWzFdIHx8XG4gICAgICAgICAgdmVyc2lvblxuICAgICAgICApKSB7XG4gICAgICBkYXRhID0gW2RhdGEsIC9CQjEwLy50ZXN0KHVhKV07XG4gICAgICBvcyA9IChkYXRhWzFdID8gKHByb2R1Y3QgPSBudWxsLCBtYW51ZmFjdHVyZXIgPSAnQmxhY2tCZXJyeScpIDogJ0RldmljZSBTb2Z0d2FyZScpICsgJyAnICsgZGF0YVswXTtcbiAgICAgIHZlcnNpb24gPSBudWxsO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgT3BlcmEgaWRlbnRpZnlpbmcvbWFza2luZyBpdHNlbGYgYXMgYW5vdGhlciBicm93c2VyLlxuICAgIC8vIGh0dHA6Ly93d3cub3BlcmEuY29tL3N1cHBvcnQva2Ivdmlldy84NDMvXG4gICAgZWxzZSBpZiAodGhpcyAhPSBmb3JPd24gJiYgcHJvZHVjdCAhPSAnV2lpJyAmJiAoXG4gICAgICAgICAgKHVzZUZlYXR1cmVzICYmIG9wZXJhKSB8fFxuICAgICAgICAgICgvT3BlcmEvLnRlc3QobmFtZSkgJiYgL1xcYig/Ok1TSUV8RmlyZWZveClcXGIvaS50ZXN0KHVhKSkgfHxcbiAgICAgICAgICAobmFtZSA9PSAnRmlyZWZveCcgJiYgL1xcYk9TIFggKD86XFxkK1xcLil7Mix9Ly50ZXN0KG9zKSkgfHxcbiAgICAgICAgICAobmFtZSA9PSAnSUUnICYmIChcbiAgICAgICAgICAgIChvcyAmJiAhL15XaW4vLnRlc3Qob3MpICYmIHZlcnNpb24gPiA1LjUpIHx8XG4gICAgICAgICAgICAvXFxiV2luZG93cyBYUFxcYi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDggfHxcbiAgICAgICAgICAgIHZlcnNpb24gPT0gOCAmJiAhL1xcYlRyaWRlbnRcXGIvLnRlc3QodWEpXG4gICAgICAgICAgKSlcbiAgICAgICAgKSAmJiAhcmVPcGVyYS50ZXN0KChkYXRhID0gcGFyc2UuY2FsbChmb3JPd24sIHVhLnJlcGxhY2UocmVPcGVyYSwgJycpICsgJzsnKSkpICYmIGRhdGEubmFtZSkge1xuICAgICAgLy8gV2hlbiBcImlkZW50aWZ5aW5nXCIsIHRoZSBVQSBjb250YWlucyBib3RoIE9wZXJhIGFuZCB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBkYXRhID0gJ2luZyBhcyAnICsgZGF0YS5uYW1lICsgKChkYXRhID0gZGF0YS52ZXJzaW9uKSA/ICcgJyArIGRhdGEgOiAnJyk7XG4gICAgICBpZiAocmVPcGVyYS50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGlmICgvXFxiSUVcXGIvLnRlc3QoZGF0YSkgJiYgb3MgPT0gJ01hYyBPUycpIHtcbiAgICAgICAgICBvcyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YSA9ICdpZGVudGlmeScgKyBkYXRhO1xuICAgICAgfVxuICAgICAgLy8gV2hlbiBcIm1hc2tpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIG9ubHkgdGhlIG90aGVyIGJyb3dzZXIncyBuYW1lLlxuICAgICAgZWxzZSB7XG4gICAgICAgIGRhdGEgPSAnbWFzaycgKyBkYXRhO1xuICAgICAgICBpZiAob3BlcmFDbGFzcykge1xuICAgICAgICAgIG5hbWUgPSBmb3JtYXQob3BlcmFDbGFzcy5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEgJDInKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmFtZSA9ICdPcGVyYSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSkge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXVzZUZlYXR1cmVzKSB7XG4gICAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxheW91dCA9IFsnUHJlc3RvJ107XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKGRhdGEpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2ViS2l0IE5pZ2h0bHkgYW5kIGFwcHJveGltYXRlIENocm9tZS9TYWZhcmkgdmVyc2lvbnMuXG4gICAgaWYgKChkYXRhID0gKC9cXGJBcHBsZVdlYktpdFxcLyhbXFxkLl0rXFwrPykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIC8vIENvcnJlY3QgYnVpbGQgbnVtYmVyIGZvciBudW1lcmljIGNvbXBhcmlzb24uXG4gICAgICAvLyAoZS5nLiBcIjUzMi41XCIgYmVjb21lcyBcIjUzMi4wNVwiKVxuICAgICAgZGF0YSA9IFtwYXJzZUZsb2F0KGRhdGEucmVwbGFjZSgvXFwuKFxcZCkkLywgJy4wJDEnKSksIGRhdGFdO1xuICAgICAgLy8gTmlnaHRseSBidWlsZHMgYXJlIHBvc3RmaXhlZCB3aXRoIGEgXCIrXCIuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiBkYXRhWzFdLnNsaWNlKC0xKSA9PSAnKycpIHtcbiAgICAgICAgbmFtZSA9ICdXZWJLaXQgTmlnaHRseSc7XG4gICAgICAgIHByZXJlbGVhc2UgPSAnYWxwaGEnO1xuICAgICAgICB2ZXJzaW9uID0gZGF0YVsxXS5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgICAvLyBDbGVhciBpbmNvcnJlY3QgYnJvd3NlciB2ZXJzaW9ucy5cbiAgICAgIGVsc2UgaWYgKHZlcnNpb24gPT0gZGF0YVsxXSB8fFxuICAgICAgICAgIHZlcnNpb24gPT0gKGRhdGFbMl0gPSAoL1xcYlNhZmFyaVxcLyhbXFxkLl0rXFwrPykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9XG4gICAgICAvLyBVc2UgdGhlIGZ1bGwgQ2hyb21lIHZlcnNpb24gd2hlbiBhdmFpbGFibGUuXG4gICAgICBkYXRhWzFdID0gKC9cXGIoPzpIZWFkbGVzcyk/Q2hyb21lXFwvKFtcXGQuXSspL2kuZXhlYyh1YSkgfHwgMClbMV07XG4gICAgICAvLyBEZXRlY3QgQmxpbmsgbGF5b3V0IGVuZ2luZS5cbiAgICAgIGlmIChkYXRhWzBdID09IDUzNy4zNiAmJiBkYXRhWzJdID09IDUzNy4zNiAmJiBwYXJzZUZsb2F0KGRhdGFbMV0pID49IDI4ICYmIGxheW91dCA9PSAnV2ViS2l0Jykge1xuICAgICAgICBsYXlvdXQgPSBbJ0JsaW5rJ107XG4gICAgICB9XG4gICAgICAvLyBEZXRlY3QgSmF2YVNjcmlwdENvcmUuXG4gICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzY3Njg0NzQvaG93LWNhbi1pLWRldGVjdC13aGljaC1qYXZhc2NyaXB0LWVuZ2luZS12OC1vci1qc2MtaXMtdXNlZC1hdC1ydW50aW1lLWluLWFuZHJvaVxuICAgICAgaWYgKCF1c2VGZWF0dXJlcyB8fCAoIWxpa2VDaHJvbWUgJiYgIWRhdGFbMV0pKSB7XG4gICAgICAgIGxheW91dCAmJiAobGF5b3V0WzFdID0gJ2xpa2UgU2FmYXJpJyk7XG4gICAgICAgIGRhdGEgPSAoZGF0YSA9IGRhdGFbMF0sIGRhdGEgPCA0MDAgPyAxIDogZGF0YSA8IDUwMCA/IDIgOiBkYXRhIDwgNTI2ID8gMyA6IGRhdGEgPCA1MzMgPyA0IDogZGF0YSA8IDUzNCA/ICc0KycgOiBkYXRhIDwgNTM1ID8gNSA6IGRhdGEgPCA1MzcgPyA2IDogZGF0YSA8IDUzOCA/IDcgOiBkYXRhIDwgNjAxID8gOCA6IGRhdGEgPCA2MDIgPyA5IDogZGF0YSA8IDYwNCA/IDEwIDogZGF0YSA8IDYwNiA/IDExIDogZGF0YSA8IDYwOCA/IDEyIDogJzEyJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIENocm9tZScpO1xuICAgICAgICBkYXRhID0gZGF0YVsxXSB8fCAoZGF0YSA9IGRhdGFbMF0sIGRhdGEgPCA1MzAgPyAxIDogZGF0YSA8IDUzMiA/IDIgOiBkYXRhIDwgNTMyLjA1ID8gMyA6IGRhdGEgPCA1MzMgPyA0IDogZGF0YSA8IDUzNC4wMyA/IDUgOiBkYXRhIDwgNTM0LjA3ID8gNiA6IGRhdGEgPCA1MzQuMTAgPyA3IDogZGF0YSA8IDUzNC4xMyA/IDggOiBkYXRhIDwgNTM0LjE2ID8gOSA6IGRhdGEgPCA1MzQuMjQgPyAxMCA6IGRhdGEgPCA1MzQuMzAgPyAxMSA6IGRhdGEgPCA1MzUuMDEgPyAxMiA6IGRhdGEgPCA1MzUuMDIgPyAnMTMrJyA6IGRhdGEgPCA1MzUuMDcgPyAxNSA6IGRhdGEgPCA1MzUuMTEgPyAxNiA6IGRhdGEgPCA1MzUuMTkgPyAxNyA6IGRhdGEgPCA1MzYuMDUgPyAxOCA6IGRhdGEgPCA1MzYuMTAgPyAxOSA6IGRhdGEgPCA1MzcuMDEgPyAyMCA6IGRhdGEgPCA1MzcuMTEgPyAnMjErJyA6IGRhdGEgPCA1MzcuMTMgPyAyMyA6IGRhdGEgPCA1MzcuMTggPyAyNCA6IGRhdGEgPCA1MzcuMjQgPyAyNSA6IGRhdGEgPCA1MzcuMzYgPyAyNiA6IGxheW91dCAhPSAnQmxpbmsnID8gJzI3JyA6ICcyOCcpO1xuICAgICAgfVxuICAgICAgLy8gQWRkIHRoZSBwb3N0Zml4IG9mIFwiLnhcIiBvciBcIitcIiBmb3IgYXBwcm94aW1hdGUgdmVyc2lvbnMuXG4gICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSArPSAnICcgKyAoZGF0YSArPSB0eXBlb2YgZGF0YSA9PSAnbnVtYmVyJyA/ICcueCcgOiAvWy4rXS8udGVzdChkYXRhKSA/ICcnIDogJysnKSk7XG4gICAgICAvLyBPYnNjdXJlIHZlcnNpb24gZm9yIHNvbWUgU2FmYXJpIDEtMiByZWxlYXNlcy5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmICghdmVyc2lvbiB8fCBwYXJzZUludCh2ZXJzaW9uKSA+IDQ1KSkge1xuICAgICAgICB2ZXJzaW9uID0gZGF0YTtcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PSAnQ2hyb21lJyAmJiAvXFxiSGVhZGxlc3NDaHJvbWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdoZWFkbGVzcycpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgT3BlcmEgZGVza3RvcCBtb2Rlcy5cbiAgICBpZiAobmFtZSA9PSAnT3BlcmEnICYmICAoZGF0YSA9IC9cXGJ6Ym92fHp2YXYkLy5leGVjKG9zKSkpIHtcbiAgICAgIG5hbWUgKz0gJyAnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICBpZiAoZGF0YSA9PSAnenZhdicpIHtcbiAgICAgICAgbmFtZSArPSAnTWluaSc7XG4gICAgICAgIHZlcnNpb24gPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmFtZSArPSAnTW9iaWxlJztcbiAgICAgIH1cbiAgICAgIG9zID0gb3MucmVwbGFjZShSZWdFeHAoJyAqJyArIGRhdGEgKyAnJCcpLCAnJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBDaHJvbWUgZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ1NhZmFyaScgJiYgL1xcYkNocm9tZVxcYi8uZXhlYyhsYXlvdXQgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICBuYW1lID0gJ0Nocm9tZSBNb2JpbGUnO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG5cbiAgICAgIGlmICgvXFxiT1MgWFxcYi8udGVzdChvcykpIHtcbiAgICAgICAgbWFudWZhY3R1cmVyID0gJ0FwcGxlJztcbiAgICAgICAgb3MgPSAnaU9TIDQuMysnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3MgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBOZXdlciB2ZXJzaW9ucyBvZiBTUldhcmUgSXJvbiB1c2VzIHRoZSBDaHJvbWUgdGFnIHRvIGluZGljYXRlIGl0cyB2ZXJzaW9uIG51bWJlci5cbiAgICBlbHNlIGlmICgvXFxiU1JXYXJlIElyb25cXGIvLnRlc3QobmFtZSkgJiYgIXZlcnNpb24pIHtcbiAgICAgIHZlcnNpb24gPSBnZXRWZXJzaW9uKCdDaHJvbWUnKTtcbiAgICB9XG4gICAgLy8gU3RyaXAgaW5jb3JyZWN0IE9TIHZlcnNpb25zLlxuICAgIGlmICh2ZXJzaW9uICYmIHZlcnNpb24uaW5kZXhPZigoZGF0YSA9IC9bXFxkLl0rJC8uZXhlYyhvcykpKSA9PSAwICYmXG4gICAgICAgIHVhLmluZGV4T2YoJy8nICsgZGF0YSArICctJykgPiAtMSkge1xuICAgICAgb3MgPSB0cmltKG9zLnJlcGxhY2UoZGF0YSwgJycpKTtcbiAgICB9XG4gICAgLy8gRW5zdXJlIE9TIGRvZXMgbm90IGluY2x1ZGUgdGhlIGJyb3dzZXIgbmFtZS5cbiAgICBpZiAob3MgJiYgb3MuaW5kZXhPZihuYW1lKSAhPSAtMSAmJiAhUmVnRXhwKG5hbWUgKyAnIE9TJykudGVzdChvcykpIHtcbiAgICAgIG9zID0gb3MucmVwbGFjZShSZWdFeHAoJyAqJyArIHF1YWxpZnkobmFtZSkgKyAnIConKSwgJycpO1xuICAgIH1cbiAgICAvLyBBZGQgbGF5b3V0IGVuZ2luZS5cbiAgICBpZiAobGF5b3V0ICYmICEvXFxiKD86QXZhbnR8Tm9vaylcXGIvLnRlc3QobmFtZSkgJiYgKFxuICAgICAgICAvQnJvd3NlcnxMdW5hc2NhcGV8TWF4dGhvbi8udGVzdChuYW1lKSB8fFxuICAgICAgICBuYW1lICE9ICdTYWZhcmknICYmIC9eaU9TLy50ZXN0KG9zKSAmJiAvXFxiU2FmYXJpXFxiLy50ZXN0KGxheW91dFsxXSkgfHxcbiAgICAgICAgL14oPzpBZG9iZXxBcm9yYXxCcmVhY2h8TWlkb3JpfE9wZXJhfFBoYW50b218UmVrb25xfFJvY2t8U2Ftc3VuZyBJbnRlcm5ldHxTbGVpcG5pcnxTUldhcmUgSXJvbnxWaXZhbGRpfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJMaW51eFwiLCBcIlVidW50dVwiLCBcIkRlYmlhblwiLCBcIkZlZG9yYVwiLCBcIlJlZCBIYXRcIixcbiAgICAgICAqIFwiU3VTRVwiLCBcIkFuZHJvaWRcIiwgXCJpT1NcIiBhbmQgXCJXaW5kb3dzIFBob25lXCJcbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm0ub3NcbiAgICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICAgKi9cbiAgICAgICdmYW1pbHknOiBudWxsLFxuXG4gICAgICAvKipcbiAgICAgICAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBPUy5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm0ub3NcbiAgICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICAgKi9cbiAgICAgICd2ZXJzaW9uJzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBSZXR1cm5zIHRoZSBPUyBzdHJpbmcuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgT1Mgc3RyaW5nLlxuICAgICAgICovXG4gICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHsgcmV0dXJuICdudWxsJzsgfVxuICAgIH07XG5cbiAgICBwbGF0Zm9ybS5wYXJzZSA9IHBhcnNlO1xuICAgIHBsYXRmb3JtLnRvU3RyaW5nID0gdG9TdHJpbmdQbGF0Zm9ybTtcblxuICAgIGlmIChwbGF0Zm9ybS52ZXJzaW9uKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KHZlcnNpb24pO1xuICAgIH1cbiAgICBpZiAocGxhdGZvcm0ubmFtZSkge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdChuYW1lKTtcbiAgICB9XG4gICAgaWYgKG9zICYmIG5hbWUgJiYgIShvcyA9PSBTdHJpbmcob3MpLnNwbGl0KCcgJylbMF0gJiYgKG9zID09IG5hbWUuc3BsaXQoJyAnKVswXSB8fCBwcm9kdWN0KSkpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2gocHJvZHVjdCA/ICcoJyArIG9zICsgJyknIDogJ29uICcgKyBvcyk7XG4gICAgfVxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24uam9pbignICcpO1xuICAgIH1cbiAgICByZXR1cm4gcGxhdGZvcm07XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvLyBFeHBvcnQgcGxhdGZvcm0uXG4gIHZhciBwbGF0Zm9ybSA9IHBhcnNlKCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3IgY29uZGl0aW9uIHBhdHRlcm5zIGxpa2UgdGhlIGZvbGxvd2luZzpcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgLy8gRXhwb3NlIHBsYXRmb3JtIG9uIHRoZSBnbG9iYWwgb2JqZWN0IHRvIHByZXZlbnQgZXJyb3JzIHdoZW4gcGxhdGZvcm0gaXNcbiAgICAvLyBsb2FkZWQgYnkgYSBzY3JpcHQgdGFnIGluIHRoZSBwcmVzZW5jZSBvZiBhbiBBTUQgbG9hZGVyLlxuICAgIC8vIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvciBtb3JlIGRldGFpbHMuXG4gICAgcm9vdC5wbGF0Zm9ybSA9IHBsYXRmb3JtO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28gcGxhdGZvcm0gY2FuIGJlIGFsaWFzZWQgdGhyb3VnaCBwYXRoIG1hcHBpbmcuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHBsYXRmb3JtO1xuICAgIH0pO1xuICB9XG4gIC8vIENoZWNrIGZvciBgZXhwb3J0c2AgYWZ0ZXIgYGRlZmluZWAgaW4gY2FzZSBhIGJ1aWxkIG9wdGltaXplciBhZGRzIGFuIGBleHBvcnRzYCBvYmplY3QuXG4gIGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmIGZyZWVNb2R1bGUpIHtcbiAgICAvLyBFeHBvcnQgZm9yIENvbW1vbkpTIHN1cHBvcnQuXG4gICAgZm9yT3duKHBsYXRmb3JtLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICBmcmVlRXhwb3J0c1trZXldID0gdmFsdWU7XG4gICAgfSk7XG4gIH1cbiAgZWxzZSB7XG4gICAgLy8gRXhwb3J0IHRvIHRoZSBnbG9iYWwgb2JqZWN0LlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cbnByb2Nlc3MubGlzdGVuZXJzID0gZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIFtdIH1cblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCJjb25zdCBkZWJ1ZyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2RlYnVnJylcbmNvbnN0IHsgTUFYX0xFTkdUSCwgTUFYX1NBRkVfSU5URUdFUiB9ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY29uc3RhbnRzJylcbmNvbnN0IHsgcmUsIHQgfSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3JlJylcblxuY29uc3QgcGFyc2VPcHRpb25zID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcGFyc2Utb3B0aW9ucycpXG5jb25zdCB7IGNvbXBhcmVJZGVudGlmaWVycyB9ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaWRlbnRpZmllcnMnKVxuY2xhc3MgU2VtVmVyIHtcbiAgY29uc3RydWN0b3IgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gcGFyc2VPcHRpb25zKG9wdGlvbnMpXG5cbiAgICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgICAgaWYgKHZlcnNpb24ubG9vc2UgPT09ICEhb3B0aW9ucy5sb29zZSAmJlxuICAgICAgICAgIHZlcnNpb24uaW5jbHVkZVByZXJlbGVhc2UgPT09ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgICAgICByZXR1cm4gdmVyc2lvblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmVyc2lvbiA9IHZlcnNpb24udmVyc2lvblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIFZlcnNpb246ICR7dmVyc2lvbn1gKVxuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgIGB2ZXJzaW9uIGlzIGxvbmdlciB0aGFuICR7TUFYX0xFTkdUSH0gY2hhcmFjdGVyc2BcbiAgICAgIClcbiAgICB9XG5cbiAgICBkZWJ1ZygnU2VtVmVyJywgdmVyc2lvbiwgb3B0aW9ucylcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gICAgdGhpcy5sb29zZSA9ICEhb3B0aW9ucy5sb29zZVxuICAgIC8vIHRoaXMgaXNuJ3QgYWN0dWFsbHkgcmVsZXZhbnQgZm9yIHZlcnNpb25zLCBidXQga2VlcCBpdCBzbyB0aGF0IHdlXG4gICAgLy8gZG9uJ3QgcnVuIGludG8gdHJvdWJsZSBwYXNzaW5nIHRoaXMub3B0aW9ucyBhcm91bmQuXG4gICAgdGhpcy5pbmNsdWRlUHJlcmVsZWFzZSA9ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZVxuXG4gICAgY29uc3QgbSA9IHZlcnNpb24udHJpbSgpLm1hdGNoKG9wdGlvbnMubG9vc2UgPyByZVt0LkxPT1NFXSA6IHJlW3QuRlVMTF0pXG5cbiAgICBpZiAoIW0pIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgVmVyc2lvbjogJHt2ZXJzaW9ufWApXG4gICAgfVxuXG4gICAgdGhpcy5yYXcgPSB2ZXJzaW9uXG5cbiAgICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICAgIHRoaXMubWFqb3IgPSArbVsxXVxuICAgIHRoaXMubWlub3IgPSArbVsyXVxuICAgIHRoaXMucGF0Y2ggPSArbVszXVxuXG4gICAgaWYgKHRoaXMubWFqb3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWFqb3IgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1ham9yIHZlcnNpb24nKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm1pbm9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1pbm9yIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBtaW5vciB2ZXJzaW9uJylcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYXRjaCA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5wYXRjaCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgcGF0Y2ggdmVyc2lvbicpXG4gICAgfVxuXG4gICAgLy8gbnVtYmVyaWZ5IGFueSBwcmVyZWxlYXNlIG51bWVyaWMgaWRzXG4gICAgaWYgKCFtWzRdKSB7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBtWzRdLnNwbGl0KCcuJykubWFwKChpZCkgPT4ge1xuICAgICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICAgIGNvbnN0IG51bSA9ICtpZFxuICAgICAgICAgIGlmIChudW0gPj0gMCAmJiBudW0gPCBNQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVtXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpZFxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0aGlzLmJ1aWxkID0gbVs1XSA/IG1bNV0uc3BsaXQoJy4nKSA6IFtdXG4gICAgdGhpcy5mb3JtYXQoKVxuICB9XG5cbiAgZm9ybWF0ICgpIHtcbiAgICB0aGlzLnZlcnNpb24gPSBgJHt0aGlzLm1ham9yfS4ke3RoaXMubWlub3J9LiR7dGhpcy5wYXRjaH1gXG4gICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMudmVyc2lvbiArPSBgLSR7dGhpcy5wcmVyZWxlYXNlLmpvaW4oJy4nKX1gXG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZlcnNpb25cbiAgfVxuXG4gIHRvU3RyaW5nICgpIHtcbiAgICByZXR1cm4gdGhpcy52ZXJzaW9uXG4gIH1cblxuICBjb21wYXJlIChvdGhlcikge1xuICAgIGRlYnVnKCdTZW1WZXIuY29tcGFyZScsIHRoaXMudmVyc2lvbiwgdGhpcy5vcHRpb25zLCBvdGhlcilcbiAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICAgIGlmICh0eXBlb2Ygb3RoZXIgPT09ICdzdHJpbmcnICYmIG90aGVyID09PSB0aGlzLnZlcnNpb24pIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICAgIH1cbiAgICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5vcHRpb25zKVxuICAgIH1cblxuICAgIGlmIChvdGhlci52ZXJzaW9uID09PSB0aGlzLnZlcnNpb24pIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29tcGFyZU1haW4ob3RoZXIpIHx8IHRoaXMuY29tcGFyZVByZShvdGhlcilcbiAgfVxuXG4gIGNvbXBhcmVNYWluIChvdGhlcikge1xuICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1ham9yLCBvdGhlci5tYWpvcikgfHxcbiAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1pbm9yLCBvdGhlci5taW5vcikgfHxcbiAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnBhdGNoLCBvdGhlci5wYXRjaClcbiAgICApXG4gIH1cblxuICBjb21wYXJlUHJlIChvdGhlcikge1xuICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gICAgfVxuXG4gICAgLy8gTk9UIGhhdmluZyBhIHByZXJlbGVhc2UgaXMgPiBoYXZpbmcgb25lXG4gICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9IGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmIG90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gMVxuICAgIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gMFxuICAgIH1cblxuICAgIGxldCBpID0gMFxuICAgIGRvIHtcbiAgICAgIGNvbnN0IGEgPSB0aGlzLnByZXJlbGVhc2VbaV1cbiAgICAgIGNvbnN0IGIgPSBvdGhlci5wcmVyZWxlYXNlW2ldXG4gICAgICBkZWJ1ZygncHJlcmVsZWFzZSBjb21wYXJlJywgaSwgYSwgYilcbiAgICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAwXG4gICAgICB9IGVsc2UgaWYgKGIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gMVxuICAgICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9IGVsc2UgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYSwgYilcbiAgICAgIH1cbiAgICB9IHdoaWxlICgrK2kpXG4gIH1cblxuICBjb21wYXJlQnVpbGQgKG90aGVyKSB7XG4gICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgICB9XG5cbiAgICBsZXQgaSA9IDBcbiAgICBkbyB7XG4gICAgICBjb25zdCBhID0gdGhpcy5idWlsZFtpXVxuICAgICAgY29uc3QgYiA9IG90aGVyLmJ1aWxkW2ldXG4gICAgICBkZWJ1ZygncHJlcmVsZWFzZSBjb21wYXJlJywgaSwgYSwgYilcbiAgICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAwXG4gICAgICB9IGVsc2UgaWYgKGIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gMVxuICAgICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9IGVsc2UgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYSwgYilcbiAgICAgIH1cbiAgICB9IHdoaWxlICgrK2kpXG4gIH1cblxuICAvLyBwcmVtaW5vciB3aWxsIGJ1bXAgdGhlIHZlcnNpb24gdXAgdG8gdGhlIG5leHQgbWlub3IgcmVsZWFzZSwgYW5kIGltbWVkaWF0ZWx5XG4gIC8vIGRvd24gdG8gcHJlLXJlbGVhc2UuIHByZW1ham9yIGFuZCBwcmVwYXRjaCB3b3JrIHRoZSBzYW1lIHdheS5cbiAgaW5jIChyZWxlYXNlLCBpZGVudGlmaWVyKSB7XG4gICAgc3dpdGNoIChyZWxlYXNlKSB7XG4gICAgICBjYXNlICdwcmVtYWpvcic6XG4gICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICAgIHRoaXMubWlub3IgPSAwXG4gICAgICAgIHRoaXMubWFqb3IrK1xuICAgICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3ByZW1pbm9yJzpcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgICAgdGhpcy5taW5vcisrXG4gICAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAncHJlcGF0Y2gnOlxuICAgICAgICAvLyBJZiB0aGlzIGlzIGFscmVhZHkgYSBwcmVyZWxlYXNlLCBpdCB3aWxsIGJ1bXAgdG8gdGhlIG5leHQgdmVyc2lvblxuICAgICAgICAvLyBkcm9wIGFueSBwcmVyZWxlYXNlcyB0aGF0IG1pZ2h0IGFscmVhZHkgZXhpc3QsIHNpbmNlIHRoZXkgYXJlIG5vdFxuICAgICAgICAvLyByZWxldmFudCBhdCB0aGlzIHBvaW50LlxuICAgICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgICAgYnJlYWtcbiAgICAgIC8vIElmIHRoZSBpbnB1dCBpcyBhIG5vbi1wcmVyZWxlYXNlIHZlcnNpb24sIHRoaXMgYWN0cyB0aGUgc2FtZSBhc1xuICAgICAgLy8gcHJlcGF0Y2guXG4gICAgICBjYXNlICdwcmVyZWxlYXNlJzpcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgICBicmVha1xuXG4gICAgICBjYXNlICdtYWpvcic6XG4gICAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWFqb3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtYWpvciB2ZXJzaW9uLlxuICAgICAgICAvLyBPdGhlcndpc2UgaW5jcmVtZW50IG1ham9yLlxuICAgICAgICAvLyAxLjAuMC01IGJ1bXBzIHRvIDEuMC4wXG4gICAgICAgIC8vIDEuMS4wIGJ1bXBzIHRvIDIuMC4wXG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLm1pbm9yICE9PSAwIHx8XG4gICAgICAgICAgdGhpcy5wYXRjaCAhPT0gMCB8fFxuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5tYWpvcisrXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ21pbm9yJzpcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIHByZS1taW5vciB2ZXJzaW9uLCBidW1wIHVwIHRvIHRoZSBzYW1lIG1pbm9yIHZlcnNpb24uXG4gICAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWlub3IuXG4gICAgICAgIC8vIDEuMi4wLTUgYnVtcHMgdG8gMS4yLjBcbiAgICAgICAgLy8gMS4yLjEgYnVtcHMgdG8gMS4zLjBcbiAgICAgICAgaWYgKHRoaXMucGF0Y2ggIT09IDAgfHwgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMubWlub3IrK1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdwYXRjaCc6XG4gICAgICAgIC8vIElmIHRoaXMgaXMgbm90IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiwgaXQgd2lsbCBpbmNyZW1lbnQgdGhlIHBhdGNoLlxuICAgICAgICAvLyBJZiBpdCBpcyBhIHByZS1yZWxlYXNlIGl0IHdpbGwgYnVtcCB1cCB0byB0aGUgc2FtZSBwYXRjaCB2ZXJzaW9uLlxuICAgICAgICAvLyAxLjIuMC01IHBhdGNoZXMgdG8gMS4yLjBcbiAgICAgICAgLy8gMS4yLjAgcGF0Y2hlcyB0byAxLjIuMVxuICAgICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMucGF0Y2grK1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICAgIGJyZWFrXG4gICAgICAvLyBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIHB1YmxpY2x5LlxuICAgICAgLy8gMS4wLjAgJ3ByZScgd291bGQgYmVjb21lIDEuMC4wLTAgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvbi5cbiAgICAgIGNhc2UgJ3ByZSc6XG4gICAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gWzBdXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGV0IGkgPSB0aGlzLnByZXJlbGVhc2UubGVuZ3RoXG4gICAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJlcmVsZWFzZVtpXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlW2ldKytcbiAgICAgICAgICAgICAgaSA9IC0yXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgICAgLy8gZGlkbid0IGluY3JlbWVudCBhbnl0aGluZ1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlLnB1c2goMClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICAgICAgICAvLyAxLjIuMC1iZXRhLjEgYnVtcHMgdG8gMS4yLjAtYmV0YS4yLFxuICAgICAgICAgIC8vIDEuMi4wLWJldGEuZm9vYmx6IG9yIDEuMi4wLWJldGEgYnVtcHMgdG8gMS4yLjAtYmV0YS4wXG4gICAgICAgICAgaWYgKGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnByZXJlbGVhc2VbMF0sIGlkZW50aWZpZXIpID09PSAwKSB7XG4gICAgICAgICAgICBpZiAoaXNOYU4odGhpcy5wcmVyZWxlYXNlWzFdKSkge1xuICAgICAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBpbmNyZW1lbnQgYXJndW1lbnQ6ICR7cmVsZWFzZX1gKVxuICAgIH1cbiAgICB0aGlzLmZvcm1hdCgpXG4gICAgdGhpcy5yYXcgPSB0aGlzLnZlcnNpb25cbiAgICByZXR1cm4gdGhpc1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2VtVmVyXG4iLCJjb25zdCBTZW1WZXIgPSByZXF1aXJlKCcuLi9jbGFzc2VzL3NlbXZlcicpXG5jb25zdCBtYWpvciA9IChhLCBsb29zZSkgPT4gbmV3IFNlbVZlcihhLCBsb29zZSkubWFqb3Jcbm1vZHVsZS5leHBvcnRzID0gbWFqb3JcbiIsImNvbnN0IFNlbVZlciA9IHJlcXVpcmUoJy4uL2NsYXNzZXMvc2VtdmVyJylcbmNvbnN0IG1pbm9yID0gKGEsIGxvb3NlKSA9PiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5taW5vclxubW9kdWxlLmV4cG9ydHMgPSBtaW5vclxuIiwiLy8gTm90ZTogdGhpcyBpcyB0aGUgc2VtdmVyLm9yZyB2ZXJzaW9uIG9mIHRoZSBzcGVjIHRoYXQgaXQgaW1wbGVtZW50c1xuLy8gTm90IG5lY2Vzc2FyaWx5IHRoZSBwYWNrYWdlIHZlcnNpb24gb2YgdGhpcyBjb2RlLlxuY29uc3QgU0VNVkVSX1NQRUNfVkVSU0lPTiA9ICcyLjAuMCdcblxuY29uc3QgTUFYX0xFTkdUSCA9IDI1NlxuY29uc3QgTUFYX1NBRkVfSU5URUdFUiA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyA5MDA3MTk5MjU0NzQwOTkxXG5cbi8vIE1heCBzYWZlIHNlZ21lbnQgbGVuZ3RoIGZvciBjb2VyY2lvbi5cbmNvbnN0IE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggPSAxNlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgU0VNVkVSX1NQRUNfVkVSU0lPTixcbiAgTUFYX0xFTkdUSCxcbiAgTUFYX1NBRkVfSU5URUdFUixcbiAgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCxcbn1cbiIsImNvbnN0IGRlYnVnID0gKFxuICB0eXBlb2YgcHJvY2VzcyA9PT0gJ29iamVjdCcgJiZcbiAgcHJvY2Vzcy5lbnYgJiZcbiAgcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJlxuICAvXFxic2VtdmVyXFxiL2kudGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKVxuKSA/ICguLi5hcmdzKSA9PiBjb25zb2xlLmVycm9yKCdTRU1WRVInLCAuLi5hcmdzKVxuICA6ICgpID0+IHt9XG5cbm1vZHVsZS5leHBvcnRzID0gZGVidWdcbiIsImNvbnN0IG51bWVyaWMgPSAvXlswLTldKyQvXG5jb25zdCBjb21wYXJlSWRlbnRpZmllcnMgPSAoYSwgYikgPT4ge1xuICBjb25zdCBhbnVtID0gbnVtZXJpYy50ZXN0KGEpXG4gIGNvbnN0IGJudW0gPSBudW1lcmljLnRlc3QoYilcblxuICBpZiAoYW51bSAmJiBibnVtKSB7XG4gICAgYSA9ICthXG4gICAgYiA9ICtiXG4gIH1cblxuICByZXR1cm4gYSA9PT0gYiA/IDBcbiAgICA6IChhbnVtICYmICFibnVtKSA/IC0xXG4gICAgOiAoYm51bSAmJiAhYW51bSkgPyAxXG4gICAgOiBhIDwgYiA/IC0xXG4gICAgOiAxXG59XG5cbmNvbnN0IHJjb21wYXJlSWRlbnRpZmllcnMgPSAoYSwgYikgPT4gY29tcGFyZUlkZW50aWZpZXJzKGIsIGEpXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjb21wYXJlSWRlbnRpZmllcnMsXG4gIHJjb21wYXJlSWRlbnRpZmllcnMsXG59XG4iLCIvLyBwYXJzZSBvdXQganVzdCB0aGUgb3B0aW9ucyB3ZSBjYXJlIGFib3V0IHNvIHdlIGFsd2F5cyBnZXQgYSBjb25zaXN0ZW50XG4vLyBvYmogd2l0aCBrZXlzIGluIGEgY29uc2lzdGVudCBvcmRlci5cbmNvbnN0IG9wdHMgPSBbJ2luY2x1ZGVQcmVyZWxlYXNlJywgJ2xvb3NlJywgJ3J0bCddXG5jb25zdCBwYXJzZU9wdGlvbnMgPSBvcHRpb25zID0+XG4gICFvcHRpb25zID8ge31cbiAgOiB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgPyB7IGxvb3NlOiB0cnVlIH1cbiAgOiBvcHRzLmZpbHRlcihrID0+IG9wdGlvbnNba10pLnJlZHVjZSgobywgaykgPT4ge1xuICAgIG9ba10gPSB0cnVlXG4gICAgcmV0dXJuIG9cbiAgfSwge30pXG5tb2R1bGUuZXhwb3J0cyA9IHBhcnNlT3B0aW9uc1xuIiwiY29uc3QgeyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIIH0gPSByZXF1aXJlKCcuL2NvbnN0YW50cycpXG5jb25zdCBkZWJ1ZyA9IHJlcXVpcmUoJy4vZGVidWcnKVxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0ge31cblxuLy8gVGhlIGFjdHVhbCByZWdleHBzIGdvIG9uIGV4cG9ydHMucmVcbmNvbnN0IHJlID0gZXhwb3J0cy5yZSA9IFtdXG5jb25zdCBzcmMgPSBleHBvcnRzLnNyYyA9IFtdXG5jb25zdCB0ID0gZXhwb3J0cy50ID0ge31cbmxldCBSID0gMFxuXG5jb25zdCBjcmVhdGVUb2tlbiA9IChuYW1lLCB2YWx1ZSwgaXNHbG9iYWwpID0+IHtcbiAgY29uc3QgaW5kZXggPSBSKytcbiAgZGVidWcobmFtZSwgaW5kZXgsIHZhbHVlKVxuICB0W25hbWVdID0gaW5kZXhcbiAgc3JjW2luZGV4XSA9IHZhbHVlXG4gIHJlW2luZGV4XSA9IG5ldyBSZWdFeHAodmFsdWUsIGlzR2xvYmFsID8gJ2cnIDogdW5kZWZpbmVkKVxufVxuXG4vLyBUaGUgZm9sbG93aW5nIFJlZ3VsYXIgRXhwcmVzc2lvbnMgY2FuIGJlIHVzZWQgZm9yIHRva2VuaXppbmcsXG4vLyB2YWxpZGF0aW5nLCBhbmQgcGFyc2luZyBTZW1WZXIgdmVyc2lvbiBzdHJpbmdzLlxuXG4vLyAjIyBOdW1lcmljIElkZW50aWZpZXJcbi8vIEEgc2luZ2xlIGAwYCwgb3IgYSBub24temVybyBkaWdpdCBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgZGlnaXRzLlxuXG5jcmVhdGVUb2tlbignTlVNRVJJQ0lERU5USUZJRVInLCAnMHxbMS05XVxcXFxkKicpXG5jcmVhdGVUb2tlbignTlVNRVJJQ0lERU5USUZJRVJMT09TRScsICdbMC05XSsnKVxuXG4vLyAjIyBOb24tbnVtZXJpYyBJZGVudGlmaWVyXG4vLyBaZXJvIG9yIG1vcmUgZGlnaXRzLCBmb2xsb3dlZCBieSBhIGxldHRlciBvciBoeXBoZW4sIGFuZCB0aGVuIHplcm8gb3Jcbi8vIG1vcmUgbGV0dGVycywgZGlnaXRzLCBvciBoeXBoZW5zLlxuXG5jcmVhdGVUb2tlbignTk9OTlVNRVJJQ0lERU5USUZJRVInLCAnXFxcXGQqW2EtekEtWi1dW2EtekEtWjAtOS1dKicpXG5cbi8vICMjIE1haW4gVmVyc2lvblxuLy8gVGhyZWUgZG90LXNlcGFyYXRlZCBudW1lcmljIGlkZW50aWZpZXJzLlxuXG5jcmVhdGVUb2tlbignTUFJTlZFUlNJT04nLCBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJdfSlcXFxcLmAgK1xuICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUl19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgYCgke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSXX0pYClcblxuY3JlYXRlVG9rZW4oJ01BSU5WRVJTSU9OTE9PU0UnLCBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19KWApXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb24gSWRlbnRpZmllclxuLy8gQSBudW1lcmljIGlkZW50aWZpZXIsIG9yIGEgbm9uLW51bWVyaWMgaWRlbnRpZmllci5cblxuY3JlYXRlVG9rZW4oJ1BSRVJFTEVBU0VJREVOVElGSUVSJywgYCg/OiR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJdXG59fCR7c3JjW3QuTk9OTlVNRVJJQ0lERU5USUZJRVJdfSlgKVxuXG5jcmVhdGVUb2tlbignUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRScsIGAoPzoke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSTE9PU0VdXG59fCR7c3JjW3QuTk9OTlVNRVJJQ0lERU5USUZJRVJdfSlgKVxuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uXG4vLyBIeXBoZW4sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIGRvdC1zZXBhcmF0ZWQgcHJlLXJlbGVhc2UgdmVyc2lvblxuLy8gaWRlbnRpZmllcnMuXG5cbmNyZWF0ZVRva2VuKCdQUkVSRUxFQVNFJywgYCg/Oi0oJHtzcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUl1cbn0oPzpcXFxcLiR7c3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJdfSkqKSlgKVxuXG5jcmVhdGVUb2tlbignUFJFUkVMRUFTRUxPT1NFJywgYCg/Oi0/KCR7c3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV1cbn0oPzpcXFxcLiR7c3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV19KSopKWApXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhIElkZW50aWZpZXJcbi8vIEFueSBjb21iaW5hdGlvbiBvZiBkaWdpdHMsIGxldHRlcnMsIG9yIGh5cGhlbnMuXG5cbmNyZWF0ZVRva2VuKCdCVUlMRElERU5USUZJRVInLCAnWzAtOUEtWmEtei1dKycpXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhXG4vLyBQbHVzIHNpZ24sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIHBlcmlvZC1zZXBhcmF0ZWQgYnVpbGQgbWV0YWRhdGFcbi8vIGlkZW50aWZpZXJzLlxuXG5jcmVhdGVUb2tlbignQlVJTEQnLCBgKD86XFxcXCsoJHtzcmNbdC5CVUlMRElERU5USUZJRVJdXG59KD86XFxcXC4ke3NyY1t0LkJVSUxESURFTlRJRklFUl19KSopKWApXG5cbi8vICMjIEZ1bGwgVmVyc2lvbiBTdHJpbmdcbi8vIEEgbWFpbiB2ZXJzaW9uLCBmb2xsb3dlZCBvcHRpb25hbGx5IGJ5IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiBhbmRcbi8vIGJ1aWxkIG1ldGFkYXRhLlxuXG4vLyBOb3RlIHRoYXQgdGhlIG9ubHkgbWFqb3IsIG1pbm9yLCBwYXRjaCwgYW5kIHByZS1yZWxlYXNlIHNlY3Rpb25zIG9mXG4vLyB0aGUgdmVyc2lvbiBzdHJpbmcgYXJlIGNhcHR1cmluZyBncm91cHMuICBUaGUgYnVpbGQgbWV0YWRhdGEgaXMgbm90IGFcbi8vIGNhcHR1cmluZyBncm91cCwgYmVjYXVzZSBpdCBzaG91bGQgbm90IGV2ZXIgYmUgdXNlZCBpbiB2ZXJzaW9uXG4vLyBjb21wYXJpc29uLlxuXG5jcmVhdGVUb2tlbignRlVMTFBMQUlOJywgYHY/JHtzcmNbdC5NQUlOVkVSU0lPTl1cbn0ke3NyY1t0LlBSRVJFTEVBU0VdfT8ke1xuICBzcmNbdC5CVUlMRF19P2ApXG5cbmNyZWF0ZVRva2VuKCdGVUxMJywgYF4ke3NyY1t0LkZVTExQTEFJTl19JGApXG5cbi8vIGxpa2UgZnVsbCwgYnV0IGFsbG93cyB2MS4yLjMgYW5kID0xLjIuMywgd2hpY2ggcGVvcGxlIGRvIHNvbWV0aW1lcy5cbi8vIGFsc28sIDEuMC4wYWxwaGExIChwcmVyZWxlYXNlIHdpdGhvdXQgdGhlIGh5cGhlbikgd2hpY2ggaXMgcHJldHR5XG4vLyBjb21tb24gaW4gdGhlIG5wbSByZWdpc3RyeS5cbmNyZWF0ZVRva2VuKCdMT09TRVBMQUlOJywgYFt2PVxcXFxzXSoke3NyY1t0Lk1BSU5WRVJTSU9OTE9PU0VdXG59JHtzcmNbdC5QUkVSRUxFQVNFTE9PU0VdfT8ke1xuICBzcmNbdC5CVUlMRF19P2ApXG5cbmNyZWF0ZVRva2VuKCdMT09TRScsIGBeJHtzcmNbdC5MT09TRVBMQUlOXX0kYClcblxuY3JlYXRlVG9rZW4oJ0dUTFQnLCAnKCg/Ojx8Pik/PT8pJylcblxuLy8gU29tZXRoaW5nIGxpa2UgXCIyLipcIiBvciBcIjEuMi54XCIuXG4vLyBOb3RlIHRoYXQgXCJ4LnhcIiBpcyBhIHZhbGlkIHhSYW5nZSBpZGVudGlmZXIsIG1lYW5pbmcgXCJhbnkgdmVyc2lvblwiXG4vLyBPbmx5IHRoZSBmaXJzdCBpdGVtIGlzIHN0cmljdGx5IHJlcXVpcmVkLlxuY3JlYXRlVG9rZW4oJ1hSQU5HRUlERU5USUZJRVJMT09TRScsIGAke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSTE9PU0VdfXx4fFh8XFxcXCpgKVxuY3JlYXRlVG9rZW4oJ1hSQU5HRUlERU5USUZJRVInLCBgJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUl19fHh8WHxcXFxcKmApXG5cbmNyZWF0ZVRva2VuKCdYUkFOR0VQTEFJTicsIGBbdj1cXFxcc10qKCR7c3JjW3QuWFJBTkdFSURFTlRJRklFUl19KWAgK1xuICAgICAgICAgICAgICAgICAgIGAoPzpcXFxcLigke3NyY1t0LlhSQU5HRUlERU5USUZJRVJdfSlgICtcbiAgICAgICAgICAgICAgICAgICBgKD86XFxcXC4oJHtzcmNbdC5YUkFOR0VJREVOVElGSUVSXX0pYCArXG4gICAgICAgICAgICAgICAgICAgYCg/OiR7c3JjW3QuUFJFUkVMRUFTRV19KT8ke1xuICAgICAgICAgICAgICAgICAgICAgc3JjW3QuQlVJTERdfT9gICtcbiAgICAgICAgICAgICAgICAgICBgKT8pP2ApXG5cbmNyZWF0ZVRva2VuKCdYUkFOR0VQTEFJTkxPT1NFJywgYFt2PVxcXFxzXSooJHtzcmNbdC5YUkFOR0VJREVOVElGSUVSTE9PU0VdfSlgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAoPzpcXFxcLigke3NyY1t0LlhSQU5HRUlERU5USUZJRVJMT09TRV19KWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCg/OlxcXFwuKCR7c3JjW3QuWFJBTkdFSURFTlRJRklFUkxPT1NFXX0pYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKD86JHtzcmNbdC5QUkVSRUxFQVNFTE9PU0VdfSk/JHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjW3QuQlVJTERdfT9gICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGApPyk/YClcblxuY3JlYXRlVG9rZW4oJ1hSQU5HRScsIGBeJHtzcmNbdC5HVExUXX1cXFxccyoke3NyY1t0LlhSQU5HRVBMQUlOXX0kYClcbmNyZWF0ZVRva2VuKCdYUkFOR0VMT09TRScsIGBeJHtzcmNbdC5HVExUXX1cXFxccyoke3NyY1t0LlhSQU5HRVBMQUlOTE9PU0VdfSRgKVxuXG4vLyBDb2VyY2lvbi5cbi8vIEV4dHJhY3QgYW55dGhpbmcgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBiZSBhIHBhcnQgb2YgYSB2YWxpZCBzZW12ZXJcbmNyZWF0ZVRva2VuKCdDT0VSQ0UnLCBgJHsnKF58W15cXFxcZF0pJyArXG4gICAgICAgICAgICAgICcoXFxcXGR7MSwnfSR7TUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSH19KWAgK1xuICAgICAgICAgICAgICBgKD86XFxcXC4oXFxcXGR7MSwke01BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEh9fSkpP2AgK1xuICAgICAgICAgICAgICBgKD86XFxcXC4oXFxcXGR7MSwke01BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEh9fSkpP2AgK1xuICAgICAgICAgICAgICBgKD86JHxbXlxcXFxkXSlgKVxuY3JlYXRlVG9rZW4oJ0NPRVJDRVJUTCcsIHNyY1t0LkNPRVJDRV0sIHRydWUpXG5cbi8vIFRpbGRlIHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJyZWFzb25hYmx5IGF0IG9yIGdyZWF0ZXIgdGhhblwiXG5jcmVhdGVUb2tlbignTE9ORVRJTERFJywgJyg/On4+PyknKVxuXG5jcmVhdGVUb2tlbignVElMREVUUklNJywgYChcXFxccyopJHtzcmNbdC5MT05FVElMREVdfVxcXFxzK2AsIHRydWUpXG5leHBvcnRzLnRpbGRlVHJpbVJlcGxhY2UgPSAnJDF+J1xuXG5jcmVhdGVUb2tlbignVElMREUnLCBgXiR7c3JjW3QuTE9ORVRJTERFXX0ke3NyY1t0LlhSQU5HRVBMQUlOXX0kYClcbmNyZWF0ZVRva2VuKCdUSUxERUxPT1NFJywgYF4ke3NyY1t0LkxPTkVUSUxERV19JHtzcmNbdC5YUkFOR0VQTEFJTkxPT1NFXX0kYClcblxuLy8gQ2FyZXQgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcImF0IGxlYXN0IGFuZCBiYWNrd2FyZHMgY29tcGF0aWJsZSB3aXRoXCJcbmNyZWF0ZVRva2VuKCdMT05FQ0FSRVQnLCAnKD86XFxcXF4pJylcblxuY3JlYXRlVG9rZW4oJ0NBUkVUVFJJTScsIGAoXFxcXHMqKSR7c3JjW3QuTE9ORUNBUkVUXX1cXFxccytgLCB0cnVlKVxuZXhwb3J0cy5jYXJldFRyaW1SZXBsYWNlID0gJyQxXidcblxuY3JlYXRlVG9rZW4oJ0NBUkVUJywgYF4ke3NyY1t0LkxPTkVDQVJFVF19JHtzcmNbdC5YUkFOR0VQTEFJTl19JGApXG5jcmVhdGVUb2tlbignQ0FSRVRMT09TRScsIGBeJHtzcmNbdC5MT05FQ0FSRVRdfSR7c3JjW3QuWFJBTkdFUExBSU5MT09TRV19JGApXG5cbi8vIEEgc2ltcGxlIGd0L2x0L2VxIHRoaW5nLCBvciBqdXN0IFwiXCIgdG8gaW5kaWNhdGUgXCJhbnkgdmVyc2lvblwiXG5jcmVhdGVUb2tlbignQ09NUEFSQVRPUkxPT1NFJywgYF4ke3NyY1t0LkdUTFRdfVxcXFxzKigke3NyY1t0LkxPT1NFUExBSU5dfSkkfF4kYClcbmNyZWF0ZVRva2VuKCdDT01QQVJBVE9SJywgYF4ke3NyY1t0LkdUTFRdfVxcXFxzKigke3NyY1t0LkZVTExQTEFJTl19KSR8XiRgKVxuXG4vLyBBbiBleHByZXNzaW9uIHRvIHN0cmlwIGFueSB3aGl0ZXNwYWNlIGJldHdlZW4gdGhlIGd0bHQgYW5kIHRoZSB0aGluZ1xuLy8gaXQgbW9kaWZpZXMsIHNvIHRoYXQgYD4gMS4yLjNgID09PiBgPjEuMi4zYFxuY3JlYXRlVG9rZW4oJ0NPTVBBUkFUT1JUUklNJywgYChcXFxccyopJHtzcmNbdC5HVExUXVxufVxcXFxzKigke3NyY1t0LkxPT1NFUExBSU5dfXwke3NyY1t0LlhSQU5HRVBMQUlOXX0pYCwgdHJ1ZSlcbmV4cG9ydHMuY29tcGFyYXRvclRyaW1SZXBsYWNlID0gJyQxJDIkMydcblxuLy8gU29tZXRoaW5nIGxpa2UgYDEuMi4zIC0gMS4yLjRgXG4vLyBOb3RlIHRoYXQgdGhlc2UgYWxsIHVzZSB0aGUgbG9vc2UgZm9ybSwgYmVjYXVzZSB0aGV5J2xsIGJlXG4vLyBjaGVja2VkIGFnYWluc3QgZWl0aGVyIHRoZSBzdHJpY3Qgb3IgbG9vc2UgY29tcGFyYXRvciBmb3JtXG4vLyBsYXRlci5cbmNyZWF0ZVRva2VuKCdIWVBIRU5SQU5HRScsIGBeXFxcXHMqKCR7c3JjW3QuWFJBTkdFUExBSU5dfSlgICtcbiAgICAgICAgICAgICAgICAgICBgXFxcXHMrLVxcXFxzK2AgK1xuICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5YUkFOR0VQTEFJTl19KWAgK1xuICAgICAgICAgICAgICAgICAgIGBcXFxccyokYClcblxuY3JlYXRlVG9rZW4oJ0hZUEhFTlJBTkdFTE9PU0UnLCBgXlxcXFxzKigke3NyY1t0LlhSQU5HRVBMQUlOTE9PU0VdfSlgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGBcXFxccystXFxcXHMrYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuWFJBTkdFUExBSU5MT09TRV19KWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYFxcXFxzKiRgKVxuXG4vLyBTdGFyIHJhbmdlcyBiYXNpY2FsbHkganVzdCBhbGxvdyBhbnl0aGluZyBhdCBhbGwuXG5jcmVhdGVUb2tlbignU1RBUicsICcoPHw+KT89P1xcXFxzKlxcXFwqJylcbi8vID49MC4wLjAgaXMgbGlrZSBhIHN0YXJcbmNyZWF0ZVRva2VuKCdHVEUwJywgJ15cXFxccyo+PVxcXFxzKjBcXFxcLjBcXFxcLjBcXFxccyokJylcbmNyZWF0ZVRva2VuKCdHVEUwUFJFJywgJ15cXFxccyo+PVxcXFxzKjBcXFxcLjBcXFxcLjAtMFxcXFxzKiQnKVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2MVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdi5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInYzXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92Mi5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInY0XCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92My5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInY1XCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92NC5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIk5JTFwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfbmlsLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmVyc2lvblwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdmVyc2lvbi5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInZhbGlkYXRlXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92YWxpZGF0ZS5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInN0cmluZ2lmeVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfc3RyaW5naWZ5LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicGFyc2VcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3BhcnNlLmRlZmF1bHQ7XG4gIH1cbn0pO1xuXG52YXIgX3YgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YxLmpzXCIpKTtcblxudmFyIF92MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjMuanNcIikpO1xuXG52YXIgX3YzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92NC5qc1wiKSk7XG5cbnZhciBfdjQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3Y1LmpzXCIpKTtcblxudmFyIF9uaWwgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL25pbC5qc1wiKSk7XG5cbnZhciBfdmVyc2lvbiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmVyc2lvbi5qc1wiKSk7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxudmFyIF9zdHJpbmdpZnkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKSk7XG5cbnZhciBfcGFyc2UgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3BhcnNlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxuLypcbiAqIEJyb3dzZXItY29tcGF0aWJsZSBKYXZhU2NyaXB0IE1ENVxuICpcbiAqIE1vZGlmaWNhdGlvbiBvZiBKYXZhU2NyaXB0IE1ENVxuICogaHR0cHM6Ly9naXRodWIuY29tL2JsdWVpbXAvSmF2YVNjcmlwdC1NRDVcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMSwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKlxuICogQmFzZWQgb25cbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUlNBIERhdGEgU2VjdXJpdHksIEluYy4gTUQ1IE1lc3NhZ2VcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXG4gKiBWZXJzaW9uIDIuMiBDb3B5cmlnaHQgKEMpIFBhdWwgSm9obnN0b24gMTk5OSAtIDIwMDlcbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cbiAqL1xuZnVuY3Rpb24gbWQ1KGJ5dGVzKSB7XG4gIGlmICh0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgbXNnID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGJ5dGVzKSk7IC8vIFVURjggZXNjYXBlXG5cbiAgICBieXRlcyA9IG5ldyBVaW50OEFycmF5KG1zZy5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyArK2kpIHtcbiAgICAgIGJ5dGVzW2ldID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1kNVRvSGV4RW5jb2RlZEFycmF5KHdvcmRzVG9NZDUoYnl0ZXNUb1dvcmRzKGJ5dGVzKSwgYnl0ZXMubGVuZ3RoICogOCkpO1xufVxuLypcbiAqIENvbnZlcnQgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcyB0byBhbiBhcnJheSBvZiBieXRlc1xuICovXG5cblxuZnVuY3Rpb24gbWQ1VG9IZXhFbmNvZGVkQXJyYXkoaW5wdXQpIHtcbiAgY29uc3Qgb3V0cHV0ID0gW107XG4gIGNvbnN0IGxlbmd0aDMyID0gaW5wdXQubGVuZ3RoICogMzI7XG4gIGNvbnN0IGhleFRhYiA9ICcwMTIzNDU2Nzg5YWJjZGVmJztcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDMyOyBpICs9IDgpIHtcbiAgICBjb25zdCB4ID0gaW5wdXRbaSA+PiA1XSA+Pj4gaSAlIDMyICYgMHhmZjtcbiAgICBjb25zdCBoZXggPSBwYXJzZUludChoZXhUYWIuY2hhckF0KHggPj4+IDQgJiAweDBmKSArIGhleFRhYi5jaGFyQXQoeCAmIDB4MGYpLCAxNik7XG4gICAgb3V0cHV0LnB1c2goaGV4KTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZSBvdXRwdXQgbGVuZ3RoIHdpdGggcGFkZGluZyBhbmQgYml0IGxlbmd0aFxuICovXG5cblxuZnVuY3Rpb24gZ2V0T3V0cHV0TGVuZ3RoKGlucHV0TGVuZ3RoOCkge1xuICByZXR1cm4gKGlucHV0TGVuZ3RoOCArIDY0ID4+PiA5IDw8IDQpICsgMTQgKyAxO1xufVxuLypcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGguXG4gKi9cblxuXG5mdW5jdGlvbiB3b3Jkc1RvTWQ1KHgsIGxlbikge1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICB4W2xlbiA+PiA1XSB8PSAweDgwIDw8IGxlbiAlIDMyO1xuICB4W2dldE91dHB1dExlbmd0aChsZW4pIC0gMV0gPSBsZW47XG4gIGxldCBhID0gMTczMjU4NDE5MztcbiAgbGV0IGIgPSAtMjcxNzMzODc5O1xuICBsZXQgYyA9IC0xNzMyNTg0MTk0O1xuICBsZXQgZCA9IDI3MTczMzg3ODtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgY29uc3Qgb2xkYSA9IGE7XG4gICAgY29uc3Qgb2xkYiA9IGI7XG4gICAgY29uc3Qgb2xkYyA9IGM7XG4gICAgY29uc3Qgb2xkZCA9IGQ7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaV0sIDcsIC02ODA4NzY5MzYpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyAxXSwgMTIsIC0zODk1NjQ1ODYpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAyXSwgMTcsIDYwNjEwNTgxOSk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDNdLCAyMiwgLTEwNDQ1MjUzMzApO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyA0XSwgNywgLTE3NjQxODg5Nyk7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDVdLCAxMiwgMTIwMDA4MDQyNik7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDZdLCAxNywgLTE0NzMyMzEzNDEpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyA3XSwgMjIsIC00NTcwNTk4Myk7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDhdLCA3LCAxNzcwMDM1NDE2KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgOV0sIDEyLCAtMTk1ODQxNDQxNyk7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDEwXSwgMTcsIC00MjA2Myk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDExXSwgMjIsIC0xOTkwNDA0MTYyKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgMTJdLCA3LCAxODA0NjAzNjgyKTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgMTNdLCAxMiwgLTQwMzQxMTAxKTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMTRdLCAxNywgLTE1MDIwMDIyOTApO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAxNV0sIDIyLCAxMjM2NTM1MzI5KTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgMV0sIDUsIC0xNjU3OTY1MTApO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyA2XSwgOSwgLTEwNjk1MDE2MzIpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE0LCA2NDM3MTc3MTMpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2ldLCAyMCwgLTM3Mzg5NzMwMik7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDVdLCA1LCAtNzAxNTU4NjkxKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMTBdLCA5LCAzODAxNjA4Myk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTQsIC02NjA0NzgzMzUpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA0XSwgMjAsIC00MDU1Mzc4NDgpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA5XSwgNSwgNTY4NDQ2NDM4KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMTRdLCA5LCAtMTAxOTgwMzY5MCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDNdLCAxNCwgLTE4NzM2Mzk2MSk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDhdLCAyMCwgMTE2MzUzMTUwMSk7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDEzXSwgNSwgLTE0NDQ2ODE0NjcpO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyAyXSwgOSwgLTUxNDAzNzg0KTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgN10sIDE0LCAxNzM1MzI4NDczKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNCwgLTM3ODU1OCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE2LCAxODM5MDMwNTYyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTRdLCAyMywgLTM1MzA5NTU2KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgMV0sIDQsIC0xNTMwOTkyMDYwKTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgNF0sIDExLCAxMjcyODkzMzUzKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDQsIDY4MTI3OTE3NCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaV0sIDExLCAtMzU4NTM3MjIyKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgM10sIDE2LCAtNzIyNTIxOTc5KTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgNl0sIDIzLCA3NjAyOTE4OSk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDldLCA0LCAtNjQwMzY0NDg3KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTYsIDUzMDc0MjUyMCk7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDJdLCAyMywgLTk5NTMzODY1MSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaV0sIDYsIC0xOTg2MzA4NDQpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyA3XSwgMTAsIDExMjY4OTE0MTUpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDVdLCAyMSwgLTU3NDM0MDU1KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgMTJdLCA2LCAxNzAwNDg1NTcxKTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgM10sIDEwLCAtMTg5NDk4NjYwNik7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDEwXSwgMTUsIC0xMDUxNTIzKTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgMV0sIDIxLCAtMjA1NDkyMjc5OSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDhdLCA2LCAxODczMzEzMzU5KTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgMTVdLCAxMCwgLTMwNjExNzQ0KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgNl0sIDE1LCAtMTU2MDE5ODM4MCk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDEzXSwgMjEsIDEzMDkxNTE2NDkpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyA0XSwgNiwgLTE0NTUyMzA3MCk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDExXSwgMTAsIC0xMTIwMjEwMzc5KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMl0sIDE1LCA3MTg3ODcyNTkpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyA5XSwgMjEsIC0zNDM0ODU1NTEpO1xuICAgIGEgPSBzYWZlQWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlQWRkKGIsIG9sZGIpO1xuICAgIGMgPSBzYWZlQWRkKGMsIG9sZGMpO1xuICAgIGQgPSBzYWZlQWRkKGQsIG9sZGQpO1xuICB9XG5cbiAgcmV0dXJuIFthLCBiLCBjLCBkXTtcbn1cbi8qXG4gKiBDb252ZXJ0IGFuIGFycmF5IGJ5dGVzIHRvIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHNcbiAqIENoYXJhY3RlcnMgPjI1NSBoYXZlIHRoZWlyIGhpZ2gtYnl0ZSBzaWxlbnRseSBpZ25vcmVkLlxuICovXG5cblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmRzKGlucHV0KSB7XG4gIGlmIChpbnB1dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsZW5ndGg4ID0gaW5wdXQubGVuZ3RoICogODtcbiAgY29uc3Qgb3V0cHV0ID0gbmV3IFVpbnQzMkFycmF5KGdldE91dHB1dExlbmd0aChsZW5ndGg4KSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg4OyBpICs9IDgpIHtcbiAgICBvdXRwdXRbaSA+PiA1XSB8PSAoaW5wdXRbaSAvIDhdICYgMHhmZikgPDwgaSAlIDMyO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5cblxuZnVuY3Rpb24gc2FmZUFkZCh4LCB5KSB7XG4gIGNvbnN0IGxzdyA9ICh4ICYgMHhmZmZmKSArICh5ICYgMHhmZmZmKTtcbiAgY29uc3QgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiBtc3cgPDwgMTYgfCBsc3cgJiAweGZmZmY7XG59XG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5cblxuZnVuY3Rpb24gYml0Um90YXRlTGVmdChudW0sIGNudCkge1xuICByZXR1cm4gbnVtIDw8IGNudCB8IG51bSA+Pj4gMzIgLSBjbnQ7XG59XG4vKlxuICogVGhlc2UgZnVuY3Rpb25zIGltcGxlbWVudCB0aGUgZm91ciBiYXNpYyBvcGVyYXRpb25zIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIG1kNWNtbihxLCBhLCBiLCB4LCBzLCB0KSB7XG4gIHJldHVybiBzYWZlQWRkKGJpdFJvdGF0ZUxlZnQoc2FmZUFkZChzYWZlQWRkKGEsIHEpLCBzYWZlQWRkKHgsIHQpKSwgcyksIGIpO1xufVxuXG5mdW5jdGlvbiBtZDVmZihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiAmIGMgfCB+YiAmIGQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBtZDVnZyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiAmIGQgfCBjICYgfmQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBtZDVoaChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1aWkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGMgXiAoYiB8IH5kKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbnZhciBfZGVmYXVsdCA9IG1kNTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xudmFyIF9kZWZhdWx0ID0gJzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCc7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF92YWxpZGF0ZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmFsaWRhdGUuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBwYXJzZSh1dWlkKSB7XG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW52YWxpZCBVVUlEJyk7XG4gIH1cblxuICBsZXQgdjtcbiAgY29uc3QgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMTYpOyAvLyBQYXJzZSAjIyMjIyMjIy0uLi4uLS4uLi4tLi4uLi0uLi4uLi4uLi4uLi5cblxuICBhcnJbMF0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMCwgOCksIDE2KSkgPj4+IDI0O1xuICBhcnJbMV0gPSB2ID4+PiAxNiAmIDB4ZmY7XG4gIGFyclsyXSA9IHYgPj4+IDggJiAweGZmO1xuICBhcnJbM10gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tIyMjIy0uLi4uLS4uLi4tLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzRdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDksIDEzKSwgMTYpKSA+Pj4gODtcbiAgYXJyWzVdID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLS4uLi4tIyMjIy0uLi4uLS4uLi4uLi4uLi4uLlxuXG4gIGFycls2XSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSgxNCwgMTgpLCAxNikpID4+PiA4O1xuICBhcnJbN10gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tLi4uLi0uLi4uLSMjIyMtLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzhdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDE5LCAyMyksIDE2KSkgPj4+IDg7XG4gIGFycls5XSA9IHYgJiAweGZmOyAvLyBQYXJzZSAuLi4uLi4uLi0uLi4uLS4uLi4tLi4uLi0jIyMjIyMjIyMjIyNcbiAgLy8gKFVzZSBcIi9cIiB0byBhdm9pZCAzMi1iaXQgdHJ1bmNhdGlvbiB3aGVuIGJpdC1zaGlmdGluZyBoaWdoLW9yZGVyIGJ5dGVzKVxuXG4gIGFyclsxMF0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMjQsIDM2KSwgMTYpKSAvIDB4MTAwMDAwMDAwMDAgJiAweGZmO1xuICBhcnJbMTFdID0gdiAvIDB4MTAwMDAwMDAwICYgMHhmZjtcbiAgYXJyWzEyXSA9IHYgPj4+IDI0ICYgMHhmZjtcbiAgYXJyWzEzXSA9IHYgPj4+IDE2ICYgMHhmZjtcbiAgYXJyWzE0XSA9IHYgPj4+IDggJiAweGZmO1xuICBhcnJbMTVdID0gdiAmIDB4ZmY7XG4gIHJldHVybiBhcnI7XG59XG5cbnZhciBfZGVmYXVsdCA9IHBhcnNlO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG52YXIgX2RlZmF1bHQgPSAvXig/OlswLTlhLWZdezh9LVswLTlhLWZdezR9LVsxLTVdWzAtOWEtZl17M30tWzg5YWJdWzAtOWEtZl17M30tWzAtOWEtZl17MTJ9fDAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCkkL2k7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHJuZztcbi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuIEluIHRoZSBicm93c2VyIHdlIHRoZXJlZm9yZVxuLy8gcmVxdWlyZSB0aGUgY3J5cHRvIEFQSSBhbmQgZG8gbm90IHN1cHBvcnQgYnVpbHQtaW4gZmFsbGJhY2sgdG8gbG93ZXIgcXVhbGl0eSByYW5kb20gbnVtYmVyXG4vLyBnZW5lcmF0b3JzIChsaWtlIE1hdGgucmFuZG9tKCkpLlxubGV0IGdldFJhbmRvbVZhbHVlcztcbmNvbnN0IHJuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xuXG5mdW5jdGlvbiBybmcoKSB7XG4gIC8vIGxhenkgbG9hZCBzbyB0aGF0IGVudmlyb25tZW50cyB0aGF0IG5lZWQgdG8gcG9seWZpbGwgaGF2ZSBhIGNoYW5jZSB0byBkbyBzb1xuICBpZiAoIWdldFJhbmRvbVZhbHVlcykge1xuICAgIC8vIGdldFJhbmRvbVZhbHVlcyBuZWVkcyB0byBiZSBpbnZva2VkIGluIGEgY29udGV4dCB3aGVyZSBcInRoaXNcIiBpcyBhIENyeXB0byBpbXBsZW1lbnRhdGlvbi4gQWxzbyxcbiAgICAvLyBmaW5kIHRoZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBjcnlwdG8gKG1zQ3J5cHRvKSBvbiBJRTExLlxuICAgIGdldFJhbmRvbVZhbHVlcyA9IHR5cGVvZiBjcnlwdG8gIT09ICd1bmRlZmluZWQnICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKGNyeXB0bykgfHwgdHlwZW9mIG1zQ3J5cHRvICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzID09PSAnZnVuY3Rpb24nICYmIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKG1zQ3J5cHRvKTtcblxuICAgIGlmICghZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoKSBub3Qgc3VwcG9ydGVkLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkI2dldHJhbmRvbXZhbHVlcy1ub3Qtc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbi8vIEFkYXB0ZWQgZnJvbSBDaHJpcyBWZW5lc3MnIFNIQTEgY29kZSBhdFxuLy8gaHR0cDovL3d3dy5tb3ZhYmxlLXR5cGUuY28udWsvc2NyaXB0cy9zaGExLmh0bWxcbmZ1bmN0aW9uIGYocywgeCwgeSwgeikge1xuICBzd2l0Y2ggKHMpIHtcbiAgICBjYXNlIDA6XG4gICAgICByZXR1cm4geCAmIHkgXiB+eCAmIHo7XG5cbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4geCBeIHkgXiB6O1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuIHggJiB5IF4geCAmIHogXiB5ICYgejtcblxuICAgIGNhc2UgMzpcbiAgICAgIHJldHVybiB4IF4geSBeIHo7XG4gIH1cbn1cblxuZnVuY3Rpb24gUk9UTCh4LCBuKSB7XG4gIHJldHVybiB4IDw8IG4gfCB4ID4+PiAzMiAtIG47XG59XG5cbmZ1bmN0aW9uIHNoYTEoYnl0ZXMpIHtcbiAgY29uc3QgSyA9IFsweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjLCAweGNhNjJjMWQ2XTtcbiAgY29uc3QgSCA9IFsweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LCAweGMzZDJlMWYwXTtcblxuICBpZiAodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1zZyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChieXRlcykpOyAvLyBVVEY4IGVzY2FwZVxuXG4gICAgYnl0ZXMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgKytpKSB7XG4gICAgICBieXRlcy5wdXNoKG1zZy5jaGFyQ29kZUF0KGkpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoYnl0ZXMpKSB7XG4gICAgLy8gQ29udmVydCBBcnJheS1saWtlIHRvIEFycmF5XG4gICAgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChieXRlcyk7XG4gIH1cblxuICBieXRlcy5wdXNoKDB4ODApO1xuICBjb25zdCBsID0gYnl0ZXMubGVuZ3RoIC8gNCArIDI7XG4gIGNvbnN0IE4gPSBNYXRoLmNlaWwobCAvIDE2KTtcbiAgY29uc3QgTSA9IG5ldyBBcnJheShOKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IE47ICsraSkge1xuICAgIGNvbnN0IGFyciA9IG5ldyBVaW50MzJBcnJheSgxNik7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IDE2OyArK2opIHtcbiAgICAgIGFycltqXSA9IGJ5dGVzW2kgKiA2NCArIGogKiA0XSA8PCAyNCB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgMV0gPDwgMTYgfCBieXRlc1tpICogNjQgKyBqICogNCArIDJdIDw8IDggfCBieXRlc1tpICogNjQgKyBqICogNCArIDNdO1xuICAgIH1cblxuICAgIE1baV0gPSBhcnI7XG4gIH1cblxuICBNW04gLSAxXVsxNF0gPSAoYnl0ZXMubGVuZ3RoIC0gMSkgKiA4IC8gTWF0aC5wb3coMiwgMzIpO1xuICBNW04gLSAxXVsxNF0gPSBNYXRoLmZsb29yKE1bTiAtIDFdWzE0XSk7XG4gIE1bTiAtIDFdWzE1XSA9IChieXRlcy5sZW5ndGggLSAxKSAqIDggJiAweGZmZmZmZmZmO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7XG4gICAgY29uc3QgVyA9IG5ldyBVaW50MzJBcnJheSg4MCk7XG5cbiAgICBmb3IgKGxldCB0ID0gMDsgdCA8IDE2OyArK3QpIHtcbiAgICAgIFdbdF0gPSBNW2ldW3RdO1xuICAgIH1cblxuICAgIGZvciAobGV0IHQgPSAxNjsgdCA8IDgwOyArK3QpIHtcbiAgICAgIFdbdF0gPSBST1RMKFdbdCAtIDNdIF4gV1t0IC0gOF0gXiBXW3QgLSAxNF0gXiBXW3QgLSAxNl0sIDEpO1xuICAgIH1cblxuICAgIGxldCBhID0gSFswXTtcbiAgICBsZXQgYiA9IEhbMV07XG4gICAgbGV0IGMgPSBIWzJdO1xuICAgIGxldCBkID0gSFszXTtcbiAgICBsZXQgZSA9IEhbNF07XG5cbiAgICBmb3IgKGxldCB0ID0gMDsgdCA8IDgwOyArK3QpIHtcbiAgICAgIGNvbnN0IHMgPSBNYXRoLmZsb29yKHQgLyAyMCk7XG4gICAgICBjb25zdCBUID0gUk9UTChhLCA1KSArIGYocywgYiwgYywgZCkgKyBlICsgS1tzXSArIFdbdF0gPj4+IDA7XG4gICAgICBlID0gZDtcbiAgICAgIGQgPSBjO1xuICAgICAgYyA9IFJPVEwoYiwgMzApID4+PiAwO1xuICAgICAgYiA9IGE7XG4gICAgICBhID0gVDtcbiAgICB9XG5cbiAgICBIWzBdID0gSFswXSArIGEgPj4+IDA7XG4gICAgSFsxXSA9IEhbMV0gKyBiID4+PiAwO1xuICAgIEhbMl0gPSBIWzJdICsgYyA+Pj4gMDtcbiAgICBIWzNdID0gSFszXSArIGQgPj4+IDA7XG4gICAgSFs0XSA9IEhbNF0gKyBlID4+PiAwO1xuICB9XG5cbiAgcmV0dXJuIFtIWzBdID4+IDI0ICYgMHhmZiwgSFswXSA+PiAxNiAmIDB4ZmYsIEhbMF0gPj4gOCAmIDB4ZmYsIEhbMF0gJiAweGZmLCBIWzFdID4+IDI0ICYgMHhmZiwgSFsxXSA+PiAxNiAmIDB4ZmYsIEhbMV0gPj4gOCAmIDB4ZmYsIEhbMV0gJiAweGZmLCBIWzJdID4+IDI0ICYgMHhmZiwgSFsyXSA+PiAxNiAmIDB4ZmYsIEhbMl0gPj4gOCAmIDB4ZmYsIEhbMl0gJiAweGZmLCBIWzNdID4+IDI0ICYgMHhmZiwgSFszXSA+PiAxNiAmIDB4ZmYsIEhbM10gPj4gOCAmIDB4ZmYsIEhbM10gJiAweGZmLCBIWzRdID4+IDI0ICYgMHhmZiwgSFs0XSA+PiAxNiAmIDB4ZmYsIEhbNF0gPj4gOCAmIDB4ZmYsIEhbNF0gJiAweGZmXTtcbn1cblxudmFyIF9kZWZhdWx0ID0gc2hhMTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3ZhbGlkYXRlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92YWxpZGF0ZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xuY29uc3QgYnl0ZVRvSGV4ID0gW107XG5cbmZvciAobGV0IGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgYnl0ZVRvSGV4LnB1c2goKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigxKSk7XG59XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeShhcnIsIG9mZnNldCA9IDApIHtcbiAgLy8gTm90ZTogQmUgY2FyZWZ1bCBlZGl0aW5nIHRoaXMgY29kZSEgIEl0J3MgYmVlbiB0dW5lZCBmb3IgcGVyZm9ybWFuY2VcbiAgLy8gYW5kIHdvcmtzIGluIHdheXMgeW91IG1heSBub3QgZXhwZWN0LiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkL3B1bGwvNDM0XG4gIGNvbnN0IHV1aWQgPSAoYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAwXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDFdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMl1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAzXV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDRdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgNV1dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA2XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDddXSArICctJyArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgOF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA5XV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDEwXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDExXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDEyXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDEzXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDE0XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDE1XV0pLnRvTG93ZXJDYXNlKCk7IC8vIENvbnNpc3RlbmN5IGNoZWNrIGZvciB2YWxpZCBVVUlELiAgSWYgdGhpcyB0aHJvd3MsIGl0J3MgbGlrZWx5IGR1ZSB0byBvbmVcbiAgLy8gb2YgdGhlIGZvbGxvd2luZzpcbiAgLy8gLSBPbmUgb3IgbW9yZSBpbnB1dCBhcnJheSB2YWx1ZXMgZG9uJ3QgbWFwIHRvIGEgaGV4IG9jdGV0IChsZWFkaW5nIHRvXG4gIC8vIFwidW5kZWZpbmVkXCIgaW4gdGhlIHV1aWQpXG4gIC8vIC0gSW52YWxpZCBpbnB1dCB2YWx1ZXMgZm9yIHRoZSBSRkMgYHZlcnNpb25gIG9yIGB2YXJpYW50YCBmaWVsZHNcblxuICBpZiAoISgwLCBfdmFsaWRhdGUuZGVmYXVsdCkodXVpZCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ1N0cmluZ2lmaWVkIFVVSUQgaXMgaW52YWxpZCcpO1xuICB9XG5cbiAgcmV0dXJuIHV1aWQ7XG59XG5cbnZhciBfZGVmYXVsdCA9IHN0cmluZ2lmeTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3JuZyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vcm5nLmpzXCIpKTtcblxudmFyIF9zdHJpbmdpZnkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vICoqYHYxKClgIC0gR2VuZXJhdGUgdGltZS1iYXNlZCBVVUlEKipcbi8vXG4vLyBJbnNwaXJlZCBieSBodHRwczovL2dpdGh1Yi5jb20vTGlvc0svVVVJRC5qc1xuLy8gYW5kIGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS91dWlkLmh0bWxcbmxldCBfbm9kZUlkO1xuXG5sZXQgX2Nsb2Nrc2VxOyAvLyBQcmV2aW91cyB1dWlkIGNyZWF0aW9uIHRpbWVcblxuXG5sZXQgX2xhc3RNU2VjcyA9IDA7XG5sZXQgX2xhc3ROU2VjcyA9IDA7IC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQgZm9yIEFQSSBkZXRhaWxzXG5cbmZ1bmN0aW9uIHYxKG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIGxldCBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuICBjb25zdCBiID0gYnVmIHx8IG5ldyBBcnJheSgxNik7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBsZXQgbm9kZSA9IG9wdGlvbnMubm9kZSB8fCBfbm9kZUlkO1xuICBsZXQgY2xvY2tzZXEgPSBvcHRpb25zLmNsb2Nrc2VxICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb2Nrc2VxIDogX2Nsb2Nrc2VxOyAvLyBub2RlIGFuZCBjbG9ja3NlcSBuZWVkIHRvIGJlIGluaXRpYWxpemVkIHRvIHJhbmRvbSB2YWx1ZXMgaWYgdGhleSdyZSBub3RcbiAgLy8gc3BlY2lmaWVkLiAgV2UgZG8gdGhpcyBsYXppbHkgdG8gbWluaW1pemUgaXNzdWVzIHJlbGF0ZWQgdG8gaW5zdWZmaWNpZW50XG4gIC8vIHN5c3RlbSBlbnRyb3B5LiAgU2VlICMxODlcblxuICBpZiAobm9kZSA9PSBudWxsIHx8IGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICBjb25zdCBzZWVkQnl0ZXMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgX3JuZy5kZWZhdWx0KSgpO1xuXG4gICAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgICAgLy8gUGVyIDQuNSwgY3JlYXRlIGFuZCA0OC1iaXQgbm9kZSBpZCwgKDQ3IHJhbmRvbSBiaXRzICsgbXVsdGljYXN0IGJpdCA9IDEpXG4gICAgICBub2RlID0gX25vZGVJZCA9IFtzZWVkQnl0ZXNbMF0gfCAweDAxLCBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XV07XG4gICAgfVxuXG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9IC8vIFVVSUQgdGltZXN0YW1wcyBhcmUgMTAwIG5hbm8tc2Vjb25kIHVuaXRzIHNpbmNlIHRoZSBHcmVnb3JpYW4gZXBvY2gsXG4gIC8vICgxNTgyLTEwLTE1IDAwOjAwKS4gIEpTTnVtYmVycyBhcmVuJ3QgcHJlY2lzZSBlbm91Z2ggZm9yIHRoaXMsIHNvXG4gIC8vIHRpbWUgaXMgaGFuZGxlZCBpbnRlcm5hbGx5IGFzICdtc2VjcycgKGludGVnZXIgbWlsbGlzZWNvbmRzKSBhbmQgJ25zZWNzJ1xuICAvLyAoMTAwLW5hbm9zZWNvbmRzIG9mZnNldCBmcm9tIG1zZWNzKSBzaW5jZSB1bml4IGVwb2NoLCAxOTcwLTAxLTAxIDAwOjAwLlxuXG5cbiAgbGV0IG1zZWNzID0gb3B0aW9ucy5tc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tc2VjcyA6IERhdGUubm93KCk7IC8vIFBlciA0LjIuMS4yLCB1c2UgY291bnQgb2YgdXVpZCdzIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGN1cnJlbnQgY2xvY2tcbiAgLy8gY3ljbGUgdG8gc2ltdWxhdGUgaGlnaGVyIHJlc29sdXRpb24gY2xvY2tcblxuICBsZXQgbnNlY3MgPSBvcHRpb25zLm5zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm5zZWNzIDogX2xhc3ROU2VjcyArIDE7IC8vIFRpbWUgc2luY2UgbGFzdCB1dWlkIGNyZWF0aW9uIChpbiBtc2VjcylcblxuICBjb25zdCBkdCA9IG1zZWNzIC0gX2xhc3RNU2VjcyArIChuc2VjcyAtIF9sYXN0TlNlY3MpIC8gMTAwMDA7IC8vIFBlciA0LjIuMS4yLCBCdW1wIGNsb2Nrc2VxIG9uIGNsb2NrIHJlZ3Jlc3Npb25cblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9IC8vIFJlc2V0IG5zZWNzIGlmIGNsb2NrIHJlZ3Jlc3NlcyAobmV3IGNsb2Nrc2VxKSBvciB3ZSd2ZSBtb3ZlZCBvbnRvIGEgbmV3XG4gIC8vIHRpbWUgaW50ZXJ2YWxcblxuXG4gIGlmICgoZHQgPCAwIHx8IG1zZWNzID4gX2xhc3RNU2VjcykgJiYgb3B0aW9ucy5uc2VjcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbnNlY3MgPSAwO1xuICB9IC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcblxuXG4gIGlmIChuc2VjcyA+PSAxMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInV1aWQudjEoKTogQ2FuJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjXCIpO1xuICB9XG5cbiAgX2xhc3RNU2VjcyA9IG1zZWNzO1xuICBfbGFzdE5TZWNzID0gbnNlY3M7XG4gIF9jbG9ja3NlcSA9IGNsb2Nrc2VxOyAvLyBQZXIgNC4xLjQgLSBDb252ZXJ0IGZyb20gdW5peCBlcG9jaCB0byBHcmVnb3JpYW4gZXBvY2hcblxuICBtc2VjcyArPSAxMjIxOTI5MjgwMDAwMDsgLy8gYHRpbWVfbG93YFxuXG4gIGNvbnN0IHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjsgLy8gYHRpbWVfbWlkYFxuXG4gIGNvbnN0IHRtaCA9IG1zZWNzIC8gMHgxMDAwMDAwMDAgKiAxMDAwMCAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjsgLy8gYHRpbWVfaGlnaF9hbmRfdmVyc2lvbmBcblxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG5cbiAgYltpKytdID0gdG1oID4+PiAxNiAmIDB4ZmY7IC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuXG4gIGJbaSsrXSA9IGNsb2Nrc2VxID4+PiA4IHwgMHg4MDsgLy8gYGNsb2NrX3NlcV9sb3dgXG5cbiAgYltpKytdID0gY2xvY2tzZXEgJiAweGZmOyAvLyBgbm9kZWBcblxuICBmb3IgKGxldCBuID0gMDsgbiA8IDY7ICsrbikge1xuICAgIGJbaSArIG5dID0gbm9kZVtuXTtcbiAgfVxuXG4gIHJldHVybiBidWYgfHwgKDAsIF9zdHJpbmdpZnkuZGVmYXVsdCkoYik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHYxO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjM1LmpzXCIpKTtcblxudmFyIF9tZCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vbWQ1LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuY29uc3QgdjMgPSAoMCwgX3YuZGVmYXVsdCkoJ3YzJywgMHgzMCwgX21kLmRlZmF1bHQpO1xudmFyIF9kZWZhdWx0ID0gdjM7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0O1xuZXhwb3J0cy5VUkwgPSBleHBvcnRzLkROUyA9IHZvaWQgMDtcblxudmFyIF9zdHJpbmdpZnkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKSk7XG5cbnZhciBfcGFyc2UgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3BhcnNlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gc3RyaW5nVG9CeXRlcyhzdHIpIHtcbiAgc3RyID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpOyAvLyBVVEY4IGVzY2FwZVxuXG4gIGNvbnN0IGJ5dGVzID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBieXRlcy5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKTtcbiAgfVxuXG4gIHJldHVybiBieXRlcztcbn1cblxuY29uc3QgRE5TID0gJzZiYTdiODEwLTlkYWQtMTFkMS04MGI0LTAwYzA0ZmQ0MzBjOCc7XG5leHBvcnRzLkROUyA9IEROUztcbmNvbnN0IFVSTCA9ICc2YmE3YjgxMS05ZGFkLTExZDEtODBiNC0wMGMwNGZkNDMwYzgnO1xuZXhwb3J0cy5VUkwgPSBVUkw7XG5cbmZ1bmN0aW9uIF9kZWZhdWx0KG5hbWUsIHZlcnNpb24sIGhhc2hmdW5jKSB7XG4gIGZ1bmN0aW9uIGdlbmVyYXRlVVVJRCh2YWx1ZSwgbmFtZXNwYWNlLCBidWYsIG9mZnNldCkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHN0cmluZ1RvQnl0ZXModmFsdWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmFtZXNwYWNlID09PSAnc3RyaW5nJykge1xuICAgICAgbmFtZXNwYWNlID0gKDAsIF9wYXJzZS5kZWZhdWx0KShuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIGlmIChuYW1lc3BhY2UubGVuZ3RoICE9PSAxNikge1xuICAgICAgdGhyb3cgVHlwZUVycm9yKCdOYW1lc3BhY2UgbXVzdCBiZSBhcnJheS1saWtlICgxNiBpdGVyYWJsZSBpbnRlZ2VyIHZhbHVlcywgMC0yNTUpJyk7XG4gICAgfSAvLyBDb21wdXRlIGhhc2ggb2YgbmFtZXNwYWNlIGFuZCB2YWx1ZSwgUGVyIDQuM1xuICAgIC8vIEZ1dHVyZTogVXNlIHNwcmVhZCBzeW50YXggd2hlbiBzdXBwb3J0ZWQgb24gYWxsIHBsYXRmb3JtcywgZS5nLiBgYnl0ZXMgPVxuICAgIC8vIGhhc2hmdW5jKFsuLi5uYW1lc3BhY2UsIC4uLiB2YWx1ZV0pYFxuXG5cbiAgICBsZXQgYnl0ZXMgPSBuZXcgVWludDhBcnJheSgxNiArIHZhbHVlLmxlbmd0aCk7XG4gICAgYnl0ZXMuc2V0KG5hbWVzcGFjZSk7XG4gICAgYnl0ZXMuc2V0KHZhbHVlLCBuYW1lc3BhY2UubGVuZ3RoKTtcbiAgICBieXRlcyA9IGhhc2hmdW5jKGJ5dGVzKTtcbiAgICBieXRlc1s2XSA9IGJ5dGVzWzZdICYgMHgwZiB8IHZlcnNpb247XG4gICAgYnl0ZXNbOF0gPSBieXRlc1s4XSAmIDB4M2YgfCAweDgwO1xuXG4gICAgaWYgKGJ1Zikge1xuICAgICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTY7ICsraSkge1xuICAgICAgICBidWZbb2Zmc2V0ICsgaV0gPSBieXRlc1tpXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9XG5cbiAgICByZXR1cm4gKDAsIF9zdHJpbmdpZnkuZGVmYXVsdCkoYnl0ZXMpO1xuICB9IC8vIEZ1bmN0aW9uI25hbWUgaXMgbm90IHNldHRhYmxlIG9uIHNvbWUgcGxhdGZvcm1zICgjMjcwKVxuXG5cbiAgdHJ5IHtcbiAgICBnZW5lcmF0ZVVVSUQubmFtZSA9IG5hbWU7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lbXB0eVxuICB9IGNhdGNoIChlcnIpIHt9IC8vIEZvciBDb21tb25KUyBkZWZhdWx0IGV4cG9ydCBzdXBwb3J0XG5cblxuICBnZW5lcmF0ZVVVSUQuRE5TID0gRE5TO1xuICBnZW5lcmF0ZVVVSUQuVVJMID0gVVJMO1xuICByZXR1cm4gZ2VuZXJhdGVVVUlEO1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3JuZyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vcm5nLmpzXCIpKTtcblxudmFyIF9zdHJpbmdpZnkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGNvbnN0IHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgX3JuZy5kZWZhdWx0KSgpOyAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG5cblxuICBybmRzWzZdID0gcm5kc1s2XSAmIDB4MGYgfCAweDQwO1xuICBybmRzWzhdID0gcm5kc1s4XSAmIDB4M2YgfCAweDgwOyAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcblxuICBpZiAoYnVmKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDE2OyArK2kpIHtcbiAgICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHJuZHNbaV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZjtcbiAgfVxuXG4gIHJldHVybiAoMCwgX3N0cmluZ2lmeS5kZWZhdWx0KShybmRzKTtcbn1cblxudmFyIF9kZWZhdWx0ID0gdjQ7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF92ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92MzUuanNcIikpO1xuXG52YXIgX3NoYSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vc2hhMS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmNvbnN0IHY1ID0gKDAsIF92LmRlZmF1bHQpKCd2NScsIDB4NTAsIF9zaGEuZGVmYXVsdCk7XG52YXIgX2RlZmF1bHQgPSB2NTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3JlZ2V4ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9yZWdleC5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHZhbGlkYXRlKHV1aWQpIHtcbiAgcmV0dXJuIHR5cGVvZiB1dWlkID09PSAnc3RyaW5nJyAmJiBfcmVnZXguZGVmYXVsdC50ZXN0KHV1aWQpO1xufVxuXG52YXIgX2RlZmF1bHQgPSB2YWxpZGF0ZTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3ZhbGlkYXRlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92YWxpZGF0ZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHZlcnNpb24odXVpZCkge1xuICBpZiAoISgwLCBfdmFsaWRhdGUuZGVmYXVsdCkodXVpZCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ0ludmFsaWQgVVVJRCcpO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlSW50KHV1aWQuc3Vic3RyKDE0LCAxKSwgMTYpO1xufVxuXG52YXIgX2RlZmF1bHQgPSB2ZXJzaW9uO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiLypcbldpbGRFbWl0dGVyLmpzIGlzIGEgc2xpbSBsaXR0bGUgZXZlbnQgZW1pdHRlciBieSBAaGVucmlram9yZXRlZyBsYXJnZWx5IGJhc2VkXG5vbiBAdmlzaW9ubWVkaWEncyBFbWl0dGVyIGZyb20gVUkgS2l0LlxuXG5XaHk/IEkgd2FudGVkIGl0IHN0YW5kYWxvbmUuXG5cbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxuXG5lbWl0dGVyLm9uKCcqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgb3RoZXIsIGV2ZW50LCBwYXlsb2Fkcykge1xuXG59KTtcblxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xuXG59KTtcblxuUGxlYXNlIG5vdGUgdGhhdCBjYWxsYmFja3MgdHJpZ2dlcmVkIGJ5IHdpbGRjYXJkIHJlZ2lzdGVyZWQgZXZlbnRzIGFsc28gZ2V0XG50aGUgZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdpbGRFbWl0dGVyO1xuXG5mdW5jdGlvbiBXaWxkRW1pdHRlcigpIHsgfVxuXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgIHZhciBwcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwgY29uc3RydWN0b3I7XG5cbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcblxuICAgIC8vIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuIFN0b3JlIGEgZ3JvdXAgbmFtZSBpZiBwcmVzZW50LlxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jLl9ncm91cE5hbWUgPSBncm91cDtcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgIC8vIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICAgICAgaGFzR3JvdXAgPSAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyksXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZnVuYyA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzFdO1xuICAgICAgICBmdW5jdGlvbiBvbigpIHtcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFVuYmluZHMgYW4gZW50aXJlIGdyb3VwXG4gICAgcHJvdG90eXBlLnJlbGVhc2VHcm91cCA9IGZ1bmN0aW9uIChncm91cE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGxlbiwgaGFuZGxlcnM7XG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXJzW2ldLl9ncm91cE5hbWUgPT09IGdyb3VwTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgaXQgYW5kIHNob3J0ZW4gdGhlIGFycmF5IHdlJ3JlIGxvb3BpbmcgdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgIHByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xuICAgICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICAvLyBhbHNvIGNhbGxzIGFueSBgKmAgaGFuZGxlcnNcbiAgICBwcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGNhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWFsQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsZW4gPSBzcGVjaWFsQ2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgW2V2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxuICAgIHByb3RvdHlwZS5nZXRXaWxkY2FyZENhbGxiYWNrcyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGl0ZW0sXG4gICAgICAgICAgICBzcGxpdCxcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAoaXRlbSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KCcqJyk7XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5jYWxsYmFja3NbaXRlbV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxufTtcblxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIgdjUuMi45IC0gZ2l0LmlvL2VlXG4gKiBVbmxpY2Vuc2UgLSBodHRwOi8vdW5saWNlbnNlLm9yZy9cbiAqIE9saXZlciBDYWxkd2VsbCAtIGh0dHBzOi8vb2xpLm1lLnVrL1xuICogQHByZXNlcnZlXG4gKi9cblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qKlxuICAgICAqIENsYXNzIGZvciBtYW5hZ2luZyBldmVudHMuXG4gICAgICogQ2FuIGJlIGV4dGVuZGVkIHRvIHByb3ZpZGUgZXZlbnQgZnVuY3Rpb25hbGl0eSBpbiBvdGhlciBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQGNsYXNzIEV2ZW50RW1pdHRlciBNYW5hZ2VzIGV2ZW50IHJlZ2lzdGVyaW5nIGFuZCBlbWl0dGluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7fVxuXG4gICAgLy8gU2hvcnRjdXRzIHRvIGltcHJvdmUgc3BlZWQgYW5kIHNpemVcbiAgICB2YXIgcHJvdG8gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gaXNWYWxpZExpc3RlbmVyIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nIHx8IGxpc3RlbmVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIubGlzdGVuZXIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIG5vdCBiZSBhZGRlZCBpZiBpdCBpcyBhIGR1cGxpY2F0ZS5cbiAgICAgKiBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGNhbGxlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGFkZGVkIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJJc1dyYXBwZWQgPSB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnB1c2gobGlzdGVuZXJJc1dyYXBwZWQgPyBsaXN0ZW5lciA6IHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZExpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub24gPSBhbGlhcygnYWRkTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIFNlbWktYWxpYXMgb2YgYWRkTGlzdGVuZXIuIEl0IHdpbGwgYWRkIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGFmdGVyIGl0cyBmaXJzdCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZE9uY2VMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZE9uY2VMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZExpc3RlbmVyKGV2dCwge1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgb25jZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkT25jZUxpc3RlbmVyLlxuICAgICAqL1xuICAgIHByb3RvLm9uY2UgPSBhbGlhcygnYWRkT25jZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGFuIGV2ZW50IG5hbWUuIFRoaXMgaXMgcmVxdWlyZWQgaWYgeW91IHdhbnQgdG8gdXNlIGEgcmVnZXggdG8gYWRkIGEgbGlzdGVuZXIgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIElmIHlvdSBkb24ndCBkbyB0aGlzIHRoZW4gaG93IGRvIHlvdSBleHBlY3QgaXQgdG8ga25vdyB3aGF0IGV2ZW50IHRvIGFkZCB0bz8gU2hvdWxkIGl0IGp1c3QgYWRkIHRvIGV2ZXJ5IHBvc3NpYmxlIG1hdGNoIGZvciBhIHJlZ2V4PyBOby4gVGhhdCBpcyBzY2FyeSBhbmQgYmFkLlxuICAgICAqIFlvdSBuZWVkIHRvIHRlbGwgaXQgd2hhdCBldmVudCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZCBieSBhIHJlZ2V4LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBjcmVhdGUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnQgPSBmdW5jdGlvbiBkZWZpbmVFdmVudChldnQpIHtcbiAgICAgICAgdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFVzZXMgZGVmaW5lRXZlbnQgdG8gZGVmaW5lIG11bHRpcGxlIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGV2dHMgQW4gYXJyYXkgb2YgZXZlbnQgbmFtZXMgdG8gZGVmaW5lLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50cyA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50cyhldnRzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5kZWZpbmVFdmVudChldnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIGZyb20gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaGVuIHBhc3NlZCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhcyB0aGUgZXZlbnQgbmFtZSwgaXQgd2lsbCByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUxpc3RlbmVyXG4gICAgICovXG4gICAgcHJvdG8ub2ZmID0gYWxpYXMoJ3JlbW92ZUxpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBhZGQgdGhlIGFycmF5IG9mIGxpc3RlbmVycyB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICogWWVhaCwgdGhpcyBmdW5jdGlvbiBkb2VzIHF1aXRlIGEgYml0LiBUaGF0J3MgcHJvYmFibHkgYSBiYWQgdGhpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyhmYWxzZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxpc3RlbmVycyBpbiBidWxrIHVzaW5nIHRoZSBtYW5pcHVsYXRlTGlzdGVuZXJzIG1ldGhvZC5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzTWFwID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXJzO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzTWFwKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXBba2V5XS5zbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHNoYWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGVpdGhlciB3aXRoIGEgYmFzaWMgY2FsbCBvciBhbiBhcHBseSBpZiB0aGVyZSBpcyBhbiBhcmdzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBsaXN0ZW5lci5saXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzIHx8IFtdKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHRoaXMuX2dldE9uY2VSZXR1cm5WYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIubGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGVtaXRFdmVudFxuICAgICAqL1xuICAgIHByb3RvLnRyaWdnZXIgPSBhbGlhcygnZW1pdEV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0bHkgZGlmZmVyZW50IGZyb20gZW1pdEV2ZW50IGluIHRoYXQgaXQgd2lsbCBwYXNzIGl0cyBhcmd1bWVudHMgb24gdG8gdGhlIGxpc3RlbmVycywgYXMgb3Bwb3NlZCB0byB0YWtpbmcgYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzIHRvIHBhc3Mgb24uXG4gICAgICogQXMgd2l0aCBlbWl0RXZlbnQsIHlvdSBjYW4gcGFzcyBhIHJlZ2V4IGluIHBsYWNlIG9mIHRoZSBldmVudCBuYW1lIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gT3B0aW9uYWwgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdEV2ZW50KGV2dCwgYXJncyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmIGFcbiAgICAgKiBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlIG9uZSBzZXQgaGVyZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGFmdGVyIGV4ZWN1dGlvbi4gVGhpcyB2YWx1ZSBkZWZhdWx0cyB0byB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlIHRvIGNoZWNrIGZvciB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uc2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gc2V0T25jZVJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX29uY2VSZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWZcbiAgICAgKiB0aGUgbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoaXMgb25lIHRoZW4gaXQgc2hvdWxkIGJlIHJlbW92ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5LiBJdCB3aWxsIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfEJvb2xlYW59IFRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGZvciBvciB0aGUgZGVmYXVsdCwgdHJ1ZS5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0T25jZVJldHVyblZhbHVlID0gZnVuY3Rpb24gX2dldE9uY2VSZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ19vbmNlUmV0dXJuVmFsdWUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uY2VSZXR1cm5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGV2ZW50cyBvYmplY3QgYW5kIGNyZWF0ZXMgb25lIGlmIHJlcXVpcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXZlbnRzIHN0b3JhZ2Ugb2JqZWN0LlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRFdmVudHMgPSBmdW5jdGlvbiBfZ2V0RXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGdsb2JhbCB7QGxpbmsgRXZlbnRFbWl0dGVyfSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IE5vbiBjb25mbGljdGluZyBFdmVudEVtaXR0ZXIgY2xhc3MuXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IG9yaWdpbmFsR2xvYmFsVmFsdWU7XG4gICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgfTtcblxuICAgIC8vIEV4cG9zZSB0aGUgY2xhc3MgZWl0aGVyIHZpYSBBTUQsIENvbW1vbkpTIG9yIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKXtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcyB8fCB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwiYXV0aG9yXCI6IFwiT3BlblZpZHVcIiwgXG4gICAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcImZyZWVpY2VcIjogXCIyLjIuMlwiLCBcbiAgICAgICAgXCJoYXJrXCI6IFwiMS4yLjNcIiwgXG4gICAgICAgIFwianNubG9nXCI6IFwiMi4zMC4wXCIsIFxuICAgICAgICBcIm1pbWVcIjogXCIzLjAuMFwiLCBcbiAgICAgICAgXCJwbGF0Zm9ybVwiOiBcIjEuMy42XCIsIFxuICAgICAgICBcInNlbXZlclwiOiBcIjcuMy43XCIsIFxuICAgICAgICBcInV1aWRcIjogXCI4LjMuMlwiLCBcbiAgICAgICAgXCJ3b2xmeTg3LWV2ZW50ZW1pdHRlclwiOiBcIjUuMi45XCIsIFxuICAgICAgICBcImV2ZW50c1wiOiBcIjMuMy4wXCIsIFxuICAgICAgICBcImluaGVyaXRzXCI6IFwiMi4wLjRcIlxuICAgIH0sIFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJPcGVuVmlkdSBCcm93c2VyXCIsIFxuICAgIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJAdHlwZXMvbm9kZVwiOiBcIjE4LjAuMFwiLCBcbiAgICAgICAgXCJAdHlwZXMvcGxhdGZvcm1cIjogXCIxLjMuNFwiLCBcbiAgICAgICAgXCJicm93c2VyaWZ5XCI6IFwiMTcuMC4wXCIsIFxuICAgICAgICBcImdydW50XCI6IFwiMS41LjNcIiwgXG4gICAgICAgIFwiZ3J1bnQtY2xpXCI6IFwiMS40LjNcIiwgXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiMS4wLjBcIiwgXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi1zYXNzXCI6IFwiMi4wLjBcIiwgXG4gICAgICAgIFwiZ3J1bnQtY29udHJpYi11Z2xpZnlcIjogXCI1LjIuMlwiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLXdhdGNoXCI6IFwiMS4xLjBcIiwgXG4gICAgICAgIFwiZ3J1bnQtcG9zdGNzc1wiOiBcIjAuOS4wXCIsIFxuICAgICAgICBcImdydW50LXN0cmluZy1yZXBsYWNlXCI6IFwiMS4zLjNcIiwgXG4gICAgICAgIFwiZ3J1bnQtdHNcIjogXCI2LjAuMC1iZXRhLjIyXCIsIFxuICAgICAgICBcInRlcnNlclwiOiBcIjUuMTQuMVwiLCBcbiAgICAgICAgXCJ0c2lmeVwiOiBcIjUuMC40XCIsIFxuICAgICAgICBcInRzbGludFwiOiBcIjYuMS4zXCIsIFxuICAgICAgICBcInR5cGVkb2NcIjogXCIwLjIyLjE3XCIsIFxuICAgICAgICBcInR5cGVzY3JpcHRcIjogXCI0LjUuNFwiXG4gICAgfSwgXG4gICAgXCJsaWNlbnNlXCI6IFwiQXBhY2hlLTIuMFwiLCBcbiAgICBcIm1haW5cIjogXCJsaWIvaW5kZXguanNcIiwgXG4gICAgXCJuYW1lXCI6IFwib3BlbnZpZHUtYnJvd3NlclwiLCBcbiAgICBcInJlcG9zaXRvcnlcIjoge1xuICAgICAgICBcInR5cGVcIjogXCJnaXRcIiwgXG4gICAgICAgIFwidXJsXCI6IFwiZ2l0Oi8vZ2l0aHViLmNvbS9PcGVuVmlkdS9vcGVudmlkdVwiXG4gICAgfSwgXG4gICAgXCJzY3JpcHRzXCI6IHtcbiAgICAgICAgXCJicm93c2VyaWZ5XCI6IFwiVkVSU0lPTj0ke1ZFUlNJT046LWRldn07IG1rZGlyIC1wIHN0YXRpYy9qcy8gJiYgY2Qgc3JjICYmIC4uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L2Jpbi9jbWQuanMgTWFpbi50cyAtcCBbIHRzaWZ5IF0gLS1leGNsdWRlIGt1cmVudG8tYnJvd3Nlci1leHRlbnNpb25zIC0tZGVidWcgLW8gLi4vc3RhdGljL2pzL29wZW52aWR1LWJyb3dzZXItJFZFUlNJT04uanMgLXZcIiwgXG4gICAgICAgIFwiYnJvd3NlcmlmeS1wcm9kXCI6IFwiVkVSU0lPTj0ke1ZFUlNJT046LWRldn07IG1rZGlyIC1wIHN0YXRpYy9qcy8gJiYgY2Qgc3JjICYmIC4uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L2Jpbi9jbWQuanMgLS1kZWJ1ZyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgfCAuLi9ub2RlX21vZHVsZXMvdGVyc2VyL2Jpbi90ZXJzZXIgLS1zb3VyY2UtbWFwIGNvbnRlbnQ9aW5saW5lIC0tb3V0cHV0IC4uL3N0YXRpYy9qcy9vcGVudmlkdS1icm93c2VyLSRWRVJTSU9OLm1pbi5qc1wiLCBcbiAgICAgICAgXCJidWlsZFwiOiBcImNkIHNyYy9PcGVuVmlkdSAmJiAuLy4uLy4uL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgJiYgY2QgLi4vLi4gJiYgLi9ub2RlX21vZHVsZXMvdHlwZXNjcmlwdC9iaW4vdHNjIC0tZGVjbGFyYXRpb24gc3JjL2luZGV4LnRzIC0tb3V0RGlyIC4vbGliIC0tc291cmNlTWFwIC0tdGFyZ2V0IGVzNSAtLWxpYiBkb20sZXM1LGVzMjAxNS5wcm9taXNlLHNjcmlwdGhvc3QgJiYgcm0gLXJmIC4vdHM0LjQgJiYgbWtkaXIgLXAgLi90czQuNC9saWIgJiYgY3AgLXIgLi9saWIgLi90czQuNCAmJiBmaW5kIC4vdHM0LjQvbGliIC10eXBlIGYgISAtaW5hbWUgJyouZC50cycgLWRlbGV0ZSAmJiAuL2NvbmZpZy9yZXBsYWNlX2Zvcl90czQ0LnNoXCIsIFxuICAgICAgICBcImRvY3NcIjogXCIuL2dlbmVyYXRlLWRvY3Muc2hcIlxuICAgIH0sIFxuICAgIFwidHlwZXNcIjogXCJsaWIvaW5kZXguZC50c1wiLCBcbiAgICBcInR5cGVzVmVyc2lvbnNcIjoge1xuICAgICAgICBcIjw0LjRcIjoge1xuICAgICAgICAgICAgXCIqXCI6IFtcbiAgICAgICAgICAgICAgICBcInRzNC40LypcIlxuICAgICAgICAgICAgXVxuICAgICAgICB9XG4gICAgfSwgXG4gICAgXCJ2ZXJzaW9uXCI6IFwiMi4yMy4wXCJcbn0iLCJpbXBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUvT3BlblZpZHUnO1xuaW1wb3J0IHsgSkwgfSBmcm9tICdqc25sb2cnO1xuXG5pZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgZ2xvYmFsVGhpc1snT3BlblZpZHUnXSA9IE9wZW5WaWR1O1xufVxuXG4vLyBEaXNhYmxlIGpzbmxvZyB3aGVuIGxpYnJhcnkgaXMgbG9hZGVkXG5KTC5zZXRPcHRpb25zKHsgZW5hYmxlZDogZmFsc2UgfSk7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbENvbm5lY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvTG9jYWxDb25uZWN0aW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1JlbW90ZUNvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgU3RyZWFtT3B0aW9uc1NlcnZlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1N0cmVhbU9wdGlvbnNTZXJ2ZXInO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBFeGNlcHRpb25FdmVudCwgRXhjZXB0aW9uRXZlbnROYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXhjZXB0aW9uRXZlbnQnO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICogUmVwcmVzZW50cyBlYWNoIG9uZSBvZiB0aGUgdXNlcidzIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24gKHRoZSBsb2NhbCBvbmUgYW5kIG90aGVyIHVzZXIncyBjb25uZWN0aW9ucykuXG4gKiBUaGVyZWZvcmUgZWFjaCBbW1Nlc3Npb25dXSBhbmQgW1tTdHJlYW1dXSBvYmplY3QgaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIENvbm5lY3Rpb25cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuICAgIC8qKlxuICAgICAqIFVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBjb25uZWN0aW9uXG4gICAgICovXG4gICAgY29ubmVjdGlvbklkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaW1lIHdoZW4gdGhpcyBjb25uZWN0aW9uIHdhcyBjcmVhdGVkIGluIE9wZW5WaWR1IFNlcnZlciAoVVRDIG1pbGxpc2Vjb25kcylcbiAgICAgKi9cbiAgICBjcmVhdGlvblRpbWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIERhdGEgYXNzb2NpYXRlZCB0byB0aGlzIGNvbm5lY3Rpb24gKGFuZCB0aGVyZWZvcmUgdG8gY2VydGFpbiB1c2VyKS4gVGhpcyBpcyBhbiBpbXBvcnRhbnQgZmllbGQ6XG4gICAgICogaXQgYWxsb3dzIHlvdSB0byBicm9hZGNhc3QgYWxsIHRoZSBpbmZvcm1hdGlvbiB5b3Ugd2FudCBmb3IgZWFjaCB1c2VyIChhIHVzZXJuYW1lLCBmb3IgZXhhbXBsZSlcbiAgICAgKi9cbiAgICBkYXRhOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBSb2xlIG9mIHRoZSBjb25uZWN0aW9uLlxuICAgICAqIC0gYFNVQlNDUklCRVJgOiBjYW4gc3Vic2NyaWJlIHRvIHB1Ymxpc2hlZCBTdHJlYW1zIG9mIG90aGVyIHVzZXJzIGJ5IGNhbGxpbmcgW1tTZXNzaW9uLnN1YnNjcmliZV1dXG4gICAgICogLSBgUFVCTElTSEVSYDogU1VCU0NSSUJFUiBwZXJtaXNzaW9ucyArIGNhbiBwdWJsaXNoIHRoZWlyIG93biBTdHJlYW1zIGJ5IGNhbGxpbmcgW1tTZXNzaW9uLnB1Ymxpc2hdXVxuICAgICAqIC0gYE1PREVSQVRPUmA6IFNVQlNDUklCRVIgKyBQVUJMSVNIRVIgcGVybWlzc2lvbnMgKyBjYW4gZm9yY2UgdGhlIHVucHVibGlzaGluZyBvciBkaXNjb25uZWN0aW9uIG92ZXIgYSB0aGlyZC1wYXJ0eSBTdHJlYW0gb3IgQ29ubmVjdGlvbiBieSBjYWxsIFtbU2Vzc2lvbi5mb3JjZVVucHVibGlzaF1dIGFuZCBbW1Nlc3Npb24uZm9yY2VEaXNjb25uZWN0XV1cbiAgICAgKlxuICAgICAqICoqT25seSBkZWZpbmVkIGZvciB0aGUgbG9jYWwgY29ubmVjdGlvbi4gSW4gcmVtb3RlIGNvbm5lY3Rpb25zIHdpbGwgYmUgYHVuZGVmaW5lZGAqKlxuICAgICAqL1xuICAgIHJvbGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbXMgcHVibGlzaGVkIGJ5IHRoaXMgQ29ubmVjdGlvbiB3aWxsIGJlIHJlY29yZGVkIG9yIG5vdC4gVGhpcyBvbmx5IGFmZmVjdHMgW0lORElWSURVQUwgcmVjb3JkaW5nXSgvZW4vc3RhYmxlL2FkdmFuY2VkLWZlYXR1cmVzL3JlY29yZGluZy8jaW5kaXZpZHVhbC1yZWNvcmRpbmctc2VsZWN0aW9uKSA8YSBocmVmPVwiaHR0cHM6Ly9kb2NzLm9wZW52aWR1LmlvL2VuL3N0YWJsZS9vcGVudmlkdS1wcm8vXCIgc3R5bGU9XCJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGJhY2tncm91bmQtY29sb3I6IHJnYigwLCAxMzYsIDE3MCk7IGNvbG9yOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IGJvbGQ7IHBhZGRpbmc6IDBweCA1cHg7IG1hcmdpbi1yaWdodDogNXB4OyBib3JkZXItcmFkaXVzOiAzcHg7IGZvbnQtc2l6ZTogMTNweDsgbGluZS1oZWlnaHQ6MjFweDsgZm9udC1mYW1pbHk6IE1vbnRzZXJyYXQsIHNhbnMtc2VyaWZcIj5QUk88L2E+XG4gICAgICpcbiAgICAgKiAqKk9ubHkgZGVmaW5lZCBmb3IgdGhlIGxvY2FsIGNvbm5lY3Rpb24uIEluIHJlbW90ZSBjb25uZWN0aW9ucyB3aWxsIGJlIGB1bmRlZmluZWRgKipcbiAgICAgKi9cbiAgICByZWNvcmQ6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3RyZWFtPzogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxvY2FsT3B0aW9uczogTG9jYWxDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdGVPcHRpb25zOiBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJwY1Nlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbiwgY29ubmVjdGlvbk9wdGlvbnM6IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMgfCBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucykge1xuICAgICAgICBsZXQgbXNnID0gXCInQ29ubmVjdGlvbicgY3JlYXRlZCBcIjtcbiAgICAgICAgaWYgKCEhKDxMb2NhbENvbm5lY3Rpb25PcHRpb25zPmNvbm5lY3Rpb25PcHRpb25zKS5yb2xlKSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIGxvY2FsXG4gICAgICAgICAgICB0aGlzLmxvY2FsT3B0aW9ucyA9IDxMb2NhbENvbm5lY3Rpb25PcHRpb25zPmNvbm5lY3Rpb25PcHRpb25zO1xuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQgPSB0aGlzLmxvY2FsT3B0aW9ucy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gdGhpcy5sb2NhbE9wdGlvbnMuY3JlYXRlZEF0O1xuICAgICAgICAgICAgdGhpcy5kYXRhID0gdGhpcy5sb2NhbE9wdGlvbnMubWV0YWRhdGE7XG4gICAgICAgICAgICB0aGlzLnJwY1Nlc3Npb25JZCA9IHRoaXMubG9jYWxPcHRpb25zLnNlc3Npb25JZDtcbiAgICAgICAgICAgIHRoaXMucm9sZSA9IHRoaXMubG9jYWxPcHRpb25zLnJvbGU7XG4gICAgICAgICAgICB0aGlzLnJlY29yZCA9IHRoaXMubG9jYWxPcHRpb25zLnJlY29yZDtcbiAgICAgICAgICAgIG1zZyArPSAnKGxvY2FsKSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBDb25uZWN0aW9uIGlzIHJlbW90ZVxuICAgICAgICAgICAgdGhpcy5yZW1vdGVPcHRpb25zID0gPFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zPmNvbm5lY3Rpb25PcHRpb25zO1xuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQgPSB0aGlzLnJlbW90ZU9wdGlvbnMuaWQ7XG4gICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHRoaXMucmVtb3RlT3B0aW9ucy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICBpZiAodGhpcy5yZW1vdGVPcHRpb25zLm1ldGFkYXRhKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhID0gdGhpcy5yZW1vdGVPcHRpb25zLm1ldGFkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMucmVtb3RlT3B0aW9ucy5zdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVtb3RlU3RyZWFtcyh0aGlzLnJlbW90ZU9wdGlvbnMuc3RyZWFtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtc2cgKz0gXCIocmVtb3RlKSB3aXRoICdjb25uZWN0aW9uSWQnIFtcIiArIHRoaXMucmVtb3RlT3B0aW9ucy5pZCArICddJztcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuaW5mbyhtc2cpO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZEljZUNhbmRpZGF0ZShjYW5kaWRhdGU6IFJUQ0ljZUNhbmRpZGF0ZSk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuZGVidWcoKCEhdGhpcy5zdHJlYW0hLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCcgOiAnUmVtb3RlJykgKyAnY2FuZGlkYXRlIGZvcicgKyB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAnb25JY2VDYW5kaWRhdGUnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuZHBvaW50TmFtZTogdGhpcy5jb25uZWN0aW9uSWQsXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlOiBjYW5kaWRhdGUuY2FuZGlkYXRlLFxuICAgICAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgICAgICBzZHBNTGluZUluZGV4OiBjYW5kaWRhdGUuc2RwTUxpbmVJbmRleFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBzZW5kaW5nIElDRSBjYW5kaWRhdGU6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRXhjZXB0aW9uRXZlbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ0FORElEQVRFX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlcmUgd2FzIGFuIHVuZXhwZWN0ZWQgZXJyb3Igb24gdGhlIHNlcnZlci1zaWRlIHByb2Nlc3NpbmcgYW4gSUNFIGNhbmRpZGF0ZSBnZW5lcmF0ZWQgYW5kIHNlbnQgYnkgdGhlIGNsaWVudC1zaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRSZW1vdGVTdHJlYW1zKG9wdGlvbnM6IFN0cmVhbU9wdGlvbnNTZXJ2ZXJbXSk6IHZvaWQge1xuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKChvcHRzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBpZDogb3B0cy5pZCxcbiAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6IG9wdHMuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb246IHRoaXMsXG4gICAgICAgICAgICAgICAgaGFzQXVkaW86IG9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgaGFzVmlkZW86IG9wdHMuaGFzVmlkZW8sXG4gICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IG9wdHMuYXVkaW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IG9wdHMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgdHlwZU9mVmlkZW86IG9wdHMudHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgZnJhbWVSYXRlOiBvcHRzLmZyYW1lUmF0ZSxcbiAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6ICEhb3B0cy52aWRlb0RpbWVuc2lvbnMgPyBKU09OLnBhcnNlKG9wdHMudmlkZW9EaW1lbnNpb25zKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBmaWx0ZXI6ICEhb3B0cy5maWx0ZXIgPyBvcHRzLmZpbHRlciA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IG5ldyBTdHJlYW0odGhpcy5zZXNzaW9uLCBzdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgdGhpcy5hZGRTdHJlYW0oc3RyZWFtKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICBcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsXG4gICAgICAgICAgICB0aGlzLnN0cmVhbSEuaW5ib3VuZFN0cmVhbU9wdHNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgYXMgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBFdmVudE1hcCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50TWFwL0V2ZW50TWFwJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnREaXNwYXRjaGVyIHtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXNlckhhbmRsZXJBcnJvd0hhbmRsZXI6IFdlYWtNYXA8KGV2ZW50OiBFdmVudCkgPT4gdm9pZCwgKGV2ZW50OiBFdmVudCkgPT4gdm9pZD4gPSBuZXcgV2Vha01hcCgpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgZnVuY3Rpb24gYGhhbmRsZXJgIHRvIGhhbmRsZSBldmVudCBgdHlwZWBcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBFdmVudERpc3BhdGNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYWJzdHJhY3Qgb248SyBleHRlbmRzIGtleW9mIEV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIEFkZHMgZnVuY3Rpb24gYGhhbmRsZXJgIHRvIGhhbmRsZSBldmVudCBgdHlwZWAganVzdCBvbmNlLiBUaGUgaGFuZGxlciB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBhZnRlciBmaXJzdCBleGVjdXRpb25cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIGFic3RyYWN0IG9uY2U8SyBleHRlbmRzIGtleW9mIEV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBgaGFuZGxlcmAgZnJvbSBldmVudCBgdHlwZWAuIElmIG5vIGhhbmRsZXIgaXMgcHJvdmlkZWQsIGFsbCBoYW5kbGVycyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIGFic3RyYWN0IG9mZjxLIGV4dGVuZHMga2V5b2YgRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkF1eCh0eXBlOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIGNvbnN0IGFycm93SGFuZGxlciA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8obWVzc2FnZSwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhtZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnVzZXJIYW5kbGVyQXJyb3dIYW5kbGVyLnNldChoYW5kbGVyLCBhcnJvd0hhbmRsZXIpO1xuICAgICAgICB0aGlzLmVlLm9uKHR5cGUsIGFycm93SGFuZGxlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbmNlQXV4KHR5cGU6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgY29uc3QgYXJyb3dIYW5kbGVyID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhtZXNzYWdlLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKG1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgICAgICAvLyBSZW1vdmUgaGFuZGxlciBmcm9tIG1hcCBhZnRlciBmaXJzdCBhbmQgb25seSBleGVjdXRpb25cbiAgICAgICAgICAgIHRoaXMudXNlckhhbmRsZXJBcnJvd0hhbmRsZXIuZGVsZXRlKGhhbmRsZXIpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnVzZXJIYW5kbGVyQXJyb3dIYW5kbGVyLnNldChoYW5kbGVyLCBhcnJvd0hhbmRsZXIpO1xuICAgICAgICB0aGlzLmVlLm9uY2UodHlwZSwgYXJyb3dIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9mZkF1eCh0eXBlOiBzdHJpbmcsIGhhbmRsZXI/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKTogRXZlbnREaXNwYXRjaGVyIHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyh0eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE11c3QgcmVtb3ZlIGludGVybmFsIGFycm93IGZ1bmN0aW9uIGhhbmRsZXIgcGFpcmVkIHdpdGggdXNlciBoYW5kbGVyXG4gICAgICAgICAgICBjb25zdCBhcnJvd0hhbmRsZXIgPSB0aGlzLnVzZXJIYW5kbGVyQXJyb3dIYW5kbGVyLmdldChoYW5kbGVyKTtcbiAgICAgICAgICAgIGlmICghIWFycm93SGFuZGxlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUub2ZmKHR5cGUsIGFycm93SGFuZGxlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnVzZXJIYW5kbGVyQXJyb3dIYW5kbGVyLmRlbGV0ZShoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgRmlsdGVyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9GaWx0ZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICogKipXQVJOSU5HKio6IGV4cGVyaW1lbnRhbCBvcHRpb24uIFRoaXMgaW50ZXJmYWNlIG1heSBjaGFuZ2UgaW4gdGhlIG5lYXIgZnV0dXJlXG4gKlxuICogVmlkZW8vYXVkaW8gZmlsdGVyIGFwcGxpZWQgdG8gYSBTdHJlYW0uIFNlZSBbW1N0cmVhbS5hcHBseUZpbHRlcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIge1xuICAgIC8qKlxuICAgICAqIFR5cGUgb2YgZmlsdGVyIGFwcGxpZWQuIFRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHJlbW90ZSBjbGFzcyBpZGVudGlmeWluZyB0aGUgZmlsdGVyIHRvIGFwcGx5IGluIEt1cmVudG8gTWVkaWEgU2VydmVyLlxuICAgICAqIEZvciBleGFtcGxlOiBgXCJGYWNlT3ZlcmxheUZpbHRlclwiYCwgYFwiR1N0cmVhbWVyRmlsdGVyXCJgLlxuICAgICAqXG4gICAgICogWW91IGNhbiBnZXQgdGhpcyBwcm9wZXJ0eSBpbiBgKi5rbWQuanNvbmAgZmlsZXMgZGVmaW5pbmcgdGhlIEt1cmVudG8gZmlsdGVycy4gRm9yIGV4YW1wbGUsIGZvciBHU3RyZWFtZXJGaWx0ZXIgdGhhdCdzXG4gICAgICogW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9LdXJlbnRvL2ttcy1maWx0ZXJzL2Jsb2IvNTNhNDUyZmFjNzFkNjE3OTU5NTJlM2QyMjAyMTU2YzZiMDBmNmQ2NS9zcmMvc2VydmVyL2ludGVyZmFjZS9maWx0ZXJzLkdTdHJlYW1lckZpbHRlci5rbWQuanNvbiNMNClcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBQYXJhbWV0ZXJzIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGUgZmlsdGVyLlxuICAgICAqIFRoZXNlIGNvcnJlc3BvbmQgdG8gdGhlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMgdXNlZCBpbiB0aGUgZmlsdGVyIGluIEt1cmVudG8gTWVkaWEgU2VydmVyIChleGNlcHQgZm9yIGBtZWRpYVBpcGVsaW5lYCBwYXJhbWV0ZXIsIHdoaWNoIGlzIG5ldmVyIG5lZWRlZCkuXG4gICAgICpcbiAgICAgKiBGb3IgZXhhbXBsZTogZm9yIGBmaWx0ZXIudHlwZSA9IFwiR1N0cmVhbWVyRmlsdGVyXCJgIGNvdWxkIGJlIGBmaWx0ZXIub3B0aW9ucyA9IHtcImNvbW1hbmRcIjogXCJ2aWRlb2JhbGFuY2Ugc2F0dXJhdGlvbj0wLjBcIn1gXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0wxMy1MMzEpXG4gICAgICovXG4gICAgb3B0aW9uczogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogVmFsdWUgcGFzc2VkIHRoZSBsYXN0IHRpbWUgW1tGaWx0ZXIuZXhlY01ldGhvZF1dIHdhcyBjYWxsZWQuIElmIGB1bmRlZmluZWRgIHRoaXMgbWV0aG9kIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0LlxuICAgICAqXG4gICAgICogWW91IGNhbiB1c2UgdGhpcyB2YWx1ZSB0byBrbm93IHRoZSBjdXJyZW50IHN0YXR1cyBvZiBhbnkgYXBwbGllZCBmaWx0ZXJcbiAgICAgKi9cbiAgICBsYXN0RXhlY01ldGhvZD86IHtcbiAgICAgICAgbWV0aG9kOiBzdHJpbmc7XG4gICAgICAgIHBhcmFtczogT2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFuZGxlcnM6IE1hcDxzdHJpbmcsIChldmVudDogRmlsdGVyRXZlbnQpID0+IHZvaWQ+ID0gbmV3IE1hcCgpO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuICAgIHByaXZhdGUgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0eXBlOiBzdHJpbmcsIG9wdGlvbnM6IE9iamVjdCkge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIGEgZmlsdGVyIG1ldGhvZC4gQXZhaWxhYmxlIG1ldGhvZHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIG1ldGhvZCBOYW1lIG9mIHRoZSBtZXRob2RcbiAgICAgKiBAcGFyYW0gcGFyYW1zIFBhcmFtZXRlcnMgb2YgdGhlIG1ldGhvZFxuICAgICAqL1xuICAgIGV4ZWNNZXRob2QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogT2JqZWN0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnRXhlY3V0aW5nIGZpbHRlciBtZXRob2QgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG5cbiAgICAgICAgICAgIGxldCBmaW5hbFBhcmFtcztcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0V4ZWNNZXRob2QgPSAodHJpZ2dlckV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ0ZpbHRlciBtZXRob2Qgc3VjY2Vzc2Z1bGx5IGV4ZWN1dGVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oe30sIHRoaXMuc3RyZWFtLmZpbHRlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyIS5sYXN0RXhlY01ldGhvZCA9IHsgbWV0aG9kLCBwYXJhbXM6IGZpbmFsUGFyYW1zIH07XG4gICAgICAgICAgICAgICAgaWYgKHRyaWdnZXJFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpbHRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyISxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlY0ZpbHRlck1ldGhvZCdcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsdGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5maWx0ZXIhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjRmlsdGVyTWV0aG9kJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnR5cGUuc3RhcnRzV2l0aCgnVkI6JykpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhcmFtcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IEpTT04ucGFyc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLCAnV3JvbmcgcGFyYW1zIHN5bnRheDogJyArIGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmaW5hbFBhcmFtcyA9IHBhcmFtcztcblxuICAgICAgICAgICAgICAgIGlmIChtZXRob2QgPT09ICd1cGRhdGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0udmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHM/LlZCKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUiwgJ1RoZXJlIGlzIG5vIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgYXBwbGllZCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMuVkIudXBkYXRlVmFsdWVzKHBhcmFtcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiBzdWNjZXNzRXhlY01ldGhvZChmYWxzZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKGVycm9yLm5hbWUsIGVycm9yLm1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0Vycm9yIHVwZGF0aW5nIHZhbHVlcyBvbiBWaXJ0dWFsIEJhY2tncm91bmQgZmlsdGVyOiAnICsgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLCBgVW5rbm93biBWaXJ0dWFsIEJhY2tncm91bmQgbWV0aG9kIFwiJHttZXRob2R9XCJgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhcmFtcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IFwiJ3BhcmFtcycgcHJvcGVydHkgbXVzdCBiZSBhIEpTT04gZm9ybWF0dGVkIG9iamVjdFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3JNc2cpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyaW5nUGFyYW1zID0gPHN0cmluZz5wYXJhbXM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZmluYWxQYXJhbXMgPSBzdHJpbmdQYXJhbXM7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAnZXhlY0ZpbHRlck1ldGhvZCcsXG4gICAgICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZXhlY3V0aW5nIGZpbHRlciBtZXRob2QgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzRXhlY01ldGhvZCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSB0byBjZXJ0YWluIGZpbHRlciBldmVudC4gQXZhaWxhYmxlIGV2ZW50cyBhcmUgc3BlY2lmaWMgZm9yIGVhY2ggZmlsdGVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHdoaWNoIHN1YnNjcmliZSB0by5cbiAgICAgKiBAcGFyYW0gaGFuZGxlciBGdW5jdGlvbiB0byBleGVjdXRlIHVwb24gZXZlbnQgZGlzcGF0Y2hlZC4gSXQgcmVjZWl2ZXMgYXMgcGFyYW1ldGVyIGEgW1tGaWx0ZXJFdmVudF1dIG9iamVjdFxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBldmVudCBsaXN0ZW5lciB3YXMgc3VjY2Vzc2Z1bGx5IGF0dGFjaGVkIHRvIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGFkZEV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRmlsdGVyRXZlbnQpID0+IHZvaWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdBZGRpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAnYWRkRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0Vycm9yIGFkZGluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzLnNldChldmVudFR5cGUsIGhhbmRsZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0ZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgY2VydGFpbiBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHVuc3Vic2NyaWJlIGZyb20uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIGV2ZW50IGxpc3RlbmVyIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBmaWx0ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAncmVtb3ZlRmlsdGVyRXZlbnRMaXN0ZW5lcicsXG4gICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGV2ZW50VHlwZSB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJ2ZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFkZCBhIGZpbHRlciBldmVudCBsaXN0ZW5lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlcnMuZGVsZXRlKGV2ZW50VHlwZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnIHN1Y2Nlc3NmdWxseSByZW1vdmVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWRcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IExvY2FsUmVjb3JkZXJTdGF0ZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm1VdGlscyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvVXRpbHMvUGxhdGZvcm0nO1xuaW1wb3J0IE1pbWUgPSByZXF1aXJlKCdtaW1lL2xpdGUnKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG4vKipcbiAqIEVhc3kgcmVjb3JkaW5nIG9mIFtbU3RyZWFtXV0gb2JqZWN0cyBzdHJhaWdodGF3YXkgZnJvbSB0aGUgYnJvd3Nlci4gSW5pdGlhbGl6ZWQgd2l0aCBbW09wZW5WaWR1LmluaXRMb2NhbFJlY29yZGVyXV0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NhbFJlY29yZGVyIHtcbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IE1lZGlhUmVjb3JkZXI7XG4gICAgcHJpdmF0ZSBjaHVua3M6IGFueVtdID0gW107XG4gICAgcHJpdmF0ZSBibG9iPzogQmxvYjtcbiAgICBwcml2YXRlIGlkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXdTcmM6IHN0cmluZztcbiAgICBwcml2YXRlIHZpZGVvUHJldmlldzogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0cmVhbTogU3RyZWFtKSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICEhdGhpcy5zdHJlYW0uY29ubmVjdGlvbiA/IHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIDogJ2RlZmF1bHQtY29ubmVjdGlvbic7XG4gICAgICAgIHRoaXMuaWQgPSB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICdfJyArIHRoaXMuY29ubmVjdGlvbklkICsgJ19sb2NhbHJlY29yZCc7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQURZYC4gQWZ0ZXIgbWV0aG9kIHN1Y2NlZWRzIGlzIHNldCB0byBgUkVDT1JESU5HYFxuICAgICAqXG4gICAgICogQHBhcmFtIG9wdGlvbnMgVGhlIFtNZWRpYVJlY29yZGVyLm9wdGlvbnNdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9NZWRpYVJlY29yZGVyL01lZGlhUmVjb3JkZXIjcGFyYW1ldGVycykgdG8gYmUgdXNlZCB0byByZWNvcmQgdGhpcyBTdHJlYW0uXG4gICAgICogRm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAgICogdmFyIHB1Ymxpc2hlciA9IGF3YWl0IE9WLmluaXRQdWJsaXNoZXJBc3luYygpO1xuICAgICAqIHZhciBsb2NhbFJlY29yZGVyID0gT1YuaW5pdExvY2FsUmVjb3JkZXIocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICogdmFyIG9wdGlvbnMgPSB7XG4gICAgICogICAgICBtaW1lVHlwZTogJ3ZpZGVvL3dlYm07Y29kZWNzPXZwOCcsXG4gICAgICogICAgICBhdWRpb0JpdHNQZXJTZWNvbmQ6MTI4MDAwLFxuICAgICAqICAgICAgdmlkZW9CaXRzUGVyU2Vjb25kOjI1MDAwMDBcbiAgICAgKiB9O1xuICAgICAqIGxvY2FsUmVjb3JkZXIucmVjb3JkKG9wdGlvbnMpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSWYgbm90IHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgb3B0aW9ucyBwcmVmZXJyZWQgYnkgdGhlIHBsYXRmb3JtIHdpbGwgYmUgdXNlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdGFydGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZWNvcmQob3B0aW9ucz86IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnIHx8IG9wdGlvbnMgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIGBXaGVuIGNhbGxpbmcgTG9jYWxSZWNvcmRlci5yZWNvcmQob3B0aW9ucykgcGFyYW1ldGVyICdvcHRpb25zJyBjYW5ub3QgYmUgYSBzdHJpbmcuIE11c3QgYmUgYW4gb2JqZWN0IGxpa2UgeyBtaW1lVHlwZTogXCIke29wdGlvbnN9XCIgfWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVJlY29yZGVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAnTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgZGV2aWNlLiBTZWUgY29tcGF0aWJpbGl0eSBpbiBodHRwczovL2Nhbml1c2UuY29tLyNzZWFyY2g9TWVkaWFSZWNvcmRlcidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAnTWVkaWFSZWNvcmRlciBub3Qgc3VwcG9ydGVkIG9uIHlvdXIgZGV2aWNlLiBTZWUgY29tcGF0aWJpbGl0eSBpbiBodHRwczovL2Nhbml1c2UuY29tLyNzZWFyY2g9TWVkaWFSZWNvcmRlcidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnJlY29yZCgpJyBuZWVkcyAnTG9jYWxSZWNvcmQuc3RhdGUnIHRvIGJlICdSRUFEWScgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5jbGVhbigpJyBvciBpbml0IGEgbmV3IExvY2FsUmVjb3JkZXIgYmVmb3JlXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcIlN0YXJ0aW5nIGxvY2FsIHJlY29yZGluZyBvZiBzdHJlYW0gJ1wiICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyBcIicgb2YgY29ubmVjdGlvbiAnXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArIFwiJ1wiKTtcblxuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0geyBtaW1lVHlwZTogJ3ZpZGVvL3dlYm0nIH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghb3B0aW9ucy5taW1lVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm1pbWVUeXBlID0gJ3ZpZGVvL3dlYm0nO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdGFydCgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25kYXRhYXZhaWxhYmxlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZS5kYXRhLnNpemUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2h1bmtzLnB1c2goZS5kYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdNZWRpYVJlY29yZGVyIGVycm9yOiAnLCBlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ01lZGlhUmVjb3JkZXIgc3RhcnRlZCAoc3RhdGU9JyArIHRoaXMubWVkaWFSZWNvcmRlci5zdGF0ZSArICcpJyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdG9wID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMub25TdG9wRGVmYXVsdCgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucGF1c2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZygnTWVkaWFSZWNvcmRlciBwYXVzZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9ucmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ01lZGlhUmVjb3JkZXIgcmVzdW1lZCAoc3RhdGU9JyArIHRoaXMubWVkaWFSZWNvcmRlci5zdGF0ZSArICcpJyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORztcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuZHMgdGhlIHJlY29yZGluZyBvZiB0aGUgU3RyZWFtLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgUkVDT1JESU5HYCBvciBgUEFVU0VEYC4gQWZ0ZXIgbWV0aG9kIHN1Y2NlZWRzIGlzIHNldCB0byBgRklOSVNIRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgc3VjY2Vzc2Z1bGx5IHN0b3BwZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQuc3RvcCgpJyBuZWVkcyAnTG9jYWxSZWNvcmQuc3RhdGUnIHRvIGJlICdSRUNPUkRJTkcnIG9yICdQQVVTRUQnIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuc3RhcnQoKScgYmVmb3JlXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0b3BEZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIuc3RvcCgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhdXNlcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQucGF1c2UoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnUkVDT1JESU5HJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuc3RhcnQoKScgb3IgJ0xvY2FsUmVjb3JkZXIucmVzdW1lKCknIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5wYXVzZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXN1bWVzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyB3YXMgc3VjY2Vzc2Z1bGx5IHJlc3VtZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHJlc3VtZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5QQVVTRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC5yZXN1bWUoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnUEFVU0VEJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnBhdXNlKCknIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5yZXN1bWUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORztcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJldmlld3MgdGhlIHJlY29yZGluZywgYXBwZW5kaW5nIGEgbmV3IEhUTUxWaWRlb0VsZW1lbnQgdG8gZWxlbWVudCB3aXRoIGlkIGBwYXJlbnRJZGAuIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBGSU5JU0hFRGBcbiAgICAgKi9cbiAgICBwcmV2aWV3KHBhcmVudEVsZW1lbnQpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQucHJldmlldygpJyBuZWVkcyAnTG9jYWxSZWNvcmQuc3RhdGUnIHRvIGJlICdGSU5JU0hFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnN0b3AoKScgYmVmb3JlXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuaWQgPSB0aGlzLmlkO1xuICAgICAgICB0aGlzLnZpZGVvUHJldmlldy5hdXRvcGxheSA9IHRydWU7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldy5wbGF5c0lubGluZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50RG9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAocGFyZW50RWxlbWVudERvbSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuc3JjID0gdGhpcy52aWRlb1ByZXZpZXdTcmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW9QcmV2aWV3O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdyYWNlZnVsbHkgc3RvcHMgYW5kIGNsZWFucyB0aGUgY3VycmVudCByZWNvcmRpbmcgKFdBUk5JTkc6IGl0IGlzIGNvbXBsZXRlbHkgZGlzbWlzc2VkKS4gU2V0cyBbW3N0YXRlXV0gdG8gYFJFQURZYCBzbyB0aGUgcmVjb3JkaW5nIGNhbiBzdGFydCBhZ2FpblxuICAgICAqL1xuICAgIGNsZWFuKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBmID0gKCkgPT4ge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuYmxvYjtcbiAgICAgICAgICAgIHRoaXMuY2h1bmtzID0gW107XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IGYoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERvd25sb2FkcyB0aGUgcmVjb3JkZWQgdmlkZW8gdGhyb3VnaCB0aGUgYnJvd3Nlci4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYFxuICAgICAqL1xuICAgIGRvd25sb2FkKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC5kb3dubG9hZCgpJyBuZWVkcyAnTG9jYWxSZWNvcmQuc3RhdGUnIHRvIGJlICdGSU5JU0hFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnN0b3AoKScgYmVmb3JlXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICAgIGEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9IGdsb2JhbFRoaXMuVVJMLmNyZWF0ZU9iamVjdFVSTCg8YW55PnRoaXMuYmxvYik7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gdGhpcy5pZCArICcuJyArIE1pbWUuZ2V0RXh0ZW5zaW9uKHRoaXMuYmxvYiEudHlwZSk7XG4gICAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgICAgICBnbG9iYWxUaGlzLlVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcblxuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHJhdyBCbG9iIGZpbGUuIE1ldGhvZHMgcHJldmlldywgZG93bmxvYWQsIHVwbG9hZEFzQmluYXJ5IGFuZCB1cGxvYWRBc011bHRpcGFydGZpbGUgdXNlIHRoaXMgc2FtZSBmaWxlIHRvIHBlcmZvcm0gdGhlaXIgc3BlY2lmaWMgYWN0aW9ucy4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYFxuICAgICAqL1xuICAgIGdldEJsb2IoKTogQmxvYiB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiQ2FsbCAnTG9jYWxSZWNvcmQuc3RvcCgpJyBiZWZvcmUgZ2V0dGluZyBCbG9iIGZpbGVcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iITtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwbG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIGFzIGEgYmluYXJ5IGZpbGUgcGVyZm9ybWluZyBhbiBIVFRQL1BPU1Qgb3BlcmF0aW9uIHRvIFVSTCBgZW5kcG9pbnRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3RcbiAgICAgKi9cbiAgICB1cGxvYWRBc0JpbmFyeShlbmRwb2ludDogc3RyaW5nLCBoZWFkZXJzPzogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnVwbG9hZEFzQmluYXJ5KCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ0ZJTklTSEVEJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnN0b3AoKScgYmVmb3JlXCJcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGh0dHAgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCBlbmRwb2ludCwgdHJ1ZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGhlYWRlcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoa2V5LCBoZWFkZXJzW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChodHRwLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChodHRwLnN0YXR1cy50b1N0cmluZygpLmNoYXJBdCgwKSA9PT0gJzInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2VzcyByZXNwb25zZSBmcm9tIHNlcnZlciAoSFRUUCBzdGF0dXMgc3RhbmRhcmQ6IDJYWCBpcyBzdWNjZXNzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGh0dHAucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIG11bHRpcGFydCBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90OlxuICAgICAqL1xuICAgIHVwbG9hZEFzTXVsdGlwYXJ0ZmlsZShlbmRwb2ludDogc3RyaW5nLCBoZWFkZXJzPzogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnVwbG9hZEFzTXVsdGlwYXJ0ZmlsZSgpJyBuZWVkcyAnTG9jYWxSZWNvcmQuc3RhdGUnIHRvIGJlICdGSU5JU0hFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5zdG9wKCknIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgc2VuZGFibGUuYXBwZW5kKCdmaWxlJywgdGhpcy5ibG9iISwgdGhpcy5pZCArICcuJyArIE1pbWUuZ2V0RXh0ZW5zaW9uKHRoaXMuYmxvYiEudHlwZSkpO1xuXG4gICAgICAgICAgICAgICAgaHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChodHRwLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChodHRwLnN0YXR1cy50b1N0cmluZygpLmNoYXJBdCgwKSA9PT0gJzInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2VzcyByZXNwb25zZSBmcm9tIHNlcnZlciAoSFRUUCBzdGF0dXMgc3RhbmRhcmQ6IDJYWCBpcyBzdWNjZXNzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGh0dHAucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaHR0cC5zZW5kKHNlbmRhYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIG9uU3RvcERlZmF1bHQoKTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci5sb2coJ01lZGlhUmVjb3JkZXIgc3RvcHBlZCAgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuXG4gICAgICAgIHRoaXMuYmxvYiA9IG5ldyBCbG9iKHRoaXMuY2h1bmtzLCB7IHR5cGU6IHRoaXMubWVkaWFSZWNvcmRlci5taW1lVHlwZSB9KTtcbiAgICAgICAgdGhpcy5jaHVua3MgPSBbXTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlld1NyYyA9IGdsb2JhbFRoaXMuVVJMLmNyZWF0ZU9iamVjdFVSTCh0aGlzLmJsb2IpO1xuXG4gICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQ7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IExvY2FsUmVjb3JkZXIgfSBmcm9tICcuL0xvY2FsUmVjb3JkZXInO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi9QdWJsaXNoZXInO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBEZXZpY2UgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0RldmljZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvQ3VzdG9tTWVkaWFTdHJlYW1Db25zdHJhaW50cyc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcblxuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZ0F1dG8gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmctQXV0byc7XG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbic7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuICAgIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuICAgIHByaXZhdGUgbWFzdGVyTm9kZUhhc0NyYXNoZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZXJzOiBQdWJsaXNoZXJbXSA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB3c1VyaTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBodHRwVXJpOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlY3JldCA9ICcnO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZWNvcmRlciA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpY2VTZXJ2ZXJzOiBSVENJY2VTZXJ2ZXJbXTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcm9sZTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBmaW5hbFVzZXJJZDogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBtZWRpYVNlcnZlcjogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB2aWRlb1NpbXVsY2FzdDogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGlmZTogbnVtYmVyID0gLTE7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFkdmFuY2VkQ29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgd2VicnRjU3RhdHNJbnRlcnZhbDogbnVtYmVyID0gLTE7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRCcm93c2VyTG9nczogT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uID0gT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uLmRpc2FibGVkO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0F0TGVhc3RQcm86IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNFbnRlcnByaXNlOiBib29sZWFuID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxpYnJhcnlWZXJzaW9uOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLmxpYnJhcnlWZXJzaW9uID0gcGFja2FnZUpzb24udmVyc2lvbjtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ09wZW5WaWR1IGluaXRpYWxpemVkJyk7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdQbGF0Zm9ybSBkZXRlY3RlZDogJyArIHBsYXRmb3JtLmdldERlc2NyaXB0aW9uKCkpO1xuICAgICAgICBsb2dnZXIuaW5mbygnb3BlbnZpZHUtYnJvd3NlciB2ZXJzaW9uOiAnICsgdGhpcy5saWJyYXJ5VmVyc2lvbik7XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLmlzTW9iaWxlRGV2aWNlKCkgfHwgcGxhdGZvcm0uaXNSZWFjdE5hdGl2ZSgpKSB7XG4gICAgICAgICAgICAvLyBMaXN0ZW4gdG8gb3JpZW50YXRpb25jaGFuZ2Ugb25seSBvbiBtb2JpbGUgZGV2aWNlc1xuICAgICAgICAgICAgdGhpcy5vbk9yaWVudGF0aW9uQ2hhbmdlZCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZXJzLmZvckVhY2goKHB1Ymxpc2hlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkICYmICEhcHVibGlzaGVyLnN0cmVhbSAmJiAhIXB1Ymxpc2hlci5zdHJlYW0uaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VuZE5ld1ZpZGVvRGltZW5zaW9uc0lmUmVxdWlyZWQocHVibGlzaGVyLCAnZGV2aWNlUm90YXRlZCcsIDc1LCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBuZXcgc2Vzc2lvblxuICAgICAqL1xuICAgIGluaXRTZXNzaW9uKCk6IFNlc3Npb24ge1xuICAgICAgICB0aGlzLnNlc3Npb24gPSBuZXcgU2Vzc2lvbih0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbjtcbiAgICB9XG5cbiAgICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQdWJsaXNoZXI7XG4gICAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCwgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpOiBQdWJsaXNoZXI7XG4gICAgaW5pdFB1Ymxpc2hlcihcbiAgICAgICAgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsXG4gICAgICAgIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMsXG4gICAgICAgIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICAgKTogUHVibGlzaGVyO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIG5ldyBwdWJsaXNoZXJcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGFuIGBhY2Nlc3NEaWFsb2dPcGVuZWRgIGV2ZW50LCBvbmx5IGlmIHRoZSBwb3AtdXAgc2hvd24gYnkgdGhlIGJyb3dzZXIgdG8gcmVxdWVzdCBwZXJtaXNzaW9ucyBmb3IgdGhlIGNhbWVyYSBpcyBvcGVuZWQuIFlvdSBjYW4gdXNlIHRoaXMgZXZlbnQgdG8gYWxlcnQgdGhlIHVzZXIgYWJvdXQgZ3JhbnRpbmcgcGVybWlzc2lvbnNcbiAgICAgKiBmb3IgeW91ciB3ZWJzaXRlLiBBbiBgYWNjZXNzRGlhbG9nQ2xvc2VkYCBldmVudCB3aWxsIGFsc28gYmUgZGlzcGF0Y2hlZCBhZnRlciB1c2VyIGNsaWNrcyBvbiBcIkFsbG93XCIgb3IgXCJCbG9ja1wiIGluIHRoZSBwb3AtdXAuXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYGFjY2Vzc0RlbmllZGAgZXZlbnQgb25jZSBpdCBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90LlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSBhIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAgICogW2xldCBPcGVuVmlkdSB0YWtlIGNhcmUgb2YgdGhlIHZpZGVvIHBsYXllcnNdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCAgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyIHdpbGwgYmUgaW5zZXJ0ZWQgKHNlZSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFB1Ymxpc2hlci5cbiAgICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1B1Ymxpc2hlci5hZGRWaWRlb0VsZW1lbnRdXSBvciBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcykgc2VjdGlvbilcbiAgICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgaW5pdFB1Ymxpc2hlcmAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBgY29tcGxldGlvbkhhbmRsZXJgIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgdGhlIFB1Ymxpc2hlciBkaXNwYXRjaGVzIGFuIGBhY2Nlc3NBbGxvd2VkYCBvciBhbiBgYWNjZXNzRGVuaWVkYCBldmVudFxuICAgICAqL1xuICAgIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIHBhcmFtMj8sIHBhcmFtMz8pOiBQdWJsaXNoZXIge1xuICAgICAgICBsZXQgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcztcblxuICAgICAgICBpZiAoISFwYXJhbTIgJiYgdHlwZW9mIHBhcmFtMiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0gPFB1Ymxpc2hlclByb3BlcnRpZXM+cGFyYW0yO1xuXG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvU291cmNlOiB0eXBlb2YgcHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcgPyBwcm9wZXJ0aWVzLmF1ZGlvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTpcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgcHJvcGVydGllcy5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHByb3BlcnRpZXMuZnJhbWVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOlxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIG1pcnJvcjogdHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJyA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwdWJsaXNoQXVkaW86IHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgICAgICAgICAgcHVibGlzaFZpZGVvOiB0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgIHJlc29sdXRpb246XG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcGVydGllcy5yZXNvbHV0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICA6ICc2NDB4NDgwJyxcbiAgICAgICAgICAgICAgICB2aWRlb1NvdXJjZTogdHlwZW9mIHByb3BlcnRpZXMudmlkZW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnID8gcHJvcGVydGllcy52aWRlb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB2aWRlb1NpbXVsY2FzdDogcHJvcGVydGllcy52aWRlb1NpbXVsY2FzdCxcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IHByb3BlcnRpZXMuZmlsdGVyXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gTWF0Y2hlcyAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50KScgb3IgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY29tcGxldGlvbkhhbmRsZXIpJ1xuXG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgbWlycm9yOiB0cnVlLFxuICAgICAgICAgICAgICAgIHB1Ymxpc2hBdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwdWJsaXNoVmlkZW86IHRydWUsXG4gICAgICAgICAgICAgICAgcmVzb2x1dGlvbjogJzY0MHg0ODAnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHVibGlzaGVyOiBQdWJsaXNoZXIgPSBuZXcgUHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIHRoaXMpO1xuXG4gICAgICAgIGxldCBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcbiAgICAgICAgaWYgKCEhcGFyYW0yICYmIHR5cGVvZiBwYXJhbTIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0yO1xuICAgICAgICB9IGVsc2UgaWYgKCEhcGFyYW0zKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfVxuXG4gICAgICAgIHB1Ymxpc2hlclxuICAgICAgICAgICAgLmluaXRpYWxpemUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uSGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uSGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW2Vycm9yXSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnB1Ymxpc2hlcnMucHVzaChwdWJsaXNoZXIpO1xuICAgICAgICByZXR1cm4gcHVibGlzaGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKlxuICAgICAqID4gV0FSTklORzogZXZlbnRzIGBhY2Nlc3NEaWFsb2dPcGVuZWRgIGFuZCBgYWNjZXNzRGlhbG9nQ2xvc2VkYCB3aWxsIG5vdCBiZSBkaXNwYXRjaGVkIGlmIHVzaW5nIHRoaXMgbWV0aG9kIGluc3RlYWQgb2YgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV1cbiAgICAgKi9cbiAgICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG4gICAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuXG4gICAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzPzogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxQdWJsaXNoZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcblxuICAgICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocHVibGlzaGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyID0gdGhpcy5pbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIG5ldyBsb2NhbCByZWNvcmRlciBmb3IgcmVjb3JkaW5nIHN0cmVhbXMgc3RyYWlnaHQgYXdheSBmcm9tIHRoZSBicm93c2VyXG4gICAgICogQHBhcmFtIHN0cmVhbSAgU3RyZWFtIHRvIHJlY29yZFxuICAgICAqL1xuICAgIGluaXRMb2NhbFJlY29yZGVyKHN0cmVhbTogU3RyZWFtKTogTG9jYWxSZWNvcmRlciB7XG4gICAgICAgIHJldHVybiBuZXcgTG9jYWxSZWNvcmRlcihzdHJlYW0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdVxuICAgICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHUsIDAgb3RoZXJ3aXNlXG4gICAgICovXG4gICAgY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFNwZWNpZmljIGlPUyBwbGF0Zm9ybSBzdXBwb3J0IChpUGhvbmUsIGlQYWQpXG4gICAgICAgIGlmIChwbGF0Zm9ybS5pc0lQaG9uZU9ySVBhZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzSU9TV2l0aFNhZmFyaSgpIHx8XG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNDaHJvbWVNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNJb25pY0lvcygpIC8vIElvbmljIGFwcHMgZm9yIGlPU1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdlbmVyYWwgcGxhdGZvcm0gc3VwcG9ydCBmb3Igd2ViIGNsaWVudHMgKERlc2t0b3AsIE1vYmlsZSlcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQ2hyb21lQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0Nocm9tZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNGaXJlZm94QnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc1NhbXN1bmdCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0FuZHJvaWRCcm93c2VyKCkgfHwgLy8gQW5kcm9pZCBXZWJWaWV3ICYgSW9uaWMgYXBwcyBmb3IgQW5kcm9pZFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNFbGVjdHJvbigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc05vZGVKcygpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLiBEZXNrdG9wIENocm9tZSwgRmlyZWZveCBhbmQgT3BlcmEgc3VwcG9ydCBzY3JlZW4tc2hhcmluZ1xuICAgICAqIEByZXR1cm5zIDEgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcsIDAgb3RoZXJ3aXNlXG4gICAgICovXG4gICAgY2hlY2tTY3JlZW5TaGFyaW5nQ2FwYWJpbGl0aWVzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0uY2FuU2NyZWVuU2hhcmUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb2xsZWN0cyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbWVkaWEgaW5wdXQgZGV2aWNlcyBhdmFpbGFibGUgb24gdGhlIHN5c3RlbS4gWW91IGNhbiBwYXNzIHByb3BlcnR5IGBkZXZpY2VJZGAgb2YgYSBbW0RldmljZV1dIG9iamVjdCBhcyB2YWx1ZSBvZiBgYXVkaW9Tb3VyY2VgIG9yIGB2aWRlb1NvdXJjZWAgcHJvcGVydGllcyBpbiBbW2luaXRQdWJsaXNoZXJdXSBtZXRob2RcbiAgICAgKi9cbiAgICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzXG4gICAgICAgICAgICAgICAgLmVudW1lcmF0ZURldmljZXMoKVxuICAgICAgICAgICAgICAgIC50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLmlzSW9uaWNBbmRyb2lkKCkgJiYgdHlwZW9mIGNvcmRvdmEgIT0gJ3VuZGVmaW5lZCcgJiYgY29yZG92YT8ucGx1Z2lucz8uRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29yZG92YS5wbHVnaW5zLkVudW1lcmF0ZURldmljZXNQbHVnaW4uZ2V0RW51bWVyYXRlRGV2aWNlcygpLnRoZW4oKHBsdWdpbkRldmljZXM6IERldmljZVtdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmlkZW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhdWRpb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RldmljZXMgPSBkZXZpY2VJbmZvcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RldmljZXMgPSBkZXZpY2VJbmZvcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbGFiZWwgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gJ0Zyb250IENhbWVyYSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnQmFjayBDYW1lcmEnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdVbmtub3duIENhbWVyYSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogbGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IGRldmljZUluZm8uZGV2aWNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EZXZpY2VzLmZvckVhY2goKGRldmljZUluZm8sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZGV2aWNlSW5mby5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiAvLyBEZWZhdWx0IE1pY3JvcGhvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnRGVmYXVsdCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogLy8gTWljcm9waG9uZSArIFNwZWFrZXJwaG9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0TWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCdWlsdCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSBkZWZhdWx0TWF0Y2ggPyBkZWZhdWx0TWF0Y2gubGFiZWwgOiAnQnVpbHQtaW4gTWljcm9waG9uZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gSGVhZHNldCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVkTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdXaXJlZCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdpcmVkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWRNYXRjaC5sYWJlbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gJ0hlYWRzZXQgZWFycGllY2UnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lyZWxlc3NNYXRjaCA9IHBsdWdpbkF1ZGlvRGV2aWNlcy5maWx0ZXIoKGQpID0+IGQubGFiZWwuaW5jbHVkZXMoJ0JsdWV0b290aCcpKVswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSB3aXJlbGVzc01hdGNoID8gd2lyZWxlc3NNYXRjaC5sYWJlbCA6ICdXaXJlbGVzcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gJ1Vua25vd24gTWljcm9waG9uZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IGRldmljZUluZm8uZGV2aWNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHBsYXRmb3Jtc1xuICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSW5mb3MuZm9yRWFjaCgoZGV2aWNlSW5mbykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXZpY2VJbmZvLmtpbmQgPT09ICdhdWRpb2lucHV0JyB8fCBkZXZpY2VJbmZvLmtpbmQgPT09ICd2aWRlb2lucHV0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IGRldmljZUluZm8uZGV2aWNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZGV2aWNlSW5mby5sYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGRldmljZXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZ2V0dGluZyBkZXZpY2VzJywgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgTWVkaWFTdHJlYW0gb2JqZWN0IHRoYXQgeW91IGNhbiBjdXN0b21pemUgYmVmb3JlIGNhbGxpbmcgW1tpbml0UHVibGlzaGVyXV0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dKVxuICAgICAqXG4gICAgICogUGFyYW1ldGVyIGBvcHRpb25zYCBpcyB0aGUgc2FtZSBhcyBpbiBbW2luaXRQdWJsaXNoZXJdXSBzZWNvbmQgcGFyYW1ldGVyIChvZiB0eXBlIFtbUHVibGlzaGVyUHJvcGVydGllc11dKSwgYnV0IG9ubHkgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIHdpbGwgYmUgYXBwbGllZDogYGF1ZGlvU291cmNlYCwgYHZpZGVvU291cmNlYCwgYGZyYW1lUmF0ZWAsIGByZXNvbHV0aW9uYFxuICAgICAqXG4gICAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAgICogYGBgXG4gICAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICAgKlxuICAgICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgICAqICAgIHZpZGVvU291cmNlOiB1bmRlZmluZWQsXG4gICAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgKlxuICAgICAqICAgIHZhciB2aWRlb1RyYWNrID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgICAqXG4gICAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgKiAgICBjdHguZmlsdGVyID0gJ2dyYXlzY2FsZSgxMDAlKSc7XG4gICAgICpcbiAgICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgICAqICAgICAgdmFyIGxvb3AgPSAoKSA9PiB7XG4gICAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICAgKiAgICAgICAgICBzZXRUaW1lb3V0KGxvb3AsIDEwMDAvIEZSQU1FX1JBVEUpOyAvLyBEcmF3aW5nIGF0IDEwIGZwc1xuICAgICAqICAgICAgICB9XG4gICAgICogICAgICB9O1xuICAgICAqICAgICAgbG9vcCgpO1xuICAgICAqICAgIH0pO1xuICAgICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICAgKlxuICAgICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICAgKiAgICAgIG15SHRtbFRhcmdldCxcbiAgICAgKiAgICAgIHtcbiAgICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgICAqICAgICAgICB2aWRlb1NvdXJjZTogZ3JheVZpZGVvVHJhY2tcbiAgICAgKiAgICAgIH0pO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFza0ZvckF1ZGlvU3RyZWFtT25seSA9IGFzeW5jIChwcmV2aW91c01lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSwgY29uc3RyYWludHM6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gY29uc3RyYWludHMuYXVkaW8gPT09IHVuZGVmaW5lZCA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbztcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50c0F1eDogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHsgYXVkaW86IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQsIHZpZGVvOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvT25seVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNNZWRpYVN0cmVhbS5hZGRUcmFjayhhdWRpb09ubHlTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXZpb3VzTWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzTWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNNZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMuZ2VuZXJhdGVBdWRpb0RldmljZUVycm9yKGVycm9yLCBjb25zdHJhaW50c0F1eCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXlDb25zdHJhaW50cyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrICYmICEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrKSB8fFxuICAgICAgICAgICAgICAgICAgICAoISFteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2sgJiYgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cz8udmlkZW8gPT09IGZhbHNlKSB8fFxuICAgICAgICAgICAgICAgICAgICAoISFteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2sgJiYgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cz8uYXVkaW8gPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAvLyBObyBuZWVkIHRvIGNhbGwgZ2V0VXNlck1lZGlhIGF0IGFsbC4gQm90aCB0cmFja3MgcHJvdmlkZWQsIG9yIG9ubHkgQVVESU8gdHJhY2sgcHJvdmlkZWQgb3Igb25seSBWSURFTyB0cmFjayBwcm92aWRlZFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh0aGlzLmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBuZXcgTWVkaWFTdHJlYW0oKSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldFVzZXJNZWRpYSBtdXN0IGJlIGNhbGxlZC4gQVVESU8gb3IgVklERU8gYXJlIHJlcXVlc3RpbmcgYSBuZXcgdHJhY2tcblxuICAgICAgICAgICAgICAgICAgICAvLyBEZWxldGUgYWxyZWFkeSBwcm92aWRlZCBjb25zdHJhaW50cyBmb3IgYXVkaW8gb3IgdmlkZW9cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW87XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEuYXVkaW87XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBsZXQgbXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBWaWRlbyBpcyBkZXZpY2VJZCBvciBzY3JlZW4gc2hhcmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3dpbmRvdycgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGxhdGZvcm0uaXNFbGVjdHJvbigpICYmIG9wdGlvbnMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmlkZW8gaXMgc2NyZWVuIHNoYXJpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXN0QXNrRm9yQXVkaW9UcmFja0xhdGVyID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIW15Q29uc3RyYWludHMuYXVkaW9UcmFjayAmJiBvcHRpb25zLmF1ZGlvU291cmNlICE9PSBudWxsICYmIG9wdGlvbnMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSAmJiAhcGxhdGZvcm0uaXNFbGVjdHJvbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtdXN0QXNrRm9yQXVkaW9UcmFja0xhdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgYXNrRm9yQXVkaW9TdHJlYW1Pbmx5KG1lZGlhU3RyZWFtLCA8TWVkaWFTdHJlYW1Db25zdHJhaW50cz5teUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBOT1Qgc3VwcG9ydGVkLiBDYW4gcGVyZm9ybSBnZXRVc2VyTWVkaWEgYmVsb3cgd2l0aCBhbHJlYWR5IGNhbGN1bGF0ZWQgY29uc3RyYWludHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZpZGVvIGlzIGRldmljZUlkLiBDYW4gcGVyZm9ybSBnZXRVc2VyTWVkaWEgYmVsb3cgd2l0aCBhbHJlYWR5IGNhbGN1bGF0ZWQgY29uc3RyYWludHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYWxyZWFkeSBjYWxjdWxhdGVkIGNvbnN0cmFpbnRzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzQXV4ID0gbXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlclxuICAgICAgICAgICAgICAgICAgICAgICAgPyB7IHZpZGVvOiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbyB9XG4gICAgICAgICAgICAgICAgICAgICAgICA6IG15Q29uc3RyYWludHMuY29uc3RyYWludHM7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtdXN0QXNrRm9yQXVkaW9UcmFja0xhdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgYXNrRm9yQXVkaW9TdHJlYW1Pbmx5KG1lZGlhU3RyZWFtLCA8TWVkaWFTdHJlYW1Db25zdHJhaW50cz5teUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgICAvKipcbiAgICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgICAqL1xuICAgIGVuYWJsZVByb2RNb2RlKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuZW5hYmxlUHJvZE1vZGUoKTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG4gICAgLyoqXG4gICAgICogU2V0IE9wZW5WaWR1IGFkdmFuY2VkIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy4gYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCBvZiB0eXBlIFtbT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb25dXS4gQ2FsbCB0aGlzIG1ldGhvZCB0byBvdmVycmlkZSBwcmV2aW91cyB2YWx1ZXMgYXQgYW55IG1vbWVudC5cbiAgICAgKi9cbiAgICBzZXRBZHZhbmNlZENvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbjogT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25PcmllbnRhdGlvbkNoYW5nZWQoaGFuZGxlcik6IHZvaWQge1xuICAgICAgICAoZ2xvYmFsVGhpcyBhcyBhbnkpLmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgaGFuZGxlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmROZXdWaWRlb0RpbWVuc2lvbnNJZlJlcXVpcmVkKHB1Ymxpc2hlcjogUHVibGlzaGVyLCByZWFzb246IHN0cmluZywgV0FJVF9JTlRFUlZBTDogbnVtYmVyLCBNQVhfQVRURU1QVFM6IG51bWJlcikge1xuICAgICAgICBsZXQgYXR0ZW1wdHMgPSAwO1xuICAgICAgICBjb25zdCBvbGRXaWR0aCA9IHB1Ymxpc2hlcj8uc3RyZWFtPy52aWRlb0RpbWVuc2lvbnM/LndpZHRoIHx8IDA7XG4gICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlcj8uc3RyZWFtPy52aWRlb0RpbWVuc2lvbnM/LmhlaWdodCB8fCAwO1xuXG4gICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlT3JNYXhBdHRlbXB0czogTm9kZUpTLlRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgaWYgKGF0dGVtcHRzID4gTUFYX0FUVEVNUFRTKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlT3JNYXhBdHRlbXB0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaXNoZXIuZ2V0VmlkZW9EaW1lbnNpb25zKCkudGhlbigobmV3RGltZW5zaW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChuZXdEaW1lbnNpb25zLndpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdEaW1lbnNpb25zLmhlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZU9yTWF4QXR0ZW1wdHMpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCByZWFzb24sIG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMud2lkdGgsIG5ld0RpbWVuc2lvbnMuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgV0FJVF9JTlRFUlZBTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQoXG4gICAgICAgIHB1Ymxpc2hlcjogUHVibGlzaGVyLFxuICAgICAgICByZWFzb246IHN0cmluZyxcbiAgICAgICAgb2xkV2lkdGg6IG51bWJlcixcbiAgICAgICAgb2xkSGVpZ2h0OiBudW1iZXIsXG4gICAgICAgIG5ld1dpZHRoOiBudW1iZXIsXG4gICAgICAgIG5ld0hlaWdodDogbnVtYmVyXG4gICAgKSB7XG4gICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgd2lkdGg6IG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICBoZWlnaHQ6IG5ld0hlaWdodCB8fCAwXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzdHJlYW1JZDogcHVibGlzaGVyLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvRGltZW5zaW9ucycsXG4gICAgICAgICAgICAgICAgbmV3VmFsdWU6IEpTT04uc3RyaW5naWZ5KHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICByZWFzb25cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25cbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHdpZHRoOiBvbGRXaWR0aCwgaGVpZ2h0OiBvbGRIZWlnaHQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25cbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5zZW5kVmlkZW9EYXRhKHB1Ymxpc2hlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kVHJhY2tDaGFuZ2VkRXZlbnQocHVibGlzaGVyOiBQdWJsaXNoZXIsIHJlYXNvbjogc3RyaW5nLCBvbGRMYWJlbDogc3RyaW5nLCBuZXdMYWJlbDogc3RyaW5nLCBwcm9wZXJ0eVR5cGU6IHN0cmluZykge1xuICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHsgbGFiZWw6IG9sZExhYmVsIH07XG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlID0geyBsYWJlbDogbmV3TGFiZWwgfTtcblxuICAgICAgICBpZiAocHVibGlzaGVyLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHB1Ymxpc2hlci5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiBwcm9wZXJ0eVR5cGUsXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBKU09OLnN0cmluZ2lmeSh7IG5ld0xhYmVsIH0pLFxuICAgICAgICAgICAgICAgICAgICByZWFzb25cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCBwdWJsaXNoZXIuc3RyZWFtLCBwcm9wZXJ0eVR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSwgcmVhc29uKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgcHJvcGVydHlUeXBlLCBuZXdWYWx1ZSwgb2xkVmFsdWUsIHJlYXNvbilcbiAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCBwdWJsaXNoZXIuc3RyZWFtLCBwcm9wZXJ0eVR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSwgcmVhc29uKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHB1Ymxpc2hlciwgcHVibGlzaGVyLnN0cmVhbSwgcHJvcGVydHlUeXBlLCBuZXdWYWx1ZSwgb2xkVmFsdWUsIHJlYXNvbilcbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBteUNvbnN0cmFpbnRzOiBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvVHJhY2s6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB2aWRlb1RyYWNrOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgY29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBhdWRpb1NvdXJjZSA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2U7XG5cbiAgICAgICAgICAgIC8vIENBU0UgMTogbnVsbC9mYWxzZVxuICAgICAgICAgICAgaWYgKGF1ZGlvU291cmNlID09PSBudWxsIHx8IGF1ZGlvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIC8vIE5vIGF1ZGlvIHRyYWNrXG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEuYXVkaW8gPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh2aWRlb1NvdXJjZSA9PT0gbnVsbCB8fCB2aWRlb1NvdXJjZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAvLyBObyB2aWRlbyB0cmFja1xuICAgICAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEuYXVkaW8gPT09IGZhbHNlICYmIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIC8vIEVSUk9SISBhdWRpb1NvdXJjZSBhbmQgdmlkZW9Tb3VyY2UgY2Fubm90IGJlIGJvdGggZmFsc2UgYXQgdGhlIHNhbWUgdGltZVxuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuTk9fSU5QVVRfU09VUkNFX1NFVCxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiUHJvcGVydGllcyAnYXVkaW9Tb3VyY2UnIGFuZCAndmlkZW9Tb3VyY2UnIGNhbm5vdCBiZSBzZXQgdG8gZmFsc2Ugb3IgbnVsbCBhdCB0aGUgc2FtZSB0aW1lXCJcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENBU0UgMjogTWVkaWFTdHJlYW1UcmFja3NcbiAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgLy8gQWxyZWFkeSBwcm92aWRlZCBhdWRpbyB0cmFja1xuICAgICAgICAgICAgICAgIG15Q29uc3RyYWludHMuYXVkaW9UcmFjayA9IGF1ZGlvU291cmNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB2aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IHByb3ZpZGVkIHZpZGVvIHRyYWNrXG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy52aWRlb1RyYWNrID0gdmlkZW9Tb3VyY2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENBU0UgMzogRGVmYXVsdCB0cmFja3NcbiAgICAgICAgICAgIGlmIChhdWRpb1NvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEuYXVkaW8gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZpZGVvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkZWFsOiA2NDBcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZGVhbDogNDgwXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDQVNFIDMuNTogZ2l2ZSB2YWx1ZXMgdG8gcmVzb2x1dGlvbiBhbmQgZnJhbWVSYXRlIGlmIHZpZGVvIG5vdCBudWxsL2ZhbHNlXG4gICAgICAgICAgICBpZiAodmlkZW9Tb3VyY2UgIT09IG51bGwgJiYgdmlkZW9Tb3VyY2UgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpZHRoQW5kSGVpZ2h0ID0gcHVibGlzaGVyUHJvcGVydGllcy5yZXNvbHV0aW9uLnRvTG93ZXJDYXNlKCkuc3BsaXQoJ3gnKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaWRlYWxXaWR0aCA9IE51bWJlcih3aWR0aEFuZEhlaWdodFswXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkZWFsSGVpZ2h0ID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZWFsOiBpZGVhbFdpZHRoXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlYWw6IGlkZWFsSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICg8TWVkaWFUcmFja0NvbnN0cmFpbnRzPm15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvKS5mcmFtZVJhdGUgPSB7IGlkZWFsOiBwdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ0FTRSA0OiBkZXZpY2VJZCBvciBzY3JlZW4gc2hhcmluZ1xuICAgICAgICAgICAgdGhpcy5jb25maWd1cmVEZXZpY2VJZE9yU2NyZWVuc2hhcmluZyhteUNvbnN0cmFpbnRzLCBwdWJsaXNoZXJQcm9wZXJ0aWVzLCByZXNvbHZlLCByZWplY3QpO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShteUNvbnN0cmFpbnRzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0YXJ0V3Mob25Db25uZWN0U3VjY2VzOiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgIGhlYXJ0YmVhdDogNTAwMCxcbiAgICAgICAgICAgIHdzOiB7XG4gICAgICAgICAgICAgICAgdXJpOiB0aGlzLndzVXJpICsgJz9zZXNzaW9uSWQ9JyArIHRoaXMuc2Vzc2lvbi5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgb25jb25uZWN0ZWQ6IG9uQ29ubmVjdFN1Y2NlcyxcbiAgICAgICAgICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgb25yZWNvbm5lY3Rpbmc6IHRoaXMucmVjb25uZWN0aW5nQ2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbnJlY29ubmVjdGVkOiB0aGlzLnJlY29ubmVjdGVkQ2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBpc21hc3Rlcm5vZGVjcmFzaGVkOiB0aGlzLmlzTWFzdGVyTm9kZUNyYXNoZWQuYmluZCh0aGlzKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJwYzoge1xuICAgICAgICAgICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxMDAwMCxcbiAgICAgICAgICAgICAgICBoZWFydGJlYXRSZXF1ZXN0VGltZW91dDogNTAwMCxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudEpvaW5lZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRKb2luZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHVibGlzaGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudFB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRVbnB1Ymxpc2hlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRVbnB1Ymxpc2hlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRMZWZ0OiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudExlZnQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50RXZpY3RlZDogdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRFdmljdGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICByZWNvcmRpbmdTdGFydGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdGFydGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICByZWNvcmRpbmdTdG9wcGVkOiB0aGlzLnNlc3Npb24ub25SZWNvcmRpbmdTdG9wcGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBzZW5kTWVzc2FnZTogdGhpcy5zZXNzaW9uLm9uTmV3TWVzc2FnZS5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgc3RyZWFtUHJvcGVydHlDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWQ6IHRoaXMuc2Vzc2lvbi5vbkNvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIG5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkOiB0aGlzLnNlc3Npb24ub25OZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZENoYW5nZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIGZpbHRlckV2ZW50RGlzcGF0Y2hlZDogdGhpcy5zZXNzaW9uLm9uRmlsdGVyRXZlbnREaXNwYXRjaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBpY2VDYW5kaWRhdGU6IHRoaXMuc2Vzc2lvbi5yZWN2SWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBtZWRpYUVycm9yOiB0aGlzLnNlc3Npb24ub25NZWRpYUVycm9yLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBtYXN0ZXJOb2RlQ3Jhc2hlZE5vdGlmaWNhdGlvbjogdGhpcy5vbk1hc3Rlck5vZGVDcmFzaGVkTm90aWZpY2F0aW9uLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgZm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyOiB0aGlzLnNlc3Npb24ub25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXIuYmluZCh0aGlzLnNlc3Npb24pXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudCA9IG5ldyBScGNCdWlsZGVyLmNsaWVudHMuSnNvblJwY0NsaWVudChjb25maWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk1hc3Rlck5vZGVDcmFzaGVkTm90aWZpY2F0aW9uKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01hc3RlciBOb2RlIGhhcyBjcmFzaGVkJyk7XG4gICAgICAgIHRoaXMubWFzdGVyTm9kZUhhc0NyYXNoZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbignbm9kZUNyYXNoZWQnKTtcbiAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LmNsb3NlKDQxMDMsICdNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRXc1JlYWR5U3RhdGUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNvblJwY0NsaWVudC5nZXRSZWFkeVN0YXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNsb3NlV3MoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAyLCAnQ29ubmVjdGlvbiBjbG9zZWQgYnkgY2xpZW50Jyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRSZXF1ZXN0KG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IGFueSwgY2FsbGJhY2s/KTogdm9pZCB7XG4gICAgICAgIGlmIChwYXJhbXMgJiYgcGFyYW1zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gcGFyYW1zO1xuICAgICAgICAgICAgcGFyYW1zID0ge307XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50Py5zZW5kKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLndzVXJpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWNyZXQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZWNvcmRlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb3JkZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdlbmVyYXRlQXVkaW9EZXZpY2VFcnJvcihlcnJvciwgY29uc3RyYWludHM6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMpOiBPcGVuVmlkdUVycm9yIHtcbiAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgIC8vIFNhZmFyaSBPdmVyQ29uc3RyYWluZWRFcnJvciBoYXMgYXMgbmFtZSBwcm9wZXJ0eSAnRXJyb3InIGluc3RlYWQgb2YgJ092ZXJDb25zdHJhaW5lZEVycm9yJ1xuICAgICAgICAgICAgZXJyb3IubmFtZSA9IGVycm9yLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG4gICAgICAgIHN3aXRjaCAoZXJyb3IubmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlICdub3Rmb3VuZGVycm9yJzpcbiAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIGNhc2UgJ25vdGFsbG93ZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpO1xuICAgICAgICAgICAgY2FzZSAnb3ZlcmNvbnN0cmFpbmVkZXJyb3InOlxuICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAgICAgICAgICAgICAgIFwiQXVkaW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgICBjYXNlICdub3RyZWFkYWJsZWVycm9yJzpcbiAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUxSRUFEWV9JTl9VU0U7XG4gICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX0dFTkVSSUNfRVJST1IsIGVycm9yLnRvU3RyaW5nKCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzOiBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzLCBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIHN0cmVhbT86IFN0cmVhbSkge1xuICAgICAgICBpZiAoISFteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2spIHtcbiAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKG15Q29uc3RyYWludHMudmlkZW9UcmFjayk7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoISFteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzLnZpZGVvKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5sYXN0VmlkZW9UcmFja0NvbnN0cmFpbnRzID0gbXlDb25zdHJhaW50cy5jb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IG15Q29uc3RyYWludHMudmlkZW9UcmFjay5nZXRDb25zdHJhaW50cygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoISFteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKG15Q29uc3RyYWludHMuYXVkaW9UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lZGlhU3RyZWFtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY29uZmlndXJlRGV2aWNlSWRPclNjcmVlbnNoYXJpbmcoXG4gICAgICAgIG15Q29uc3RyYWludHM6IEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHMsXG4gICAgICAgIHB1Ymxpc2hlclByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMsXG4gICAgICAgIHJlc29sdmUsXG4gICAgICAgIHJlamVjdFxuICAgICkge1xuICAgICAgICBjb25zdCBhdWRpb1NvdXJjZSA9IHB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2U7XG4gICAgICAgIGNvbnN0IHZpZGVvU291cmNlID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcbiAgICAgICAgaWYgKHR5cGVvZiBhdWRpb1NvdXJjZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLmF1ZGlvID0geyBkZXZpY2VJZDogeyBleGFjdDogYXVkaW9Tb3VyY2UgfSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1NjcmVlblNoYXJlKHZpZGVvU291cmNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VmlkZW9Tb3VyY2UobXlDb25zdHJhaW50cywgdmlkZW9Tb3VyY2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTY3JlZW4gc2hhcmluZ1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNoZWNrU2NyZWVuU2hhcmluZ0NhcGFiaWxpdGllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVELFxuICAgICAgICAgICAgICAgICAgICAgICAgJ1lvdSBjYW4gb25seSBzY3JlZW4gc2hhcmUgaW4gZGVza3RvcCBDaHJvbWUsIEZpcmVmb3gsIE9wZXJhLCBTYWZhcmkgKD49MTMuMCksIEVkZ2UgKD49IDgwKSBvciBFbGVjdHJvbi4gRGV0ZWN0ZWQgY2xpZW50OiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXROYW1lKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uZ2V0VmVyc2lvbigpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5pc0VsZWN0cm9uKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9ICdzY3JlZW46JztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlU3RyaW5nOiBzdHJpbmcgPSB2aWRlb1NvdXJjZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVsZWN0cm9uU2NyZWVuSWQgPSB2aWRlb1NvdXJjZVN0cmluZy5zdWJzdHIodmlkZW9Tb3VyY2VTdHJpbmcuaW5kZXhPZihwcmVmaXgpICsgcHJlZml4Lmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAoPGFueT5teUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbykgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNocm9tZU1lZGlhU291cmNlSWQ6IGVsZWN0cm9uU2NyZWVuSWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobXlDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgISF0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICEocGxhdGZvcm0uaXNGaXJlZm94QnJvd3NlcigpIHx8IHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ11cbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEN1c3RvbSBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gZm9yIENocm9tZSAoYW5kIE9wZXJhKSBhbmQgbm8gc3VwcG9ydCBmb3IgTWVkaWFEZXZpY2VzLmdldERpc3BsYXlNZWRpYSgpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5TaGFyaW5nLmdldFNjcmVlbkNvbnN0cmFpbnRzKChlcnJvciwgc2NyZWVuQ29uc3RyYWludHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISFlcnJvciB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCEhc2NyZWVuQ29uc3RyYWludHMubWFuZGF0b3J5ICYmIHNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZSA9PT0gJ3NjcmVlbicpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAncGVybWlzc2lvbi1kZW5pZWQnIHx8IGVycm9yID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1lvdSBtdXN0IGFsbG93IGFjY2VzcyB0byBvbmUgd2luZG93IG9mIHlvdXIgZGVza3RvcCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbklkID0gdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uIS5zcGxpdCgnLycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wb3AoKSEhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50cmltKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uSWQsIChzdGF0dXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ2luc3RhbGxlZC1kaXNhYmxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJpbmc+dGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbyA9IHNjcmVlbkNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobXlDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXREaXNwbGF5TWVkaWEgc3VwcG9ydCAoQ2hyb21lID49IDcyLCBGaXJlZm94ID49IDY2LCBTYWZhcmkgPj0gMTMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlZmF1bHQgc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGZvciBDaHJvbWUvT3BlcmEsIG9yIGlzIEZpcmVmb3ggPCA2NlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXJlZm94U3RyaW5nID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveEJyb3dzZXIoKSB8fCBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5TaGFyaW5nQXV0by5nZXRTY3JlZW5JZChmaXJlZm94U3RyaW5nLCAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5Db25zdHJhaW50cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdub3QtaW5zdGFsbGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25VcmwgPSAhIXRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdodHRwczovL2Nocm9tZS5nb29nbGUuY29tL3dlYnN0b3JlL2RldGFpbC9vcGVudmlkdS1zY3JlZW5zaGFyaW5nL2xmY2dmZXBhZm5vYmRsb2VjY2huZmFjbGliZW5qb2xkJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVELCBleHRlbnNpb25VcmwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdZb3UgbXVzdCBlbmFibGUgdGhlIHNjcmVlbiBleHRlbnNpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlcnJvciA9PT0gJ3Blcm1pc3Npb24tZGVuaWVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5HRU5FUklDX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1Vua25vd24gZXJyb3Igd2hlbiBhY2Nlc3Npbmcgc2NyZWVuIHNoYXJlJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSBzY3JlZW5Db25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShteUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHNldFZpZGVvU291cmNlKG15Q29uc3RyYWludHM6IEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHMsIHZpZGVvU291cmNlOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCFteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbykge1xuICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSB7fTtcbiAgICAgICAgfVxuICAgICAgICAoPE1lZGlhVHJhY2tDb25zdHJhaW50cz5teUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbylbJ2RldmljZUlkJ10gPSB7IGV4YWN0OiB2aWRlb1NvdXJjZSB9O1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBkaXNjb25uZWN0Q2FsbGJhY2soKTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdXZWJzb2NrZXQgY29ubmVjdGlvbiBsb3N0Jyk7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbignbmV0d29ya0Rpc2Nvbm5lY3QnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlY29ubmVjdGluZ0NhbGxiYWNrKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCAocmVjb25uZWN0aW5nKScpO1xuICAgICAgICBpZiAoIXRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdyZWNvbm5lY3RpbmcnLCBbXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlY29ubmVjdFdlYnNvY2tldFRocm91Z2hScGNDb25uZWN0TWV0aG9kKHJwY1Nlc3Npb25JZCkge1xuICAgICAgICAvLyBUaGlzIFJQQyBtZXRob2QgYWxsb3dzIGNoZWNraW5nOlxuICAgICAgICAvLyBTaW5nbGUgTWFzdGVyOiBpZiBzdWNjZXNzLCBjb25uZWN0aW9uIHJlY292ZXJlZFxuICAgICAgICAvLyAgICAgICAgICAgICAgICBpZiBlcnJvciwgbm8gTWFzdGVyIE5vZGUgY3Jhc2hlZCBhbmQgbGlmZSB3aWxsIGJlIC0xLiBvbkxvc3RDb25uZWN0aW9uIHdpdGggcmVhc29uIG5ldHdvcmtEaXNjb25uZWN0IHdpbGwgYmUgdHJpZ2dlcmVkXG4gICAgICAgIC8vIE11bHRpIE1hc3RlcjogaWYgc3VjY2VzcywgY29ubmVjdGlvbiByZWNvdmVyZWRcbiAgICAgICAgLy8gICAgICAgICAgICAgICBpZiBlcnJvciBhbmQgTWFzdGVyIE5vZGUgY3Jhc2hlZCBub3RpZmljYXRpb24gd2FzIGFscmVhZHkgcmVjZWl2ZWQsIG5vdGhpbmcgbXVzdCBiZSBkb25lXG4gICAgICAgIC8vICAgICAgICAgICAgICAgaWYgZXJyb3IgYW5kIE1hc3RlciBOb2RlIE5PVCBjcmFzaGVkLCBzZXNzaW9uU3RhdHVzIG1ldGhvZCBtdXN0IGJlIHNlbnQ6XG4gICAgICAgIC8vICAgICAgICAgICAgICAgICBpZiBsaWZlIGlzIGVxdWFsLCBuZXR3b3JrRGlzY29ubmVjdFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgaWYgbGlmZSBpcyBncmVhdGVyLCBub2RlQ3Jhc2hlZFxuICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KCdjb25uZWN0JywgeyBzZXNzaW9uSWQ6IHJwY1Nlc3Npb25JZCwgcmVjb25uZWN0OiB0cnVlIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNNYXN0ZXJOb2RlQ3Jhc2hlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZCEnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vdGlmeUxvc3RDb25uZWN0aW9uID0gKHJlYXNvbiwgZXJyb3JNc2cpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKGVycm9yTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vbkxvc3RDb25uZWN0aW9uKHJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQuY2xvc2UoNDEwMSwgJ1JlY29ubmVjdGlvbiBmYXVsdDogJyArIGVycm9yTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBycGNTZXNzaW9uU3RhdHVzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlmZSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTaW5nbGUgTWFzdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZ5TG9zdENvbm5lY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICduZXR3b3JrRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXUyBzdWNjZXNzZnVsbHkgcmVjb25uZWN0ZWQgYnV0IHRoZSB1c2VyIHdhcyBhbHJlYWR5IGV2aWN0ZWQgZHVlIHRvIHRpbWVvdXQnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTXVsdGkgTWFzdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBSUEMgbWV0aG9kIGlzIG9ubHkgcmVxdWlyZWQgdG8gZmluZCBvdXQgdGhlIHJlYXNvbiBvZiB0aGUgZGlzY29ubmVjdGlvbjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGV0aGVyIHRoZSBjbGllbnQgbG9zdCBpdHMgbmV0d29yayBjb25uZWN0aW9uIG9yIGEgTWFzdGVyIE5vZGUgY3Jhc2hlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VuZFJlcXVlc3QoJ3Nlc3Npb25TdGF0dXMnLCB7IHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBjaGVja2luZyBzZXNzaW9uIHN0YXR1cycsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpZmUgPT09IHJlc3BvbnNlLmxpZmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlmZSBzdG9yZWQgaW4gdGhlIGNsaWVudCBtYXRjaGVzIHRoZSBsaWZlIHN0b3JlZCBpbiB0aGUgc2VydmVyLCBpdCBtZWFucyB0aGF0IHRoZSBjbGllbnQgbG9zdCBpdHMgbmV0d29yayBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZ5TG9zdENvbm5lY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICduZXR3b3JrRGlzY29ubmVjdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXUyBzdWNjZXNzZnVsbHkgcmVjb25uZWN0ZWQgYnV0IHRoZSB1c2VyIHdhcyBhbHJlYWR5IGV2aWN0ZWQgZHVlIHRvIHRpbWVvdXQnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpZmUgc3RvcmVkIGluIHRoZSBjbGllbnQgaXMgYmVsb3cgdGhlIGxpZmUgc3RvcmVkIGluIHRoZSBzZXJ2ZXIsIGl0IG1lYW5zIHRoYXQgdGhlIE1hc3RlciBOb2RlIGhhcyBjcmFzaGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZ5TG9zdENvbm5lY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdub2RlQ3Jhc2hlZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXUyBzdWNjZXNzZnVsbHkgcmVjb25uZWN0ZWQgdG8gT3BlblZpZHUgU2VydmVyIGJ1dCB5b3VyIE1hc3RlciBOb2RlIGNyYXNoZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDAwNyAmJiBlcnJvci5tZXNzYWdlID09PSAncmVjb25uZWN0aW9uIGVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gS3VyZW50byBlcnJvcjogaW52YWxpZCBSUEMgc2Vzc2lvbklkLiBUaGlzIG1lYW5zIHRoYXQgdGhlIGt1cmVudG8tanNvbnJwYy1zZXJ2ZXIgb2Ygb3BlbnZpZHUtc2VydmVyIHdoZXJlIGt1cmVudG8tanNvbnJwYy1jbGllbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzIHRyeWluZyB0byByZWNvbm5lY3QgZG9lcyBub3Qga25vdyBhYm91dCB0aGlzIHNlc3Npb25JZC4gVGhpcyBjYW4gbWVhbiB0d28gdGhpbmdzOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gMSkgb3BlbnZpZHUtYnJvd3NlciBtYW5hZ2VkIHRvIHJlY29ubmVjdCBhZnRlciBhIHdoaWxlLCBidXQgb3BlbnZpZHUtc2VydmVyIGFscmVhZHkgZXZpY3RlZCB0aGUgdXNlciBmb3Igbm90IHJlY2VpdmluZyBwaW5nLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gMikgb3BlbnZpZHUtc2VydmVyIHByb2Nlc3MgaXMgYSBkaWZmZXJlbnQgb25lIGJlY2F1c2Ugb2YgYSBub2RlIGNyYXNoLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2VuZCBhIFwic2Vzc2lvblN0YXR1c1wiIG1ldGhvZCB0byBjaGVjayB0aGUgcmVhc29uXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIFJQQyBzZXNzaW9uSWQuIENsaWVudCBuZXR3b3JrIGRpc2Nvbm5lY3Rpb24gb3IgTWFzdGVyIE5vZGUgY3Jhc2gnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJwY1Nlc3Npb25TdGF0dXMoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJwY1Nlc3Npb25TdGF0dXMoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LnJlc2V0UGluZygpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vblJlY292ZXJlZENvbm5lY3Rpb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24uY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0V2Vic29ja2V0VGhyb3VnaFJwY0Nvbm5lY3RNZXRob2QodGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1RoZXJlIHdhcyBubyBwcmV2aW91cyBjb25uZWN0aW9uIHdoZW4gcnVubmluZyByZWNvbm5lY3Rpb24gY2FsbGJhY2snKTtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudFxuICAgICAgICAgICAgICAgIGNvbnN0IHNlc3Npb25EaXNjb25uZWN0RXZlbnQgPSBuZXcgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbGVydCgnQ29ubmVjdGlvbiBlcnJvci4gUGxlYXNlIHJlbG9hZCBwYWdlLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc01hc3Rlck5vZGVDcmFzaGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXN0ZXJOb2RlSGFzQ3Jhc2hlZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbiAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc2Vzc2lvbiBpbnN0YW5jZW9mIFNlc3Npb24pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1Nlc3Npb24gaW5zdGFuY2Ugbm90IGZvdW5kJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzU2NyZWVuU2hhcmUodmlkZW9Tb3VyY2U6IHN0cmluZykge1xuICAgICAgICByZXR1cm4gdmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8IHZpZGVvU291cmNlID09PSAnd2luZG93JyB8fCAocGxhdGZvcm0uaXNFbGVjdHJvbigpICYmIHZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKSk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgUHVibGlzaGVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvUHVibGlzaGVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBQdWJsaXNoZXJFdmVudE1hcCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50TWFwL1B1Ymxpc2hlckV2ZW50TWFwJztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcbmltcG9ydCB7IFR5cGVPZlZpZGVvIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9UeXBlT2ZWaWRlbyc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBQYWNrcyBsb2NhbCBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgY2FuIHB1Ymxpc2ggaXQgdG8gYSBzZXNzaW9uLiBJbml0aWFsaXplZCB3aXRoIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZC5cbiAqXG4gKiBTZWUgYXZhaWxhYmxlIGV2ZW50IGxpc3RlbmVycyBhdCBbW1B1Ymxpc2hlckV2ZW50TWFwXV0uXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBQdWJsaXNoZXIgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdFxuICAgICAqL1xuICAgIGFjY2Vzc0FsbG93ZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgeW91IGhhdmUgY2FsbGVkIFtbUHVibGlzaGVyLnN1YnNjcmliZVRvUmVtb3RlXV0gd2l0aCB2YWx1ZSBgdHJ1ZWAgb3IgYGZhbHNlYCAoKmZhbHNlKiBieSBkZWZhdWx0KVxuICAgICAqL1xuICAgIGlzU3Vic2NyaWJlZFRvUmVtb3RlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gdG8gd2hpY2ggdGhlIFB1Ymxpc2hlciBiZWxvbmdzXG4gICAgICovXG4gICAgc2Vzc2lvbjogU2Vzc2lvbjsgLy8gSW5pdGlhbGl6ZWQgYnkgU2Vzc2lvbi5wdWJsaXNoKFB1Ymxpc2hlcilcblxuICAgIHByaXZhdGUgYWNjZXNzRGVuaWVkID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnRWw6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBvcGVudmlkdTogT3BlblZpZHUpIHtcbiAgICAgICAgc3VwZXIoXG4gICAgICAgICAgICBuZXcgU3RyZWFtKCEhb3BlbnZpZHUuc2Vzc2lvbiA/IG9wZW52aWR1LnNlc3Npb24gOiBuZXcgU2Vzc2lvbihvcGVudmlkdSksIHtcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHt9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHRhcmdFbFxuICAgICAgICApO1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICAgICAgdGhpcy5vcGVudmlkdSA9IG9wZW52aWR1O1xuXG4gICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uKCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgKHJlYXNvbjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gZmFsc2U7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgdGhpcy5zdHJlYW0sIHJlYXNvbik7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2ggb3IgdW5wdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIGBlbmFibGVkYCB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVuYWJsZWQgYHRydWVgIHRvIHB1Ymxpc2ggdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnB1Ymxpc2ggaXRcbiAgICAgKi9cbiAgICBwdWJsaXNoQXVkaW8oZW5hYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IGVuYWJsZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGFmZmVjdGVkTWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtID0gdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKClcbiAgICAgICAgICAgICAgICA/IHRoaXMuc3RyZWFtLmxvY2FsTWVkaWFTdHJlYW1XaGVuU3Vic2NyaWJlZFRvUmVtb3RlIVxuICAgICAgICAgICAgICAgIDogdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIGFmZmVjdGVkTWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24gJiYgISF0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAnYXVkaW9BY3RpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IGVuYWJsZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICByZWFzb246ICdwdWJsaXNoQXVkaW8nXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCBlbmFibGVkLCAhZW5hYmxlZCwgJ3B1Ymxpc2hBdWRpbycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAnYXVkaW9BY3RpdmUnLCBlbmFibGVkLCAhZW5hYmxlZCwgJ3B1Ymxpc2hBdWRpbycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnNlbmRWaWRlb0RhdGEodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgPSBlbmFibGVkO1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oXCInUHVibGlzaGVyJyBoYXMgXCIgKyAoZW5hYmxlZCA/ICdwdWJsaXNoZWQnIDogJ3VucHVibGlzaGVkJykgKyAnIGl0cyBhdWRpbyBzdHJlYW0nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2ggb3IgdW5wdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIGBlbmFibGVkYCB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwidmlkZW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVuYWJsZWQgYHRydWVgIHRvIHB1Ymxpc2ggdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnB1Ymxpc2ggaXRcbiAgICAgKiBAcGFyYW0gcmVzb3VyY2VcbiAgICAgKiAtIElmIHBhcmFtZXRlciAqKmBlbmFibGVkYCoqIGlzIGBmYWxzZWAsIHRoaXMgb3B0aW9uYWwgcGFyYW1ldGVyIGlzIG9mIHR5cGUgYm9vbGVhbi4gSXQgY2FuIGJlIHNldCB0byBgdHJ1ZWAgdG8gZm9yY2libHkgZnJlZSB0aGUgaGFyZHdhcmUgcmVzb3VyY2UgYXNzb2NpYXRlZCB0byB0aGUgdmlkZW8gdHJhY2ssIG9yIGNhbiBiZSBzZXQgdG8gYGZhbHNlYCB0byBrZWVwIHRoZSBhY2Nlc3MgdG8gdGhlIGhhcmR3YXJlIHJlc291cmNlLlxuICAgICAqIE5vdCBmcmVlaW5nIHRoZSByZXNvdXJjZSBtYWtlcyB0aGUgb3BlcmF0aW9uIG11Y2ggbW9yZSBlZmZpY2llbnQsIGJ1dCBkZXBlbmRpbmcgb24gdGhlIHBsYXRmb3JtIHR3byBzaWRlLWVmZmVjdHMgY2FuIGJlIGludHJvZHVjZWQ6IHRoZSB2aWRlbyBkZXZpY2UgbWF5IG5vdCBiZSBhY2Nlc3NpYmxlIGJ5IG90aGVyIGFwcGxpY2F0aW9ucyBhbmQgdGhlIGFjY2VzcyBsaWdodCBvZlxuICAgICAqIHdlYmNhbXMgbWF5IHJlbWFpbiBvbi4gVGhpcyBpcyBwbGF0Zm9ybS1kZXBlbmRlbnQ6IHNvbWUgYnJvd3NlcnMgd2lsbCBub3QgcHJlc2VudCB0aGUgc2lkZS1lZmZlY3RzIGV2ZW4gd2hlbiBub3QgZnJlZWluZyB0aGUgcmVzb3VyY2UuPC9saT5cbiAgICAgKiAtIElmIHBhcmFtZXRlciAqKmBlbmFibGVkYCoqIGlzIGB0cnVlYCwgdGhpcyBvcHRpb25hbCBwYXJhbWV0ZXIgaXMgb2YgdHlwZSBbTWVkaWFTdHJlYW1UcmFja10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZG9jcy9XZWIvQVBJL01lZGlhU3RyZWFtVHJhY2spLiBJdCBjYW4gYmUgc2V0IHRvIGZvcmNlIHRoZSByZXN0b3JhdGlvbiBvZiB0aGUgdmlkZW8gdHJhY2sgd2l0aCBhIGN1c3RvbSB0cmFjay4gVGhpcyBtYXkgYmVcbiAgICAgKiB1c2VmdWwgaWYgdGhlIFB1Ymxpc2hlciB3YXMgdW5wdWJsaXNoZWQgZnJlZWluZyB0aGUgaGFyZHdhcmUgcmVzb3VyY2UsIGFuZCBvcGVudmlkdS1icm93c2VyIGlzIG5vdCBhYmxlIHRvIHN1Y2Nlc3NmdWxseSByZS1jcmVhdGUgdGhlIHZpZGVvIHRyYWNrIGFzIGl0IHdhcyBiZWZvcmUgdW5wdWJsaXNoaW5nLiBJbiB0aGlzIHdheSBwcmV2aW91cyB0cmFjayBzZXR0aW5ncyB3aWxsIGJlIGlnbm9yZWQgYW5kIHRoaXMgTWVkaWFTdHJlYW1UcmFja1xuICAgICAqIHdpbGwgYmUgdXNlZCBpbnN0ZWFkLlxuICAgICAqL1xuICAgIHB1Ymxpc2hWaWRlbzxUIGV4dGVuZHMgYm9vbGVhbj4oZW5hYmxlZDogVCwgcmVzb3VyY2U/OiBUIGV4dGVuZHMgZmFsc2UgPyBib29sZWFuIDogTWVkaWFTdHJlYW1UcmFjayk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlICE9PSBlbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYWZmZWN0ZWRNZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0gPSB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKVxuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuc3RyZWFtLmxvY2FsTWVkaWFTdHJlYW1XaGVuU3Vic2NyaWJlZFRvUmVtb3RlIVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgbGV0IG11c3RSZXN0YXJ0TWVkaWFTdHJlYW0gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBhZmZlY3RlZE1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZW5hYmxlZCAmJiByZXNvdXJjZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVuYWJsZWQgJiYgdHJhY2sucmVhZHlTdGF0ZSA9PT0gJ2VuZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzb3VyY2Ugd2FzIGZyZWVkXG4gICAgICAgICAgICAgICAgICAgICAgICBtdXN0UmVzdGFydE1lZGlhU3RyZWFtID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgYSBWaXJ0dWFsIEJhY2tncm91bmQgZmlsdGVyIGFwcGxpZWQgdGhhdCBtdXN0IGJlIHJlbW92ZWQgaW4gY2FzZSB0aGUgaGFyZHdhcmUgbXVzdCBiZSBmcmVlZFxuICAgICAgICAgICAgICAgIGlmICghZW5hYmxlZCAmJiByZXNvdXJjZSA9PT0gdHJ1ZSAmJiAhIXRoaXMuc3RyZWFtLmZpbHRlciAmJiB0aGlzLnN0cmVhbS5maWx0ZXIudHlwZS5zdGFydHNXaXRoKCdWQjonKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5sYXN0VkJGaWx0ZXIgPSB0aGlzLnN0cmVhbS5maWx0ZXI7IC8vIFNhdmUgdGhlIGZpbHRlciB0byBiZSByZS1hcHBsaWVkIGluIGNhc2Ugb2YgdW5tdXRlXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc3RyZWFtLnJlbW92ZUZpbHRlckF1eCh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAobXVzdFJlc3RhcnRNZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWaWRlb1RyYWNrID0gYWZmZWN0ZWRNZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgICAgICAgICAgICAgICAgICBhZmZlY3RlZE1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKG9sZFZpZGVvVHJhY2spO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcGxhY2VWaWRlb1RyYWNrID0gYXN5bmMgKHRyOiBNZWRpYVN0cmVhbVRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZmZlY3RlZE1lZGlhU3RyZWFtLmFkZFRyYWNrKHRyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXBsYWNlVHJhY2tJblJ0Y1J0cFNlbmRlcih0cik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbS5sYXN0VkJGaWx0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG9wdGlvbnMgPSB0aGlzLnN0cmVhbS5sYXN0VkJGaWx0ZXIhLm9wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RFeGVjTWV0aG9kID0gdGhpcy5zdHJlYW0ubGFzdFZCRmlsdGVyIS5sYXN0RXhlY01ldGhvZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhbGFzdEV4ZWNNZXRob2QgJiYgbGFzdEV4ZWNNZXRob2QubWV0aG9kID09PSAndXBkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMsIGxhc3RFeGVjTWV0aG9kLnBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zdHJlYW0uYXBwbHlGaWx0ZXIodGhpcy5zdHJlYW0ubGFzdFZCRmlsdGVyIS50eXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtLmxhc3RWQkZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXNvdXJjZSAmJiByZXNvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlcGxhY2VWaWRlb1RyYWNrKHJlc291cmNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRoaXMuc3RyZWFtLmxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXBsYWNlVmlkZW9UcmFjayhtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24gJiYgISF0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JZDogdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICd2aWRlb0FjdGl2ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IGVuYWJsZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiAncHVibGlzaFZpZGVvJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmlkZW9BY3RpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIWVuYWJsZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5zdHJlYW0sICd2aWRlb0FjdGl2ZScsIGVuYWJsZWQsICFlbmFibGVkLCAncHVibGlzaFZpZGVvJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5zZW5kVmlkZW9EYXRhKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFwiJ1B1Ymxpc2hlcicgaGFzIFwiICsgKGVuYWJsZWQgPyAncHVibGlzaGVkJyA6ICd1bnB1Ymxpc2hlZCcpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCB0aGlzIG1ldGhvZCBiZWZvcmUgW1tTZXNzaW9uLnB1Ymxpc2hdXSBpZiB5b3UgcHJlZmVyIHRvIHN1YnNjcmliZSB0byB5b3VyIFB1Ymxpc2hlcidzIHJlbW90ZSBzdHJlYW0gaW5zdGVhZCBvZiB1c2luZyB0aGUgbG9jYWwgc3RyZWFtLCBhcyBhbnkgb3RoZXIgdXNlciB3b3VsZCBkby5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb1JlbW90ZSh2YWx1ZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiB0cnVlO1xuICAgICAgICB0aGlzLmlzU3Vic2NyaWJlZFRvUmVtb3RlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuc3RyZWFtLnN1YnNjcmliZVRvTXlSZW1vdGUodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb248SyBleHRlbmRzIGtleW9mIFB1Ymxpc2hlckV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IFB1Ymxpc2hlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uKDxhbnk+dHlwZSwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1DcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZTxLIGV4dGVuZHMga2V5b2YgUHVibGlzaGVyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogUHVibGlzaGVyRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub25jZSg8YW55PnR5cGUsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQ3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbmNlKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmY8SyBleHRlbmRzIGtleW9mIFB1Ymxpc2hlckV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyPzogKGV2ZW50OiBQdWJsaXNoZXJFdmVudE1hcFtLXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICBzdXBlci5vZmYoPGFueT50eXBlLCBoYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVwbGFjZXMgdGhlIGN1cnJlbnQgdmlkZW8gb3IgYXVkaW8gdHJhY2sgd2l0aCBhIGRpZmZlcmVudCBvbmUuIFRoaXMgYWxsb3dzIHlvdSB0byByZXBsYWNlIGFuIG9uZ29pbmcgdHJhY2sgd2l0aCBhIGRpZmZlcmVudCBvbmVcbiAgICAgKiB3aXRob3V0IGhhdmluZyB0byByZW5lZ290aWF0ZSB0aGUgd2hvbGUgV2ViUlRDIGNvbm5lY3Rpb24gKHRoYXQgaXMsIGluaXRpYWxpemluZyBhIG5ldyBQdWJsaXNoZXIsIHVucHVibGlzaGluZyB0aGUgcHJldmlvdXMgb25lXG4gICAgICogYW5kIHB1Ymxpc2hpbmcgdGhlIG5ldyBvbmUpLlxuICAgICAqXG4gICAgICogWW91IGNhbiBnZXQgdGhpcyBuZXcgTWVkaWFTdHJlYW1UcmFjayBieSB1c2luZyB0aGUgbmF0aXZlIFdlYiBBUEkgb3Igc2ltcGx5IHdpdGggW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXSBtZXRob2QuXG4gICAgICpcbiAgICAgKiAqKldBUk5JTkc6IHRoaXMgbWV0aG9kIGhhcyBiZWVuIHByb3ZlbiB0byB3b3JrIGluIHRoZSBtYWpvcml0eSBvZiBjYXNlcywgYnV0IHRoZXJlIG1heSBiZSBzb21lIGNvbWJpbmF0aW9ucyBvZiBwdWJsaXNoZWQvcmVwbGFjZWQgdHJhY2tzIHRoYXQgbWF5IGJlIGluY29tcGF0aWJsZVxuICAgICAqIGJldHdlZW4gdGhlbSBhbmQgYnJlYWsgdGhlIGNvbm5lY3Rpb24gaW4gT3BlblZpZHUgU2VydmVyLiBBIGNvbXBsZXRlIHJlbmVnb3RpYXRpb24gbWF5IGJlIHRoZSBvbmx5IHNvbHV0aW9uIGluIHRoaXMgY2FzZS5cbiAgICAgKiBWaXNpdCBbUlRDUnRwU2VuZGVyLnJlcGxhY2VUcmFja10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JUQ1J0cFNlbmRlci9yZXBsYWNlVHJhY2spIGRvY3VtZW50YXRpb24gZm9yIGZ1cnRoZXIgZGV0YWlscy4qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHRyYWNrIFRoZSBbTWVkaWFTdHJlYW1UcmFja10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhU3RyZWFtVHJhY2spIG9iamVjdCB0byByZXBsYWNlIHRoZSBjdXJyZW50IG9uZS5cbiAgICAgKiBJZiBpdCBpcyBhbiBhdWRpbyB0cmFjaywgdGhlIGN1cnJlbnQgYXVkaW8gdHJhY2sgd2lsbCBiZSB0aGUgcmVwbGFjZWQgb25lLiBJZiBpdCBpcyBhIHZpZGVvIHRyYWNrLCB0aGUgY3VycmVudCB2aWRlbyB0cmFjayB3aWxsIGJlIHRoZSByZXBsYWNlZCBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRyYWNrIHdhcyBzdWNjZXNzZnVsbHkgcmVwbGFjZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICBhc3luYyByZXBsYWNlVHJhY2sodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVRyYWNrQXV4KHRyYWNrLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgY29uc3RyYWludHM6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7fTtcbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50c0F1eDogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgY29uc3QgdGltZUZvckRpYWxvZ0V2ZW50ID0gMjAwMDtcbiAgICAgICAgICAgIGxldCBzdGFydFRpbWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9yQ2FsbGJhY2sgPSAob3BlblZpZHVFcnJvcjogT3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYFB1Ymxpc2hlciBpbml0aWFsaXphdGlvbiBmYWlsZWQuICR7b3BlblZpZHVFcnJvci5uYW1lfTogJHtvcGVuVmlkdUVycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvIGFuZCBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlb1xuICAgICAgICAgICAgICAgIGlmICghIW1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlICE9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogISF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIW1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlICE9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogISF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gU2V0IENvbnRlbnQgSGludCBvbiBhbGwgTWVkaWFTdHJlYW1UcmFja3NcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmFjay5jb250ZW50SGludD8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250ZW50SGludCBmb3IgYXVkaW86IFwiXCIsIFwic3BlZWNoXCIsIFwic3BlZWNoLXJlY29nbml0aW9uXCIsIFwibXVzaWNcIi5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby9tc3QtY29udGVudC1oaW50LyNhdWRpby1jb250ZW50LWhpbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5jb250ZW50SGludCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYEF1ZGlvIHRyYWNrIENvbnRlbnQgSGludCBzZXQ6ICcke3RyYWNrLmNvbnRlbnRIaW50fSdgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmFjay5jb250ZW50SGludD8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250ZW50SGludCBmb3IgdmlkZW86IFwiXCIsIFwibW90aW9uXCIsIFwiZGV0YWlsXCIsIFwidGV4dFwiLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93M2MuZ2l0aHViLmlvL21zdC1jb250ZW50LWhpbnQvI3ZpZGVvLWNvbnRlbnQtaGludHNcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGhpcy5zdHJlYW0udHlwZU9mVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFR5cGVPZlZpZGVvLlNDUkVFTjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suY29udGVudEhpbnQgPSAnZGV0YWlsJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBUeXBlT2ZWaWRlby5DVVNUT006XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdDVVNUT00gdHlwZSB2aWRlbyB0cmFjayB3YXMgcHJvdmlkZWQgd2l0aG91dCBDb250ZW50IEhpbnQhJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLmNvbnRlbnRIaW50ID0gJ21vdGlvbic7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVHlwZU9mVmlkZW8uQ0FNRVJBOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVHlwZU9mVmlkZW8uSVBDQU06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suY29udGVudEhpbnQgPSAnbW90aW9uJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgVmlkZW8gdHJhY2sgQ29udGVudCBIaW50IHNldDogJyR7dHJhY2suY29udGVudEhpbnR9J2ApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9SZWZlcmVuY2UobWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBzdWJzY3JpYmVkIHRvIG91ciByZW1vdGUgd2UgZG9uJ3Qgc3RpbGwgc2V0IHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaW4gdGhlIHZpZGVvIGVsZW1lbnRzIHRvXG4gICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGVhcmx5ICdzdHJlYW1QbGF5aW5nJyBldmVudFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmZpcnN0VmlkZW9FbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSGFzIHZpZGVvIHRyYWNrXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0VmlkZW9EaW1lbnNpb25zKCkudGhlbigoZGltZW5zaW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBkaW1lbnNpb25zLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogZGltZW5zaW9ucy5oZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBpbnRlcnZhbCB0byBsaXN0ZW4gZm9yIHNjcmVlbiByZXNpemUgZXZlbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXR0aW5nczogTWVkaWFUcmFja1NldHRpbmdzID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IHNldHRpbmdzLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBzZXR0aW5ncy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpZHRoQ2hhbmdlZCA9IG5ld1dpZHRoICE9IG51bGwgJiYgbmV3V2lkdGggIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0Q2hhbmdlZCA9IG5ld0hlaWdodCAhPSBudWxsICYmIG5ld0hlaWdodCAhPT0gdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgJiYgKHdpZHRoQ2hhbmdlZCB8fCBoZWlnaHRDaGFuZ2VkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kVmlkZW9EaW1lbnNpb25zQ2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NjcmVlblJlc2l6ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA2NTApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBhdWRpbyB0cmFjayAobm8gdmlkZW9EaW1lbnNpb25zKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgW10pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBnZXRNZWRpYVN1Y2Nlc3MgPSBhc3luYyAobWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtLCBkZWZpbmVkQXVkaW9Db25zdHJhaW50KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpICYmIHRoaXMuc3RyZWFtLmlzU2VuZEF1ZGlvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiBnZXR0aW5nIGRlc2t0b3AgYXMgdXNlciBtZWRpYSBhdWRpbyBjb25zdHJhaW50IG11c3QgYmUgZmFsc2UuIE5vdyB3ZSBjYW4gYXNrIGZvciBpdCBpZiByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LnZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHRpbWVGb3JEaWFsb2dFdmVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvT25seVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayh0aGlzLm9wZW52aWR1LmdlbmVyYXRlQXVkaW9EZXZpY2VFcnJvcihlcnJvciwgY29uc3RyYWludHMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TWVkaWFFcnJvciA9IGFzeW5jIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgZ2V0TWVkaWFFcnJvcjogJHtlcnJvci50b1N0cmluZygpfWApO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBPdmVyQ29uc3RyYWluZWRFcnJvciBoYXMgYXMgbmFtZSBwcm9wZXJ0eSAnRXJyb3InIGluc3RlYWQgb2YgJ092ZXJDb25zdHJhaW5lZEVycm9yJ1xuICAgICAgICAgICAgICAgICAgICBlcnJvci5uYW1lID0gZXJyb3IuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXJyb3IubmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGZvdW5kZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlbzogY29uc3RyYWludHMudmlkZW9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90YWxsb3dlZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRURcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiQXVkaW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJBdWRpbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiVmlkZW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJWaWRlbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdhYm9ydGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90cmVhZGFibGVlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUxSRUFEWV9JTl9VU0U7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5HRU5FUklDX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXlDb25zdHJhaW50cyA9IGF3YWl0IHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcyk7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAoISFteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2sgJiYgISFteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2spIHx8XG4gICAgICAgICAgICAgICAgICAgICghIW15Q29uc3RyYWludHMuYXVkaW9UcmFjayAmJiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzPy52aWRlbyA9PT0gZmFsc2UpIHx8XG4gICAgICAgICAgICAgICAgICAgICghIW15Q29uc3RyYWludHMudmlkZW9UcmFjayAmJiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzPy5hdWRpbyA9PT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gY2FsbCBnZXRVc2VyTWVkaWEgYXQgYWxsLiBNZWRpYVN0cmVhbVRyYWNrcyBhbHJlYWR5IHByb3ZpZGVkXG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayh0aGlzLm9wZW52aWR1LmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBuZXcgTWVkaWFTdHJlYW0oKSwgdGhpcy5zdHJlYW0pKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHMuY29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCA9IGNvbnN0cmFpbnRzLmF1ZGlvID09PSB1bmRlZmluZWQgPyB0cnVlIDogY29uc3RyYWludHMuYXVkaW87XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgPyBmYWxzZSA6IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LnZpZGVvID0gY29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHRpbWVGb3JEaWFsb2dFdmVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSAmJiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSAmJiAhcGxhdGZvcm0uaXNFbGVjdHJvbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSh7IHZpZGVvOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5sYXN0VmlkZW9UcmFja0NvbnN0cmFpbnRzID0gY29uc3RyYWludHNBdXgudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5hZGRBbHJlYWR5UHJvdmlkZWRUcmFja3MobXlDb25zdHJhaW50cywgbWVkaWFTdHJlYW0sIHRoaXMuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYXN5bmMgcmVwbGFjZVRyYWNrQXV4KHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHM6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gU2V0IGZpZWxkIFwiZW5hYmxlZFwiIG9mIHRoZSBuZXcgdHJhY2sgdG8gdGhlIHByZXZpb3VzIHZhbHVlXG4gICAgICAgIGNvbnN0IHRyYWNrT3JpZ2luYWxFbmFibGVkVmFsdWU6IGJvb2xlYW4gPSB0cmFjay5lbmFibGVkO1xuICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlO1xuICAgICAgICB9IGVsc2UgaWYgKHRyYWNrLmtpbmQgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGlmIHRoZSBQdWJsaXNoZXIgaGFzIGJlZW4gcHVibGlzaGVkIGlzIG5lY2Vzc2FyeSB0byBjYWxsIG5hdGl2ZSBXZWIgQVBJIFJUQ1J0cFNlbmRlci5yZXBsYWNlVHJhY2tcbiAgICAgICAgICAgICAgICAvLyBJZiBpdCBoYXMgbm90IGJlZW4gcHVibGlzaGVkIHlldCwgcmVwbGFjaW5nIGl0IG9uIHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaXMgZW5vdWdoXG4gICAgICAgICAgICAgICAgdGhpcy5yZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlcGxhY2VUcmFja0luUnRjUnRwU2VuZGVyKHRyYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIG5vdCBwdWJsaXNoZWQuIFNpbXBseSByZXBsYWNlIHRoZSB0cmFjayBvbiB0aGUgbG9jYWwgTWVkaWFTdHJlYW1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHRyYWNrT3JpZ2luYWxFbmFibGVkVmFsdWU7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKlxuICAgICAqIFRvIG9idGFpbiB0aGUgdmlkZW9EaW1lbnNpb25zIHdlIHdhaXQgZm9yIHRoZSB2aWRlbyByZWZlcmVuY2UgdG8gaGF2ZSBlbm91Z2ggbWV0YWRhdGFcbiAgICAgKiBhbmQgdGhlbiB0cnkgdG8gdXNlIE1lZGlhU3RyZWFtVHJhY2suZ2V0U2V0dGluZ3NNZXRob2QoKS4gSWYgbm90IGF2YWlsYWJsZSwgdGhlbiB3ZVxuICAgICAqIHVzZSB0aGUgSFRNTFZpZGVvRWxlbWVudCBwcm9wZXJ0aWVzIHZpZGVvV2lkdGggYW5kIHZpZGVvSGVpZ2h0XG4gICAgICovXG4gICAgZ2V0VmlkZW9EaW1lbnNpb25zKCk6IFByb21pc2U8eyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyBJb25pYyBpT1MgYW5kIFNhZmFyaSBpT1Mgc3VwcG9zZWRseSByZXF1aXJlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGFjdHVhbGx5IGV4aXN0IGluc2lkZSB0aGUgRE9NXG4gICAgICAgICAgICBjb25zdCByZXF1aXJlc0RvbUluc2VydGlvbjogYm9vbGVhbiA9IHBsYXRmb3JtLmlzSW9uaWNJb3MoKSB8fCBwbGF0Zm9ybS5pc0lPU1dpdGhTYWZhcmkoKTtcblxuICAgICAgICAgICAgbGV0IGxvYWRlZG1ldGFkYXRhTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlRGltZW5zaW9ucyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICAgICAgICAgICAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBzZXR0aW5ncy53aWR0aCB8fCB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IHNldHRpbmdzLmhlaWdodCB8fCB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdNZWRpYVN0cmVhbVRyYWNrIGRvZXMgbm90IGhhdmUgZ2V0U2V0dGluZ3MgbWV0aG9kIG9uICcgKyBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpKTtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGggPSB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGxvYWRlZG1ldGFkYXRhTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgbG9hZGVkbWV0YWRhdGFMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlc0RvbUluc2VydGlvbikge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHsgd2lkdGgsIGhlaWdodCB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvUmVmZXJlbmNlLnJlYWR5U3RhdGUgPj0gMSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSB2aWRlbyBhbHJlYWR5IGhhcyBtZXRhZGF0YSBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAvLyBObyBuZWVkIG9mIGxvYWRlZG1ldGFkYXRhIGV2ZW50XG4gICAgICAgICAgICAgICAgcmVzb2x2ZURpbWVuc2lvbnMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHZpZGVvIGRvZXMgbm90IGhhdmUgbWV0YWRhdGEgYXZhaWxhYmxlIHlldFxuICAgICAgICAgICAgICAgIC8vIE11c3QgbGlzdGVuIHRvIGxvYWRlZG1ldGFkYXRhIGV2ZW50XG4gICAgICAgICAgICAgICAgbG9hZGVkbWV0YWRhdGFMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVEaW1lbnNpb25zKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZURpbWVuc2lvbnMoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdsb2FkZWRtZXRhZGF0YScsIGxvYWRlZG1ldGFkYXRhTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlc0RvbUluc2VydGlvbikge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlZXN0YWJsaXNoU3RyZWFtUGxheWluZ0V2ZW50KCkge1xuICAgICAgICBpZiAodGhpcy5lZS5nZXRMaXN0ZW5lcnMoJ3N0cmVhbVBsYXlpbmcnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1JlZmVyZW5jZShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5tdXRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UuYXV0b3BsYXkgPSB0cnVlO1xuICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmNvbnRyb2xzID0gZmFsc2U7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0uaXNJUGhvbmVPcklQYWQoKSAmJlxuICAgICAgICAgICAgICAgIChwbGF0Zm9ybS5pc0Nocm9tZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkpKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UucGxheXNJbmxpbmUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNldE1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVWaWRlb0VsZW1lbnQodGhpcy5maXJzdFZpZGVvRWxlbWVudC50YXJnZXRFbGVtZW50LCA8VmlkZW9JbnNlcnRNb2RlPnRoaXMucHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLnNyY09iamVjdCA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlcGxhY2VUcmFja0luTWVkaWFTdHJlYW0odHJhY2s6IE1lZGlhU3RyZWFtVHJhY2ssIHVwZGF0ZUxhc3RDb25zdHJhaW50czogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0gPSB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKVxuICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZSFcbiAgICAgICAgICAgIDogdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgbGV0IHJlbW92ZWRUcmFjazogTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHJlbW92ZWRUcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICAgICAgICBpZiAodXBkYXRlTGFzdENvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IHRyYWNrLmdldENvbnN0cmFpbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZW1vdmVkVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgICAgICB9XG4gICAgICAgIHJlbW92ZWRUcmFjay5lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHJlbW92ZWRUcmFjay5zdG9wKCk7XG4gICAgICAgIG1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKHJlbW92ZWRUcmFjayk7XG4gICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKHRyYWNrKTtcbiAgICAgICAgY29uc3QgdHJhY2tJbmZvID0ge1xuICAgICAgICAgICAgb2xkTGFiZWw6IHJlbW92ZWRUcmFjaz8ubGFiZWwgfHwgJycsXG4gICAgICAgICAgICBuZXdMYWJlbDogdHJhY2s/LmxhYmVsIHx8ICcnXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0cmFjay5raW5kID09PSAndmlkZW8nICYmIHVwZGF0ZUxhc3RDb25zdHJhaW50cykge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kTmV3VmlkZW9EaW1lbnNpb25zSWZSZXF1aXJlZCh0aGlzLCAndHJhY2tSZXBsYWNlZCcsIDUwLCAzMCk7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRUcmFja0NoYW5nZWRFdmVudCh0aGlzLCAndHJhY2tSZXBsYWNlZCcsIHRyYWNrSW5mby5vbGRMYWJlbCwgdHJhY2tJbmZvLm5ld0xhYmVsLCAndmlkZW9BY3RpdmUnKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnNlbmRWaWRlb0RhdGEodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciwgNSwgdHJ1ZSwgNSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHJhY2sua2luZCA9PT0gJ2F1ZGlvJyAmJiB1cGRhdGVMYXN0Q29uc3RyYWludHMpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFRyYWNrQ2hhbmdlZEV2ZW50KHRoaXMsICd0cmFja1JlcGxhY2VkJywgdHJhY2tJbmZvLm9sZExhYmVsLCB0cmFja0luZm8ubmV3TGFiZWwsICdhdWRpb0FjdGl2ZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1NwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmluaXRIYXJrRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHdhaXRUaW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RpYWxvZ09wZW5lZCcsIFtdKTtcbiAgICAgICAgfSwgd2FpdFRpbWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lOiBudW1iZXIsIHdhaXRUaW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGVybWlzc2lvbkRpYWxvZ1RpbWVvdXQpO1xuICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA+IHdhaXRUaW1lKSB7XG4gICAgICAgICAgICAvLyBQZXJtaXNzaW9uIGRpYWxvZyB3YXMgc2hvd24gYW5kIG5vdyBpcyBjbG9zZWRcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NEaWFsb2dDbG9zZWQnLCBbXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlcGxhY2VUcmFja0luUnRjUnRwU2VuZGVyKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHNlbmRlcnM6IFJUQ1J0cFNlbmRlcltdID0gdGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTZW5kZXJzKCk7XG4gICAgICAgIGxldCBzZW5kZXI6IFJUQ1J0cFNlbmRlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHNlbmRlciA9IHNlbmRlcnMuZmluZCgocykgPT4gISFzLnRyYWNrICYmIHMudHJhY2sua2luZCA9PT0gJ3ZpZGVvJyk7XG4gICAgICAgICAgICBpZiAoIXNlbmRlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZXJlJ3Mgbm8gcmVwbGFjZWFibGUgdHJhY2sgZm9yIHRoYXQga2luZCBvZiBNZWRpYVN0cmVhbVRyYWNrIGluIHRoaXMgUHVibGlzaGVyIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICBzZW5kZXIgPSBzZW5kZXJzLmZpbmQoKHMpID0+ICEhcy50cmFjayAmJiBzLnRyYWNrLmtpbmQgPT09ICdhdWRpbycpO1xuICAgICAgICAgICAgaWYgKCFzZW5kZXIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGVyZSdzIG5vIHJlcGxhY2VhYmxlIHRyYWNrIGZvciB0aGF0IGtpbmQgb2YgTWVkaWFTdHJlYW1UcmFjayBpbiB0aGlzIFB1Ymxpc2hlciBvYmplY3RcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gdHJhY2sga2luZCAnICsgdHJhY2sua2luZCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgKHNlbmRlciBhcyBSVENSdHBTZW5kZXIpLnJlcGxhY2VUcmFjayh0cmFjayk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi9GaWx0ZXInO1xuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0NhcGFiaWxpdGllcyc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTaWduYWxPcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TaWduYWxPcHRpb25zJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1JlbW90ZUNvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Mb2NhbENvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IFNlc3Npb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvU2Vzc2lvbk9wdGlvbnMnO1xuaW1wb3J0IHsgU2Vzc2lvbkV2ZW50TWFwIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnRNYXAvU2Vzc2lvbkV2ZW50TWFwJztcbmltcG9ydCB7IENvbm5lY3Rpb25FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0Nvbm5lY3Rpb25FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50JztcbmltcG9ydCB7IFJlY29yZGluZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUmVjb3JkaW5nRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50JztcbmltcG9ydCB7IFNpZ25hbEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0Nvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBOZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvTmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcbi8qKlxuICogQGhpZGRlblxuICovXG5pbXBvcnQgc2VtdmVyTWFqb3IgPSByZXF1aXJlKCdzZW12ZXIvZnVuY3Rpb25zL21ham9yJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IHNlbXZlck1pbm9yID0gcmVxdWlyZSgnc2VtdmVyL2Z1bmN0aW9ucy9taW5vcicpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5sZXQgcGxhdGZvcm06IFBsYXRmb3JtVXRpbHM7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHZpZGVvIGNhbGwuIEl0IGNhbiBhbHNvIGJlIHNlZW4gYXMgYSB2aWRlb2NvbmZlcmVuY2Ugcm9vbSB3aGVyZSBtdWx0aXBsZSB1c2VycyBjYW4gY29ubmVjdC5cbiAqIFBhcnRpY2lwYW50cyB3aG8gcHVibGlzaCB0aGVpciB2aWRlb3MgdG8gYSBzZXNzaW9uIGNhbiBiZSBzZWVuIGJ5IHRoZSByZXN0IG9mIHVzZXJzIGNvbm5lY3RlZCB0byB0aGF0IHNwZWNpZmljIHNlc3Npb24uXG4gKiBJbml0aWFsaXplZCB3aXRoIFtbT3BlblZpZHUuaW5pdFNlc3Npb25dXSBtZXRob2QuXG4gKlxuICogU2VlIGF2YWlsYWJsZSBldmVudCBsaXN0ZW5lcnMgYXQgW1tTZXNzaW9uRXZlbnRNYXBdXS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb24gZXh0ZW5kcyBFdmVudERpc3BhdGNoZXIge1xuICAgIC8qKlxuICAgICAqIExvY2FsIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24uIFRoaXMgb2JqZWN0IGlzIGRlZmluZWQgb25seSBhZnRlciBbW1Nlc3Npb24uY29ubmVjdF1dIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBleGVjdXRlZCwgYW5kIGNhbiBiZSByZXRyaWV2ZWQgc3Vic2NyaWJpbmcgdG8gYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgU2Vzc2lvblxuICAgICAqL1xuICAgIHNlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ29sbGVjdGlvbiBvZiBhbGwgU3RyZWFtTWFuYWdlcnMgb2YgdGhpcyBTZXNzaW9uIChbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSlcbiAgICAgKi9cbiAgICBzdHJlYW1NYW5hZ2VyczogU3RyZWFtTWFuYWdlcltdID0gW107XG5cbiAgICAvKipcbiAgICAgKiBPYmplY3QgZGVmaW5pbmcgdGhlIG1ldGhvZHMgdGhhdCB0aGUgY2xpZW50IGlzIGFibGUgdG8gY2FsbC4gVGhlc2UgYXJlIGRlZmluZWQgYnkgdGhlIFtbQ29ubmVjdGlvbi5yb2xlXV0uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc29sdmVkXG4gICAgICovXG4gICAgY2FwYWJpbGl0aWVzOiBDYXBhYmlsaXRpZXM7XG5cbiAgICAvLyBUaGlzIG1hcCBpcyBvbmx5IHVzZWQgdG8gYXZvaWQgcmFjZSBjb25kaXRpb24gYmV0d2VlbiAnam9pblJvb20nIHJlc3BvbnNlIGFuZCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcgbm90aWZpY2F0aW9uXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZVN0cmVhbXNDcmVhdGVkOiBNYXA8c3RyaW5nLCBib29sZWFuPiA9IG5ldyBNYXAoKTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdGVDb25uZWN0aW9uczogTWFwPHN0cmluZywgQ29ubmVjdGlvbj4gPSBuZXcgTWFwKCk7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHRva2VuOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByaXZhdGUgdmlkZW9EYXRhSW50ZXJ2YWw6IE5vZGVKUy5UaW1lb3V0O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIHZpZGVvRGF0YVRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wZW52aWR1OiBPcGVuVmlkdSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5vcGVudmlkdSA9IG9wZW52aWR1O1xuICAgIH1cblxuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZyk6IFByb21pc2U8YW55PjtcbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcsIG1ldGFkYXRhOiBhbnkpOiBQcm9taXNlPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0cyB0byB0aGUgc2Vzc2lvbiB1c2luZyBgdG9rZW5gLiBQYXJhbWV0ZXIgYG1ldGFkYXRhYCBhbGxvd3MgeW91IHRvIHBhc3MgZXh0cmEgZGF0YSB0byBzaGFyZSB3aXRoIG90aGVyIHVzZXJzIHdoZW5cbiAgICAgKiB0aGV5IHJlY2VpdmUgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50LiBUaGUgc3RydWN0dXJlIG9mIGBtZXRhZGF0YWAgc3RyaW5nIGlzIHVwIHRvIHlvdSAobWF5YmUgc29tZSBzdGFuZGFyZGl6ZWQgZm9ybWF0XG4gICAgICogYXMgSlNPTiBvciBYTUwgaXMgYSBnb29kIGlkZWEpLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRhZGF0YSBpcyBub3QgY29uc2lkZXJlZCBzZWN1cmUsIGFzIGl0IGlzIGdlbmVyYXRlZCBpbiB0aGUgY2xpZW50IHNpZGUuIFRvIHBhc3Mgc2VjdXJlIGRhdGEsIGFkZCBpdCBhcyBhIHBhcmFtZXRlciBpbiB0aGVcbiAgICAgKiB0b2tlbiBnZW5lcmF0aW9uIG9wZXJhdGlvbiAodGhyb3VnaCB0aGUgQVBJIFJFU1QsIG9wZW52aWR1LWphdmEtY2xpZW50IG9yIG9wZW52aWR1LW5vZGUtY2xpZW50KS5cbiAgICAgKlxuICAgICAqIE9ubHkgYWZ0ZXIgdGhlIHJldHVybmVkIFByb21pc2UgaXMgc3VjY2Vzc2Z1bGx5IHJlc29sdmVkIFtbU2Vzc2lvbi5jb25uZWN0aW9uXV0gb2JqZWN0IHdpbGwgYmUgYXZhaWxhYmxlIGFuZCBwcm9wZXJseSBkZWZpbmVkLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBmaXJzdCBkaXNwYXRjaCBvbmUgb3IgbW9yZSBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50cyB1cG9uIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gb2YgdGhpcyBtZXRob2Q6XG4gICAgICogLSBGaXJzdCBvbmUgZm9yIHlvdXIgb3duIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0LCBzbyB5b3UgY2FuIHJldHJpZXZlIFtbU2Vzc2lvbi5jb25uZWN0aW9uXV0gcHJvcGVydHkuXG4gICAgICogLSBUaGVuIG9uZSBmb3IgZWFjaCByZW1vdGUgQ29ubmVjdGlvbiBwcmV2aW91c2x5IGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiwgaWYgYW55LiBBbnkgb3RoZXIgcmVtb3RlIHVzZXIgY29ubmVjdGluZyB0byB0aGUgU2Vzc2lvbiBhZnRlciB5b3UgaGF2ZVxuICAgICAqIHN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCB3aGVuIHRoZXkgZG8gc28uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQgZm9yIGVhY2ggcmVtb3RlIGFjdGl2ZSBbW1B1Ymxpc2hlcl1dIHRoYXQgd2FzIGFscmVhZHkgc3RyZWFtaW5nXG4gICAgICogd2hlbiBjb25uZWN0aW5nLCBqdXN0IGFmdGVyIGRpc3BhdGNoaW5nIGFsbCByZW1vdGUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0byB3aGljaCB5b3UgbXVzdCBzdWJzY3JpYmUgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24gd2FzIHN1Y2Nlc3NmdWwgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqXG4gICAgICovXG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YT86IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wcm9jZXNzVG9rZW4odG9rZW4pO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5vcGVudmlkdS5jaGVja1N5c3RlbVJlcXVpcmVtZW50cygpKSB7XG4gICAgICAgICAgICAgICAgLy8gRWFybHkgY29uZmlndXJhdGlvbiB0byBkZWFjdGl2YXRlIGF1dG9tYXRpYyBzdWJzY3JpcHRpb24gdG8gc3RyZWFtc1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRJZDogdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIW1ldGFkYXRhID8gdGhpcy5zdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YSkgOiAnJ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0QXV4KHRva2VuKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLkJST1dTRVJfTk9UX1NVUFBPUlRFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICdCcm93c2VyICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldE5hbWUoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJyAodmVyc2lvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRWZXJzaW9uKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcpIGZvciAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRGYW1pbHkoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVhdmVzIHRoZSBzZXNzaW9uLCBkZXN0cm95aW5nIGFsbCBzdHJlYW1zIGFuZCBkZWxldGluZyB0aGUgdXNlciBhcyBhIHBhcnRpY2lwYW50LlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZSB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCBlYWNoIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzZXNzaW9uRGlzY29ubmVjdGVkYCB0byBhdm9pZCB0aGlzIGJlaGF2aW9yIGFuZCB0YWtlIGNhcmUgb2YgZGlzcG9zaW5nIGFuZCBjbGVhbmluZyBhbGwgdGhlIFN1YnNjcmliZXIgb2JqZWN0cyB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCBpZiB0aGVyZSBpcyBhIFtbUHVibGlzaGVyXV0gb2JqZWN0IHB1Ymxpc2hpbmcgdG8gdGhlIHNlc3Npb24uXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgc3RvcCBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIGlmIHlvdSB3YW50IHRvIGNsZWFuIHRoZSBQdWJsaXNoZXIgb2JqZWN0IG9uIHlvdXIgb3duIG9yIHJlLXB1Ymxpc2ggaXQgaW4gYSBkaWZmZXJlbnQgU2Vzc2lvbiAodG8gZG8gc28gaXQgaXMgYSBtYW5kYXRvcnkgcmVxdWlyZW1lbnQgdG8gY2FsbCBgU2Vzc2lvbi51bnB1Ymxpc2goKWBcbiAgICAgKiBvci9hbmQgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBpbiB0aGUgcHJldmlvdXMgc2Vzc2lvbikuIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBkaXNjb25uZWN0ZWQgcGFydGljaXBhbnQgd2FzIHB1Ymxpc2hpbmcuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhhdCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB5b3Vyc2VsZi5cbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgaW4gYW55IGNhc2UuIFNlZSBbW0Nvbm5lY3Rpb25FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKFxuICAgICAgICBzdHJlYW06IFN0cmVhbSxcbiAgICAgICAgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsXG4gICAgICAgIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICAgKTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoXG4gICAgICAgIHN0cmVhbTogU3RyZWFtLFxuICAgICAgICB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCxcbiAgICAgICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMsXG4gICAgICAgIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICAgKTogU3Vic2NyaWJlcjtcblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gYSBgc3RyZWFtYCwgYWRkaW5nIGEgbmV3IEhUTUwgdmlkZW8gZWxlbWVudCB0byBET00gd2l0aCBgc3Vic2NyaWJlclByb3BlcnRpZXNgIHNldHRpbmdzLiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGNhbGxlZCBpbiB0aGUgY2FsbGJhY2sgb2YgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00gKG9ubHkgaWYgeW91XG4gICAgICogW2xldCBPcGVuVmlkdSB0YWtlIGNhcmUgb2YgdGhlIHZpZGVvIHBsYXllcnNdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1N1YnNjcmliZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0IHRvIHN1YnNjcmliZSB0b1xuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFN1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZCAoc2VlIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dKS4gSWYgKm51bGwqIG9yICp1bmRlZmluZWQqIG5vIGRlZmF1bHQgdmlkZW8gd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIFN1YnNjcmliZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tTdWJzY3JpYmVyLmFkZFZpZGVvRWxlbWVudF1dIG9yIFtbU3Vic2NyaWJlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSB0byBtYW5hZ2UgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duIChzZWUgW01hbmFnZSB2aWRlbyBwbGF5ZXJzXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcykgc2VjdGlvbilcbiAgICAgKiBAcGFyYW0gY29tcGxldGlvbkhhbmRsZXIgYGVycm9yYCBwYXJhbWV0ZXIgaXMgbnVsbCBpZiBgc3Vic2NyaWJlYCBzdWNjZWVkcywgYW5kIGlzIGRlZmluZWQgaWYgaXQgZmFpbHMuXG4gICAgICovXG4gICAgc3Vic2NyaWJlKFxuICAgICAgICBzdHJlYW06IFN0cmVhbSxcbiAgICAgICAgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsXG4gICAgICAgIHBhcmFtMz86ICgoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKSB8IFN1YnNjcmliZXJQcm9wZXJ0aWVzLFxuICAgICAgICBwYXJhbTQ/OiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICAgKTogU3Vic2NyaWJlciB7XG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyA9IHt9O1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOlxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgcGFyYW0zLmluc2VydE1vZGUgIT09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFZpZGVvSW5zZXJ0TW9kZVtwYXJhbTMuaW5zZXJ0TW9kZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86IHR5cGVvZiBwYXJhbTMuc3Vic2NyaWJlVG9BdWRpbyAhPT0gJ3VuZGVmaW5lZCcgPyBwYXJhbTMuc3Vic2NyaWJlVG9BdWRpbyA6IHRydWUsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9WaWRlbzogdHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvICE9PSAndW5kZWZpbmVkJyA/IHBhcmFtMy5zdWJzY3JpYmVUb1ZpZGVvIDogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICAgICAgaW5zZXJ0TW9kZTogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb0F1ZGlvOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvVmlkZW86IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY29tcGxldGlvbkhhbmRsZXI6ICgoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCEhcGFyYW0zICYmIHR5cGVvZiBwYXJhbTMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgICAgICB9IGVsc2UgaWYgKCEhcGFyYW00KSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtNDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgIGlmIChjb21wbGV0aW9uSGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci5pbmZvKCdTdWJzY3JpYmluZyB0byAnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcblxuICAgICAgICBzdHJlYW1cbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdTdWJzY3JpYmVkIGNvcnJlY3RseSB0byAnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICBjb25zdCBzdWJzY3JpYmVyID0gbmV3IFN1YnNjcmliZXIoc3RyZWFtLCB0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzKTtcbiAgICAgICAgaWYgKCEhc3Vic2NyaWJlci50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBzdHJlYW0uc3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQoc3Vic2NyaWJlci50YXJnZXRFbGVtZW50LCA8VmlkZW9JbnNlcnRNb2RlPnByb3BlcnRpZXMuaW5zZXJ0TW9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1YnNjcmliZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW1Nlc3Npb24uc3Vic2NyaWJlXV1cbiAgICAgKi9cbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiBQcm9taXNlPFN1YnNjcmliZXI+O1xuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpOiBQcm9taXNlPFN1YnNjcmliZXI+O1xuXG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzPzogU3Vic2NyaWJlclByb3BlcnRpZXMpOiBQcm9taXNlPFN1YnNjcmliZXI+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFN1YnNjcmliZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBzdWJzY3JpYmVyOiBTdWJzY3JpYmVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShzdWJzY3JpYmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoISFwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHRoaXMuc3Vic2NyaWJlKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmUoc3RyZWFtLCB0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVuc3Vic2NyaWJlcyBmcm9tIGBzdWJzY3JpYmVyYCwgYXV0b21hdGljYWxseSByZW1vdmluZyBpdHMgYXNzb2NpYXRlZCBIVE1MIHZpZGVvIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQgZm9yIGVhY2ggdmlkZW8gYXNzb2NpYXRlZCB0byBpdCB0aGF0IHdhcyByZW1vdmVkIGZyb20gRE9NLlxuICAgICAqIE9ubHkgdmlkZW9zIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHJlbW92ZWRcbiAgICAgKlxuICAgICAqIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZVxuICAgICAqL1xuICAgIHVuc3Vic2NyaWJlKHN1YnNjcmliZXI6IFN1YnNjcmliZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1Vuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkKTtcblxuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgICd1bnN1YnNjcmliZUZyb21WaWRlbycsXG4gICAgICAgICAgICAgICAgICAgIHsgc2VuZGVyOiBzdWJzY3JpYmVyLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCB9LFxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSAnICsgY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1Vuc3Vic2NyaWJlZCBjb3JyZWN0bHkgZnJvbSAnICsgY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLnJlbW92ZUFsbFZpZGVvcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyB0byB0aGUgU2Vzc2lvbiB0aGUgUHVibGlzaGVyIG9iamVjdFxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGxvY2FsIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQgdXBvbiBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoaXMgbWV0aG9kLiBTZWUgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgbG9jYWwgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBvbmNlIHRoZSBtZWRpYSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHNvIHRoZXkgY2FuIHN1YnNjcmliZSB0byBpdC4gU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHB1Ymxpc2hlciB3YXMgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcHVibGlzaChwdWJsaXNoZXI6IFB1Ymxpc2hlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbS5zZXNzaW9uID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCFwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2hlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIE5PVCBiZWVuIGNhbGxlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbVxuICAgICAgICAgICAgICAgICAgICAucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VuZFZpZGVvRGF0YShwdWJsaXNoZXIsIDgsIHRydWUsIDUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgYmVlbiBjYWxsZWQuIE11c3QgaW5pdGlhbGl6ZSBhZ2FpbiBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAgICAgLmluaXRpYWxpemUoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uYWRkU3RyZWFtKHB1Ymxpc2hlci5zdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLnJlZXN0YWJsaXNoU3RyZWFtUGxheWluZ0V2ZW50KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZW5kVmlkZW9EYXRhKHB1Ymxpc2hlciwgOCwgdHJ1ZSwgNSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVucHVibGlzaGVzIGZyb20gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gdGhpcyBQdWJsaXNoZXJcbiAgICAgKiAob25seSB0aG9zZSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFB1Ymxpc2hlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHN0cmVhbURlc3Ryb3llZGAgaWYgeW91IHdhbnQgdG8gY2xlYW4gdGhlIFB1Ymxpc2hlciBvYmplY3Qgb24geW91ciBvd24gb3IgcmUtcHVibGlzaCBpdCBpbiBhIGRpZmZlcmVudCBTZXNzaW9uLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCBvbiB5b3VyIG93bi5cbiAgICAgKlxuICAgICAqIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqL1xuICAgIHVucHVibGlzaChwdWJsaXNoZXI6IFB1Ymxpc2hlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHRocm93IHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gcHVibGlzaGVyLnN0cmVhbTtcblxuICAgICAgICAgICAgaWYgKCFzdHJlYW0uY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdUaGUgYXNzb2NpYXRlZCBDb25uZWN0aW9uIG9iamVjdCBvZiB0aGlzIFB1Ymxpc2hlciBpcyBudWxsJykpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uY29ubmVjdGlvbiAhPT0gdGhpcy5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ1RoZSBhc3NvY2lhdGVkIENvbm5lY3Rpb24gb2JqZWN0IG9mIHRoaXMgUHVibGlzaGVyIGlzIG5vdCB5b3VyIGxvY2FsIENvbm5lY3Rpb24uICAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIk9ubHkgbW9kZXJhdG9ycyBjYW4gZm9yY2UgdW5wdWJsaXNoIG9uIHJlbW90ZSBTdHJlYW1zIHZpYSAnZm9yY2VVbnB1Ymxpc2gnIG1ldGhvZFwiXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnVW5wdWJsaXNoaW5nIGxvY2FsIG1lZGlhICgnICsgc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyknKTtcblxuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3VucHVibGlzaFZpZGVvJywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ01lZGlhIHVucHVibGlzaGVkIGNvcnJlY3RseScpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbS5jb25uZWN0aW9uLnN0cmVhbSA9PSBzdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgQ29ubmVjdGlvbi5zdHJlYW0gbWF5IGhhdmUgY2hhbmdlZCBpZiBTZXNzaW9uLnB1Ymxpc2ggd2FzIGNhbGxlZCB3aXRoIG90aGVyIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzdHJlYW0uY29ubmVjdGlvbi5zdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHB1Ymxpc2hlciwgJ3N0cmVhbURlc3Ryb3llZCcsIHB1Ymxpc2hlci5zdHJlYW0sICd1bnB1Ymxpc2gnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gbGVhdmUgdGhlIHNlc3Npb25cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyB3aGVuIHNvbWUgdXNlciBjYWxscyBbW1Nlc3Npb24uZGlzY29ubmVjdF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IGV4Y2VwdCB0aGUgZXZpY3RlZCBvbmUgd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBmb3IgdGhlIGV2aWN0ZWQgdXNlciwgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogSWYgYW55LCB0aGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dLCBbW0Nvbm5lY3Rpb25FdmVudF1dIGFuZCBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2ZvcmNlRGlzY29ubmVjdCcsIHsgY29ubmVjdGlvbklkOiBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZm9yY2luZyBkaXNjb25uZWN0IGZvciBDb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBmb3JjZSBhIGRpc2Nvbm5lY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgY29ycmVjdGx5IGZvciBDb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gdW5wdWJsaXNoIGEgU3RyZWFtXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgd2hlbiBzb21lIHVzZXIgY2FsbHMgW1tTZXNzaW9uLnVucHVibGlzaF1dLCBidXQgYHJlYXNvbmAgcHJvcGVydHkgaW4gYWxsIGV2ZW50cyB3aWxsIGJlIGBcImZvcmNlVW5wdWJsaXNoQnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImBcbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgYWZmZWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcmVtb3RlIFN0cmVhbSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VVbnB1Ymxpc2goc3RyZWFtOiBTdHJlYW0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGb3JjaW5nIHVucHVibGlzaCBmb3Igc3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdCgnZm9yY2VVbnB1Ymxpc2gnLCB7IHN0cmVhbUlkOiBzdHJlYW0uc3RyZWFtSWQgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgdW5wdWJsaXNoIGZvciBTdHJlYW0gJyArIHN0cmVhbS5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBmb3JjZSBhbiB1bnB1Ymxpc2hpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGb3JjaW5nIHVucHVibGlzaCBjb3JyZWN0bHkgZm9yIFN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgb25lIHNpZ25hbC4gYHNpZ25hbGAgb2JqZWN0IGhhcyB0aGUgZm9sbG93aW5nIG9wdGlvbmFsIHByb3BlcnRpZXM6XG4gICAgICogYGBganNvblxuICAgICAqIHtkYXRhOnN0cmluZywgdG86Q29ubmVjdGlvbltdLCB0eXBlOnN0cmluZ31cbiAgICAgKiBgYGBcbiAgICAgKiBBbGwgdXNlcnMgc3Vic2NyaWJlZCB0byB0aGF0IHNpZ25hbCAoYHNlc3Npb24ub24oJ3NpZ25hbDp0eXBlJywgLi4uKWAgb3IgYHNlc3Npb24ub24oJ3NpZ25hbCcsIC4uLilgIGZvciBhbGwgc2lnbmFscykgYW5kIHdob3NlIENvbm5lY3Rpb24gb2JqZWN0cyBhcmUgaW4gYHRvYCBhcnJheSB3aWxsIHJlY2VpdmUgaXQuIFRoZWlyIGxvY2FsXG4gICAgICogU2Vzc2lvbiBvYmplY3RzIHdpbGwgZGlzcGF0Y2ggYSBgc2lnbmFsYCBvciBgc2lnbmFsOnR5cGVgIGV2ZW50LiBTZWUgW1tTaWduYWxFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIG1lc3NhZ2Ugc3VjY2Vzc2Z1bGx5IHJlYWNoZWQgb3BlbnZpZHUtc2VydmVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3QuIF9UaGlzIGRvZXNuJ3RcbiAgICAgKiBtZWFuIHRoYXQgb3BlbnZpZHUtc2VydmVyIGNvdWxkIHJlc2VuZCB0aGUgbWVzc2FnZSB0byBhbGwgdGhlIGxpc3RlZCByZWNlaXZlcnMuX1xuICAgICAqL1xuICAgIC8qIHRzbGludDpkaXNhYmxlOm5vLXN0cmluZy1saXRlcmFsICovXG4gICAgc2lnbmFsKHNpZ25hbDogU2lnbmFsT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgICAgICBzaWduYWwudG8uZm9yRWFjaCgoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbklkcy5wdXNoKGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdzZW5kTWVzc2FnZScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qIHRzbGludDplbmFibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb248SyBleHRlbmRzIGtleW9mIFNlc3Npb25FdmVudE1hcD4odHlwZTogSywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub25BdXgodHlwZSwgXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnU2Vzc2lvbidcIiwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJykge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zIHdpdGggYXVkaW8sIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5lbmFibGVIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uPy5zdHJlYW0/Lmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgY29ubmVjdGVkIHRvIHRoZSBTZXNzaW9uIGFuZCBwdWJsaXNoaW5nIHdpdGggYXVkaW8sIGFsc28gZW5hYmxlIGhhcmsgJ3NwZWFraW5nJyBldmVudCBmb3IgdGhlIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSByZW1vdGUgc3RyZWFtcyB3aXRoIGF1ZGlvLCBlbmFibGUgaGFyayAnc3RvcHBlZF9zcGVha2luZycgZXZlbnQgaW4gYWxsIG9mIHRoZW1cbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5lbmFibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbj8uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIC8vIElmIGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiBhbmQgcHVibGlzaGluZyB3aXRoIGF1ZGlvLCBhbHNvIGVuYWJsZSBoYXJrICdzdG9wcGVkX3NwZWFraW5nJyBldmVudCBmb3IgdGhlIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25jZV1dXG4gICAgICovXG4gICAgb25jZTxLIGV4dGVuZHMga2V5b2YgU2Vzc2lvbkV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IFNlc3Npb25FdmVudE1hcFtLXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICBzdXBlci5vbmNlQXV4KHR5cGUsIFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgb25jZSBieSAnU2Vzc2lvbidcIiwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJykge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zIHdpdGggYXVkaW8sIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgKG9uY2UpIGluIGFsbCBvZiB0aGVtIG9uY2VcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5lbmFibGVPbmNlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbj8uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIC8vIElmIGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiBhbmQgcHVibGlzaGluZyB3aXRoIGF1ZGlvLCBhbHNvIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgKG9uY2UpIGZvciB0aGUgUHVibGlzaGVyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5lbmFibGVPbmNlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSByZW1vdGUgc3RyZWFtcyB3aXRoIGF1ZGlvLCBlbmFibGUgaGFyayAnc3RvcHBlZF9zcGVha2luZycgZXZlbnQgKG9uY2UpIGluIGFsbCBvZiB0aGVtIG9uY2VcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5lbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24/LnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24gYW5kIHB1Ymxpc2hpbmcgd2l0aCBhdWRpbywgYWxzbyBlbmFibGUgaGFyayAnc3RvcHBlZF9zcGVha2luZycgZXZlbnQgKG9uY2UpIGZvciB0aGUgUHVibGlzaGVyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5lbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmY8SyBleHRlbmRzIGtleW9mIFNlc3Npb25FdmVudE1hcD4odHlwZTogSywgaGFuZGxlcj86IChldmVudDogU2Vzc2lvbkV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9mZkF1eCh0eXBlLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiBTZXNzaW9uIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBmYWxzZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0/LnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFN1YnNjcmliZXIgb2JqZWN0IHN0aWxsIGhhcyBzb21lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIGZhbHNlLCByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24/LnN0cmVhbT8uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBQdWJsaXNoZXIgb2JqZWN0IHN0aWxsIGhhcyBzb21lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgZmFsc2UsIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZGlzYWJsZUhhcmtTcGVha2luZ0V2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIFNlc3Npb24gb2JqZWN0IHN0aWxsIGhhcyBzb21lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRcbiAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBTdWJzY3JpYmVyIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIGZhbHNlLCByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmRpc2FibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uPy5zdHJlYW0/LnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgUHVibGlzaGVyIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgZmFsc2UsIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZGlzYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKGV2ZW50OiBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24oZXZlbnQuaWQsICcnKVxuICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybignQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgKyAnIGFscmVhZHkgZXhpc3RzIGluIGNvbm5lY3Rpb25zIGxpc3QnKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgZXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuc2V0KGV2ZW50LmlkLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25DcmVhdGVkJywgY29ubmVjdGlvbiwgJycpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudExlZnQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHJlYXNvbjogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKGV2ZW50LmNvbm5lY3Rpb25JZCwgJ29uUGFydGljaXBhbnRMZWZ0JylcbiAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbi5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW07XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIHN0cmVhbSwgZXZlbnQucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5kZWxldGUoc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5kZWxldGUoY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW1xuICAgICAgICAgICAgICAgICAgICBuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkRlc3Ryb3llZCcsIGNvbm5lY3Rpb24sIGV2ZW50LnJlYXNvbilcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFB1Ymxpc2hlZChldmVudDogUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5zZXQoY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGNvbm5lY3Rpb24pO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuZ2V0KGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkKSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuc2V0KGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkLCB0cnVlKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuaWQsICdvblBhcnRpY2lwYW50UHVibGlzaGVkJylcblxuICAgICAgICAgICAgLnRoZW4oKGNvbikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICBldmVudC5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ucmVtb3RlT3B0aW9ucyA9IGV2ZW50O1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMoZXZlbnQuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICBhZnRlckNvbm5lY3Rpb25Gb3VuZChjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHJlYXNvbjogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKGV2ZW50LnJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnb25QYXJ0aWNpcGFudFVucHVibGlzaGVkJylcblxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSEsIGV2ZW50LnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkOiBzdHJpbmcgPSBjb25uZWN0aW9uLnN0cmVhbSEuc3RyZWFtSWQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuZGVsZXRlKHN0cmVhbUlkKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW92ZVN0cmVhbShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRFdmljdGVkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyByZWFzb246IHN0cmluZyB9KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudC5jb25uZWN0aW9uSWQgPT09IHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgIC8vIFlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICBpZiAoISF0aGlzLnNlc3Npb25JZCAmJiAhdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWF2ZSh0cnVlLCBldmVudC5yZWFzb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uTmV3TWVzc2FnZShldmVudDogeyB0eXBlPzogc3RyaW5nOyBkYXRhPzogc3RyaW5nOyBmcm9tPzogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ05ldyBzaWduYWw6ICcgKyBKU09OLnN0cmluZ2lmeShldmVudCkpO1xuXG4gICAgICAgIGNvbnN0IHN0cmlwcGVkVHlwZSA9ICEhZXZlbnQudHlwZSA/IGV2ZW50LnR5cGUucmVwbGFjZSgvXihzaWduYWw6KS8sICcnKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoISFldmVudC5mcm9tKSB7XG4gICAgICAgICAgICAvLyBTaWduYWwgc2VudCBieSBvdGhlciBjbGllbnRcbiAgICAgICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihcbiAgICAgICAgICAgICAgICBldmVudC5mcm9tLFxuICAgICAgICAgICAgICAgIFwiQ29ubmVjdGlvbiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICBldmVudC5mcm9tICtcbiAgICAgICAgICAgICAgICAgICAgXCInIHVua25vd24gd2hlbiAnb25OZXdNZXNzYWdlJy4gRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiBcIiArXG4gICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMucmVtb3RlQ29ubmVjdGlvbnMua2V5cygpKSArXG4gICAgICAgICAgICAgICAgICAgICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgICAgICAudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBzdHJpcHBlZFR5cGUsIGV2ZW50LmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3NpZ25hbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KGV2ZW50LnR5cGUsIFtuZXcgU2lnbmFsRXZlbnQodGhpcywgc3RyaXBwZWRUeXBlLCBldmVudC5kYXRhLCBjb25uZWN0aW9uKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2lnbmFsIHNlbnQgYnkgc2VydmVyXG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBzdHJpcHBlZFR5cGUsIGV2ZW50LmRhdGEsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgIGlmICghIWV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3NpZ25hbCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChldmVudC50eXBlLCBbbmV3IFNpZ25hbEV2ZW50KHRoaXMsIHN0cmlwcGVkVHlwZSwgZXZlbnQuZGF0YSwgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyBzdHJlYW1JZDogc3RyaW5nOyBwcm9wZXJ0eTogc3RyaW5nOyBuZXdWYWx1ZTogYW55OyByZWFzb246IHN0cmluZyB9KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBldmVudC5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGxldCBvbGRWYWx1ZTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2F1ZGlvQWN0aXZlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBldmVudC5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmF1ZGlvQWN0aXZlID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndmlkZW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0udmlkZW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IGV2ZW50Lm5ld1ZhbHVlID09PSAndHJ1ZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9BY3RpdmUgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0RpbWVuc2lvbnMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0udmlkZW9EaW1lbnNpb25zO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBKU09OLnBhcnNlKEpTT04ucGFyc2UoZXZlbnQubmV3VmFsdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdmaWx0ZXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBPYmplY3Qua2V5cyhldmVudC5uZXdWYWx1ZSkubGVuZ3RoID4gMCA/IGV2ZW50Lm5ld1ZhbHVlIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50Lm5ld1ZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyID0gbmV3IEZpbHRlcihldmVudC5uZXdWYWx1ZS50eXBlLCBldmVudC5uZXdWYWx1ZS5vcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQubmV3VmFsdWUubGFzdEV4ZWNNZXRob2QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5sYXN0RXhlY01ldGhvZCA9IGV2ZW50Lm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHN0cmVhbSwgZXZlbnQucHJvcGVydHksIGV2ZW50Lm5ld1ZhbHVlLCBvbGRWYWx1ZSwgZXZlbnQucmVhc29uKVxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHN0cmVhbS5zdHJlYW1NYW5hZ2VyLCBzdHJlYW0sIGV2ZW50LnByb3BlcnR5LCBldmVudC5uZXdWYWx1ZSwgb2xkVmFsdWUsIGV2ZW50LnJlYXNvbilcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJyBmb3VuZCBmb3IgY29ubmVjdGlvbiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuY29ubmVjdGlvbklkICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJyBvbiAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoZXZlbnQuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3VyIHN0cmVhbSBoYXMgYmVlbiBmb3JjZWRseSBjaGFuZ2VkIChmaWx0ZXIgZmVhdHVyZSlcbiAgICAgICAgICAgIGNhbGxiYWNrKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnb25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKVxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkNvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWQoZXZlbnQ6IHsgcHJvcGVydHk6IHN0cmluZzsgbmV3VmFsdWU6IGFueSB9KTogdm9pZCB7XG4gICAgICAgIGxldCBvbGRWYWx1ZTtcbiAgICAgICAgc3dpdGNoIChldmVudC5wcm9wZXJ0eSkge1xuICAgICAgICAgICAgY2FzZSAncm9sZSc6XG4gICAgICAgICAgICAgICAgb2xkVmFsdWUgPSB0aGlzLmNvbm5lY3Rpb24ucm9sZS5zbGljZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5yb2xlID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmxvY2FsT3B0aW9ucyEucm9sZSA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncmVjb3JkJzpcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHRoaXMuY29ubmVjdGlvbi5yZWNvcmQ7XG4gICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBldmVudC5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5yZWNvcmQgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24ubG9jYWxPcHRpb25zIS5yZWNvcmQgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgIG5ldyBDb25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5jb25uZWN0aW9uLCBldmVudC5wcm9wZXJ0eSwgZXZlbnQubmV3VmFsdWUsIG9sZFZhbHVlKVxuICAgICAgICBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZENoYW5nZWQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IG5ld1ZhbHVlOiBudW1iZXI7IG9sZFZhbHVlOiBudW1iZXIgfSk6IHZvaWQge1xuICAgICAgICBpZiAoZXZlbnQuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnbmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgbmV3IE5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkRXZlbnQodGhpcywgZXZlbnQubmV3VmFsdWUsIGV2ZW50Lm9sZFZhbHVlLCB0aGlzLmNvbm5lY3Rpb24pXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihldmVudC5jb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBldmVudC5jb25uZWN0aW9uSWQpXG4gICAgICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ25ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkRXZlbnQodGhpcywgZXZlbnQubmV3VmFsdWUsIGV2ZW50Lm9sZFZhbHVlLCBjb25uZWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjdkljZUNhbmRpZGF0ZShldmVudDoge1xuICAgICAgICBzZW5kZXJDb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICAgICAgZW5kcG9pbnROYW1lOiBzdHJpbmc7XG4gICAgICAgIHNkcE1MaW5lSW5kZXg6IG51bWJlcjtcbiAgICAgICAgc2RwTWlkOiBzdHJpbmc7XG4gICAgICAgIGNhbmRpZGF0ZTogc3RyaW5nO1xuICAgIH0pOiB2b2lkIHtcbiAgICAgICAgLy8gVGhlIGV2ZW50IGNvbnRhaW5zIGZpZWxkcyB0aGF0IGNhbiBiZSB1c2VkIHRvIG9idGFpbiBhIHByb3BlciBjYW5kaWRhdGUsXG4gICAgICAgIC8vIHVzaW5nIHRoZSBSVENJY2VDYW5kaWRhdGUgY29uc3RydWN0b3I6XG4gICAgICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJydGMtcGMvI2RvbS1ydGNpY2VjYW5kaWRhdGUtY29uc3RydWN0b3JcbiAgICAgICAgY29uc3QgY2FuZGlkYXRlSW5pdDogUlRDSWNlQ2FuZGlkYXRlSW5pdCA9IHtcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogZXZlbnQuY2FuZGlkYXRlLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogZXZlbnQuc2RwTUxpbmVJbmRleCxcbiAgICAgICAgICAgIHNkcE1pZDogZXZlbnQuc2RwTWlkXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGljZUNhbmRpZGF0ZSA9IG5ldyBSVENJY2VDYW5kaWRhdGUoY2FuZGlkYXRlSW5pdCk7XG5cbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKFxuICAgICAgICAgICAgZXZlbnQuc2VuZGVyQ29ubmVjdGlvbklkLFxuICAgICAgICAgICAgJ0Nvbm5lY3Rpb24gbm90IGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArXG4gICAgICAgICAgICAgICAgZXZlbnQuc2VuZGVyQ29ubmVjdGlvbklkICtcbiAgICAgICAgICAgICAgICAnIG93bmluZyBlbmRwb2ludCAnICtcbiAgICAgICAgICAgICAgICBldmVudC5lbmRwb2ludE5hbWUgK1xuICAgICAgICAgICAgICAgICcuIEljZSBjYW5kaWRhdGUgd2lsbCBiZSBpZ25vcmVkOiAnICtcbiAgICAgICAgICAgICAgICBpY2VDYW5kaWRhdGVcbiAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtITtcbiAgICAgICAgICAgICAgICBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgLmdldFdlYlJ0Y1BlZXIoKVxuICAgICAgICAgICAgICAgICAgICAuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciBhZGRpbmcgY2FuZGlkYXRlIGZvciAnICsgc3RyZWFtIS5zdHJlYW1JZCArICcgc3RyZWFtIG9mIGVuZHBvaW50ICcgKyBldmVudC5lbmRwb2ludE5hbWUgKyAnOiAnICsgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblNlc3Npb25DbG9zZWQobXNnKTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdTZXNzaW9uIGNsb3NlZDogJyArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuICAgICAgICBjb25zdCBzID0gbXNnLnNlc3Npb25JZDtcbiAgICAgICAgaWYgKHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3Nlc3Npb24tY2xvc2VkJywgW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbjogc1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1Nlc3Npb24gdW5kZWZpbmVkIG9uIHNlc3Npb24gY2xvc2VkJywgbXNnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkxvc3RDb25uZWN0aW9uKHJlYXNvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdMb3N0IGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICBpZiAoISF0aGlzLnNlc3Npb25JZCAmJiAhIXRoaXMuY29ubmVjdGlvbiAmJiAhdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICB0aGlzLmxlYXZlKHRydWUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvdmVyZWRDb25uZWN0aW9uKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuaW5mbygnUmVjb3ZlcmVkIGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICB0aGlzLnJlY29ubmVjdEJyb2tlblN0cmVhbXMoKTtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29ubmVjdGVkJywgW10pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk1lZGlhRXJyb3IoZXZlbnQ6IHsgZXJyb3I6IHN0cmluZyB9KTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci5lcnJvcignTWVkaWEgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShldmVudCkpO1xuICAgICAgICBjb25zdCBlcnIgPSBldmVudC5lcnJvcjtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Vycm9yLW1lZGlhJywgW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVyclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlY2VpdmVkIHVuZGVmaW5lZCBtZWRpYSBlcnJvcjonLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdGFydGVkKGV2ZW50OiB7IGlkOiBzdHJpbmc7IG5hbWU6IHN0cmluZyB9KTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIGV2ZW50LmlkLCBldmVudC5uYW1lKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0b3BwZWQoZXZlbnQ6IHsgaWQ6IHN0cmluZzsgbmFtZTogc3RyaW5nOyByZWFzb246IHN0cmluZyB9KTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdG9wcGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RvcHBlZCcsIGV2ZW50LmlkLCBldmVudC5uYW1lLCBldmVudC5yZWFzb24pXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyBzdHJlYW1JZDogc3RyaW5nOyBmaWx0ZXJUeXBlOiBzdHJpbmc7IGV2ZW50VHlwZTogc3RyaW5nOyBkYXRhOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQ6IHN0cmluZyA9IGV2ZW50LmNvbm5lY3Rpb25JZDtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKGNvbm5lY3Rpb25JZCwgJ05vIGNvbm5lY3Rpb24gZm91bmQgZm9yIGNvbm5lY3Rpb25JZCAnICsgY29ubmVjdGlvbklkKS50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgRmlsdGVyIGV2ZW50IG9mIHR5cGUgXCIke2V2ZW50LmV2ZW50VHlwZX1cIiBkaXNwYXRjaGVkYCk7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtITtcbiAgICAgICAgICAgIGlmICghc3RyZWFtIHx8ICFzdHJlYW0uZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYEZpbHRlciBldmVudCBvZiB0eXBlIFwiJHtldmVudC5ldmVudFR5cGV9XCIgZGlzcGF0Y2hlZCBmb3Igc3RyZWFtICR7c3RyZWFtLnN0cmVhbUlkfSBidXQgdGhlcmUgaXMgbm8gJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICFzdHJlYW0gPyAnc3RyZWFtJyA6ICdmaWx0ZXInXG4gICAgICAgICAgICAgICAgICAgIH0gZGVmaW5lZGBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZXZlbnRIYW5kbGVyID0gc3RyZWFtLmZpbHRlci5oYW5kbGVycy5nZXQoZXZlbnQuZXZlbnRUeXBlKTtcbiAgICAgICAgICAgIGlmICghZXZlbnRIYW5kbGVyIHx8IHR5cGVvZiBldmVudEhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3R1YWxIYW5kbGVyczogc3RyaW5nW10gPSBBcnJheS5mcm9tKHN0cmVhbS5maWx0ZXIuaGFuZGxlcnMua2V5cygpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICBgRmlsdGVyIGV2ZW50IG9mIHR5cGUgXCIke2V2ZW50LmV2ZW50VHlwZX1cIiBub3QgaGFuZGxlZCBvciBub3QgYSBmdW5jdGlvbiEgQWN0aXZlIGZpbHRlciBldmVudHM6ICR7YWN0dWFsSGFuZGxlcnMuam9pbihcbiAgICAgICAgICAgICAgICAgICAgICAgICcsJ1xuICAgICAgICAgICAgICAgICAgICApfWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBldmVudEhhbmRsZXIuY2FsbCh0aGlzLCBuZXcgRmlsdGVyRXZlbnQoc3RyZWFtLmZpbHRlciwgZXZlbnQuZXZlbnRUeXBlLCBldmVudC5kYXRhKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlcihldmVudDogeyBjb25uZWN0aW9uSWQ6IHN0cmluZzsgc3RyZWFtSWQ6IHN0cmluZzsgc2RwT2ZmZXI6IHN0cmluZyB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXInKVxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBldmVudC5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW0uc2V0dXBSZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIocmVzb2x2ZSwgcmVqZWN0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZ29pbmcgcmVjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2FpdCBmb3IgdGhlIGV2ZW50IGVtaXR0ZXIgdG8gYmUgZnJlZSAod2l0aCBzdWNjZXNzIG9yIGVycm9yKSBhbmQgY2FsbCB0aGUgbWV0aG9kIGFnYWluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhWydvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlckxhc3RFdmVudCddICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHdvIG9yIG1vcmUgb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXIgZXZlbnRzIHdlcmUgcmVjZWl2ZWQgd2hpbGUgYSByZWNvbm5lY3Rpb24gcHJvY2Vzc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgc3Vic2NyaWJlciB3YXMgYWxyZWFkeSB0YWtpbmcgcGxhY2UuIEFsd2F5cyB1c2UgdGhlIGxhc3Qgb25lIHRvIHJldHJ5IHRoZSByZS1zdWJzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2VzcywgYXMgdGhhdCBTRFAgb2ZmZXIgd2lsbCBiZSB0aGUgb25seSBvbmUgYXZhaWxhYmxlIGF0IHRoZSBzZXJ2ZXIgc2lkZS4gSWdub3JlIHByZXZpb3VzIG9uZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciFbJ29uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyTGFzdEV2ZW50J10gPSBldmVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCgnT25nb2luZyBmb3JjZWQgc3Vic2NyaWJlciByZWNvbm5lY3Rpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXIgZXZlbiBoYXMgYmVlbiByZWNlaXZlZCB3aGlsZSBhIHJlY29ubmVjdGlvbiBwcm9jZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBzdWJzY3JpYmVyIHdhcyBhbHJlYWR5IHRha2luZyBwbGFjZS4gU2V0IHVwIGEgbGlzdGVuZXIgdG8gd2FpdCBmb3IgaXQgdG8gcmV0cnkgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvcmNlZCByZWNvbm5lY3Rpb24gcHJvY2Vzc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIVsnb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXJMYXN0RXZlbnQnXSA9IGV2ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50QXV4ID0gc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciFbJ29uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyTGFzdEV2ZW50J107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciFbJ29uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyTGFzdEV2ZW50J107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyKGV2ZW50QXV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciEub25jZSgnc3VjY2VzcycsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIS5vbmNlKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wbGV0ZVdlYlJ0Y1BlZXJSZWNlaXZlKHRydWUsIHRydWUsIGV2ZW50LnNkcE9mZmVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHN0cmVhbS5maW5hbFJlc29sdmVGb3JTdWJzY3JpcHRpb24odHJ1ZSwgcmVzb2x2ZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbmFsUmVqZWN0Rm9yU3Vic2NyaXB0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBFcnJvciB3aGlsZSBmb3JjaWJseSByZWNvbm5lY3RpbmcgcmVtb3RlIHN0cmVhbSAke2V2ZW50LnN0cmVhbUlkfTogJHtlcnJvci50b1N0cmluZygpfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJNc2cgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiTm8gc3RyZWFtIHdpdGggc3RyZWFtSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdHJlYW1JZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuY29ubmVjdGlvbklkICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJNc2cpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJNc2cpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjb25uZWN0QnJva2VuU3RyZWFtcygpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1JlLWVzdGFibGlzaGluZyBtZWRpYSBjb25uZWN0aW9ucy4uLicpO1xuICAgICAgICBsZXQgc29tZVJlY29ubmVjdGlvbiA9IGZhbHNlO1xuICAgICAgICAvLyBSZS1lc3RhYmxpc2ggUHVibGlzaGVyIHN0cmVhbVxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24uc3RyZWFtICYmIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWNlQ29ubmVjdGlvblN0YXRlQnJva2VuKCkpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdSZS1lc3RhYmxpc2hpbmcgUHVibGlzaGVyICcgKyB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uaW5pdFdlYlJ0Y1BlZXJTZW5kKHRydWUpO1xuICAgICAgICAgICAgc29tZVJlY29ubmVjdGlvbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmUtZXN0YWJsaXNoIFN1YnNjcmliZXIgc3RyZWFtc1xuICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtICYmIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUljZUNvbm5lY3Rpb25TdGF0ZUJyb2tlbigpKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlLWVzdGFibGlzaGluZyBTdWJzY3JpYmVyICcgKyByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKHRydWUpO1xuICAgICAgICAgICAgICAgIHNvbWVSZWNvbm5lY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFzb21lUmVjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnVGhlcmUgd2VyZSBubyBtZWRpYSBzdHJlYW1zIGluIG5lZWQgb2YgYSByZWNvbm5lY3Rpb24nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGVhdmUoZm9yY2VkOiBib29sZWFuLCByZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0xlYXZpbmcgU2Vzc2lvbiAoZm9yY2VkPScgKyBmb3JjZWQgKyAnKScpO1xuICAgICAgICB0aGlzLnN0b3BWaWRlb0RhdGFJbnRlcnZhbHMoKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBsZWF2ZVJvb20gZXJyb3I6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IpfWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LmNsb3NlV3MoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKHJlYXNvbik7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBTZXNzaW9uIG9iamVjdCBkaXNwYXRjaCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcgZXZlbnQgKGlmIGl0IGlzIG5vdCBhbHJlYWR5IGRpc3Bvc2VkKVxuICAgICAgICAgICAgICAgIGNvbnN0IHNlc3Npb25EaXNjb25uZWN0RXZlbnQgPSBuZXcgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50KHRoaXMsIHJlYXNvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3Nlc3Npb25EaXNjb25uZWN0ZWQnLCBbc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudF0pO1xuICAgICAgICAgICAgICAgIHNlc3Npb25EaXNjb25uZWN0RXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuZmx1c2goKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZVBhcmFtcyh0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICB0b2tlbjogISF0b2tlbiA/IHRva2VuIDogJycsXG4gICAgICAgICAgICBzZXNzaW9uOiB0aGlzLnNlc3Npb25JZCxcbiAgICAgICAgICAgIHBsYXRmb3JtOiAhIXBsYXRmb3JtLmdldERlc2NyaXB0aW9uKCkgPyBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpIDogJ3Vua25vd24nLFxuICAgICAgICAgICAgc2RrVmVyc2lvbjogdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbixcbiAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gam9pblBhcmFtcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZFZpZGVvRGF0YShzdHJlYW1NYW5hZ2VyOiBTdHJlYW1NYW5hZ2VyLCBpbnRlcnZhbFNlY29uZHM6IG51bWJlciA9IDEsIGRvSW50ZXJ2YWw6IGJvb2xlYW4gPSBmYWxzZSwgbWF4TG9vcHM6IG51bWJlciA9IDEpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNDaHJvbWVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNFbGVjdHJvbigpIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgJiYgIXBsYXRmb3JtLmlzSW9uaWNJb3MoKSkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQW5kcm9pZEJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYW1zdW5nQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0lvbmljQW5kcm9pZCgpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0lPU1dpdGhTYWZhcmkoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IG9idGFpbkFuZFNlbmRWaWRlbyA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYyA9IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHBjLmNvbm5lY3Rpb25TdGF0ZSA9PT0gJ2Nvbm5lY3RlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdHNNYXAgPSBhd2FpdCBwYy5nZXRTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcnI6IGFueVtdID0gW107XG4gICAgICAgICAgICAgICAgICAgIHN0YXRzTWFwLmZvckVhY2goKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2ZyYW1lV2lkdGgnIGluIHN0YXRzICYmICdmcmFtZUhlaWdodCcgaW4gc3RhdHMgJiYgYXJyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHN0YXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcnIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmlkZW9EYXRhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogYXJyWzBdLmZyYW1lSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogYXJyWzBdLmZyYW1lV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0FjdGl2ZSAhPSBudWxsID8gc3RyZWFtTWFuYWdlci5zdHJlYW0udmlkZW9BY3RpdmUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmF1ZGlvQWN0aXZlICE9IG51bGwgPyBzdHJlYW1NYW5hZ2VyLnN0cmVhbS5hdWRpb0FjdGl2ZSA6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAndmlkZW9EYXRhJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChkb0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxvb3BzID0gMTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvRGF0YUludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobG9vcHMgPCBtYXhMb29wcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9vcHMrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIG9idGFpbkFuZFNlbmRWaWRlbygpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnZpZGVvRGF0YUludGVydmFsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIGludGVydmFsU2Vjb25kcyAqIDEwMDApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvRGF0YVRpbWVvdXQgPSBzZXRUaW1lb3V0KG9idGFpbkFuZFNlbmRWaWRlbywgaW50ZXJ2YWxTZWNvbmRzICogMTAwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocGxhdGZvcm0uaXNGaXJlZm94QnJvd3NlcigpIHx8IHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSB8fCBwbGF0Zm9ybS5pc0lvbmljSW9zKCkgfHwgcGxhdGZvcm0uaXNSZWFjdE5hdGl2ZSgpKSB7XG4gICAgICAgICAgICAvLyBCYXNpYyB2ZXJzaW9uIGZvciBGaXJlZm94IGFuZCBJb25pYyBpT1MuIFRoZXkgZG8gbm90IHN1cHBvcnQgc3RhdHNcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ3ZpZGVvRGF0YScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucz8uaGVpZ2h0IHx8IDAsXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnM/LndpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0FjdGl2ZSAhPSBudWxsID8gc3RyZWFtTWFuYWdlci5zdHJlYW0udmlkZW9BY3RpdmUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmF1ZGlvQWN0aXZlICE9IG51bGwgPyBzdHJlYW1NYW5hZ2VyLnN0cmVhbS5hdWRpb0FjdGl2ZSA6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAndmlkZW9EYXRhJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICdCcm93c2VyICcgK1xuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXROYW1lKCkgK1xuICAgICAgICAgICAgICAgICAgICAnICh2ZXJzaW9uICcgK1xuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRWZXJzaW9uKCkgK1xuICAgICAgICAgICAgICAgICAgICAnKSBmb3IgJyArXG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldEZhbWlseSgpICtcbiAgICAgICAgICAgICAgICAgICAgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1IGZvciBOZXR3b3JrIFF1YWxpdHknXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb25Db25uZWN0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24gIT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbm90Q29ubmVjdGVkRXJyb3IoKTogT3BlblZpZHVFcnJvciB7XG4gICAgICAgIHJldHVybiBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX05PVF9DT05ORUNURUQsXG4gICAgICAgICAgICBcIlRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24uIE1ldGhvZCAnU2Vzc2lvbi5jb25uZWN0JyBtdXN0IGJlIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgZmlyc3RcIlxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZChldmVudDogc3RyaW5nLCBvbmx5T25jZTogYm9vbGVhbiwgc3RyZWFtTWFuYWdlcj86IFN0cmVhbU1hbmFnZXIpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGhhbmRsZXJzSW5TZXNzaW9uID0gdGhpcy5lZS5nZXRMaXN0ZW5lcnMoZXZlbnQpO1xuICAgICAgICBpZiAob25seU9uY2UpIHtcbiAgICAgICAgICAgIGhhbmRsZXJzSW5TZXNzaW9uID0gaGFuZGxlcnNJblNlc3Npb24uZmlsdGVyKChoKSA9PiAoaCBhcyBhbnkpLm9uY2UpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsaXN0ZW5lcnNJblNlc3Npb24gPSBoYW5kbGVyc0luU2Vzc2lvbi5sZW5ndGg7XG4gICAgICAgIGlmIChsaXN0ZW5lcnNJblNlc3Npb24gPiAwKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IGxpc3RlbmVyc0luU3RyZWFtTWFuYWdlciA9IDA7XG4gICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgIGxldCBoYW5kbGVyc0luU3RyZWFtTWFuYWdlciA9IHN0cmVhbU1hbmFnZXIuZWUuZ2V0TGlzdGVuZXJzKGV2ZW50KTtcbiAgICAgICAgICAgIGlmIChvbmx5T25jZSkge1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzSW5TdHJlYW1NYW5hZ2VyID0gaGFuZGxlcnNJblN0cmVhbU1hbmFnZXIuZmlsdGVyKChoKSA9PiAoaCBhcyBhbnkpLm9uY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGlzdGVuZXJzSW5TdHJlYW1NYW5hZ2VyID0gaGFuZGxlcnNJblN0cmVhbU1hbmFnZXIubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsaXN0ZW5lcnNJblN0cmVhbU1hbmFnZXIgPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRUb2tlblBhcmFtcyh0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzPylcXDpcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcCgocGFyYW0pID0+IHBhcmFtLnNwbGl0KCc9JykpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgodmFsdWVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgICAgICAgICB9LCB7fSk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkOiBxdWVyeVBhcmFtc1snc2Vzc2lvbklkJ10sXG4gICAgICAgICAgICAgICAgc2VjcmV0OiBxdWVyeVBhcmFtc1snc2VjcmV0J10sXG4gICAgICAgICAgICAgICAgcmVjb3JkZXI6IHF1ZXJ5UGFyYW1zWydyZWNvcmRlciddLFxuICAgICAgICAgICAgICAgIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IHF1ZXJ5UGFyYW1zWyd3ZWJydGNTdGF0c0ludGVydmFsJ10sXG4gICAgICAgICAgICAgICAgc2VuZEJyb3dzZXJMb2dzOiBxdWVyeVBhcmFtc1snc2VuZEJyb3dzZXJMb2dzJ10sXG4gICAgICAgICAgICAgICAgZWRpdGlvbjogcXVlcnlQYXJhbXNbJ2VkaXRpb24nXSxcbiAgICAgICAgICAgICAgICB3c1VyaTogdXJsLnByb3RvY29sICsgJzovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnLFxuICAgICAgICAgICAgICAgIGh0dHBVcmk6ICdodHRwczovLycgKyB1cmwuaG9zdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW4gbm90IHZhbGlkOiBcIiR7dG9rZW59XCJgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0QXV4KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc3RhcnRXcygoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBqb2luUGFyYW1zID0gdGhpcy5pbml0aWFsaXplUGFyYW1zKHRva2VuKTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdqb2luUm9vbScsIGpvaW5QYXJhbXMsIChlcnJvciwgcmVzcG9uc2U6IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByb2Nlc3Mgam9pbiByb29tIHJlc3BvbnNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzSm9pblJvb21SZXNwb25zZShyZXNwb25zZSwgdG9rZW4pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb25PcHRpb25zOiBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLnNldChjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCwgY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5zZXQoY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCB0aGlzLmNvbm5lY3Rpb24sICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lICdjb25uZWN0aW9uQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggZXhpc3RpbmcgY29ubmVjdGlvbiBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5mb3JFYWNoKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIGNvbm5lY3Rpb24sICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goKHN0cmVhbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlc3BvbnNlLnJlY29yZGluZ0lkICYmICEhcmVzcG9uc2UucmVjb3JkaW5nTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVjb3JkaW5nU3RhcnRlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLnJlY29yZGluZ0lkLCByZXNwb25zZS5yZWNvcmRpbmdOYW1lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wUHVibGlzaGVyU3RyZWFtKHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbi5zdHJlYW0pIHtcbiAgICAgICAgICAgIC8vIERpc3Bvc2UgUHVibGlzaGVyJ3MgIGxvY2FsIHN0cmVhbVxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIC8vIE1ha2UgUHVibGlzaGVyIG9iamVjdCBkaXNwYXRjaCAnc3RyZWFtRGVzdHJveWVkJyBldmVudCBpZiB0aGUgU3RyZWFtIHdhcyBwdWJsaXNoZWRcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVlLmVtaXRFdmVudCgnbG9jYWwtc3RyZWFtLWRlc3Ryb3llZCcsIFtyZWFzb25dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RvcFZpZGVvRGF0YUludGVydmFscygpOiB2b2lkIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnZpZGVvRGF0YUludGVydmFsKTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudmlkZW9EYXRhVGltZW91dCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRhZGF0YSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQ6IHN0cmluZywgZXJyb3JNZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPENvbm5lY3Rpb24+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPENvbm5lY3Rpb24+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgPT09IGNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIGxvY2FsIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUodGhpcy5jb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBDb25uZWN0aW9uIG5vdCBmb3VuZC4gUmVqZWN0IHdpdGggT3BlblZpZHVFcnJvclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZW1vdGVDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBvcGVyYXRpb246IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSByZW1vdGUgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdGUgY29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAnUmVtb3RlIGNvbm5lY3Rpb24gJyArXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZCArXG4gICAgICAgICAgICAgICAgICAgIFwiIHVua25vd24gd2hlbiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gK1xuICAgICAgICAgICAgICAgICAgICBcIicuIFwiICtcbiAgICAgICAgICAgICAgICAgICAgJ0V4aXN0aW5nIHJlbW90ZSBjb25uZWN0aW9uczogJyArXG4gICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMucmVtb3RlQ29ubmVjdGlvbnMua2V5cygpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRva2VuUGFyYW1zID0gdGhpcy5nZXRUb2tlblBhcmFtcyh0b2tlbik7XG4gICAgICAgIHRoaXMuc2Vzc2lvbklkID0gdG9rZW5QYXJhbXMuc2Vzc2lvbklkO1xuXG4gICAgICAgIGlmICghIXRva2VuUGFyYW1zLnNlY3JldCkge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZWNyZXQgPSB0b2tlblBhcmFtcy5zZWNyZXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdG9rZW5QYXJhbXMucmVjb3JkZXIpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUucmVjb3JkZXIgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIXRva2VuUGFyYW1zLndlYnJ0Y1N0YXRzSW50ZXJ2YWwpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA9IHRva2VuUGFyYW1zLndlYnJ0Y1N0YXRzSW50ZXJ2YWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdG9rZW5QYXJhbXMuc2VuZEJyb3dzZXJMb2dzKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRCcm93c2VyTG9ncyA9IHRva2VuUGFyYW1zLnNlbmRCcm93c2VyTG9ncztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wZW52aWR1LmlzQXRMZWFzdFBybyA9IHRva2VuUGFyYW1zLmVkaXRpb24gPT09ICdwcm8nIHx8IHRva2VuUGFyYW1zLmVkaXRpb24gPT09ICdlbnRlcnByaXNlJztcbiAgICAgICAgdGhpcy5vcGVudmlkdS5pc0VudGVycHJpc2UgPSB0b2tlblBhcmFtcy5lZGl0aW9uID09PSAnZW50ZXJwcmlzZSc7XG5cbiAgICAgICAgdGhpcy5vcGVudmlkdS53c1VyaSA9IHRva2VuUGFyYW1zLndzVXJpO1xuICAgICAgICB0aGlzLm9wZW52aWR1Lmh0dHBVcmkgPSB0b2tlblBhcmFtcy5odHRwVXJpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHJvY2Vzc0pvaW5Sb29tUmVzcG9uc2Uob3B0czogTG9jYWxDb25uZWN0aW9uT3B0aW9ucywgdG9rZW46IHN0cmluZykge1xuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IG9wdHMuc2Vzc2lvbjtcbiAgICAgICAgaWYgKG9wdHMuY3VzdG9tSWNlU2VydmVycyAhPSBudWxsICYmIG9wdHMuY3VzdG9tSWNlU2VydmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LmljZVNlcnZlcnMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaWNlU2VydmVyIG9mIG9wdHMuY3VzdG9tSWNlU2VydmVycykge1xuICAgICAgICAgICAgICAgIGxldCBydGNJY2VTZXJ2ZXI6IFJUQ0ljZVNlcnZlciA9IHtcbiAgICAgICAgICAgICAgICAgICAgdXJsczogW2ljZVNlcnZlci51cmxdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdTVFVOL1RVUk4gc2VydmVyIElQOiAnICsgaWNlU2VydmVyLnVybCk7XG4gICAgICAgICAgICAgICAgaWYgKGljZVNlcnZlci51c2VybmFtZSAhPSBudWxsICYmIGljZVNlcnZlci5jcmVkZW50aWFsICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcnRjSWNlU2VydmVyLnVzZXJuYW1lID0gaWNlU2VydmVyLnVzZXJuYW1lO1xuICAgICAgICAgICAgICAgICAgICBydGNJY2VTZXJ2ZXIuY3JlZGVudGlhbCA9IGljZVNlcnZlci5jcmVkZW50aWFsO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdUVVJOIGNyZWRlbnRpYWxzIFsnICsgaWNlU2VydmVyLnVzZXJuYW1lICsgJzonICsgaWNlU2VydmVyLmNyZWRlbnRpYWwgKyAnXScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LmljZVNlcnZlcnMucHVzaChydGNJY2VTZXJ2ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbnZpZHUucm9sZSA9IG9wdHMucm9sZTtcbiAgICAgICAgdGhpcy5vcGVudmlkdS5maW5hbFVzZXJJZCA9IG9wdHMuZmluYWxVc2VySWQ7XG4gICAgICAgIHRoaXMub3BlbnZpZHUubWVkaWFTZXJ2ZXIgPSBvcHRzLm1lZGlhU2VydmVyO1xuICAgICAgICB0aGlzLm9wZW52aWR1LnZpZGVvU2ltdWxjYXN0ID0gb3B0cy52aWRlb1NpbXVsY2FzdDtcbiAgICAgICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgICAgICAgICBzdWJzY3JpYmU6IHRydWUsXG4gICAgICAgICAgICBwdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgIT09ICdTVUJTQ1JJQkVSJyxcbiAgICAgICAgICAgIGZvcmNlVW5wdWJsaXNoOiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InLFxuICAgICAgICAgICAgZm9yY2VEaXNjb25uZWN0OiB0aGlzLm9wZW52aWR1LnJvbGUgPT09ICdNT0RFUkFUT1InXG4gICAgICAgIH07XG4gICAgICAgIGxvZ2dlci5pbmZvKCdvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbjogJyArIG9wdHMudmVyc2lvbik7XG4gICAgICAgIGlmIChvcHRzLmxpZmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5saWZlID0gb3B0cy5saWZlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1pbm9yRGlmZmVyZW5jZTogbnVtYmVyID0gc2VtdmVyTWlub3Iob3B0cy52ZXJzaW9uKSAtIHNlbXZlck1pbm9yKHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pO1xuICAgICAgICBpZiAoc2VtdmVyTWFqb3Iob3B0cy52ZXJzaW9uKSAhPT0gc2VtdmVyTWFqb3IodGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbikgfHwgIShtaW5vckRpZmZlcmVuY2UgPT0gMCB8fCBtaW5vckRpZmZlcmVuY2UgPT0gMSkpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgb3BlbnZpZHUtYnJvd3NlciAoJHt0aGlzLm9wZW52aWR1LmxpYnJhcnlWZXJzaW9ufSkgYW5kIG9wZW52aWR1LXNlcnZlciAoJHtvcHRzLnZlcnNpb259KSB2ZXJzaW9ucyBhcmUgaW5jb21wYXRpYmxlLiBgICtcbiAgICAgICAgICAgICAgICAgICAgJ0Vycm9ycyBhcmUgbGlrZWx5IHRvIG9jY3VyLiBvcGVudmlkdS1icm93c2VyIFNESyBpcyBvbmx5IGNvbXBhdGlibGUgd2l0aCB0aGUgc2FtZSB2ZXJzaW9uIG9yIHRoZSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgbWlub3IgdmVyc2lvbiBvZiBhbiBPcGVuVmlkdSBkZXBsb3ltZW50J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChtaW5vckRpZmZlcmVuY2UgPT0gMSkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgYG9wZW52aWR1LWJyb3dzZXIgdmVyc2lvbiAke3RoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb259IGRvZXMgbm90IG1hdGNoIG9wZW52aWR1LXNlcnZlciB2ZXJzaW9uICR7b3B0cy52ZXJzaW9ufS4gYCArXG4gICAgICAgICAgICAgICAgICAgIGBUaGVzZSB2ZXJzaW9ucyBhcmUgc3RpbGwgY29tcGF0aWJsZSB3aXRoIGVhY2ggb3RoZXIsIGJ1dCBvcGVudmlkdS1icm93c2VyIHZlcnNpb24gbXVzdCBiZSB1cGRhdGVkIGFzIHNvb24gYXMgcG9zc2libGUgdG8gJHtzZW12ZXJNYWpvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdHMudmVyc2lvblxuICAgICAgICAgICAgICAgICAgICApfS4ke3NlbXZlck1pbm9yKG9wdHMudmVyc2lvbil9LnguIGAgK1xuICAgICAgICAgICAgICAgICAgICBgVGhpcyBjbGllbnQgdXNpbmcgb3BlbnZpZHUtYnJvd3NlciAke3RoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb259IHdpbGwgYmVjb21lIGluY29tcGF0aWJsZSB3aXRoIHRoZSBuZXh0IHJlbGVhc2Ugb2Ygb3BlbnZpZHUtc2VydmVyYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbmZpZ3VyZSBKU05Mb2dzXG4gICAgICAgIE9wZW5WaWR1TG9nZ2VyLmNvbmZpZ3VyZUpTTkxvZyh0aGlzLm9wZW52aWR1LCB0b2tlbik7XG5cbiAgICAgICAgLy8gU3RvcmUgdG9rZW5cbiAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyIH0gZnJvbSAnLi9TdWJzY3JpYmVyJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgT3V0Ym91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvT3V0Ym91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7XG4gICAgV2ViUnRjUGVlcixcbiAgICBXZWJSdGNQZWVyU2VuZG9ubHksXG4gICAgV2ViUnRjUGVlclJlY3Zvbmx5LFxuICAgIFdlYlJ0Y1BlZXJTZW5kcmVjdixcbiAgICBXZWJSdGNQZWVyQ29uZmlndXJhdGlvblxufSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1BlZXIvV2ViUnRjUGVlcic7XG5pbXBvcnQgeyBXZWJSdGNTdGF0cyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvV2ViUnRjU3RhdHMvV2ViUnRjU3RhdHMnO1xuaW1wb3J0IHsgRXhjZXB0aW9uRXZlbnQsIEV4Y2VwdGlvbkV2ZW50TmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V4Y2VwdGlvbkV2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcbmltcG9ydCB7IFR5cGVPZlZpZGVvIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9UeXBlT2ZWaWRlbyc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcblxuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ29ubmVjdGlvbiBvYmplY3QgdGhhdCBpcyBwdWJsaXNoaW5nIHRoZSBzdHJlYW1cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRnJhbWUgcmF0ZSBvZiB0aGUgdmlkZW8gaW4gZnJhbWVzIHBlciBzZWNvbmQuIFRoaXMgcHJvcGVydHkgaXMgb25seSBkZWZpbmVkIGlmIHRoZSBbW1B1Ymxpc2hlcl1dIG9mXG4gICAgICogdGhlIHN0cmVhbSB3YXMgaW5pdGlhbGl6ZWQgcGFzc2luZyBhIF9mcmFtZVJhdGVfIHByb3BlcnR5IG9uIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgICAqL1xuICAgIGZyYW1lUmF0ZT86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgYSB2aWRlbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNWaWRlbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgYW4gYXVkaW8gdHJhY2sgb3Igbm90XG4gICAgICovXG4gICAgaGFzQXVkaW86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSB2aWRlbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkLlxuICAgICAqXG4gICAgICogVGhpcyBwcm9wZXJ0eSBtYXkgY2hhbmdlIGlmIHRoZSBQdWJsaXNoZXIgcHVibGlzaGluZyB0aGUgc3RyZWFtIGNhbGxzIFtbUHVibGlzaGVyLnB1Ymxpc2hWaWRlb11dLiBXaGVuZXZlciB0aGlzIGhhcHBlbnMgYSBbW1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50XV0gd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgICogYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvQWN0aXZlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyB0aGUgYXVkaW8gdHJhY2sgbXV0ZWQgb3IgdW5tdXRlZC4gSWYgW1toYXNBdWRpb11dIGlzIGZhbHNlLCB0aGlzIHByb3BlcnR5IGlzIHVuZGVmaW5lZFxuICAgICAqXG4gICAgICogVGhpcyBwcm9wZXJ0eSBtYXkgY2hhbmdlIGlmIHRoZSBQdWJsaXNoZXIgcHVibGlzaGluZyB0aGUgc3RyZWFtIGNhbGxzIFtbUHVibGlzaGVyLnB1Ymxpc2hBdWRpb11dLiBXaGVuZXZlciB0aGlzIGhhcHBlbnMgYSBbW1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50XV0gd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgICogYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIGF1ZGlvQWN0aXZlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHN0cmVhbS4gSWYgdGhlIHN0cmVhbSBiZWxvbmdzIHRvIGEuLi5cbiAgICAgKiAtIFN1YnNjcmliZXIgb2JqZWN0OiBwcm9wZXJ0eSBgc3RyZWFtSWRgIGlzIGFsd2F5cyBkZWZpbmVkXG4gICAgICogLSBQdWJsaXNoZXIgb2JqZWN0OiBwcm9wZXJ0eSBgc3RyZWFtSWRgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIHN0cmVhbSB3YXMgY3JlYXRlZCBpbiBPcGVuVmlkdSBTZXJ2ZXIgKFVUQyBtaWxsaXNlY29uZHMpLiBEZXBlbmRpbmcgb24gdGhlIG93bmVyIG9mIHRoaXMgc3RyZWFtOlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIGFsd2F5cyBkZWZpbmVkXG4gICAgICogLSBQdWJsaXNoZXIgb2JqZWN0OiBwcm9wZXJ0eSBgY3JlYXRpb25UaW1lYCBpcyBvbmx5IGRlZmluZWQgYWZ0ZXIgc3VjY2Vzc2Z1bCBleGVjdXRpb24gb2YgW1tTZXNzaW9uLnB1Ymxpc2hdXVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQ2FuIGJlOlxuICAgICAqIC0gYFwiQ0FNRVJBXCJgOiB3aGVuIHRoZSB2aWRlbyBzb3VyY2UgY29tZXMgZnJvbSBhIHdlYmNhbS5cbiAgICAgKiAtIGBcIlNDUkVFTlwiYDogd2hlbiB0aGUgdmlkZW8gc291cmNlIGNvbWVzIGZyb20gc2NyZWVuLXNoYXJpbmcuXG4gICAgICogLSBgXCJDVVNUT01cImA6IHdoZW4gW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgaW4gdGhlIFB1Ymxpc2hlciBzaWRlIHdpdGggYSBjdXN0b20gTWVkaWFTdHJlYW1UcmFjayB3aGVuIGNhbGxpbmcgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0pLlxuICAgICAqIC0gYFwiSVBDQU1cImA6IHdoZW4gdGhlIHZpZGVvIHNvdXJjZSBjb21lcyBmcm9tIGFuIElQIGNhbWVyYSBwYXJ0aWNpcGFudCBpbnN0ZWFkIG9mIGEgcmVndWxhciBwYXJ0aWNpcGFudCAoc2VlIFtJUCBjYW1lcmFzXSgvZW4vc3RhYmxlL2FkdmFuY2VkLWZlYXR1cmVzL2lwLWNhbWVyYXMvKSkuXG4gICAgICpcbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBrZXlvZiB0eXBlb2YgVHlwZU9mVmlkZW87IC8vIFRPRE86IENoYW5nZSB0aGlzIHR5cGUgdG8gZW51bSBUeXBlT2ZWaWRlbyBvbiB0aGUgbmV4dCBicmVha2luZy1jaGFuZ2UgcmVsZWFzZVxuXG4gICAgLyoqXG4gICAgICogU3RyZWFtTWFuYWdlciBvYmplY3QgKFtbUHVibGlzaGVyXV0gb3IgW1tTdWJzY3JpYmVyXV0pIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoaXMgc3RyZWFtIGluIHRoZSBET01cbiAgICAgKi9cbiAgICBzdHJlYW1NYW5hZ2VyOiBTdHJlYW1NYW5hZ2VyO1xuXG4gICAgLyoqXG4gICAgICogV2lkdGggYW5kIGhlaWdodCBpbiBwaXhlbHMgb2YgdGhlIGVuY29kZWQgdmlkZW8gc3RyZWFtLiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciB0aGF0IGlzIHB1Ymxpc2hpbmc6XG4gICAgICogLSBJZiBpdCBpcyBhIG1vYmlsZSBkZXZpY2UsIHdoZW5ldmVyIHRoZSB1c2VyIHJvdGF0ZXMgdGhlIGRldmljZS5cbiAgICAgKiAtIElmIGl0IGlzIHNjcmVlbi1zaGFyaW5nLCB3aGVuZXZlciB0aGUgdXNlciBjaGFuZ2VzIHRoZSBzaXplIG9mIHRoZSBjYXB0dXJlZCB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBXaGVuZXZlciB0aGlzIGhhcHBlbnMgYSBbW1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50XV0gd2lsbCBiZSBkaXNwYXRjaGVkIGJ5IHRoZSBTZXNzaW9uIG9iamVjdCBhcyB3ZWxsIGFzIGJ5IHRoZSBhZmZlY3RlZCBTdWJzY3JpYmVyL1B1Ymxpc2hlciBvYmplY3RcbiAgICAgKi9cbiAgICB2aWRlb0RpbWVuc2lvbnM6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcblxuICAgIC8qKlxuICAgICAqICoqV0FSTklORyoqOiBleHBlcmltZW50YWwgb3B0aW9uLiBUaGlzIGludGVyZmFjZSBtYXkgY2hhbmdlIGluIHRoZSBuZWFyIGZ1dHVyZVxuICAgICAqXG4gICAgICogRmlsdGVyIGFwcGxpZWQgdG8gdGhlIFN0cmVhbS4gWW91IGNhbiBhcHBseSBmaWx0ZXJzIGJ5IGNhbGxpbmcgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgZXhlY3V0ZSBtZXRob2RzIG9mIHRoZSBhcHBsaWVkIGZpbHRlciB3aXRoXG4gICAgICogW1tGaWx0ZXIuZXhlY01ldGhvZF1dIGFuZCByZW1vdmUgaXQgd2l0aCBbW1N0cmVhbS5yZW1vdmVGaWx0ZXJdXS4gQmUgYXdhcmUgdGhhdCB0aGUgY2xpZW50IGNhbGxpbmcgdGhpcyBtZXRob2RzIG11c3QgaGF2ZSB0aGVcbiAgICAgKiBuZWNlc3NhcnkgcGVybWlzc2lvbnM6IHRoZSB0b2tlbiBvd25lZCBieSB0aGUgY2xpZW50IG11c3QgaGF2ZSBiZWVuIGluaXRpYWxpemVkIHdpdGggdGhlIGFwcHJvcHJpYXRlZCBgYWxsb3dlZEZpbHRlcnNgIGFycmF5LlxuICAgICAqL1xuICAgIGZpbHRlcj86IEZpbHRlcjtcblxuICAgIHByb3RlY3RlZCB3ZWJSdGNQZWVyOiBXZWJSdGNQZWVyO1xuICAgIHByb3RlY3RlZCBtZWRpYVN0cmVhbT86IE1lZGlhU3RyZWFtO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHM6IFdlYlJ0Y1N0YXRzO1xuXG4gICAgcHJpdmF0ZSBpc1N1YnNjcmliZVRvUmVtb3RlID0gZmFsc2U7XG5cbiAgICBwcml2YXRlIHZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHM/OiB7IHZpZGVvQ2xvbmU6IEhUTUxWaWRlb0VsZW1lbnQ7IG1lZGlhU3RyZWFtQ2xvbmU6IE1lZGlhU3RyZWFtIH07XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzPzogeyBWQjogYW55OyB2aWRlbzogSFRNTFZpZGVvRWxlbWVudCB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2Vzc2lvbjogU2Vzc2lvbjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5ib3VuZFN0cmVhbU9wdHM6IEluYm91bmRTdHJlYW1PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvdXRib3VuZFN0cmVhbU9wdHM6IE91dGJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3BlZWNoRXZlbnQ6IGFueTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1NwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhcmtPcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZT86IE1lZGlhU3RyZWFtO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyOiBFdmVudEVtaXR0ZXIgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHM6IE1lZGlhVHJhY2tDb25zdHJhaW50cyB8IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhc3RWQkZpbHRlcj86IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzZXNzaW9uOiBTZXNzaW9uLCBvcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyB8IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB8IHt9KSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLnNlc3Npb24gPSBzZXNzaW9uO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCdpZCcpKSB7XG4gICAgICAgICAgICAvLyBJbmJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBTdWJzY3JpYmVyXG4gICAgICAgICAgICB0aGlzLmluYm91bmRTdHJlYW1PcHRzID0gPEluYm91bmRTdHJlYW1PcHRpb25zPm9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5oYXNBdWRpbztcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvO1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5hdWRpb0FjdGl2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudmlkZW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9ICF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvID8gdW5kZWZpbmVkIDogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy50eXBlT2ZWaWRlbztcbiAgICAgICAgICAgICAgICB0aGlzLmZyYW1lUmF0ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlID09PSAtMSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcikubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCAmJlxuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCkubGVuZ3RoID09PSAwXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE91dGJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBQdWJsaXNoZXJcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gPE91dGJvdW5kU3RyZWFtT3B0aW9ucz5vcHRpb25zO1xuXG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pc1NlbmRBdWRpbygpO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaXNTZW5kVmlkZW8oKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gVHlwZU9mVmlkZW8uQ1VTVE9NO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHlwZU9mVmlkZW8gPSB0aGlzLmlzU2VuZFNjcmVlbigpID8gVHlwZU9mVmlkZW8uU0NSRUVOIDogVHlwZU9mVmlkZW8uQ0FNRVJBO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSEpO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtPy5pZCArICddIHVwZGF0ZWQgaW4gc3RyZWFtIFsnICsgdGhpcy5zdHJlYW1JZCArICddJyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3JlYXRlcyB0aGUgbWVkaWEgY29ubmVjdGlvbiB3aXRoIHRoZSBzZXJ2ZXIuIFRoaXMgZW50YWlscyB0aGUgZGlzcG9zYWwgb2YgdGhlIHByZXZpb3VzIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCB0aGUgcmUtbmVnb3RpYXRpb25cbiAgICAgKiBvZiBhIG5ldyBvbmUsIHRoYXQgd2lsbCBhcHBseSB0aGUgc2FtZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWZ1bCBpbiB0aG9zZSBzaXR1YXRpb25zIHdlcmUgdGhlcmUgdGhlIG1lZGlhIGNvbm5lY3Rpb24gYnJlYWtzIGFuZCBPcGVuVmlkdSBpcyBub3QgYWJsZSB0byByZWNvdmVyIG9uIGl0cyBvd25cbiAgICAgKiBmb3IgYW55IGtpbmQgb2YgdW5hbnRpY2lwYXRlZCByZWFzb24gKHNlZSBbQXV0b21hdGljIHJlY29ubmVjdGlvbl0oL2VuL3N0YWJsZS9hZHZhbmNlZC1mZWF0dXJlcy9hdXRvbWF0aWMtcmVjb25uZWN0aW9uLykpLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvbm5lY3Rpb24gb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWNvbm5lY3RTdHJlYW0oJ0FQSScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHRvIHRoZSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdHlwZSBUeXBlIG9mIGZpbHRlciBhcHBsaWVkLiBTZWUgW1tGaWx0ZXIudHlwZV1dXG4gICAgICogQHBhcmFtIG9wdGlvbnMgUGFyYW1ldGVycyB1c2VkIHRvIGluaXRpYWxpemUgdGhlIGZpbHRlci4gU2VlIFtbRmlsdGVyLm9wdGlvbnNdXVxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHRvIHRoZSBhcHBsaWVkIGZpbHRlciBpZiBzdWNjZXNzIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhcHBseUZpbHRlcih0eXBlOiBzdHJpbmcsIG9wdGlvbnM6IE9iamVjdCk6IFByb21pc2U8RmlsdGVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmZpbHRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsICdUaGVyZSBpcyBhbHJlYWR5IGEgZmlsdGVyIGFwcGxpZWQgdG8gU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVBcHBseUZpbHRlciA9IChlcnJvciwgdHJpZ2dlckV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgYXBwbHlpbmcgZmlsdGVyIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZTogRmlsdGVyID0gdGhpcy5maWx0ZXIhO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIodHlwZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyLnN0cmVhbSA9IHRoaXM7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0cmlnZ2VyRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJylcbiAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodHlwZS5zdGFydHNXaXRoKCdWQjonKSkge1xuICAgICAgICAgICAgICAgIC8vIENsaWVudCBmaWx0ZXJzXG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgcmVxdWlyZXMgYSB2aWRlbyB0cmFjayB0byBiZSBhcHBsaWVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubWVkaWFTdHJlYW0gfHwgdGhpcy5zdHJlYW1NYW5hZ2VyLnZpZGVvcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIFN0cmVhbU1hbmFnZXIgcmVxdWlyZXMgc29tZSB2aWRlbyBlbGVtZW50IHRvIGJlIGF0dGFjaGVkIHRvIGl0IGluIG9yZGVyIHRvIGFwcGx5IGEgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgb3BlbnZpZHVUb2tlbjogc3RyaW5nO1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi50b2tlbikge1xuICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVRva2VuID0gdGhpcy5zZXNzaW9uLnRva2VuO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4gPSBvcHRpb25zWyd0b2tlbiddO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIW9wZW52aWR1VG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVmlydHVhbCBCYWNrZ3JvdW5kIHJlcXVpcmVzIHRoZSBjbGllbnQgdG8gYmUgY29ubmVjdGVkIHRvIGEgU2Vzc2lvbiBvciB0byBoYXZlIGEgXCJ0b2tlblwiIHByb3BlcnR5IGF2YWlsYWJsZSBpbiBcIm9wdGlvbnNcIiBwYXJhbWV0ZXIgd2l0aCBhIHZhbGlkIE9wZW5WaWR1IHRva2VuJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuUGFyYW1zID0gdGhpcy5zZXNzaW9uLmdldFRva2VuUGFyYW1zKG9wZW52aWR1VG9rZW4pO1xuICAgICAgICAgICAgICAgIGlmICh0b2tlblBhcmFtcy5lZGl0aW9uICE9PSAncHJvJyAmJiB0b2tlblBhcmFtcy5lZGl0aW9uICE9PSAnZW50ZXJwcmlzZScpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnT3BlblZpZHUgVmlydHVhbCBCYWNrZ3JvdW5kIEFQSSBpcyBhdmFpbGFibGUgZnJvbSBPcGVuVmlkdSBQcm8gZWRpdGlvbiBvbndhcmRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQoYnRvYShvcGVudmlkdVRva2VuKSk7XG5cbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnQXBwbHlpbmcgVmlydHVhbCBCYWNrZ3JvdW5kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBhZnRlclNjcmlwdExvYWRlZCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5zdHJlYW1JZCArICdfJyArIHV1aWR2NCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW1DbG9uZSA9IHRoaXMubWVkaWFTdHJlYW0hLmNsb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2aWRlb0Nsb25lID0gdGhpcy5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby5jbG9uZU5vZGUoZmFsc2UpIGFzIEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0Nsb25lLmlkID0gVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQuU09VUkNFX1ZJREVPX1BSRUZJWCArIGlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9DbG9uZS5zcmNPYmplY3QgPSBtZWRpYVN0cmVhbUNsb25lO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9DbG9uZS5tdXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHMgPSB7IHZpZGVvQ2xvbmUsIG1lZGlhU3RyZWFtQ2xvbmUgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQuaGlkZUh0bWxFbGVtZW50KHZpZGVvQ2xvbmUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIFZpcnR1YWxCYWNrZ3JvdW5kLlZpcnR1YWxCYWNrZ3JvdW5kLmFwcGVuZEh0bWxFbGVtZW50VG9IaWRkZW5Db250YWluZXIodmlkZW9DbG9uZSwgaWQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB2aWRlb0Nsb25lLnBsYXkoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVkIgPSBuZXcgVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZW52aWR1U2VydmVyVXJsOiBuZXcgVVJMKHRva2VuUGFyYW1zLmh0dHBVcmkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRWaWRlbzogdmlkZW9DbG9uZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFJlc29sdXRpb246ICcxNjB4OTYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dEZyYW1lcmF0ZTogMjRcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmlsdGVyZWRWaWRlbzogSFRNTFZpZGVvRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1ZCOmJsdXInOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkVmlkZW8gPSBhd2FpdCBWQi5iYWNrZ3JvdW5kQmx1cihvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1ZCOmltYWdlJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZFZpZGVvID0gYXdhaXQgVkIuYmFja2dyb3VuZEltYWdlKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXI6ICcgKyB0eXBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aXJ0dWFsQmFja2dyb3VuZFNpbmtFbGVtZW50cyA9IHsgVkIsIHZpZGVvOiBmaWx0ZXJlZFZpZGVvIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvQ2xvbmUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlci5yZW1vdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIucmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMudmlkZW8uc3JjT2JqZWN0IGFzIE1lZGlhU3RyZWFtKS5nZXRWaWRlb1RyYWNrcygpWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLnN0cmVhbU1hbmFnZXIgYXMgUHVibGlzaGVyKS5yZXBsYWNlVHJhY2tBdXgoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzLnZpZGVvLnNyY09iamVjdCBhcyBNZWRpYVN0cmVhbSkuZ2V0VmlkZW9UcmFja3MoKVswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQXBwbHlGaWx0ZXIodW5kZWZpbmVkLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUFwcGx5RmlsdGVyKG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUiwgZXJyb3IubWVzc2FnZSksIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUFwcGx5RmlsdGVyKGVycm9yLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVmlydHVhbEJhY2tncm91bmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzY3JpcHQ6IEhUTUxTY3JpcHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCc7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdC5zcmMgPSB0b2tlblBhcmFtcy5odHRwVXJpICsgJy9vcGVudmlkdS92aXJ0dWFsLWJhY2tncm91bmQvb3BlbnZpZHUtdmlydHVhbC1iYWNrZ3JvdW5kLmpzP3Rva2VuPScgKyBvcGVudmlkdVRva2VuO1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHQub25sb2FkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBhZnRlclNjcmlwdExvYWRlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IEZpbHRlcih0eXBlLCBvcHRpb25zKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhZnRlclNjcmlwdExvYWRlZCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKG5ldyBGaWx0ZXIodHlwZSwgb3B0aW9ucykpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTZXJ2ZXIgZmlsdGVyc1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb24uc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5zZXNzaW9uLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdBcHBseWluZyBzZXJ2ZXIgZmlsdGVyIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgIT0gbnVsbCA/IG9wdGlvbnMgOiB7fTtcbiAgICAgICAgICAgICAgICBsZXQgb3B0aW9uc1N0cmluZyA9IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zU3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkob3B0aW9uc1N0cmluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ2FwcGx5RmlsdGVyJyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9uczogb3B0aW9uc1N0cmluZyB9LFxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQXBwbHlGaWx0ZXIoZXJyb3IsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbiBhdWRpby92aWRlbyBmaWx0ZXIgcHJldmlvdXNseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBwcmV2aW91c2x5IGFwcGxpZWQgZmlsdGVyIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZW1vdmVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpbiBvdGhlciBjYXNlXG4gICAgICovXG4gICAgYXN5bmMgcmVtb3ZlRmlsdGVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZW1vdmVGaWx0ZXJBdXgoZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGludGVybmFsIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCBhc3NvY2lhdGVkIHRvIHRoaXMgc3RyZWFtIChodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24pXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBOYXRpdmUgUlRDUGVlckNvbm5lY3Rpb24gV2ViIEFQSSBvYmplY3RcbiAgICAgKi9cbiAgICBnZXRSVENQZWVyQ29ubmVjdGlvbigpOiBSVENQZWVyQ29ubmVjdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucGM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW50ZXJuYWwgTWVkaWFTdHJlYW0gb2JqZWN0IGFzc29jaWF0ZWQgdG8gdGhpcyBzdHJlYW0gKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9NZWRpYVN0cmVhbSlcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIE5hdGl2ZSBNZWRpYVN0cmVhbSBXZWIgQVBJIG9iamVjdFxuICAgICAqL1xuICAgIGdldE1lZGlhU3RyZWFtKCk6IE1lZGlhU3RyZWFtIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWVkaWFTdHJlYW0hO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3ZlRmlsdGVyQXV4KGlzRGlzcG9zaW5nOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlUmVtb3ZlRmlsdGVyID0gKGVycm9yLCB0cmlnZ2VyRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcmVtb3ZlIGEgZmlsdGVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnRmlsdGVyIHN1Y2Nlc3NmdWxseSByZW1vdmVkIGZyb20gU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLmZpbHRlciE7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyaWdnZXJFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciEsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyISwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXG4gICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghIXRoaXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgYSBmaWx0ZXIgYXBwbGllZFxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmlsdGVyPy50eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENsaWVudCBmaWx0ZXJzXG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtQ2xvbmUgPSB0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHMhLm1lZGlhU3RyZWFtQ2xvbmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRGlzcG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlci5yZW1vdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLnJlcGxhY2VUcmFja0luTWVkaWFTdHJlYW0obWVkaWFTdHJlYW1DbG9uZS5nZXRWaWRlb1RyYWNrcygpWzBdLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgKHRoaXMuc3RyZWFtTWFuYWdlciBhcyBQdWJsaXNoZXIpLnJlcGxhY2VUcmFja0F1eChtZWRpYVN0cmVhbUNsb25lLmdldFZpZGVvVHJhY2tzKClbMF0sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtQ2xvbmUuZ2V0VHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMhLlZCLmNsZWFuVXAoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHM7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy52aXJ0dWFsQmFja2dyb3VuZFNvdXJjZUVsZW1lbnRzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZVJlbW92ZUZpbHRlcih1bmRlZmluZWQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlUmVtb3ZlRmlsdGVyKGVycm9yLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTZXJ2ZXIgZmlsdGVyc1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLnNlc3Npb24ubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIG9mIHN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVtb3ZlRmlsdGVyJywgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZVJlbW92ZUZpbHRlcihlcnJvciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gZmlsdGVyIGFwcGxpZWRcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsICdTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQgKyAnIGhhcyBubyBmaWx0ZXIgYXBwbGllZCcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldE1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSk6IHZvaWQge1xuICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbWVkaWFTdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKSB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdtZWRpYXN0cmVhbS11cGRhdGVkJywgW10pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRXZWJSdGNQZWVyKCk6IFdlYlJ0Y1BlZXIge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNTdWJzY3JpYmVUb1JlbW90ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPSBvdXRib3VuZFN0cmVhbU9wdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN1YnNjcmliZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKGZhbHNlKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZChmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5vbmNlKCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZVdlYlJ0Y1BlZXIoKTogdm9pZCB7XG4gICAgICAgIGxldCB3ZWJydGNJZDtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZGlzcG9zZSgpO1xuICAgICAgICAgICAgd2VicnRjSWQgPSB0aGlzLndlYlJ0Y1BlZXIuZ2V0SWQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArXG4gICAgICAgICAgICAgICAgJ1JUQ1BlZXJDb25uZWN0aW9uIHdpdGggaWQgWycgK1xuICAgICAgICAgICAgICAgIHdlYnJ0Y0lkICtcbiAgICAgICAgICAgICAgICBcIl0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCArXG4gICAgICAgICAgICAgICAgJ10gaXMgbm93IGNsb3NlZCdcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYXN5bmMgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoISF0aGlzLmZpbHRlciAmJiB0aGlzLmZpbHRlci50eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlRmlsdGVyQXV4KHRydWUpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoYFN1Y2Nlc3MgcmVtb3ZpbmcgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlciBmb3Igc3RyZWFtICR7dGhpcy5zdHJlYW1JZH1gKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgcmVtb3ZpbmcgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlciBmb3Igc3RyZWFtICR7dGhpcy5zdHJlYW1JZH1gLCBlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5tZWRpYVN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiBzdWJzY3JpYmVUb1JlbW90ZSBsb2NhbCBNZWRpYVN0cmVhbSBtdXN0IGJlIHN0b3BwZWRcbiAgICAgICAgaWYgKHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50LnN0b3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnTG9jYWwgJyA6ICdSZW1vdGUgJykgKyBcIk1lZGlhU3RyZWFtIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGRpc3Bvc2VkJ1xuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gZmFsc2VcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICE9PSBmYWxzZVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLmlzRWxlY3Ryb24oKSkge1xuICAgICAgICAgICAgc2NyZWVuID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZUhhcmtTcGVha2luZ0V2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkICYmICEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtcbiAgICAgICAgICAgICAgICAgICAgbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlID0gZmFsc2U7IC8vIERpc2FibGUgJ29uY2UnIHZlcnNpb24gaWYgJ29uJyB2ZXJzaW9uIHdhcyB0cmlnZ2VyZWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VIYXJrU3BlYWtpbmdFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMuaGFya1NwZWFraW5nRW5hYmxlZE9uY2UgJiYgISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIGhhcyBiZWVuIGRpc2FibGVkIGluIHRoZSBtZWFudGltZSAoZm9yIGV4YW1wbGUgYnkgdGhlICdvbicgdmVyc2lvbikgZG8gbm90IHRyaWdnZXIgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudCh0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChkaXNhYmxlZEJ5T25jZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzYWJsZWRCeU9uY2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSAnb24nIHZlcnNpb24gb2YgdGhpcyBzYW1lIGV2ZW50IGlzIGVuYWJsZWQgdG9vLiBEbyBub3QgcmVtb3ZlIHRoZSBoYXJrIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU2h1dHRpbmcgZG93biB0aGUgaGFyayBldmVudFxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gU29tZSBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIENhbm5vdCBzdG9wIHRoZSBoYXJrIHByb2Nlc3MsIGp1c3QgcmVtb3ZlIHRoZSBzcGVjaWZpYyBsaXN0ZW5lclxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBObyBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIFdlIGNhbiBnZXQgZW50aXJlbHkgcmlkIG9mIGl0XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCAmJiAhIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlOyAvLyBEaXNhYmxlICdvbmNlJyB2ZXJzaW9uIGlmICdvbicgdmVyc2lvbiB3YXMgdHJpZ2dlcmVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgJiYgISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsaXN0ZW5lciBoYXMgYmVlbiBkaXNhYmxlZCBpbiB0aGUgbWVhbnRpbWUgKGZvciBleGFtcGxlIGJ5IHRoZSAnb24nIHZlcnNpb24pIGRvIG5vdCB0cmlnZ2VyIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KGRpc2FibGVkQnlPbmNlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzYWJsZWRCeU9uY2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXZSBhcmUgY2FuY2VsbGluZyB0aGUgJ29uY2UnIGxpc3RlbmVyIGZvciB0aGlzIGV2ZW50LCBidXQgdGhlICdvbicgdmVyc2lvblxuICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGlzIHNhbWUgZXZlbnQgaXMgZW5hYmxlZCB0b28uIERvIG5vdCByZW1vdmUgdGhlIGhhcmsgbGlzdGVuZXJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU2h1dHRpbmcgZG93biB0aGUgaGFyayBldmVudFxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZE9uY2VcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIC8vIFNvbWUgb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzLCBqdXN0IHJlbW92ZSB0aGUgc3BlY2lmaWMgbGlzdGVuZXJcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9mZignc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBObyBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIFdlIGNhbiBnZXQgZW50aXJlbHkgcmlkIG9mIGl0XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZvcmNlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZCB8fCBmb3JjZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCAoaGFya0V2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoaXMgd2F5IHdoZW5ldmVyIHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaXMgYXZhaWxhYmxlLCB0aGUgZXZlbnQgbGlzdGVuZXIgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGFkZGVkXG4gICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZvcmNlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgfHwgZm9yY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgKGhhcmtFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoaXMgd2F5IHdoZW5ldmVyIHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaXMgYXZhaWxhYmxlLCB0aGUgZXZlbnQgbGlzdGVuZXIgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGFkZGVkXG4gICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYWJsZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChkaXNhYmxlZEJ5T25jZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2FibGVkQnlPbmNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2UgYXJlIGNhbmNlbGxpbmcgdGhlICdvbmNlJyBsaXN0ZW5lciBmb3IgdGhpcyBldmVudCwgYnV0IHRoZSAnb24nIHZlcnNpb25cbiAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhpcyBzYW1lIGV2ZW50IGlzIGVuYWJsZWQgdG9vLiBEbyBub3QgcmVtb3ZlIHRoZSBoYXJrIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNodXR0aW5nIGRvd24gdGhlIGhhcmsgZXZlbnRcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBTb21lIG90aGVyIGhhcmsgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2VzcywganVzdCByZW1vdmUgdGhlIHNwZWNpZmljIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBXZSBjYW4gZ2V0IGVudGlyZWx5IHJpZCBvZiBpdFxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNcbiAgICAgICAgICAgICAgICAuZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKClcbiAgICAgICAgICAgICAgICAudGhlbigocmVwb3J0KSA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0cmVhbUljZUNvbm5lY3Rpb25TdGF0ZUJyb2tlbigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmdldFdlYlJ0Y1BlZXIoKSB8fCAhdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpICYmICEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5mb3JjZU1lZGlhUmVjb25uZWN0aW9uQWZ0ZXJOZXR3b3JrRHJvcCkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgYE9wZW5WaWR1IEJyb3dzZXIgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb24gXCJmb3JjZU1lZGlhUmVjb25uZWN0aW9uQWZ0ZXJOZXR3b3JrRHJvcFwiIGlzIGVuYWJsZWQuIFN0cmVhbSAke1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInfSkgd2lsbCBmb3JjZSBhIHJlY29ubmVjdGlvbmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpY2VDb25uZWN0aW9uU3RhdGU6IFJUQ0ljZUNvbm5lY3Rpb25TdGF0ZSA9IHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5pY2VDb25uZWN0aW9uU3RhdGU7XG4gICAgICAgIHJldHVybiBpY2VDb25uZWN0aW9uU3RhdGUgIT09ICdjb25uZWN0ZWQnICYmIGljZUNvbm5lY3Rpb25TdGF0ZSAhPT0gJ2NvbXBsZXRlZCc7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIHNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9ICEhdGhpcy5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuaGFya09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgICAgICBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9IHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDEwMDtcbiAgICAgICAgICAgICAgICBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPSB0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJyA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldHVwUmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyKHJlc29sdmU6ICh2YWx1ZTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+KSA9PiB2b2lkLCByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gb25nb2luZyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gT25nb2luZyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICBgVHJ5aW5nIHRvIHJlY29ubmVjdCBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgICAgIH0pIGJ1dCBhbiBvbmdvaW5nIHJlY29ubmVjdGlvbiBwcm9jZXNzIGlzIGFjdGl2ZS4gV2FpdGluZyBmb3IgcmVzcG9uc2UuLi5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIub25jZSgnc3VjY2VzcycsICgpID0+IHJlc29sdmUoKSk7XG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlci5vbmNlKCdlcnJvcicsIChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0V2ViUnRjUGVlclNlbmQocmVjb25uZWN0OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dXBSZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIocmVzb2x2ZSwgcmVqZWN0KSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBPbmdvaW5nIHJlY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBNZWRpYVN0cmVhbSB3aWxsIGFscmVhZHkgaGF2ZSBoYXJrIGV2ZW50cyBmb3IgcmVjb25uZWN0ZWQgc3RyZWFtc1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdEhhcmtFdmVudHMoKTsgLy8gSW5pdCBoYXJrIGV2ZW50cyBmb3IgdGhlIGxvY2FsIHN0cmVhbVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBmaW5hbFJlc29sdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcj8uZW1pdEV2ZW50KCdzdWNjZXNzJyk7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVqZWN0ID0gKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcj8uZW1pdEV2ZW50KCdlcnJvcicsIFtlcnJvcl0pO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc09mZmVyQ2FsbGJhY2sgPSAoc2RwT2ZmZXJQYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyAnICsgdGhpcy5zdHJlYW1JZCwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBtZXRob2QgPSByZWNvbm5lY3QgPyAncmVjb25uZWN0U3RyZWFtJyA6ICdwdWJsaXNoVmlkZW8nO1xuICAgICAgICAgICAgICAgIGxldCBwYXJhbXM7XG4gICAgICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW06IHRoaXMuc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZHBTdHJpbmc6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdHlwZU9mVmlkZW87XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFR5cGVPZlZpZGVvLkNVU1RPTVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuaXNTZW5kU2NyZWVuKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBUeXBlT2ZWaWRlby5TQ1JFRU5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBUeXBlT2ZWaWRlby5DQU1FUkE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9Mb29wYmFjazogdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0F1ZGlvOiB0aGlzLmlzU2VuZEF1ZGlvKCksXG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNWaWRlbzogdGhpcy5pc1NlbmRWaWRlbygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHRoaXMuYXVkaW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy52aWRlb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVSYXRlOiAhIXRoaXMuZnJhbWVSYXRlID8gdGhpcy5mcmFtZVJhdGUgOiAtMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvRGltZW5zaW9uczogSlNPTi5zdHJpbmdpZnkodGhpcy52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBwdWJsaXNoXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZWplY3QoJ0Vycm9yIG9uIHB1Ymxpc2hWaWRlbzogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc1JlbW90ZUFuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gcmVzcG9uc2UuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gcmVzcG9uc2UuY3JlYXRlZEF0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZSA9IHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZVBlZXJTdWNjZXNzZnVsbHlFc3RhYmxpc2hlZChyZWNvbm5lY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVjb25uZWN0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJ1B1Ymxpc2hlcicgKFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnKSBzdWNjZXNzZnVsbHkgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlY29ubmVjdCA/ICdyZWNvbm5lY3RlZCcgOiAncHVibGlzaGVkJykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgdG8gc2Vzc2lvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBjb25maWc6IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmhhc1ZpZGVvXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaW11bGNhc3Q6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9TaW11bGNhc3QgPz8gdGhpcy5zZXNzaW9uLm9wZW52aWR1LnZpZGVvU2ltdWxjYXN0LFxuICAgICAgICAgICAgICAgIG9uSWNlQ2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgb25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb246IChleGNlcHRpb25OYW1lOiBFeGNlcHRpb25FdmVudE5hbWUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbbmV3IEV4Y2VwdGlvbkV2ZW50KHRoaXMuc2Vzc2lvbiwgZXhjZXB0aW9uTmFtZSwgdGhpcywgbWVzc2FnZSwgZGF0YSldKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGljZVNlcnZlcnM6IHRoaXMuZ2V0SWNlU2VydmVyc0NvbmYoKSxcbiAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbTogdGhpcy5tZWRpYVN0cmVhbSxcbiAgICAgICAgICAgICAgICBtZWRpYVNlcnZlcjogdGhpcy5zZXNzaW9uLm9wZW52aWR1Lm1lZGlhU2VydmVyLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiB0aGlzLnR5cGVPZlZpZGVvID8gVHlwZU9mVmlkZW9bdGhpcy50eXBlT2ZWaWRlb10gOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUubWVkaWFTZXJ2ZXIgIT09ICdtZWRpYXNvdXAnKSB7XG4gICAgICAgICAgICAgICAgLy8gU2ltdWxjYXN0IGlzIG9ubHkgc3VwcG9ydGVkIGJ5IG1lZGlhc291cFxuICAgICAgICAgICAgICAgIGNvbmZpZy5zaW11bGNhc3QgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyID0gbmV3IFdlYlJ0Y1BlZXJTZW5kcmVjdihjb25maWcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuYWRkSWNlQ29ubmVjdGlvblN0YXRlQ2hhbmdlTGlzdGVuZXIoJ3B1Ymxpc2hlciBvZiAnICsgdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXJcbiAgICAgICAgICAgICAgICAuY3JlYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKChzZHBPZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzTG9jYWxPZmZlcihzZHBPZmZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzT2ZmZXJDYWxsYmFjayhzZHBPZmZlci5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgcHJvY2VzcyBsb2NhbCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsUmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBjcmVhdGUgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpbmFsUmVzb2x2ZUZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3Q6IGJvb2xlYW4sIHJlc29sdmU6ICh2YWx1ZTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+KSA9PiB2b2lkKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKFwiJ1N1YnNjcmliZXInIChcIiArIHRoaXMuc3RyZWFtSWQgKyAnKSBzdWNjZXNzZnVsbHkgJyArIChyZWNvbm5lY3QgPyAncmVjb25uZWN0ZWQnIDogJ3N1YnNjcmliZWQnKSk7XG4gICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKHJlY29ubmVjdCk7XG4gICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyPy5lbWl0RXZlbnQoJ3N1Y2Nlc3MnKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBmaW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3Q6IGJvb2xlYW4sIGVycm9yOiBhbnksIHJlamVjdDogKHJlYXNvbj86IGFueSkgPT4gdm9pZCkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICBcIkVycm9yIGZvciAnU3Vic2NyaWJlcicgKFwiICtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAnKSB3aGlsZSB0cnlpbmcgdG8gJyArXG4gICAgICAgICAgICAgICAgKHJlY29ubmVjdCA/ICdyZWNvbm5lY3QnIDogJ3N1YnNjcmliZScpICtcbiAgICAgICAgICAgICAgICAnOiAnICtcbiAgICAgICAgICAgICAgICBlcnJvci50b1N0cmluZygpXG4gICAgICAgICk7XG4gICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyPy5lbWl0RXZlbnQoJ2Vycm9yJywgW2Vycm9yXSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNQZWVyUmVjZWl2ZShyZWNvbm5lY3Q6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR1cFJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcihyZXNvbHZlLCByZWplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9uZ29pbmcgcmVjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUubWVkaWFTZXJ2ZXIgPT09ICdtZWRpYXNvdXAnKSB7XG4gICAgICAgICAgICAgICAgLy8gU2VydmVyIGluaXRpYXRlcyBuZWdvdGlhdGlvblxuXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmVGcm9tU2VydmVyKHJlY29ubmVjdClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5maW5hbFJlc29sdmVGb3JTdWJzY3JpcHRpb24ocmVjb25uZWN0LCByZXNvbHZlKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gdGhpcy5maW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3QsIGVycm9yLCByZWplY3QpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ2xpZW50IGluaXRpYXRlcyBuZWdvdGlhdGlvblxuXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmVGcm9tQ2xpZW50KHJlY29ubmVjdClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5maW5hbFJlc29sdmVGb3JTdWJzY3JpcHRpb24ocmVjb25uZWN0LCByZXNvbHZlKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gdGhpcy5maW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3QsIGVycm9yLCByZWplY3QpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNQZWVyUmVjZWl2ZUZyb21DbGllbnQocmVjb25uZWN0OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvbXBsZXRlV2ViUnRjUGVlclJlY2VpdmUocmVjb25uZWN0LCBmYWxzZSlcbiAgICAgICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc1JlbW90ZUFuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlRnJvbVNlcnZlcihyZWNvbm5lY3Q6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIC8vIFNlcnZlciBpbml0aWF0ZXMgbmVnb3RpYXRpb25cbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncHJlcGFyZVJlY2VpdmVWaWRlb0Zyb20nLCB7IHNlbmRlcjogdGhpcy5zdHJlYW1JZCwgcmVjb25uZWN0IH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIG9uIHByZXBhcmVSZWNlaXZlVmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVdlYlJ0Y1BlZXJSZWNlaXZlKHJlY29ubmVjdCwgZmFsc2UsIHJlc3BvbnNlLnNkcE9mZmVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb21wbGV0ZVdlYlJ0Y1BlZXJSZWNlaXZlKHJlY29ubmVjdDogYm9vbGVhbiwgZm9yY2libHlSZWNvbm5lY3Q6IGJvb2xlYW4sIHNkcE9mZmVyQnlTZXJ2ZXI/OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZFwiKTtcblxuICAgICAgICAgICAgY29uc3Qgc2VuZFNkcFRvU2VydmVyID0gKHNkcFN0cmluZzogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBTZW5kaW5nIGxvY2FsIFNEUCAkeyEhc2RwT2ZmZXJCeVNlcnZlciA/ICdhbnN3ZXInIDogJ29mZmVyJ30gdG8gc3Vic2NyaWJlIHRvICR7dGhpcy5zdHJlYW1JZH1gLCBzZHBTdHJpbmcpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kID0gcmVjb25uZWN0ID8gJ3JlY29ubmVjdFN0cmVhbScgOiAncmVjZWl2ZVZpZGVvRnJvbSc7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge307XG4gICAgICAgICAgICAgICAgcGFyYW1zW3JlY29ubmVjdCA/ICdzdHJlYW0nIDogJ3NlbmRlciddID0gdGhpcy5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICBpZiAoISFzZHBPZmZlckJ5U2VydmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtc1tyZWNvbm5lY3QgPyAnc2RwU3RyaW5nJyA6ICdzZHBBbnN3ZXInXSA9IHNkcFN0cmluZztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNbJ3NkcE9mZmVyJ10gPSBzZHBTdHJpbmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zWydmb3JjaWJseVJlY29ubmVjdCddID0gZm9yY2libHlSZWNvbm5lY3Q7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIG9uICcgKyBtZXRob2QgKyAnIDogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBjb25maWc6IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmhhc1ZpZGVvXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaW11bGNhc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG9uSWNlQ2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgb25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb246IChleGNlcHRpb25OYW1lOiBFeGNlcHRpb25FdmVudE5hbWUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbbmV3IEV4Y2VwdGlvbkV2ZW50KHRoaXMuc2Vzc2lvbiwgZXhjZXB0aW9uTmFtZSwgdGhpcywgbWVzc2FnZSwgZGF0YSldKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGljZVNlcnZlcnM6IHRoaXMuZ2V0SWNlU2VydmVyc0NvbmYoKSxcbiAgICAgICAgICAgICAgICBtZWRpYVNlcnZlcjogdGhpcy5zZXNzaW9uLm9wZW52aWR1Lm1lZGlhU2VydmVyLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiB0aGlzLnR5cGVPZlZpZGVvID8gVHlwZU9mVmlkZW9bdGhpcy50eXBlT2ZWaWRlb10gOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkoY29uZmlnKTtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5hZGRJY2VDb25uZWN0aW9uU3RhdGVDaGFuZ2VMaXN0ZW5lcih0aGlzLnN0cmVhbUlkKTtcblxuICAgICAgICAgICAgaWYgKCEhc2RwT2ZmZXJCeVNlcnZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc1JlbW90ZU9mZmVyKHNkcE9mZmVyQnlTZXJ2ZXIpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVBbnN3ZXIoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKChzZHBBbnN3ZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc0xvY2FsQW5zd2VyKHNkcEFuc3dlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kU2RwVG9TZXJ2ZXIoc2RwQW5zd2VyLnNkcCEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIHByb2Nlc3MgbG9jYWwgYW5zd2VyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBjcmVhdGUgYW5zd2VyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCcoc3Vic2NyaWJlKSBTRFAgcHJvY2VzcyByZW1vdGUgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAuY3JlYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoc2RwT2ZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzTG9jYWxPZmZlcihzZHBPZmZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRTZHBUb1NlcnZlcihzZHBPZmZlci5zZHAhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBwcm9jZXNzIGxvY2FsIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCcoc3Vic2NyaWJlKSBTRFAgY3JlYXRlIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKHJlY29ubmVjdDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAocmVjb25uZWN0ICYmIHRoaXMubWVkaWFTdHJlYW0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gTm93IHdlIGNhbiBkZXN0cm95IHRoZSBleGlzdGluZyBNZWRpYVN0cmVhbVxuICAgICAgICAgICAgdGhpcy5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdQZWVyIHJlbW90ZSBzdHJlYW0nLCB0aGlzLm1lZGlhU3RyZWFtKTtcblxuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9IHJlY29ubmVjdCA/IHRoaXMuYXVkaW9BY3RpdmUgOiAhISh0aGlzLnN0cmVhbU1hbmFnZXIgYXMgU3Vic2NyaWJlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gcmVjb25uZWN0ID8gdGhpcy52aWRlb0FjdGl2ZSA6ICEhKHRoaXMuc3RyZWFtTWFuYWdlciBhcyBTdWJzY3JpYmVyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW87XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpO1xuICAgICAgICAgICAgdGhpcy5pbml0SGFya0V2ZW50cygpOyAvLyBJbml0IGhhcmsgZXZlbnRzIGZvciB0aGUgcmVtb3RlIHN0cmVhbVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRIYXJrRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtIS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAvLyBIYXJrIGV2ZW50cyBjYW4gb25seSBiZSBzZXQgaWYgYXVkaW8gdHJhY2sgaXMgYXZhaWxhYmxlXG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdHJ1ZSwgdGhpcy5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlT25jZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgZmFsc2UsIHRoaXMuc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0cnVlLCB0aGlzLnN0cmVhbU1hbmFnZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBmYWxzZSwgdGhpcy5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZU9uY2VIYXJrVm9sdW1lQ2hhbmdlRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkljZUNvbm5lY3Rpb25TdGF0ZUV4Y2VwdGlvbkhhbmRsZXIoZXhjZXB0aW9uTmFtZTogRXhjZXB0aW9uRXZlbnROYW1lLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgc3dpdGNoIChleGNlcHRpb25OYW1lKSB7XG4gICAgICAgICAgICBjYXNlIEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ09OTkVDVElPTl9GQUlMRUQ6XG4gICAgICAgICAgICAgICAgdGhpcy5vbkljZUNvbm5lY3Rpb25GYWlsZWQoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRXhjZXB0aW9uRXZlbnROYW1lLklDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRDpcbiAgICAgICAgICAgICAgICB0aGlzLm9uSWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ2V4Y2VwdGlvbicsIFtuZXcgRXhjZXB0aW9uRXZlbnQodGhpcy5zZXNzaW9uLCBleGNlcHRpb25OYW1lLCB0aGlzLCBtZXNzYWdlLCBkYXRhKV0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25JY2VDb25uZWN0aW9uRmFpbGVkKCkge1xuICAgICAgICAvLyBJbW1lZGlhdGVseSByZWNvbm5lY3QsIGFzIHRoaXMgaXMgYSB0ZXJtaW5hbCBlcnJvclxuICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgYFtJQ0VfQ09OTkVDVElPTl9GQUlMRURdIEhhbmRsaW5nIElDRV9DT05ORUNUSU9OX0ZBSUxFRCBldmVudC4gUmVjb25uZWN0aW5nIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke1xuICAgICAgICAgICAgICAgIHRoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgIH0pYFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlY29ubmVjdFN0cmVhbUFuZExvZ1Jlc3VsdGluZ0ljZUNvbm5lY3Rpb25TdGF0ZShFeGNlcHRpb25FdmVudE5hbWUuSUNFX0NPTk5FQ1RJT05fRkFJTEVEKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uSWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZCgpIHtcbiAgICAgICAgLy8gV2FpdCB0byBzZWUgaWYgdGhlIElDRSBjb25uZWN0aW9uIGlzIGFibGUgdG8gcmVjb25uZWN0XG4gICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICBgW0lDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRF0gSGFuZGxpbmcgSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEIGV2ZW50LiBXYWl0aW5nIGZvciBJQ0UgdG8gYmUgcmVzdG9yZWQgYW5kIHJlY29ubmVjdCBzdHJlYW0gJHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkXG4gICAgICAgICAgICB9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcid9KSBpZiBub3QgcG9zc2libGVgXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHRpbWVvdXQgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZUNvbm5lY3Rpb25EaXNjb25uZWN0ZWRFeGNlcHRpb25UaW1lb3V0IHx8IDQwMDA7XG4gICAgICAgIHRoaXMuYXdhaXRXZWJSdGNQZWVyQ29ubmVjdGlvblN0YXRlKHRpbWVvdXQpLnRoZW4oKHN0YXRlKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZmFpbGVkJzpcbiAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90aGluZywgYXMgYW4gSUNFX0NPTk5FQ1RJT05fRkFJTEVEIGV2ZW50IHdpbGwgaGF2ZSBhbHJlYWR5IHJhaXNlZFxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBbSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEXSBJQ0UgY29ubmVjdGlvbiBvZiBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBpcyBub3cgZmFpbGVkIGFmdGVyIElDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRGBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY29ubmVjdGVkJzpcbiAgICAgICAgICAgICAgICBjYXNlICdjb21wbGV0ZWQnOlxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFtJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURURdIElDRSBjb25uZWN0aW9uIG9mIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pIGF1dG9tYXRpY2FsbHkgcmVzdG9yZWQgYWZ0ZXIgSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVELiBDdXJyZW50IElDRSBjb25uZWN0aW9uIHN0YXRlOiAke3N0YXRlfWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xvc2VkJzpcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2luZyc6XG4gICAgICAgICAgICAgICAgY2FzZSAnbmV3JzpcbiAgICAgICAgICAgICAgICBjYXNlICdkaXNjb25uZWN0ZWQnOlxuICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHN0YXRlc1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBbSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEXSBJQ0UgY29ubmVjdGlvbiBvZiBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBjb3VsZG4ndCBiZSByZXN0b3JlZCBhZnRlciBJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQgZXZlbnQuIEN1cnJlbnQgSUNFIGNvbm5lY3Rpb24gc3RhdGUgYWZ0ZXIgJHt0aW1lb3V0fSBtczogJHtzdGF0ZX1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0U3RyZWFtQW5kTG9nUmVzdWx0aW5nSWNlQ29ubmVjdGlvblN0YXRlKEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWNvbm5lY3RTdHJlYW1BbmRMb2dSZXN1bHRpbmdJY2VDb25uZWN0aW9uU3RhdGUoZXZlbnQ6IHN0cmluZykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZmluYWxJY2VTdGF0ZUFmdGVyUmVjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5yZWNvbm5lY3RTdHJlYW1BbmRSZXR1cm5JY2VDb25uZWN0aW9uU3RhdGUoZXZlbnQpO1xuICAgICAgICAgICAgc3dpdGNoIChmaW5hbEljZVN0YXRlQWZ0ZXJSZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjb25uZWN0ZWQnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2NvbXBsZXRlZCc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBTdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBzdWNjZXNzZnVsbHkgcmVjb25uZWN0ZWQgYWZ0ZXIgJHtldmVudH0uIEN1cnJlbnQgSUNFIGNvbm5lY3Rpb24gc3RhdGU6ICR7ZmluYWxJY2VTdGF0ZUFmdGVyUmVjb25uZWN0aW9ufWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFske2V2ZW50fV0gU3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkgZmFpbGVkIHRvIHJlY29ubmVjdCBhZnRlciAke2V2ZW50fS4gQ3VycmVudCBJQ0UgY29ubmVjdGlvbiBzdGF0ZTogJHtmaW5hbEljZVN0YXRlQWZ0ZXJSZWNvbm5lY3Rpb259YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBFcnJvciByZWNvbm5lY3Rpbmcgc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICB9KSBhZnRlciAke2V2ZW50fTogJHtlcnJvcn1gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWNvbm5lY3RTdHJlYW1BbmRSZXR1cm5JY2VDb25uZWN0aW9uU3RhdGUoZXZlbnQ6IHN0cmluZyk6IFByb21pc2U8UlRDSWNlQ29ubmVjdGlvblN0YXRlPiB7XG4gICAgICAgIGxvZ2dlci5sb2coYFske2V2ZW50fV0gUmVjb25uZWN0aW5nIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcid9KSBhZnRlciBldmVudCAke2V2ZW50fWApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWNvbm5lY3RTdHJlYW0oZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgdGltZW91dCA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZEV4Y2VwdGlvblRpbWVvdXQgfHwgNDAwMDtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmF3YWl0V2ViUnRjUGVlckNvbm5lY3Rpb25TdGF0ZSh0aW1lb3V0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgIGBbJHtldmVudH1dIEVycm9yIHJlY29ubmVjdGluZyBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInfSkuIFJlYXNvbjogJHtlcnJvcn1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXdhaXRXZWJSdGNQZWVyQ29ubmVjdGlvblN0YXRlKDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWNvbm5lY3RTdHJlYW0oZXZlbnQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBpc1dzQ29ubmVjdGVkID0gYXdhaXQgdGhpcy5pc1dlYnNvY2tldENvbm5lY3RlZChldmVudCwgMzAwMCk7XG4gICAgICAgIGlmIChpc1dzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAvLyBUaGVyZSBpcyBjb25uZWN0aW9uIHRvIG9wZW52aWR1LXNlcnZlci4gVGhlIFJUQ1BlZXJDb25uZWN0aW9uIGlzIHRoZSBvbmx5IG9uZSBicm9rZW5cbiAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgYFske2V2ZW50fV0gVHJ5aW5nIHRvIHJlY29ubmVjdCBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgICAgIH0pIGFuZCB0aGUgd2Vic29ja2V0IGlzIG9wZW5lZGBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbml0V2ViUnRjUGVlclNlbmQodHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmluaXRXZWJSdGNQZWVyUmVjZWl2ZSh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gdG8gb3BlbnZpZHUtc2VydmVyLiBOb3RoaW5nIGNhbiBiZSBkb25lLiBUaGUgYXV0b21hdGljIHJlY29ubmVjdGlvblxuICAgICAgICAgICAgLy8gZmVhdHVyZSBzaG91bGQgaGFuZGxlIGEgcG9zc2libGUgcmVjb25uZWN0aW9uIG9mIFJUQ1BlZXJDb25uZWN0aW9uIGluIGNhc2UgbmV0d29yayBjb21lcyBiYWNrXG4gICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IGBbJHtldmVudH1dIFRyeWluZyB0byByZWNvbm5lY3Qgc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7XG4gICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgfSkgYnV0IHRoZSB3ZWJzb2NrZXQgd2Fzbid0IG9wZW5lZGA7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1dlYnNvY2tldENvbm5lY3RlZChldmVudDogc3RyaW5nLCBtc1Jlc3BvbnNlVGltZW91dDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3c1JlYWR5U3RhdGUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuZ2V0V3NSZWFkeVN0YXRlKCk7XG4gICAgICAgICAgICBpZiAod3NSZWFkeVN0YXRlID09PSAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgWyR7ZXZlbnR9XSBXZWJzb2NrZXQgdGltZW91dCBvZiAke21zUmVzcG9uc2VUaW1lb3V0fW1zYCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9LCBtc1Jlc3BvbnNlVGltZW91dCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdlY2hvJywge30sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlVGltZW91dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFske2V2ZW50fV0gV2Vic29ja2V0ICdlY2hvJyByZXR1cm5lZCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgWyR7ZXZlbnR9XSBXZWJzb2NrZXQgcmVhZHlTdGF0ZSBpcyAke3dzUmVhZHlTdGF0ZX1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgYXdhaXRXZWJSdGNQZWVyQ29ubmVjdGlvblN0YXRlKHRpbWVvdXQ6IG51bWJlcik6IFByb21pc2U8UlRDSWNlQ29ubmVjdGlvblN0YXRlPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5pY2VDb25uZWN0aW9uU3RhdGU7XG4gICAgICAgIGNvbnN0IGludGVydmFsID0gMTUwO1xuICAgICAgICBjb25zdCBpbnRlcnZhbHMgPSBNYXRoLmNlaWwodGltZW91dCAvIGludGVydmFsKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnRlcnZhbHM7IGkrKykge1xuICAgICAgICAgICAgc3RhdGUgPSB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuaWNlQ29ubmVjdGlvblN0YXRlO1xuICAgICAgICAgICAgaWYgKHN0YXRlID09PSAnY29ubmVjdGVkJyB8fCBzdGF0ZSA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNsZWVwXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBpbnRlcnZhbCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzID0gbmV3IFdlYlJ0Y1N0YXRzKHRoaXMpO1xuICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLmluaXRXZWJSdGNTdGF0cygpO1xuXG4gICAgICAgIC8vVE9ETzogc2VuZCBjb21tb24gd2VicnRjIHN0YXRzIGZyb20gY2xpZW50IHRvIG9wZW52aWR1LXNlcnZlclxuICAgICAgICAvKmlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCA+IDApIHtcbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGhlclN0YXRzRm9yUGVlcigpLnRoZW4oanNvblN0YXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZDogdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50UHJpdmF0ZUlkOiB0aGlzLmNvbm5lY3Rpb24ucnBjU2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHM6IGpzb25TdGF0c1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLm9wZW4oJ1BPU1QnLCB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaHR0cFVyaSArICcvZWxhc3RpY3NlYXJjaC93ZWJydGMtc3RhdHMnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICAgICAgfSovXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wV2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMud2ViUnRjU3RhdHMgJiYgdGhpcy53ZWJSdGNTdGF0cy5pc0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5zdG9wV2ViUnRjU3RhdHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SWNlU2VydmVyc0NvbmYoKTogUlRDSWNlU2VydmVyW10gfCB1bmRlZmluZWQge1xuICAgICAgICBsZXQgcmV0dXJuVmFsdWU7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPVxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA9PT0gJ2ZyZWVpY2UnXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5pY2VTZXJ2ZXJzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2F0aGVyU3RhdHNGb3JQZWVyKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKClcbiAgICAgICAgICAgICAgICAgICAgLmdldFNlbmRlcnMoKVxuICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaCgoc2VuZGVyKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZGVyLmdldFN0YXRzKCkudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKChyZXBvcnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmluYWxSZXBvcnQgPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3R5cGUnXSA9IHJlcG9ydC50eXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3RpbWVzdGFtcCddID0gcmVwb3J0LnRpbWVzdGFtcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydpZCddID0gcmVwb3J0LmlkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21tb24gdG8gQ2hyb21lLCBGaXJlZm94IGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRW5jb2RlZCddID0gcmVwb3J0LmZyYW1lc0VuY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNTZW50J10gPSByZXBvcnQucGFja2V0c1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzU2VudCddID0gcmVwb3J0LmJ5dGVzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU3Vic2NyaWJlciBzdHJlYW0gc3RhdHNcblxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKVxuICAgICAgICAgICAgICAgICAgICAuZ2V0UmVjZWl2ZXJzKClcbiAgICAgICAgICAgICAgICAgICAgLmZvckVhY2goKHJlY2VpdmVyKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZXIuZ2V0U3RhdHMoKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2goKHJlcG9ydCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0RlY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNEZWNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzUmVjZWl2ZWQnXSA9IHJlcG9ydC5wYWNrZXRzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNMb3N0J10gPSByZXBvcnQucGFja2V0c0xvc3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ppdHRlciddID0gcmVwb3J0LmppdHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYnl0ZXNSZWNlaXZlZCddID0gcmVwb3J0LmJ5dGVzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlSW5jb21pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlSW5jb21pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coZmluYWxSZXBvcnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUmVwb3J0V2FudGVkKHJlcG9ydDogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcgJiYgIXRoaXMuaXNMb2NhbCgpKSB8fFxuICAgICAgICAgICAgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJyAmJiB0aGlzLmlzTG9jYWwoKSkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQubm9taW5hdGVkICYmIHJlcG9ydC5ieXRlc1NlbnQgPiAwKVxuICAgICAgICApO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdWJzY3JpYmVyIH0gZnJvbSAnLi9TdWJzY3JpYmVyJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4vRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3RyZWFtTWFuYWdlclZpZGVvJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudE1hcCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50TWFwL1N0cmVhbU1hbmFnZXJFdmVudE1hcCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1NYW5hZ2VyRXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9FbGVtZW50RXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9WaWRlb0VsZW1lbnRFdmVudCc7XG5pbXBvcnQgeyBFeGNlcHRpb25FdmVudCwgRXhjZXB0aW9uRXZlbnROYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXhjZXB0aW9uRXZlbnQnO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVV0aWxzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybSc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBJbnRlcmZhY2UgaW4gY2hhcmdlIG9mIGRpc3BsYXlpbmcgdGhlIG1lZGlhIHN0cmVhbXMgaW4gdGhlIEhUTUwgRE9NLiBUaGlzIHdyYXBzIGFueSBbW1B1Ymxpc2hlcl1dIGFuZCBbW1N1YnNjcmliZXJdXSBvYmplY3QuXG4gKiBZb3UgY2FuIGluc2VydCBhcyBtYW55IHZpZGVvIHBsYXllcnMgZm8gdGhlIHNhbWUgU3RyZWFtIGFzIHlvdSB3YW50IGJ5IGNhbGxpbmcgW1tTdHJlYW1NYW5hZ2VyLmFkZFZpZGVvRWxlbWVudF1dIG9yXG4gKiBbW1N0cmVhbU1hbmFnZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0uXG4gKiBUaGUgdXNlIG9mIFN0cmVhbU1hbmFnZXIgd3JhcHBlciBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIFB1Ymxpc2hlciBvciBTdWJzY3JpYmVyIHN0cmVhbXMgb3IganVzdFxuICogd2FudCB0byBkaXJlY3RseSBtYW5hZ2UgeW91ciBvd24gdmlkZW8gZWxlbWVudHMgKGV2ZW4gbW9yZSB0aGFuIG9uZSB2aWRlbyBlbGVtZW50IHBlciBTdHJlYW0pLiBUaGlzIHNjZW5hcmlvIGlzIHByZXR0eSBjb21tb24gaW5cbiAqIGRlY2xhcmF0aXZlLCBNVkMgZnJvbnRlbmQgZnJhbWV3b3JrcyBzdWNoIGFzIEFuZ3VsYXIsIFJlYWN0IG9yIFZ1ZS5qc1xuICpcbiAqIFNlZSBhdmFpbGFibGUgZXZlbnQgbGlzdGVuZXJzIGF0IFtbU3RyZWFtTWFuYWdlckV2ZW50TWFwXV0uXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGV4dGVuZHMgRXZlbnREaXNwYXRjaGVyIHtcbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3IgW1tQdWJsaXNoZXJdXVxuICAgICAqIC0gYHRydWVgIGZvciBbW1N1YnNjcmliZXJdXVxuICAgICAqL1xuICAgIHJlbW90ZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gSFRNTEVsZW1lbnQgYXNzaWduZWQgYXMgdGFyZ2V0IGVsZW1lbnQgd2hlbiBjcmVhdGluZyB0aGUgdmlkZW8gZm9yIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSBbW1B1Ymxpc2hlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICogLSBbW1N1YnNjcmliZXJdXSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBmaXJzdFZpZGVvRWxlbWVudD86IFN0cmVhbU1hbmFnZXJWaWRlbztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY2FuUGxheUxpc3RlbmVyOiBFdmVudExpc3RlbmVyO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQ/OiBOb2RlSlMuVGltZW91dDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJpdmF0ZSBsYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIgPSB0aGlzO1xuICAgICAgICB0aGlzLnJlbW90ZSA9ICF0aGlzLnN0cmVhbS5pc0xvY2FsKCk7XG5cbiAgICAgICAgaWYgKCEhdGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0RWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0RWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCEhdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKSxcbiAgICAgICAgICAgICAgICAgICAgaWQ6ICcnLFxuICAgICAgICAgICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgKHBsYXRmb3JtLmlzSVBob25lT3JJUGFkKCkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChwbGF0Zm9ybS5pc0Nocm9tZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkpKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnZpZGVvLnBsYXlzSW5saW5lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRFbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FuUGxheUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZWFjdGl2YXRlU3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCgpO1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uPEsgZXh0ZW5kcyBrZXlvZiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogU3RyZWFtTWFuYWdlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uQXV4KHR5cGUsIFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1wiICsgKHRoaXMucmVtb3RlID8gJ1N1YnNjcmliZXInIDogJ1B1Ymxpc2hlcicpICsgXCInXCIsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlPEsgZXh0ZW5kcyBrZXlvZiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogU3RyZWFtTWFuYWdlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uY2VBdXgodHlwZSwgXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0XG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZU9uY2VIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub2ZmXV1cbiAgICAgKi9cbiAgICBvZmY8SyBleHRlbmRzIGtleW9mIFN0cmVhbU1hbmFnZXJFdmVudE1hcD4odHlwZTogSywgaGFuZGxlcj86IChldmVudDogU3RyZWFtTWFuYWdlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9mZkF1eCh0eXBlLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBCb3RoIFN0cmVhbU1hbmFnZXIgYW5kIFNlc3Npb24gY2FuIGhhdmUgXCJwdWJsaXNoZXJTdGFydFNwZWFraW5nXCIgZXZlbnQgbGlzdGVuZXJzXG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdTdGFydFNwZWFraW5nRXZlbnRMaXN0ZW5lcnMgPVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZ2V0TGlzdGVuZXJzKHR5cGUpLmxlbmd0aCArIHRoaXMuc3RyZWFtLnNlc3Npb24uZWUuZ2V0TGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChyZW1haW5pbmdTdGFydFNwZWFraW5nRXZlbnRMaXN0ZW5lcnMgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1NwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgLy8gQm90aCBTdHJlYW1NYW5hZ2VyIGFuZCBTZXNzaW9uIGNhbiBoYXZlIFwicHVibGlzaGVyU3RvcFNwZWFraW5nXCIgZXZlbnQgbGlzdGVuZXJzXG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdTdG9wU3BlYWtpbmdFdmVudExpc3RlbmVycyA9XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5nZXRMaXN0ZW5lcnModHlwZSkubGVuZ3RoICsgdGhpcy5zdHJlYW0uc2Vzc2lvbi5lZS5nZXRMaXN0ZW5lcnModHlwZSkubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKHJlbWFpbmluZ1N0b3BTcGVha2luZ0V2ZW50TGlzdGVuZXJzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgU3RyZWFtTWFuYWdlciBjYW4gaGF2ZSBcInN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlXCIgZXZlbnQgbGlzdGVuZXJzXG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdWb2x1bWVFdmVudExpc3RlbmVycyA9IHRoaXMuZWUuZ2V0TGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChyZW1haW5pbmdWb2x1bWVFdmVudExpc3RlbmVycyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYHZpZGVvYCBlbGVtZW50IHBhcmFtZXRlciBkaXNwbGF5IHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB5b3UgYXJlXG4gICAgICogW21hbmFnaW5nIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93bl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI3lvdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpXG4gICAgICpcbiAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIHdpdGggYSB2aWRlbyBhbHJlYWR5IGFkZGVkIHRvIG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgY2F1c2UgdGhlIHZpZGVvIGVsZW1lbnQgdG8gYmVcbiAgICAgKiBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBwcmV2aW91cyBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgdG8gYmUgYXNzb2NpYXRlZCB0byB0aGlzIG9uZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIDEgaWYgdGhlIHZpZGVvIHdhc24ndCBhc3NvY2lhdGVkIHRvIGFueSBvdGhlciBQdWJsaXNoZXIvU3Vic2NyaWJlciBhbmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqIDAgaWYgdGhlIHZpZGVvIHdhcyBhbHJlYWR5IGFkZGVkIHRvIHRoaXMgUHVibGlzaGVyL1N1YnNjcmliZXIuIC0xIGlmIHRoZSB2aWRlbyB3YXMgcHJldmlvdXNseSBhc3NvY2lhdGVkIHRvIGFueSBvdGhlclxuICAgICAqIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZGlzYXNzb2NpYXRlZCBmcm9tIHRoYXQgb25lIGFuZCBwcm9wZXJseSBhZGRlZCB0byB0aGlzIG9uZS5cbiAgICAgKi9cbiAgICBhZGRWaWRlb0VsZW1lbnQodmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiBudW1iZXIge1xuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGlmICghdGhpcy5yZW1vdGUgJiYgdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGVsZW1lbnQgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMgU3RyZWFtTWFuYWdlciBkbyBub3RoaW5nXG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLnZpZGVvcykge1xuICAgICAgICAgICAgaWYgKHYudmlkZW8gPT09IHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0dXJuTnVtYmVyID0gMTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbU1hbmFnZXIgb2YgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycykge1xuICAgICAgICAgICAgaWYgKHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuTnVtYmVyID0gLTE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmZvckVhY2goKHN0cmVhbU1hbmFnZXIpID0+IHtcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXIuZGlzYXNzb2NpYXRlVmlkZW8odmlkZW8pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oe1xuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbG9nZ2VyLmluZm8oJ05ldyB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gJywgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHJldHVybk51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZpZGVvIGVsZW1lbnQgZGlzcGxheWluZyB0aGlzIFtbc3RyZWFtXV0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSBbW1ZpZGVvRWxlbWVudEV2ZW50XV1cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWRcbiAgICAgKiBAcGFyYW0gaW5zZXJ0TW9kZSBIb3cgdGhlIHZpZGVvIGVsZW1lbnQgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseSB0byBgdGFyZ2V0RWxlbWV0YFxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgSFRNTFZpZGVvRWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVZpZGVvRWxlbWVudCh0YXJnZXRFbGVtZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIGluc2VydE1vZGU/OiBWaWRlb0luc2VydE1vZGUpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgbGV0IHRhcmdFbDtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWRlbyA9IHRoaXMuY3JlYXRlVmlkZW8oKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvKTtcblxuICAgICAgICBsZXQgaW5zTW9kZSA9ICEhaW5zZXJ0TW9kZSA/IGluc2VydE1vZGUgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICBzd2l0Y2ggKGluc01vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFGVEVSOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQVBQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5CRUZPUkU6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5QUkVQRU5EOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlJFUExBQ0U6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5yZXBsYWNlQ2hpbGQodmlkZW8sIHRhcmdFbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluc01vZGUgPSBWaWRlb0luc2VydE1vZGUuQVBQRU5EO1xuICAgICAgICAgICAgICAgIHRhcmdFbC5hcHBlbmRDaGlsZCh2aWRlbyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2OiBTdHJlYW1NYW5hZ2VyVmlkZW8gPSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGluc2VydE1vZGU6IGluc01vZGUsXG4gICAgICAgICAgICBpZDogdmlkZW8uaWQsXG4gICAgICAgICAgICBjYW5wbGF5TGlzdGVuZXJBZGRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wdXNoTmV3U3RyZWFtTWFuYWdlclZpZGVvKHYpO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh2LnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9ICEhdGhpcy5maXJzdFZpZGVvRWxlbWVudDtcblxuICAgICAgICByZXR1cm4gdmlkZW87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uIGZvciB0aGUgW1tQdWJsaXNoZXJTcGVha2luZ0V2ZW50XV0gZmVhdHVyZSBhbmQgdGhlIFtTdHJlYW1NYW5hZ2VyRXZlbnQuc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2VdKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvY2xhc3Nlcy9TdHJlYW1NYW5hZ2VyRXZlbnQuaHRtbCkgZmVhdHVyZSBmb3IgdGhpcyBzcGVjaWZpY1xuICAgICAqIFN0cmVhbU1hbmFnZXIgYXVkaW8gc3RyZWFtLCBvdmVycmlkaW5nIHRoZSBnbG9iYWwgb3B0aW9ucyBzZXQgd2l0aCBbW09wZW5WaWR1LnNldEFkdmFuY2VkQ29uZmlndXJhdGlvbl1dLiBUaGlzIHdheSB5b3UgY2FuIGN1c3RvbWl6ZSB0aGUgYXVkaW8gZXZlbnRzIG9wdGlvbnNcbiAgICAgKiBmb3IgZWFjaCBzcGVjaWZpYyBTdHJlYW1NYW5hZ2VyIGFuZCBjaGFuZ2UgdGhlbSBkeW5hbWljYWxseS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMgTmV3IG9wdGlvbnMgdG8gYmUgYXBwbGllZCB0byB0aGlzIFN0cmVhbU1hbmFnZXIncyBhdWRpbyBzdHJlYW0uIEl0IGlzIGFuIG9iamVjdCB3aGljaCBpbmNsdWRlcyB0aGUgZm9sbG93aW5nIG9wdGlvbmFsIHByb3BlcnRpZXM6XG4gICAgICogLSBgaW50ZXJ2YWxgOiAobnVtYmVyKSBob3cgZnJlcXVlbnRseSB0aGUgYW5hbHlzZXIgcG9sbHMgdGhlIGF1ZGlvIHN0cmVhbSB0byBjaGVjayBpZiBzcGVha2luZyBoYXMgc3RhcnRlZC9zdG9wcGVkIG9yIGF1ZGlvIHZvbHVtZSBoYXMgY2hhbmdlZC4gRGVmYXVsdCAqKjEwMCoqIChtcylcbiAgICAgKiAtIGB0aHJlc2hvbGRgOiAobnVtYmVyKSB0aGUgdm9sdW1lIGF0IHdoaWNoIF9wdWJsaXNoZXJTdGFydFNwZWFraW5nXywgX3B1Ymxpc2hlclN0b3BTcGVha2luZ18gZXZlbnRzIHdpbGwgYmUgZmlyZWQuIERlZmF1bHQgKiotNTAqKiAoZEIpXG4gICAgICovXG4gICAgdXBkYXRlUHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zKHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uczogeyBpbnRlcnZhbD86IG51bWJlcjsgdGhyZXNob2xkPzogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY3VycmVudEhhcmtPcHRpb25zID0gISF0aGlzLnN0cmVhbS5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgOiB0aGlzLnN0cmVhbS5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMgfHwge307XG4gICAgICAgIGNvbnN0IG5ld0ludGVydmFsID1cbiAgICAgICAgICAgIHR5cGVvZiBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMuaW50ZXJ2YWwgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMuaW50ZXJ2YWxcbiAgICAgICAgICAgICAgICA6IHR5cGVvZiBjdXJyZW50SGFya09wdGlvbnMuaW50ZXJ2YWwgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBjdXJyZW50SGFya09wdGlvbnMuaW50ZXJ2YWxcbiAgICAgICAgICAgICAgICA6IDEwMDtcbiAgICAgICAgY29uc3QgbmV3VGhyZXNob2xkID1cbiAgICAgICAgICAgIHR5cGVvZiBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgID8gcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zLnRocmVzaG9sZFxuICAgICAgICAgICAgICAgIDogdHlwZW9mIGN1cnJlbnRIYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBjdXJyZW50SGFya09wdGlvbnMudGhyZXNob2xkXG4gICAgICAgICAgICAgICAgOiAtNTA7XG4gICAgICAgIHRoaXMuc3RyZWFtLmhhcmtPcHRpb25zID0ge1xuICAgICAgICAgICAgaW50ZXJ2YWw6IG5ld0ludGVydmFsLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBuZXdUaHJlc2hvbGRcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0uc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNwZWVjaEV2ZW50LnNldEludGVydmFsKG5ld0ludGVydmFsKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNwZWVjaEV2ZW50LnNldFRocmVzaG9sZChuZXdUaHJlc2hvbGQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKCF0aGlzLnJlbW90ZSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5pc0lQaG9uZU9ySVBhZCgpICYmXG4gICAgICAgICAgICAgICAgKHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSkpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdmlkZW8ucGxheXNJbmxpbmUgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucmVtb3RlICYmIHRoaXMuaXNNaXJyb3JlZFZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgLy8gU3Vic2NyaWJlciB2aWRlbyBhc3NvY2lhdGVkIHRvIGEgcHJldmlvdXNseSBtaXJyb3JlZCB2aWRlbyBlbGVtZW50XG4gICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5yZW1vdGUgJiYgIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAvLyBQdWJsaXNoZXIgdmlkZW9cbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTWlycm9yZWRWaWRlbyh2aWRlbykgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyBpcyBub3cgc2V0IHRvIG1pcnJvciBhbmQgaXMgbm90IHNjcmVlbiBzaGFyZVxuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKChzdHJlYW1NYW5hZ2VyVmlkZW8pID0+IHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBvbmNhbnBsYXkgZXZlbnQgbGlzdGVuZXIgKG9ubHkgT3BlblZpZHUgYnJvd3NlciBsaXN0ZW5lciwgbm90IHRoZSB1c2VyIG9uZXMpXG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gJiYgISFzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBWaWRlb0VsZW1lbnRFdmVudChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnREZXN0cm95ZWQnKVxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmVtb3ZlIHNyY09iamVjdCBmcm9tIHRoZSB2aWRlb1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTcmNPYmplY3Qoc3RyZWFtTWFuYWdlclZpZGVvKTtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKCh2KSA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnVmlkZW8gZWxlbWVudCBkaXNhc3NvY2lhdGVkIGZyb20gJywgdGhpcyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpc2Fzc29jaWF0ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpIHtcbiAgICAgICAgaWYgKCEhdGhpcy52aWRlb3NbMF0gJiYgISF0aGlzLnZpZGVvc1swXS52aWRlbyAmJiAhdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVTdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0KCk7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKChzdHJlYW1NYW5hZ2VyVmlkZW8pID0+IHtcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBtZWRpYVN0cmVhbTtcbiAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5pc0lvbmljSW9zKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY3JlYXRlVmlkZW8oKTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVTcmNPYmplY3Qoc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG51bGw7XG4gICAgICAgIHRoaXMuZGVhY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgcmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbSh0cmFjazogTWVkaWFTdHJlYW1UcmFjaywgdXBkYXRlTGFzdENvbnN0cmFpbnRzOiBib29sZWFuKTogdm9pZDtcblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJvdGVjdGVkIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtLmlzSW9uaWNJb3MoKSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzTWlycm9yZWRWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdmlkZW8uc3R5bGUudHJhbnNmb3JtID09PSAncm90YXRlWSgxODBkZWcpJyB8fCB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgIH1cblxuICAgIHByaXZhdGUgYWN0aXZhdGVTdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0KCkge1xuICAgICAgICBpZiAoIXRoaXMucmVtb3RlKSB7XG4gICAgICAgICAgICAvLyBFeGNlcHRpb25FdmVudCBOT19TVFJFQU1fUExBWUlOR19FVkVOVCBpcyBvbmx5IGZvciBzdWJzY3JpYmVyc1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gVGhlIHRpbWVvdXQgaXMgYWxyZWFkeSBhY3RpdmF0ZWRcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBUcmlnZ2VyIEV4Y2VwdGlvbkV2ZW50IE5PX1NUUkVBTV9QTEFZSU5HX0VWRU5UIGlmIGFmdGVyIHRpbWVvdXQgdGhlcmUgaXMgbm8gJ2NhbnBsYXknIGV2ZW50XG4gICAgICAgIGNvbnN0IG1zVGltZW91dCA9IHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLm5vU3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCB8fCA0MDAwO1xuICAgICAgICB0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9XG4gICAgICAgICAgICAgICAgJ1N0cmVhbU1hbmFnZXIgb2YgU3RyZWFtICcgK1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAnICgnICtcbiAgICAgICAgICAgICAgICAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgK1xuICAgICAgICAgICAgICAgICcpIGRpZCBub3QgdHJpZ2dlciBcInN0cmVhbVBsYXlpbmdcIiBldmVudCBpbiAnICtcbiAgICAgICAgICAgICAgICBtc1RpbWVvdXQgK1xuICAgICAgICAgICAgICAgICcgbXMnO1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4obXNnKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbXG4gICAgICAgICAgICAgICAgbmV3IEV4Y2VwdGlvbkV2ZW50KHRoaXMuc3RyZWFtLnNlc3Npb24sIEV4Y2VwdGlvbkV2ZW50TmFtZS5OT19TVFJFQU1fUExBWUlOR19FVkVOVCwgKDxhbnk+dGhpcykgYXMgU3Vic2NyaWJlciwgbXNnKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0O1xuICAgICAgICB9LCBtc1RpbWVvdXQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZGVhY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQgYXMgYW55KTtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dDtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCBbW1Nlc3Npb24uc3Vic2NyaWJlXV0gbWV0aG9kXG4gKlxuICogU2VlIGF2YWlsYWJsZSBldmVudCBsaXN0ZW5lcnMgYXQgW1tTdHJlYW1NYW5hZ2VyRXZlbnRNYXBdXS5cbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXM7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtOiBTdHJlYW0sIHRhcmdFbDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKHN0cmVhbSwgdGFyZ0VsKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgYXVkaW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIGF1ZGlvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9BdWRpbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbVxuICAgICAgICAgICAgLmdldE1lZGlhU3RyZWFtKClcbiAgICAgICAgICAgIC5nZXRBdWRpb1RyYWNrcygpXG4gICAgICAgICAgICAuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgPSB2YWx1ZTtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCInU3Vic2NyaWJlcicgaGFzIFwiICsgKHZhbHVlID8gJ3N1YnNjcmliZWQgdG8nIDogJ3Vuc3Vic2NyaWJlZCBmcm9tJykgKyAnIGl0cyBhdWRpbyBzdHJlYW0nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIG9yIHVuc3Vic2NyaWJlIGZyb20gdGhlIHZpZGVvIHN0cmVhbSAoaWYgYXZhaWxhYmxlKS4gQ2FsbGluZyB0aGlzIG1ldGhvZCB0d2ljZSBpbiBhIHJvdyBwYXNzaW5nIHNhbWUgdmFsdWUgd2lsbCBoYXZlIG5vIGVmZmVjdFxuICAgICAqIEBwYXJhbSB2YWx1ZSBgdHJ1ZWAgdG8gc3Vic2NyaWJlIHRvIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5zdWJzY3JpYmUgZnJvbSBpdFxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvVmlkZW8odmFsdWU6IGJvb2xlYW4pOiBTdWJzY3JpYmVyIHtcbiAgICAgICAgdGhpcy5zdHJlYW1cbiAgICAgICAgICAgIC5nZXRNZWRpYVN0cmVhbSgpXG4gICAgICAgICAgICAuZ2V0VmlkZW9UcmFja3MoKVxuICAgICAgICAgICAgLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlID0gdmFsdWU7XG4gICAgICAgIGxvZ2dlci5pbmZvKFwiJ1N1YnNjcmliZXInIGhhcyBcIiArICh2YWx1ZSA/ICdzdWJzY3JpYmVkIHRvJyA6ICd1bnN1YnNjcmliZWQgZnJvbScpICsgJyBpdHMgdmlkZW8gc3RyZWFtJyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbSh0cmFjazogTWVkaWFTdHJlYW1UcmFjaywgdXBkYXRlTGFzdENvbnN0cmFpbnRzOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgICAgIGxldCByZW1vdmVkVHJhY2s6IE1lZGlhU3RyZWFtVHJhY2s7XG4gICAgICAgIGlmICh0cmFjay5raW5kID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICByZW1vdmVkVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZUxhc3RDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHMgPSB0cmFjay5nZXRDb25zdHJhaW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVtb3ZlZFRyYWNrID0gbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXTtcbiAgICAgICAgfVxuICAgICAgICBtZWRpYVN0cmVhbS5yZW1vdmVUcmFjayhyZW1vdmVkVHJhY2spO1xuICAgICAgICByZW1vdmVkVHJhY2suc3RvcCgpO1xuICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayh0cmFjayk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIExvY2FsUmVjb3JkZXJTdGF0ZSB7XG4gICAgUkVBRFkgPSAnUkVBRFknLFxuICAgIFJFQ09SRElORyA9ICdSRUNPUkRJTkcnLFxuICAgIFBBVVNFRCA9ICdQQVVTRUQnLFxuICAgIEZJTklTSEVEID0gJ0ZJTklTSEVEJ1xufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8qKlxuICogRGVmaW5lcyBwcm9wZXJ0eSBbW09wZW5WaWR1RXJyb3IubmFtZV1dXG4gKi9cbmV4cG9ydCBlbnVtIE9wZW5WaWR1RXJyb3JOYW1lIHtcbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIEJST1dTRVJfTk9UX1NVUFBPUlRFRCA9ICdCUk9XU0VSX05PVF9TVVBQT1JURUQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzbid0IGdyYW50ZWQgcGVybWlzc2lvbnMgdG8gdGhlIHJlcXVpcmVkIGlucHV0IGRldmljZSB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBUaGlzIGVycm9yIGNhbiBhbHNvIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGdyYW50ZWQgcGVybWlzc2lvbiB0byB1c2UgdGhlIGRldmljZXMgYnV0IGEgaGFyZHdhcmVcbiAgICAgKiBlcnJvciBvY2N1cnJlZCBhdCB0aGUgT1MsIGJyb3dzZXIgb3Igd2ViIHBhZ2UgbGV2ZWwsIHdoaWNoIHByZXZlbnRlZCBhY2Nlc3MgdG8gdGhlIGRldmljZS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgREVWSUNFX0FMUkVBRFlfSU5fVVNFID0gJ0RFVklDRV9BTFJFQURZX0lOX1VTRScsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdXNlciBoYXNuJ3QgZ3JhbnRlZCBwZXJtaXNzaW9ucyB0byBjYXB0dXJlIHNvbWUgZGVza3RvcCBzY3JlZW4gd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgU0NSRUVOX0NBUFRVUkVfREVOSUVEID0gJ1NDUkVFTl9DQVBUVVJFX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGRvZXMgbm90IHN1cHBvcnQgc2NyZWVuIHNoYXJpbmcuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9OT1RfSU5TVEFMTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlIHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgYnV0IGlzIGRpc2FibGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQgPSAnU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCcsXG5cbiAgICAvKipcbiAgICAgKiBObyB2aWRlbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gYXVkaW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2VdXSlcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIFRoZXJlIHdhcyBhbiB1bmtub3duIGVycm9yIHdoZW4gdHJ5aW5nIHRvIGFjY2VzcyB0aGUgc3BlY2lmaWVkIGF1ZGlvIGRldmljZVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBJTlBVVF9BVURJT19ERVZJQ0VfR0VORVJJQ19FUlJPUiA9ICdJTlBVVF9BVURJT19ERVZJQ0VfR0VORVJJQ19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV0gaGFzIGJlZW4gY2FsbGVkIHdpdGggcHJvcGVydGllcyBgdmlkZW9Tb3VyY2VgIGFuZCBgYXVkaW9Tb3VyY2VgIG9mXG4gICAgICogW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2YgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzXV0gc3VjaCBhcyBgZnJhbWVSYXRlYCBvciBgcmVzb2x1dGlvbmAgaXMgbm90IHN1cHBvcnRlZFxuICAgICAqIGJ5IHRoZSBpbnB1dCBkZXZpY2VzICh3aGVuZXZlciBpdCBpcyBwb3NzaWJsZSB0aGV5IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIHRvIHRoZSBtb3N0IHNpbWlsYXIgdmFsdWUpLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIFtbU2Vzc2lvbi5wdWJsaXNoXV0sXG4gICAgICogW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0sIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXSwgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgW1tTdHJlYW0ucmVtb3ZlRmlsdGVyXV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCA9ICdPUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGVyZSBpcyBubyBjb25uZWN0aW9uIHRvIHRoZSBTZXNzaW9uLiBUaGlzIGVycm9yIHdpbGwgYmUgdGhyb3duIHdoZW4gYW55IG1ldGhvZCByZXF1aXJpbmcgYSBjb25uZWN0aW9uIHRvXG4gICAgICogb3BlbnZpZHUtc2VydmVyIGlzIGNhbGxlZCBiZWZvcmUgc3VjY2Vzc2Z1bGx5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5jb25uZWN0XV1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9OT1RfQ09OTkVDVEVEID0gJ09QRU5WSURVX05PVF9DT05ORUNURUQnLFxuXG4gICAgLyoqXG4gICAgICogRXJyb3IgcmVsYXRlZCB0byBbVmlydHVhbCBCYWNrZ3JvdW5kXSgvZW4vc3RhYmxlL2FkdmFuY2VkLWZlYXR1cmVzL3ZpcnR1YWwtYmFja2dyb3VuZC8pXG4gICAgICovXG4gICAgVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SID0gJ1ZJUlRVQUxfQkFDS0dST1VORF9FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmljIGVycm9yXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWVseSBpZGVudGlmeWluZyBuYW1lIG9mIHRoZSBlcnJvclxuICAgICAqL1xuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuXG4gICAgLyoqXG4gICAgICogRnVsbCBkZXNjcmlwdGlvbiBvZiB0aGUgZXJyb3JcbiAgICAgKi9cbiAgICBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobmFtZTogT3BlblZpZHVFcnJvck5hbWUsIG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5leHBvcnQgZW51bSBUeXBlT2ZWaWRlbyB7XG4gICAgQ0FNRVJBID0gJ0NBTUVSQScsXG4gICAgU0NSRUVOID0gJ1NDUkVFTicsXG4gICAgQ1VTVE9NID0gJ0NVU1RPTScsXG4gICAgSVBDQU0gPSAnSVBDQU0nXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBIb3cgdGhlIHZpZGVvIHdpbGwgYmUgaW5zZXJ0ZWQgaW4gdGhlIERPTSBmb3IgUHVibGlzaGVycyBhbmQgU3Vic2NyaWJlcnMuIFNlZSBbW1B1Ymxpc2hlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dIGFuZCBbW1N1YnNjcmliZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXVxuICovXG5leHBvcnQgZW51bSBWaWRlb0luc2VydE1vZGUge1xuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFmdGVyIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgbmV4dCBzaWJsaW5nKVxuICAgICAqL1xuICAgIEFGVEVSID0gJ0FGVEVSJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBsYXN0IGNoaWxkIG9mIHRoZSB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIEFQUEVORCA9ICdBUFBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGJlZm9yZSB0aGUgdGFyZ2V0IGVsZW1lbnQgKGFzIHByZXZpb3VzIHNpYmxpbmcpXG4gICAgICovXG4gICAgQkVGT1JFID0gJ0JFRk9SRScsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYXMgZmlyc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUFJFUEVORCA9ICdQUkVQRU5EJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyByZXBsYWNlcyB0YXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIFJFUExBQ0UgPSAnUkVQTEFDRSdcbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0gW1tjb25uZWN0aW9uQ3JlYXRlZF1dXG4gKiAtIFtbY29ubmVjdGlvbkRlc3Ryb3llZF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogQ29ubmVjdGlvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRm9yIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudDpcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJub2RlQ3Jhc2hlZFwiOiBhIG5vZGUgaGFzIGNyYXNoZWQgaW4gdGhlIHNlcnZlciBzaWRlXG4gICAgICpcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgKi9cbiAgICByZWFzb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24sIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5cbi8qKlxuICogKipUaGlzIGZlYXR1cmUgaXMgcGFydCBvZiBPcGVuVmlkdSBQcm8gdGllcioqIDxhIGhyZWY9XCJodHRwczovL2RvY3Mub3BlbnZpZHUuaW8vZW4vc3RhYmxlL29wZW52aWR1LXByby9cIiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogcmdiKDAsIDEzNiwgMTcwKTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogYm9sZDsgcGFkZGluZzogMHB4IDVweDsgbWFyZ2luLXJpZ2h0OiA1cHg7IGJvcmRlci1yYWRpdXM6IDNweDsgZm9udC1zaXplOiAxM3B4OyBsaW5lLWhlaWdodDoyMXB4OyBmb250LWZhbWlseTogTW9udHNlcnJhdCwgc2Fucy1zZXJpZlwiPlBSTzwvYT5cbiAqXG4gKiBUcmlnZ2VyZWQgYnkgW1tjb25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkXV1cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ29ubmVjdGlvbiB3aG9zZSBwcm9wZXJ0eSBoYXMgY2hhbmdlZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInJvbGVcImAgb3IgYFwicmVjb3JkXCJgXG4gICAgICovXG4gICAgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBOZXcgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChhZnRlciBjaGFuZ2UsIGN1cnJlbnQgdmFsdWUpXG4gICAgICovXG4gICAgbmV3VmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIFByZXZpb3VzIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYmVmb3JlIGNoYW5nZSlcbiAgICAgKi9cbiAgICBvbGRWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsIG5ld1ZhbHVlOiBPYmplY3QsIG9sZFZhbHVlOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ2Nvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5jaGFuZ2VkUHJvcGVydHkgPSBjaGFuZ2VkUHJvcGVydHk7XG4gICAgICAgIHRoaXMubmV3VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGV2ZW50IGhhcyBhIGRlZmF1bHQgYmVoYXZpb3IgdGhhdCBtYXkgYmUgcHJldmVudGVkIGJ5IGNhbGxpbmcgW1tFdmVudC5wcmV2ZW50RGVmYXVsdF1dXG4gICAgICovXG4gICAgY2FuY2VsYWJsZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBldmVudC4gVGhpcyBpcyB0aGUgc2FtZSBzdHJpbmcgeW91IHBhc3MgYXMgZmlyc3QgcGFyYW1ldGVyIHdoZW4gY2FsbGluZyBtZXRob2QgYG9uKClgIG9mIGFueSBvYmplY3QgaW1wbGVtZW50aW5nIFtbRXZlbnREaXNwYXRjaGVyXV0gaW50ZXJmYWNlXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhc0JlZW5QcmV2ZW50ZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyIHwgRmlsdGVyLCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxhYmxlID0gY2FuY2VsYWJsZTtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZGVmYXVsdCBiZWFoaXZvdXIgb2YgdGhlIGV2ZW50IGhhcyBiZWVuIHByZXZlbnRlZCBvciBub3QuIENhbGwgW1tFdmVudC5wcmV2ZW50RGVmYXVsdF1dIHRvIHByZXZlbnQgaXRcbiAgICAgKi9cbiAgICBpc0RlZmF1bHRQcmV2ZW50ZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc0JlZW5QcmV2ZW50ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJldmVudHMgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIGV2ZW50LiBUaGUgZm9sbG93aW5nIGV2ZW50cyBoYXZlIGEgZGVmYXVsdCBiZWhhdmlvcjpcbiAgICAgKlxuICAgICAqIC0gYHNlc3Npb25EaXNjb25uZWN0ZWRgOiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dIG9iamVjdCwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIGxlYXZpbmcgcGFydGljaXBhbnQgZnJvbSBldmVyeSBTdWJzY3JpYmVyIG9iamVjdCBvZiB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAtIGBzdHJlYW1EZXN0cm95ZWRgOlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IGEgW1tQdWJsaXNoZXJdXSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgYnkgY2FsbGluZyBbW1B1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnRdXSkuIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiAgIC0gSWYgZGlzcGF0Y2hlZCBieSBbW1Nlc3Npb25dXSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBvclxuICAgICAqIGJ5IGNhbGxpbmcgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRoaXMuY2FsbERlZmF1bHRCZWhhdmlvciA9ICgpID0+IHt9O1xuICAgICAgICB0aGlzLmhhc0JlZW5QcmV2ZW50ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhYnN0cmFjdCBjYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdWJzY3JpYmVyJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5cbi8qKlxuICogRGVmaW5lcyBwcm9wZXJ0eSBbW0V4Y2VwdGlvbkV2ZW50Lm5hbWVdXVxuICovXG5leHBvcnQgZW51bSBFeGNlcHRpb25FdmVudE5hbWUge1xuICAgIC8qKlxuICAgICAqIFRoZXJlIHdhcyBhbiB1bmV4cGVjdGVkIGVycm9yIG9uIHRoZSBzZXJ2ZXItc2lkZSBwcm9jZXNzaW5nIGFuIElDRSBjYW5kaWRhdGUgZ2VuZXJhdGVkIGFuZCBzZW50IGJ5IHRoZSBjbGllbnQtc2lkZS5cbiAgICAgKlxuICAgICAqIFtbRXhjZXB0aW9uRXZlbnRdXSBvYmplY3RzIHdpdGggdGhpcyBbW0V4Y2VwdGlvbkV2ZW50Lm5hbWVdXSB3aWxsIGhhdmUgYXMgW1tFeGNlcHRpb25FdmVudC5vcmlnaW5dXSBwcm9wZXJ0eSBhIFtbU2Vzc2lvbl1dIG9iamVjdC5cbiAgICAgKi9cbiAgICBJQ0VfQ0FORElEQVRFX0VSUk9SID0gJ0lDRV9DQU5ESURBVEVfRVJST1InLFxuXG4gICAgLyoqXG4gICAgICogVGhlIFtJQ0UgY29ubmVjdGlvbiBzdGF0ZV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JUQ1BlZXJDb25uZWN0aW9uL2ljZUNvbm5lY3Rpb25TdGF0ZSlcbiAgICAgKiBvZiBhbiBbUlRDUGVlckNvbm5lY3Rpb25dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SVENQZWVyQ29ubmVjdGlvbikgcmVhY2hlZCBgZmFpbGVkYCBzdGF0dXMuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIGEgdGVybWluYWwgZXJyb3IgdGhhdCB3b24ndCBoYXZlIGFueSBraW5kIG9mIHBvc3NpYmxlIHJlY292ZXJ5LiBJZiB0aGUgY2xpZW50IGlzIHN0aWxsIGNvbm5lY3RlZCB0byBPcGVuVmlkdSBTZXJ2ZXIsXG4gICAgICogdGhlbiBhbiBhdXRvbWF0aWMgcmVjb25uZWN0aW9uIHByb2Nlc3Mgb2YgdGhlIG1lZGlhIHN0cmVhbSBpcyBpbW1lZGlhdGVseSBwZXJmb3JtZWQuIElmIHRoZSBJQ0UgY29ubmVjdGlvbiBoYXMgYnJva2VuIGR1ZSB0b1xuICAgICAqIGEgdG90YWwgbmV0d29yayBkcm9wLCB0aGVuIG5vIGF1dG9tYXRpYyByZWNvbm5lY3Rpb24gcHJvY2VzcyB3aWxsIGJlIHBvc3NpYmxlLlxuICAgICAqXG4gICAgICogW1tFeGNlcHRpb25FdmVudF1dIG9iamVjdHMgd2l0aCB0aGlzIFtbRXhjZXB0aW9uRXZlbnQubmFtZV1dIHdpbGwgaGF2ZSBhcyBbW0V4Y2VwdGlvbkV2ZW50Lm9yaWdpbl1dIHByb3BlcnR5IGEgW1tTdHJlYW1dXSBvYmplY3QuXG4gICAgICovXG4gICAgSUNFX0NPTk5FQ1RJT05fRkFJTEVEID0gJ0lDRV9DT05ORUNUSU9OX0ZBSUxFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgW0lDRSBjb25uZWN0aW9uIHN0YXRlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24vaWNlQ29ubmVjdGlvblN0YXRlKVxuICAgICAqIG9mIGFuIFtSVENQZWVyQ29ubmVjdGlvbl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JUQ1BlZXJDb25uZWN0aW9uKSByZWFjaGVkIGBkaXNjb25uZWN0ZWRgIHN0YXR1cy5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgbm90IGEgdGVybWluYWwgZXJyb3IsIGFuZCBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIElDRSBjb25uZWN0aW9uIHRvIGJlIHJlY29ubmVjdGVkLiBJZiB0aGUgY2xpZW50IGlzIHN0aWxsIGNvbm5lY3RlZCB0b1xuICAgICAqIE9wZW5WaWR1IFNlcnZlciBhbmQgYWZ0ZXIgY2VydGFpbiB0aW1lb3V0IHRoZSBJQ0UgY29ubmVjdGlvbiBoYXMgbm90IHJlYWNoZWQgYSBzdWNjZXNzIG9yIHRlcm1pbmFsIHN0YXR1cywgdGhlbiBhbiBhdXRvbWF0aWNcbiAgICAgKiByZWNvbm5lY3Rpb24gcHJvY2VzcyBvZiB0aGUgbWVkaWEgc3RyZWFtIGlzIHBlcmZvcm1lZC4gSWYgdGhlIElDRSBjb25uZWN0aW9uIGhhcyBicm9rZW4gZHVlIHRvIGEgdG90YWwgbmV0d29yayBkcm9wLCB0aGVuIG5vXG4gICAgICogYXV0b21hdGljIHJlY29ubmVjdGlvbiBwcm9jZXNzIHdpbGwgYmUgcG9zc2libGUuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGN1c3RvbWl6ZSB0aGUgdGltZW91dCBmb3IgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0IHdpdGggcHJvcGVydHkgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VDb25uZWN0aW9uRGlzY29ubmVjdGVkRXhjZXB0aW9uVGltZW91dF1dLFxuICAgICAqIHdoaWNoIGJ5IGRlZmF1bHQgaXMgNDAwMCBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBbW0V4Y2VwdGlvbkV2ZW50XV0gb2JqZWN0cyB3aXRoIHRoaXMgW1tFeGNlcHRpb25FdmVudC5uYW1lXV0gd2lsbCBoYXZlIGFzIFtbRXhjZXB0aW9uRXZlbnQub3JpZ2luXV0gcHJvcGVydHkgYSBbW1N0cmVhbV1dIG9iamVjdC5cbiAgICAgKi9cbiAgICBJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQgPSAnSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEJyxcblxuICAgIC8qKlxuICAgICAqIEEgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IGhhcyBub3QgZmlyZWQgZXZlbnQgYHN0cmVhbVBsYXlpbmdgIGFmdGVyIGNlcnRhaW4gdGltZW91dC4gYHN0cmVhbVBsYXlpbmdgIGV2ZW50IGJlbG9uZ3MgdG8gW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXVxuICAgICAqIGNhdGVnb3J5LiBJdCB3cmFwcyBXZWIgQVBJIG5hdGl2ZSBldmVudCBbY2FucGxheV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxNZWRpYUVsZW1lbnQvY2FucGxheV9ldmVudCkuXG4gICAgICpcbiAgICAgKiBPcGVuVmlkdSBCcm93c2VyIGNhbiB0YWtlIGNhcmUgb2YgdGhlIHZpZGVvIHBsYXllcnMgKHNlZSBbaGVyZV0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKSxcbiAgICAgKiBvciB5b3UgY2FuIHRha2UgY2FyZSBvZiB2aWRlbyBwbGF5ZXJzIG9uIHlvdXIgb3duIChzZWUgW2hlcmVdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRWl0aGVyIHdheSwgd2hlbmV2ZXIgYSBbW1N1YnNjcmliZXJdXSBvYmplY3QgaXMgY29tbWFuZGVkIHRvIGF0dGFjaCBpdHMgW1tTdHJlYW1dXSB0byBhIHZpZGVvIGVsZW1lbnQsIGl0IGlzIHN1cHBvc2VkIHRvIGZpcmUgYHN0cmVhbVBsYXlpbmdgXG4gICAgICogZXZlbnQgc2hvcnRseSBhZnRlci4gSWYgaXQgZG9lcyBub3QsIHRoZW4gd2UgY2FuIHNhZmVseSBhc3N1bWUgdGhhdCBzb21ldGhpbmcgd3JvbmcgaGFzIGhhcHBlbmVkIHdoaWxlIHBsYXlpbmcgdGhlIHJlbW90ZSB2aWRlbyBhbmQgdGhlXG4gICAgICogYXBwbGljYXRpb24gbWF5IGJlIG5vdGlmaWVkIHRocm91Z2ggdGhpcyBzcGVjaWZpYyBFeGNlcHRpb25FdmVudC5cbiAgICAgKlxuICAgICAqIFRoZSB0aW1lb3V0IGNhbiBiZSBjb25maWd1cmVkIHdpdGggcHJvcGVydHkgW1tPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbi5ub1N0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXRdXS4gQnkgZGVmYXVsdCBpdCBpcyA0MDAwIG1pbGxpc2Vjb25kcy5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMganVzdCBhbiBpbmZvcm1hdGl2ZSBleGNlcHRpb24uIEl0IG9ubHkgbWVhbnMgdGhhdCBhIHJlbW90ZSBTdHJlYW0gdGhhdCBpcyBzdXBwb3NlZCB0byBiZSBwbGF5aW5nIGJ5IGEgdmlkZW8gcGxheWVyIGhhcyBub3QgZG9uZSBzb1xuICAgICAqIGluIGEgcmVhc29uYWJsZSB0aW1lLiBCdXQgdGhlIGxhY2sgb2YgdGhlIGV2ZW50IGNhbiBiZSBjYXVzZWQgYnkgbXVsdGlwbGUgcmVhc29ucy4gSWYgYSBTdWJzY3JpYmVyIGlzIG5vdCBwbGF5aW5nIGl0cyBTdHJlYW0sIHRoZSBvcmlnaW5cbiAgICAgKiBvZiB0aGUgcHJvYmxlbSBjb3VsZCBiZSBsb2NhdGVkIGF0IHRoZSBQdWJsaXNoZXIgc2lkZS4gT3IgbWF5IGJlIGNhdXNlZCBieSBhIHRyYW5zaWVudCBuZXR3b3JrIHByb2JsZW0uIEJ1dCBpdCBhbHNvIGNvdWxkIGJlIGEgcHJvYmxlbSB3aXRoXG4gICAgICogYXV0b3BsYXkgcGVybWlzc2lvbnMuIEJvdHRvbSBsaW5lLCB0aGUgY2F1c2UgY2FuIGJlIHZlcnkgdmFyaWVkLCBhbmQgZGVwZW5kaW5nIG9uIHRoZSBhcHBsaWNhdGlvbiB0aGUgbGFjayBvZiB0aGUgZXZlbnQgY291bGQgZXZlbiBiZSBleHBlY3RlZC5cbiAgICAgKlxuICAgICAqIFtbRXhjZXB0aW9uRXZlbnRdXSBvYmplY3RzIHdpdGggdGhpcyBbW0V4Y2VwdGlvbkV2ZW50Lm5hbWVdXSB3aWxsIGhhdmUgYXMgW1tFeGNlcHRpb25FdmVudC5vcmlnaW5dXSBwcm9wZXJ0eSBhIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAgICAgKi9cbiAgICBOT19TVFJFQU1fUExBWUlOR19FVkVOVCA9ICdOT19TVFJFQU1fUExBWUlOR19FVkVOVCdcbn1cblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgW1tTZXNzaW9uRXZlbnRNYXAuZXhjZXB0aW9uXV1cbiAqL1xuZXhwb3J0IGNsYXNzIEV4Y2VwdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGV4Y2VwdGlvblxuICAgICAqL1xuICAgIG5hbWU6IEV4Y2VwdGlvbkV2ZW50TmFtZTtcblxuICAgIC8qKlxuICAgICAqIE9iamVjdCBhZmZlY3RlZCBieSB0aGUgZXhjZXB0aW9uLiBEZXBlbmRpbmcgb24gdGhlIFtbRXhjZXB0aW9uRXZlbnQubmFtZV1dIHByb3BlcnR5OlxuICAgICAqIC0gW1tTZXNzaW9uXV06IGBJQ0VfQ0FORElEQVRFX0VSUk9SYFxuICAgICAqIC0gW1tTdHJlYW1dXTogYElDRV9DT05ORUNUSU9OX0ZBSUxFRGAsIGBJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURURgXG4gICAgICogLSBbW1N1YnNjcmliZXJdXTogYE5PX1NUUkVBTV9QTEFZSU5HX0VWRU5UYFxuICAgICAqL1xuICAgIG9yaWdpbjogU2Vzc2lvbiB8IFN0cmVhbSB8IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBJbmZvcm1hdGl2ZSBkZXNjcmlwdGlvbiBvZiB0aGUgZXhjZXB0aW9uXG4gICAgICovXG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQW55IGV4dHJhIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgdG8gdGhlIGV4Y2VwdGlvblxuICAgICAqL1xuICAgIGRhdGE/OiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgbmFtZTogRXhjZXB0aW9uRXZlbnROYW1lLCBvcmlnaW46IFNlc3Npb24gfCBTdHJlYW0gfCBTdWJzY3JpYmVyLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHNlc3Npb24sICdleGNlcHRpb24nKTtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5vcmlnaW4gPSBvcmlnaW47XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlcnkgZXZlbnQgZGlzcGF0Y2hlZCBieSBhdWRpby92aWRlbyBzdHJlYW0gZmlsdGVycy4gWW91IGNhbiBzdWJzY3JpYmUgdG8gZmlsdGVyIGV2ZW50cyBieSBjYWxsaW5nIFtbRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXJdXVxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgW1tuZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgbmV0d29yayBxdWFsaXR5IGxldmVsXG4gICAgICovXG4gICAgbmV3VmFsdWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIE9sZCB2YWx1ZSBvZiB0aGUgbmV0d29yayBxdWFsaXR5IGxldmVsXG4gICAgICovXG4gICAgb2xkVmFsdWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIENvbm5lY3Rpb24gZm9yIHdob20gdGhlIG5ldHdvcmsgcXVhbGl0eSBsZXZlbCBjaGFuZ2VkXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIG5ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXIsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ25ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMubmV3VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0gYHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjcHVibGlzaGVyU3RhcnRTcGVha2luZykgYW5kIFtTdHJlYW1NYW5hZ2VyXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU3RyZWFtTWFuYWdlckV2ZW50TWFwLmh0bWwjcHVibGlzaGVyU3RhcnRTcGVha2luZykgb2JqZWN0cylcbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgKGF2YWlsYWJsZSBmb3IgW1Nlc3Npb25dKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TZXNzaW9uRXZlbnRNYXAuaHRtbCNwdWJsaXNoZXJTdG9wU3BlYWtpbmcpIGFuZCBbU3RyZWFtTWFuYWdlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1N0cmVhbU1hbmFnZXJFdmVudE1hcC5odG1sI3B1Ymxpc2hlclN0b3BTcGVha2luZykgb2JqZWN0cylcbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHN0YXJ0ZWQgb3Igc3RvcHBlZCBzcGVha2luZ1xuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3RyZWFtSWQgb2YgdGhlIFN0cmVhbSBhZmZlY3RlZCBieSB0aGUgc3BlYWtpbmcgZXZlbnRcbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0gW1tyZWNvcmRpbmdTdGFydGVkXV1cbiAqIC0gW1tyZWNvcmRpbmdTdG9wcGVkXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFJlY29yZGluZ0V2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSBbW2lkXV1cbiAgICAgKi9cbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdyZWNvcmRpbmdTdG9wcGVkJyBldmVudDpcbiAgICAgKiAtIFwicmVjb3JkaW5nU3RvcHBlZEJ5U2VydmVyXCI6IHRoZSByZWNvcmRpbmcgaGFzIGJlZW4gZ3JhY2VmdWxseSBzdG9wcGVkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJhdXRvbWF0aWNTdG9wXCI6IHNlZSBbQXV0b21hdGljIHN0b3Agb2YgcmVjb3JkaW5nc10oL2VuL3N0YWJsZS9hZHZhbmNlZC1mZWF0dXJlcy9yZWNvcmRpbmcvI2F1dG9tYXRpYy1zdG9wLW9mLXJlY29yZGluZ3MpXG4gICAgICogLSBcIm5vZGVDcmFzaGVkXCI6IGEgbm9kZSBoYXMgY3Jhc2hlZCBpbiB0aGUgc2VydmVyIHNpZGVcbiAgICAgKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RhcnRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBpZiAobmFtZSAhPT0gaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgW1tzZXNzaW9uRGlzY29ubmVjdGVkXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiB5b3UgaGF2ZSBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwibmV0d29ya0Rpc2Nvbm5lY3RcIjogeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWQuIEJlZm9yZSBhIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCB3aXRoIHRoaXMgcmVhc29uIGlzIHRyaWdnZXJlZCxcbiAgICAgKiAgICAgIFNlc3Npb24gb2JqZWN0IHdpbGwgYWx3YXlzIGhhdmUgcHJldmlvdXNseSBkaXNwYXRjaGVkIGEgYHJlY29ubmVjdGluZ2AgZXZlbnQuIElmIHRoZSByZWNvbm5lY3Rpb24gcHJvY2VzcyBzdWNjZWVkcyxcbiAgICAgKiAgICAgIFNlc3Npb24gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgcmVjb25uZWN0ZWRgIGV2ZW50LiBJZiBpdCBmYWlscywgU2Vzc2lvbiBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudFxuICAgICAqICAgICAgd2l0aCByZWFzb24gXCJuZXR3b3JrRGlzY29ubmVjdFwiXG4gICAgICogLSBcIm5vZGVDcmFzaGVkXCI6IGEgbm9kZSBoYXMgY3Jhc2hlZCBpbiB0aGUgc2VydmVyIHNpZGUuIFlvdSBjYW4gdXNlIHRoaXMgcmVhc29uIHRvIGFzayB5b3VyIGFwcGxpY2F0aW9uJ3MgYmFja2VuZCB0byByZWNvbm5lY3RcbiAgICAgKiB0byBhIG5ldyBzZXNzaW9uIHRvIHJlcGxhY2UgdGhlIGNyYXNoZWQgb25lXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCByZWFzb246IHN0cmluZykge1xuICAgICAgICBzdXBlcih0cnVlLCB0YXJnZXQsICdzZXNzaW9uRGlzY29ubmVjdGVkJyk7XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBsb2dnZXIuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcblxuICAgICAgICBjb25zdCBzZXNzaW9uID0gPFNlc3Npb24+dGhpcy50YXJnZXQ7XG5cbiAgICAgICAgLy8gRGlzcG9zZSBhbmQgZGVsZXRlIGFsbCByZW1vdGUgQ29ubmVjdGlvbnNcbiAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQgPSByZW1vdGVDb25uZWN0aW9uLmNvbm5lY3Rpb25JZDtcbiAgICAgICAgICAgIGlmICghIXNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LnN0cmVhbSkge1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LnN0cmVhbSEuZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5zdHJlYW0hLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5zdHJlYW0hLnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uc3RyZWFtIS5zdHJlYW1NYW5hZ2VyLnJlbW92ZUFsbFZpZGVvcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1JZCA9IHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LnN0cmVhbT8uc3RyZWFtSWQ7XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5kZWxldGUoc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmRlbGV0ZShjb25uZWN0aW9uSWQpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgW1tTZXNzaW9uRXZlbnRNYXAuc2lnbmFsXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25hbEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHNpZ25hbC4gSXQgaXMgc3RyaW5nIGBcInNpZ25hbFwiYCBmb3IgdGhvc2Ugc2lnbmFscyBzZW50IHdpdGggbm8gW1tTaWduYWxPcHRpb25zLnR5cGVdXSBwcm9wZXJ0eSwgYW5kIGBcInNpZ25hbDp0eXBlXCJgIGlmIHdhcyBzZW50IHdpdGggYVxuICAgICAqIHZhbGlkIFtbU2lnbmFsT3B0aW9ucy50eXBlXV0gcHJvcGVydHkuXG4gICAgICpcbiAgICAgKiBUaGUgY2xpZW50IG11c3QgYmUgc3BlY2lmaWNhbGx5IHN1YnNjcmliZWQgdG8gYFNlc3Npb24ub24oJ3NpZ25hbDp0eXBlJywgZnVuY3Rpb24oc2lnbmFsRXZlbnQpIHsuLi59KWAgdG8gdHJpZ2dlciB0aGF0IHR5cGUgb2Ygc2lnbmFsLlxuICAgICAqXG4gICAgICogU3Vic2NyaWJpbmcgdG8gYFNlc3Npb24ub24oJ3NpZ25hbCcsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHdpbGwgdHJpZ2dlciBhbGwgc2lnbmFscywgbm8gbWF0dGVyIHRoZWlyIHR5cGUuXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1lc3NhZ2Ugb2YgdGhlIHNpZ25hbCAoY2FuIGJlIGVtcHR5KVxuICAgICAqL1xuICAgIGRhdGE/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRoYXQgc2VudCB0aGUgc2lnbmFsLiBUaGlzIHByb3BlcnR5IGlzIHVuZGVmaW5lZCBpZiB0aGUgc2lnbmFsXG4gICAgICogd2FzIGRpcmVjdGx5IGdlbmVyYXRlZCBieSB0aGUgYXBwbGljYXRpb24gc2VydmVyIChub3QgYnkgb3RoZXIgY2xpZW50KVxuICAgICAqL1xuICAgIGZyb20/OiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZT86IHN0cmluZywgZGF0YT86IHN0cmluZywgZnJvbT86IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ3NpZ25hbCcpO1xuICAgICAgICBpZiAoISF0eXBlKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSAnc2lnbmFsOicgKyB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBQdWJsaXNoZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9QdWJsaXNoZXInO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjc3RyZWFtQ3JlYXRlZCkgYW5kIFtQdWJsaXNoZXJdKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9QdWJsaXNoZXJFdmVudE1hcC5odG1sI3N0cmVhbUNyZWF0ZWQpIG9iamVjdHMpXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjc3RyZWFtRGVzdHJveWVkKSBhbmQgW1B1Ymxpc2hlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1B1Ymxpc2hlckV2ZW50TWFwLmh0bWwjc3RyZWFtRGVzdHJveWVkKSBvYmplY3RzKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJub2RlQ3Jhc2hlZFwiOiBhIG5vZGUgaGFzIGNyYXNoZWQgaW4gdGhlIHNlcnZlciBzaWRlXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFB1Ymxpc2hlciwgdHlwZTogc3RyaW5nLCBzdHJlYW06IFN0cmVhbSwgcmVhc29uOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1B1Ymxpc2hlcidcIik7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCgoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkuc2NyZWVuU2hhcmVSZXNpemVJbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVJlYWR5VG9QdWJsaXNoID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAvLyBEZWxldGUgUHVibGlzaGVyIG9iamVjdCBmcm9tIE9wZW5WaWR1IHB1Ymxpc2hlcnMgYXJyYXlcbiAgICAgICAgICAgICAgICBjb25zdCBvcGVudmlkdVB1Ymxpc2hlcnMgPSAoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkub3BlbnZpZHUucHVibGlzaGVycztcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wZW52aWR1UHVibGlzaGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAob3BlbnZpZHVQdWJsaXNoZXJzW2ldID09PSA8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkLmRlbGV0ZSh0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldCh0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5yZW1vdGVPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ucmVtb3RlT3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnk6XG4gKiAtIFtbc3RyZWFtUGxheWluZ11dXG4gKiAtIFtbc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2VdXVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtTWFuYWdlckV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIEZvciBgc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2VgIGV2ZW50OlxuICAgICAqIC0gYHtuZXdWYWx1ZTogbnVtYmVyLCBvbGRWYWx1ZTogbnVtYmVyfWA6IG5ldyBhbmQgb2xkIGF1ZGlvIHZvbHVtZSB2YWx1ZXMuIFRoZXNlIHZhbHVlcyBhcmUgYmV0d2VlbiAtMTAwIChzaWxlbmNlKSBhbmQgMCAobG91ZGVzdCBwb3NzaWJsZSB2b2x1bWUpLlxuICAgICAqIFRoZXkgYXJlIG5vdCBleGFjdCBhbmQgZGVwZW5kIG9uIGhvdyB0aGUgYnJvd3NlciBpcyBtYW5hZ2luZyB0aGUgYXVkaW8gdHJhY2ssIGJ1dCAtMTAwIGFuZCAwIGNhbiBiZSB0YWtlbiBhcyBsaW1pdCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBGb3IgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIHZhbHVlOiBPYmplY3QgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5IGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjc3RyZWFtUHJvcGVydHlDaGFuZ2VkKSBhbmQgW1N0cmVhbU1hbmFnZXJdKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TdHJlYW1NYW5hZ2VyRXZlbnRNYXAuaHRtbCNzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQpIG9iamVjdHMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLiBZb3UgY2FuIGFsd2F5cyBpZGVudGlmeSB0aGUgdXNlciBwdWJsaXNoaW5nIHRoZSBjaGFuZ2VkIHN0cmVhbSBieSBjb25zdWx0aW5nIHByb3BlcnR5IFtbU3RyZWFtLmNvbm5lY3Rpb25dXVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgLCBgXCJzY3JlZW5SZXNpemVkXCJgIG9yIGBcInRyYWNrUmVwbGFjZWRcImBcbiAgICAgKiAtIEZvciBgZmlsdGVyYDogYFwiYXBwbHlGaWx0ZXJcImAsIGBcImV4ZWNGaWx0ZXJNZXRob2RcImAgb3IgYFwicmVtb3ZlRmlsdGVyXCJgXG4gICAgICovXG4gICAgcmVhc29uOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBOZXcgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChhZnRlciBjaGFuZ2UsIGN1cnJlbnQgdmFsdWUpXG4gICAgICovXG4gICAgbmV3VmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIFByZXZpb3VzIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYmVmb3JlIGNoYW5nZSlcbiAgICAgKi9cbiAgICBvbGRWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLFxuICAgICAgICBzdHJlYW06IFN0cmVhbSxcbiAgICAgICAgY2hhbmdlZFByb3BlcnR5OiBzdHJpbmcsXG4gICAgICAgIG5ld1ZhbHVlOiBPYmplY3QsXG4gICAgICAgIG9sZFZhbHVlOiBPYmplY3QsXG4gICAgICAgIHJlYXNvbjogc3RyaW5nXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5OlxuICogLSBbW3ZpZGVvRWxlbWVudENyZWF0ZWRdXVxuICogLSBbW3ZpZGVvRWxlbWVudERlc3Ryb3llZF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBWaWRlb0VsZW1lbnRFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCJmdW5jdGlvbiBNYXBwZXIoKSB7XG4gICAgdmFyIHNvdXJjZXMgPSB7fTtcblxuICAgIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlcykge1xuICAgICAgICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgICAgICAgZm9yICh2YXIga2V5MiBpbiBzb3VyY2UpIGNhbGxiYWNrKHNvdXJjZVtrZXkyXSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5nZXQgPSBmdW5jdGlvbiAoaWQsIHNvdXJjZSkge1xuICAgICAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgICAgICBpZiAoaWRzID09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICByZXR1cm4gaWRzW2lkXTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZW1vdmUgPSBmdW5jdGlvbiAoaWQsIHNvdXJjZSkge1xuICAgICAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgICAgICBpZiAoaWRzID09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICAgICAgZm9yICh2YXIgaSBpbiBpZHMpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gICAgfTtcblxuICAgIHRoaXMuc2V0ID0gZnVuY3Rpb24gKHZhbHVlLCBpZCwgc291cmNlKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgICAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgICAgICBpZiAoaWRzID09IHVuZGVmaW5lZCkgc291cmNlc1tzb3VyY2VdID0gaWRzID0ge307XG5cbiAgICAgICAgaWRzW2lkXSA9IHZhbHVlO1xuICAgIH07XG59XG5cbk1hcHBlci5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24gKGlkLCBzb3VyY2UpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgICBpZiAodmFsdWUgPT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgPSBKc29uUnBjQ2xpZW50O1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vJyk7XG52YXIgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0cy93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG52YXIgT3BlblZpZHVMb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInKS5PcGVuVmlkdUxvZ2dlcjtcblxuRGF0ZS5ub3cgPVxuICAgIERhdGUubm93IHx8XG4gICAgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gK25ldyBEYXRlKCk7XG4gICAgfTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogPHByZT5cbiAqIHdzIDoge1xuICogXHR1cmkgOiBVUkkgdG8gY29ubnRlY3QgdG8sXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCAncHVzaCcpO1xuICAgIH07XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCctLS0tLS0tLS0gT05SRUNPTk5FQ1RJTkcgLS0tLS0tLS0tLS0nKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ1dlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RvcFBpbmcoKTtcblxuICAgICAgICBzdGF0dXMgPSBSRUNPTk5FQ1RJTkc7XG4gICAgICAgIGlmIChvbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJy0tLS0tLS0tLSBPTlJFQ09OTkVDVEVEIC0tLS0tLS0tLS0tJyk7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyA9IENPTk5FQ1RFRDtcblxuICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG5cbiAgICAgICAgaWYgKG9ucmVjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCctLS0tLS0tLS0gT05DT05ORUNURUQgLS0tLS0tLS0tLS0nKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ1dlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyA9IENPTk5FQ1RFRDtcblxuICAgICAgICBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgICAgICB1c2VQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCctLS0tLS0tLS0gT05FUlJPUiAtLS0tLS0tLS0tLScpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgd3MgPSBuZXcgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbih3c0NvbmZpZyk7XG5cbiAgICBMb2dnZXIuZGVidWcoJ0Nvbm5lY3Rpbmcgd2Vic29ja2V0IHRvIFVSSTogJyArIHdzQ29uZmlnLnVyaSk7XG5cbiAgICB2YXIgcnBjQnVpbGRlck9wdGlvbnMgPSB7XG4gICAgICAgIHJlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMucmVxdWVzdFRpbWVvdXQsXG4gICAgICAgIHBpbmdfcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5oZWFydGJlYXRSZXF1ZXN0VGltZW91dFxuICAgIH07XG5cbiAgICB2YXIgcnBjID0gbmV3IFJwY0J1aWxkZXIoUnBjQnVpbGRlci5wYWNrZXJzLkpzb25SUEMsIHJwY0J1aWxkZXJPcHRpb25zLCB3cywgZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZWNlaXZlZCByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgaWYgKGZ1bmMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignTWV0aG9kICcgKyByZXF1ZXN0Lm1ldGhvZCArICcgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50Jyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgcnBjLmVuY29kZShtZXRob2QsIHBhcmFtcywgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICdFUlJPUjonICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIGluIFJlcXVlc3Q6IG1ldGhvZDonICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgcGFyYW1zOicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgcmVxdWVzdDonICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ0VSUk9SIERBVEE6JyArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJ25vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSAnICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gKyAnKScpO1xuICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gcGluZ05leHROdW07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2VuZFBpbmcoKSB7XG4gICAgICAgIGlmIChlbmFibGVkUGluZ3MpIHtcbiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBudWxsO1xuICAgICAgICAgICAgaWYgKHBpbmdOZXh0TnVtID09IDAgfHwgcGluZ05leHROdW0gPT0gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0IHx8IFBJTkdfSU5URVJWQUxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGluZ05leHROdW0rKztcblxuICAgICAgICAgICAgc2VsZi5zZW5kKFxuICAgICAgICAgICAgICAgICdwaW5nJyxcbiAgICAgICAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdFcnJvciBpbiBwaW5nIHJlcXVlc3QgIycgKyBwaW5nTnVtICsgJyAoJyArIGVycm9yLm1lc3NhZ2UgKyAnKScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwaW5nTnVtID4gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1NlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICMnICsgcGluZ051bSArICcuIFJlY29ubmVjdGluZy4uLiAnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkocGluZ05leHROdW0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdUcnlpbmcgdG8gc2VuZCBwaW5nLCBidXQgcGluZyBpcyBub3QgZW5hYmxlZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1N0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpJyk7XG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdDbG9zaW5nICB3aXRoIGNvZGU6ICcgKyBjb2RlICsgJyBiZWNhdXNlOiAnICsgcmVhc29uKTtcbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnQ2xlYXJpbmcgcGluZyBpbnRlcnZhbCcpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVzZXRQaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IDA7XG4gICAgICAgIHVzZVBpbmcoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5nZXRSZWFkeVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gd3MuZ2V0UmVhZHlTdGF0ZSgpO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5leHBvcnRzLldlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgT3BlblZpZHVMb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInKS5PcGVuVmlkdUxvZ2dlcjtcbnZhciBMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcbnVyaSA6IHdzVXJpLFxub25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxub25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG5vbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbm9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcbn07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcbiAgICB2YXIgY2xvc2luZyA9IGZhbHNlO1xuICAgIHZhciByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyO1xuICAgIHZhciB3c1VyaSA9IGNvbmZpZy51cmk7XG4gICAgdmFyIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG5cbiAgICB3cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygnV2ViU29ja2V0IGNvbm5lY3RlZCB0byAnICsgd3NVcmkpO1xuICAgICAgICBpZiAoY29uZmlnLm9uY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBjb25maWcub25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgIExvZ2dlci5lcnJvcignQ291bGQgbm90IGNvbm5lY3QgdG8gJyArIHdzVXJpICsgJyAoaW52b2tpbmcgb25lcnJvciBpZiBkZWZpbmVkKScsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcuaXNtYXN0ZXJub2RlY3Jhc2hlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignTWFzdGVyIE5vZGUgaGFzIGNyYXNoZWQuIFN0b3BwaW5nIHJlY29ubmVjdGlvbiBwcm9jZXNzJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVkbHkuIFJlY29ubmVjdGluZy4uLicpO1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3QoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0Jyk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG5cbiAgICBmdW5jdGlvbiByZWNvbm5lY3QobWF4UmV0cmllcywgbnVtUmV0cmllcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoJ3JlY29ubmVjdCAoYXR0ZW1wdCAjJyArIG51bVJldHJpZXMgKyAnLCBtYXg9JyArIG1heFJldHJpZXMgKyAnKScpO1xuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKCdUcnlpbmcgdG8gcmVjb25uZWN0IHdoZW4gYWxyZWFkeSByZWNvbm5lY3RpbmcuLi4gSWdub3JpbmcgdGhpcyByZWNvbm5lY3Rpb24uJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlY29ubmVjdEF1eChtYXhSZXRyaWVzLCBudW1SZXRyaWVzKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRSZWNvbm5lY3Rpb25RdWVyeVBhcmFtc0lmTWlzc2luZyh1cmlTdHJpbmcpIHtcbiAgICAgICAgdmFyIHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMobmV3IFVSTCh1cmlTdHJpbmcpLnNlYXJjaCk7XG4gICAgICAgIGlmICghc2VhcmNoUGFyYW1zLmhhcygncmVjb25uZWN0JykpIHtcbiAgICAgICAgICAgIHVyaVN0cmluZyA9IEFycmF5LmZyb20oc2VhcmNoUGFyYW1zKS5sZW5ndGggPiAwID8gdXJpU3RyaW5nICsgJyZyZWNvbm5lY3Q9dHJ1ZScgOiB1cmlTdHJpbmcgKyAnP3JlY29ubmVjdD10cnVlJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJpU3RyaW5nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdEF1eChtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjb25uZWN0aW9uIGF0dGVtcHQgIycgKyBudW1SZXRyaWVzKTtcbiAgICAgICAgd3MuY2xvc2UoNDEwNCwgJ0Nvbm5lY3Rpb24gY2xvc2VkIGZvciByZWNvbm5lY3Rpb24nKTtcblxuICAgICAgICB3c1VyaSA9IGFkZFJlY29ubmVjdGlvblF1ZXJ5UGFyYW1zSWZNaXNzaW5nKHdzVXJpKTtcbiAgICAgICAgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcblxuICAgICAgICB3cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY29ubmVjdGVkIHRvICcgKyB3c1VyaSArICcgYWZ0ZXIgJyArIG51bVJldHJpZXMgKyAnIGF0dGVtcHRzLi4uJyk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuICAgICAgICB9O1xuXG4gICAgICAgIHdzLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKCdSZWNvbm5lY3Rpb24gZXJyb3I6ICcsIGVycm9yKTtcbiAgICAgICAgICAgIGlmIChudW1SZXRyaWVzID09PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5vbmRpc2Nvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLm9uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdChtYXhSZXRyaWVzLCBudW1SZXRyaWVzICsgMSk7XG4gICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IChjb2RlLCByZWFzb24pID0+IHtcbiAgICAgICAgY2xvc2luZyA9IHRydWU7XG4gICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSAoKSA9PiB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygncmVjb25uZWN0V3MnKTtcbiAgICAgICAgcmVjb25uZWN0KE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gKHR5cGUsIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgIH07XG5cbiAgICB0aGlzLmdldFJlYWR5U3RhdGUgPSAoKSA9PiB7XG4gICAgICAgIHJldHVybiB3cy5yZWFkeVN0YXRlO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgZGVmaW5lUHJvcGVydHlfSUU4ID0gZmFsc2U7XG5pZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7XG4gICAgdHJ5IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAneCcsIHt9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGRlZmluZVByb3BlcnR5X0lFOCA9IHRydWU7XG4gICAgfVxufVxuXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9iaW5kXG5pZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSB7XG4gICAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAob1RoaXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgICAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYUFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgICAgICBmTk9QID0gZnVuY3Rpb24gKCkge30sXG4gICAgICAgICAgICBmQm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXMgPyB0aGlzIDogb1RoaXMsIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgICAgIHJldHVybiBmQm91bmQ7XG4gICAgfTtcbn1cblxudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHBhY2tlcnMgPSByZXF1aXJlKCcuL3BhY2tlcnMnKTtcbnZhciBNYXBwZXIgPSByZXF1aXJlKCcuL01hcHBlcicpO1xuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKSB7XG4gICAgaWYgKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICAgIGZvciAodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgICAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID0ge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2VNZXRob2RzO1xufVxuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgICBpZiAoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gICAgLy8gVHJhbnNwb3J0IGFzIGEgZnVuY3Rpb25cbiAgICBpZiAodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZW5kOiB0cmFuc3BvcnRcbiAgICAgICAgfTtcblxuICAgIC8vIFdlYlNvY2tldCAmIERhdGFDaGFubmVsXG4gICAgaWYgKHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgICAvLyBNZXNzYWdlIEFQSSAoSW50ZXItd2luZG93ICYgV2ViV29ya2VyKVxuICAgIGlmICh0cmFuc3BvcnQucG9zdE1lc3NhZ2UgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG5cbiAgICAvLyBTdHJlYW0gQVBJXG4gICAgaWYgKHRyYW5zcG9ydC53cml0ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH1cblxuICAgIC8vIFRyYW5zcG9ydHMgdGhhdCBvbmx5IGNhbiByZWNlaXZlIG1lc3NhZ2VzLCBidXQgbm90IHNlbmRcbiAgICBpZiAodHJhbnNwb3J0Lm9ubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgaWYgKHRyYW5zcG9ydC5wYXVzZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSByZXR1cm47XG5cbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1RyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3QnKTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyBub3RpZmljYXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICovXG5mdW5jdGlvbiBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpIHtcbiAgICBpZiAoZGVmaW5lUHJvcGVydHlfSUU4KSB7XG4gICAgICAgIHRoaXMubWV0aG9kID0gbWV0aG9kO1xuICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ21ldGhvZCcsIHtcbiAgICAgICAgICAgIHZhbHVlOiBtZXRob2QsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHtcbiAgICAgICAgICAgIHZhbHVlOiBwYXJhbXMsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGlmICghcGFja2VyKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gICAgaWYgKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaykgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG4gICAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICBpZiAodHJhbnNwb3J0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICAgICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIGlmICh0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHRocm93IG5ldyBTeW50YXhFcnJvcignT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnQnKTtcblxuICAgICAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRyYW5zcG9ydCA9IG9wdGlvbnM7XG4gICAgICAgIG9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIGlmIChvblJlcXVlc3QgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgICAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICAgIGlmIChvblJlcXVlc3QgJiYgIShvblJlcXVlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHRocm93IG5ldyBTeW50YXhFcnJvcignT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnQnKTtcblxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgICBpZiAob25SZXF1ZXN0KSB0aGlzLm9uKCdyZXF1ZXN0Jywgb25SZXF1ZXN0KTtcblxuICAgIGlmIChkZWZpbmVQcm9wZXJ0eV9JRTgpIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySUQ7XG4gICAgZWxzZVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BlZXJJRCcsIHtcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBlZXJJRFxuICAgICAgICB9KTtcblxuICAgIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuICAgIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpIHtcbiAgICAgICAgc2VsZi5kZWNvZGUoZXZlbnQuZGF0YSB8fCBldmVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfTtcbiAgICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBSZW1vdmUgbGlzdGVuZXIgZnJvbSBvbGQgdHJhbnNwb3J0XG4gICAgICAgIGlmICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgICAgICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICAgICAgICBlbHNlIGlmICh0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIpIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgICAgICAgaWYgKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICAgICAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLmFkZExpc3RlbmVyKSB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH07XG5cbiAgICBpZiAoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLCB7XG4gICAgICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgdmFyIHJlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucmVxdWVzdF90aW1lb3V0IHx8IEJBU0VfVElNRU9VVDtcbiAgICB2YXIgcGluZ19yZXF1ZXN0X3RpbWVvdXQgPSBvcHRpb25zLnBpbmdfcmVxdWVzdF90aW1lb3V0IHx8IHJlcXVlc3RfdGltZW91dDtcbiAgICB2YXIgcmVzcG9uc2VfdGltZW91dCA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCB8fCBCQVNFX1RJTUVPVVQ7XG4gICAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCA9IG9wdGlvbnMuZHVwbGljYXRlc190aW1lb3V0IHx8IEJBU0VfVElNRU9VVDtcblxuICAgIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gICAgdmFyIHJlcXVlc3RzID0gbmV3IE1hcHBlcigpO1xuICAgIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gICAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcblxuICAgIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG4gICAgLyoqXG4gICAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VzLnJlbW92ZShpZCwgZGVzdCk7XG4gICAgICAgICAgICB9LCByZXNwb25zZV90aW1lb3V0KVxuICAgICAgICB9O1xuXG4gICAgICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gaWdub3JlIGR1cGxpY2F0ZWQgbWVzc2FnZXMgbGF0ZXJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSkge1xuICAgICAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgICAgICB9LCBkdXBsaWNhdGVzX3RpbWVvdXQpO1xuXG4gICAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAY2xhc3NcbiAgICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICAgKiBAcGFyYW0gW2Zyb21dIC0gc291cmNlIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KSB7XG4gICAgICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsIHtcbiAgICAgICAgICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGNvbnN0YW50IHtCb29sZWFufSBkdXBsaWNhdGVkXG4gICAgICAgICAqL1xuICAgICAgICBpZiAoISh0cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKSkpIHtcbiAgICAgICAgICAgIGlmIChkZWZpbmVQcm9wZXJ0eV9JRTgpIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgICAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVwbHkgPSBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgKGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IChyZXN1bHQgJiYgcmVzdWx0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgICAgICAgICAgICBpZiAodHJhbnNwb3J0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgICAgIHRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgICAgICAgaWYgKHJlc3BvbnNlKSBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgICAgICAgIGlmIChmcm9tICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikgZXJyb3IuZGVzdCA9IGZyb207XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0KSByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBtZXNzYWdlO1xuXG4gICAgICAgICAgICAvLyBOZXcgcmVxdWVzdCBvciBvdmVycmlkZW4gb25lLCBjcmVhdGUgbmV3IHJlc3BvbnNlIHdpdGggcHJvdmlkZWQgZGF0YVxuICAgICAgICAgICAgaWYgKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3IgPyByZXNwb25zZU1ldGhvZC5lcnJvciA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRHVwbGljYXRlICYgbm90LW92ZXJyaWRlbiByZXF1ZXN0LCByZS1zZW5kIG9sZCByZXNwb25zZVxuICAgICAgICAgICAgZWxzZSBpZiAocmVzcG9uc2UpIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuICAgICAgICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IG51bGxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaWRcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICAgICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydCkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuICAgIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKSB7XG4gICAgICAgIHZhciBrZXkgPSBtZXNzYWdlMktleVttZXNzYWdlXTtcbiAgICAgICAgaWYgKCFrZXkpIHJldHVybjtcblxuICAgICAgICBkZWxldGUgbWVzc2FnZTJLZXlbbWVzc2FnZV07XG5cbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgICAgIGlmICghcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShrZXkuaWQsIGtleS5kZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAgICpcbiAgICAgKiBJZiBgbWVzc2FnZWAgaXMgbm90IGdpdmVuLCBjYW5jZWwgYWxsIHRoZSByZXF1ZXN0XG4gICAgICovXG4gICAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICBpZiAobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBmb3IgKHZhciBtZXNzYWdlIGluIG1lc3NhZ2UyS2V5KSBjYW5jZWwobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFByZXZlbnQgdG8gcmVjZWl2ZSBuZXcgbWVzc2FnZXNcbiAgICAgICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmICh0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LmNsb3NlKSB0cmFuc3BvcnQuY2xvc2UoNDAwMywgJ0NhbmNlbCByZXF1ZXN0Jyk7XG5cbiAgICAgICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICAgICAgdGhpcy5jYW5jZWwoKTtcblxuICAgICAgICBwcm9jZXNzZWRSZXNwb25zZXMuZm9yRWFjaChjbGVhclRpbWVvdXQpO1xuXG4gICAgICAgIC8vIFJlc3BvbnNlc1xuICAgICAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhbmQgZW5jb2RlIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgICAqIEBwYXJhbSBbY2FsbGJhY2tdIC0gZnVuY3Rpb24gY2FsbGVkIHdoZW4gYSByZXNwb25zZSB0byB0aGlzIHJlcXVlc3QgaXNcbiAgICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEEgcmF3IEpzb25SUEMgMi4wIHJlcXVlc3Qgb3Igbm90aWZpY2F0aW9uIHN0cmluZ1xuICAgICAqL1xuICAgIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24gKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICAgIGlmIChwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgaWYgKGRlc3QgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgICAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGRlc3QgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBwYXJhbXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIH0gZWxzZSBpZiAoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgY2FsbGJhY2sgPSBkZXN0O1xuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgZGVzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIGlmICh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgY2FsbGJhY2sgPSB0cmFuc3BvcnQ7XG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgICAgICAgIHBhcmFtcy5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVzdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgICAgICAgcGFyYW1zLmRlc3QgPSBkZXN0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgIHBhcmFtczogcGFyYW1zXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgICAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogZGlzcGF0Y2hDYWxsYmFjayxcbiAgICAgICAgICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgICAgIHZhciBydCA9IG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdC50aW1lb3V0ID0gc2V0VGltZW91dCh0aW1lb3V0LCBydCAqIE1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge1xuICAgICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIGRlc3Q6IGRlc3RcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgICAgICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgZW5jb2RlX3RyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICAgICAgICAgIGlmICh0cmFuc3BvcnQpIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQgKyAnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JywgbWVzc2FnZSk7XG5cbiAgICAgICAgICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiB0aW1lb3V0KCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXRyaWVkIDwgbWF4X3JldHJpZXMpIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdSZXF1ZXN0IGhhcyB0aW1lZCBvdXQnKTtcbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICAgICAgICAgIGVycm9yLnJldHJ5ID0gcmV0cnk7XG5cbiAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm4gdGhlIHBhY2tlZCBtZXNzYWdlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYgKHRyYW5zcG9ydCkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UnBjTm90aWZpY2F0aW9ufFJwY1JlcXVlc3R8dW5kZWZpbmVkfSAtIHRoZSByZXByZXNlbnRhdGlvbiBvZiB0aGVcbiAgICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgICAqXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICAgKi9cbiAgICB0aGlzLmRlY29kZSA9IGZ1bmN0aW9uIChtZXNzYWdlLCB0cmFuc3BvcnQpIHtcbiAgICAgICAgaWYgKCFtZXNzYWdlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdNZXNzYWdlIGlzIG5vdCBkZWZpbmVkJyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgaW52YWxpZCBtZXNzYWdlc1xuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZGVidWcoZSwgbWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaWQgPSBtZXNzYWdlLmlkO1xuICAgICAgICB2YXIgYWNrID0gbWVzc2FnZS5hY2s7XG4gICAgICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICAgICAgdmFyIHBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zIHx8IHt9O1xuXG4gICAgICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAgICAgLy8gSWdub3JlIG1lc3NhZ2VzIHNlbmQgYnkgdXNcbiAgICAgICAgaWYgKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAgICAgLy8gTm90aWZpY2F0aW9uXG4gICAgICAgIGlmIChpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdmFyIG5vdGlmaWNhdGlvbiA9IG5ldyBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXF1ZXN0KCkge1xuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaWRBY2sgPSBpZCAhPSB1bmRlZmluZWQgPyBpZCA6IGFjaztcbiAgICAgICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZCcsIG1lc3NhZ2UpO1xuXG4gICAgICAgICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVxdWVzdCwgb3IgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICAgIGlmIChtZXRob2QpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICAgICAgICAgIGlmIChkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgICAgICAgICBpZiAocmVxdWVzdCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzcG9uc2VNZXRob2RzID0gcmVxdWVzdC5yZXNwb25zZU1ldGhvZHM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5yZXNwb25zZSkgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZCkgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZXF1ZXN0XG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBlcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgICAgIHZhciByZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcblxuICAgICAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5kZXN0ICYmIGVycm9yLmRlc3QgIT0gc2VsZi5wZWVySUQpIHJldHVybjtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFJlc3BvbnNlXG4gICAgICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzZWQpIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUud2FybignTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZScsIG1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgICAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcbn1cbmluaGVyaXRzKFJwY0J1aWxkZXIsIEV2ZW50RW1pdHRlcik7XG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZCkge1xuICAgIHZhciByZXN1bHQgPSB7XG4gICAgICAgIGpzb25ycGM6ICcyLjAnXG4gICAgfTtcblxuICAgIC8vIFJlcXVlc3RcbiAgICBpZiAobWVzc2FnZS5tZXRob2QpIHtcbiAgICAgICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgICAgIGlmIChtZXNzYWdlLnBhcmFtcykgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgICAgIC8vIFJlcXVlc3QgaXMgYSBub3RpZmljYXRpb25cbiAgICAgICAgaWYgKGlkICE9IHVuZGVmaW5lZCkgcmVzdWx0LmlkID0gaWQ7XG4gICAgfVxuXG4gICAgLy8gUmVzcG9uc2VcbiAgICBlbHNlIGlmIChpZCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQnKTtcblxuICAgICAgICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN1bHQucmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG4gICAgICAgIGVsc2UgdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWQnKTtcblxuICAgICAgICByZXN1bHQuaWQgPSBpZDtcbiAgICB9XG5cbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn1cblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSkge1xuICAgIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICAgIHJlc3VsdCA9IEpTT04ucGFyc2UobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICAgIHZhciB2ZXJzaW9uID0gcmVzdWx0Lmpzb25ycGM7XG4gICAgaWYgKHZlcnNpb24gIT09ICcyLjAnKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAgIC8vIFJlc3BvbnNlXG4gICAgaWYgKHJlc3VsdC5tZXRob2QgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1lc3NhZ2U6ICcgKyBtZXNzYWdlKTtcblxuICAgICAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBlcnJvcl9kZWZpbmVkID0gcmVzdWx0LmVycm9yICE9PSB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgICAgICBpZiAocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZCkgdGhyb3cgbmV3IFR5cGVFcnJvcignQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiAnICsgbWVzc2FnZSk7XG5cbiAgICAgICAgaWYgKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZCkgdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWQ6ICcgKyBtZXNzYWdlKTtcblxuICAgICAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgICAgICBkZWxldGUgcmVzdWx0LmlkO1xuICAgIH1cblxuICAgIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0cy5wYWNrID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm90IHlldCBpbXBsZW1lbnRlZCcpO1xufVxuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ05vdCB5ZXQgaW1wbGVtZW50ZWQnKTtcbn1cblxuZXhwb3J0cy5wYWNrID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgPSBYbWxSUEM7XG4iLCJ0eXBlIENvbnNvbGVGdW5jdGlvbiA9ICguLi5kYXRhOiBhbnkpID0+IHZvaWQ7XG5leHBvcnQgY2xhc3MgQ29uc29sZUxvZ2dlciB7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxvZ2dlcjogQ29uc29sZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsb2c6IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbmZvOiBDb25zb2xlRnVuY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGVidWc6IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB3YXJuOiBDb25zb2xlRnVuY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZXJyb3I6IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnNvbGU6IENvbnNvbGUpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIgPSBjb25zb2xlO1xuICAgICAgICAodGhpcy5sb2cgPSBjb25zb2xlLmxvZyksXG4gICAgICAgICAgICAodGhpcy5pbmZvID0gY29uc29sZS5pbmZvKSxcbiAgICAgICAgICAgICh0aGlzLmRlYnVnID0gY29uc29sZS5kZWJ1ZyksXG4gICAgICAgICAgICAodGhpcy53YXJuID0gY29uc29sZS53YXJuKSxcbiAgICAgICAgICAgICh0aGlzLmVycm9yID0gY29uc29sZS5lcnJvcik7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgSkwgfSBmcm9tICdqc25sb2cnO1xuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9PcGVuVmlkdSc7XG5pbXBvcnQgeyBDb25zb2xlTG9nZ2VyIH0gZnJvbSAnLi9Db25zb2xlTG9nZ2VyJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uJztcblxuZXhwb3J0IGNsYXNzIE9wZW5WaWR1TG9nZ2VyIHtcbiAgICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogT3BlblZpZHVMb2dnZXI7XG5cbiAgICBwcml2YXRlIEpTTkxPR19VUkw6IHN0cmluZyA9ICcvb3BlbnZpZHUvZWxrL29wZW52aWR1LWJyb3dzZXItbG9ncyc7XG4gICAgcHJpdmF0ZSBNQVhfSlNOTE9HX0JBVENIX0xPR19NRVNTQUdFUzogbnVtYmVyID0gMTAwO1xuICAgIHByaXZhdGUgTUFYX01TRUNPTkRTX0JBVENIX01FU1NBR0VTOiBudW1iZXIgPSA1MDAwO1xuICAgIHByaXZhdGUgTUFYX0xFTkdUSF9TVFJJTkdfSlNPTjogbnVtYmVyID0gMTAwMDtcblxuICAgIHByaXZhdGUgZGVmYXVsdENvbnNvbGVMb2dnZXI6IENvbnNvbGVMb2dnZXIgPSBuZXcgQ29uc29sZUxvZ2dlcihnbG9iYWxUaGlzLmNvbnNvbGUpO1xuXG4gICAgcHJpdmF0ZSBjdXJyZW50QXBwZW5kZXI6IGFueTtcblxuICAgIHByaXZhdGUgaXNQcm9kTW9kZSA9IGZhbHNlO1xuICAgIHByaXZhdGUgaXNKU05Mb2dTZXR1cCA9IGZhbHNlO1xuXG4gICAgLy8gVGhpcyB0d28gdmFyaWFibGVzIGFyZSB1c2VkIHRvIHJlc3RhcnQgSlNOTG9nXG4gICAgLy8gb24gZGlmZmVyZW50IHNlc3Npb25zIGFuZCBkaWZmZXJlbnQgdXNlcklkc1xuICAgIHByaXZhdGUgbG9nZ2luZ1Nlc3Npb25JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0YXRpYyBjb25maWd1cmVKU05Mb2cob3BlblZpZHU6IE9wZW5WaWR1LCB0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBJZiBkZXYgbW9kZSBvci4uLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ0xPR19KU05MT0dfUkVTVUxUUyddIHx8XG4gICAgICAgICAgICAgICAgLy8gSWYgaW5zdGFuY2UgaXMgY3JlYXRlZCBhbmQgaXQgaXMgT3BlblZpZHUgUHJvXG4gICAgICAgICAgICAgICAgKHRoaXMuaW5zdGFuY2UgJiZcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHUuaXNBdExlYXN0UHJvICYmXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGxvZ3MgYXJlIGVuYWJsZWRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5pc09wZW5WaWR1QnJvd3NlckxvZ3NEZWJ1Z0FjdGl2ZShvcGVuVmlkdSkgJiZcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSByZWNvbmZpZ3VyZSBpdCBpZiBzZXNzaW9uIG9yIGZpbmFsVXNlcklkIGhhcyBjaGFuZ2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuY2FuQ29uZmlndXJlSlNOTG9nKG9wZW5WaWR1LCB0aGlzLmluc3RhbmNlKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGFwcCBsb2dzIGNhbiBiZSBzZW50XG4gICAgICAgICAgICAgICAgLy8gYW5kIHJlcGxhY2UgY29uc29sZS5sb2cgZnVuY3Rpb24gdG8gc2VuZFxuICAgICAgICAgICAgICAgIC8vIGxvZ3Mgb2YgdGhlIGFwcGxpY2F0aW9uXG4gICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1LnNlbmRCcm93c2VyTG9ncyA9PT0gT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uLmRlYnVnX2FwcCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLnJlcGxhY2VXaW5kb3dDb25zb2xlKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gaXNKU05Mb2dTZXR1cCB3aWxsIG5vdCBiZSB0cnVlIHVudGlsIGNvbXBsZXRlZCBzZXR1cFxuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaXNKU05Mb2dTZXR1cCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaW5mbygnQ29uZmlndXJpbmcgSlNOTG9ncy4nKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsVXNlcklkID0gb3BlblZpZHUuZmluYWxVc2VySWQ7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gb3BlblZpZHUuc2Vzc2lvbi5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBiZWZvcmVTZW5kQ2FsbGJhY2sgPSAoeGhyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIDQwMSBvciA0MDMgb3IgNDA0IG1vZGlmeSByZWFkeSBhbmQgc3RhdHVzIHNvIEpTTkxvZyBkb24ndCByZXRyeSB0byBzZW5kIGxvZ3NcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21wZXJkZWNrL2pzbmxvZy5qcy9ibG9iL3YyLjMwLjAvanNubG9nLnRzI0w4MDUtTDgxOFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRSZWFkeVN0YXRlRnVuY3Rpb24gPSB4aHIub25yZWFkeXN0YXRlY2hhbmdlO1xuICAgICAgICAgICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNJbnZhbGlkUmVzcG9uc2UoeGhyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh4aHIsICdyZWFkeVN0YXRlJywgeyB2YWx1ZTogNCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoeGhyLCAnc3RhdHVzJywgeyB2YWx1ZTogMjAwIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERpc2FibGUgSlNOTG9nIHRvbyB0byBub3Qgc2VuZCBwZXJpb2RpY2FsbHkgZXJyb3JzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5kaXNhYmxlTG9nZ2VyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRSZWFkeVN0YXRlRnVuY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXJzIHRvIGlkZW50aWZ5IGFuZCBhdXRoZW50aWNhdGUgbG9nc1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgYnRvYShgJHtmaW5hbFVzZXJJZH0lLyUke3Nlc3Npb25JZH1gICsgJzonICsgdG9rZW4pKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBoZWFkZXJzIGZvciBPcGVuVmlkdVxuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignT1YtRmluYWwtVXNlci1JZCcsIGZpbmFsVXNlcklkKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ09WLVNlc3Npb24tSWQnLCBzZXNzaW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignT1YtVG9rZW4nLCB0b2tlbik7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIC8vIENyZWF0aW9uIG9mIHRoZSBhcHBlbmRlci5cbiAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLmN1cnJlbnRBcHBlbmRlciA9IEpMLmNyZWF0ZUFqYXhBcHBlbmRlcihgYXBwZW5kZXItJHtmaW5hbFVzZXJJZH0tJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5jdXJyZW50QXBwZW5kZXIuc2V0T3B0aW9ucyh7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVNlbmQ6IGJlZm9yZVNlbmRDYWxsYmFjayxcbiAgICAgICAgICAgICAgICAgICAgbWF4QmF0Y2hTaXplOiAxMDAwLFxuICAgICAgICAgICAgICAgICAgICBiYXRjaFNpemU6IHRoaXMuaW5zdGFuY2UuTUFYX0pTTkxPR19CQVRDSF9MT0dfTUVTU0FHRVMsXG4gICAgICAgICAgICAgICAgICAgIGJhdGNoVGltZW91dDogdGhpcy5pbnN0YW5jZS5NQVhfTVNFQ09ORFNfQkFUQ0hfTUVTU0FHRVNcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIEF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY2llc1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvZ1NlcmlhbGl6ZXIgPSAob2JqKTogc3RyaW5nID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2V0Q2lyY3VsYXJSZXBsYWNlciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Vlbi5oYXModmFsdWUpIHx8IChnbG9iYWxUaGlzLkhUTUxFbGVtZW50ICYmIHZhbHVlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vlbi5hZGQodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEN1dCBsb25nIG1lc3NhZ2VzXG4gICAgICAgICAgICAgICAgICAgIGxldCBzdHJpbmdpZnlKc29uID0gSlNPTi5zdHJpbmdpZnkob2JqLCBnZXRDaXJjdWxhclJlcGxhY2VyKCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5naWZ5SnNvbi5sZW5ndGggPiB0aGlzLmluc3RhbmNlLk1BWF9MRU5HVEhfU1RSSU5HX0pTT04pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ2lmeUpzb24gPSBgJHtzdHJpbmdpZnlKc29uLnN1YnN0cmluZygwLCB0aGlzLmluc3RhbmNlLk1BWF9MRU5HVEhfU1RSSU5HX0pTT04pfS4uLmA7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoZ2xvYmFsVGhpc1snTE9HX0pTTkxPR19SRVNVTFRTJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHN0cmluZ2lmeUpzb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZ2lmeUpzb247XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgSkwgdG8gc2VuZCBsb2dzXG4gICAgICAgICAgICAgICAgSkwuc2V0T3B0aW9ucyh7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRBamF4VXJsOiBvcGVuVmlkdS5odHRwVXJpICsgdGhpcy5pbnN0YW5jZS5KU05MT0dfVVJMLFxuICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemU6IGxvZ1NlcmlhbGl6ZXIsXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBKTCgpLnNldE9wdGlvbnMoe1xuICAgICAgICAgICAgICAgICAgICBhcHBlbmRlcnM6IFt0aGlzLmluc3RhbmNlLmN1cnJlbnRBcHBlbmRlcl1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaXNKU05Mb2dTZXR1cCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5sb2dnaW5nU2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaW5mbygnSlNOTG9nIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIFByaW50IGVycm9yXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBjb25maWd1cmluZyBKU05Mb2c6ICcpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICAgIC8vIFJlc3RvcmUgZGVmYXVsdHMgdmFsdWVzIGp1c3QgaW4gY2FzZSBhbnkgZXhjZXB0aW9uIGhhcHBlbi1cbiAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuZGlzYWJsZUxvZ2dlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBPcGVuVmlkdUxvZ2dlciB7XG4gICAgICAgIGlmICghT3BlblZpZHVMb2dnZXIuaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIE9wZW5WaWR1TG9nZ2VyLmluc3RhbmNlID0gbmV3IE9wZW5WaWR1TG9nZ2VyKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9wZW5WaWR1TG9nZ2VyLmluc3RhbmNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzSW52YWxpZFJlc3BvbnNlKHhocjogWE1MSHR0cFJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHhoci5zdGF0dXMgPT0gNDAxIHx8IHhoci5zdGF0dXMgPT0gNDAzIHx8IHhoci5zdGF0dXMgPT0gNDA0IHx8IHhoci5zdGF0dXMgPT0gMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbkNvbmZpZ3VyZUpTTkxvZyhvcGVuVmlkdTogT3BlblZpZHUsIGxvZ2dlcjogT3BlblZpZHVMb2dnZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIG9wZW5WaWR1LnNlc3Npb24uc2Vzc2lvbklkICE9IGxvZ2dlci5sb2dnaW5nU2Vzc2lvbklkO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNPcGVuVmlkdUJyb3dzZXJMb2dzRGVidWdBY3RpdmUob3BlblZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBvcGVuVmlkdS5zZW5kQnJvd3NlckxvZ3MgPT09IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi5kZWJ1ZyB8fFxuICAgICAgICAgICAgb3BlblZpZHUuc2VuZEJyb3dzZXJMb2dzID09PSBPcGVuVmlkdUxvZ2dlckNvbmZpZ3VyYXRpb24uZGVidWdfYXBwXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGNvbnNvbGUgZnVuY3Rpb25zIHdpdGgganNubG9nIGludGVncmF0aW9uXG4gICAgcHJpdmF0ZSBnZXRDb25zb2xlV2l0aEpTTkxvZygpIHtcbiAgICAgICAgcmV0dXJuIChmdW5jdGlvbiAob3BlblZpZHVMb2dnZXI6IE9wZW5WaWR1TG9nZ2VyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGxvZzogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkuaW5mbyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbmZvOiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICAgICAgICAgICAgICBvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5pbmZvLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkuaW5mbyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBkZWJ1ZzogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIuZGVidWcuYXBwbHkob3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgd2FybjogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIud2Fybi5hcHBseShvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVuVmlkdUxvZ2dlci5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBKTCgpLndhcm4oYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmVycm9yLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkuZXJyb3IoYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVwbGFjZVdpbmRvd0NvbnNvbGUoKSB7XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZSA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUubG9nID0gdGhpcy5nZXRDb25zb2xlV2l0aEpTTkxvZygpLmxvZztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmluZm8gPSB0aGlzLmdldENvbnNvbGVXaXRoSlNOTG9nKCkuaW5mbztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmRlYnVnID0gdGhpcy5nZXRDb25zb2xlV2l0aEpTTkxvZygpLmRlYnVnO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUud2FybiA9IHRoaXMuZ2V0Q29uc29sZVdpdGhKU05Mb2coKS53YXJuO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuZXJyb3IgPSB0aGlzLmdldENvbnNvbGVXaXRoSlNOTG9nKCkuZXJyb3I7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkaXNhYmxlTG9nZ2VyKCkge1xuICAgICAgICBKTC5zZXRPcHRpb25zKHsgZW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICAgIHRoaXMuaXNKU05Mb2dTZXR1cCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxvZ2dpbmdTZXNzaW9uSWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY3VycmVudEFwcGVuZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUgPSB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlcjtcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmxvZyA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuaW5mbyA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuaW5mbztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmRlYnVnID0gdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5kZWJ1ZztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLndhcm4gPSB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLndhcm47XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZS5lcnJvciA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuZXJyb3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxvZyguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNQcm9kTW9kZSkge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2cuYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNKU05Mb2dTZXR1cCkge1xuICAgICAgICAgICAgSkwoKS5pbmZvKGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGVidWcoLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzUHJvZE1vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuZGVidWcuYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5mbyguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNQcm9kTW9kZSkge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5pbmZvLmFwcGx5KHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgIEpMKCkuaW5mbyhhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHdhcm4oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci53YXJuLmFwcGx5KHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICBpZiAodGhpcy5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICBKTCgpLndhcm4oYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlcnJvciguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmVycm9yLmFwcGx5KHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICBpZiAodGhpcy5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICBKTCgpLmVycm9yKGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmx1c2goKSB7XG4gICAgICAgIGlmICh0aGlzLmlzSlNOTG9nU2V0dXAgJiYgdGhpcy5jdXJyZW50QXBwZW5kZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50QXBwZW5kZXIuc2VuZEJhdGNoKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVQcm9kTW9kZSgpIHtcbiAgICAgICAgdGhpcy5pc1Byb2RNb2RlID0gdHJ1ZTtcbiAgICB9XG59XG4iLCJleHBvcnQgZW51bSBPcGVuVmlkdUxvZ2dlckNvbmZpZ3VyYXRpb24ge1xuICAgIGRpc2FibGVkID0gJ2Rpc2FibGVkJyxcbiAgICBkZWJ1ZyA9ICdkZWJ1ZycsXG4gICAgZGVidWdfYXBwID0gJ2RlYnVnX2FwcCdcbn1cbiIsIi8vIExhc3QgdGltZSB1cGRhdGVkIG9uIEp1bmUgMDgsIDIwMThcblxuLy8gTGF0ZXN0IGZpbGUgY2FuIGJlIGZvdW5kIGhlcmU6IGh0dHBzOi8vY2RuLndlYnJ0Yy1leHBlcmltZW50LmNvbS9nZXRTY3JlZW5JZC5qc1xuXG4vLyBNdWF6IEtoYW4gICAgICAgICAtIHd3dy5NdWF6S2hhbi5jb21cbi8vIE1JVCBMaWNlbnNlICAgICAgIC0gd3d3LldlYlJUQy1FeHBlcmltZW50LmNvbS9saWNlbmNlXG4vLyBEb2N1bWVudGF0aW9uICAgICAtIGh0dHBzOi8vZ2l0aHViLmNvbS9tdWF6LWtoYW4vZ2V0U2NyZWVuSWQuXG5cbi8vIF9fX19fX19fX19fX19fXG4vLyBnZXRTY3JlZW5JZC5qc1xuXG4vKlxuZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgLy8gZXJyb3IgICAgPT0gbnVsbCB8fCAncGVybWlzc2lvbi1kZW5pZWQnIHx8ICdub3QtaW5zdGFsbGVkJyB8fCAnaW5zdGFsbGVkLWRpc2FibGVkJyB8fCAnbm90LWNocm9tZSdcbiAgICAvLyBzb3VyY2VJZCA9PSBudWxsIHx8ICdzdHJpbmcnIHx8ICdmaXJlZm94J1xuXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxuZ2xvYmFsVGhpcy5nZXRTY3JlZW5JZCA9IGZ1bmN0aW9uIChmaXJlZm94U3RyaW5nLCBjYWxsYmFjaywgY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0VkZ2UnKSAhPT0gLTEgJiYgKCEhbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IgfHwgISFuYXZpZ2F0b3IubXNTYXZlQmxvYikpIHtcbiAgICAgICAgLy8gbWljcm9zb2Z0IGVkZ2UgPT4gbmF2aWdhdG9yLmdldERpc3BsYXlNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzLCBvbkZhaWx1cmUpO1xuICAgICAgICBjYWxsYmFjayh7XG4gICAgICAgICAgICB2aWRlbzogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIC8vIHNvdXJjZUlkID09ICdmaXJlZm94J1xuICAgIC8vIHNjcmVlbl9jb25zdHJhaW50cyA9IHsuLi59XG4gICAgaWYgKCEhbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgICBjYWxsYmFjayhudWxsLCAnZmlyZWZveCcsIHtcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgbW96TWVkaWFTb3VyY2U6IGZpcmVmb3hTdHJpbmcsXG4gICAgICAgICAgICAgICAgbWVkaWFTb3VyY2U6IGZpcmVmb3hTdHJpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cywgbnVsbCwgZ2V0U2NyZWVuQ29uc3RyYWludHMoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IGdsb2JhbFRoaXMuc2NyZWVuLndpZHRoID4gMTkyMCA/IGdsb2JhbFRoaXMuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IGdsb2JhbFRoaXMuc2NyZWVuLmhlaWdodCA+IDEwODAgPyBnbG9iYWxUaGlzLnNjcmVlbi5oZWlnaHQgOiAxMDgwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKCEhY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvID0ge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCdcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICcqJ1xuICAgICAgICApO1xuICAgIH0gZWxzZSBpZiAoISFjdXN0b21fcGFyYW1ldGVyLmZvckVhY2gpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwdHVyZUN1c3RvbVNvdXJjZUlkOiBjdXN0b21fcGFyYW1ldGVyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJyonXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJyonXG4gICAgICAgICk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG5nbG9iYWxUaGlzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbmdsb2JhbFRoaXMuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgaWYgKCEhbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgIHtcbiAgICAgICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgICAgICB9LFxuICAgICAgICAnKidcbiAgICApO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2xvYmFsVGhpcy5nZXRTY3JlZW5JZDtcbiIsIi8vIGdsb2JhbCB2YXJpYWJsZXNcbnZhciBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xudmFyIHNvdXJjZUlkO1xudmFyIHNjcmVlbkNhbGxiYWNrO1xuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG5hdmlnYXRvci51c2VyQWdlbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGlzRmlyZWZveCA9IHR5cGVvZiB3aW5kb3cuSW5zdGFsbFRyaWdnZXIgIT09ICd1bmRlZmluZWQnO1xuICAgIHZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG4gICAgdmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG4gICAgfSk7XG59XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaykgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gbm90aWZpZWQgaGlzIHByZXNlbmNlXG4gICAgaWYgKGRhdGEgPT0gJ3J0Y211bHRpY29ubmVjdGlvbi1leHRlbnNpb24tbG9hZGVkJykge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdkZXNrdG9wJztcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIHNoYXJlZCB0ZW1wIHNvdXJjZUlkXG4gICAgaWYgKGRhdGEuc291cmNlSWQgJiYgc2NyZWVuQ2FsbGJhY2spIHtcbiAgICAgICAgc2NyZWVuQ2FsbGJhY2soKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCksIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgICAge1xuICAgICAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICAgICAgfSxcbiAgICAgICAgJyonXG4gICAgKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2UgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIH0sIDIwMDApO1xuICAgIH07XG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2FsbGJhY2soJ25vdC1pbnN0YWxsZWQnKTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyhjYWxsYmFjaykge1xuICAgIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCB0cnVlKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBleHBsYWlucyBob3cgdG8gdXNlIGFib3ZlIG1ldGhvZHMvb2JqZWN0c1xuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgIHNvdXJjZUlkID0gJyc7XG4gICAgdmFyIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyA9IHtcbiAgICAgICAgbW96TWVkaWFTb3VyY2U6ICd3aW5kb3cnLFxuICAgICAgICBtZWRpYVNvdXJjZTogJ3dpbmRvdydcbiAgICB9O1xuICAgIGlmIChpc0ZpcmVmb3gpIHJldHVybiBjYWxsYmFjayhudWxsLCBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMpO1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IGRlZmluZXMgZ2V0VXNlck1lZGlhIGNvbnN0cmFpbnRzXG4gICAgLy8gdGhhdCB3aWxsIGJlIHVzZWQgdG8gY2FwdHVyZSBjb250ZW50IG9mIHNjcmVlblxuICAgIHZhciBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGNocm9tZU1lZGlhU291cmNlLFxuICAgICAgICAgICAgbWF4V2lkdGg6IHNjcmVlbi53aWR0aCA+IDE5MjAgPyBzY3JlZW4ud2lkdGggOiAxOTIwLFxuICAgICAgICAgICAgbWF4SGVpZ2h0OiBzY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHNjcmVlbi5oZWlnaHQgOiAxMDgwXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbmFsOiBbXVxuICAgIH07XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgdmVyaWZpZXMgY2hyb21lIGV4dGVuc2lvbiBhdmFpbGFiaWxpdHlcbiAgICAvLyBpZiBpbnN0YWxsZWQgYW5kIGF2YWlsYWJsZSB0aGVuIGl0IHdpbGwgaW52b2tlIGV4dGVuc2lvbiBBUElcbiAgICAvLyBvdGhlcndpc2UgaXQgd2lsbCBmYWxsYmFjayB0byBjb21tYW5kLWxpbmUgYmFzZWQgc2NyZWVuIGNhcHR1cmluZyBBUElcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnICYmICFzb3VyY2VJZCkge1xuICAgICAgICBpZiAoY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZFdpdGhBdWRpbyhmdW5jdGlvbiAoc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmNhblJlcXVlc3RBdWRpb1RyYWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkKGZ1bmN0aW9uIChzb3VyY2VJZCkge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRoaXMgc3RhdGVtZW50IHNldHMgZ2V0cyAnc291cmNlSWRcIiBhbmQgc2V0cyBcImNocm9tZU1lZGlhU291cmNlSWRcIlxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7XG4iLCJpbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgY2xhc3MgUGxhdGZvcm1VdGlscyB7XG4gICAgcHJvdGVjdGVkIHN0YXRpYyBpbnN0YW5jZTogUGxhdGZvcm1VdGlscztcbiAgICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgICBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogUGxhdGZvcm1VdGlscyB7XG4gICAgICAgIGlmICghdGhpcy5pbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5pbnN0YW5jZSA9IG5ldyBQbGF0Zm9ybVV0aWxzKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBsYXRmb3JtVXRpbHMuaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgcHVibGljIGlzQ2hyb21lQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdDaHJvbWUnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNTYWZhcmlCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0Nocm9tZU1vYmlsZUJyb3dzZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0ZpcmVmb3hCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0ZpcmVmb3gnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdGaXJlZm94IE1vYmlsZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ0ZpcmVmb3ggZm9yIGlPUyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc09wZXJhQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdPcGVyYSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc09wZXJhTW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdPcGVyYSBNb2JpbGUnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNFZGdlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHBsYXRmb3JtPy52ZXJzaW9uID8gcGFyc2VGbG9hdChwbGF0Zm9ybS52ZXJzaW9uKSA6IC0xO1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ01pY3Jvc29mdCBFZGdlJyAmJiB2ZXJzaW9uID49IDgwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNFZGdlTW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHBsYXRmb3JtPy52ZXJzaW9uID8gcGFyc2VGbG9hdChwbGF0Zm9ybS52ZXJzaW9uKSA6IC0xO1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ01pY3Jvc29mdCBFZGdlJyAmJiAocGxhdGZvcm0ub3M/LmZhbWlseSA9PT0gJ0FuZHJvaWQnIHx8IHBsYXRmb3JtLm9zPy5mYW1pbHkgPT09ICdpT1MnKSAmJiB2ZXJzaW9uID4gNDU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0FuZHJvaWRCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0FuZHJvaWQgQnJvd3Nlcic7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0VsZWN0cm9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0VsZWN0cm9uJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzTm9kZUpzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ05vZGUuanMnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNTYW1zdW5nQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdTYW1zdW5nIEludGVybmV0IE1vYmlsZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ1NhbXN1bmcgSW50ZXJuZXQnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNJUGhvbmVPcklQYWQoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHVzZXJBZ2VudCA9ICEhcGxhdGZvcm0udWEgPyBwbGF0Zm9ybS51YSA6IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgICAgIGNvbnN0IGlzVG91Y2hhYmxlID0gJ29udG91Y2hlbmQnIGluIGRvY3VtZW50O1xuICAgICAgICBjb25zdCBpc0lQYWQgPSAvXFxiKFxcdypNYWNpbnRvc2hcXHcqKVxcYi8udGVzdCh1c2VyQWdlbnQpICYmIGlzVG91Y2hhYmxlO1xuICAgICAgICBjb25zdCBpc0lQaG9uZSA9IC9cXGIoXFx3KmlQaG9uZVxcdyopXFxiLy50ZXN0KHVzZXJBZ2VudCkgJiYgL1xcYihcXHcqTW9iaWxlXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJiBpc1RvdWNoYWJsZTtcbiAgICAgICAgcmV0dXJuIGlzSVBhZCB8fCBpc0lQaG9uZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzSU9TV2l0aFNhZmFyaSgpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuaXNJUGhvbmVPcklQYWQoKSAmJlxuICAgICAgICAgICAgL1xcYihcXHcqQXBwbGVcXHcqKVxcYi8udGVzdChuYXZpZ2F0b3IudmVuZG9yKSAmJlxuICAgICAgICAgICAgL1xcYihcXHcqU2FmYXJpXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJlxuICAgICAgICAgICAgIS9cXGIoXFx3KkNyaU9TXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJlxuICAgICAgICAgICAgIS9cXGIoXFx3KkZ4aU9TXFx3KilcXGIvLnRlc3QodXNlckFnZW50KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNJb25pY0lvcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNJUGhvbmVPcklQYWQoKSAmJiBwbGF0Zm9ybS51YSEhLmluZGV4T2YoJ1NhZmFyaScpID09PSAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzSW9uaWNBbmRyb2lkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdBbmRyb2lkJyAmJiBwbGF0Zm9ybS5uYW1lID09ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNNb2JpbGVEZXZpY2UoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ2lPUycgfHwgcGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdBbmRyb2lkJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzUmVhY3ROYXRpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzQ2hyb21pdW0oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLmlzQ2hyb21lQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzT3BlcmFCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0VkZ2VCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzU2Ftc3VuZ0Jyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0lvbmljQW5kcm9pZCgpIHx8XG4gICAgICAgICAgICB0aGlzLmlzSW9uaWNJb3MoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0VsZWN0cm9uKClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGNhblNjcmVlblNoYXJlKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB2ZXJzaW9uID0gcGxhdGZvcm0/LnZlcnNpb24gPyBwYXJzZUZsb2F0KHBsYXRmb3JtLnZlcnNpb24pIDogLTE7XG4gICAgICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgICAgICBpZiAodGhpcy5pc01vYmlsZURldmljZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuaXNDaHJvbWVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNGaXJlZm94QnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzT3BlcmFCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNFbGVjdHJvbigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzRWRnZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgKHRoaXMuaXNTYWZhcmlCcm93c2VyKCkgJiYgdmVyc2lvbiA+PSAxMylcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldE5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgfHwgJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRWZXJzaW9uKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS52ZXJzaW9uIHx8ICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RmFtaWx5KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5vcyEhLmZhbWlseSB8fCAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldERlc2NyaXB0aW9uKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5kZXNjcmlwdGlvbiB8fCAnJztcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IGZyZWVpY2UgPSByZXF1aXJlKCdmcmVlaWNlJyk7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7IFR5cGVPZlZpZGVvIH0gZnJvbSAnLi4vRW51bXMvVHlwZU9mVmlkZW8nO1xuaW1wb3J0IHsgRXhjZXB0aW9uRXZlbnROYW1lIH0gZnJvbSAnLi4vRXZlbnRzL0V4Y2VwdGlvbkV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9VdGlscy9QbGF0Zm9ybSc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5sZXQgcGxhdGZvcm06IFBsYXRmb3JtVXRpbHM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24ge1xuICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgYXVkaW86IGJvb2xlYW47XG4gICAgICAgIHZpZGVvOiBib29sZWFuO1xuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG1lZGlhU2VydmVyOiBzdHJpbmc7XG4gICAgb25JY2VDYW5kaWRhdGU6IChldmVudDogUlRDSWNlQ2FuZGlkYXRlKSA9PiB2b2lkO1xuICAgIG9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uOiAoZXhjZXB0aW9uTmFtZTogRXhjZXB0aW9uRXZlbnROYW1lLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVycz86IFJUQ0ljZVNlcnZlcltdO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW0gfCBudWxsO1xuICAgIG1vZGU/OiAnc2VuZG9ubHknIHwgJ3JlY3Zvbmx5JyB8ICdzZW5kcmVjdic7XG4gICAgaWQ/OiBzdHJpbmc7XG4gICAgdHlwZU9mVmlkZW86IFR5cGVPZlZpZGVvIHwgdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIHJlbW90ZUNhbmRpZGF0ZXNRdWV1ZTogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcbiAgICBsb2NhbENhbmRpZGF0ZXNRdWV1ZTogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIC8vIFNhbWUgYXMgV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24gYnV0IHdpdGhvdXQgb3B0aW9uYWwgZmllbGRzLlxuICAgIHByb3RlY3RlZCBjb25maWd1cmF0aW9uOiBSZXF1aXJlZDxXZWJSdGNQZWVyQ29uZmlndXJhdGlvbj47XG5cbiAgICBwcml2YXRlIGljZUNhbmRpZGF0ZUxpc3Q6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcblxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAgICAgICAuLi5jb25maWd1cmF0aW9uLFxuICAgICAgICAgICAgaWNlU2VydmVyczogISFjb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDAgPyBjb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCksXG4gICAgICAgICAgICBtZWRpYVN0cmVhbTogY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSAhPT0gdW5kZWZpbmVkID8gY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSA6IG51bGwsXG4gICAgICAgICAgICBtb2RlOiAhIWNvbmZpZ3VyYXRpb24ubW9kZSA/IGNvbmZpZ3VyYXRpb24ubW9kZSA6ICdzZW5kcmVjdicsXG4gICAgICAgICAgICBpZDogISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHRoaXMuZ2VuZXJhdGVVbmlxdWVJZCgpXG4gICAgICAgIH07XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICBsb2dnZXIuZGVidWcoYFtXZWJSdGNQZWVyXSBjb25maWd1cmF0aW9uOlxcbiR7SlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWd1cmF0aW9uLCBudWxsLCAyKX1gKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG5cbiAgICAgICAgdGhpcy5wYy5hZGRFdmVudExpc3RlbmVyKCdpY2VjYW5kaWRhdGUnLCAoZXZlbnQ6IFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5jYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBgUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudC5jYW5kaWRhdGVgIGlzIHN1cHBvc2VkIHRvIGJlIGFuIFJUQ0ljZUNhbmRpZGF0ZTpcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL3czYy5naXRodWIuaW8vd2VicnRjLXBjLyNkb20tcnRjcGVlcmNvbm5lY3Rpb25pY2VldmVudC1jYW5kaWRhdGVcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIEJ1dCBpbiBwcmFjdGljZSwgaXQgaXMgYWN0dWFsbHkgYW4gUlRDSWNlQ2FuZGlkYXRlSW5pdCB0aGF0IGNhbiBiZSB1c2VkIHRvXG4gICAgICAgICAgICAgICAgLy8gb2J0YWluIGEgcHJvcGVyIGNhbmRpZGF0ZSwgdXNpbmcgdGhlIFJUQ0ljZUNhbmRpZGF0ZSBjb25zdHJ1Y3RvcjpcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL3czYy5naXRodWIuaW8vd2VicnRjLXBjLyNkb20tcnRjaWNlY2FuZGlkYXRlLWNvbnN0cnVjdG9yXG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlSW5pdDogUlRDSWNlQ2FuZGlkYXRlSW5pdCA9IGV2ZW50LmNhbmRpZGF0ZSBhcyBSVENJY2VDYW5kaWRhdGVJbml0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGljZUNhbmRpZGF0ZSA9IG5ldyBSVENJY2VDYW5kaWRhdGUoY2FuZGlkYXRlSW5pdCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ub25JY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICBpZiAoaWNlQ2FuZGlkYXRlLmNhbmRpZGF0ZSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnBjLmFkZEV2ZW50TGlzdGVuZXIoJ3NpZ25hbGluZ3N0YXRlY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdzdGFibGUnKSB7XG4gICAgICAgICAgICAgICAgLy8gU0RQIE9mZmVyL0Fuc3dlciBmaW5pc2hlZC4gQWRkIHN0b3JlZCByZW1vdGUgY2FuZGlkYXRlcy5cbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNhbmRpZGF0ZSA9IHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRJZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWd1cmF0aW9uLmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDYW5kaWRhdGVzUXVldWUgPSBbXTtcbiAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIERFUFJFQ0FURUQgTEVHQUNZIE1FVEhPRDogT2xkIFdlYlJUQyB2ZXJzaW9ucyBkb24ndCBpbXBsZW1lbnRcbiAgICAvLyBUcmFuc2NlaXZlcnMsIGFuZCBpbnN0ZWFkIGRlcGVuZCBvbiB0aGUgZGVwcmVjYXRlZFxuICAgIC8vIFwib2ZmZXJUb1JlY2VpdmVBdWRpb1wiIGFuZCBcIm9mZmVyVG9SZWNlaXZlVmlkZW9cIi5cbiAgICBwcml2YXRlIGNyZWF0ZU9mZmVyTGVnYWN5KCk6IFByb21pc2U8UlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdD4ge1xuICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMuZGVwcmVjYXRlZFBlZXJDb25uZWN0aW9uVHJhY2tBcGkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGhhc0F1ZGlvID0gdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW87XG4gICAgICAgIGNvbnN0IGhhc1ZpZGVvID0gdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW87XG5cbiAgICAgICAgY29uc3Qgb3B0aW9uczogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgaGFzQXVkaW8sXG4gICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBoYXNWaWRlb1xuICAgICAgICB9O1xuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnW2NyZWF0ZU9mZmVyTGVnYWN5XSBSVENQZWVyQ29ubmVjdGlvbi5jcmVhdGVPZmZlcigpIG9wdGlvbnM6JywgSlNPTi5zdHJpbmdpZnkob3B0aW9ucykpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnBjLmNyZWF0ZU9mZmVyKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gU0RQIG9mZmVyIGZyb20gdGhlIGxvY2FsIFJUQ1BlZXJDb25uZWN0aW9uIHRvIHNlbmQgdG8gdGhlIG90aGVyIHBlZXIuXG4gICAgICogT25seSBpZiB0aGUgbmVnb3RpYXRpb24gd2FzIGluaXRpYXRlZCBieSB0aGlzIHBlZXIuXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlT2ZmZXIoKTogUHJvbWlzZTxSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0PiB7XG4gICAgICAgIC8vIFRPRE86IERlbGV0ZSB0aGlzIGNvbmRpdGlvbmFsIHdoZW4gYWxsIHN1cHBvcnRlZCBicm93c2VycyBhcmVcbiAgICAgICAgLy8gbW9kZXJuIGVub3VnaCB0byBpbXBsZW1lbnQgdGhlIFRyYW5zY2VpdmVyIG1ldGhvZHMuXG4gICAgICAgIGlmICghKCdhZGRUcmFuc2NlaXZlcicgaW4gdGhpcy5wYykpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICdbY3JlYXRlT2ZmZXJdIE1ldGhvZCBSVENQZWVyQ29ubmVjdGlvbi5hZGRUcmFuc2NlaXZlcigpIGlzIE5PVCBhdmFpbGFibGU7IHVzaW5nIExFR0FDWSBvZmZlclRvUmVjZWl2ZXtBdWRpbyxWaWRlb30nXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT2ZmZXJMZWdhY3koKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnW2NyZWF0ZU9mZmVyXSBNZXRob2QgUlRDUGVlckNvbm5lY3Rpb24uYWRkVHJhbnNjZWl2ZXIoKSBpcyBhdmFpbGFibGU7IHVzaW5nIGl0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTcGVjIGRvYzogaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3dlYnJ0Yy1wYy8jZG9tLXJ0Y3BlZXJjb25uZWN0aW9uLWFkZHRyYW5zY2VpdmVyXG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAncmVjdm9ubHknKSB7XG4gICAgICAgICAgICAvLyBUbyBzZW5kIG1lZGlhLCBhc3N1bWUgdGhhdCBhbGwgZGVzaXJlZCBtZWRpYSB0cmFja3MgaGF2ZSBiZWVuXG4gICAgICAgICAgICAvLyBhbHJlYWR5IGFkZGVkIGJ5IGhpZ2hlciBsZXZlbCBjb2RlIHRvIG91ciBNZWRpYVN0cmVhbS5cblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBbV2ViUnRjUGVlci5jcmVhdGVPZmZlcl0gRGlyZWN0aW9uIGlzICcke3RoaXMuY29uZmlndXJhdGlvbi5tb2RlfScsIGJ1dCBubyBzdHJlYW0gd2FzIGNvbmZpZ3VyZWQgdG8gYmUgc2VudGBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRjSW5pdDogUlRDUnRwVHJhbnNjZWl2ZXJJbml0ID0ge1xuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBbdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtXVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJyAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uc2ltdWxjYXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSByZXF1ZXN0ZWQgc2l6ZSBpcyBlbm91Z2ggdG8gYXNrIGZvciAzIGxheWVycy5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tTZXR0aW5ncyA9IHRyYWNrLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYWNrQ29uc3RzID0gdHJhY2suZ2V0Q29uc3RyYWludHMoKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFja1dpZHRoOiBudW1iZXIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tTZXR0aW5ncy53aWR0aCA/PyAodHJhY2tDb25zdHMud2lkdGggYXMgQ29uc3RyYWluVUxvbmdSYW5nZSkuaWRlYWwgPz8gKHRyYWNrQ29uc3RzLndpZHRoIGFzIG51bWJlcikgPz8gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tIZWlnaHQ6IG51bWJlciA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFja1NldHRpbmdzLmhlaWdodCA/PyAodHJhY2tDb25zdHMuaGVpZ2h0IGFzIENvbnN0cmFpblVMb25nUmFuZ2UpLmlkZWFsID8/ICh0cmFja0NvbnN0cy5oZWlnaHQgYXMgbnVtYmVyKSA/PyAwO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgW2NyZWF0ZU9mZmVyXSBWaWRlbyB0cmFjayBkaW1lbnNpb25zOiAke3RyYWNrV2lkdGh9eCR7dHJhY2tIZWlnaHR9YCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tQaXhlbHMgPSB0cmFja1dpZHRoICogdHJhY2tIZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIGxldCBtYXhMYXllcnMgPSAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2tQaXhlbHMgPj0gOTYwICogNTQwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhMYXllcnMgPSAzO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRyYWNrUGl4ZWxzID49IDQ4MCAqIDI3MCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF4TGF5ZXJzID0gMjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heExheWVycyA9IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB0Y0luaXQuc2VuZEVuY29kaW5ncyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBsID0gMDsgbCA8IG1heExheWVyczsgbCsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXllckRpdiA9IDIgKiogKG1heExheWVycyAtIGwgLSAxKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5jb2Rpbmc6IFJUQ1J0cEVuY29kaW5nUGFyYW1ldGVycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWQ6ICdyZGl2JyArIGxheWVyRGl2LnRvU3RyaW5nKCksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlIC0tIFByb3BlcnR5IG1pc3NpbmcgZnJvbSBET00gdHlwZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGFiaWxpdHlNb2RlOiAnTDFUMSdcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChbJ2RldGFpbCcsICd0ZXh0J10uaW5jbHVkZXModHJhY2suY29udGVudEhpbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJpb3JpdGl6ZSBiZXN0IHJlc29sdXRpb24sIGZvciBtYXhpbXVtIHBpY3R1cmUgZGV0YWlsLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nLnNjYWxlUmVzb2x1dGlvbkRvd25CeSA9IDEuMDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgLS0gUHJvcGVydHkgbWlzc2luZyBmcm9tIERPTSB0eXBlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZy5tYXhGcmFtZXJhdGUgPSBNYXRoLmZsb29yKDMwIC8gbGF5ZXJEaXYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZy5zY2FsZVJlc29sdXRpb25Eb3duQnkgPSBsYXllckRpdjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGNJbml0LnNlbmRFbmNvZGluZ3MucHVzaChlbmNvZGluZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0YyA9IHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIodHJhY2ssIHRjSW5pdCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc2VuZFBhcmFtcyA9IHRjLnNlbmRlci5nZXRQYXJhbWV0ZXJzKCk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZWVkU2V0UGFyYW1zID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZT8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWdyYWRhdGlvblByZWZlcmVuY2UgZm9yIHZpZGVvOiBcImJhbGFuY2VkXCIsIFwibWFpbnRhaW4tZnJhbWVyYXRlXCIsIFwibWFpbnRhaW4tcmVzb2x1dGlvblwiLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMTgvQ1Itd2VicnRjLTIwMTgwOTI3LyNkb20tcnRjZGVncmFkYXRpb25wcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWydkZXRhaWwnLCAndGV4dCddLmluY2x1ZGVzKHRyYWNrLmNvbnRlbnRIaW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQYXJhbXMuZGVncmFkYXRpb25QcmVmZXJlbmNlID0gJ21haW50YWluLXJlc29sdXRpb24nO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZSA9ICdiYWxhbmNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlT2ZmZXJdIFZpZGVvIHNlbmRlciBEZWdyYWRhdGlvbiBQcmVmZXJlbmNlIHNldDogJHtzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZX1gKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRklYTUU6IEZpcmVmb3ggaW1wbGVtZW50cyBkZWdyYWRhdGlvblByZWZlcmVuY2Ugb24gZWFjaCBpbmRpdmlkdWFsIGVuY29kaW5nIVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHNldCBpdCBvbiBldmVyeSBlbGVtZW50IG9mIHRoZSBzZW5kUGFyYW1zLmVuY29kaW5ncyBhcnJheSlcblxuICAgICAgICAgICAgICAgICAgICAgICAgbmVlZFNldFBhcmFtcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRTogQ2hlY2sgdGhhdCB0aGUgc2ltdWxjYXN0IGVuY29kaW5ncyB3ZXJlIGFwcGxpZWQuXG4gICAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggZG9lc24ndCBpbXBsZW1lbnQgYFJUQ1J0cFRyYW5zY2VpdmVySW5pdC5zZW5kRW5jb2RpbmdzYFxuICAgICAgICAgICAgICAgICAgICAvLyBzbyB0aGUgb25seSB3YXkgdG8gZW5hYmxlIHNpbXVsY2FzdCBpcyB3aXRoIGBSVENSdHBTZW5kZXIuc2V0UGFyYW1ldGVycygpYC5cbiAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBuZXh0IGJsb2NrIGNhbiBiZSBkZWxldGVkIHdoZW4gRmlyZWZveCBmaXhlcyBidWcgIzEzOTY5MTg6XG4gICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTEzOTY5MThcbiAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogVGhpcyBpcyBkb25lIGluIGEgd2F5IHRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIGFsbCBicm93c2VycywgdG8gc2F2ZSBvblxuICAgICAgICAgICAgICAgICAgICAvLyBicm93c2VyLWNvbmRpdGlvbmFsIGNvZGUuIFRoZSBpZGVhIGNvbWVzIGZyb20gV2ViUlRDIEFkYXB0ZXIuanM6XG4gICAgICAgICAgICAgICAgICAgIC8vICogaHR0cHM6Ly9naXRodWIuY29tL3dlYnJ0Y0hhY2tzL2FkYXB0ZXIvaXNzdWVzLzk5OFxuICAgICAgICAgICAgICAgICAgICAvLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJydGNIYWNrcy9hZGFwdGVyL2Jsb2IvdjcuNy4wL3NyYy9qcy9maXJlZm94L2ZpcmVmb3hfc2hpbS5qcyNMMjMxLUwyNTVcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlndXJhdGlvbi5zaW11bGNhc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZW5kUGFyYW1zLmVuY29kaW5ncz8ubGVuZ3RoICE9PSB0Y0luaXQuc2VuZEVuY29kaW5ncyEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBhcmFtcy5lbmNvZGluZ3MgPSB0Y0luaXQuc2VuZEVuY29kaW5ncyE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWVkU2V0UGFyYW1zID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChuZWVkU2V0UGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYFtjcmVhdGVPZmZlcl0gU2V0dGluZyBuZXcgUlRDUnRwU2VuZFBhcmFtZXRlcnMgdG8gdmlkZW8gc2VuZGVyYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRjLnNlbmRlci5zZXRQYXJhbWV0ZXJzKHNlbmRQYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9IGBbV2ViUnRjUGVlci5jcmVhdGVPZmZlcl0gQ2Fubm90IHNldCBSVENSdHBTZW5kUGFyYW1ldGVycyB0byB2aWRlbyBzZW5kZXJgO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYDogJHtlcnJvci5tZXNzYWdlfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIERFQlVHOiBVbmNvbW1lbnQgZm9yIGRldGFpbHMuXG4gICAgICAgICAgICAgICAgLy8gaWYgKHRyYWNrLmtpbmQgPT09IFwidmlkZW9cIiAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uc2ltdWxjYXN0KSB7XG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIFByaW50IGJyb3dzZXIgY2FwYWJpbGl0aWVzLlxuICAgICAgICAgICAgICAgIC8vICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgICAgICAgICAvLyAgICAgbG9nZ2VyLmRlYnVnKGBbY3JlYXRlT2ZmZXJdIFRyYW5zY2VpdmVyIHNlbmQgY2FwYWJpbGl0aWVzIChzdGF0aWMpOlxcbiR7SlNPTi5zdHJpbmdpZnkoUlRDUnRwU2VuZGVyLmdldENhcGFiaWxpdGllcz8uKFwidmlkZW9cIiksIG51bGwsIDIpfWApO1xuICAgICAgICAgICAgICAgIC8vICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgICAgICAgICAvLyAgICAgbG9nZ2VyLmRlYnVnKGBbY3JlYXRlT2ZmZXJdIFRyYW5zY2VpdmVyIHJlY3YgY2FwYWJpbGl0aWVzIChzdGF0aWMpOlxcbiR7SlNPTi5zdHJpbmdpZnkoUlRDUnRwUmVjZWl2ZXIuZ2V0Q2FwYWJpbGl0aWVzPy4oXCJ2aWRlb1wiKSwgbnVsbCwgMil9YCk7XG5cbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gUHJpbnQgcmVxdWVzdGVkIFRyYW5zY2VpdmVyIGVuY29kaW5ncyBhbmQgcGFyYW1ldGVycy5cbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW2NyZWF0ZU9mZmVyXSBUcmFuc2NlaXZlciBzZW5kIGVuY29kaW5ncyAocmVxdWVzdGVkKTpcXG4ke0pTT04uc3RyaW5naWZ5KHRjSW5pdC5zZW5kRW5jb2RpbmdzLCBudWxsLCAyKX1gKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW2NyZWF0ZU9mZmVyXSBUcmFuc2NlaXZlciBzZW5kIHBhcmFtZXRlcnMgKGFjY2VwdGVkKTpcXG4ke0pTT04uc3RyaW5naWZ5KHRjLnNlbmRlci5nZXRQYXJhbWV0ZXJzKCksIG51bGwsIDIpfWApO1xuICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRvIGp1c3QgcmVjZWl2ZSBtZWRpYSwgY3JlYXRlIG5ldyByZWN2b25seSB0cmFuc2NlaXZlcnMuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtpbmQgb2YgWydhdWRpbycsICd2aWRlbyddKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG1lZGlhIGtpbmQgc2hvdWxkIGJlIHVzZWQuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50c1traW5kXSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKGtpbmQsIHtcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtczogW3RoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbV1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzZHBPZmZlcjogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHNkcE9mZmVyID0gYXdhaXQgdGhpcy5wYy5jcmVhdGVPZmZlcigpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSBgW1dlYlJ0Y1BlZXIuY3JlYXRlT2ZmZXJdIEJyb3dzZXIgZmFpbGVkIGNyZWF0aW5nIGFuIFNEUCBPZmZlcmA7XG4gICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYDogJHtlcnJvci5tZXNzYWdlfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2RwT2ZmZXI7XG4gICAgfVxuXG4gICAgZGVwcmVjYXRlZFBlZXJDb25uZWN0aW9uVHJhY2tBcGkoKSB7XG4gICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtIS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtISk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIFNEUCBhbnN3ZXIgZnJvbSB0aGUgbG9jYWwgUlRDUGVlckNvbm5lY3Rpb24gdG8gc2VuZCB0byB0aGUgb3RoZXIgcGVlclxuICAgICAqIE9ubHkgaWYgdGhlIG5lZ290aWF0aW9uIHdhcyBpbml0aWF0ZWQgYnkgdGhlIG90aGVyIHBlZXJcbiAgICAgKi9cbiAgICBjcmVhdGVBbnN3ZXIoKTogUHJvbWlzZTxSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyBUT0RPOiBEZWxldGUgdGhpcyBjb25kaXRpb25hbCB3aGVuIGFsbCBzdXBwb3J0ZWQgYnJvd3NlcnMgYXJlXG4gICAgICAgICAgICAvLyBtb2Rlcm4gZW5vdWdoIHRvIGltcGxlbWVudCB0aGUgVHJhbnNjZWl2ZXIgbWV0aG9kcy5cbiAgICAgICAgICAgIGlmICgnZ2V0VHJhbnNjZWl2ZXJzJyBpbiB0aGlzLnBjKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdbY3JlYXRlQW5zd2VyXSBNZXRob2QgUlRDUGVlckNvbm5lY3Rpb24uZ2V0VHJhbnNjZWl2ZXJzKCkgaXMgYXZhaWxhYmxlOyB1c2luZyBpdCcpO1xuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhlIFBlZXJDb25uZWN0aW9uIGFscmVhZHkgY29udGFpbnMgb25lIFRyYW5zY2VpdmVyXG4gICAgICAgICAgICAgICAgLy8gZm9yIGVhY2gga2luZCBvZiBtZWRpYS5cbiAgICAgICAgICAgICAgICAvLyBUaGUgVHJhbnNjZWl2ZXJzIHNob3VsZCBoYXZlIGJlZW4gYWxyZWFkeSBjcmVhdGVkIGludGVybmFsbHkgYnlcbiAgICAgICAgICAgICAgICAvLyB0aGUgUEMgaXRzZWxmLCB3aGVuIGBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihzZHBPZmZlcilgIHdhcyBjYWxsZWQuXG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtpbmQgb2YgWydhdWRpbycsICd2aWRlbyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBtZWRpYSBraW5kIHNob3VsZCBiZSB1c2VkLlxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzW2tpbmRdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGxldCB0YyA9IHRoaXMucGMuZ2V0VHJhbnNjZWl2ZXJzKCkuZmluZCgodGMpID0+IHRjLnJlY2VpdmVyLnRyYWNrLmtpbmQgPT09IGtpbmQpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0Yykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRW5mb3JjZSBvdXIgZGVzaXJlZCBkaXJlY3Rpb24uXG4gICAgICAgICAgICAgICAgICAgICAgICB0Yy5kaXJlY3Rpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKGAke2tpbmR9IHJlcXVlc3RlZCwgYnV0IG5vIHRyYW5zY2VpdmVyIHdhcyBjcmVhdGVkIGZyb20gcmVtb3RlIGRlc2NyaXB0aW9uYCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQW5zd2VyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHNkcEFuc3dlcikgPT4gcmVzb2x2ZShzZHBBbnN3ZXIpKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogRGVsZXRlIGVsc2UgYnJhbmNoIHdoZW4gYWxsIHN1cHBvcnRlZCBicm93c2VycyBhcmVcbiAgICAgICAgICAgICAgICAvLyBtb2Rlcm4gZW5vdWdoIHRvIGltcGxlbWVudCB0aGUgVHJhbnNjZWl2ZXIgbWV0aG9kc1xuXG4gICAgICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sXG4gICAgICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicgPyB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicgPyB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZUF1ZGlvOiBvZmZlckF1ZGlvLFxuICAgICAgICAgICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVWaWRlbzogb2ZmZXJWaWRlb1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjIS5jcmVhdGVBbnN3ZXIoY29uc3RyYWludHMpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoc2RwQW5zd2VyKSA9PiByZXNvbHZlKHNkcEFuc3dlcikpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGVsc2UsIHRoZXJlIGlzIG5vdGhpbmcgdG8gZG87IHRoZSBsZWdhY3kgY3JlYXRlQW5zd2VyKCkgb3B0aW9ucyBkb1xuICAgICAgICAgICAgLy8gbm90IG9mZmVyIGFueSBjb250cm9sIG92ZXIgd2hpY2ggdHJhY2tzIGFyZSBpbmNsdWRlZCBpbiB0aGUgYW5zd2VyLlxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHBlZXIgaW5pdGlhdGVkIG5lZ290aWF0aW9uLiBTdGVwIDEvNCBvZiBTRFAgb2ZmZXItYW5zd2VyIHByb3RvY29sXG4gICAgICovXG4gICAgcHJvY2Vzc0xvY2FsT2ZmZXIob2ZmZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcilcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWxvY2FsRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPdGhlciBwZWVyIGluaXRpYXRlZCBuZWdvdGlhdGlvbi4gU3RlcCAyLzQgb2YgU0RQIG9mZmVyLWFuc3dlciBwcm90b2NvbFxuICAgICAqL1xuICAgIHByb2Nlc3NSZW1vdGVPZmZlcihzZHBPZmZlcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBvZmZlcjogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdCA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnb2ZmZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwT2ZmZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NEUCBvZmZlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nLCBvZmZlcik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCB3aGVuIHRyeWluZyB0byBzZXQgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFJlbW90ZURlc2NyaXB0aW9uKG9mZmVyKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3RoZXIgcGVlciBpbml0aWF0ZWQgbmVnb3RpYXRpb24uIFN0ZXAgMy80IG9mIFNEUCBvZmZlci1hbnN3ZXIgcHJvdG9jb2xcbiAgICAgKi9cbiAgICBwcm9jZXNzTG9jYWxBbnN3ZXIoYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NEUCBhbnN3ZXIgY3JlYXRlZCwgc2V0dGluZyBsb2NhbCBkZXNjcmlwdGlvbicpO1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCgnUlRDUGVlckNvbm5lY3Rpb24gaXMgY2xvc2VkIHdoZW4gdHJ5aW5nIHRvIHNldCBsb2NhbCBkZXNjcmlwdGlvbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgIC5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcilcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgcGVlciBpbml0aWF0ZWQgbmVnb3RpYXRpb24uIFN0ZXAgNC80IG9mIFNEUCBvZmZlci1hbnN3ZXIgcHJvdG9jb2xcbiAgICAgKi9cbiAgICBwcm9jZXNzUmVtb3RlQW5zd2VyKHNkcEFuc3dlcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NEUCBhbnN3ZXIgcmVjZWl2ZWQsIHNldHRpbmcgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCB3aGVuIHRyeWluZyB0byBzZXQgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcilcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERFQlVHOiBVbmNvbW1lbnQgZm9yIGRldGFpbHMuXG4gICAgICAgICAgICAgICAgICAgIC8vIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIGNvbnN0IHRjID0gdGhpcy5wYy5nZXRUcmFuc2NlaXZlcnMoKS5maW5kKCh0YykgPT4gdGMuc2VuZGVyLnRyYWNrPy5raW5kID09PSBcInZpZGVvXCIpO1xuICAgICAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICBsb2dnZXIuZGVidWcoYFtwcm9jZXNzUmVtb3RlQW5zd2VyXSBUcmFuc2NlaXZlciBzZW5kIHBhcmFtZXRlcnMgKGVmZmVjdGl2ZSk6XFxuJHtKU09OLnN0cmluZ2lmeSh0Yz8uc2VuZGVyLmdldFBhcmFtZXRlcnMoKSwgbnVsbCwgMil9YCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFzeW5jIHNldFJlbW90ZURlc2NyaXB0aW9uKHNkcDogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihzZHApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkSWNlQ29ubmVjdGlvblN0YXRlQ2hhbmdlTGlzdGVuZXIob3RoZXJJZDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGMuYWRkRXZlbnRMaXN0ZW5lcignaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaWNlQ29ubmVjdGlvblN0YXRlOiBSVENJY2VDb25uZWN0aW9uU3RhdGUgPSB0aGlzLnBjLmljZUNvbm5lY3Rpb25TdGF0ZTtcbiAgICAgICAgICAgIHN3aXRjaCAoaWNlQ29ubmVjdGlvblN0YXRlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZGlzY29ubmVjdGVkJzpcbiAgICAgICAgICAgICAgICAgICAgLy8gUG9zc2libGUgbmV0d29yayBkaXNjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zZzEgPVxuICAgICAgICAgICAgICAgICAgICAgICAgJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAnICgnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG90aGVySWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJykgY2hhbmdlIHRvIFwiZGlzY29ubmVjdGVkXCIuIFBvc3NpYmxlIG5ldHdvcmsgZGlzY29ubmVjdGlvbic7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKG1zZzEpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ub25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb24oRXhjZXB0aW9uRXZlbnROYW1lLklDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRCwgbXNnMSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2ZhaWxlZCc6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zZzIgPSAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIHRvIFwiZmFpbGVkXCInO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IobXNnMik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbkljZUNvbm5lY3Rpb25TdGF0ZUV4Y2VwdGlvbihFeGNlcHRpb25FdmVudE5hbWUuSUNFX0NPTk5FQ1RJT05fRkFJTEVELCBtc2cyKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xvc2VkJzpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICdJY2VDb25uZWN0aW9uU3RhdGUgb2YgUlRDUGVlckNvbm5lY3Rpb24gJyArIHRoaXMuY29uZmlndXJhdGlvbi5pZCArICcgKCcgKyBvdGhlcklkICsgJykgY2hhbmdlIHRvIFwiY2xvc2VkXCInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ25ldyc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICsgdGhpcy5jb25maWd1cmF0aW9uLmlkICsgJyAoJyArIG90aGVySWQgKyAnKSBjaGFuZ2UgdG8gXCJuZXdcIicpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2luZyc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIGNoYW5nZSB0byBcImNoZWNraW5nXCInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nvbm5lY3RlZCc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIGNoYW5nZSB0byBcImNvbm5lY3RlZFwiJ1xuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjb21wbGV0ZWQnOlxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICsgdGhpcy5jb25maWd1cmF0aW9uLmlkICsgJyAoJyArIG90aGVySWQgKyAnKSBjaGFuZ2UgdG8gXCJjb21wbGV0ZWRcIidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZW5lcmF0ZVVuaXF1ZUlkKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB1dWlkdjQoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9VdGlscy9QbGF0Zm9ybSc7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG5pbnRlcmZhY2UgV2VicnRjU3RhdHNDb25maWcge1xuICAgIGludGVydmFsOiBudW1iZXI7XG4gICAgaHR0cEVuZHBvaW50OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBKU09OU3RhdHNSZXNwb25zZSB7XG4gICAgJ0B0aW1lc3RhbXAnOiBzdHJpbmc7XG4gICAgcGFydGljaXBhbnRfaWQ6IHN0cmluZztcbiAgICBzZXNzaW9uX2lkOiBzdHJpbmc7XG4gICAgcGxhdGZvcm06IHN0cmluZztcbiAgICBwbGF0Zm9ybV9kZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHN0cmVhbTogc3RyaW5nO1xuICAgIHdlYnJ0Y19zdGF0czogSVdlYnJ0Y1N0YXRzO1xufVxuXG4vKipcbiAqIENvbW1vbiBXZWJSdGNTVGF0cyBmb3IgbGF0ZXN0IENocm9taXVtIGFuZCBGaXJlZm94IHZlcnNpb25zXG4gKi9cbmludGVyZmFjZSBJV2VicnRjU3RhdHMge1xuICAgIGluYm91bmQ/OiB7XG4gICAgICAgIGF1ZGlvOlxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBqaXR0ZXI6IG51bWJlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICAgICAgdmlkZW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGppdHRlcj86IG51bWJlcjsgLy8gRmlyZWZveFxuICAgICAgICAgICAgICAgICAgaml0dGVyQnVmZmVyRGVsYXk/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgZmlyQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIG5hY2tDb3VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGxpQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGZyYW1lSGVpZ2h0PzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgICAgIGZyYW1lV2lkdGg/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVzRHJvcHBlZD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZXNSZWNlaXZlZD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHwge307XG4gICAgfTtcbiAgICBvdXRib3VuZD86IHtcbiAgICAgICAgYXVkaW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICAgICAgdmlkZW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGZpckNvdW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBsaUNvdW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBxcFN1bTogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgZnJhbWVIZWlnaHQ/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVXaWR0aD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZXNTZW50PzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICB9O1xuICAgIGNhbmRpZGF0ZXBhaXI/OiB7XG4gICAgICAgIGN1cnJlbnRSb3VuZFRyaXBUaW1lPzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlPzogbnVtYmVyOyAvL0Nocm9tZVxuICAgICAgICAvLyBhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU/OiBudW1iZXIgLy8gTm8gc3VwcG9ydCBmb3IgYW55IGJyb3dzZXJzIChodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDSWNlQ2FuZGlkYXRlUGFpclN0YXRzL2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSlcbiAgICB9O1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjU3RhdHMge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgU1RBVFNfSVRFTV9OQU1FID0gJ3dlYnJ0Yy1zdGF0cy1jb25maWcnO1xuXG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0VuYWJsZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzSW50ZXJ2YWxJZDogTm9kZUpTLlRpbWVyO1xuICAgIHByaXZhdGUgc3RhdHNJbnRlcnZhbCA9IDE7XG4gICAgcHJpdmF0ZSBQT1NUX1VSTDogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgd2VicnRjT2JqID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5TVEFUU19JVEVNX05BTUUpO1xuXG4gICAgICAgIGlmICghIXdlYnJ0Y09iaikge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3Qgd2VicnRjU3RhdHNDb25maWc6IFdlYnJ0Y1N0YXRzQ29uZmlnID0gSlNPTi5wYXJzZSh3ZWJydGNPYmopO1xuICAgICAgICAgICAgLy8gd2VicnRjIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG4gICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAnV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkod2VicnRjU3RhdHNDb25maWcpKTtcblxuICAgICAgICAgICAgdGhpcy5QT1NUX1VSTCA9IHdlYnJ0Y1N0YXRzQ29uZmlnLmh0dHBFbmRwb2ludDtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IHdlYnJ0Y1N0YXRzQ29uZmlnLmludGVydmFsOyAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHtcbiAgICAvLyBcImxvY2FsQ2FuZGlkYXRlXCI6IHtcbiAgICAvLyAgICAgXCJpZFwiOiBcIlJUQ0ljZUNhbmRpZGF0ZV8vcjRQMXkyUVwiLFxuICAgIC8vICAgICBcInRpbWVzdGFtcFwiOiAxNjE2MDgwMTU1NjE3LFxuICAgIC8vICAgICBcInR5cGVcIjogXCJsb2NhbC1jYW5kaWRhdGVcIixcbiAgICAvLyAgICAgXCJ0cmFuc3BvcnRJZFwiOiBcIlJUQ1RyYW5zcG9ydF8wXzFcIixcbiAgICAvLyAgICAgXCJpc1JlbW90ZVwiOiBmYWxzZSxcbiAgICAvLyAgICAgXCJuZXR3b3JrVHlwZVwiOiBcIndpZmlcIixcbiAgICAvLyAgICAgXCJpcFwiOiBcIjEyMy40NS42Ny44OVwiLFxuICAgIC8vICAgICBcInBvcnRcIjogNjMzNDAsXG4gICAgLy8gICAgIFwicHJvdG9jb2xcIjogXCJ1ZHBcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGVUeXBlXCI6IFwic3JmbHhcIixcbiAgICAvLyAgICAgXCJwcmlvcml0eVwiOiAxNjg2MDUyNjA3LFxuICAgIC8vICAgICBcImRlbGV0ZWRcIjogZmFsc2UsXG4gICAgLy8gICAgIFwicmF3XCI6IFtcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6MzM0NTQxMjkyMSAxIHVkcCAxNjg2MDUyNjA3IDEyMy40NS42Ny44OSA2MzM0MCB0eXAgc3JmbHggcmFkZHIgMTkyLjE2OC4xLjMxIHJwb3J0IDYzMzQwIGdlbmVyYXRpb24gMCB1ZnJhZyAwWnRUIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6NTgwOTQ0ODIgMSB1ZHAgNDE4ODU2OTUgOTguNzYuNTQuMzIgNDQ0MzEgdHlwIHJlbGF5IHJhZGRyIDEyMy40NS42Ny44OSBycG9ydCA2MzM0MCBnZW5lcmF0aW9uIDAgdWZyYWcgMFp0VCBuZXR3b3JrLWlkIDEgbmV0d29yay1jb3N0IDEwXCJcbiAgICAvLyAgICAgXVxuICAgIC8vIH0sXG4gICAgLy8gXCJyZW1vdGVDYW5kaWRhdGVcIjoge1xuICAgIC8vICAgICBcImlkXCI6IFwiUlRDSWNlQ2FuZGlkYXRlXzFZTzE4Z3BoXCIsXG4gICAgLy8gICAgIFwidGltZXN0YW1wXCI6IDE2MTYwODAxNTU2MTcsXG4gICAgLy8gICAgIFwidHlwZVwiOiBcInJlbW90ZS1jYW5kaWRhdGVcIixcbiAgICAvLyAgICAgXCJ0cmFuc3BvcnRJZFwiOiBcIlJUQ1RyYW5zcG9ydF8wXzFcIixcbiAgICAvLyAgICAgXCJpc1JlbW90ZVwiOiB0cnVlLFxuICAgIC8vICAgICBcImlwXCI6IFwiMTIuMzQuNTYuNzhcIixcbiAgICAvLyAgICAgXCJwb3J0XCI6IDY0OTg5LFxuICAgIC8vICAgICBcInByb3RvY29sXCI6IFwidWRwXCIsXG4gICAgLy8gICAgIFwiY2FuZGlkYXRlVHlwZVwiOiBcInNyZmx4XCIsXG4gICAgLy8gICAgIFwicHJpb3JpdHlcIjogMTY3OTgxOTI2MyxcbiAgICAvLyAgICAgXCJkZWxldGVkXCI6IGZhbHNlLFxuICAgIC8vICAgICBcInJhd1wiOiBbXG4gICAgLy8gICAgIFwiY2FuZGlkYXRlOjE2IDEgVURQIDE2Nzk4MTkyNjMgMTIuMzQuNTYuNzggNjQ5ODkgdHlwIHNyZmx4IHJhZGRyIDE3Mi4xOS4wLjEgcnBvcnQgNjQ5ODlcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6MTYgMSBVRFAgMTY3OTgxOTI2MyAxMi4zNC41Ni43OCA2NDk4OSB0eXAgc3JmbHggcmFkZHIgMTcyLjE5LjAuMSBycG9ydCA2NDk4OVwiXG4gICAgLy8gICAgIF1cbiAgICAvLyB9XG4gICAgLy8gfVxuICAgIC8vIEhhdmUgYmVlbiB0ZXN0ZWQgaW46XG4gICAgLy8gICAtIExpbnV4IERlc2t0b3A6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NC4wLjM5MTEuMjE4XG4gICAgLy8gICAgICAgLSBGaXJlZm94IDg2XG4gICAgLy8gICAgICAgLSBNaWNyb3NvZnQgRWRnZSA5MS4wLjgyNS4wXG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIFdpbmRvd3MgRGVza3RvcDpcbiAgICAvLyAgICAgICAtIENocm9tZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc0LjAuMzkxMS4yMzJcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODYuMC4xXG4gICAgLy8gICAgICAgLSBNaWNyb3NvZnQgRWRnZSA4OS4wLjc3NC41NFxuICAgIC8vICAgICAgIC0gRWxlY3Ryb24gMTEuMy4wIChDaHJvbWl1bSA4Ny4wLjQyODAuMTQxKVxuICAgIC8vICAgLSBNYWNPUyBEZXNrdG9wOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gRmlyZWZveCA4Ny4wXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NS4wLjM5NjkuOTNcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDg5LjAuNzc0LjU3XG4gICAgLy8gICAgICAgLSBTYWZhcmkgMTQuMCAoMTQ2MTAuMS4yOC4xLjkpXG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIEFuZHJvaWQ6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgTW9iaWxlIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gT3BlcmEgNjIuMy4zMTQ2LjU3NzYzXG4gICAgLy8gICAgICAgLSBGaXJlZm94IE1vYmlsZSA4Ni42LjFcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIE1vYmlsZSA0Ni4wMi40LjUxNDdcbiAgICAvLyAgICAgICAtIElvbmljIDVcbiAgICAvLyAgICAgICAtIFJlYWN0IE5hdGl2ZSAwLjY0XG4gICAgLy8gICAtIGlPUzpcbiAgICAvLyAgICAgICAtIFNhZmFyaSBNb2JpbGVcbiAgICAvLyAgICAgICAtIMK/SW9uaWM/XG4gICAgLy8gICAgICAgLSDCv1JlYWN0IE5hdGl2ZT9cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGF0c1JlcG9ydDogYW55ID0gYXdhaXQgdGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTdGF0cygpO1xuICAgICAgICAgICAgbGV0IHRyYW5zcG9ydFN0YXQ7XG4gICAgICAgICAgICBjb25zdCBjYW5kaWRhdGVQYWlyczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IGxvY2FsQ2FuZGlkYXRlczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXM6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBzdGF0c1JlcG9ydC5mb3JFYWNoKChzdGF0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAndHJhbnNwb3J0JyAmJiAocGxhdGZvcm0uaXNDaHJvbWl1bSgpIHx8IHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpIHx8IHBsYXRmb3JtLmlzUmVhY3ROYXRpdmUoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0U3RhdCA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXRjaCAoc3RhdC50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2NhbmRpZGF0ZS1wYWlyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZVBhaXJzLnNldChzdGF0LmlkLCBzdGF0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdsb2NhbC1jYW5kaWRhdGUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzLnNldChzdGF0LmlkLCBzdGF0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyZW1vdGUtY2FuZGlkYXRlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZXMuc2V0KHN0YXQuaWQsIHN0YXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBsZXQgc2VsZWN0ZWRDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydFN0YXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkQ2FuZGlkYXRlUGFpcklkID0gdHJhbnNwb3J0U3RhdC5zZWxlY3RlZENhbmRpZGF0ZVBhaXJJZDtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZENhbmRpZGF0ZVBhaXIgPSBjYW5kaWRhdGVQYWlycy5nZXQoc2VsZWN0ZWRDYW5kaWRhdGVQYWlySWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGJhc2ljYWxseSBGaXJlZm94XG4gICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gY2FuZGlkYXRlUGFpcnMuc2l6ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVyYXRvciA9IGNhbmRpZGF0ZVBhaXJzLnZhbHVlcygpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlUGFpciA9IGl0ZXJhdG9yLm5leHQoKS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZVBhaXJbJ3NlbGVjdGVkJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkQ2FuZGlkYXRlUGFpciA9IGNhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGxvY2FsQ2FuZGlkYXRlSWQgPSBzZWxlY3RlZENhbmRpZGF0ZVBhaXIubG9jYWxDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZUlkID0gc2VsZWN0ZWRDYW5kaWRhdGVQYWlyLnJlbW90ZUNhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXMuZ2V0KGxvY2FsQ2FuZGlkYXRlSWQpO1xuICAgICAgICAgICAgaWYgKCEhZmluYWxMb2NhbENhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0TG9jYWxJY2VDYW5kaWRhdGVMaXN0KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZCA9IGNhbmRMaXN0LmZpbHRlcigoYzogUlRDSWNlQ2FuZGlkYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAhIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLmlwKSA+PSAwIHx8IGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5hZGRyZXNzKSA+PSAwKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnBvcnQpID49IDBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGMgb2YgY2FuZCkge1xuICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdy5wdXNoKGMuY2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSBsb2NhbCBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSByZW1vdGVDYW5kaWRhdGVzLmdldChyZW1vdGVDYW5kaWRhdGVJZCk7XG4gICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgISFjLmNhbmRpZGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXApID49IDAgfHwgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5hZGRyZXNzKSA+PSAwKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0KSA+PSAwXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUucmF3ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYyBvZiBjYW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdy5wdXNoKGMuY2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgcmVtb3RlIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0b3BXZWJSdGNTdGF0cygpIHtcbiAgICAgICAgaWYgKHRoaXMud2ViUnRjU3RhdHNFbmFibGVkKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkKTtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWRcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNlbmRTdGF0cyh1cmw6IHN0cmluZywgcmVzcG9uc2U6IEpTT05TdGF0c1Jlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjb25maWd1cmF0aW9uOiBSZXF1ZXN0SW5pdCA9IHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgICdDb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IGZldGNoKHVybCwgY29uZmlndXJhdGlvbik7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYHNlbmRTdGF0cyBlcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJvcil9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgd2VicnRjU3RhdHM6IElXZWJydGNTdGF0cyA9IGF3YWl0IHRoaXMuZ2V0Q29tbW9uU3RhdHMoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5nZW5lcmF0ZUpTT05TdGF0c1Jlc3BvbnNlKHdlYnJ0Y1N0YXRzKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VuZFN0YXRzKHRoaXMuUE9TVF9VUkwsIHJlc3BvbnNlKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGF2ZSBiZWVuIHRlc3RlZCBpbjpcbiAgICAvLyAgIC0gTGludXggRGVza3RvcDpcbiAgICAvLyAgICAgICAtIENocm9tZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc0LjAuMzkxMS4yMThcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODZcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDkxLjAuODI1LjBcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gV2luZG93cyBEZXNrdG9wOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gT3BlcmEgNzQuMC4zOTExLjIzMlxuICAgIC8vICAgICAgIC0gRmlyZWZveCA4Ni4wLjFcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDg5LjAuNzc0LjU0XG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIE1hY09TIERlc2t0b3A6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NS4wLjM5NjkuOTNcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODcuMFxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgODkuMC43NzQuNTdcbiAgICAvLyAgICAgICAtIFNhZmFyaSAxNC4wICgxNDYxMC4xLjI4LjEuOSlcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gQW5kcm9pZDpcbiAgICAvLyAgICAgICAtIENocm9tZSBNb2JpbGUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA2Mi4zLjMxNDYuNTc3NjNcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggTW9iaWxlIDg2LjYuMVxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgTW9iaWxlIDQ2LjAyLjQuNTE0N1xuICAgIC8vICAgICAgIC0gSW9uaWMgNVxuICAgIC8vICAgICAgIC0gUmVhY3QgTmF0aXZlIDAuNjRcbiAgICAvLyAgIC0gaU9TOlxuICAgIC8vICAgICAgIC0gU2FmYXJpIE1vYmlsZVxuICAgIC8vICAgICAgIC0gwr9Jb25pYz9cbiAgICAvLyAgICAgICAtIMK/UmVhY3QgTmF0aXZlP1xuICAgIHB1YmxpYyBhc3luYyBnZXRDb21tb25TdGF0cygpOiBQcm9taXNlPElXZWJydGNTdGF0cz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGF0c1JlcG9ydDogYW55ID0gYXdhaXQgdGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTdGF0cygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlOiBJV2VicnRjU3RhdHMgPSB0aGlzLmdldFdlYlJ0Y1N0YXRzUmVzcG9uc2VPdXRsaW5lKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmlkZW9UcmFja1N0YXRzID0gWydmcmFtZXNSZWNlaXZlZCcsICdmcmFtZXNEcm9wcGVkJywgJ2ZyYW1lc1NlbnQnLCAnZnJhbWVIZWlnaHQnLCAnZnJhbWVXaWR0aCddO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRpZGF0ZVBhaXJTdGF0cyA9IFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJywgJ2N1cnJlbnRSb3VuZFRyaXBUaW1lJ107XG5cbiAgICAgICAgICAgICAgICBzdGF0c1JlcG9ydC5mb3JFYWNoKChzdGF0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1lZGlhVHlwZSA9IHN0YXQubWVkaWFUeXBlICE9IG51bGwgPyBzdGF0Lm1lZGlhVHlwZSA6IHN0YXQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRkU3RhdCA9IChkaXJlY3Rpb246IHN0cmluZywga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0W2tleV0gIT0gbnVsbCAmJiByZXNwb25zZVtkaXJlY3Rpb25dICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1lZGlhVHlwZSAmJiB2aWRlb1RyYWNrU3RhdHMuaW5kZXhPZihrZXkpID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFUeXBlID0gJ3ZpZGVvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpcmVjdGlvbiAhPSBudWxsICYmIG1lZGlhVHlwZSAhPSBudWxsICYmIGtleSAhPSBudWxsICYmIHJlc3BvbnNlW2RpcmVjdGlvbl1bbWVkaWFUeXBlXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlW2RpcmVjdGlvbl1bbWVkaWFUeXBlXVtrZXldID0gTnVtYmVyKHN0YXRba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gIT0gbnVsbCAmJiBrZXkgIT0gbnVsbCAmJiBjYW5kaWRhdGVQYWlyU3RhdHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW5kaWRhdGUtcGFpci1zdGF0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtkaXJlY3Rpb25dW2tleV0gPSBOdW1iZXIoc3RhdFtrZXldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChzdGF0LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ291dGJvdW5kLXJ0cCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnYnl0ZXNTZW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAncGFja2V0c1NlbnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdmcmFtZXNFbmNvZGVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnbmFja0NvdW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnZmlyQ291bnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdwbGlDb3VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ291dGJvdW5kJywgJ3FwU3VtJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdpbmJvdW5kLXJ0cCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdieXRlc1JlY2VpdmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdwYWNrZXRzUmVjZWl2ZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ3BhY2tldHNMb3N0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdqaXR0ZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ2ZyYW1lc0RlY29kZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ25hY2tDb3VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAnZmlyQ291bnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ3BsaUNvdW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd0cmFjayc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdqaXR0ZXJCdWZmZXJEZWxheScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAnZnJhbWVzUmVjZWl2ZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdmcmFtZXNEcm9wcGVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnZnJhbWVzU2VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQodGhpcy5zdHJlYW0uaXNMb2NhbCgpID8gJ291dGJvdW5kJyA6ICdpbmJvdW5kJywgJ2ZyYW1lSGVpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgPyAnb3V0Ym91bmQnIDogJ2luYm91bmQnLCAnZnJhbWVXaWR0aCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnY2FuZGlkYXRlLXBhaXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2NhbmRpZGF0ZXBhaXInLCAnY3VycmVudFJvdW5kVHJpcFRpbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdjYW5kaWRhdGVwYWlyJywgJ2F2YWlsYWJsZU91dGdvaW5nQml0cmF0ZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZWxldGUgY2FuZGlkYXRlcGFpciBmcm9tIHJlc3BvbnNlIGlmIG51bGxcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlPy5jYW5kaWRhdGVwYWlyIHx8IE9iamVjdC5rZXlzKDxPYmplY3Q+cmVzcG9uc2UuY2FuZGlkYXRlcGFpcikubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZS5jYW5kaWRhdGVwYWlyO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBnZXR0aW5nIGNvbW1vbiBzdGF0czogJywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdlbmVyYXRlSlNPTlN0YXRzUmVzcG9uc2Uoc3RhdHM6IElXZWJydGNTdGF0cyk6IEpTT05TdGF0c1Jlc3BvbnNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgcGFydGljaXBhbnRfaWQ6IHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uZGF0YSxcbiAgICAgICAgICAgIHNlc3Npb25faWQ6IHRoaXMuc3RyZWFtLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgcGxhdGZvcm06IHBsYXRmb3JtLmdldE5hbWUoKSxcbiAgICAgICAgICAgIHBsYXRmb3JtX2Rlc2NyaXB0aW9uOiBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpLFxuICAgICAgICAgICAgc3RyZWFtOiAnd2ViUlRDJyxcbiAgICAgICAgICAgIHdlYnJ0Y19zdGF0czogc3RhdHNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFdlYlJ0Y1N0YXRzUmVzcG9uc2VPdXRsaW5lKCk6IElXZWJydGNTdGF0cyB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHt9LFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzoge31cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXBhaXI6IHt9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpbmJvdW5kOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHt9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==