7374 lines
863 KiB
JavaScript
7374 lines
863 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
// In order to test this interface implementation run jsc interface.js
|
|
|
|
class Interface {
|
|
// Abstract interface that should be extended in interface subclasses.
|
|
// By convention all interfaces should start with an upper 'I'
|
|
|
|
static implementationError(klass) {
|
|
let interfaceKeys = Reflect.ownKeys(this.prototype);
|
|
let classKeys = Reflect.ownKeys(klass.prototype);
|
|
for(let key of interfaceKeys) {
|
|
let interfaceDesc = this.prototype[key];
|
|
let classDesc = klass.prototype[key];
|
|
if (typeof(classDesc) == 'undefined')
|
|
return 'Missing ' + key
|
|
}
|
|
return null
|
|
}
|
|
|
|
static implementedBy(klass) {
|
|
// In the first step only checks whether the methods of this
|
|
// interface are all implemented by the given class
|
|
let error = this.implementationError(klass);
|
|
return error == null
|
|
}
|
|
|
|
// TODO: Specify optional methods
|
|
// static optionalMethods() {
|
|
// return [this.onMouseWheel]
|
|
// }
|
|
}
|
|
|
|
/** Basic Application object to be used as a singleton.
|
|
Provides an interface for automatic testing and common device specific
|
|
feature detection.
|
|
*/
|
|
|
|
class IApp extends Interface {
|
|
/** Build the app by registering event handlers,
|
|
* adding DOM elements, instanciating templates, etc...
|
|
*/
|
|
setup() { return this }
|
|
|
|
/** Run the application by starting a main loop, ...
|
|
*/
|
|
run() { return this }
|
|
}
|
|
|
|
class App extends Object {
|
|
/** Override this method to build your app.
|
|
*/
|
|
setup() {
|
|
return this
|
|
}
|
|
|
|
/** Start and run the application. Override this method with everything
|
|
that is needed to maintain your App, main loops, etc.
|
|
*/
|
|
run() {
|
|
return this
|
|
}
|
|
|
|
/** Defines all test suites. Overwrite this method to ensure that
|
|
all testable aspects of your App are evaluated.
|
|
*/
|
|
allTests() {
|
|
console.log('Overwrite App.allTests()');
|
|
}
|
|
|
|
/** Run all tests. Should return 'ok' and the amount of time needed to
|
|
run App.allTests() or a failure message with diagnostic error decription.
|
|
@return {array} - array with 'ok' as first element and needed time as
|
|
second element or "Tests failed" and an error string
|
|
*/
|
|
runTests() {
|
|
var start = performance.now();
|
|
try {
|
|
this.allTests();
|
|
var end = performance.now();
|
|
return ['ok', end - start]
|
|
}
|
|
catch(e) {
|
|
console.trace();
|
|
return ['Tests failed', e.message]
|
|
}
|
|
}
|
|
}
|
|
|
|
IApp.implementedBy(App);
|
|
|
|
// Allows browsers to perform doctests.
|
|
// Uses the code highlight package from http://highlightjs.readthedocs.io
|
|
// if available
|
|
|
|
var docTestLogMessages = [];
|
|
|
|
Array.prototype.equals = function(array) {
|
|
return this.length == array.length &&
|
|
this.every( function(this_i,i) { return this_i == array[i] } )
|
|
};
|
|
|
|
class Doctest {
|
|
|
|
static assert(value) {
|
|
if (!value) {
|
|
throw new Error('Assertion violated')
|
|
}
|
|
}
|
|
|
|
static pprint(obj) {
|
|
if (obj === null)
|
|
return 'null'
|
|
let stringified = obj.toString();
|
|
if (stringified == '[object Object]')
|
|
return JSON.stringify(obj)
|
|
return stringified
|
|
}
|
|
|
|
static expect(expr, value) {
|
|
if (this.pprint(expr) != this.pprint(value)) {
|
|
//throw new Error("got `" + expr + "` but expected `" + value + "`.")
|
|
throw new Error('got `' + this.pprint(expr) + '` but expected `' + this.pprint(value) + '`.')
|
|
}
|
|
}
|
|
|
|
static expectError(error, message) {
|
|
let index = error.toString().indexOf(message);
|
|
if (index < 0) {
|
|
throw new Error('got `' + message + '` but expected `' + error + '`.')
|
|
}
|
|
}
|
|
|
|
static expectLog(...messages) {
|
|
// if (!docTestLogMessages.equals(messages)) {
|
|
docTestLogMessages.forEach((msg, i) => {
|
|
if (msg != messages[i])
|
|
throw new Error('Unexpected log message: `' + messages[i] + '`.')
|
|
});
|
|
// throw new Error('Uups')
|
|
//}
|
|
}
|
|
|
|
static log(message) {
|
|
docTestLogMessages.push(message);
|
|
}
|
|
|
|
static highlight(code) {
|
|
if (typeof(hljs) == 'undefined')
|
|
return code
|
|
return hljs.highlight('javascript', code)
|
|
}
|
|
|
|
static stripLeadingLines(code) {
|
|
let result = [];
|
|
let informative = false;
|
|
for(let line of code.split('\n')) {
|
|
if (line.trim().length > 0) {
|
|
informative = true;
|
|
}
|
|
if (informative)
|
|
result.push(line);
|
|
}
|
|
return result.join('\n')
|
|
}
|
|
|
|
static event(type='mouse', {clientX = 0, clientY = 0} = {}) {
|
|
if (type.startsWith('mouse')) {
|
|
return new MouseEvent(type, { clientX, clientY })
|
|
}
|
|
return { type, clientX, clientY }
|
|
}
|
|
|
|
static run(replaceExpect=false) {
|
|
if (typeof(hljs) != 'undefined') {
|
|
hljs.initHighlighting();
|
|
}
|
|
let doctests = document.querySelectorAll('.doctest');
|
|
for(let i=0; i<doctests.length; i++) {
|
|
let doctest = doctests[i];
|
|
let code = this.stripLeadingLines(doctest.innerHTML);
|
|
let text = this.highlight(code);
|
|
let pre = document.createElement('pre');
|
|
// See http://stackoverflow.com/questions/1068280/javascript-regex-multiline-flag-doesnt-work
|
|
// let re = /Doctest\.expect\(([\s\S]*)[\,\s\S]*([\s\S]*)\)/g
|
|
let lines = text.value.split('\n');
|
|
let better = [];
|
|
for(let line of lines) {
|
|
if (replaceExpect && line.trim().startsWith('Doctest.expect(')) {
|
|
line = line.replace(/Doctest\.expect\(/, '>>> ').trim();
|
|
if (line.endsWith(')') || line.endsWith(',')) {
|
|
line = line.slice(0, -1);
|
|
}
|
|
}
|
|
better.push(line);
|
|
}
|
|
pre.innerHTML = better.join('\n'); // text.value.replace(re, ">>> $1\n$2")
|
|
doctest.parentNode.replaceChild(pre, doctest);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Needed to make Doctest visible in modules
|
|
//window.Doctest = Doctest
|
|
|
|
var recordedErrors = new Map();
|
|
|
|
class Errors {
|
|
|
|
static countErrors() {
|
|
let total = 0;
|
|
for(let error of recordedErrors.keys()) {
|
|
total += recordedErrors.get(error).size;
|
|
}
|
|
return total
|
|
}
|
|
|
|
static setStyle(element, styles) {
|
|
for(let key in styles) {
|
|
element.style[key] = styles[key];
|
|
}
|
|
}
|
|
|
|
static appendError(error, source) {
|
|
if (recordedErrors.has(error)) {
|
|
let sources = recordedErrors.get(error);
|
|
sources.add(source);
|
|
}
|
|
else {
|
|
recordedErrors.set(error, new Set([source]));
|
|
}
|
|
}
|
|
|
|
static showErrors() {
|
|
if (this.countErrors() == 0) {
|
|
return
|
|
}
|
|
let errors = document.getElementById('runtime-errors');
|
|
if (errors == null) {
|
|
errors = document.createElement('div');
|
|
errors.setAttribute('id', 'runtime-errors');
|
|
this.setStyle(document.body, {
|
|
border: '2px solid red'
|
|
});
|
|
this.setStyle(errors, {position: 'absolute',
|
|
top: '0px',
|
|
padding: '8px',
|
|
width: '100%',
|
|
background: 'red',
|
|
color: 'white'});
|
|
document.body.appendChild(errors);
|
|
let counter = document.createElement('div');
|
|
counter.setAttribute('id', 'runtime-errors-counter');
|
|
this.setStyle(counter, {borderRadius: '50%',
|
|
width: '32px',
|
|
height: '32px',
|
|
background: 'white',
|
|
color: 'red',
|
|
fontSize: '18px',
|
|
textAlign: 'center',
|
|
lineHeight: '32px',
|
|
verticalAlign: 'middle'});
|
|
counter.innerHTML = '1';
|
|
errors.appendChild(counter);
|
|
|
|
let header = document.createElement('div');
|
|
this.setStyle(header, {position: 'absolute',
|
|
top: '6px',
|
|
left: '48px',
|
|
height: '44px',
|
|
fontSize: '32px'});
|
|
header.innerHTML = 'Runtime Errors';
|
|
errors.appendChild(header);
|
|
errors.addEventListener('click', this.toggleErrors.bind(this));
|
|
}
|
|
let counter = document.getElementById('runtime-errors-counter');
|
|
counter.innerHTML = this.countErrors();
|
|
}
|
|
|
|
static expandErrors() {
|
|
let errors = document.getElementById('runtime-errors');
|
|
for(let error of recordedErrors.keys()) {
|
|
for(var source of recordedErrors.get(error)) {
|
|
if (typeof(source) == 'undefined') {
|
|
source = 'See console for details';
|
|
return
|
|
}
|
|
let info = document.createElement('div');
|
|
info.className = 'info';
|
|
info.style.wordWrap = 'break-word';
|
|
info.innerHTML = error + `<br/><small>${source}</small>`;
|
|
errors.appendChild(info);
|
|
}
|
|
}
|
|
}
|
|
|
|
static toggleErrors() {
|
|
let errors = document.getElementById('runtime-errors');
|
|
let infos = errors.querySelectorAll('.info');
|
|
if (infos.length > 0) {
|
|
infos.forEach((info) => errors.removeChild(info));
|
|
}
|
|
else {
|
|
this.expandErrors();
|
|
}
|
|
}
|
|
|
|
static removeError(event) {
|
|
console.log('removeError', event);
|
|
if (recordedErrors.has(event.error)) {
|
|
let sources = recordedErrors.get(event.error);
|
|
sources.delete(event.source);
|
|
console.log('sources', sources);
|
|
}
|
|
}
|
|
|
|
static registerGlobalErrorHandler() {
|
|
// Register more informative error handler
|
|
window.addEventListener('error', (event) => {
|
|
// if (typeof(event.error) == 'undefined') {
|
|
// console.info("Catched undefined error", event)
|
|
// }
|
|
this.appendError(event.error, event.filename);
|
|
}, true);
|
|
|
|
document.addEventListener('DOMContentLoaded', (event) => {
|
|
this.showErrors();
|
|
});
|
|
}
|
|
|
|
static registerFrameAwaitErrors() {
|
|
let iframes = document.getElementsByTagName('iframe');
|
|
for(let i=0; i<iframes.length; i++) {
|
|
let target = iframes[i];
|
|
target.iframeTimeout = setTimeout(
|
|
() => {
|
|
this.appendError('Cannot load iframe', target.src);},
|
|
frameErrorTimeout);
|
|
target.onload = () => {
|
|
clearTimeout(target.iframeTimeout);
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
Errors.registerGlobalErrorHandler();
|
|
|
|
class Events {
|
|
|
|
static stop(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
|
|
static extractPoint(event) {
|
|
switch (event.constructor.name) {
|
|
case 'TouchEvent':
|
|
for (let i = 0; i < event.targetTouches.length; i++) {
|
|
let t = event.targetTouches[i];
|
|
return { x: t.clientX, y: t.clientY }
|
|
}
|
|
break
|
|
default:
|
|
return { x: event.clientX, y: event.clientY }
|
|
}
|
|
}
|
|
|
|
static isCaptured(event) {
|
|
if (event.__capturedBy)
|
|
return true
|
|
return false
|
|
}
|
|
|
|
static capturedBy(event, obj) {
|
|
event.__capturedBy = obj;
|
|
}
|
|
|
|
static isMouseDown(event) {
|
|
// Attempts to clone the which attribute of events failed in WebKit. May
|
|
// be this is a bug or a security feature. Workaround: we introduce
|
|
// a mouseDownSubstitute attribute that can be assigned to cloned
|
|
// events after instantiation.
|
|
if (Reflect.has(event, 'mouseDownSubstitute'))
|
|
return event.mouseDownSubstitute
|
|
return event.buttons || event.which
|
|
}
|
|
|
|
static isSimulatedEvent(event) {
|
|
return Reflect.has(event, 'mouseDownSubstitute')
|
|
}
|
|
|
|
static isMouseRightClick(event) {
|
|
return event.buttons || event.which
|
|
}
|
|
|
|
static extractTouches(targets) {
|
|
let touches = [];
|
|
for (let i = 0; i < targets.length; i++) {
|
|
let t = targets[i];
|
|
touches.push({
|
|
targetSelector: this.selector(t.target),
|
|
identifier: t.identifier,
|
|
screenX: t.screenX,
|
|
screenY: t.screenY,
|
|
clientX: t.clientX,
|
|
clientY: t.clientY,
|
|
pageX: t.pageX,
|
|
pageY: t.pageY
|
|
});
|
|
}
|
|
return touches
|
|
}
|
|
|
|
static createTouchList(targets) {
|
|
let touches = [];
|
|
for (let i = 0; i < targets.length; i++) {
|
|
let t = targets[i];
|
|
let touchTarget = document.elementFromPoint(t.pageX, t.pageY);
|
|
let touch = new Touch(undefined, touchTarget, t.identifier,
|
|
t.pageX, t.pageY, t.screenX, t.screenY);
|
|
touches.push(touch);
|
|
}
|
|
return new TouchList(...touches)
|
|
}
|
|
|
|
static extractEvent(timestamp, event) {
|
|
let targetSelector = this.selector(event.target);
|
|
let infos = {
|
|
type: event.type,
|
|
time: timestamp,
|
|
constructor: event.constructor,
|
|
data: {
|
|
targetSelector: targetSelector,
|
|
view: event.view,
|
|
mouseDownSubstitute: event.buttons || event.which, // which cannot be cloned directly
|
|
bubbles: event.bubbles,
|
|
cancelable: event.cancelable,
|
|
screenX: event.screenX,
|
|
screenY: event.screenY,
|
|
clientX: event.clientX,
|
|
clientY: event.clientY,
|
|
layerX: event.layerX,
|
|
layerY: event.layerY,
|
|
pageX: event.pageX,
|
|
pageY: event.pageY,
|
|
ctrlKey: event.ctrlKey,
|
|
altKey: event.altKey,
|
|
shiftKey: event.shiftKey,
|
|
metaKey: event.metaKey
|
|
}
|
|
};
|
|
if (event.type.startsWith('touch')) {
|
|
// On Safari-WebKit the TouchEvent has layerX, layerY coordinates
|
|
let data = infos.data;
|
|
data.targetTouches = this.extractTouches(event.targetTouches);
|
|
data.changedTouches = this.extractTouches(event.changedTouches);
|
|
data.touches = this.extractTouches(event.touches);
|
|
}
|
|
if (event.type.startsWith('pointer')) {
|
|
let data = infos.data;
|
|
data.pointerId = event.pointerId;
|
|
data.pointerType = event.pointerType;
|
|
}
|
|
if (Events.debug) {
|
|
Events.extracted.push(this.toLine(event));
|
|
}
|
|
return infos
|
|
}
|
|
|
|
static cloneEvent(type, constructor, data) {
|
|
if (type.startsWith('touch')) {
|
|
// We need to find target from layerX, layerY
|
|
//var target = document.querySelector(data.targetSelector)
|
|
// elementFromPoint(data.layerX, data.layerY)
|
|
//data.target = target
|
|
data.targetTouches = this.createTouchList(data.targetTouches);
|
|
data.changedTouches = this.createTouchList(data.changedTouches);
|
|
data.touches = this.createTouchList(data.touches);
|
|
}
|
|
// We need to find target from pageX, pageY which are only
|
|
// available after construction. They seem to getter items.
|
|
|
|
let clone = Reflect.construct(constructor, [type, data]);
|
|
clone.mouseDownSubstitute = data.mouseDownSubstitute;
|
|
return clone
|
|
}
|
|
|
|
static simulateEvent(type, constructor, data) {
|
|
data.target = document.querySelector(data.targetSelector);
|
|
let clone = this.cloneEvent(type, constructor, data);
|
|
if (data.target != null) {
|
|
data.target.dispatchEvent(clone);
|
|
}
|
|
if (Events.debug) {
|
|
Events.simulated.push(this.toLine(clone));
|
|
}
|
|
}
|
|
|
|
static toLine(event) {
|
|
return `${event.type} #${event.target.id} ${event.clientX} ${event.clientY}`
|
|
let result = event.type;
|
|
let selector = this.selector(event.target);
|
|
result += ' selector: ' + selector;
|
|
if (event.target != document.querySelector(selector))
|
|
console.log('Cannot resolve', selector);
|
|
let keys = ['layerX', 'layerY', 'pageX', 'pageY', 'clientX', 'clientY'];
|
|
for (let key of keys) {
|
|
try {
|
|
result += ' ' + key + ':' + event[key];
|
|
}
|
|
catch (e) {
|
|
console.log('Invalid key: ' + key);
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
static compareExtractedWithSimulated() {
|
|
if (this.extracted.length != this.simulated.length) {
|
|
alert('Unequal length of extracted [' + this.extracted.length +
|
|
'] and simulated events [' + this.simulated.length + '].');
|
|
}
|
|
else {
|
|
for (let i = 0; i < this.extracted.length; i++) {
|
|
var extracted = this.extracted[i];
|
|
var simulated = this.simulated[i];
|
|
if (extracted != simulated) {
|
|
console.log('Events differ:' + extracted + '|' + simulated);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static selector(context) {
|
|
return OptimalSelect.select(context)
|
|
}
|
|
|
|
static reset() {
|
|
this.extracted = [];
|
|
this.simulated = [];
|
|
}
|
|
|
|
static resetSimulated() {
|
|
this.simulated = [];
|
|
}
|
|
|
|
static showExtractedEvents(event) {
|
|
if (!event.shiftKey) {
|
|
return
|
|
}
|
|
if (this.popup == null) {
|
|
let element = document.createElement('div');
|
|
Elements.setStyle(element, {
|
|
position: 'absolute',
|
|
width: '480px',
|
|
height: '640px',
|
|
overflow: 'auto',
|
|
backgroundColor: 'lightgray'
|
|
});
|
|
document.body.appendChild(element);
|
|
this.popup = element;
|
|
}
|
|
this.popup.innerHTML = '';
|
|
for (let line of this.extracted) {
|
|
let div = document.createElement('div');
|
|
div.innerHTML = line;
|
|
this.popup.appendChild(div);
|
|
}
|
|
let div = document.createElement('div');
|
|
div.innerHTML = '------------ Simulated -----------';
|
|
this.popup.appendChild(div);
|
|
for (let line of this.simulated) {
|
|
let div = document.createElement('div');
|
|
div.innerHTML = line;
|
|
this.popup.appendChild(div);
|
|
}
|
|
Elements.setStyle(this.popup,
|
|
{ left: event.clientX + 'px', top: event.clientY + 'px' });
|
|
}
|
|
}
|
|
|
|
Events.popup = null;
|
|
Events.debug = true;
|
|
Events.extracted = [];
|
|
Events.simulated = [];
|
|
Events.simulationRunning = false;
|
|
|
|
class EventRecorder {
|
|
|
|
constructor() {
|
|
this.recording = [];
|
|
this.recorded = [];
|
|
this.step = 0;
|
|
}
|
|
|
|
record(event) {
|
|
let length = this.recording.length;
|
|
if (length == 0) {
|
|
this.startTime = event.timeStamp;
|
|
Events.reset();
|
|
}
|
|
else {
|
|
let last = this.recording[length - 1];
|
|
if (event.timeStamp < last.time) {
|
|
console.log('warning: wrong temporal order');
|
|
}
|
|
}
|
|
let t = event.timeStamp - this.startTime;
|
|
this.recording.push(Events.extractEvent(t, event));
|
|
}
|
|
|
|
stopRecording() {
|
|
this.recorded = this.recording;
|
|
this.recording = [];
|
|
console.log('Recorded ' + this.recorded.length + ' events');
|
|
}
|
|
|
|
startReplay(whileCondition = null, onComplete = null) {
|
|
this.step = 0;
|
|
Events.resetSimulated();
|
|
console.log('Start replay');
|
|
Events.simulationRunning = true;
|
|
this.replay(whileCondition, onComplete);
|
|
}
|
|
|
|
replay(whileCondition = null, onComplete = null) {
|
|
if (this.step < this.recorded.length) {
|
|
let { type, time, constructor, data } = this.recorded[this.step];
|
|
Events.simulateEvent(type, constructor, data);
|
|
|
|
this.step += 1;
|
|
let dt = 0;
|
|
if (this.step < this.recorded.length) {
|
|
var next = this.recorded[this.step];
|
|
dt = next.time - time;
|
|
if (dt < 0) {
|
|
console.log('warning: wrong temporal order');
|
|
}
|
|
}
|
|
if (whileCondition == null || whileCondition()) {
|
|
let delta = Math.round(dt);
|
|
setTimeout(() => this.replay(whileCondition, onComplete), delta);
|
|
}
|
|
}
|
|
else {
|
|
console.log('Played ' + this.step + ' events' + onComplete);
|
|
Events.simulationRunning = false;
|
|
if (onComplete != null) {
|
|
onComplete();
|
|
}
|
|
//Events.compareExtractedWithSimulated()
|
|
}
|
|
}
|
|
}
|
|
|
|
/* globals WebKitPoint */
|
|
|
|
/** Tests whether an object is empty
|
|
* @param {Object} obj - the object to be tested
|
|
* @return {boolean}
|
|
*/
|
|
function isEmpty(obj) {
|
|
// > isEmpty({})
|
|
// true
|
|
for (let i in obj) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
function lerp(start, stop, amt) {
|
|
return amt * (stop - start) + start
|
|
}
|
|
|
|
|
|
// Returns a function, that, as long as it continues to be invoked, will not
|
|
// be triggered. The function will be called after it stops being called for
|
|
// N milliseconds. If `immediate` is passed, trigger the function on the
|
|
// leading edge, instead of the trailing.
|
|
// Taken from: https://davidwalsh.name/essential-javascript-functions
|
|
function debounce(func, wait, immediate) {
|
|
let timeout;
|
|
return function () {
|
|
let context = this,
|
|
args = arguments;
|
|
let later = function () {
|
|
timeout = null;
|
|
if (!immediate) func.apply(context, args);
|
|
};
|
|
let callNow = immediate && !timeout;
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(later, wait);
|
|
if (callNow) func.apply(context, args);
|
|
}
|
|
}
|
|
|
|
/** Returns an id that is guaranteed to be unique within the livetime of the
|
|
* application
|
|
* @return {string}
|
|
*/
|
|
let _idGenerator = 0;
|
|
function getId$1() {
|
|
return 'id' + _idGenerator++
|
|
}
|
|
|
|
function randomInt(min = 0, max = 100) {
|
|
return Math.floor(Math.random() * (max - min + 1) + min)
|
|
}
|
|
|
|
function randomFloat(min = 0.0, max = 1.0) {
|
|
return Math.random() * (max - min) + min
|
|
}
|
|
|
|
class Dates {
|
|
|
|
static create(fullYear, month, day) {
|
|
return new Date(Date.UTC(fullYear, month, day))
|
|
}
|
|
|
|
static daysInMonth(date) {
|
|
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate()
|
|
}
|
|
|
|
static startYearRange(date) {
|
|
return new Date(Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999))
|
|
}
|
|
|
|
static endYearRange(date) {
|
|
return new Date(Date.UTC(date.getFullYear() + 1, 0, 1))
|
|
}
|
|
|
|
static prevYear(date, offset = 1) {
|
|
return this.create(date.getFullYear() - offset, 0, 1)
|
|
}
|
|
|
|
static nextYear(date, offset = 1) {
|
|
return this.create(date.getFullYear() + offset, 0, 1)
|
|
}
|
|
|
|
static nextMonth(date) {
|
|
return this.create(date.getFullYear(), date.getMonth() + 1, 1)
|
|
}
|
|
|
|
static nextDay(date) {
|
|
return this.create(
|
|
date.getFullYear(),
|
|
date.getMonth(),
|
|
date.getDate() + 1
|
|
)
|
|
}
|
|
|
|
static nextHour(date) {
|
|
// See http://stackoverflow.com/questions/1050720/adding-hours-to-javascript-date-object
|
|
return new Date(date.getTime() + 60 * 60 * 1000)
|
|
}
|
|
|
|
static nextMinute(date) {
|
|
// See above
|
|
return new Date(date.getTime() + 60 * 1000)
|
|
}
|
|
|
|
static nextSecond(date) {
|
|
// See above
|
|
return new Date(date.getTime() + 1000)
|
|
}
|
|
|
|
static nextMillisecond(date) {
|
|
// See above
|
|
return new Date(date.getTime() + 1)
|
|
}
|
|
|
|
static *iterYears(start, end) {
|
|
let date = this.create(start.getFullYear(), 0, 1);
|
|
while (date <= end) {
|
|
yield date;
|
|
date = this.nextYear(date);
|
|
}
|
|
yield date;
|
|
}
|
|
|
|
static *iterMonths(year, limit = 12) {
|
|
let month = 0;
|
|
while (month < limit) {
|
|
let date = this.create(year.getFullYear(), month, 1);
|
|
yield date;
|
|
month += 1;
|
|
}
|
|
}
|
|
|
|
static *iterMonthsOfYears(years) {
|
|
for (let year of years) {
|
|
for (let month of this.iterMonths(year)) {
|
|
yield month;
|
|
}
|
|
}
|
|
}
|
|
|
|
static *iterDays(month) {
|
|
let day = 1;
|
|
let limit = Dates.daysInMonth(month);
|
|
while (day <= limit) {
|
|
let date = this.create(month.getFullYear(), month.getMonth(), day);
|
|
yield date;
|
|
day += 1;
|
|
}
|
|
}
|
|
|
|
static *iterDaysOfMonths(months) {
|
|
for (let month of months) {
|
|
for (let day of this.iterDays(month)) {
|
|
yield day;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* Color conversion functions */
|
|
|
|
class Colors {
|
|
// http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
|
|
|
|
static rgb2num(red, green, blue) {
|
|
let rgb = blue | (green << 8) | (red << 16);
|
|
return 0x000000 + rgb
|
|
}
|
|
|
|
static rgb2hex(red, green, blue) {
|
|
let rgb = blue | (green << 8) | (red << 16);
|
|
return '#' + (0x1000000 + rgb).toString(16).slice(1)
|
|
}
|
|
|
|
static hex2rgb(hex) {
|
|
// long version
|
|
let r = hex.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
|
|
if (r) {
|
|
return r.slice(1, 4).map(x => {
|
|
return parseInt(x, 16)
|
|
})
|
|
}
|
|
// short version
|
|
r = hex.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i);
|
|
if (r) {
|
|
return r.slice(1, 4).map(x => {
|
|
return 0x11 * parseInt(x, 16)
|
|
})
|
|
}
|
|
return null
|
|
}
|
|
|
|
static rgb(r, g, b) {
|
|
return { r, g, b }
|
|
}
|
|
|
|
static string2hex(str) {
|
|
return parseInt('0x' + str.slice(1))
|
|
}
|
|
|
|
static lerp(rgb1, rgb2, amount) {
|
|
return {
|
|
r: Math.round(lerp(rgb1.r, rgb2.r, amount)),
|
|
g: Math.round(lerp(rgb1.g, rgb2.g, amount)),
|
|
b: Math.round(lerp(rgb1.b, rgb2.b, amount))
|
|
}
|
|
}
|
|
|
|
static get violet() {
|
|
return Colors.rgb2num(89, 34, 131)
|
|
}
|
|
|
|
static get steelblue() {
|
|
return Colors.rgb2num(0, 130, 164)
|
|
}
|
|
|
|
static get ochre() {
|
|
return Colors.rgb2num(181, 157, 0)
|
|
}
|
|
|
|
static get turquoise() {
|
|
return Colors.rgb2num(34, 164, 131)
|
|
}
|
|
|
|
static get eminence() {
|
|
return Colors.rgb2num(150, 60, 134)
|
|
}
|
|
|
|
static random() {
|
|
let r = Math.round(Math.random() * 255);
|
|
let g = Math.round(Math.random() * 255);
|
|
let b = Math.round(Math.random() * 255);
|
|
return Colors.rgb2num(r, g, b)
|
|
}
|
|
}
|
|
|
|
class Cycle extends Array {
|
|
constructor(...items) {
|
|
super();
|
|
for (let item of items) {
|
|
this.push(item);
|
|
}
|
|
this.index = 0;
|
|
}
|
|
|
|
next() {
|
|
if (this.index == this.length) {
|
|
this.index = 0;
|
|
}
|
|
return this[this.index++]
|
|
}
|
|
|
|
current() {
|
|
if (this.index === this.length) {
|
|
this.index = 0;
|
|
}
|
|
return this[this.index]
|
|
}
|
|
}
|
|
|
|
/** Static methods to compute 2D points with x and y coordinates.
|
|
*/
|
|
class Points {
|
|
static length(a) {
|
|
return Math.sqrt(a.x * a.x + a.y * a.y)
|
|
}
|
|
|
|
static normalize(p) {
|
|
let len = this.length(p);
|
|
return this.multiplyScalar(p, 1 / len)
|
|
}
|
|
|
|
static mean(a, b) {
|
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }
|
|
}
|
|
|
|
static subtract(a, b) {
|
|
return { x: a.x - b.x, y: a.y - b.y }
|
|
}
|
|
|
|
static multiply(a, b) {
|
|
return { x: a.x * b.x, y: a.y * b.y }
|
|
}
|
|
|
|
static divide(a, b) {
|
|
return { x: a.x / b.x, y: a.y / b.y }
|
|
}
|
|
|
|
static multiplyScalar(a, b) {
|
|
return { x: a.x * b, y: a.y * b }
|
|
}
|
|
|
|
static add(a, b) {
|
|
return { x: a.x + b.x, y: a.y + b.y }
|
|
}
|
|
|
|
static negate(p) {
|
|
return { x: -p.x, y: -p.y }
|
|
}
|
|
|
|
static angle(p1, p2) {
|
|
return Math.atan2(p1.y - p2.y, p1.x - p2.x)
|
|
}
|
|
|
|
static normalizedAngle(p1, p2) {
|
|
return Angle.normalize(this.angle(p1, p2))
|
|
}
|
|
|
|
static normalized2Angle(p1, p2) {
|
|
return Angle.normalize2(this.angle(p1, p2))
|
|
}
|
|
|
|
static arc(p, alpha, radius) {
|
|
return {
|
|
x: p.x + radius * Math.cos(alpha),
|
|
y: p.y + radius * Math.sin(alpha)
|
|
}
|
|
}
|
|
|
|
static distance(a, b) {
|
|
let dx = a.x - b.x;
|
|
let dy = a.y - b.y;
|
|
return Math.sqrt(dx * dx + dy * dy)
|
|
}
|
|
|
|
static fromPageToNode(element, p) {
|
|
// if (window.webkitConvertPointFromPageToNode) {
|
|
// return window.webkitConvertPointFromPageToNode(element,
|
|
// new WebKitPoint(p.x, p.y))
|
|
// }
|
|
return window.convertPointFromPageToNode(element, p.x, p.y)
|
|
}
|
|
|
|
static fromNodeToPage(element, p) {
|
|
// if (window.webkitConvertPointFromNodeToPage) {
|
|
// return window.webkitConvertPointFromNodeToPage(element,
|
|
// new WebKitPoint(p.x, p.y))
|
|
// }
|
|
return window.convertPointFromNodeToPage(element, p.x, p.y)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A helper class for common set operations.
|
|
*
|
|
* @export
|
|
* @class Sets
|
|
*/
|
|
class Sets {
|
|
|
|
/**
|
|
* Returns the intersection of all sets
|
|
* https://stackoverflow.com/questions/31930894/javascript-set-data-structure-intersect
|
|
* @static
|
|
* @param {*} sets
|
|
* @returns
|
|
* @memberof Sets
|
|
*/
|
|
static intersect(...sets) {
|
|
if (!sets.length) return new Set()
|
|
const i = sets.reduce((m, s, i) => s.size < sets[m].size ? i : m, 0);
|
|
const [smallest] = sets.splice(i, 1);
|
|
const res = new Set();
|
|
for (let val of smallest)
|
|
if (sets.every(s => s.has(val)))
|
|
res.add(val);
|
|
return res
|
|
}
|
|
|
|
/**
|
|
* Returns the union of all sets
|
|
*
|
|
* @static
|
|
* @param {*} sets
|
|
* @returns
|
|
* @memberof Sets
|
|
*/
|
|
static union(...sets) {
|
|
let result = new Set();
|
|
for (let set of sets) {
|
|
for (let m of set) {
|
|
result.add(m);
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* Returns the difference of the given sets. Starts with the first set and removing all elements of the following sets.
|
|
*
|
|
* @static
|
|
* @param {*} set
|
|
* @param {*} sets
|
|
* @returns
|
|
* @memberof Sets
|
|
*/
|
|
static difference(set, ...sets) {
|
|
let result = new Set();
|
|
for (let m of set) {
|
|
result.add(m);
|
|
}
|
|
for (let s of sets) {
|
|
for (let m of s) {
|
|
result.delete(m);
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
/** Static methods to compute angles.
|
|
*/
|
|
class Angle {
|
|
|
|
static normalize(angle) {
|
|
let TAU = Math.PI * 2.0;
|
|
while (angle > Math.PI) {
|
|
angle -= TAU;
|
|
}
|
|
while (angle < -Math.PI) {
|
|
angle += TAU;
|
|
}
|
|
return angle
|
|
}
|
|
|
|
static normalize2(angle) {
|
|
let TAU = Math.PI * 2.0;
|
|
while (angle > TAU) {
|
|
angle -= TAU;
|
|
}
|
|
while (angle < 0) {
|
|
angle += TAU;
|
|
}
|
|
return angle
|
|
}
|
|
|
|
static normalizeDegree(angle) {
|
|
let full = 360.0;
|
|
while (angle > 180.0) {
|
|
angle -= full;
|
|
}
|
|
while (angle < -180.0) {
|
|
angle += full;
|
|
}
|
|
return angle
|
|
}
|
|
|
|
static normalizedDiff(a, b) {
|
|
return this.normalize(this.diff(a, b))
|
|
}
|
|
|
|
static normalized2Diff(a, b) {
|
|
return this.normalize2(this.diff(a, b))
|
|
}
|
|
|
|
static diff(a, b) {
|
|
return Math.atan2(Math.sin(a - b), Math.cos(a - b))
|
|
}
|
|
|
|
static degree2radian(degree) {
|
|
return Math.PI * degree / 180.0
|
|
}
|
|
|
|
static radian2degree(rad) {
|
|
return 180.0 / Math.PI * rad
|
|
}
|
|
}
|
|
|
|
class Elements$1 {
|
|
static setStyle(element, styles) {
|
|
for (let key in styles) {
|
|
element.style[key] = styles[key];
|
|
}
|
|
}
|
|
|
|
static addClass(element, cssClass) {
|
|
element.classList.add(cssClass);
|
|
}
|
|
|
|
static removeClass(element, cssClass) {
|
|
element.classList.remove(cssClass);
|
|
}
|
|
|
|
static toggleClass(element, cssClass) {
|
|
element.classList.toggle(cssClass);
|
|
}
|
|
|
|
static hasClass(element, cssClass) {
|
|
return element.classList.contains(cssClass)
|
|
}
|
|
}
|
|
|
|
class MapProxy {
|
|
/* This class is needed if we want to use the interaction classes
|
|
in Firefox 45.8 and modern Browsers.
|
|
|
|
A workaround for https://github.com/babel/babel/issues/2334
|
|
*/
|
|
constructor() {
|
|
this.map = new Map();
|
|
}
|
|
|
|
get size() {
|
|
return this.map.size
|
|
}
|
|
|
|
get(key) {
|
|
return this.map.get(key)
|
|
}
|
|
|
|
set(key, value) {
|
|
return this.map.set(key, value)
|
|
}
|
|
|
|
delete(key) {
|
|
return this.map.delete(key)
|
|
}
|
|
|
|
clear() {
|
|
return this.map.clear()
|
|
}
|
|
|
|
has(key) {
|
|
return this.map.has(key)
|
|
}
|
|
|
|
keys() {
|
|
return this.map.keys()
|
|
}
|
|
|
|
values() {
|
|
return this.map.values()
|
|
}
|
|
|
|
entries() {
|
|
return this.map.entries()
|
|
}
|
|
|
|
forEach(func) {
|
|
this.map.forEach(func);
|
|
}
|
|
}
|
|
|
|
/* Based om https://gist.github.com/cwleonard/e124d63238bda7a3cbfa */
|
|
class Polygon {
|
|
/*
|
|
* This is the Polygon constructor. All points are center-relative.
|
|
*/
|
|
constructor(center) {
|
|
this.points = new Array();
|
|
this.center = center;
|
|
}
|
|
|
|
/*
|
|
* Point x and y values should be relative to the center.
|
|
*/
|
|
addPoint(p) {
|
|
this.points.push(p);
|
|
}
|
|
|
|
/*
|
|
* Point x and y values should be absolute coordinates.
|
|
*/
|
|
addAbsolutePoint(p) {
|
|
this.points.push({ x: p.x - this.center.x, y: p.y - this.center.y });
|
|
}
|
|
|
|
/*
|
|
* Returns the number of sides. Equal to the number of vertices.
|
|
*/
|
|
getNumberOfSides() {
|
|
return this.points.length
|
|
}
|
|
|
|
/*
|
|
* rotate the polygon by a number of radians
|
|
*/
|
|
rotate(rads) {
|
|
for (let i = 0; i < this.points.length; i++) {
|
|
let x = this.points[i].x;
|
|
let y = this.points[i].y;
|
|
this.points[i].x = Math.cos(rads) * x - Math.sin(rads) * y;
|
|
this.points[i].y = Math.sin(rads) * x + Math.cos(rads) * y;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The draw function takes as a parameter a Context object from
|
|
* a Canvas element and draws the polygon on it.
|
|
*/
|
|
draw(context, { lineWidth = 2, stroke = '#000000', fill = null } = {}) {
|
|
context.beginPath();
|
|
context.moveTo(
|
|
this.points[0].x + this.center.x,
|
|
this.points[0].y + this.center.y
|
|
);
|
|
for (let i = 1; i < this.points.length; i++) {
|
|
context.lineTo(
|
|
this.points[i].x + this.center.x,
|
|
this.points[i].y + this.center.y
|
|
);
|
|
}
|
|
context.closePath();
|
|
context.lineWidth = lineWidth;
|
|
if (stroke) {
|
|
context.strokeStyle = stroke;
|
|
context.stroke();
|
|
}
|
|
if (fill) {
|
|
context.fillStyle = fill;
|
|
context.fill();
|
|
}
|
|
}
|
|
|
|
absolutePoints() {
|
|
let result = new Array();
|
|
for (let p of this.points) {
|
|
result.push(Points.add(p, this.center));
|
|
}
|
|
return result
|
|
}
|
|
|
|
flatAbsolutePoints() {
|
|
let result = new Array();
|
|
for (let p of this.points) {
|
|
let a = Points.add(p, this.center);
|
|
result.push(a.x);
|
|
result.push(a.y);
|
|
}
|
|
return result
|
|
}
|
|
|
|
/*
|
|
* This function returns true if the given point is inside the polygon,
|
|
* and false otherwise.
|
|
*/
|
|
containsPoint(pnt) {
|
|
let nvert = this.points.length;
|
|
let testx = pnt.x;
|
|
let testy = pnt.y;
|
|
|
|
let vertx = new Array();
|
|
for (let q = 0; q < this.points.length; q++) {
|
|
vertx.push(this.points[q].x + this.center.x);
|
|
}
|
|
|
|
let verty = new Array();
|
|
for (let w = 0; w < this.points.length; w++) {
|
|
verty.push(this.points[w].y + this.center.y);
|
|
}
|
|
|
|
let i,
|
|
j = 0;
|
|
let c = false;
|
|
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
|
|
if (
|
|
verty[i] > testy != verty[j] > testy &&
|
|
testx <
|
|
(vertx[j] - vertx[i]) *
|
|
(testy - verty[i]) /
|
|
(verty[j] - verty[i]) +
|
|
vertx[i]
|
|
)
|
|
c = !c;
|
|
}
|
|
return c
|
|
}
|
|
|
|
multiplyScalar(scale) {
|
|
let center = Points.multiplyScalar(this.center, scale);
|
|
let clone = new Polygon(center);
|
|
for (let p of this.points) {
|
|
clone.addPoint(Points.multiplyScalar(p, scale));
|
|
}
|
|
return clone
|
|
}
|
|
|
|
/*
|
|
* To detect intersection with another Polygon object, this
|
|
* function uses the Separating Axis Theorem. It returns false
|
|
* if there is no intersection, or an object if there is. The object
|
|
* contains 2 fields, overlap and axis. Moving the polygon by overlap
|
|
* on axis will get the polygons out of intersection.
|
|
*/
|
|
intersectsWith(other) {
|
|
let axis = { x: 0, y: 0 };
|
|
let tmp, minA, maxA, minB, maxB;
|
|
let side, i;
|
|
let smallest = null;
|
|
let overlap = 99999999;
|
|
|
|
/* test polygon A's sides */
|
|
for (side = 0; side < this.getNumberOfSides(); side++) {
|
|
/* get the axis that we will project onto */
|
|
if (side == 0) {
|
|
axis.x =
|
|
this.points[this.getNumberOfSides() - 1].y -
|
|
this.points[0].y;
|
|
axis.y =
|
|
this.points[0].x -
|
|
this.points[this.getNumberOfSides() - 1].x;
|
|
} else {
|
|
axis.x = this.points[side - 1].y - this.points[side].y;
|
|
axis.y = this.points[side].x - this.points[side - 1].x;
|
|
}
|
|
|
|
/* normalize the axis */
|
|
tmp = Math.sqrt(axis.x * axis.x + axis.y * axis.y);
|
|
axis.x /= tmp;
|
|
axis.y /= tmp;
|
|
|
|
/* project polygon A onto axis to determine the min/max */
|
|
minA = maxA = this.points[0].x * axis.x + this.points[0].y * axis.y;
|
|
for (i = 1; i < this.getNumberOfSides(); i++) {
|
|
tmp = this.points[i].x * axis.x + this.points[i].y * axis.y;
|
|
if (tmp > maxA) maxA = tmp;
|
|
else if (tmp < minA) minA = tmp;
|
|
}
|
|
/* correct for offset */
|
|
tmp = this.center.x * axis.x + this.center.y * axis.y;
|
|
minA += tmp;
|
|
maxA += tmp;
|
|
|
|
/* project polygon B onto axis to determine the min/max */
|
|
minB = maxB =
|
|
other.points[0].x * axis.x + other.points[0].y * axis.y;
|
|
for (i = 1; i < other.getNumberOfSides(); i++) {
|
|
tmp = other.points[i].x * axis.x + other.points[i].y * axis.y;
|
|
if (tmp > maxB) maxB = tmp;
|
|
else if (tmp < minB) minB = tmp;
|
|
}
|
|
/* correct for offset */
|
|
tmp = other.center.x * axis.x + other.center.y * axis.y;
|
|
minB += tmp;
|
|
maxB += tmp;
|
|
|
|
/* test if lines intersect, if not, return false */
|
|
if (maxA < minB || minA > maxB) {
|
|
return false
|
|
} else {
|
|
let o = maxA > maxB ? maxB - minA : maxA - minB;
|
|
if (o < overlap) {
|
|
overlap = o;
|
|
smallest = { x: axis.x, y: axis.y };
|
|
}
|
|
}
|
|
}
|
|
|
|
/* test polygon B's sides */
|
|
for (side = 0; side < other.getNumberOfSides(); side++) {
|
|
/* get the axis that we will project onto */
|
|
if (side == 0) {
|
|
axis.x =
|
|
other.points[other.getNumberOfSides() - 1].y -
|
|
other.points[0].y;
|
|
axis.y =
|
|
other.points[0].x -
|
|
other.points[other.getNumberOfSides() - 1].x;
|
|
} else {
|
|
axis.x = other.points[side - 1].y - other.points[side].y;
|
|
axis.y = other.points[side].x - other.points[side - 1].x;
|
|
}
|
|
|
|
/* normalize the axis */
|
|
tmp = Math.sqrt(axis.x * axis.x + axis.y * axis.y);
|
|
axis.x /= tmp;
|
|
axis.y /= tmp;
|
|
|
|
/* project polygon A onto axis to determine the min/max */
|
|
minA = maxA = this.points[0].x * axis.x + this.points[0].y * axis.y;
|
|
for (i = 1; i < this.getNumberOfSides(); i++) {
|
|
tmp = this.points[i].x * axis.x + this.points[i].y * axis.y;
|
|
if (tmp > maxA) maxA = tmp;
|
|
else if (tmp < minA) minA = tmp;
|
|
}
|
|
/* correct for offset */
|
|
tmp = this.center.x * axis.x + this.center.y * axis.y;
|
|
minA += tmp;
|
|
maxA += tmp;
|
|
|
|
/* project polygon B onto axis to determine the min/max */
|
|
minB = maxB =
|
|
other.points[0].x * axis.x + other.points[0].y * axis.y;
|
|
for (i = 1; i < other.getNumberOfSides(); i++) {
|
|
tmp = other.points[i].x * axis.x + other.points[i].y * axis.y;
|
|
if (tmp > maxB) maxB = tmp;
|
|
else if (tmp < minB) minB = tmp;
|
|
}
|
|
/* correct for offset */
|
|
tmp = other.center.x * axis.x + other.center.y * axis.y;
|
|
minB += tmp;
|
|
maxB += tmp;
|
|
|
|
/* test if lines intersect, if not, return false */
|
|
if (maxA < minB || minA > maxB) {
|
|
return false
|
|
} else {
|
|
let o = maxA > maxB ? maxB - minA : maxA - minB;
|
|
if (o < overlap) {
|
|
overlap = o;
|
|
smallest = { x: axis.x, y: axis.y };
|
|
}
|
|
}
|
|
}
|
|
return { overlap: overlap + 0.001, axis: smallest }
|
|
}
|
|
|
|
static fromPoints(points) {
|
|
let min = { x: Number.MAX_VALUE, y: Number.MAX_VALUE };
|
|
let max = { x: Number.MIN_VALUE, y: Number.MIN_VALUE };
|
|
for (let p of points) {
|
|
min.x = Math.min(p.x, min.x);
|
|
max.x = Math.max(p.x, max.x);
|
|
min.y = Math.min(p.y, min.y);
|
|
max.y = Math.max(p.y, max.y);
|
|
}
|
|
let center = Points.mean(min, max);
|
|
let polygon = new Polygon(center);
|
|
for (let p of points) {
|
|
polygon.addAbsolutePoint(p);
|
|
}
|
|
return polygon
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Util functions to deal with DOMRects.
|
|
*/
|
|
class Rect {
|
|
|
|
|
|
/**
|
|
* Test if a given point is contained by the provided Rect.
|
|
*
|
|
* @static
|
|
* @param {DOMRect} rect - Rectangle to check the collision with.
|
|
* @param {Point} point - Point that should be tested.
|
|
* @returns {boolean} - True if point is inside of rect, otherwise false.
|
|
* @memberof Rect
|
|
*/
|
|
static contains(rect, point) {
|
|
return (point.x > rect.left &&
|
|
point.x < rect.x + rect.right
|
|
&& point.y > rect.top && point.y < rect.bottom)
|
|
}
|
|
|
|
|
|
/**
|
|
*Returns the position of an rect as point object.
|
|
*
|
|
* @static
|
|
* @param {Rect} rect - The rectangle we want to get the position from.
|
|
* @returns {Point} - Returns the position as Point.
|
|
* @memberof Rect
|
|
*/
|
|
static getPosition(rect) {
|
|
return { x: rect.x, y: rect.y }
|
|
}
|
|
}
|
|
|
|
/** String utility functions */
|
|
|
|
class Strings {
|
|
|
|
static toUpperCaseFirstChar(str) {
|
|
return str.substr(0, 1).toUpperCase() + str.substr(1)
|
|
}
|
|
|
|
static toLowerCaseFirstChar(str) {
|
|
return str.substr(0, 1).toLowerCase() + str.substr(1)
|
|
}
|
|
|
|
static toUpperCaseEachWord(str, delim = ' ') {
|
|
return str.split(delim).map((v) => v.toUpperCaseFirstChar()).join(delim)
|
|
}
|
|
|
|
static toLowerCaseEachWord(str, delim = ' ') {
|
|
return str.split(delim).map((v) => v.toLowerCaseFirstChar()).join(delim)
|
|
}
|
|
|
|
}
|
|
|
|
/* globals Hammer, propagating */
|
|
|
|
/** Interaction patterns
|
|
|
|
See interaction.html for explanation
|
|
*/
|
|
|
|
class IInteractionTarget extends Interface {
|
|
capture(event) {
|
|
return typeof true
|
|
}
|
|
|
|
onStart(event, interaction) { }
|
|
onMove(event, interaction) { }
|
|
onEnd(event, interaction) { }
|
|
|
|
onMouseWheel(event) { }
|
|
}
|
|
|
|
class IInteractionMapperTarget extends Interface {
|
|
capture(event) {
|
|
return typeof true
|
|
}
|
|
|
|
findTarget(event, local, global) {
|
|
return IInteractionTarget
|
|
}
|
|
}
|
|
|
|
class PointMap extends MapProxy {
|
|
// Collects touch points, mouse coordinates, etc. as key value pairs.
|
|
// Keys are pointer and touch ids, the special "mouse" key.
|
|
// Values are points, i.e. all objects with numeric x and y properties.
|
|
constructor(points = {}) {
|
|
super();
|
|
for (let key in points) {
|
|
this.set(key, points[key]);
|
|
}
|
|
}
|
|
|
|
toString() {
|
|
let points = [];
|
|
for (let key of this.keys()) {
|
|
let value = this.get(key);
|
|
points.push(`${key}:{x:${value.x}, y:${value.y}}`);
|
|
}
|
|
let attrs = points.join(', ');
|
|
return `[PointMap ${attrs}]`
|
|
}
|
|
|
|
clone() {
|
|
let result = new PointMap();
|
|
for (let key of this.keys()) {
|
|
let value = this.get(key);
|
|
result.set(key, { x: value.x, y: value.y });
|
|
}
|
|
return result
|
|
}
|
|
|
|
keyOf(value) {
|
|
for (let key of this.keys()) {
|
|
let p = this.get(key);
|
|
if (p.x == value.x && p.y == value.y) {
|
|
return key
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
firstKey() {
|
|
for (let key of this.keys()) {
|
|
return key
|
|
}
|
|
return null
|
|
}
|
|
|
|
first() {
|
|
for (let key of this.keys()) {
|
|
return this.get(key)
|
|
}
|
|
return null
|
|
}
|
|
|
|
farthests() {
|
|
if (this.size == 0) {
|
|
return null
|
|
}
|
|
let pairs = [];
|
|
for (let key of this.keys()) {
|
|
let p = this.get(key);
|
|
p.key = key;
|
|
for (let k of this.keys()) {
|
|
let q = this.get(k);
|
|
q.key = k;
|
|
pairs.push([p, q]);
|
|
}
|
|
}
|
|
let sorted = pairs.sort((a, b) => {
|
|
return Points.distance(b[0], b[1]) - Points.distance(a[0], a[1])
|
|
});
|
|
return sorted[0]
|
|
}
|
|
|
|
mean() {
|
|
if (this.size == 0) {
|
|
return null
|
|
}
|
|
let x = 0.0,
|
|
y = 0.0;
|
|
for (let p of this.values()) {
|
|
x += p.x;
|
|
y += p.y;
|
|
}
|
|
return { x: x / this.size, y: y / this.size }
|
|
}
|
|
}
|
|
|
|
class InteractionDelta {
|
|
constructor(x, y, zoom, rotate, about) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.zoom = zoom;
|
|
this.rotate = rotate;
|
|
this.about = about;
|
|
}
|
|
|
|
toString() {
|
|
let values = [];
|
|
for (let key of Object.keys(this)) {
|
|
let value = this[key];
|
|
if (key == 'about') {
|
|
values.push(`${key}:{x:${value.x}, y:${value.y}}`);
|
|
} else {
|
|
values.push(`${key}:${value}`);
|
|
}
|
|
}
|
|
let attrs = values.join(', ');
|
|
return `[InteractionDelta ${attrs}]`
|
|
}
|
|
}
|
|
|
|
class InteractionPoints {
|
|
constructor(parent = null) {
|
|
this.parent = parent;
|
|
this.current = new PointMap();
|
|
this.previous = new PointMap();
|
|
this.start = new PointMap();
|
|
this.ended = new PointMap();
|
|
this.timestamps = new Map();
|
|
}
|
|
|
|
moved(key) {
|
|
let current = this.current.get(key);
|
|
let previous = this.previous.get(key);
|
|
return Points.subtract(current, previous)
|
|
}
|
|
|
|
move() {
|
|
let current = this.current.mean();
|
|
let previous = this.previous.mean();
|
|
return Points.subtract(current, previous)
|
|
}
|
|
|
|
/**
|
|
* Computes the delta between previous and current angles. Corrects
|
|
* value that are larger than 45°
|
|
* @param {*} a
|
|
* @param {*} b
|
|
* @returns delta
|
|
*/
|
|
diffAngle(a, b) {
|
|
let alpha = Math.atan2(Math.sin(a - b), Math.cos(a - b));
|
|
if (Math.abs(alpha) > Math.PI / 4) {
|
|
alpha -= Math.PI;
|
|
}
|
|
return alpha
|
|
}
|
|
|
|
/**
|
|
* Computes the delta between interaction points at t and t+1.
|
|
*
|
|
* @returns InteractionDelta
|
|
* @memberof InteractionPoints
|
|
*/
|
|
delta() {
|
|
let csize = this.current.size;
|
|
let psize = this.previous.size;
|
|
if (csize >= 2 && csize == psize) {
|
|
// Reduce to the two farthests points
|
|
let current = this.current.farthests();
|
|
|
|
let c1 = current[0];
|
|
let c2 = current[1];
|
|
|
|
let p1 = this.previous.get(c1.key);
|
|
let p2 = this.previous.get(c2.key);
|
|
|
|
//let p1 = previous[0]
|
|
//let p2 = previous[1]
|
|
|
|
let d1 = Points.subtract(c1, p1);
|
|
let d2 = Points.subtract(c2, p2);
|
|
let cm = Points.mean(c1, c2);
|
|
//let pm = Points.mean(p1, p2)
|
|
// UO: Using the mean lead to jumps between time slices with 3 and 2 fingers
|
|
// We use the mean of deltas instead
|
|
let delta = Points.mean(d1, d2); //Points.subtract(cm, pm)
|
|
let zoom = 1.0;
|
|
let distance1 = Points.distance(p1, p2);
|
|
let distance2 = Points.distance(c1, c2);
|
|
if (distance1 != 0 && distance2 != 0) {
|
|
zoom = distance2 / distance1;
|
|
}
|
|
let currentAngle = Points.angle(c1, c2);
|
|
let previousAngle = Points.angle(p1, p2);
|
|
let alpha = this.diffAngle(currentAngle, previousAngle);
|
|
return new InteractionDelta(delta.x, delta.y, zoom, alpha, cm)
|
|
} else if (csize == 1 && psize == 1 && this.current.firstKey() == this.previous.firstKey()) {
|
|
// We need to ensure that the keys are the same
|
|
let current = this.current.first();
|
|
let previous = this.previous.first();
|
|
let delta = Points.subtract(current, previous);
|
|
return new InteractionDelta(delta.x, delta.y, 1.0, 0.0, current)
|
|
}
|
|
return null
|
|
}
|
|
|
|
started(key, point) {
|
|
this.current.set(key, point);
|
|
this.start.set(key, point);
|
|
this.previous.set(key, point);
|
|
this.timestamps.set(key, performance.now());
|
|
}
|
|
|
|
update(key, point) {
|
|
// Returns true iff the key is new
|
|
this.current.set(key, point);
|
|
if (!this.start.has(key)) {
|
|
this.start.set(key, point);
|
|
this.previous.set(key, point);
|
|
this.timestamps.set(key, performance.now());
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
updatePrevious() {
|
|
for (let key of this.current.keys()) {
|
|
this.previous.set(key, this.current.get(key));
|
|
}
|
|
}
|
|
|
|
stop(key, point) {
|
|
if (this.current.has(key)) {
|
|
this.current.delete(key);
|
|
this.previous.delete(key);
|
|
this.ended.set(key, point);
|
|
}
|
|
}
|
|
|
|
finish(key, point) {
|
|
this.current.delete(key);
|
|
this.previous.delete(key);
|
|
this.start.delete(key);
|
|
this.timestamps.delete(key);
|
|
this.ended.delete(key);
|
|
}
|
|
|
|
isFinished() {
|
|
return this.current.size == 0
|
|
}
|
|
|
|
isNoLongerTwoFinger() {
|
|
return this.previous.size > 1 && this.current.size < 2
|
|
}
|
|
|
|
isTap(key) {
|
|
return this.parent.isTap(key)
|
|
}
|
|
|
|
isDoubleTap(key) {
|
|
return this.parent.isDoubleTap(key)
|
|
}
|
|
|
|
isLongPress(key) {
|
|
return this.parent.isLongPress(key)
|
|
}
|
|
}
|
|
|
|
class Interaction extends InteractionPoints {
|
|
constructor(tapDistance = 10, tapDuration = 250.0, longPressTime = 500.0) {
|
|
super();
|
|
this.tapDistance = tapDistance;
|
|
this.tapCounts = new Map();
|
|
this.tapPositions = new Map();
|
|
this.tapTimestamps = new Map();
|
|
this.tapDuration = tapDuration;
|
|
this.longPressTime = longPressTime;
|
|
this.targets = new Map();
|
|
this.subInteractions = new Map(); // target:Object : InteractionPoints
|
|
}
|
|
|
|
stop(key, point) {
|
|
super.stop(key, point);
|
|
for (let points of this.subInteractions.values()) {
|
|
points.stop(key, point);
|
|
}
|
|
}
|
|
|
|
addTarget(key, target) {
|
|
this.targets.set(key, target);
|
|
this.subInteractions.set(target, new InteractionPoints(this));
|
|
}
|
|
|
|
removeTarget(key) {
|
|
let target = this.targets.get(key);
|
|
this.targets.delete(key);
|
|
// Only remove target if no keys are refering to the target
|
|
let remove = true;
|
|
for (let t of this.targets.values()) {
|
|
if (target === t) {
|
|
remove = false;
|
|
}
|
|
}
|
|
if (remove) {
|
|
this.subInteractions.delete(target);
|
|
}
|
|
}
|
|
|
|
finish(key, point) {
|
|
super.finish(key, point);
|
|
this.removeTarget(key);
|
|
}
|
|
|
|
mapInteraction(points, aspects, mappingFunc) {
|
|
// Map centrally registered points to target interactions
|
|
// Returns an array of [target, updated subInteraction] pairs
|
|
let result = new Map();
|
|
for (let key in points) {
|
|
if (this.targets.has(key)) {
|
|
let target = this.targets.get(key);
|
|
if (this.subInteractions.has(target)) {
|
|
let interaction = this.subInteractions.get(target);
|
|
for (let aspect of aspects) {
|
|
let pointMap = this[aspect];
|
|
let point = pointMap.get(key);
|
|
let mapped = mappingFunc(point, target);
|
|
interaction[aspect].set(key, mapped);
|
|
}
|
|
result.set(target, interaction);
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
registerTap(key, point) {
|
|
if (this.tapCounts.has(key)) {
|
|
let count = this.tapCounts.get(key);
|
|
this.tapCounts.set(key, count+1);
|
|
}
|
|
else {
|
|
this.tapCounts.set(key, 1);
|
|
}
|
|
this.tapPositions.set(key, point);
|
|
this.tapTimestamps.set(key, performance.now());
|
|
}
|
|
|
|
unregisterTap(key) {
|
|
this.tapCounts.delete(key);
|
|
this.tapPositions.delete(key);
|
|
this.tapTimestamps.delete(key);
|
|
}
|
|
|
|
isTap(key) {
|
|
let ended = this.ended.get(key);
|
|
let start = this.start.get(key);
|
|
if (
|
|
start &&
|
|
ended &&
|
|
Points.distance(ended, start) < this.tapDistance
|
|
) {
|
|
let t1 = this.timestamps.get(key);
|
|
let tookLong = performance.now() > t1 + this.longPressTime;
|
|
if (tookLong) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
isDoubleTap(key) {
|
|
let ended = this.ended.get(key);
|
|
if (this.tapCounts.has(key) && this.tapCounts.get(key) > 2) {
|
|
this.unregisterTap(key);
|
|
}
|
|
if (this.tapPositions.has(key)) {
|
|
let pos = this.tapPositions.get(key);
|
|
if (Points.distance(ended, pos) > this.tapDistance) {
|
|
this.unregisterTap(key);
|
|
}
|
|
}
|
|
if (this.tapTimestamps.has(key) && performance.now() > this.tapTimestamps.get(key) + this.tapDuration) {
|
|
//console.log("tap too long")
|
|
this.unregisterTap(key);
|
|
}
|
|
let result = false;
|
|
if (this.isTap(key)) {
|
|
|
|
this.registerTap(key, ended);
|
|
result = this.tapCounts.get(key) == 2;
|
|
}
|
|
else {
|
|
this.unregisterTap(key);
|
|
}
|
|
//console.log("isDoubleTap", this.tapCounts.get(key), result)
|
|
return result
|
|
}
|
|
|
|
isAnyTap() {
|
|
for (let key of this.ended.keys()) {
|
|
if (this.isTap(key)) return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
isLongPress(key) {
|
|
let ended = this.ended.get(key);
|
|
let start = this.start.get(key);
|
|
if (
|
|
start &&
|
|
ended &&
|
|
Points.distance(ended, start) < this.tapDistance
|
|
) {
|
|
let t1 = this.timestamps.get(key);
|
|
let tookLong = performance.now() > t1 + this.longPressTime;
|
|
if (tookLong) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
return false
|
|
}
|
|
|
|
isAnyLongPress() {
|
|
for (let key of this.ended.keys()) {
|
|
if (this.isLongPress(key)) return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
isStylus(key) {
|
|
return key === 'stylus'
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This class implements the main delegate functionality: All necessary event handlers are registered for the
|
|
* given element. Uses PointerEvents if available or TouchEvents on iOS. The fallback is on mouse events.
|
|
* Collects the events if the interaction target captures the start event (i.e. declares that
|
|
* the target wants the start event as well as all following move and end evcents.)
|
|
*
|
|
* @export
|
|
* @class InteractionDelegate
|
|
*/
|
|
class InteractionDelegate {
|
|
// Long press: http://stackoverflow.com/questions/1930895/how-long-is-the-event-onlongpress-in-the-android
|
|
// Stylus support: https://w3c.github.io/touch-events/
|
|
|
|
/**
|
|
* Creates an instance of InteractionDelegate.
|
|
* @param {any} element
|
|
* @param {any} target
|
|
* @param {any} [{ mouseWheelElement = null, useCapture = true, capturePointerEvents = true, debug = false }={}]
|
|
* @memberof InteractionDelegate
|
|
*/
|
|
constructor(
|
|
element,
|
|
target,
|
|
{ mouseWheelElement = null, useCapture = true, capturePointerEvents = true, cancelOnWindowOut = true, debug = false } = {}
|
|
) {
|
|
this.debug = debug;
|
|
this.interaction = new Interaction();
|
|
this.element = element;
|
|
this.mouseWheelElement = mouseWheelElement || element;
|
|
this.target = target;
|
|
this.useCapture = useCapture;
|
|
this.capturePointerEvents = capturePointerEvents;
|
|
this.cancelOnWindowOut = cancelOnWindowOut;
|
|
this.setupInteraction();
|
|
}
|
|
|
|
setupInteraction() {
|
|
if (this.debug) {
|
|
let error = this.targetInterface.implementationError(
|
|
this.target.constructor
|
|
);
|
|
if (error != null) {
|
|
throw new Error('Expected IInteractionTarget: ' + error)
|
|
}
|
|
}
|
|
this.setupTouchInteraction();
|
|
this.setupMouseWheelInteraction();
|
|
}
|
|
|
|
get targetInterface() {
|
|
return IInteractionTarget
|
|
}
|
|
|
|
setupTouchInteraction() {
|
|
let element = this.element;
|
|
let useCapture = this.useCapture;
|
|
if (window.PointerEvent) {
|
|
if (this.debug) console.log('Pointer API' + window.PointerEvent);
|
|
element.addEventListener(
|
|
'pointerdown',
|
|
e => {
|
|
if (this.debug) console.log('pointerdown', e.pointerId);
|
|
if (this.capture(e)) {
|
|
if (this.capturePointerEvents) {
|
|
try {
|
|
element.setPointerCapture(e.pointerId);
|
|
} catch (e) { }
|
|
}
|
|
this.onStart(e);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'pointermove',
|
|
e => {
|
|
if (this.debug) console.log('pointermove', e.pointerId);
|
|
|
|
if (
|
|
e.pointerType == 'touch' ||
|
|
(e.pointerType == 'mouse' && Events.isMouseDown(e))
|
|
) {
|
|
// this.capture(e) &&
|
|
if (this.debug)
|
|
console.log('pointermove captured', e.pointerId);
|
|
this.onMove(e);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'pointerup',
|
|
e => {
|
|
if (this.debug) console.log('pointerup');
|
|
this.onEnd(e);
|
|
if (this.capturePointerEvents) {
|
|
try {
|
|
element.releasePointerCapture(e.pointerId);
|
|
} catch (e) { }
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'pointercancel',
|
|
e => {
|
|
if (this.debug) console.log('pointercancel');
|
|
this.onEnd(e);
|
|
if (this.capturePointerEvents)
|
|
element.releasePointerCapture(e.pointerId);
|
|
},
|
|
useCapture
|
|
);
|
|
|
|
if (!this.capturePointerEvents) {
|
|
element.addEventListener(
|
|
'pointerleave',
|
|
e => {
|
|
if (this.debug) console.log('pointerleave');
|
|
if (e.target == element) this.onEnd(e);
|
|
},
|
|
useCapture
|
|
);
|
|
}
|
|
|
|
if (!this.capturePointerEvents) {
|
|
element.addEventListener(
|
|
'pointerout',
|
|
e => {
|
|
if (this.debug) console.log('pointerout');
|
|
if (e.target == element) this.onEnd(e);
|
|
},
|
|
useCapture
|
|
);
|
|
}
|
|
|
|
if (this.cancelOnWindowOut) {
|
|
window.addEventListener(
|
|
'pointerout',
|
|
e => {
|
|
if (e.target == element) {
|
|
this.onEnd(e);
|
|
}
|
|
},
|
|
useCapture);
|
|
}
|
|
|
|
} else if (window.TouchEvent) {
|
|
if (this.debug) console.log('Touch API');
|
|
element.addEventListener(
|
|
'touchstart',
|
|
e => {
|
|
if (this.debug)
|
|
console.log('touchstart', this.touchPoints(e));
|
|
if (this.capture(e)) {
|
|
for (let touch of e.changedTouches) {
|
|
this.onStart(touch);
|
|
}
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'touchmove',
|
|
e => {
|
|
if (this.debug)
|
|
console.log('touchmove', this.touchPoints(e), e);
|
|
for (let touch of e.changedTouches) {
|
|
this.onMove(touch);
|
|
}
|
|
for (let touch of e.targetTouches) {
|
|
this.onMove(touch);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'touchend',
|
|
e => {
|
|
if (this.debug) console.log('touchend', this.touchPoints(e));
|
|
for (let touch of e.changedTouches) {
|
|
this.onEnd(touch);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'touchcancel',
|
|
e => {
|
|
if (this.debug)
|
|
console.log(
|
|
'touchcancel',
|
|
e.targetTouches.length,
|
|
e.changedTouches.length
|
|
);
|
|
for (let touch of e.changedTouches) {
|
|
this.onEnd(touch);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
} else {
|
|
if (this.debug) console.log('Mouse API');
|
|
|
|
element.addEventListener(
|
|
'mousedown',
|
|
e => {
|
|
if (this.debug) console.log('mousedown', e);
|
|
if (this.capture(e)) {
|
|
this.onStart(e);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'mousemove',
|
|
e => {
|
|
// Dow we only use move events if the mouse is down?
|
|
// HOver effects have to be implemented by other means
|
|
// && Events.isMouseDown(e))
|
|
|
|
if (Events.isMouseDown(e)) {
|
|
if (this.debug)
|
|
console.log('mousemove', e);
|
|
this.onMove(e);
|
|
}
|
|
},
|
|
useCapture
|
|
);
|
|
element.addEventListener(
|
|
'mouseup',
|
|
e => {
|
|
if (this.debug) console.log('mouseup', e);
|
|
this.onEnd(e);
|
|
},
|
|
true
|
|
);
|
|
|
|
if (!this.capturePointerEvents) {
|
|
element.addEventListener(
|
|
'mouseout',
|
|
e => {
|
|
if (e.target == element) {
|
|
this.onEnd(e);
|
|
console.warn("Shouldn't happen: mouseout ends interaction");
|
|
}
|
|
|
|
},
|
|
useCapture
|
|
);
|
|
}
|
|
if (this.cancelOnWindowOut) {
|
|
window.addEventListener(
|
|
'mouseout',
|
|
e => {
|
|
if (e.target == element) {
|
|
this.onEnd(e);
|
|
}
|
|
},
|
|
useCapture);
|
|
}
|
|
}
|
|
}
|
|
|
|
isDescendant(parent, child) {
|
|
if (parent == child) return true
|
|
let node = child.parentNode;
|
|
while (node != null) {
|
|
if (node == parent) {
|
|
return true
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
return false
|
|
}
|
|
|
|
touchPoints(event) {
|
|
let result = [];
|
|
for (let touch of event.changedTouches) {
|
|
result.push(this.extractPoint(touch));
|
|
}
|
|
return result
|
|
}
|
|
|
|
setupMouseWheelInteraction() {
|
|
this.mouseWheelElement.addEventListener(
|
|
'mousewheel',
|
|
this.onMouseWheel.bind(this),
|
|
true
|
|
);
|
|
this.mouseWheelElement.addEventListener(
|
|
'DOMMouseScroll',
|
|
this.onMouseWheel.bind(this),
|
|
true
|
|
);
|
|
}
|
|
|
|
onMouseWheel(event) {
|
|
if (this.capture(event) && this.target.onMouseWheel) {
|
|
this.target.onMouseWheel(event);
|
|
}
|
|
}
|
|
|
|
onStart(event) {
|
|
let extracted = this.extractPoint(event);
|
|
this.startInteraction(event, extracted);
|
|
this.target.onStart(event, this.interaction);
|
|
}
|
|
|
|
onMove(event) {
|
|
let extracted = this.extractPoint(event, 'all');
|
|
this.updateInteraction(event, extracted);
|
|
this.target.onMove(event, this.interaction);
|
|
this.interaction.updatePrevious();
|
|
}
|
|
|
|
onEnd(event) {
|
|
let extracted = this.extractPoint(event, 'changedTouches');
|
|
this.endInteraction(event, extracted);
|
|
this.target.onEnd(event, this.interaction);
|
|
this.finishInteraction(event, extracted);
|
|
}
|
|
|
|
/**
|
|
* Asks the target whether the event should be captured
|
|
*
|
|
* @param {any} event
|
|
* @returns {bool}
|
|
* @memberof InteractionDelegate
|
|
*/
|
|
capture(event) {
|
|
if (Events.isCaptured(event)) {
|
|
return false
|
|
}
|
|
let captured = this.target.capture(event);
|
|
return captured
|
|
}
|
|
|
|
getPosition(event) {
|
|
return { x: event.clientX, y: event.clientY }
|
|
}
|
|
|
|
extractPoint(event, touchEventKey = 'all') {
|
|
// 'targetTouches'
|
|
let result = {};
|
|
switch (event.constructor.name) {
|
|
case 'MouseEvent':
|
|
let buttons = event.buttons || event.which;
|
|
if (buttons) result['mouse'] = this.getPosition(event);
|
|
break
|
|
case 'PointerEvent':
|
|
result[event.pointerId.toString()] = this.getPosition(event);
|
|
break
|
|
case 'Touch':
|
|
let id =
|
|
event.touchType === 'stylus'
|
|
? 'stylus'
|
|
: event.identifier.toString();
|
|
result[id] = this.getPosition(event);
|
|
break
|
|
// case 'TouchEvent':
|
|
// // Needs to be observed: Perhaps changedTouches are all we need. If so
|
|
// // we can remove the touchEventKey default parameter
|
|
// if (touchEventKey == 'all') {
|
|
// for(let t of event.targetTouches) {
|
|
// result[t.identifier.toString()] = this.getPosition(t)
|
|
// }
|
|
// for(let t of event.changedTouches) {
|
|
// result[t.identifier.toString()] = this.getPosition(t)
|
|
// }
|
|
// }
|
|
// else {
|
|
// for(let t of event.changedTouches) {
|
|
// result[t.identifier.toString()] = this.getPosition(t)
|
|
// }
|
|
// }
|
|
// break
|
|
default:
|
|
break
|
|
}
|
|
return result
|
|
}
|
|
|
|
interactionStarted(event, key, point) {
|
|
// Callback: can be overwritten
|
|
}
|
|
|
|
interactionEnded(event, key, point) {
|
|
// Callback: can be overwritten
|
|
}
|
|
|
|
interactionFinished(event, key, point) { }
|
|
|
|
startInteraction(event, extracted) {
|
|
for (let key in extracted) {
|
|
let point = extracted[key];
|
|
this.interaction.started(key, point);
|
|
this.interactionStarted(event, key, point);
|
|
}
|
|
}
|
|
|
|
updateInteraction(event, extracted) {
|
|
for (let key in extracted) {
|
|
let point = extracted[key];
|
|
let updated = this.interaction.update(key, point);
|
|
if (updated) {
|
|
console.warn("new pointer in updateInteraction shouldn't happen");
|
|
this.interactionStarted(event, key, point);
|
|
}
|
|
}
|
|
}
|
|
|
|
endInteraction(event, ended) {
|
|
for (let key in ended) {
|
|
let point = ended[key];
|
|
this.interaction.stop(key, point);
|
|
this.interactionEnded(event, key, point);
|
|
}
|
|
}
|
|
|
|
finishInteraction(event, ended) {
|
|
for (let key in ended) {
|
|
let point = ended[key];
|
|
this.interaction.finish(key, point);
|
|
this.interactionFinished(event, key, point);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* A special InteractionDelegate that maps events to specific parts of
|
|
* the interaction target. The InteractionTarget must implement a findTarget
|
|
* method that returns an object implementing the IInteractionTarget interface.
|
|
*
|
|
* If the InteractionTarget also implements a mapPositionToPoint method this
|
|
* is used to map the points to the local coordinate space of the the target.
|
|
*
|
|
* This makes it easier to lookup elements and relate events to local
|
|
* positions.
|
|
*
|
|
* @export
|
|
* @class InteractionMapper
|
|
* @extends {InteractionDelegate}
|
|
*/
|
|
class InteractionMapper$1 extends InteractionDelegate {
|
|
|
|
constructor(
|
|
element,
|
|
target,
|
|
{ tapDistance = 10, longPressTime = 500.0, useCapture = true, mouseWheelElement = null } = {}
|
|
) {
|
|
super(element, target, { tapDistance, useCapture, longPressTime, mouseWheelElement });
|
|
}
|
|
|
|
get targetInterface() {
|
|
return IInteractionMapperTarget
|
|
}
|
|
|
|
mapPositionToPoint(point, element = null) {
|
|
if (this.target.mapPositionToPoint) {
|
|
return this.target.mapPositionToPoint(point, element)
|
|
}
|
|
return point
|
|
}
|
|
|
|
interactionStarted(event, key, point) {
|
|
if (this.target.findTarget) {
|
|
let local = this.mapPositionToPoint(point);
|
|
let found = this.target.findTarget(event, local, point);
|
|
if (found != null) {
|
|
this.interaction.addTarget(key, found);
|
|
}
|
|
}
|
|
}
|
|
|
|
onMouseWheel(event) {
|
|
if (this.capture(event)) {
|
|
if (this.target.findTarget) {
|
|
let point = this.getPosition(event);
|
|
let local = this.mapPositionToPoint(point);
|
|
let found = this.target.findTarget(event, local, point);
|
|
if (found != null && found.onMouseWheel) {
|
|
found.onMouseWheel(event);
|
|
return
|
|
}
|
|
}
|
|
if (this.target.onMouseWheel) {
|
|
this.target.onMouseWheel(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
onStart(event) {
|
|
let extracted = this.extractPoint(event);
|
|
this.startInteraction(event, extracted);
|
|
let mapped = this.interaction.mapInteraction(
|
|
extracted,
|
|
['current', 'start'],
|
|
this.mapPositionToPoint.bind(this)
|
|
);
|
|
for (let [target, interaction] of mapped.entries()) {
|
|
target.onStart(event, interaction);
|
|
}
|
|
}
|
|
|
|
onMove(event) {
|
|
let extracted = this.extractPoint(event, 'all');
|
|
this.updateInteraction(event, extracted);
|
|
let mapped = this.interaction.mapInteraction(
|
|
extracted,
|
|
['current', 'previous'],
|
|
this.mapPositionToPoint.bind(this)
|
|
);
|
|
for (let [target, interaction] of mapped.entries()) {
|
|
target.onMove(event, interaction);
|
|
interaction.updatePrevious();
|
|
}
|
|
this.interaction.updatePrevious();
|
|
}
|
|
|
|
onEnd(event) {
|
|
let extracted = this.extractPoint(event, 'changedTouches');
|
|
this.endInteraction(event, extracted);
|
|
let mapped = this.interaction.mapInteraction(
|
|
extracted,
|
|
['ended'],
|
|
this.mapPositionToPoint.bind(this)
|
|
);
|
|
for (let [target, interaction] of mapped.entries()) {
|
|
target.onEnd(event, interaction);
|
|
}
|
|
this.finishInteraction(event, extracted);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @static
|
|
* @param {string|array} types - An event type, an array of event types or event types seperated by a space sign. The following
|
|
* events are possible:
|
|
* pan, panstart, panmove, panend, pancancel, panleft, panright, panup, pandown
|
|
* pinch, pinchstart, pinchmove, pinchend, pinchcancel, pinchin, pinchout
|
|
* press, pressup
|
|
* rotate, rotatestart, rotatemove, rotateend, rotatecancel
|
|
* swipe, swipeleft, swiperight, swipeup, swipedown
|
|
* tap
|
|
* @param {HTMLElement|HTMLElement[]} elements - An HTML element or an array of HTML elements.
|
|
* @param {function} [cb] - The callback. A function which is executed after the event occurs. Receives the event object as the
|
|
* first paramter
|
|
* @param {object} [opts] - An options object. See the hammer documentation for more details.
|
|
*/
|
|
static on(types, elements, cb, opts = {}) {
|
|
opts = Object.assign({}, {
|
|
|
|
}, opts);
|
|
|
|
if (typeof Hammer === 'undefined') {
|
|
console.error('Hammer.js not found!');
|
|
return this
|
|
}
|
|
|
|
// convert to array
|
|
types = Array.isArray(types) ? types : types.split(/\s/);
|
|
if (elements instanceof NodeList || elements instanceof HTMLCollection) {
|
|
elements = Array.from(elements);
|
|
}
|
|
elements = Array.isArray(elements) ? elements : [elements];
|
|
|
|
for (let i = 0; i < types.length; i++) {
|
|
|
|
const type = types[i].toLowerCase();
|
|
|
|
// list of hammer events
|
|
const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test(type);
|
|
|
|
// if it is a hammer event
|
|
if (useHammer) {
|
|
|
|
for (let j = 0; j < elements.length; j++) {
|
|
|
|
// if(elements[j].tagName == "svg") return false;
|
|
|
|
let hammer = new Hammer(elements[j], opts);
|
|
|
|
if (window.propagating !== 'undefined') {
|
|
hammer = propagating(hammer);
|
|
}
|
|
|
|
// recognizers
|
|
if (type.startsWith('pan')) {
|
|
hammer.get('pan').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts));
|
|
} else if (type.startsWith('pinch')) {
|
|
hammer.get('pinch').set(Object.assign({ enable: true }, opts));
|
|
} else if (type.startsWith('press')) {
|
|
hammer.get('press').set(opts);
|
|
} else if (type.startsWith('rotate')) {
|
|
hammer.get('rotate').set(Object.assign({ enable: true }, opts));
|
|
} else if (type.startsWith('swipe')) {
|
|
hammer.get('swipe').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts));
|
|
} else if (type.startsWith('tap')) {
|
|
hammer.get('tap').set(opts);
|
|
}
|
|
|
|
hammer.on(type, event => {
|
|
cb(event);
|
|
});
|
|
}
|
|
|
|
} else {
|
|
|
|
for (let j = 0; j < elements.length; j++) {
|
|
Hammer.on(elements[j], type, event => {
|
|
cb(event);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return this
|
|
}
|
|
}
|
|
|
|
window.InteractionMapper = InteractionMapper$1;
|
|
|
|
/** Report capabilities with guaranteed values.
|
|
*/
|
|
class Capabilities {
|
|
|
|
/** Returns the browser userAgent.
|
|
@return {string}
|
|
*/
|
|
static get userAgent() {
|
|
return navigator.userAgent || 'Unknown Agent'
|
|
}
|
|
|
|
/** Tests whether the app is running on a mobile device.
|
|
Implemented as a readonly attribute.
|
|
@return {boolean}
|
|
*/
|
|
static get isMobile() {
|
|
return (/Mobi/.test(navigator.userAgent))
|
|
}
|
|
|
|
/** Tests whether the app is running on a iOS device.
|
|
Implemented as a readonly attribute.
|
|
@return {boolean}
|
|
*/
|
|
static get isIOS() {
|
|
return (/iPad|iPhone|iPod/.test(navigator.userAgent)) && !window.MSStream
|
|
}
|
|
|
|
/** Tests whether the app is running in a Safari environment.
|
|
See https://stackoverflow.com/questions/7944460/detect-safari-browser
|
|
Implemented as a readonly attribute.
|
|
@return {boolean}
|
|
*/
|
|
static get isSafari() {
|
|
return navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS')
|
|
}
|
|
|
|
/**
|
|
* Distincts if the app is running inside electron or not.
|
|
*
|
|
* source: https://discuss.atom.io/t/detect-electron-or-web-page-running/33180/3
|
|
*/
|
|
static get isElectron() {
|
|
return typeof process != 'undefined' && process.versions && process.versions.electron !== undefined
|
|
}
|
|
|
|
/** Returns the display resolution. Necessary for retina displays.
|
|
@return {number}
|
|
*/
|
|
static get devicePixelRatio() {
|
|
return window.devicePixelRatio || 1
|
|
}
|
|
|
|
/** Returns true if the device is a multi-touch table. This method is currently not universal usable and not sure!
|
|
@return {boolean}
|
|
*/
|
|
static get isMultiTouchTable() {
|
|
return Capabilities.devicePixelRatio > 2 && Capabilities.isMobile === false && /Windows/i.test(Capabilities.userAgent)
|
|
}
|
|
|
|
/** Returns true if mouse events are supported
|
|
@return {boolean}
|
|
*/
|
|
static supportsMouseEvents() {
|
|
return typeof(window.MouseEvent) != 'undefined'
|
|
}
|
|
|
|
/** Returns true if touch events are supported
|
|
@return {boolean}
|
|
*/
|
|
static supportsTouchEvents() {
|
|
return typeof(window.TouchEvent) != 'undefined'
|
|
}
|
|
|
|
/** Returns true if pointer events are supported
|
|
@return {boolean}
|
|
*/
|
|
static supportsPointerEvents() {
|
|
return typeof(window.PointerEvent) != 'undefined'
|
|
}
|
|
|
|
/** Returns true if DOM templates are supported
|
|
@return {boolean}
|
|
*/
|
|
static supportsTemplate() {
|
|
return 'content' in document.createElement('template');
|
|
}
|
|
}
|
|
|
|
/** Basic tests for Capabilities.
|
|
*/
|
|
class CapabilitiesTests {
|
|
|
|
static testConfirm() {
|
|
let bool = confirm('Please confirm');
|
|
document.getElementById('demo').innerHTML = (bool) ? 'Confirmed' : 'Not confirmed';
|
|
}
|
|
|
|
static testPrompt() {
|
|
let person = prompt('Please enter your name', 'Harry Potter');
|
|
if (person != null) {
|
|
demo.innerHTML =
|
|
'Hello ' + person + '! How are you today?';
|
|
}
|
|
}
|
|
|
|
static testUserAgent() {
|
|
let agent = 'User-agent: ' + Capabilities.userAgent;
|
|
user_agent.innerHTML = agent;
|
|
}
|
|
|
|
static testDevicePixelRatio() {
|
|
let value = 'Device Pixel Ratio: ' + Capabilities.devicePixelRatio;
|
|
device_pixel_ratio.innerHTML = value;
|
|
}
|
|
|
|
static testMultiTouchTable() {
|
|
let value = 'Is the device a multi-touch table? ' + Capabilities.isMultiTouchTable;
|
|
multi_touch_table.innerHTML = value;
|
|
}
|
|
|
|
static testSupportedEvents() {
|
|
let events = [];
|
|
if (Capabilities.supportsMouseEvents()) {
|
|
events.push('MouseEvents');
|
|
}
|
|
if (Capabilities.supportsTouchEvents()) {
|
|
events.push('TouchEvents');
|
|
}
|
|
if (Capabilities.supportsPointerEvents()) {
|
|
events.push('PointerEvents');
|
|
}
|
|
supported_events.innerHTML = 'Supported Events: ' + events.join(', ');
|
|
}
|
|
|
|
static testAll() {
|
|
this.testUserAgent();
|
|
this.testDevicePixelRatio();
|
|
this.testMultiTouchTable();
|
|
this.testSupportedEvents();
|
|
}
|
|
}
|
|
|
|
/* Optional global variables, needed in DocTests. */
|
|
window.Capabilities = Capabilities;
|
|
window.CapabilitiesTests = CapabilitiesTests;
|
|
|
|
/**
|
|
* A base class for scatter specific events.
|
|
*
|
|
* @constructor
|
|
* @param {name} String - The name of the event
|
|
* @param {target} Object - The target of the event
|
|
*/
|
|
class BaseEvent {
|
|
constructor(name, target) {
|
|
this.name = name;
|
|
this.target = target;
|
|
}
|
|
}
|
|
|
|
// Event types
|
|
const START = 'onStart';
|
|
const UPDATE = 'onUpdate';
|
|
const END = 'onEnd';
|
|
|
|
/**
|
|
* A scatter event that describes how the scatter has changed.
|
|
*
|
|
* @constructor
|
|
* @param {target} Object - The target scatter of the event
|
|
* @param {optional} Object - Optional parameter
|
|
*/
|
|
class ScatterEvent extends BaseEvent {
|
|
constructor(
|
|
target,
|
|
{
|
|
translate = { x: 0, y: 0 },
|
|
scale = null,
|
|
rotate = 0,
|
|
about = null,
|
|
fast = false,
|
|
type = null
|
|
} = {}
|
|
) {
|
|
super('scatterTransformed', { target: target });
|
|
this.translate = translate;
|
|
this.scale = scale;
|
|
this.rotate = rotate;
|
|
this.about = about;
|
|
this.fast = fast;
|
|
this.type = type;
|
|
}
|
|
|
|
toString() {
|
|
return (
|
|
"Event('scatterTransformed', scale: " +
|
|
this.scale +
|
|
' about: ' +
|
|
this.about.x +
|
|
', ' +
|
|
this.about.y +
|
|
')'
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A scatter resize event that describes how the scatter has changed.
|
|
*
|
|
* @constructor
|
|
* @param {target} Object - The target scatter of the event
|
|
* @param {optional} Object - Optional parameter
|
|
*/
|
|
class ResizeEvent extends BaseEvent {
|
|
constructor(target, { width = 0, height = 0 } = {}) {
|
|
super('scatterResized', { width: width, height: height });
|
|
this.width = width;
|
|
this.height = height;
|
|
}
|
|
|
|
toString() {
|
|
return (
|
|
'Event(scatterResized width: ' +
|
|
this.width +
|
|
'height: ' +
|
|
this.height +
|
|
')'
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A abstract base class that implements the throwable behavior of a scatter
|
|
* object.
|
|
*
|
|
* @constructor
|
|
*/
|
|
class Throwable {
|
|
constructor({
|
|
movableX = true,
|
|
movableY = true,
|
|
throwVisibility = 44,
|
|
throwDamping = 0.95,
|
|
autoThrow = true,
|
|
onThrowFinished = null
|
|
} = {}) {
|
|
this.movableX = movableX;
|
|
this.movableY = movableY;
|
|
this.throwVisibility = throwVisibility;
|
|
this.throwDamping = throwDamping;
|
|
this.autoThrow = autoThrow;
|
|
this.velocities = [];
|
|
this.velocity = null;
|
|
this.timestamp = null;
|
|
this.onThrowFinished = onThrowFinished;
|
|
//console.log("onThrowFinished", onThrowFinished)
|
|
}
|
|
|
|
observeVelocity() {
|
|
this.lastframe = performance.now();
|
|
}
|
|
|
|
addVelocity(delta, buffer = 5) {
|
|
let t = performance.now();
|
|
let dt = t - this.lastframe;
|
|
this.lastframe = t;
|
|
if (dt > 0) {
|
|
// Avoid division by zero errors later on
|
|
let velocity = { t: t, dt: dt, dx: delta.x, dy: delta.y };
|
|
this.velocities.push(velocity);
|
|
while (this.velocities.length > buffer) {
|
|
this.velocities.shift();
|
|
}
|
|
}
|
|
}
|
|
|
|
meanVelocity(milliseconds = 30) {
|
|
this.addVelocity({ x: 0, y: 0 });
|
|
let sum = { x: 0, y: 0 };
|
|
let count = 0;
|
|
let t = 0;
|
|
for (let i = this.velocities.length - 1; i > 0; i--) {
|
|
let v = this.velocities[i];
|
|
t += v.dt;
|
|
let nv = { x: v.dx / v.dt, y: v.dy / v.dt };
|
|
sum = Points.add(sum, nv);
|
|
count += 1;
|
|
if (t > milliseconds) {
|
|
break
|
|
}
|
|
}
|
|
if (count === 0) return sum // empty vector
|
|
return Points.multiplyScalar(sum, 1 / count)
|
|
}
|
|
|
|
killAnimation() {
|
|
this.velocity = null;
|
|
this.velocities = [];
|
|
}
|
|
|
|
startThrow() {
|
|
this.velocity = this.meanVelocity();
|
|
if (this.velocity != null) {
|
|
// Call next velocity to ansure that specializations
|
|
// that use keepOnStage are called
|
|
this.velocity = this.nextVelocity(this.velocity);
|
|
if (this.autoThrow) this.animateThrow(performance.now());
|
|
} else {
|
|
this.onDragComplete();
|
|
}
|
|
}
|
|
|
|
animateThrow(time) {
|
|
if (this.velocity != null) {
|
|
let t = performance.now();
|
|
let dt = t - this.lastframe;
|
|
this.lastframe = t;
|
|
// console.log("animateThrow", dt)
|
|
let next = this.nextVelocity(this.velocity);
|
|
let prevLength = Points.length(this.velocity);
|
|
let nextLength = Points.length(next);
|
|
if (nextLength > prevLength) {
|
|
let factor = nextLength / prevLength;
|
|
next = Points.multiplyScalar(next, 1 / factor);
|
|
console.log('Prevent acceleration', factor, this.velocity, next);
|
|
}
|
|
this.velocity = next;
|
|
let d = Points.multiplyScalar(this.velocity, dt);
|
|
this._move(d);
|
|
|
|
this.onDragUpdate(d);
|
|
if (dt == 0 || this.needsAnimation()) {
|
|
requestAnimationFrame(this.animateThrow.bind(this));
|
|
return
|
|
} else {
|
|
if (this.isOutside()) {
|
|
requestAnimationFrame(this.animateThrow.bind(this));
|
|
return
|
|
}
|
|
}
|
|
}
|
|
this.onDragComplete();
|
|
if (this.onThrowFinished != null) {
|
|
this.onThrowFinished();
|
|
}
|
|
}
|
|
|
|
needsAnimation() {
|
|
if (this.velocity == null) {
|
|
return false
|
|
}
|
|
return Points.length(this.velocity) > 0.01
|
|
}
|
|
|
|
nextVelocity(velocity) {
|
|
// Must be overwritten: computes the changed velocity. Implement
|
|
// damping, collison detection, etc. here
|
|
let next = Points.multiplyScalar(velocity, this.throwDamping);
|
|
return {
|
|
x: (this.movableX) ? next.x : 0,
|
|
y: (this.movableY) ? next.y : 0
|
|
}
|
|
}
|
|
|
|
_move(delta) {
|
|
// Overwrite if necessary
|
|
}
|
|
|
|
onDragComplete() {
|
|
// Overwrite if necessary
|
|
}
|
|
|
|
onDragUpdate(delta) {
|
|
// Overwrite if necessary
|
|
}
|
|
}
|
|
|
|
class AbstractScatter extends Throwable {
|
|
constructor({
|
|
minScale = 0.1,
|
|
maxScale = 1.0,
|
|
startScale = 1.0,
|
|
autoBringToFront = true,
|
|
autoThrow = true,
|
|
translatable = true,
|
|
scalable = true,
|
|
rotatable = true,
|
|
resizable = false,
|
|
movableX = true,
|
|
movableY = true,
|
|
throwVisibility = 44,
|
|
throwDamping = 0.95,
|
|
overdoScaling = 1,
|
|
mouseZoomFactor = 1.1,
|
|
rotationDegrees = null,
|
|
rotation = null,
|
|
onTransform = null,
|
|
interactive = true,
|
|
onClose = null,
|
|
onThrowFinished = null,
|
|
scaleAutoClose = false,
|
|
scaleCloseThreshold = 0.10,
|
|
scaleCloseBuffer = 0.05
|
|
} = {}) {
|
|
if (rotationDegrees != null && rotation != null) {
|
|
throw new Error('Use rotationDegrees or rotation but not both')
|
|
} else if (rotation != null) {
|
|
rotationDegrees = Angle.radian2degree(rotation);
|
|
} else if (rotationDegrees == null) {
|
|
rotationDegrees = 0;
|
|
}
|
|
super({
|
|
movableX,
|
|
movableY,
|
|
throwVisibility,
|
|
throwDamping,
|
|
autoThrow,
|
|
onThrowFinished
|
|
});
|
|
|
|
/**
|
|
* Closes the card when the minScale is reached and the
|
|
* card is released. Card can be saved by scaling it up again.
|
|
*/
|
|
this.scaleAutoClose = scaleAutoClose;
|
|
this.scaleCloseThreshold = scaleCloseThreshold;
|
|
this.scaleCloseBuffer = scaleCloseBuffer;
|
|
this.scaleAutoCloseTimeout = null;
|
|
|
|
this.interactive = interactive;
|
|
this.startRotationDegrees = rotationDegrees;
|
|
this.startScale = startScale; // Needed to reset object
|
|
this.minScale = minScale;
|
|
this.maxScale = maxScale;
|
|
this.overdoScaling = overdoScaling;
|
|
this.translatable = translatable;
|
|
if (!translatable) {
|
|
this.movableX = false;
|
|
this.movableY = false;
|
|
}
|
|
this.scalable = scalable;
|
|
this.rotatable = rotatable;
|
|
this.resizable = resizable;
|
|
this.mouseZoomFactor = mouseZoomFactor;
|
|
this.autoBringToFront = autoBringToFront;
|
|
this.dragging = false;
|
|
this.onTransform = onTransform != null ? [onTransform] : null;
|
|
this.onClose = onClose != null ? [onClose] : null;
|
|
}
|
|
|
|
addCloseEventCallback(callback) {
|
|
if (this.onClose == null) {
|
|
this.onClose = [];
|
|
}
|
|
this.onClose.push(callback);
|
|
}
|
|
|
|
addTransformEventCallback(callback) {
|
|
if (this.onTransform == null) {
|
|
this.onTransform = [];
|
|
}
|
|
this.onTransform.push(callback);
|
|
}
|
|
|
|
startGesture(interaction) {
|
|
this.bringToFront();
|
|
this.killAnimation();
|
|
this.observeVelocity();
|
|
return true
|
|
}
|
|
|
|
close() {
|
|
if (this.onClose) {
|
|
this.onClose.forEach(callback => callback(this));
|
|
}
|
|
}
|
|
|
|
gesture(interaction) {
|
|
let delta = interaction.delta();
|
|
//console.log("gesture", delta)
|
|
if (delta != null) {
|
|
this.addVelocity(delta);
|
|
this.transform(delta, delta.zoom, delta.rotate, delta.about);
|
|
if (delta.zoom != 1) this.interactionAnchor = delta.about;
|
|
}
|
|
}
|
|
|
|
get polygon() {
|
|
let w2 = this.width * this.scale / 2;
|
|
let h2 = this.height * this.scale / 2;
|
|
let center = this.center;
|
|
let polygon = new Polygon(center);
|
|
polygon.addPoint({ x: -w2, y: -h2 });
|
|
polygon.addPoint({ x: w2, y: -h2 });
|
|
polygon.addPoint({ x: w2, y: h2 });
|
|
polygon.addPoint({ x: -w2, y: h2 });
|
|
polygon.rotate(this.rotation);
|
|
return polygon
|
|
}
|
|
|
|
isOutside() {
|
|
let stagePolygon = this.containerPolygon;
|
|
if (stagePolygon == null)
|
|
return false
|
|
let polygon = this.polygon;
|
|
if (polygon == null)
|
|
return false
|
|
let result = stagePolygon.intersectsWith(polygon);
|
|
return result === false || result.overlap < this.throwVisibility
|
|
}
|
|
|
|
recenter() {
|
|
// Return a small vector that guarantees that the scatter is moving
|
|
// towards the center of the stage
|
|
let center = this.center;
|
|
let target = this.container.center;
|
|
let delta = Points.subtract(target, center);
|
|
return Points.normalize(delta)
|
|
}
|
|
|
|
nextVelocity(velocity) {
|
|
return this.keepOnStage(velocity)
|
|
}
|
|
|
|
bouncing() {
|
|
// Implements the bouncing behavior of the scatter. Moves the scatter
|
|
// to the center of the stage if the scatter is outside the stage or
|
|
// not within the limits of the throwVisibility.
|
|
|
|
let stagePolygon = this.containerPolygon;
|
|
let polygon = this.polygon;
|
|
let result = stagePolygon.intersectsWith(polygon);
|
|
if (result === false || result.overlap < this.throwVisibility) {
|
|
let cv = this.recenter();
|
|
let recentered = false;
|
|
while (result === false || result.overlap < this.throwVisibility) {
|
|
polygon.center.x += cv.x;
|
|
polygon.center.y += cv.y;
|
|
this._move(cv);
|
|
result = stagePolygon.intersectsWith(polygon);
|
|
recentered = true;
|
|
}
|
|
return recentered
|
|
}
|
|
return false
|
|
}
|
|
|
|
keepOnStage(velocity, collision = 0.5) {
|
|
let stagePolygon = this.containerPolygon;
|
|
if (!stagePolygon) return
|
|
let polygon = this.polygon;
|
|
let bounced = this.bouncing();
|
|
if (bounced) {
|
|
let stage = this.containerBounds;
|
|
let x = this.center.x;
|
|
let y = this.center.y;
|
|
let dx = this.movableX ? velocity.x : 0;
|
|
let dy = this.movableY ? velocity.y : 0;
|
|
let factor = this.throwDamping;
|
|
// if (recentered) {
|
|
if (x < 0) {
|
|
dx = -dx;
|
|
factor = collision;
|
|
}
|
|
if (x > stage.width) {
|
|
dx = -dx;
|
|
factor = collision;
|
|
}
|
|
if (y < 0) {
|
|
dy = -dy;
|
|
factor = collision;
|
|
}
|
|
if (y > stage.height) {
|
|
dy = -dy;
|
|
factor = collision;
|
|
}
|
|
// }
|
|
return Points.multiplyScalar({ x: dx, y: dy }, factor)
|
|
}
|
|
return super.nextVelocity(velocity)
|
|
}
|
|
|
|
endGesture(interaction) {
|
|
this.startThrow();
|
|
this._checkAutoClose();
|
|
}
|
|
|
|
_checkAutoClose() {
|
|
if (this.scaleAutoClose)
|
|
if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) {
|
|
this.zoom(this.minScale, { animate: 0.2, onComplete: this.close.bind(this) });
|
|
} else if (this.scale < this.minScale + this.scaleCloseThreshold) {
|
|
this.zoom(this.minScale + this.scaleCloseThreshold, { animate: 0.4 });
|
|
}
|
|
}
|
|
|
|
rotateDegrees(degrees, anchor) {
|
|
let rad = Angle.degree2radian(degrees);
|
|
this.rotate(rad, anchor);
|
|
}
|
|
|
|
rotate(rad, anchor) {
|
|
this.transform({ x: 0, y: 0 }, 1.0, rad, anchor);
|
|
}
|
|
|
|
move(d, { animate = 0 } = {}) {
|
|
if (this.translatable) {
|
|
if (animate > 0) {
|
|
let startPos = this.position;
|
|
TweenLite.to(this, animate, {
|
|
x: '+=' + d.x,
|
|
y: '+=' + d.y,
|
|
/* scale: scale, uo: not defined, why was this here? */
|
|
onUpdate: e => {
|
|
let p = this.position;
|
|
let dx = p.x - startPos.x;
|
|
let dy = p.x - startPos.y;
|
|
this.onMoved(dx, dy);
|
|
}
|
|
});
|
|
} else {
|
|
this._move(d);
|
|
this.onMoved(d.x, d.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
moveTo(p, { animate = 0 } = {}) {
|
|
let c = this.origin;
|
|
let delta = Points.subtract(p, c);
|
|
this.move(delta, { animate: animate });
|
|
}
|
|
|
|
centerAt(p, { animate = 0 } = {}) {
|
|
let c = this.center;
|
|
let delta = Points.subtract(p, c);
|
|
this.move(delta, { animate: animate });
|
|
}
|
|
|
|
zoom(
|
|
scale,
|
|
{
|
|
animate = 0,
|
|
about = null,
|
|
delay = 0,
|
|
x = null,
|
|
y = null,
|
|
onComplete = null
|
|
} = {}
|
|
) {
|
|
let anchor = about || this.center;
|
|
if (scale != this.scale) {
|
|
if (animate > 0) {
|
|
TweenLite.to(this, animate, {
|
|
scale: scale,
|
|
delay: delay,
|
|
onComplete: onComplete,
|
|
onUpdate: this.onZoomed.bind(this)
|
|
});
|
|
} else {
|
|
this.scale = scale;
|
|
this.onZoomed(anchor);
|
|
}
|
|
}
|
|
}
|
|
|
|
_move(delta) {
|
|
this.x += this.movableX ? delta.x : 0;
|
|
this.y += this.movableX ? delta.y : 0;
|
|
}
|
|
|
|
transform(translate, zoom, rotate, anchor) {
|
|
let delta = {
|
|
x: this.movableX ? translate.x : 0,
|
|
y: this.movableY ? translate.y : 0
|
|
};
|
|
if (this.resizable) var vzoom = zoom;
|
|
if (!this.translatable) delta = { x: 0, y: 0 };
|
|
if (!this.rotatable) rotate = 0;
|
|
if (!this.scalable) zoom = 1.0;
|
|
if (zoom == 1.0 && rotate == 0) {
|
|
this._move(delta);
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
translate: delta,
|
|
scale: this.scale,
|
|
rotate: 0,
|
|
about: anchor,
|
|
fast: false,
|
|
type: UPDATE
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
return
|
|
}
|
|
let origin = this.rotationOrigin;
|
|
let beta = Points.angle(origin, anchor);
|
|
let distance = Points.distance(origin, anchor);
|
|
let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale(zoom);
|
|
|
|
let newOrigin = Points.arc(anchor, beta + rotate, distance * thresholdedZoom);
|
|
let extra = Points.subtract(newOrigin, origin);
|
|
let offset = Points.subtract(anchor, origin);
|
|
this._move(offset);
|
|
this.scale = newScale;
|
|
this.rotation += rotate;
|
|
offset = Points.negate(offset);
|
|
offset = Points.add(offset, extra);
|
|
offset = Points.add(offset, translate);
|
|
this._move(offset);
|
|
|
|
delta.x += extra.x;
|
|
delta.y += extra.y;
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
translate: delta,
|
|
scale: newScale,
|
|
rotate: rotate,
|
|
about: anchor
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
if (this.resizable) {
|
|
this.resizeAfterTransform(vzoom);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* For a given zoom, a new scale is calculated, taking
|
|
* min and max scale into account.
|
|
*
|
|
* @param {number} zoom - The zoom factor, to scale the object with.
|
|
* @returns {object} - Returns an object containing the a value for a valid scale and the corrected zoom factor.
|
|
*/
|
|
calculateScale(zoom) {
|
|
let scale = this.scale * zoom;
|
|
|
|
let minScale = this.minScale / this.overdoScaling;
|
|
let maxScale = this.maxScale * this.overdoScaling;
|
|
if (scale < minScale) {
|
|
scale = minScale;
|
|
zoom = scale / this.scale;
|
|
}
|
|
if (scale > maxScale) {
|
|
scale = maxScale;
|
|
zoom = scale / this.scale;
|
|
}
|
|
|
|
if (this.scaleAutoClose)
|
|
this._updateTransparency();
|
|
|
|
return { zoom, scale }
|
|
}
|
|
|
|
_updateTransparency() {
|
|
if (this.scale < this.minScale + this.scaleCloseThreshold) {
|
|
let transparency = this.calculateScaleTransparency();
|
|
this.element.style.opacity = transparency;
|
|
} else this.element.style.opacity = 1;
|
|
}
|
|
|
|
calculateScaleTransparency() {
|
|
let transparency = (this.scale - this.minScale) / this.scaleCloseThreshold;
|
|
transparency = (transparency > 1) ? 1 : (transparency < 0) ? 0 : transparency;
|
|
return transparency
|
|
}
|
|
|
|
resizeAfterTransform(zoom) {
|
|
// Overwrite this in subclasses.
|
|
}
|
|
|
|
validScale(scale) {
|
|
scale = Math.max(scale, this.minScale);
|
|
scale = Math.min(scale, this.maxScale);
|
|
return scale
|
|
}
|
|
|
|
animateZoomBounce(dt = 1) {
|
|
if (this.zoomAnchor != null) {
|
|
let zoom = 1;
|
|
let amount = Math.min(0.01, 0.3 * dt / 100000.0);
|
|
if (this.scale < this.minScale) zoom = 1 + amount;
|
|
if (this.scale > this.maxScale) zoom = 1 - amount;
|
|
if (zoom != 1) {
|
|
this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor);
|
|
requestAnimationFrame(dt => {
|
|
this.animateZoomBounce(dt);
|
|
});
|
|
return
|
|
}
|
|
this.zoomAnchor = null;
|
|
}
|
|
}
|
|
|
|
checkScaling(about, delay = 0) {
|
|
this.zoomAnchor = about;
|
|
clearTimeout(this.animateZoomBounce.bind(this));
|
|
setTimeout(this.animateZoomBounce.bind(this), delay);
|
|
}
|
|
|
|
onMouseWheel(event) {
|
|
if (event.claimedByScatter) {
|
|
if (event.claimedByScatter != this) return
|
|
}
|
|
this.killAnimation();
|
|
this.targetScale = null;
|
|
let direction = event.detail < 0 || event.wheelDelta > 0;
|
|
let globalPoint = { x: event.clientX, y: event.clientY };
|
|
let centerPoint = this.mapPositionToContainerPoint(globalPoint);
|
|
if (event.shiftKey) {
|
|
let degrees = direction ? 5 : -5;
|
|
let rad = Angle.degree2radian(degrees);
|
|
return this.transform({ x: 0, y: 0 }, 1.0, rad, centerPoint)
|
|
}
|
|
const zoomFactor = this.mouseZoomFactor;
|
|
let zoom = direction ? zoomFactor : 1 / zoomFactor;
|
|
this.transform({ x: 0, y: 0 }, zoom, 0, centerPoint);
|
|
this.checkScaling(centerPoint, 200);
|
|
|
|
if (this.scaleAutoClose) {
|
|
if (this.scale <= this.minScale + this.scaleCloseThreshold) {
|
|
|
|
if (this.scaleAutoCloseTimeout) clearTimeout(this.scaleAutoCloseTimeout);
|
|
this.scaleAutoCloseTimeout = setTimeout(() => {
|
|
this._checkAutoClose();
|
|
}, 600);
|
|
}
|
|
this._updateTransparency();
|
|
}
|
|
//
|
|
// if (this.onTransform != null) {
|
|
// let event = new ScatterEvent(this, {
|
|
// translate: {x: 0, y: 0},
|
|
// scale: this.scale,
|
|
// rotate: 0,
|
|
// about: null,
|
|
// fast: false,
|
|
// type: ZOOM
|
|
// })
|
|
// this.onTransform.forEach(function(f) {
|
|
// f(event)
|
|
// })
|
|
// }
|
|
}
|
|
|
|
onStart(event, interaction) {
|
|
|
|
if (this.startGesture(interaction)) {
|
|
this.dragging = true;
|
|
this.interactionAnchor = null;
|
|
}
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
translate: { x: 0, y: 0 },
|
|
scale: this.scale,
|
|
rotate: 0,
|
|
about: null,
|
|
fast: false,
|
|
type: START
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
|
|
onMove(event, interaction) {
|
|
/** As long as mouseout && mouseleave interrupt we cannot be sure that
|
|
* dragging remains correct.
|
|
*/
|
|
if (this.dragging) {
|
|
this.gesture(interaction);
|
|
}
|
|
}
|
|
|
|
onEnd(event, interaction) {
|
|
//console.log("Scatter.onEnd", this.dragging)
|
|
if (interaction.isFinished()) {
|
|
this.endGesture(interaction);
|
|
this.dragging = false;
|
|
for (let key of interaction.ended.keys()) {
|
|
if (interaction.isTap(key)) {
|
|
let point = interaction.ended.get(key);
|
|
this.onTap(event, interaction, point);
|
|
}
|
|
}
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
translate: { x: 0, y: 0 },
|
|
scale: this.scale,
|
|
rotate: 0,
|
|
about: null,
|
|
fast: false,
|
|
type: END
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
let about = this.interactionAnchor;
|
|
if (about != null) {
|
|
this.checkScaling(about, 100);
|
|
}
|
|
}
|
|
|
|
onTap(event, interaction, point) { }
|
|
|
|
onDragUpdate(delta) {
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
fast: true,
|
|
translate: delta,
|
|
scale: this.scale,
|
|
about: this.currentAbout,
|
|
type: null
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
|
|
onDragComplete() {
|
|
if (this.onTransform) {
|
|
let event = new ScatterEvent(this, {
|
|
scale: this.scale,
|
|
about: this.currentAbout,
|
|
fast: false,
|
|
type: null
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
|
|
onMoved(dx, dy, about) {
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
translate: { x: dx, y: dy },
|
|
about: about,
|
|
fast: true,
|
|
type: null
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
|
|
onResizing() {
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
scale: this.scale,
|
|
fast: false,
|
|
type: null
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
|
|
onZoomed(about) {
|
|
|
|
if (this.scaleAutoClose)
|
|
this._updateTransparency();
|
|
|
|
if (this.onTransform != null) {
|
|
let event = new ScatterEvent(this, {
|
|
scale: this.scale,
|
|
about: about,
|
|
fast: false,
|
|
type: null
|
|
});
|
|
this.onTransform.forEach(function (f) {
|
|
f(event);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/** A container for scatter objects, which uses a single InteractionMapper
|
|
* for all children. This reduces the number of registered event handlers
|
|
* and covers the common use case that multiple objects are scattered
|
|
* on the same level.
|
|
*/
|
|
class DOMScatterContainer {
|
|
/**
|
|
* @constructor
|
|
* @param {DOM node} element - DOM element that receives events
|
|
* @param {Bool} stopEvents - Whether events should be stopped or propagated
|
|
* @param {Bool} claimEvents - Whether events should be marked as claimed
|
|
* if findTarget return as non-null value.
|
|
* @param {String} [touchAction=none] - CSS to set touch action style, needed to prevent
|
|
* pointer cancel events. Use null if the
|
|
* the touch action should not be set.
|
|
*/
|
|
constructor(
|
|
element,
|
|
{ stopEvents = 'auto', claimEvents = true, useCapture = true, touchAction = 'none' } = {}
|
|
) {
|
|
this.onCapture = null;
|
|
this.element = element;
|
|
if (stopEvents === 'auto') {
|
|
if (Capabilities.isSafari) {
|
|
document.addEventListener(
|
|
'touchmove',
|
|
event => this.preventPinch(event),
|
|
false
|
|
);
|
|
stopEvents = false;
|
|
} else {
|
|
stopEvents = true;
|
|
}
|
|
}
|
|
this.stopEvents = stopEvents;
|
|
this.claimEvents = claimEvents;
|
|
if (touchAction !== null) {
|
|
Elements$1.setStyle(element, { touchAction });
|
|
}
|
|
this.scatter = new Map();
|
|
this.delegate = new InteractionMapper$1(element, this, {
|
|
useCapture,
|
|
mouseWheelElement: window
|
|
});
|
|
|
|
if (typeof debugCanvas !== 'undefined') {
|
|
requestAnimationFrame(dt => {
|
|
this.showTouches(dt);
|
|
});
|
|
}
|
|
}
|
|
|
|
showTouches(dt) {
|
|
let resolution = window.devicePixelRatio;
|
|
let canvas = debugCanvas;
|
|
let current = this.delegate.interaction.current;
|
|
let context = canvas.getContext('2d');
|
|
let radius = 20 * resolution;
|
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
context.fillStyle = 'rgba(0, 0, 0, 0.3)';
|
|
context.lineWidth = 2;
|
|
context.strokeStyle = '#003300';
|
|
for (let [key, point] of current.entries()) {
|
|
let local = point;
|
|
context.beginPath();
|
|
context.arc(
|
|
local.x * resolution,
|
|
local.y * resolution,
|
|
radius,
|
|
0,
|
|
2 * Math.PI,
|
|
false
|
|
);
|
|
context.fill();
|
|
context.stroke();
|
|
}
|
|
requestAnimationFrame(dt => {
|
|
this.showTouches(dt);
|
|
});
|
|
}
|
|
|
|
preventPinch(event) {
|
|
event = event.originalEvent || event;
|
|
if (event.scale !== 1) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
|
|
add(scatter) {
|
|
this.scatter.set(scatter.element, scatter);
|
|
}
|
|
|
|
capture(event) {
|
|
if (this.onCapture) {
|
|
return this.onCapture(event)
|
|
}
|
|
if (event.target == this.element && this.stopEvents) {
|
|
Events.stop(event);
|
|
}
|
|
return true
|
|
}
|
|
|
|
mapPositionToPoint(point) {
|
|
return Points.fromPageToNode(this.element, point)
|
|
}
|
|
|
|
isDescendant(parent, child, clickable = false) {
|
|
if (parent == child) return true
|
|
let node = child.parentNode;
|
|
while (node != null) {
|
|
if (!clickable && node.onclick) {
|
|
return false
|
|
}
|
|
if (node == parent) {
|
|
return true
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
return false
|
|
}
|
|
|
|
findTarget(event, local, global) {
|
|
/*** Note that elementFromPoint works with clientX, clientY, not pageX, pageY
|
|
The important point is that event should not be used, since the TouchEvent
|
|
points are hidden in sub objects.
|
|
***/
|
|
let found = document.elementFromPoint(global.x, global.y);
|
|
for (let target of this.scatter.values()) {
|
|
if (target.interactive && this.isDescendant(target.element, found)) {
|
|
if (this.stopEvents) Events.stop(event);
|
|
if (this.claimEvents) event.claimedByScatter = target;
|
|
return target
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
get center() {
|
|
let r = this.bounds;
|
|
let w2 = r.width / 2;
|
|
let h2 = r.height / 2;
|
|
return { x: w2, y: h2 }
|
|
}
|
|
|
|
get bounds() {
|
|
return this.element.getBoundingClientRect()
|
|
}
|
|
|
|
get polygon() {
|
|
let r = this.bounds;
|
|
let w2 = r.width / 2;
|
|
let h2 = r.height / 2;
|
|
let center = { x: w2, y: h2 };
|
|
let polygon = new Polygon(center);
|
|
polygon.addPoint({ x: -w2, y: -h2 });
|
|
polygon.addPoint({ x: w2, y: -h2 });
|
|
polygon.addPoint({ x: w2, y: h2 });
|
|
polygon.addPoint({ x: -w2, y: h2 });
|
|
return polygon
|
|
}
|
|
}
|
|
|
|
|
|
class DOMScatter extends AbstractScatter {
|
|
constructor(
|
|
element,
|
|
container,
|
|
{
|
|
startScale = 1.0,
|
|
minScale = 0.1,
|
|
maxScale = 1.0,
|
|
overdoScaling = 1.5,
|
|
autoBringToFront = true,
|
|
translatable = true,
|
|
scalable = true,
|
|
rotatable = true,
|
|
movableX = true,
|
|
movableY = true,
|
|
rotationDegrees = null,
|
|
rotation = null,
|
|
onTransform = null,
|
|
transformOrigin = 'center center',
|
|
// extras which are in part needed
|
|
x = 0,
|
|
y = 0,
|
|
width = null, // required
|
|
height = null, // required
|
|
resizable = false,
|
|
simulateClick = false,
|
|
verbose = true,
|
|
onResize = null,
|
|
touchAction = 'none',
|
|
throwVisibility = 44,
|
|
throwDamping = 0.95,
|
|
autoThrow = true,
|
|
scaleAutoClose = false,
|
|
onClose = null,
|
|
scaleCloseThreshold = 0.10,
|
|
scaleCloseBuffer = 0.05
|
|
} = {}
|
|
) {
|
|
super({
|
|
minScale,
|
|
maxScale,
|
|
startScale,
|
|
overdoScaling,
|
|
autoBringToFront,
|
|
translatable,
|
|
scalable,
|
|
rotatable,
|
|
movableX,
|
|
movableY,
|
|
resizable,
|
|
rotationDegrees,
|
|
rotation,
|
|
onTransform,
|
|
throwVisibility,
|
|
throwDamping,
|
|
autoThrow,
|
|
scaleAutoClose,
|
|
scaleCloseThreshold,
|
|
scaleCloseBuffer,
|
|
onClose
|
|
});
|
|
if (container == null || width == null || height == null) {
|
|
throw new Error('Invalid value: null')
|
|
}
|
|
element.scatter = this;
|
|
this.element = element;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.oldX = 0;
|
|
this.oldY = 0;
|
|
this.meanX = x;
|
|
this.meanY = y;
|
|
this.width = width;
|
|
this.height = height;
|
|
this.throwVisibility = Math.min(width, height, throwVisibility);
|
|
this.container = container;
|
|
this.simulateClick = simulateClick;
|
|
this.scale = startScale;
|
|
this.rotationDegrees = this.startRotationDegrees;
|
|
this.transformOrigin = transformOrigin;
|
|
this.initialValues = {
|
|
x: x,
|
|
y: y,
|
|
width: width,
|
|
height: height,
|
|
scale: startScale,
|
|
rotation: this.startRotationDegrees,
|
|
transformOrigin: transformOrigin
|
|
};
|
|
|
|
|
|
// For tweenlite we need initial values in _gsTransform
|
|
TweenLite.set(element, this.initialValues);
|
|
this.onResize = onResize;
|
|
this.verbose = verbose;
|
|
if (touchAction !== null) {
|
|
Elements$1.setStyle(element, { touchAction });
|
|
}
|
|
this.resizeButton = null;
|
|
if (resizable) {
|
|
let button = document.createElement("div");
|
|
button.style.position = "absolute";
|
|
button.style.right = "0px";
|
|
button.style.bottom = "0px";
|
|
button.style.width = "50px";
|
|
button.style.height = "50px";
|
|
// button.style.borderRadius = "100% 0px 0px 0px";
|
|
// button.style.background = this.element.style.backgroundColor
|
|
button.className = "interactiveElement";
|
|
this.element.appendChild(button);
|
|
|
|
button.addEventListener('pointerdown', (e) => {
|
|
this.startResize(e);
|
|
});
|
|
|
|
button.addEventListener('pointermove', (e) => {
|
|
this.resize(e);
|
|
});
|
|
|
|
button.addEventListener('pointerup', (e) => {
|
|
this.stopResize(e);
|
|
});
|
|
this.resizeButton = button;
|
|
}
|
|
container.add(this);
|
|
}
|
|
|
|
/** Returns geometry data as object. **/
|
|
getState() {
|
|
return {
|
|
scale: this.scale,
|
|
x: this.x,
|
|
y: this.y,
|
|
rotation: this.rotation
|
|
}
|
|
}
|
|
|
|
close() {
|
|
super.close();
|
|
let parent = this.element.parentNode;
|
|
if (parent) parent.removeChild(this.element);
|
|
}
|
|
|
|
get rotationOrigin() {
|
|
return this.center
|
|
}
|
|
|
|
get x() {
|
|
return this._x
|
|
}
|
|
|
|
get y() {
|
|
return this._y
|
|
}
|
|
|
|
set x(value) {
|
|
this._x = value;
|
|
TweenLite.set(this.element, { x: value });
|
|
}
|
|
|
|
set y(value) {
|
|
this._y = value;
|
|
TweenLite.set(this.element, { y: value });
|
|
}
|
|
|
|
get position() {
|
|
let transform = this.element._gsTransform;
|
|
let x = transform.x;
|
|
let y = transform.y;
|
|
return { x, y }
|
|
}
|
|
|
|
get origin() {
|
|
let p = this.fromNodeToPage(0, 0);
|
|
return Points.fromPageToNode(this.container.element, p)
|
|
}
|
|
|
|
get bounds() {
|
|
let stage = this.container.element.getBoundingClientRect();
|
|
let rect = this.element.getBoundingClientRect();
|
|
return {
|
|
top: rect.top - stage.top,
|
|
left: rect.left - stage.left,
|
|
width: rect.width,
|
|
height: rect.height
|
|
}
|
|
}
|
|
|
|
get center() {
|
|
let r = this.bounds;
|
|
let w2 = r.width / 2;
|
|
let h2 = r.height / 2;
|
|
// if (this.resizable) {
|
|
// w2 *= this.scale
|
|
// h2 *= this.scale
|
|
// }
|
|
var x = r.left + w2;
|
|
var y = r.top + h2;
|
|
return { x, y }
|
|
}
|
|
|
|
set rotation(radians) {
|
|
let rad = radians; // Angle.normalize(radians)
|
|
let degrees = Angle.radian2degree(rad);
|
|
TweenLite.set(this.element, { rotation: degrees });
|
|
this._rotation = rad;
|
|
}
|
|
|
|
set rotationDegrees(degrees) {
|
|
let deg = degrees; // Angle.normalizeDegree(degrees)
|
|
TweenLite.set(this.element, { rotation: deg });
|
|
this._rotation = Angle.degree2radian(deg);
|
|
}
|
|
|
|
get rotation() {
|
|
return this._rotation
|
|
}
|
|
|
|
get rotationDegrees() {
|
|
return this._rotation
|
|
}
|
|
|
|
set scale(scale) {
|
|
TweenLite.set(this.element, {
|
|
scale: scale,
|
|
transformOrigin: this.transformOrigin
|
|
});
|
|
this._scale = scale;
|
|
}
|
|
|
|
get scale() {
|
|
return this._scale
|
|
}
|
|
|
|
get containerBounds() {
|
|
return this.container.bounds
|
|
}
|
|
|
|
get containerPolygon() {
|
|
return this.container.polygon
|
|
}
|
|
|
|
mapPositionToContainerPoint(point) {
|
|
return this.container.mapPositionToPoint(point)
|
|
}
|
|
|
|
capture(event) {
|
|
return true
|
|
}
|
|
|
|
reset() {
|
|
TweenLite.set(this.element, this.initialValues);
|
|
}
|
|
|
|
hide() {
|
|
TweenLite.to(this.element, 0.1, {
|
|
display: 'none',
|
|
onComplete: e => {
|
|
this.element.parentNode.removeChild(this.element);
|
|
}
|
|
});
|
|
}
|
|
|
|
show() {
|
|
TweenLite.set(this.element, { display: 'block' });
|
|
}
|
|
|
|
showAt(p, rotationDegrees) {
|
|
TweenLite.set(this.element, {
|
|
display: 'block',
|
|
x: p.x,
|
|
y: p.y,
|
|
rotation: rotationDegrees,
|
|
transformOrigin: this.transformOrigin
|
|
});
|
|
}
|
|
|
|
bringToFront() {
|
|
// this.element.parentNode.appendChild(this.element)
|
|
// uo: On Chome and Electon appendChild leads to flicker
|
|
TweenLite.set(this.element, { zIndex: DOMScatter.zIndex++ });
|
|
}
|
|
|
|
toggleVideo(element) {
|
|
if (element.paused) {
|
|
element.play();
|
|
} else {
|
|
element.pause();
|
|
}
|
|
}
|
|
|
|
onTap(event, interaction, point) {
|
|
if (this.simulateClick) {
|
|
let p = Points.fromPageToNode(this.element, point);
|
|
let iframe = this.element.querySelector('iframe');
|
|
if (iframe) {
|
|
let doc = iframe.contentWindow.document;
|
|
let element = doc.elementFromPoint(p.x, p.y);
|
|
if (element == null) {
|
|
return
|
|
}
|
|
switch (element.tagName) {
|
|
case 'VIDEO':
|
|
console.log(element.currentSrc);
|
|
if (PopupMenu) {
|
|
PopupMenu.open(
|
|
{
|
|
Fullscreen: () =>
|
|
window.open(element.currentSrc),
|
|
Play: () => element.play()
|
|
},
|
|
{ x, y }
|
|
);
|
|
} else {
|
|
this.toggleVideo(element);
|
|
}
|
|
break
|
|
default:
|
|
element.click();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
isDescendant(parent, child) {
|
|
let node = child.parentNode;
|
|
while (node != null) {
|
|
if (node == parent) {
|
|
return true
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
return false
|
|
}
|
|
|
|
fromPageToNode(x, y) {
|
|
return Points.fromPageToNode(this.element, { x, y })
|
|
}
|
|
|
|
fromNodeToPage(x, y) {
|
|
return Points.fromNodeToPage(this.element, { x, y })
|
|
}
|
|
|
|
_move(delta) {
|
|
// UO: We need to keep TweenLite's _gsTransform and the private
|
|
// _x and _y attributes aligned
|
|
let x = this.element._gsTransform.x;
|
|
let y = this.element._gsTransform.y;
|
|
if (this.movableX) {
|
|
x += delta.x;
|
|
}
|
|
if (this.movableY) {
|
|
y += delta.y;
|
|
}
|
|
this._x = x;
|
|
this._y = y;
|
|
TweenLite.set(this.element, { x: x, y: y });
|
|
}
|
|
|
|
resizeAfterTransform(zoom) {
|
|
// let w = this.width * this.scale
|
|
// let h = this.height * this.scale
|
|
// TweenLite.set(this.element, { width: w, height: h })
|
|
if (this.onResize) {
|
|
let event = new ResizeEvent(this, { width: w, height: h });
|
|
this.onResize(event);
|
|
}
|
|
if (this.resizeButton != null) ;
|
|
}
|
|
|
|
startResize(e) {
|
|
e.preventDefault();
|
|
let event = new CustomEvent('resizeStarted');
|
|
|
|
let oldPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
|
|
this.bringToFront();
|
|
|
|
this.element.style.transformOrigin = "0% 0%";
|
|
|
|
let newPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
|
|
|
|
let offset = Points.subtract(oldPostition, newPostition);
|
|
|
|
this.oldX = e.clientX;
|
|
this.oldY = e.clientY;
|
|
|
|
e.target.setAttribute('resizing', "true");
|
|
e.target.setPointerCapture(e.pointerId);
|
|
|
|
TweenLite.to(this.element, 0, { css: { left: "+=" + offset.x + "px" } });
|
|
TweenLite.to(this.element, 0, { css: { top: "+=" + offset.y + "px" } });
|
|
|
|
this.element.dispatchEvent(event);
|
|
}
|
|
|
|
resize(e) {
|
|
e.preventDefault();
|
|
|
|
let rotation = Angle.radian2degree(this.rotation);
|
|
rotation = (rotation + 360) % 360;
|
|
let event = new CustomEvent('resized');
|
|
if (e.target.getAttribute('resizing') == "true") {
|
|
|
|
let deltaX = (e.clientX - this.oldX);
|
|
let deltaY = (e.clientY - this.oldY);
|
|
|
|
let r = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
|
|
let phi = Angle.radian2degree(Math.atan2(deltaX, deltaY));
|
|
|
|
phi = ((phi) + 630) % 360;
|
|
let rot = ((rotation + 90) + 630) % 360;
|
|
|
|
let diffAngle = ((0 + rot) + 360) % 360;
|
|
let phiCorrected = (phi + diffAngle + 360) % 360;
|
|
|
|
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected));
|
|
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected));
|
|
|
|
if (this.element.offsetWidth + resizeW / this.scale > this.width * 0.3 && this.element.offsetHeight + resizeH / this.scale > this.height * 0.3) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
|
|
|
this.oldX = e.clientX;
|
|
this.oldY = e.clientY;
|
|
this.onResizing();
|
|
|
|
this.element.dispatchEvent(event);
|
|
}
|
|
}
|
|
|
|
stopResize(e) {
|
|
e.preventDefault();
|
|
|
|
let event = new CustomEvent('resizeEnded');
|
|
let oldPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
|
|
this.element.style.transformOrigin = "50% 50%";
|
|
let newPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
|
|
let offset = Points.subtract(oldPostition, newPostition);
|
|
|
|
TweenLite.to(this.element, 0, { css: { left: "+=" + offset.x + "px" } });
|
|
TweenLite.to(this.element, 0, { css: { top: "+=" + offset.y + "px" } });
|
|
|
|
e.target.setAttribute('resizing', "false");
|
|
|
|
this.element.dispatchEvent(event);
|
|
}
|
|
}
|
|
|
|
DOMScatter.zIndex = 1000;
|
|
|
|
class CardLoader {
|
|
constructor(
|
|
src,
|
|
{
|
|
x = 0,
|
|
y = 0,
|
|
width = 1000,
|
|
height = 800,
|
|
maxWidth = null,
|
|
maxHeight = null,
|
|
scale = 1,
|
|
minScale = 0.5,
|
|
maxScale = 1.5,
|
|
rotation = 0
|
|
} = {}
|
|
) {
|
|
this.src = src;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.scale = scale;
|
|
this.rotation = 0;
|
|
this.maxScale = maxScale;
|
|
this.minScale = minScale;
|
|
this.wantedWidth = width;
|
|
this.wantedHeight = height;
|
|
this.maxWidth = maxWidth != null ? maxWidth : window.innerWidth;
|
|
this.maxHeight = maxHeight != null ? maxHeight : window.innerHeight;
|
|
this.addedNode = null;
|
|
console.log({
|
|
|
|
width,
|
|
height,
|
|
maxWidth,
|
|
maxHeight,
|
|
|
|
});
|
|
}
|
|
|
|
unload() {
|
|
if (this.addedNode) {
|
|
this.addedNode.remove();
|
|
this.addedNode = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
class PDFLoader extends CardLoader {
|
|
constructor(src, { width = 1640, height = 800, scale = 1 } = {}) {
|
|
super(src, { width, height, scale });
|
|
if (typeof PDFJS == 'undefined') {
|
|
alert('PDF.js needed');
|
|
}
|
|
}
|
|
|
|
load(domNode) {
|
|
return new Promise((resolve, reject) => {
|
|
PDFJS.getDocument(this.src).then(pdf => {
|
|
pdf.getPage(1).then(page => {
|
|
let scale = this.scale * app.renderer.resolution;
|
|
let invScale = 1 / scale;
|
|
let viewport = page.getViewport(scale);
|
|
|
|
// Prepare canvas using PDF page dimensions.
|
|
let canvas = document.createElement('canvas');
|
|
let context = canvas.getContext('2d');
|
|
canvas.height = viewport.height;
|
|
canvas.width = viewport.width;
|
|
|
|
// Render PDF page into canvas context.
|
|
let renderContext = {
|
|
canvasContext: context,
|
|
viewport: viewport
|
|
};
|
|
page.render(renderContext);
|
|
domNode.appendChild(canvas);
|
|
this.wantedWidth = canvas.width;
|
|
this.wantedHeight = canvas.height;
|
|
this.scale = invScale;
|
|
this.addedNode = canvas;
|
|
resolve(this);
|
|
});
|
|
});
|
|
})
|
|
}
|
|
}
|
|
|
|
class ImageLoader extends CardLoader {
|
|
load(domNode) {
|
|
return new Promise((resolve, reject) => {
|
|
let isImage = domNode instanceof HTMLImageElement;
|
|
let image = isImage ? domNode : document.createElement('img');
|
|
image.onload = e => {
|
|
if (!isImage) {
|
|
domNode.appendChild(image);
|
|
this.addedNode = image;
|
|
}
|
|
this.wantedWidth = image.naturalWidth;
|
|
this.wantedHeight = image.naturalHeight;
|
|
|
|
let scaleW = this.maxWidth / image.naturalWidth;
|
|
let scaleH = this.maxHeight / image.naturalHeight;
|
|
this.scale = Math.min(this.maxScale, Math.min(scaleW, scaleH));
|
|
image.setAttribute('draggable', false);
|
|
image.width = image.naturalWidth;
|
|
image.height = image.naturalHeight;
|
|
resolve(this);
|
|
};
|
|
image.onerror = e => {
|
|
reject(this);
|
|
};
|
|
image.src = this.src;
|
|
})
|
|
}
|
|
}
|
|
|
|
class FrameLoader extends CardLoader {
|
|
load(domNode) {
|
|
return new Promise((resolve, reject) => {
|
|
let isFrame = domNode instanceof HTMLIFrameElement;
|
|
let iframe = isFrame ? domNode : document.createElement('iframe');
|
|
console.log('FrameLoader.load', isFrame, iframe, this.src);
|
|
iframe.frameBorder = 0;
|
|
iframe.style.scrolling = false;
|
|
iframe.width = this.wantedWidth;
|
|
iframe.height = this.wantedHeight;
|
|
if (!isFrame) {
|
|
// Unlike img onload is only triggered if the iframe is part of the DOM tree
|
|
domNode.appendChild(iframe);
|
|
this.addedNode = iframe;
|
|
}
|
|
iframe.onload = e => {
|
|
resolve(this);
|
|
};
|
|
iframe.onerror = e => {
|
|
reject(this);
|
|
};
|
|
iframe.src = this.src;
|
|
})
|
|
}
|
|
}
|
|
|
|
class HTMLLoader extends CardLoader {
|
|
load(domNode) {
|
|
return new Promise((resolve, reject) => {
|
|
let xhr = new XMLHttpRequest();
|
|
xhr.open('GET', this.src, false);
|
|
xhr.onload = e => {
|
|
domNode.innerHTML = xhr.response;
|
|
this.addedNode = domNode.firstElementChild;
|
|
let { width, height } = this.size(this.addedNode);
|
|
console.log("HTMLLoader.load", { added: this.addedNode, width, height });
|
|
if (width)
|
|
this.wantedWidth = width || this.wantedWidth;
|
|
if (height)
|
|
this.wantedHeight = height || this.wantedHeight;
|
|
resolve(this);
|
|
};
|
|
xhr.onerror = e => {
|
|
reject(this);
|
|
};
|
|
xhr.send();
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Tries to determine the size of the addedNode.
|
|
* Checks for explicit width and height style attributes.
|
|
*
|
|
* Overwrite this method if you want to extract values from other infos.
|
|
*
|
|
* @returns { width: int, height: int }
|
|
* @memberof HTMLLoader
|
|
*/
|
|
size(node) {
|
|
let width = parseInt(node.style.width) || null;
|
|
let height = parseInt(node.style.height) || null;
|
|
return { width, height }
|
|
}
|
|
}
|
|
|
|
class DOMFlip {
|
|
constructor(
|
|
domScatterContainer,
|
|
flipTemplate,
|
|
frontLoader,
|
|
backLoader,
|
|
{
|
|
closeOnMinScale = false,
|
|
flipDuration = 1,
|
|
fadeDuration = 0.2,
|
|
overdoScaling = 1,
|
|
autoLoad = false,
|
|
center = null,
|
|
preloadBack = false,
|
|
translatable = true,
|
|
scalable = true,
|
|
rotatable = true,
|
|
onFront = null,
|
|
onBack = null,
|
|
onClose = null,
|
|
onUpdate = null,
|
|
onRemoved = null,
|
|
onLoaded = null
|
|
} = {}
|
|
) {
|
|
this.domScatterContainer = domScatterContainer;
|
|
this.id = getId$1();
|
|
this.flipDuration = flipDuration;
|
|
this.fadeDuration = fadeDuration;
|
|
this.closeOnMinScale = closeOnMinScale;
|
|
this.flipTemplate = flipTemplate;
|
|
this.frontLoader = frontLoader;
|
|
this.backLoader = backLoader;
|
|
this.translatable = translatable;
|
|
this.scalable = scalable;
|
|
this.rotatable = rotatable;
|
|
this.onFrontFlipped = onFront;
|
|
this.onBackFlipped = onBack;
|
|
this.onClose = onClose;
|
|
this.onRemoved = onRemoved;
|
|
this.onUpdate = onUpdate;
|
|
this.onLoaded = onLoaded;
|
|
this.center = center;
|
|
this.preloadBack = preloadBack;
|
|
this.overdoScaling = overdoScaling;
|
|
if (autoLoad) {
|
|
this.load();
|
|
}
|
|
}
|
|
|
|
load() {
|
|
return new Promise((resolve, reject) => {
|
|
let t = this.flipTemplate;
|
|
let dom = this.domScatterContainer.element;
|
|
let wrapper = t.content.querySelector('.flipWrapper');
|
|
wrapper.id = this.id;
|
|
let clone = document.importNode(t.content, true);
|
|
dom.appendChild(clone);
|
|
// We cannot use the document fragment itself because it
|
|
// is not part of the main dom tree. After the appendChild
|
|
// call we can access the new dom element by id
|
|
this.cardWrapper = dom.querySelector('#' + this.id);
|
|
let front = this.cardWrapper.querySelector('.front');
|
|
this.frontLoader.load(front).then(loader => {
|
|
this.frontLoaded(loader).then((obj) => {
|
|
if (this.onLoaded) this.onLoaded();
|
|
resolve(this);
|
|
});
|
|
});
|
|
})
|
|
}
|
|
|
|
frontLoaded(loader) {
|
|
return new Promise((resolve, reject) => {
|
|
let scatter = new DOMScatter(
|
|
this.cardWrapper,
|
|
this.domScatterContainer,
|
|
{
|
|
x: loader.x,
|
|
y: loader.y,
|
|
startScale: loader.scale,
|
|
scale: loader.scale,
|
|
maxScale: loader.maxScale,
|
|
minScale: loader.minScale,
|
|
width: loader.wantedWidth,
|
|
height: loader.wantedHeight,
|
|
rotation: loader.rotation,
|
|
translatable: this.translatable,
|
|
scalable: this.scalable,
|
|
rotatable: this.rotatable,
|
|
overdoScaling: this.overdoScaling
|
|
}
|
|
);
|
|
|
|
if (this.center) {
|
|
scatter.centerAt(this.center);
|
|
}
|
|
|
|
if (this.closeOnMinScale) {
|
|
|
|
const removeOnMinScale = function () {
|
|
if (scatter.scale <= scatter.minScale) {
|
|
this.flippable.close();
|
|
|
|
// 'Disable' overdoscaling to avoid weird jumps on close.
|
|
scatter.minScale /= scatter.overdoScaling;
|
|
scatter.overdoScaling = 1;
|
|
|
|
//Remove callback
|
|
if (scatter.onTransform) {
|
|
let callbackIdx = scatter.onTransform.indexOf(removeOnMinScale);
|
|
scatter.onTransform.splice(callbackIdx, 1);
|
|
}
|
|
}
|
|
|
|
}.bind(this);
|
|
|
|
|
|
|
|
scatter.addTransformEventCallback(removeOnMinScale);
|
|
}
|
|
|
|
let flippable = new DOMFlippable(this.cardWrapper, scatter, this);
|
|
let back = this.cardWrapper.querySelector('.back');
|
|
|
|
if (this.preloadBack) {
|
|
this.backLoader.load(back).then(loader => {
|
|
this.setupFlippable(flippable, loader);
|
|
});
|
|
}
|
|
this.flippable = flippable;
|
|
resolve(this);
|
|
})
|
|
}
|
|
|
|
centerAt(p) {
|
|
this.center = p;
|
|
this.flippable.centerAt(p);
|
|
}
|
|
|
|
zoom(scale) {
|
|
this.flippable.zoom(scale);
|
|
}
|
|
|
|
setupFlippable(flippable, loader) {
|
|
flippable.wantedWidth = loader.wantedWidth;
|
|
flippable.wantedHeight = loader.wantedHeight;
|
|
flippable.wantedScale = loader.scale;
|
|
flippable.minScale = loader.minScale;
|
|
flippable.maxScale = loader.maxScale;
|
|
flippable.scaleButtons();
|
|
}
|
|
|
|
start({ targetCenter = null } = {}) {
|
|
console.log('DOMFlip.start', targetCenter);
|
|
if (this.preloadBack) this.flippable.start({ duration: this.flipDuration, targetCenter });
|
|
else {
|
|
let back = this.cardWrapper.querySelector('.back');
|
|
let flippable = this.flippable;
|
|
this.backLoader.load(back).then(loader => {
|
|
this.setupFlippable(flippable, loader);
|
|
flippable.start({ duration: this.flipDuration, targetCenter });
|
|
});
|
|
}
|
|
}
|
|
|
|
fadeOutAndRemove() {
|
|
TweenLite.to(this.cardWrapper, this.fadeDuration, {
|
|
opacity: 0,
|
|
onComplete: () => {
|
|
this.cardWrapper.remove();
|
|
}
|
|
});
|
|
}
|
|
|
|
closed() {
|
|
this.unload();
|
|
}
|
|
|
|
unload() {
|
|
if (!this.preloadBack) {
|
|
this.backLoader.unload();
|
|
}
|
|
}
|
|
}
|
|
|
|
class DOMFlippable {
|
|
constructor(element, scatter, flip) {
|
|
// Set log to console.log or a custom log function
|
|
// define data structures to store our touchpoints in
|
|
|
|
this.element = element;
|
|
this.flip = flip;
|
|
this.card = element.querySelector('.flipCard');
|
|
this.front = element.querySelector('.front');
|
|
this.back = element.querySelector('.back');
|
|
this.flipped = false;
|
|
this.scatter = scatter;
|
|
this.onFrontFlipped = flip.onFrontFlipped;
|
|
this.onBackFlipped = flip.onBackFlipped;
|
|
this.onClose = flip.onClose;
|
|
this.onRemoved = flip.onRemoved;
|
|
this.onUpdate = flip.onUpdate;
|
|
|
|
this.flipDuration = flip.flipDuration;
|
|
this.fadeDuration = flip.fadeDuration;
|
|
scatter.addTransformEventCallback(this.scatterTransformed.bind(this));
|
|
console.log('lib.DOMFlippable', 5000);
|
|
TweenLite.set(this.element, { perspective: 5000 });
|
|
TweenLite.set(this.card, { transformStyle: 'preserve-3d' });
|
|
TweenLite.set(this.back, { rotationY: -180 });
|
|
TweenLite.set([this.back, this.front], {
|
|
backfaceVisibility: 'hidden',
|
|
perspective: 5000
|
|
});
|
|
TweenLite.set(this.front, { visibility: 'visible' });
|
|
this.infoBtn = element.querySelector('.infoBtn');
|
|
this.backBtn = element.querySelector('.backBtn');
|
|
this.closeBtn = element.querySelector('.closeBtn');
|
|
/* Buttons are not guaranteed to exist. */
|
|
if (this.infoBtn) {
|
|
InteractionMapper$1.on('tap', this.infoBtn, event => this.flip.start());
|
|
|
|
this.enable(this.infoBtn);
|
|
}
|
|
if (this.backBtn) {
|
|
InteractionMapper$1.on('tap', this.backBtn, event => this.start());
|
|
}
|
|
if (this.closeBtn) {
|
|
InteractionMapper$1.on('tap', this.closeBtn, event => this.close());
|
|
this.enable(this.closeBtn);
|
|
}
|
|
this.scaleButtons();
|
|
this.bringToFront();
|
|
}
|
|
|
|
close() {
|
|
this.disable(this.infoBtn);
|
|
this.disable(this.closeBtn);
|
|
if (this.onClose) {
|
|
this.onClose(this);
|
|
this.flip.closed();
|
|
} else {
|
|
this.scatter.zoom(0.1, {
|
|
animate: this.fadeDuration,
|
|
onComplete: () => {
|
|
this.element.remove();
|
|
this.flip.closed();
|
|
if (this.onRemoved) {
|
|
this.onRemoved.call(this);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
showFront() {
|
|
TweenLite.set(this.front, { visibility: 'visible' });
|
|
}
|
|
|
|
centerAt(p) {
|
|
this.scatter.centerAt(p);
|
|
}
|
|
|
|
zoom(scale) {
|
|
this.scatter.zoom(scale);
|
|
}
|
|
|
|
get buttonScale() {
|
|
let iscale = 1.0;
|
|
|
|
if (this.scatter != null) {
|
|
let scale = this.scatter.scale || 1;
|
|
iscale = 1.0 / scale;
|
|
}
|
|
return iscale
|
|
}
|
|
|
|
scaleButtons() {
|
|
//This also works for svgs.
|
|
// if (this.infoBtn)
|
|
// this.infoBtn.style.transform = "scale(" + this.buttonScale + ")"
|
|
|
|
// if (this.backBtn)
|
|
// this.backBtn.style.transform = "scale(" + this.buttonScale + ")"
|
|
|
|
// if (this.closeBtn)
|
|
// this.closeBtn.style.transform = "scale(" + this.buttonScale + ")"
|
|
|
|
console.log(this.buttonScale);
|
|
//// This did not work with svgs!
|
|
TweenLite.set([this.infoBtn, this.backBtn, this.closeBtn], {
|
|
scale: this.buttonScale
|
|
});
|
|
}
|
|
|
|
bringToFront() {
|
|
this.scatter.bringToFront();
|
|
TweenLite.set(this.element, { zIndex: DOMScatter.zIndex++ });
|
|
}
|
|
|
|
clickInfo() {
|
|
this.bringToFront();
|
|
this.infoBtn.click();
|
|
}
|
|
|
|
scatterTransformed(event) {
|
|
this.scaleButtons();
|
|
}
|
|
|
|
targetRotation(alpha) {
|
|
let ortho = 90;
|
|
let rest = alpha % ortho;
|
|
let delta = 0.0;
|
|
if (rest > ortho / 2.0) {
|
|
delta = ortho - rest;
|
|
} else {
|
|
delta = -rest;
|
|
}
|
|
return delta
|
|
}
|
|
|
|
infoValues(info) {
|
|
let startX = this.element._gsTransform.x;
|
|
let startY = this.element._gsTransform.y;
|
|
let startAngle = this.element._gsTransform.rotation;
|
|
let startScale = this.element._gsTransform.scaleX;
|
|
let w = this.element.style.width;
|
|
let h = this.element.style.height;
|
|
console.log(info, startX, startY, startAngle, startScale, w, h);
|
|
}
|
|
|
|
show(element, duration = 0, alpha = 1) {
|
|
if (element) {
|
|
TweenLite.to(element, duration, { autoAlpha: alpha }); // visibility: 'visible', display: 'initial'})
|
|
}
|
|
}
|
|
|
|
hide(element, duration = 0, alpha = 0) {
|
|
if (element) {
|
|
TweenLite.to(element, duration, { autoAlpha: alpha }); // {visibility: 'hidden', display: 'none'})
|
|
}
|
|
}
|
|
|
|
|
|
|
|
enable(button) {
|
|
this.show(button, this.fadeDuration);
|
|
if (button) {
|
|
TweenLite.set(button, { pointerEvents: 'auto' });
|
|
}
|
|
}
|
|
|
|
disable(button) {
|
|
this.hide(button, this.fadeDuration);
|
|
if (button) {
|
|
TweenLite.set(button, { pointerEvents: 'none' });
|
|
}
|
|
}
|
|
|
|
start({ targetCenter = null } = {}) {
|
|
this.bringToFront();
|
|
if (!this.flipped) {
|
|
this.startX = this.element._gsTransform.x;
|
|
this.startY = this.element._gsTransform.y;
|
|
this.startAngle = this.element._gsTransform.rotation;
|
|
this.startScale = this.element._gsTransform.scaleX;
|
|
this.startWidth = this.element.style.width;
|
|
this.startHeight = this.element.style.height;
|
|
this.scatterStartWidth = this.scatter.width;
|
|
this.scatterStartHeight = this.scatter.height;
|
|
this.show(this.back);
|
|
this.disable(this.infoBtn);
|
|
this.disable(this.closeBtn);
|
|
} else {
|
|
this.show(this.front, this.fadeDuration);
|
|
this.disable(this.backBtn);
|
|
}
|
|
let { scalable, translatable, rotatable } = this.scatter;
|
|
this.saved = { scalable, translatable, rotatable };
|
|
this.scatter.scalable = false;
|
|
this.scatter.translatable = false;
|
|
this.scatter.rotatable = false;
|
|
this.scatter.killAnimation();
|
|
|
|
this.flipped = !this.flipped;
|
|
let targetY = this.flipped ? 180 : 0;
|
|
let targetZ = this.flipped
|
|
? this.startAngle + this.targetRotation(this.startAngle)
|
|
: this.startAngle;
|
|
let targetScale = this.flipped ? this.wantedScale : this.startScale;
|
|
let w = this.flipped ? this.wantedWidth : this.startWidth;
|
|
let h = this.flipped ? this.wantedHeight : this.startHeight;
|
|
let dw = this.wantedWidth - this.scatter.width;
|
|
let dh = this.wantedHeight - this.scatter.height;
|
|
let tc = targetCenter;
|
|
let xx = tc != null ? tc.x - w / 2 : this.startX - dw / 2;
|
|
let yy = tc != null ? tc.y - h / 2 : this.startY - dh / 2;
|
|
let x = this.flipped ? xx : this.startX;
|
|
let y = this.flipped ? yy : this.startY;
|
|
|
|
console.log("DOMFlippable.start", this.flipped, targetCenter, x, y, this.saved);
|
|
let onUpdate = this.onUpdate !== null ? () => this.onUpdate(this) : null;
|
|
console.log(this.flipDuration);
|
|
TweenLite.to(this.card, this.flipDuration, {
|
|
rotationY: targetY,
|
|
ease: Power1.easeOut,
|
|
transformOrigin: '50% 50%',
|
|
onUpdate,
|
|
onComplete: e => {
|
|
if (this.flipped) {
|
|
//this.hide(this.front)
|
|
this.enable(this.backBtn);
|
|
this.show(this.backBtn);
|
|
|
|
if (this.onFrontFlipped) {
|
|
this.onFrontFlipped(this);
|
|
}
|
|
} else {
|
|
|
|
if (this.onBackFlipped == null) {
|
|
this.enable(this.infoBtn, this.fadeDuration);
|
|
this.enable(this.closeBtn, this.fadeDuration);
|
|
} else {
|
|
this.onBackFlipped(this);
|
|
}
|
|
this.flip.unload();
|
|
}
|
|
this.scatter.scale = targetScale;
|
|
this.scaleButtons();
|
|
this.scatter.rotationDegrees = targetZ;
|
|
this.scatter.width = this.flipped ? w : this.scatterStartWidth;
|
|
this.scatter.height = this.flipped ? h : this.scatterStartHeight;
|
|
|
|
let { scalable, translatable, rotatable } = this.saved;
|
|
this.scatter.scalable = scalable;
|
|
this.scatter.translatable = translatable;
|
|
this.scatter.rotatable = rotatable;
|
|
},
|
|
force3D: true
|
|
});
|
|
|
|
// See https://greensock.com/forums/topic/7997-rotate-the-shortest-way/
|
|
TweenLite.to(this.element, this.flipDuration / 2, {
|
|
scale: targetScale,
|
|
ease: Power1.easeOut,
|
|
rotationZ: targetZ + '_short',
|
|
transformOrigin: '50% 50%',
|
|
width: w,
|
|
height: h,
|
|
x: x,
|
|
y: y,
|
|
onComplete: e => {
|
|
if (this.flipped) {
|
|
this.hide(this.front);
|
|
// this.hide(this.infoBtn)
|
|
} else {
|
|
this.hide(this.back);
|
|
// this.show(this.infoBtn)
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
class Index {
|
|
|
|
constructor(template, pages, notfound='thumbnails/notfound.png') {
|
|
this.template = template;
|
|
this.pages = pages;
|
|
this.notfound = notfound;
|
|
}
|
|
|
|
setup() {
|
|
for(let pair of this.pages) {
|
|
let [title, src] = pair;
|
|
let id = getId();
|
|
pair.push(id);
|
|
let t = this.template;
|
|
let wrapper = t.content.querySelector('.wrapper');
|
|
wrapper.id = id;
|
|
let clone = document.importNode(t.content, true);
|
|
container.appendChild(clone);
|
|
wrapper = container.querySelector('#'+id);
|
|
|
|
let icon = wrapper.querySelector('.icon');
|
|
|
|
icon.onerror = (e) => {
|
|
if (this.notfound)
|
|
icon.src = this.notfound;
|
|
};
|
|
let iconSrc = src.replace('.html', '.png');
|
|
//console.log("iconSrc", iconSrc)
|
|
if (iconSrc.endsWith('index.png')) {
|
|
icon.src = iconSrc.replace('index.png', 'thumbnail.png');
|
|
} else if (iconSrc.endsWith('test.png')) {
|
|
icon.src = iconSrc.replace('test.png', 'thumbnail.test.png');
|
|
} else {
|
|
icon.src = 'thumbnails/' + iconSrc;
|
|
}
|
|
wrapper.href = src;
|
|
let titleDiv = wrapper.querySelector('.title');
|
|
titleDiv.innerText = title;
|
|
}
|
|
}
|
|
|
|
frames() {
|
|
if (this.pages.length == 0)
|
|
return
|
|
let [title, src, id] = this.pages.shift();
|
|
let iframe = document.createElement('iframe');
|
|
iframe.frameborder = 0;
|
|
let wrapper = document.getElementById(id);
|
|
let icon = wrapper.querySelector('.icon');
|
|
|
|
icon.parentNode.replaceChild(iframe, icon);
|
|
iframe.onload = (e) => {
|
|
this.frames();
|
|
};
|
|
iframe.src = src + window.location.search;
|
|
}
|
|
|
|
load() {
|
|
this.setup();
|
|
if (window.location.search.startsWith('?test'))
|
|
this.frames();
|
|
}
|
|
|
|
loadAndTest() {
|
|
this.setup();
|
|
if (!Capabilities.isMobile)
|
|
this.frames();
|
|
}
|
|
}
|
|
|
|
/** Basic class for poppable elements that need to be closed as soon as one poppable is
|
|
* shown.
|
|
*/
|
|
class Poppable {
|
|
|
|
/** Register the poppable element in a context. Closes previously registered ones.
|
|
* @param {*} context
|
|
*/
|
|
register(context) {
|
|
let registered = Poppable.get(context);
|
|
if (registered != null) {
|
|
registered.close();
|
|
}
|
|
Poppable.set(context, this);
|
|
}
|
|
|
|
/**
|
|
* Unregister object from context
|
|
* @param {*} context
|
|
*/
|
|
unregister(context) {
|
|
Poppable.delete(context);
|
|
}
|
|
|
|
/**
|
|
* Returns the given poppable in a context
|
|
* @static
|
|
* @param {*} context
|
|
* @returns
|
|
* @memberof Poppable
|
|
*/
|
|
static get(context) {
|
|
return Poppable.registrations.get(context)
|
|
}
|
|
|
|
/** Sets the poppable in the given context
|
|
* @static
|
|
* @param {*} context
|
|
* @param {*} poppable
|
|
* @returns
|
|
* @memberof Poppable
|
|
*/
|
|
static set(context, poppable) {
|
|
return Poppable.registrations.set(context, poppable)
|
|
}
|
|
|
|
/** Test whether a poppable exists in the given context
|
|
*
|
|
* @param {*} context
|
|
*/
|
|
static has(context) {
|
|
return Poppable.registrations.has(context)
|
|
}
|
|
|
|
/**
|
|
* Removes the poppable from the given context.
|
|
*
|
|
* @static
|
|
* @param {*} context
|
|
* @memberof Poppable
|
|
*/
|
|
static delete(context) {
|
|
Poppable.registrations.delete(context);
|
|
}
|
|
|
|
/** All poppable must implement a close method. */
|
|
close() {
|
|
console.error("Must be implemented");
|
|
}
|
|
}
|
|
|
|
Poppable.registrations = new Map();
|
|
|
|
/** A Popup that shows text labels, images, or html
|
|
*/
|
|
class Popup extends Poppable {
|
|
/**
|
|
* Creates an instance of Popup.
|
|
* @param {any} [{
|
|
* parent = null, - The DOM parent element.
|
|
* content = null, - A dict object with type strings (text, img, html) as keys
|
|
* and corresponding values.
|
|
* context = window, - A context object for poppable elements
|
|
* fontSize = "1em", - Describes the font size as CSS value
|
|
* fontFamily = "Arial", - Describes the font family as CSS value
|
|
* padding = 16, - {number || string} padding - Describes the padding as CSS value
|
|
* notchSize = 10, - {number || string} notchSize - Describes the size of the notch (callout) as CSS value
|
|
* switchPos = false,
|
|
* minWidth = null,
|
|
* maxWidth = 800,
|
|
* backgroundColor = "#EEE", - The color of the background as CSS value
|
|
* normalColor = "#444", - normalColor - The color of textitems as CSS value
|
|
* notchPosition = "bottomLeft",
|
|
* zIndex = 0,
|
|
* keepWithin = null, - Ensure that popup is visible within the bounds of the given container
|
|
* autoClose = true, - Autoclose the Popup on tap
|
|
* closeIcon = null,
|
|
* resizeIcon = null,
|
|
* closeCommand = null,
|
|
* draggable = false
|
|
* noStyle = false - When true, prevents the popup from doing any aesthetic manipulations to the DOM leaving the styling completely to the style sheets.
|
|
* }={}]
|
|
* @memberof Popup
|
|
*/
|
|
constructor({
|
|
parent = null,
|
|
content = null,
|
|
context = window,
|
|
fontSize = "1em",
|
|
fontFamily = "Arial",
|
|
padding = 16,
|
|
notchSize = 10,
|
|
switchPos = false,
|
|
minWidth = null,
|
|
maxWidth = 800,
|
|
backgroundColor = "#EEE",
|
|
normalColor = "#444",
|
|
notchPosition = "bottomCenter",
|
|
zIndex = 0,
|
|
keepWithin = null,
|
|
autoClose = true,
|
|
closeIcon = null,
|
|
resizeIcon = null,
|
|
closeCommand = null,
|
|
draggable = false,
|
|
posOffset = 0,
|
|
targetBoundingBox = null,
|
|
useEventPosWithBoundingBox = false,
|
|
interactive = false,
|
|
onResize = null,
|
|
onMove = null,
|
|
noStyle = false,
|
|
hideOnUp = true,
|
|
} = {}) {
|
|
super();
|
|
this.context = context;
|
|
this.noStyle = noStyle;
|
|
this.hideOnUp = hideOnUp;
|
|
this.padding = padding;
|
|
this.notchPosition = notchPosition;
|
|
this.notchSize = notchSize;
|
|
this.switchPos = switchPos;
|
|
this.fontSize = fontSize;
|
|
this.fontFamily = fontFamily;
|
|
this.minWidth = minWidth;
|
|
this.maxWidth = maxWidth;
|
|
this.normalColor = normalColor;
|
|
this.backgroundColor = backgroundColor;
|
|
this.keepWithin = keepWithin;
|
|
this.autoClose = autoClose;
|
|
this.resizeIcon = resizeIcon;
|
|
this.closeIcon = closeIcon;
|
|
this.closeCommand = closeCommand;
|
|
this.zIndex = zIndex;
|
|
this.parent = parent || document.body;
|
|
this.draggable = draggable;
|
|
this.posOffset = posOffset;
|
|
this.targetBoundingBox = targetBoundingBox;
|
|
this.useEventPosWithBoundingBox = useEventPosWithBoundingBox;
|
|
this.currentPos = null;
|
|
this.insertedNode = null;
|
|
this.loaded = false;
|
|
this.interactive = interactive;
|
|
this.onload = null;
|
|
this.onResize = onResize;
|
|
this.onMove = onMove;
|
|
if (content) {
|
|
this.show(content);
|
|
}
|
|
}
|
|
|
|
/** Setup popup with a dictionary of content types and contents.
|
|
* @param {Object} content - A dict object with type strings (text, img, html) as keys
|
|
* and corresponding values.
|
|
* @return {Popup} this
|
|
*/
|
|
setup(content) {
|
|
//console.log("Popup.setup", this.draggable)
|
|
this.content = content;
|
|
this.items = {};
|
|
this.element = document.createElement("div");
|
|
this.element.classList.add("popup");
|
|
this.setAlpha(this.element, 0);
|
|
// this.element.style.opacity = 0
|
|
Elements$1.addClass(this.element, "unselectable");
|
|
this.notch = document.createElement("div");
|
|
Elements$1.setStyle(this.notch, this.notchStyle());
|
|
this.notch.className = "notch";
|
|
this.setupDraggable();
|
|
if (this.closeIcon) {
|
|
let img = document.createElement("img");
|
|
img.setAttribute("draggable", false);
|
|
img.src = this.closeIcon;
|
|
img.style.position = "absolute";
|
|
img.style.right = "0px";
|
|
img.style.top = "0px";
|
|
img.style.width = "16px";
|
|
img.style.height = "16px";
|
|
img.onclick = e => {
|
|
this.close();
|
|
};
|
|
this.element.appendChild(img);
|
|
}
|
|
if (this.resizeIcon) {
|
|
let img = document.createElement("img");
|
|
img.style.position = "absolute";
|
|
img.style.right = "0px";
|
|
img.style.bottom = "0px";
|
|
img.style.width = "16px";
|
|
img.style.height = "16px";
|
|
img.src = this.resizeIcon;
|
|
img.setAttribute("draggable", true);
|
|
img.ondragstart = e => {
|
|
this.currentPos = { x: e.clientX, y: e.clientY };
|
|
return true
|
|
};
|
|
img.ondrag = e => {
|
|
e.preventDefault();
|
|
|
|
let target = this.element.querySelector("iframe") || this.element;
|
|
let delta = {
|
|
x: e.clientX - this.currentPos.x,
|
|
y: e.clientY - this.currentPos.y
|
|
};
|
|
|
|
this.currentPos = { x: e.clientX, y: e.clientY };
|
|
if (delta.x == 0 && delta.y == 0)
|
|
return
|
|
|
|
let rect = target.getBoundingClientRect();
|
|
let width = rect.width + delta.x;
|
|
let height = rect.height + delta.y;
|
|
target.style.width = width + "px";
|
|
target.style.height = height + "px";
|
|
|
|
switch (this.notchPosition) {
|
|
case "bottomLeft":
|
|
case "bottomCenter":
|
|
let bottom = parseFloat(this.element.style.bottom);
|
|
this.element.style.bottom = bottom - delta.y + "px";
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
//console.log("onResize", this.onResize)
|
|
if (this.onResize) {
|
|
this.onResize({ target, delta, width, height });
|
|
}
|
|
};
|
|
img.ondragend = e => { };
|
|
this.element.appendChild(img);
|
|
}
|
|
|
|
|
|
for (let key in content) {
|
|
switch (key) {
|
|
case "selector":
|
|
break
|
|
case "text":
|
|
let text = document.createElement("span");
|
|
this.element.appendChild(text);
|
|
text.innerHTML = content[key];
|
|
Elements$1.setStyle(text, { color: this.normalColor });
|
|
Elements$1.addClass(text, "unselectable");
|
|
Elements$1.addClass(text, "PopupContent");
|
|
this.insertedNode = text;
|
|
this.loaded = true;
|
|
break
|
|
case "img":
|
|
alert("img to be implemented");
|
|
break
|
|
case "iframe":
|
|
let iframe = document.createElement("iframe");
|
|
iframe.setAttribute("frameBorder", 0);
|
|
iframe.src = content[key];
|
|
iframe.onload = e => {
|
|
let body = iframe.contentWindow.document.body;
|
|
let observer = new MutationObserver(() => {
|
|
this.iframeChanged(iframe);
|
|
});
|
|
observer.observe(iframe.contentWindow.document, {
|
|
attributes: true,
|
|
subtree: true,
|
|
childList: true,
|
|
characterData: true
|
|
});
|
|
let w = Math.max(body.scrollWidth, body.offsetWidth);
|
|
let h = Math.max(body.scrollHeight, body.offsetHeight);
|
|
iframe.style.width = w + "px";
|
|
iframe.style.height = h + "px";
|
|
this.layoutAfterInsert();
|
|
if (this.onload != null) {
|
|
this.onload();
|
|
}
|
|
this.loaded = true;
|
|
};
|
|
this.element.appendChild(iframe);
|
|
Elements$1.addClass(iframe, "PopupContent");
|
|
this.insertIntoDOM();
|
|
return
|
|
case "html":
|
|
this.loaded = false;
|
|
let div = document.createElement("div");
|
|
Elements$1.addClass(div, "PopupContent");
|
|
this.element.appendChild(div);
|
|
div.innerHTML = content.html;
|
|
//console.log("insert", content)
|
|
let selector = content.selector;
|
|
if (selector) {
|
|
this.insertedNode = div.querySelector(selector);
|
|
if (this.insertedNode == null) {
|
|
div.innerHTML = `<p style="color:red;">Popup content not found. Missing ${selector}</p>`;
|
|
this.insertedNode = div.firstElementChild;
|
|
}
|
|
}
|
|
else {
|
|
this.insertedNode = div.firstElementChild || div;
|
|
}
|
|
this.setAlpha(this.insertedNode, 0);
|
|
let images = this.element.querySelectorAll('img');
|
|
let total = 0;
|
|
if (images.length > 0) {
|
|
let count = 0;
|
|
for (let image of images) {
|
|
if (!image.complete && !image.src.startsWith('data:')) {
|
|
total += 1;
|
|
console.log("image not complete", image.src);
|
|
image.onload = e => {
|
|
count += 1;
|
|
if (count == total) {
|
|
this.loaded = true;
|
|
if (this.onload != null) {
|
|
this.onload();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
if (total == 0) {
|
|
this.loaded = true;
|
|
}
|
|
break
|
|
case "node":
|
|
this.loaded = true;
|
|
Elements$1.addClass(content.node, "PopupContent");
|
|
this.element.appendChild(content.node);
|
|
this.insertedNode = content.node;
|
|
this.setAlpha(this.insertedNode, 0);
|
|
break
|
|
default:
|
|
alert("Unexpected content type: " + key);
|
|
break
|
|
}
|
|
}
|
|
this.insertIntoDOM();
|
|
this.layoutAfterInsert();
|
|
this.setupEventHandler();
|
|
return this
|
|
}
|
|
|
|
handleClose(e) {
|
|
let closing = this.closingEvent(e);
|
|
if (closing) {
|
|
this.close();
|
|
}
|
|
else {
|
|
this.setupCloseHandler();
|
|
}
|
|
}
|
|
|
|
setupCloseHandler() {
|
|
let close = this.handleClose;
|
|
if (this.hideOnUp) {
|
|
if (window.PointerEvent)
|
|
this.parent.addEventListener("pointerup", close.bind(this), { capture: true, once: true });
|
|
else if (window.TouchEvent)
|
|
this.parent.addEventListener("touchend", close.bind(this), { capture: true, once: true });
|
|
else
|
|
this.parent.addEventListener("mouseup", close.bind(this), { capture: true, once: true });
|
|
} else {
|
|
if (window.PointerEvent)
|
|
this.parent.addEventListener("pointerdown", close.bind(this), { capture: true, once: true });
|
|
else if (window.TouchEvent)
|
|
this.parent.addEventListener("touchstart", close.bind(this), { capture: true, once: true });
|
|
else
|
|
this.parent.addEventListener("mousedown", close.bind(this), { capture: true, once: true });
|
|
}
|
|
}
|
|
|
|
setupEventHandler() {
|
|
if (this.autoClose) {
|
|
this.setupCloseHandler();
|
|
}
|
|
}
|
|
|
|
closingEvent(e) {
|
|
if (this.interactive) {
|
|
let node = e.target.closest(".PopupContent");
|
|
return node == null
|
|
}
|
|
return true
|
|
}
|
|
|
|
iframeChanged(iframe) {
|
|
let body = iframe.contentWindow.document.body;
|
|
let w = Math.max(body.scrollWidth, body.offsetWidth);
|
|
let h = Math.max(body.scrollHeight, body.offsetHeight);
|
|
iframe.style.width = w + "px";
|
|
iframe.style.height = h + "px";
|
|
}
|
|
|
|
setupDraggable() {
|
|
if (this.draggable) {
|
|
let target = this.element;
|
|
target.setAttribute("draggable", true);
|
|
target.ondragstart = e => {
|
|
this.currentPos = { x: e.clientX, y: e.clientY };
|
|
var img = document.createElement('img');
|
|
img.src = 'data:image/gifbase64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
e.dataTransfer.setDragImage(img, 0, 0);
|
|
};
|
|
target.ondrag = e => {
|
|
e.preventDefault();
|
|
let delta = {
|
|
x: e.clientX - this.currentPos.x,
|
|
y: e.clientY - this.currentPos.y
|
|
};
|
|
this.currentPos = { x: e.clientX, y: e.clientY };
|
|
let left = parseFloat(target.style.left);
|
|
let top = parseFloat(target.style.top);
|
|
|
|
target.style.left = left + delta.x + 'px';
|
|
target.style.top = top + delta.y + 'px';
|
|
|
|
//console.log("Popup.ondrag", target, event.target)
|
|
if (this.onMove) {
|
|
this.onMove({ target, delta });
|
|
}
|
|
|
|
this.lastDrag = { left, top };
|
|
};
|
|
target.ondragend = e => {
|
|
target.style.left = this.lastDrag.left + 'px';
|
|
target.style.top = this.lastDrag.top + 'px';
|
|
this.currentPos = null;
|
|
};
|
|
}
|
|
}
|
|
|
|
moveDragged(target) {
|
|
|
|
}
|
|
|
|
insertIntoDOM(layout = true) {
|
|
this.setAlpha(this.insertedNode, 0);
|
|
this.element.appendChild(this.notch);
|
|
this.parent.appendChild(this.element);
|
|
}
|
|
|
|
layoutAfterInsert() {
|
|
Elements$1.setStyle(this.element, this.defaultStyle());
|
|
this.layout();
|
|
//this.element.style.opacity = 1
|
|
}
|
|
|
|
/** Layout the menu items. Needed only in the subclass.
|
|
*/
|
|
layout() { }
|
|
|
|
|
|
remove() {
|
|
if (this.parent.contains(this.element))
|
|
this.parent.removeChild(this.element);
|
|
this.unregister(this.context);
|
|
}
|
|
|
|
/** Close and remove the Popup from the DOM tree.
|
|
*/
|
|
close() {
|
|
//console.log("Popup.close", this.closeCommand)
|
|
this.unregister(this.context);
|
|
if (this.closeCommand) {
|
|
this.closeCommand(this, () => this.remove());
|
|
}
|
|
else {
|
|
this.remove();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the alpha value to show or hide the popup. Uses CSS transitions.
|
|
* (A former dependency on TweenLite has beeen removed.)
|
|
*
|
|
* @param {*} targets
|
|
* @param {*} value
|
|
* @memberof Popup
|
|
*/
|
|
setAlpha(targets, value) {
|
|
let objs = (targets instanceof Array) ? targets : [targets];
|
|
for (let obj of objs) {
|
|
if (value) {
|
|
obj.style.transition = "opacity 0.2s ease-in";
|
|
}
|
|
obj.style.opacity = value;
|
|
}
|
|
// if (value) {
|
|
// TweenLite.to(targets, 0.2, { autoAlpha: value })
|
|
// }
|
|
// else {
|
|
// TweenLite.set(targets, { autoAlpha: 0 })
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* Starts a fade in animation.
|
|
*
|
|
* @memberof Popup
|
|
*/
|
|
fadeIn() {
|
|
this.setAlpha([this.element, this.insertedNode], 1);
|
|
}
|
|
|
|
/** Shows the Popup with the given commands at the specified point.
|
|
* @param {Object} content - A dict object with type strings (text, img, html) as keys
|
|
* and corresponding values.
|
|
* @param {Point} point - The position as x, y coordinates {px}.
|
|
* @return {Popup} this
|
|
*/
|
|
showAt(content, point) {
|
|
this.setup(content);
|
|
console.log("showAt", this.loaded);
|
|
if (this.loaded) {
|
|
this.placeAt(point);
|
|
this.fadeIn();
|
|
}
|
|
else {
|
|
this.setAlpha([this.element, this.insertedNode], 0);
|
|
this.onload = () => {
|
|
this.layoutAfterInsert();
|
|
this.placeAt(point);
|
|
this.fadeIn();
|
|
};
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Place the origin, i.e. the upper left corner at the given position using CSS styles.
|
|
*
|
|
* @param {any} x
|
|
* @param {any} y
|
|
* @memberof Popup
|
|
*/
|
|
placeOrigin(x, y) {
|
|
Elements$1.setStyle(this.element, { left: x + "px", top: y + "px" });
|
|
}
|
|
|
|
/**
|
|
* Calculate the local coordinates within the keepWithin container.
|
|
*
|
|
* @param {any} x
|
|
* @param {any} y
|
|
* @returns
|
|
* @memberof Popup
|
|
*/
|
|
localPointWithin(x, y, width, height) {
|
|
let pt = { x, y };
|
|
return pt
|
|
}
|
|
|
|
withinDimensions() {
|
|
return {
|
|
width: this.keepWithin.offsetWidth,
|
|
height: this.keepWithin.offsetHeight
|
|
}
|
|
}
|
|
|
|
localDimensions() {
|
|
return {
|
|
width: this.element.offsetWidth,
|
|
height: this.element.offsetHeight
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the notch position depending on the local coordinates within the keepWithin container
|
|
* Divides the space vertically into top, center, bottom and horizontally into left, center, right
|
|
*
|
|
* @param {any} x
|
|
* @param {any} y
|
|
* @returns
|
|
* @memberof Popup
|
|
*/
|
|
notchPositionWithin(x, y) {
|
|
let horizontal = "Center";
|
|
let vertical = "center";
|
|
let { width, height } = this.withinDimensions();
|
|
let local = this.localPointWithin(x, y, width, height);
|
|
if (local.y < height * 0.33) {
|
|
vertical = "top";
|
|
}
|
|
if (local.y > height * 0.66) {
|
|
vertical = "bottom";
|
|
}
|
|
if (local.x < width * 0.33) {
|
|
horizontal = "Left";
|
|
}
|
|
if (local.x > width * 0.66) {
|
|
horizontal = "Right";
|
|
}
|
|
let result = vertical + horizontal;
|
|
if (result == "centerCenter")
|
|
return this.notchPosition
|
|
return result
|
|
}
|
|
|
|
placeAt(point) {
|
|
let x = point.x;
|
|
let y = point.y;
|
|
let notchPosition = this.notchPosition;
|
|
if (this.keepWithin != null) {
|
|
notchPosition = this.notchPositionWithin(x, y);
|
|
}
|
|
Elements$1.setStyle(this.notch, this.notchStyle(notchPosition));
|
|
this.notch.className = "notch " + notchPosition;
|
|
let { width, height } = this.localDimensions();
|
|
|
|
//if targetBoundingBox is set, popup is placed next to the rectangle
|
|
if (this.targetBoundingBox) {
|
|
let bbTop = this.targetBoundingBox.y;
|
|
let bbBottom = this.targetBoundingBox.y + this.targetBoundingBox.height;
|
|
let bbLeft = this.targetBoundingBox.x;
|
|
let bbRight = this.targetBoundingBox.x + this.targetBoundingBox.width;
|
|
//console.log("place popup with bb set:", x, y, bbTop, bbBottom, bbLeft, bbRight)
|
|
switch (notchPosition) {
|
|
case "bottomLeft":
|
|
case "bottomRight":
|
|
case "bottomCenter":
|
|
y = bbTop;
|
|
if (!this.useEventPosWithBoundingBox)
|
|
x = (bbLeft + bbRight) / 2;
|
|
break
|
|
case "topLeft":
|
|
case "topRight":
|
|
case "topCenter":
|
|
y = bbBottom;
|
|
if (!this.useEventPosWithBoundingBox)
|
|
x = (bbLeft + bbRight) / 2;
|
|
break
|
|
case "centerRight":
|
|
x = bbLeft;
|
|
if (!this.useEventPosWithBoundingBox)
|
|
y = (bbTop + bbBottom) / 2;
|
|
break
|
|
case "centerLeft":
|
|
x = bbRight;
|
|
if (!this.useEventPosWithBoundingBox)
|
|
y = (bbTop + bbBottom) / 2;
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
//calculate position depending on several (optional) parameters
|
|
switch (notchPosition) {
|
|
case "bottomLeft":
|
|
x -= this.padding;
|
|
x -= this.notchSize;
|
|
y -= height;
|
|
y -= this.notchSize * 2;
|
|
y -= this.posOffset;
|
|
break
|
|
case "bottomRight":
|
|
x -= width;
|
|
x += this.padding;
|
|
x += this.notchSize;
|
|
y -= height;
|
|
y -= this.notchSize * 2;
|
|
y -= this.posOffset;
|
|
break
|
|
case "bottomCenter":
|
|
x -= width / 2;
|
|
y -= height;
|
|
y -= this.notchSize * 2;
|
|
y -= this.posOffset;
|
|
break
|
|
case "topLeft":
|
|
x -= this.padding;
|
|
x -= this.notchSize;
|
|
y += this.notchSize * 2;
|
|
y += this.posOffset;
|
|
break
|
|
case "topRight":
|
|
x -= width;
|
|
x += this.padding;
|
|
x += this.notchSize;
|
|
y += this.notchSize * 2;
|
|
y += this.posOffset;
|
|
break
|
|
case "topCenter":
|
|
x -= width / 2;
|
|
y += this.notchSize * 2;
|
|
y += this.posOffset;
|
|
break
|
|
case "centerRight":
|
|
x -= width + this.notchSize * 2;
|
|
x -= this.posOffset;
|
|
y -= height / 2;
|
|
break
|
|
case "centerLeft":
|
|
//console.log("height", height)
|
|
y -= height / 2;
|
|
x += this.notchSize * 2;
|
|
x += this.posOffset;
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
this.placeOrigin(x, y);
|
|
}
|
|
|
|
/** Shows the Popup with the given commands at the current position.
|
|
* @param {Object} content - A dict object with type strings (text, img, html) as keys
|
|
* and corresponding values.
|
|
* @return {Popup} this
|
|
*/
|
|
show(content) {
|
|
this.setup(content);
|
|
this.fadeIn();
|
|
return this
|
|
}
|
|
|
|
/** Configuration object. Return default styles as CSS values.
|
|
*/
|
|
defaultStyle() {
|
|
let padding = this.padding;
|
|
let style = {
|
|
maxWidth: this.maxWidth + "px",
|
|
zIndex: this.zIndex,
|
|
position: "absolute",
|
|
};
|
|
if (this.minWidth) {
|
|
style.minWidth = this.minWidth + "px";
|
|
}
|
|
if (!this.noStyle) {
|
|
Object.assign(style, {
|
|
borderRadius: Math.round(this.padding / 2) + "px",
|
|
backgroundColor: this.backgroundColor,
|
|
padding: this.padding + "px",
|
|
boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)",
|
|
fontFamily: this.fontFamily,
|
|
fontSize: this.fontSize,
|
|
stroke: "black",
|
|
fill: "white"
|
|
});
|
|
}
|
|
|
|
return style
|
|
}
|
|
|
|
/** Configuration object. Return notch styles as CSS values.
|
|
*/
|
|
notchStyle(notchPosition = null) {
|
|
if (notchPosition == null) {
|
|
notchPosition = this.notchPosition;
|
|
}
|
|
let width = 0;
|
|
let height = 0;
|
|
let left = this.padding;
|
|
let size = this.localDimensions();
|
|
if (notchPosition.endsWith("Right")) {
|
|
left = size.width - this.padding - this.notchSize * 2;
|
|
}
|
|
if (notchPosition.endsWith("Center")) {
|
|
left = size.width / 2 - this.notchSize;
|
|
}
|
|
left = Math.round(left) + 'px';
|
|
|
|
if (notchPosition.startsWith("bottom")) {
|
|
if (this.noStyle) {
|
|
return {
|
|
width,
|
|
height,
|
|
left,
|
|
bottom: -this.notchSize + "px",
|
|
position: "absolute",
|
|
borderStyle: "solid",
|
|
borderTopWidth: this.notchSize + "px",
|
|
borderRight: this.notchSize + "px solid transparent",
|
|
borderLeft: this.notchSize + "px solid transparent",
|
|
borderBottom: 0
|
|
}
|
|
|
|
} else {
|
|
return {
|
|
width,
|
|
height,
|
|
left,
|
|
boxShadow: "0 12px 15px rgba(0, 0, 0, 0.1)",
|
|
bottom: -this.notchSize + "px",
|
|
position: "absolute",
|
|
borderTop: this.notchSize + "px solid " + this.backgroundColor,
|
|
borderRight: this.notchSize + "px solid transparent",
|
|
borderLeft: this.notchSize + "px solid transparent",
|
|
borderBottom: 0
|
|
}
|
|
}
|
|
}
|
|
if (notchPosition.startsWith("top")) {
|
|
if (this.noStyle) {
|
|
return {
|
|
width,
|
|
height,
|
|
left,
|
|
top: -this.notchSize + "px",
|
|
position: "absolute",
|
|
borderStyle: "solid",
|
|
borderBottomWidth: this.notchSize + "px",
|
|
borderRight: this.notchSize + "px solid transparent",
|
|
borderLeft: this.notchSize + "px solid transparent",
|
|
borderTop: 0
|
|
}
|
|
} else {
|
|
return {
|
|
width,
|
|
height,
|
|
left,
|
|
top: -this.notchSize + "px",
|
|
position: "absolute",
|
|
borderBottom: this.notchSize + "px solid " + this.backgroundColor,
|
|
borderRight: this.notchSize + "px solid transparent",
|
|
borderLeft: this.notchSize + "px solid transparent",
|
|
borderTop: 0
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.noStyle) {
|
|
|
|
if (notchPosition.endsWith("Left")) {
|
|
left = -this.notchSize * 2 + "px";
|
|
}
|
|
|
|
if (notchPosition.endsWith("Right")) {
|
|
left = size.width + "px";
|
|
}
|
|
|
|
|
|
let top = size.height / 2 - this.notchSize;
|
|
top = Math.round(top) + 'px';
|
|
|
|
|
|
return {
|
|
width,
|
|
height,
|
|
left,
|
|
top,
|
|
borderRightWidth: this.notchSize,
|
|
borderLeftWidth: this.notchSize,
|
|
position: "absolute",
|
|
borderTop: this.notchSize + "px solid transparent",
|
|
borderBottom: this.notchSize + "px solid transparent"
|
|
}
|
|
|
|
} else {
|
|
let borderRight = this.notchSize + "px solid transparent";
|
|
let borderLeft = this.notchSize + "px solid transparent";
|
|
let top = size.height / 2 - this.notchSize;
|
|
if (notchPosition.endsWith("Left")) {
|
|
left = -this.notchSize * 2 + "px";
|
|
borderRight = this.notchSize + "px solid " + this.backgroundColor;
|
|
this.element.style.boxShadow = "15px 10px 15px rgba(0, 0, 0, 0.3)";
|
|
}
|
|
if (notchPosition.endsWith("Right")) {
|
|
left = size.width + "px";
|
|
borderLeft = this.notchSize + "px solid " + this.backgroundColor;
|
|
this.element.style.boxShadow = "15px 5px 15px rgba(0, 0, 0, 0.3)";
|
|
}
|
|
|
|
top = Math.round(top) + 'px';
|
|
|
|
|
|
return {
|
|
width,
|
|
height,
|
|
left,
|
|
top,
|
|
borderRight,
|
|
borderLeft,
|
|
// boxShadow,
|
|
position: "absolute",
|
|
borderTop: this.notchSize + "px solid transparent",
|
|
borderBottom: this.notchSize + "px solid transparent"
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Convenient static methods to show and reuse a Popup implemented
|
|
* as a class variable.
|
|
* @param {Object} content - A dict object with type strings (text, img, html) as keys
|
|
* and corresponding values.
|
|
* @param {Point} point - The position as x, y coordinates {px}.
|
|
* @param {boolean} autoClose - Autoclose the menu after selecting an item.
|
|
*/
|
|
static open(
|
|
content,
|
|
point,
|
|
{
|
|
parent = null,
|
|
context = window,
|
|
fontSize = "1em",
|
|
fontFamily = "Arial",
|
|
padding = 16,
|
|
notchSize = 10,
|
|
switchPos = false,
|
|
minWidth = null,
|
|
maxWidth = 800,
|
|
backgroundColor = "#EEE",
|
|
zIndex = 0,
|
|
normalColor = "#444",
|
|
closeIcon = null,
|
|
resizeIcon = null,
|
|
closeCommand = null,
|
|
autoClose = true,
|
|
keepWithin = null,
|
|
draggable = false,
|
|
posOffset = 0,
|
|
targetBoundingBox = null,
|
|
useEventPosWithBoundingBox = false,
|
|
interactive = false,
|
|
onResize = null,
|
|
onMove = null
|
|
} = {}
|
|
) {
|
|
|
|
|
|
let notchPosition = (switchPos && point.y < 50) ? "topCenter" : "bottomCenter";
|
|
let popup = new Popup({
|
|
parent,
|
|
context,
|
|
fontFamily,
|
|
fontSize,
|
|
padding,
|
|
notchSize,
|
|
switchPos,
|
|
minWidth,
|
|
maxWidth,
|
|
backgroundColor,
|
|
normalColor,
|
|
notchPosition,
|
|
zIndex,
|
|
autoClose,
|
|
keepWithin,
|
|
closeCommand,
|
|
closeIcon,
|
|
resizeIcon,
|
|
draggable,
|
|
posOffset,
|
|
targetBoundingBox,
|
|
useEventPosWithBoundingBox,
|
|
interactive,
|
|
onResize,
|
|
onMove
|
|
});
|
|
popup.register(context);
|
|
popup.showAt(content, point);
|
|
return popup
|
|
}
|
|
|
|
/** Convenient static method to close the Popup implemented
|
|
* as a class variable. Calls the close command.
|
|
*/
|
|
static closePopup(context = window) {
|
|
let popup = Poppable.registrations.get(context);
|
|
if (popup != null) {
|
|
popup.close();
|
|
}
|
|
}
|
|
|
|
/** Convenient static methods to remove the Popup implemented
|
|
* as a class variable. Removes the popup without performing the close command.
|
|
*/
|
|
static remove(context = window) {
|
|
let popup = Poppable.registrations.get(context);
|
|
if (popup != null) {
|
|
popup.remove();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convenient static method to compute the clicked rect of objects that have multiple clients rects.
|
|
* Needed to position popups correctly above objects with line breaks, e.g. spans
|
|
*
|
|
* @static
|
|
* @param {*} event
|
|
* @returns {*} DOMRect
|
|
* @memberof Popup
|
|
*/
|
|
static targetRect(event) {
|
|
let target = event.target;
|
|
let x = event.pageX;
|
|
let y = event.pageY;
|
|
for (let rect of target.getClientRects()) {
|
|
let withinX = x >= rect.left && x <= rect.left + rect.width;
|
|
let withinY = y >= rect.top && y <= rect.top + rect.height;
|
|
if (withinX && withinY) {
|
|
return rect
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Convenient static method to compute the center of objects that have multiple clients rects.
|
|
* Needed to position popups correctly above objects with line breaks, e.g. spans
|
|
*
|
|
* @static
|
|
* @param {*} event
|
|
* @returns {*} Point
|
|
* @memberof Popup
|
|
*/
|
|
static targetCenter(event) {
|
|
let target = event.target;
|
|
let x = event.pageX;
|
|
let y = event.pageY;
|
|
let rect = Popup.targetRect(event);
|
|
if (rect != null) {
|
|
x = rect.left + rect.width / 2;
|
|
y = rect.top + rect.height / 2;
|
|
}
|
|
return { x, y }
|
|
}
|
|
}
|
|
|
|
/** A Popup Menu that shows text labels in a vertical row.
|
|
*/
|
|
class PopupMenu$1 extends Popup {
|
|
/**
|
|
* The constructor.
|
|
* @constructor
|
|
* @param {DOM Element} parent - The DOM parent element.
|
|
* @param {Object} commands - A dict object with command label strings as keys
|
|
* and command functions as values.
|
|
* @param {string} fontSize - Describes the font size as CSS value
|
|
* @param {number || string} padding - Describes the padding as CSS value
|
|
* @param {number || string} notchSize - Describes the size of the notch (callout) as CSS value
|
|
* @param {string} highlightColor - The color of highlighted menu items as CSS value
|
|
* @param {string} backgroundColor - The color of the background as CSS value
|
|
* @param {string} normalColor - The color of normal menu items as CSS value
|
|
* @param {DOM Element} keepWithin - The container to stay within
|
|
* @param {boolean} autoClose - Autoclose the menu after selecting an item
|
|
*/
|
|
constructor({ parent = null,
|
|
commands = null,
|
|
fontSize = '1em',
|
|
fontFamily = 'Arial',
|
|
padding = 16,
|
|
zIndex = 1,
|
|
spacing = '0px',
|
|
switchPos = false,
|
|
notchSize = 10,
|
|
maxWidth = 800,
|
|
backgroundColor = '#EEE',
|
|
normalColor = '#444',
|
|
highlightColor = 'black',
|
|
notchPosition = 'bottomLeft',
|
|
keepWithin = null,
|
|
autoClose = true } = {}) {
|
|
super({ parent, fontSize, fontFamily, padding, notchSize, notchPosition, backgroundColor, keepWithin, normalColor, autoClose });
|
|
this.commands = commands;
|
|
this.zIndex = zIndex;
|
|
this.switchPos = switchPos;
|
|
this.spacing = spacing;
|
|
this.highlightColor = highlightColor;
|
|
}
|
|
|
|
/** Setup menu with a dictionary of command labels and command functions.
|
|
* @param {Object} commands - A dict object with command label strings as keys
|
|
* and command functions as values.
|
|
* @return {PopupMenu} this
|
|
*/
|
|
setup(commands) {
|
|
|
|
this.commands = commands;
|
|
this.items = {};
|
|
this.element = document.createElement('div');
|
|
this.element.style.zIndex = this.zIndex;
|
|
Elements$1.addClass(this.element, 'unselectable');
|
|
this.notch = document.createElement('div');
|
|
Elements$1.setStyle(this.notch, this.notchStyle());
|
|
for (let key in commands) {
|
|
let item = document.createElement('div');
|
|
this.element.appendChild(item);
|
|
item.innerHTML = key;
|
|
item.style.paddingBottom = item.style.paddingTop = this.spacing;
|
|
Elements$1.setStyle(item, { color: this.normalColor, cursor: 'default' });
|
|
Elements$1.addClass(item, 'unselectable');
|
|
Elements$1.addClass(item, 'popupMenuItem');
|
|
this.items[key] = item;
|
|
item.onclick = (event) => { this.perform(key); };
|
|
item.ontap = (event) => { this.perform(key); };
|
|
item.onmouseover = (event) => { this.over(event, key); };
|
|
item.onmouseout = (event) => { this.out(event, key); };
|
|
}
|
|
|
|
this.element.appendChild(this.notch);
|
|
this.parent.appendChild(this.element);
|
|
this.insertedNode = this.element;
|
|
Elements$1.setStyle(this.element, this.defaultStyle());
|
|
this.layout();
|
|
return this
|
|
}
|
|
|
|
/** Execute a menu command.
|
|
* @param {string} key - The selected key.
|
|
*/
|
|
perform(key) {
|
|
let func = this.commands[key];
|
|
if (this.autoClose) {
|
|
this.close();
|
|
}
|
|
setTimeout(() => {
|
|
func.call();
|
|
}, 20);
|
|
}
|
|
|
|
/** Update the menu item denoted by key.
|
|
* @param {string} key - The selected key.
|
|
* @param {boolean} highlight - Show the item highlighted.
|
|
*/
|
|
update(key, highlight = false) {
|
|
let text = this.items[key];
|
|
text.style.color = (highlight) ? this.highlightColor : this.normalColor;
|
|
}
|
|
|
|
/** Mouse over handöer.
|
|
* @param {Event} event - The mouse event.
|
|
* @param {boolean} key - The selected key.
|
|
*/
|
|
over(event, key) {
|
|
for (let k in this.items) {
|
|
this.update(k, k == key);
|
|
}
|
|
}
|
|
|
|
/** Mouse out handöer.
|
|
* @param {Event} event - The mouse event.
|
|
* @param {boolean} key - The selected key.
|
|
*/
|
|
out(event, key) {
|
|
this.update(key);
|
|
}
|
|
|
|
/** Shows the PopupMenu with the given commands at the specified point.
|
|
* @param {Object} commands - A dict object with command label strings as keys
|
|
* and command functions as values.
|
|
* @param {Point} point - The position as x, y coordinates {px}.
|
|
* @return {PopupMenu} this
|
|
*/
|
|
showAt(commands, point) {
|
|
this.show(commands);
|
|
this.placeAt(point);
|
|
return this
|
|
}
|
|
|
|
/** Convenient static methods to show and reuse a PopupMenu implemented
|
|
* as a class variable.
|
|
* @param {Object} commands - A dict object with command label strings as keys
|
|
* and command functions as values.
|
|
* @param {Point} point - The position as x, y coordinates {px}.
|
|
* @param {string} fontSize - Describes the font size as CSS value
|
|
* @param {number || string} padding - Describes the padding as CSS value
|
|
* @param {number || string} notchSize - Describes the size of the notch (callout) as CSS value
|
|
* @param {string} highlightColor - The color of highlighted menu items as CSS value
|
|
* @param {string} backgroundColor - The color of the background as CSS value
|
|
* @param {string} normalColor - The color of normal menu items as CSS value
|
|
* @param {boolean} autoClose - Autoclose the menu after selecting an item
|
|
*/
|
|
static open(commands, point, { parent = null,
|
|
context = window,
|
|
fontSize = '1em',
|
|
fontFamily = 'Arial',
|
|
padding = 16,
|
|
zIndex = 1,
|
|
spacing = '0px',
|
|
switchPos = false,
|
|
notchSize = 10,
|
|
maxWidth = 800,
|
|
keepWithin = null,
|
|
backgroundColor = '#EEE',
|
|
normalColor = '#444',
|
|
autoClose = true } = {}) {
|
|
|
|
let registered = Poppable.get(context);
|
|
if (registered) {
|
|
this.closePopup();
|
|
return
|
|
}
|
|
console.log("open", point);
|
|
let notchPosition = (point.y < 50 && switchPos) ? 'topCenter' : 'bottomCenter';
|
|
let popup = new PopupMenu$1({
|
|
parent, fontSize, padding, zIndex, spacing, switchPos, notchSize,
|
|
notchPosition,
|
|
maxWidth, backgroundColor, normalColor,
|
|
notchPosition, keepWithin, autoClose
|
|
});
|
|
popup.showAt(commands, point);
|
|
popup.register(context);
|
|
popup.closeEventListener = (e) => {
|
|
if (this.eventOutside(e))
|
|
this.closePopup(context);
|
|
};
|
|
if (autoClose) {
|
|
context.addEventListener('mousedown', popup.closeEventListener, true);
|
|
context.addEventListener('touchstart', popup.closeEventListener, true);
|
|
context.addEventListener('pointerdown', popup.closeEventListener, true);
|
|
}
|
|
}
|
|
|
|
static eventOutside(e) {
|
|
return !Elements$1.hasClass(e.target, 'popupMenuItem')
|
|
}
|
|
|
|
/** Convenient static methods to close the PopupMenu implemented
|
|
* as a class variable.
|
|
*/
|
|
static closePopup(context=window) {
|
|
let registered = Poppable.get(context);
|
|
if (registered) {
|
|
registered.close();
|
|
context.removeEventListener('mousedown', registered.closeEventListener);
|
|
context.removeEventListener('touchstart', registered.closeEventListener);
|
|
context.removeEventListener('pointerdown', registered.closeEventListener);
|
|
}
|
|
}
|
|
}
|
|
|
|
class FrameContainer {
|
|
|
|
constructor(element) {
|
|
this.element = element;
|
|
this.delegate = new InteractionMapper(element, this,
|
|
{ mouseWheelElement: window});
|
|
}
|
|
|
|
capture(event) {
|
|
return true
|
|
}
|
|
|
|
findTarget(event, local, global) {
|
|
let found = document.elementFromPoint(global.x, global.y);
|
|
let iframe = found.querySelector('iframe');
|
|
if (iframe) {
|
|
let p = Points.fromPageToNode(found, global);
|
|
let doc = iframe.contentWindow.document;
|
|
let target = doc.elementFromPoint(p.x, p.y);
|
|
if (target != null) {
|
|
console.log('iframe element', target);
|
|
return new FrameTarget(iframe, target)
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
}
|
|
|
|
class FrameTarget {
|
|
|
|
constructor(frame, target, debug=false) {
|
|
this.frame = frame;
|
|
this.target = target;
|
|
this.debug = debug;
|
|
}
|
|
|
|
capture(event) {
|
|
return true
|
|
}
|
|
|
|
simulateMouseEvent(type, point) {
|
|
let p = Points.fromPageToNode(this.frame, point);
|
|
let event = new MouseEvent(type, {
|
|
view: this.frame.contentWindow,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
clientX: p.x,
|
|
clientY: p.y});
|
|
this.target.dispatchEvent(event);
|
|
}
|
|
|
|
createTouchList(pointMap) {
|
|
let touches = [];
|
|
let doc = this.frame.contentWindow.document;
|
|
for(let key of pointMap.keys()) {
|
|
let point = pointMap.get(key);
|
|
let p = Points.fromPageToNode(this.frame, point);
|
|
let touchTarget = doc.elementFromPoint(p.x, p.y);
|
|
let touch = new Touch(undefined, touchTarget, key,
|
|
p.x, p.y, p.x, p.y);
|
|
touches.push(touch);
|
|
}
|
|
return new TouchList(...touches)
|
|
}
|
|
|
|
simulateTouchEventChrome(type, point, pointMap) {
|
|
let doc = this.frame.contentWindow.document;
|
|
let p = Points.fromPageToNode(this.frame, point);
|
|
let touchTarget = doc.elementFromPoint(p.x, p.y);
|
|
const touchObj = new Touch({
|
|
identifier: Date.now(),
|
|
target: touchTarget,
|
|
clientX: p.x,
|
|
clientY: p.y,
|
|
pageX: p.x,
|
|
pageY: p.y,
|
|
radiusX: 2.5,
|
|
radiusY: 2.5,
|
|
rotationAngle: 10,
|
|
force: 0.5,
|
|
});
|
|
|
|
const touchEvent = new TouchEvent(type, {
|
|
cancelable: true,
|
|
bubbles: true,
|
|
touches: [touchObj],
|
|
targetTouches: [touchObj],
|
|
changedTouches: [touchObj],
|
|
shiftKey: false,
|
|
});
|
|
if (this.debug) console.log("simulateTouchEventChrome", touchEvent);
|
|
this.target.dispatchEvent(touchEvent);
|
|
}
|
|
|
|
simulateTouchEventSafari(type, point, pointMap, touchEventKey='targetTouches') {
|
|
let p = Points.fromPageToNode(this.frame, point);
|
|
let data = { view: this.frame.contentWindow,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
clientX: p.x,
|
|
clientY: p.y};
|
|
data[touchEventKey] = this.createTouchList(pointMap);
|
|
let event = new TouchEvent(type, data);
|
|
if (this.debug) console.log("simulateTouchEventChrome", touchEvent);
|
|
this.target.dispatchEvent(event);
|
|
}
|
|
|
|
simulateTouchEvent(type, point, pointMap, touchEventKey='targetTouches') {
|
|
if (Capabilities.isSafari) {
|
|
this.simulateTouchEventSafari(type, point, pointMap, touchEventKey);
|
|
}
|
|
else {
|
|
this.simulateTouchEventChrome(type, point, pointMap);
|
|
}
|
|
}
|
|
|
|
isMouseLikeEvent(event) {
|
|
return event.type.startsWith('mouse') || event.type.startsWith('pointer')
|
|
}
|
|
|
|
onStart(event, interaction) {
|
|
if (this.debug) console.log('onStart', this.frame.parentNode);
|
|
for(let [key, point] of interaction.current.entries()) {
|
|
if (this.isMouseLikeEvent(event)) {
|
|
this.simulateMouseEvent('mousedown', point);
|
|
}
|
|
else {
|
|
this.simulateTouchEvent('touchstart', point,
|
|
interaction.current);
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
onMove(event, interaction) {
|
|
if (this.debug) console.log('onMove');
|
|
for(let [key, point] of interaction.current.entries()) {
|
|
if (this.isMouseLikeEvent(event)) {
|
|
this.simulateMouseEvent('mousemove', point);
|
|
}
|
|
else {
|
|
this.simulateTouchEvent('touchmove', point,
|
|
interaction.current);
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
onEnd(event, interaction) {
|
|
if (this.debug) console.log('onEnd');
|
|
for(let [key, point] of interaction.current.entries()) {
|
|
if (this.isMouseLikeEvent(event)) {
|
|
this.simulateMouseEvent('mouseend', point);
|
|
}
|
|
else {
|
|
this.simulateTouchEvent('touchend', point,
|
|
interaction.ended, 'changedTouches');
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class Inspect {
|
|
// Code inspection functions
|
|
|
|
static allScriptSources()
|
|
{
|
|
let sources = [];
|
|
let scripts = document.getElementsByTagName('script');
|
|
for (let i = 0; i < scripts.length; i++) {
|
|
console.dir(scripts[i]);
|
|
sources.push(scripts[i]);
|
|
}
|
|
return sources
|
|
}
|
|
}
|
|
|
|
/* globals Power0 */
|
|
/* eslint no-console: ["error", { allow: ["log", "info", "warn", "error"] }] */
|
|
|
|
/**
|
|
* Imports
|
|
*/
|
|
|
|
/**
|
|
* A class that can be used to perform automated user interface tests.
|
|
*
|
|
* @example
|
|
* // Create the UITest object
|
|
* const test = new UITest({
|
|
* timeScale: 2
|
|
* })
|
|
*
|
|
* // Add an action to the test case
|
|
* test.tap(button, {eventType: 'click'})
|
|
*
|
|
* // Start the test case
|
|
* test.start()
|
|
*
|
|
* @class
|
|
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/uitest.html|DocTest}
|
|
*/
|
|
class UITest {
|
|
|
|
/**
|
|
* Creates an instance of an UITest.
|
|
*
|
|
* In the background, the class UITest uses the Greensock TimelineMax class. The opts object is passed directly to the TimelineMax class, so it can use any key that uses the TimelineMax class.
|
|
*
|
|
* @constructor
|
|
* @param {object} [opts] - An options object to specify the behaviour of the test case.
|
|
* @param {number} [opts.timeScale=1] - The speed at which the test should run, see https://greensock.com/docs/TimelineMax/timeScale().
|
|
* @param {string} [opts.eventType=auto] - The type of events which should be used. Possible values: pointer, touch, mouse, auto. If set to auto, the eventType is set depending on the support of the browser used.
|
|
* @param {boolean} [opts.debug=false] - If set to true, multiple informations will be print to the console.
|
|
* @param {number} [opts.defaultInterval] - The interval used when no action is specified for an action.
|
|
*/
|
|
constructor(opts = {}) {
|
|
|
|
this.opts = Object.assign({}, {
|
|
timeScale: 1,
|
|
eventType: 'auto',
|
|
debug: false,
|
|
defaultInterval: null
|
|
}, opts);
|
|
|
|
// timeline
|
|
//--------------------
|
|
this._timeline = new TimelineMax(Object.assign({}, {
|
|
paused: true
|
|
}, this.opts));
|
|
this._timeline.timeScale(this.opts.timeScale);
|
|
|
|
// eventType
|
|
//--------------------
|
|
if (this.opts.eventType === 'auto') {
|
|
if (window.PointerEvent) {
|
|
this.opts.eventType = 'pointer';
|
|
} else if ('ontouchstart' in window) {
|
|
this.opts.eventType = 'touch';
|
|
} else {
|
|
this.opts.eventType = 'mouse';
|
|
}
|
|
}
|
|
|
|
if (this.opts.debug) {
|
|
console.log(`Event type: ${this.opts.eventType}`);
|
|
}
|
|
|
|
this._timelinePositions = [0];
|
|
this._actions = 0;
|
|
|
|
// setup
|
|
//-----------------
|
|
this.setup();
|
|
}
|
|
|
|
/**
|
|
* Generates the required structure.
|
|
*
|
|
* @private
|
|
* @return {UITest} A reference to the UITest for chaining.
|
|
*/
|
|
setup() {
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Gets the Greensock TimelineMax object, used in the background of UITest.
|
|
*
|
|
* @member {TimelineMax}
|
|
*/
|
|
get timeline() {
|
|
return this._timeline
|
|
}
|
|
|
|
/**
|
|
* Starts the test case and executes the corresponding statements in the specified order.
|
|
*
|
|
* @return {UITest} A reference to the UITest for chaining.
|
|
*/
|
|
start() {
|
|
this._timeline.play();
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Stops the test case and stops executing any further instructions.
|
|
*
|
|
* @return {UITest} A reference to the UITest for chaining.
|
|
*/
|
|
stop() {
|
|
this._timeline.pause();
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Clears all instructions of the test case.
|
|
*
|
|
* @return {UITest} A reference to the UITest for chaining.
|
|
*/
|
|
clear() {
|
|
this._timeline.clear();
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Restarts the test case.
|
|
*
|
|
* @return {UITest} A reference to the UITest for chaining.
|
|
*/
|
|
restart() {
|
|
this._timeline.restart();
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Executes a tap event (pointerdown, pointerup) on a specific element.
|
|
*
|
|
* @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method.
|
|
* @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object.
|
|
* @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback().
|
|
* @param {object} [opts] - An options object to specify the behaviour of the action.
|
|
* @param {function} [opts.onStart] - A function that runs after the first event is fired. Will not be fired if only one event is running (for example, a click event). Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {function} [opts.onComplete] - A function that runs after the second event is fired. Always fired, even if only one event is running (for example, a click event). Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {string[]} [opts.eventTypes=['pointerdown', 'pointerup']] - The event types to use. If no types are specified, the event types specified in the UITest constructor are used (or auto if not specified).
|
|
* @param {string} [opts.eventType] - If you want the tap method to fire only one event (for example, a click event), you can specify the opts.eventType parameter. If eventType is not null, the parameter opts.eventTypes is ignored.
|
|
* @param {Window|Frame} [opts.context=window] - The context within which the optionally specified element selector should be executed.
|
|
* @param {boolean} [opts.bubbles=true] - The Event property bubbles indicates whether the event bubbles up through the DOM or not.
|
|
* @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring.
|
|
*/
|
|
tap(element, position, timelinePosition, opts = {}) {
|
|
|
|
// arguments
|
|
//--------------------
|
|
[position, timelinePosition, opts] = this.reorderArguments(arguments);
|
|
this._timelinePositions.push(timelinePosition);
|
|
|
|
// debug
|
|
//--------------------
|
|
if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts});
|
|
|
|
// opts
|
|
//--------------------
|
|
opts = Object.assign({}, {
|
|
onStart: null,
|
|
onComplete: null,
|
|
eventTypes: this.resolveEvents(['down', 'up']),
|
|
eventType: null,
|
|
context: window,
|
|
bubbles: true,
|
|
cancelable: true
|
|
}, opts);
|
|
|
|
if (opts.eventType) {
|
|
opts.eventTypes = opts.eventType;
|
|
}
|
|
opts.eventTypes = Array.isArray(opts.eventTypes) ? opts.eventTypes : [opts.eventTypes];
|
|
|
|
// timeline
|
|
//--------------------
|
|
this._timeline.addCallback(position => {
|
|
|
|
// element
|
|
//--------------------
|
|
const elem = Util.extractElement(opts.context, element);
|
|
|
|
// position
|
|
//--------------------
|
|
if (position === null) {
|
|
const rect = elem.getBoundingClientRect();
|
|
position = [rect.width / 2, rect.height / 2];
|
|
}
|
|
|
|
// coords
|
|
//--------------------
|
|
const coords = Util.extractPosition(position);
|
|
if (this.opts.debug) console.log('local coords', coords);
|
|
|
|
// eventTypes
|
|
//--------------------
|
|
if (opts.eventTypes.length === 1) {
|
|
opts.eventTypes.unshift(null);
|
|
}
|
|
|
|
// event opts
|
|
//--------------------
|
|
const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable};
|
|
|
|
if (opts.eventTypes[0]) {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const eventStart = Event.create(elem, coords, opts.eventTypes[0], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', eventStart);
|
|
elem.dispatchEvent(eventStart);
|
|
|
|
// onStart
|
|
//--------------------
|
|
if (opts.onStart) {
|
|
opts.onStart.call(this, eventStart);
|
|
}
|
|
}
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const eventComplete = Event.create(elem, coords, opts.eventTypes[1], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', eventComplete);
|
|
elem.dispatchEvent(eventComplete);
|
|
|
|
// onComplete
|
|
//--------------------
|
|
if (opts.onComplete) {
|
|
opts.onComplete.call(this, eventComplete);
|
|
}
|
|
|
|
}, timelinePosition, [position]);
|
|
|
|
this._actions++;
|
|
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Executes a pan event (pointerdown, pointermove, pointerup) on a specific element.
|
|
*
|
|
* @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method.
|
|
* @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object.
|
|
* @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback().
|
|
* @param {object} [opts] - An options object to specify the behaviour of the action.
|
|
* @param {function} [opts.onStart] - A function that runs after the first event is fired. Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {function} [opts.onUpdate] - A function that runs after each execution of the second event. Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {function} [opts.onComplete] - A function that runs after the third event is fired. Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {number[]|object|PIXI.DisplayObject} [opts.to={x: 0, y: 0}] - The target of the pan process. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object.
|
|
* @param {number} [opts.duration=1] - The duration of the pan animation in seconds, see https://greensock.com/docs/TweenLite/duration().
|
|
* @param {Ease} [opts.ease=Power0.easeNone] - The easing of the pan animation, see https://greensock.com/docs/Easing.
|
|
* @param {string[]} [opts.eventTypes=['pointerdown', 'pointermove', 'pointerup']] - The event types to use. If no types are specified, the event types specified in the UITest constructor are used (or auto if not specified).
|
|
* @param {Window|Frame} [opts.context=window] - The context within which the optionally specified element selector should be executed.
|
|
* @param {boolean} [opts.bubbles=true] - The Event property bubbles indicates whether the event bubbles up through the DOM or not.
|
|
* @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring.
|
|
*/
|
|
pan(element, position, timelinePosition, opts = {}) {
|
|
|
|
// arguments
|
|
//--------------------
|
|
[position, timelinePosition, opts] = this.reorderArguments(arguments);
|
|
this._timelinePositions.push(timelinePosition);
|
|
|
|
// debug
|
|
//--------------------
|
|
if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts});
|
|
|
|
// opts
|
|
//--------------------
|
|
opts = Object.assign({}, {
|
|
onStart: null,
|
|
onUpdate: null,
|
|
onComplete: null,
|
|
to: {x: 0, y: 0},
|
|
duration: 1,
|
|
ease: Power0.easeNone,
|
|
eventTypes: this.resolveEvents(['down', 'move', 'up']),
|
|
context: window,
|
|
bubbles: true,
|
|
cancelable: true
|
|
}, opts);
|
|
|
|
// timeline
|
|
//--------------------
|
|
this._timeline.addCallback(position => {
|
|
|
|
// element
|
|
//--------------------
|
|
const elem = Util.extractElement(opts.context, element);
|
|
|
|
// coords
|
|
//--------------------
|
|
const from = Util.extractPosition(position);
|
|
|
|
// event opts
|
|
//--------------------
|
|
const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable};
|
|
|
|
const gsOpts = {
|
|
ease: opts.ease,
|
|
onStart: () => {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const event = Event.create(elem, from, opts.eventTypes[0], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', event);
|
|
elem.dispatchEvent(event);
|
|
|
|
// onStart
|
|
//--------------------
|
|
if (opts.onStart) {
|
|
opts.onStart.call(this, event);
|
|
}
|
|
},
|
|
onUpdate: () => {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const event = Event.create(elem, from, opts.eventTypes[1], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', event);
|
|
elem.dispatchEvent(event);
|
|
|
|
// onUpdate
|
|
//--------------------
|
|
if (opts.onUpdate) {
|
|
opts.onUpdate.call(this, event);
|
|
}
|
|
},
|
|
onComplete: () => {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const event = Event.create(elem, from, opts.eventTypes[2], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', event);
|
|
elem.dispatchEvent(event);
|
|
|
|
// onComplete
|
|
//--------------------
|
|
if (opts.onComplete) {
|
|
opts.onComplete.call(this, event);
|
|
}
|
|
}
|
|
};
|
|
|
|
// to
|
|
//--------------------
|
|
const object = Util.extractTo(opts);
|
|
Object.assign(gsOpts, object);
|
|
|
|
// drag animation
|
|
//--------------------
|
|
TweenMax.to(from, opts.duration, gsOpts);
|
|
|
|
}, timelinePosition, [position]);
|
|
|
|
this._actions++;
|
|
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Executes a pinch event (pointerdown, pointermove, pointerup) on a specific element with two "fingers" simultaneously.
|
|
*
|
|
* @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method.
|
|
* @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object.
|
|
* @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback().
|
|
* @param {object} [opts] - An options object to specify the behaviour of the action.
|
|
* @param {function} [opts.onStart] - A function that runs after the first events are fired. Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {function} [opts.onUpdate] - A function that runs after each execution of the second events. Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {function} [opts.onComplete] - A function that runs after the third events are fired. Receives the fired event object as the first parameter. The test case (UITest) is bound to this.
|
|
* @param {boolean} [opts.doubleCallbacks=false] - The callbacks onStart, onUpdate and onComplete will be fired only for one finger. If set to true, the events will be fired for both fingers.
|
|
* @param {number} [opts.distance=100] - The distance in pixels, how far the two "fingers" should move apart. If to or bezier specified, distance is ignored.
|
|
* @param {number[][]|object[]|PIXI.DisplayObject[]} [opts.to] - The targets of the pinch process. The position must be an array with two entries. An entry can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. If bezier is specified, to is ignored.
|
|
* @param {number[][]|object[]|PIXI.DisplayObject[]} [opts.bezier] - The targets of the pinch process. The position must be an array with two entries. An entry may be an array of positions or a bezier object (https://greensock.com/docs/Plugins/BezierPlugin). A position in the array or the values array of the bezier object can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. If bezier is specified, to is ignored.
|
|
* @param {number} [opts.duration=1] - The duration of the pan animation in seconds, see https://greensock.com/docs/TweenLite/duration().
|
|
* @param {Ease} [opts.ease=Power0.easeNone] - The easing of the pan animation, see https://greensock.com/docs/Easing.
|
|
* @param {string[]} [opts.eventTypes=['pointerdown', 'pointermove', 'pointerup']] - The event types to use. If no types are specified, the event types specified in the UITest constructor are used (or auto if not specified).
|
|
* @param {Window|Frame} [opts.context=window] - The context within which the optionally specified element selector should be executed.
|
|
* @param {boolean} [opts.bubbles=true] - The Event property bubbles indicates whether the event bubbles up through the DOM or not.
|
|
* @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring.
|
|
*/
|
|
pinch(element, position, timelinePosition, opts = {}) {
|
|
|
|
// arguments
|
|
//--------------------
|
|
[position, timelinePosition, opts] = this.reorderArguments(arguments);
|
|
this._timelinePositions.push(timelinePosition);
|
|
|
|
// debug
|
|
//--------------------
|
|
if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts});
|
|
|
|
// opts
|
|
//--------------------
|
|
opts = Object.assign({}, {
|
|
onStart: null,
|
|
onUpdate: null,
|
|
onComplete: null,
|
|
doubleCallbacks: false,
|
|
duration: 1,
|
|
distance: 100,
|
|
to: null,
|
|
bezier: null,
|
|
ease: Power0.easeNone,
|
|
eventTypes: this.resolveEvents(['down', 'move', 'up']),
|
|
context: window,
|
|
bubbles: true,
|
|
cancelable: true
|
|
}, opts);
|
|
|
|
// timeline
|
|
//--------------------
|
|
this._timeline.addCallback(position => {
|
|
|
|
// element
|
|
//--------------------
|
|
const elem = Util.extractElement(opts.context, element);
|
|
|
|
// from
|
|
//--------------------
|
|
let from1 = null;
|
|
let from2 = null;
|
|
|
|
if (Array.isArray(position) && !Util.isNumber(position[0])) {
|
|
from1 = Util.extractPosition(position[0]);
|
|
from2 = Util.extractPosition(position[1]);
|
|
} else {
|
|
from1 = Util.extractPosition(position);
|
|
from2 = {x: from1.x, y: from1.y};
|
|
}
|
|
|
|
// to
|
|
//--------------------
|
|
let gsOpts1 = {};
|
|
let gsOpts2 = {};
|
|
|
|
if (opts.to || opts.bezier) {
|
|
[gsOpts1, gsOpts2] = Util.extractMultiTo(opts);
|
|
} else {
|
|
const distance = opts.distance != null ? opts.distance : 100;
|
|
gsOpts1.x = from1.x - distance / 2;
|
|
gsOpts1.y = from1.y;
|
|
gsOpts2.x = from2.x + distance / 2;
|
|
gsOpts2.y = from2.y;
|
|
}
|
|
|
|
// pointers
|
|
//--------------------
|
|
const pointers = new Map();
|
|
pointers.set(0, {element: from1, gsOpts: gsOpts1});
|
|
pointers.set(1, {element: from2, gsOpts: gsOpts2});
|
|
|
|
// loop
|
|
//--------------------
|
|
pointers.forEach((value, key) => {
|
|
|
|
// from
|
|
//--------------------
|
|
const from = value.element;
|
|
|
|
// event opts
|
|
//--------------------
|
|
const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable, pointerId: key, isPrimary: key === 0};
|
|
|
|
const gsOpts = {
|
|
ease: opts.ease,
|
|
onStart: () => {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const event = Event.create(elem, from, opts.eventTypes[0], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', event);
|
|
elem.dispatchEvent(event);
|
|
|
|
// onStart
|
|
//--------------------
|
|
if (opts.onStart && (opts.doubleCallbacks || key === 0)) {
|
|
opts.onStart.call(this, event);
|
|
}
|
|
},
|
|
onUpdate: () => {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const event = Event.create(elem, from, opts.eventTypes[1], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', event);
|
|
elem.dispatchEvent(event);
|
|
|
|
// onUpdate
|
|
//--------------------
|
|
if (opts.onUpdate && (opts.doubleCallbacks || key === 0)) {
|
|
opts.onUpdate.call(this, event);
|
|
}
|
|
},
|
|
onComplete: () => {
|
|
|
|
// create and dispatch event
|
|
//--------------------
|
|
const event = Event.create(elem, from, opts.eventTypes[2], eventOpts);
|
|
if (this.opts.debug) console.log('dispatch event', event);
|
|
elem.dispatchEvent(event);
|
|
|
|
// onComplete
|
|
//--------------------
|
|
if (opts.onComplete && (opts.doubleCallbacks || key === 0)) {
|
|
opts.onComplete.call(this, event);
|
|
}
|
|
}
|
|
};
|
|
|
|
// to
|
|
//--------------------
|
|
Object.assign(gsOpts, value.gsOpts);
|
|
|
|
// drag animation
|
|
//--------------------
|
|
TweenMax.to(from, opts.duration, gsOpts);
|
|
});
|
|
|
|
}, timelinePosition, [position]);
|
|
|
|
this._actions++;
|
|
|
|
return this
|
|
}
|
|
|
|
// /**
|
|
// * Adds a tap event to the timeline.
|
|
// *
|
|
// * @return {UITest} A reference to the uitest for chaining.
|
|
// */
|
|
// rotate() {
|
|
// return this
|
|
// }
|
|
|
|
// /**
|
|
// * Adds a tap event to the timeline.
|
|
// *
|
|
// * @return {UITest} A reference to the uitest for chaining.
|
|
// */
|
|
// swipe() {
|
|
// return this
|
|
// }
|
|
|
|
// /**
|
|
// * Adds a tap event to the timeline.
|
|
// *
|
|
// * @return {UITest} A reference to the uitest for chaining.
|
|
// */
|
|
// press() {
|
|
// return this
|
|
// }
|
|
|
|
// /**
|
|
// * Adds a tap event to the timeline.
|
|
// *
|
|
// * @return {UITest} A reference to the uitest for chaining.
|
|
// */
|
|
// event() {
|
|
// return this
|
|
// }
|
|
|
|
/**
|
|
* Sorts the parameters so that the second, third, and fourth parameters can be optional (and possibly slip forward).
|
|
*
|
|
* @private
|
|
* @param {arguments} params - The arguments which were passed to the function.
|
|
* @returns {array} - Returns an array of the position, the timelinePosition and the opts object.
|
|
*/
|
|
reorderArguments(params) {
|
|
|
|
// first parameter
|
|
//--------------------
|
|
const element = params[0];
|
|
|
|
// other parameter
|
|
//--------------------
|
|
let position = null;
|
|
let timelinePosition = null;
|
|
let opts = null;
|
|
|
|
// second parameter
|
|
//--------------------
|
|
if (Util.isNumber(params[1])) {
|
|
timelinePosition = params[1];
|
|
} else if (Util.isObject(params[1]) && !Util.isPixiDisplayObject(params[1]) && (params[1].x == null || params[1].y == null)) {
|
|
opts = params[1];
|
|
} else if (params[1] != null) {
|
|
position = params[1];
|
|
}
|
|
|
|
// third parameter
|
|
//--------------------
|
|
if (Util.isNumber(params[2])) {
|
|
timelinePosition = params[2];
|
|
} else if (Util.isObject(params[2])) {
|
|
opts = params[2];
|
|
}
|
|
|
|
// fourth parameter
|
|
//--------------------
|
|
if (Util.isObject(params[3])) {
|
|
opts = params[3];
|
|
}
|
|
|
|
if (timelinePosition === null) {
|
|
if (this.opts.defaultInterval === null && this._actions > 1) {
|
|
throw new Error('No execution time was specified for this action, and a default interval was not set in the class constructor!')
|
|
}
|
|
timelinePosition = Math.max(...this._timelinePositions) + (this.opts.defaultInterval || 1);
|
|
}
|
|
|
|
if (opts === null) {
|
|
opts = {};
|
|
}
|
|
|
|
return [position, timelinePosition, opts]
|
|
}
|
|
|
|
/**
|
|
* Converts event type shortcuts to real event names.
|
|
*
|
|
* @private
|
|
* @param {string[]} events - An array of event types.
|
|
*/
|
|
resolveEvents(events) {
|
|
|
|
const data = [];
|
|
|
|
if (this.opts.eventType === 'pointer') {
|
|
events.forEach(it => {
|
|
if (it === 'down') {
|
|
data.push('pointerdown');
|
|
} else if (it === 'move') {
|
|
data.push('pointermove');
|
|
} else if (it === 'up') {
|
|
data.push('pointerup');
|
|
}
|
|
});
|
|
} else if (this.opts.eventType === 'touch') {
|
|
events.forEach(it => {
|
|
if (it === 'down') {
|
|
data.push('touchstart');
|
|
} else if (it === 'move') {
|
|
data.push('touchmove');
|
|
} else if (it === 'up') {
|
|
data.push('touchend');
|
|
}
|
|
});
|
|
} else {
|
|
events.forEach(it => {
|
|
if (it === 'down') {
|
|
data.push('mousedown');
|
|
} else if (it === 'move') {
|
|
data.push('mousemove');
|
|
} else if (it === 'up') {
|
|
data.push('mouseup');
|
|
}
|
|
});
|
|
}
|
|
|
|
return data
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class.
|
|
*
|
|
* @example
|
|
* // Checks if a thing is a number.
|
|
* const num = Util.isNumber(20)
|
|
*
|
|
* @private
|
|
* @ignore
|
|
* @class
|
|
*/
|
|
class Util {
|
|
|
|
/**
|
|
* Resolves the element from a specific context.
|
|
*
|
|
* @static
|
|
* @param {Window|Frame} context - The context within which the optionally specified element selector should be executed.
|
|
* @return {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method.
|
|
*/
|
|
static extractElement(context, element) {
|
|
|
|
const cont = Util.isFrame(context) ? context.contentDocument : context.document;
|
|
const elem = Util.isString(element) ? cont.querySelector(element) : element;
|
|
|
|
return elem
|
|
}
|
|
|
|
/**
|
|
* Extracts the position of the second parameter.
|
|
*
|
|
* @static
|
|
* @param {object} object - Something were the coords should be extracted.
|
|
* @return {object} - Returns an object with the keys x and y.
|
|
*/
|
|
static extractPosition(object) {
|
|
|
|
// event coords
|
|
//--------------------
|
|
const position = {x: 0, y: 0};
|
|
|
|
// get the position
|
|
//--------------------
|
|
if (!object) {
|
|
position.x = 0;
|
|
position.y = 0;
|
|
} else if (typeof object.getBounds === 'function') {
|
|
const bounds = object.getBounds();
|
|
position.x = bounds.x + bounds.width / 2;
|
|
position.y = bounds.y + bounds.height / 2;
|
|
} else if (Array.isArray(object)) {
|
|
position.x = object[0];
|
|
position.y = object[1];
|
|
} else if (object.x != null && object.y != null) {
|
|
position.x = object.x;
|
|
position.y = object.y;
|
|
}
|
|
|
|
return position
|
|
}
|
|
|
|
/**
|
|
* Extracts the to or bezier key.
|
|
*
|
|
* @static
|
|
* @param {object} opts - An options object where to or bezier should be extracted.
|
|
* @return {object} - Returns an object with the to or bezier keys.
|
|
*/
|
|
static extractTo(opts) {
|
|
|
|
const object = {};
|
|
|
|
if (opts.bezier) {
|
|
|
|
let bezier = null;
|
|
|
|
if (Array.isArray(opts.bezier)) {
|
|
bezier = {
|
|
values: opts.bezier.map(it => Util.extractPosition(it)),
|
|
type: 'thru'
|
|
};
|
|
} else {
|
|
opts.bezier.values = opts.bezier.values.map(it => Util.extractPosition(it));
|
|
bezier = opts.bezier;
|
|
}
|
|
|
|
object.bezier = bezier;
|
|
} else {
|
|
const to = Util.extractPosition(opts.to);
|
|
object.x = to.x;
|
|
object.y = to.y;
|
|
}
|
|
|
|
return object
|
|
}
|
|
|
|
/**
|
|
* Extracts multiple to or bezier keys.
|
|
*
|
|
* @static
|
|
* @param {object} opts - An options object where to or bezier should be extracted.
|
|
* @return {object[]} - Returns an array of objects with the keys x and y.
|
|
*/
|
|
static extractMultiTo(opts) {
|
|
|
|
const objects = [];
|
|
|
|
if (opts.bezier) {
|
|
|
|
opts.bezier.forEach(it => {
|
|
|
|
let bezier = null;
|
|
|
|
if (Array.isArray(it)) {
|
|
bezier = {
|
|
values: it.map(it => Util.extractPosition(it)),
|
|
type: 'thru'
|
|
};
|
|
} else {
|
|
it.values = it.values.map(it => Util.extractPosition(it));
|
|
bezier = it;
|
|
}
|
|
|
|
objects.push({
|
|
bezier
|
|
});
|
|
});
|
|
|
|
} else {
|
|
|
|
opts.to.forEach(it => {
|
|
const to = Util.extractPosition(it);
|
|
objects.push({
|
|
x: to.x,
|
|
y: to.y
|
|
});
|
|
});
|
|
}
|
|
|
|
return objects
|
|
}
|
|
|
|
/**
|
|
* Checks if a thing is a string.
|
|
*
|
|
* @static
|
|
* @param {object} object - The object to test for.
|
|
* @return {boolean} - true if the thing is a string, otherwise false.
|
|
*/
|
|
static isString(object) {
|
|
return typeof object === 'string'
|
|
}
|
|
|
|
/**
|
|
* Checks if a thing is a number.
|
|
*
|
|
* @static
|
|
* @param {object} object - The object to test for.
|
|
* @return {boolean} - true if the thing is a number, otherwise false.
|
|
*/
|
|
static isNumber(object) {
|
|
return typeof object === 'number'
|
|
}
|
|
|
|
/**
|
|
* Checks if a thing is an object.
|
|
*
|
|
* @static
|
|
* @param {object} object - The object to test for.
|
|
* @return {boolean} - true if the thing is an object, otherwise false.
|
|
*/
|
|
static isObject(object) {
|
|
return typeof object === 'object' && !Array.isArray(object)
|
|
}
|
|
|
|
/**
|
|
* Checks if a thing is an PIXI.DisplayObject.
|
|
*
|
|
* @static
|
|
* @param {object} object - The object to test for.
|
|
* @return {boolean} - true if the thing is a PIXI.DisplayObject, otherwise false.
|
|
*/
|
|
static isPixiDisplayObject(object) {
|
|
return typeof object.getBounds === 'function' && typeof object.renderWebGL === 'function' && typeof object.setTransform === 'function'
|
|
}
|
|
|
|
/**
|
|
* Checks if a thing is a frame.
|
|
*
|
|
* @static
|
|
* @param {object} object - The object to test for.
|
|
* @return {boolean} - true if the thing is a frame, otherwise false.
|
|
*/
|
|
static isFrame(object) {
|
|
return object.contentDocument != null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Event helper class.
|
|
*
|
|
* @example
|
|
* // Creates an event object.
|
|
* const event = Event.create(h2, {x: 5, y: 10}, 'touchstart')
|
|
*
|
|
* @private
|
|
* @ignore
|
|
* @class
|
|
*/
|
|
class Event {
|
|
|
|
/**
|
|
* Creates an event object.
|
|
*
|
|
* @static
|
|
* @param {HTMLElement} target - The element on which the event should be executed.
|
|
* @param {object} position - The local position of the event in relation to the target. The object must have the keys x and y.
|
|
* @param {string} type - The type of the event, see https://developer.mozilla.org/de/docs/Web/Events
|
|
* @param {object} opts - An options object. Every paramter of the event object can be overridden, see e.g. https://developer.mozilla.org/de/docs/Web/API/MouseEvent for all the properties.
|
|
*/
|
|
static create(target, position = {x: 0, y: 0}, type = 'pointerup', opts = {}) {
|
|
|
|
const rect = typeof target.getBoundingClientRect === 'function' ? target.getBoundingClientRect() : {x: 0, y: 0};
|
|
|
|
// EventInit
|
|
const eventOpts = {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
composed: false
|
|
};
|
|
|
|
// UIEventInit
|
|
const uiEventOpts = {
|
|
detail: 0,
|
|
view: window
|
|
};
|
|
|
|
// MouseEvent
|
|
const mouseEventOpts = {
|
|
screenX: window.screenX + target.offsetLeft + position.x,
|
|
screenY: window.screenY + target.offsetTop + position.y,
|
|
clientX: rect.x + position.x,
|
|
clientY: rect.y + position.y,
|
|
ctrlKey: false,
|
|
shiftKey: false,
|
|
altKey: false,
|
|
metaKey: false,
|
|
button: 0,
|
|
buttons: 1,
|
|
relatedTarget: null,
|
|
region: null
|
|
};
|
|
|
|
// TouchEvent
|
|
const touchEventOpts = {
|
|
touches: [],
|
|
targetTouches: [],
|
|
changedTouches: [],
|
|
ctrlKey: false,
|
|
shiftKey: false,
|
|
altKey: false,
|
|
metaKey: false
|
|
};
|
|
|
|
// PointerEvent
|
|
const pointerEventOpts = {
|
|
pointerId: 0,
|
|
width: 1,
|
|
height: 1,
|
|
pressure: 0,
|
|
tangentialPressure: 0,
|
|
tiltX: 0,
|
|
tiltY: 0,
|
|
twist: 0,
|
|
pointerType: 'touch',
|
|
isPrimary: true
|
|
};
|
|
|
|
if (type.startsWith('pointer')) {
|
|
return new PointerEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, pointerEventOpts, opts))
|
|
} else if (type.startsWith('touch')) {
|
|
return new TouchEvent(type, Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts))
|
|
} else {
|
|
return new MouseEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts))
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Needed to ensure that rollup.js includes class definitions and the classes
|
|
are visible inside doctests.
|
|
*/
|
|
|
|
window.AbstractScatter = AbstractScatter;
|
|
window.Angle = Angle;
|
|
window.App = App;
|
|
window.BaseEvent = BaseEvent;
|
|
window.Capabilities = Capabilities;
|
|
window.CapabilitiesTests = CapabilitiesTests;
|
|
window.Colors = Colors;
|
|
window.Cycle = Cycle;
|
|
|
|
window.DOMFlip = DOMFlip;
|
|
window.DOMFlippable = DOMFlippable;
|
|
window.CardLoader = CardLoader;
|
|
window.PDFLoader = PDFLoader;
|
|
window.HTMLLoader = HTMLLoader;
|
|
window.ImageLoader = ImageLoader;
|
|
window.FrameLoader = FrameLoader;
|
|
|
|
window.DOMScatter = DOMScatter;
|
|
window.DOMScatterContainer = DOMScatterContainer;
|
|
window.Dates = Dates;
|
|
window.Doctest = Doctest;
|
|
window.Elements = Elements$1;
|
|
window.Errors = Errors;
|
|
window.EventRecorder = EventRecorder;
|
|
window.Events = Events;
|
|
window.FrameContainer = FrameContainer;
|
|
window.FrameTarget = FrameTarget;
|
|
window.IApp = IApp;
|
|
window.IInteractionMapperTarget = IInteractionMapperTarget;
|
|
window.IInteractionTarget = IInteractionTarget;
|
|
window.Index = Index;
|
|
window.Inspect = Inspect;
|
|
window.Interaction = Interaction;
|
|
window.InteractionDelegate = InteractionDelegate;
|
|
window.InteractionDelta = InteractionDelta;
|
|
window.InteractionMapper = InteractionMapper$1;
|
|
window.InteractionPoints = InteractionPoints;
|
|
window.Interface = Interface;
|
|
window.PointMap = PointMap;
|
|
window.Rect = Rect;
|
|
window.Points = Points;
|
|
window.Polygon = Polygon;
|
|
window.Poppable = Poppable;
|
|
window.Popup = Popup;
|
|
window.PopupMenu = PopupMenu$1;
|
|
window.ResizeEvent = ResizeEvent;
|
|
window.ScatterEvent = ScatterEvent;
|
|
window.Sets = Sets;
|
|
window.Strings = Strings;
|
|
window.UITest = UITest;
|
|
window.getId = getId$1;
|
|
window.isEmpty = isEmpty;
|
|
window.lerp = lerp;
|
|
window.debounce = debounce;
|
|
window.randomInt = randomInt;
|
|
window.randomFloat = randomFloat;
|
|
|
|
}());
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsLmpzIiwic291cmNlcyI6WyJpbnRlcmZhY2UuanMiLCJhcHAuanMiLCJkb2N0ZXN0LmpzIiwiZXJyb3JzLmpzIiwiZXZlbnRzLmpzIiwidXRpbHMuanMiLCJpbnRlcmFjdGlvbi5qcyIsImNhcGFiaWxpdGllcy5qcyIsInNjYXR0ZXIuanMiLCJmbGlwcGFibGUuanMiLCJpbmRleC5qcyIsInBvcHBhYmxlLmpzIiwicG9wdXAuanMiLCJwb3B1cG1lbnUuanMiLCJmcmFtZXMuanMiLCJpbnNwZWN0LmpzIiwidWl0ZXN0LmpzIiwiYnVuZGxlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEluIG9yZGVyIHRvIHRlc3QgdGhpcyBpbnRlcmZhY2UgaW1wbGVtZW50YXRpb24gcnVuIGpzYyBpbnRlcmZhY2UuanNcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW50ZXJmYWNlIHtcbiAgICAvLyBBYnN0cmFjdCBpbnRlcmZhY2UgdGhhdCBzaG91bGQgYmUgZXh0ZW5kZWQgaW4gaW50ZXJmYWNlIHN1YmNsYXNzZXMuXG4gICAgLy8gQnkgY29udmVudGlvbiBhbGwgaW50ZXJmYWNlcyBzaG91bGQgc3RhcnQgd2l0aCBhbiB1cHBlciAnSSdcblxuICAgIHN0YXRpYyBpbXBsZW1lbnRhdGlvbkVycm9yKGtsYXNzKSB7XG4gICAgICAgIGxldCBpbnRlcmZhY2VLZXlzID0gUmVmbGVjdC5vd25LZXlzKHRoaXMucHJvdG90eXBlKVxuICAgICAgICBsZXQgY2xhc3NLZXlzID0gUmVmbGVjdC5vd25LZXlzKGtsYXNzLnByb3RvdHlwZSlcbiAgICAgICAgZm9yKGxldCBrZXkgb2YgaW50ZXJmYWNlS2V5cykge1xuICAgICAgICAgICAgbGV0IGludGVyZmFjZURlc2MgPSB0aGlzLnByb3RvdHlwZVtrZXldXG4gICAgICAgICAgICBsZXQgY2xhc3NEZXNjID0ga2xhc3MucHJvdG90eXBlW2tleV1cbiAgICAgICAgICAgIGlmICh0eXBlb2YoY2xhc3NEZXNjKSA9PSAndW5kZWZpbmVkJylcbiAgICAgICAgICAgICAgICByZXR1cm4gJ01pc3NpbmcgJyArIGtleVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgc3RhdGljIGltcGxlbWVudGVkQnkoa2xhc3MpIHtcbiAgICAgICAgLy8gSW4gdGhlIGZpcnN0IHN0ZXAgb25seSBjaGVja3Mgd2hldGhlciB0aGUgbWV0aG9kcyBvZiB0aGlzXG4gICAgICAgIC8vIGludGVyZmFjZSBhcmUgYWxsIGltcGxlbWVudGVkIGJ5IHRoZSBnaXZlbiBjbGFzc1xuICAgICAgICBsZXQgZXJyb3IgPSB0aGlzLmltcGxlbWVudGF0aW9uRXJyb3Ioa2xhc3MpXG4gICAgICAgIHJldHVybiBlcnJvciA9PSBudWxsXG4gICAgfVxuXG4gICAgICAgIC8vIFRPRE86IFNwZWNpZnkgb3B0aW9uYWwgbWV0aG9kc1xuLy8gICAgIHN0YXRpYyBvcHRpb25hbE1ldGhvZHMoKSB7XG4vLyAgICAgICAgIHJldHVybiBbdGhpcy5vbk1vdXNlV2hlZWxdXG4vLyAgICAgfVxufVxuIiwiaW1wb3J0IEludGVyZmFjZSBmcm9tICcuL2ludGVyZmFjZS5qcydcblxuLyoqIEJhc2ljIEFwcGxpY2F0aW9uIG9iamVjdCB0byBiZSB1c2VkIGFzIGEgc2luZ2xldG9uLlxuICAgIFByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgYXV0b21hdGljIHRlc3RpbmcgYW5kIGNvbW1vbiBkZXZpY2Ugc3BlY2lmaWNcbiAgICBmZWF0dXJlIGRldGVjdGlvbi5cbiovXG5cbmV4cG9ydCBjbGFzcyBJQXBwIGV4dGVuZHMgSW50ZXJmYWNlIHtcbiAgICAvKiogQnVpbGQgdGhlIGFwcCBieSByZWdpc3RlcmluZyBldmVudCBoYW5kbGVycyxcbiAgICAgKiAgIGFkZGluZyBET00gZWxlbWVudHMsIGluc3RhbmNpYXRpbmcgdGVtcGxhdGVzLCBldGMuLi5cbiAgICAgKi9cbiAgICBzZXR1cCgpIHsgcmV0dXJuIHRoaXMgfVxuXG4gICAgLyoqIFJ1biB0aGUgYXBwbGljYXRpb24gYnkgc3RhcnRpbmcgYSBtYWluIGxvb3AsIC4uLlxuICAgICAqL1xuICAgIHJ1bigpIHsgcmV0dXJuIHRoaXMgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBcHAgZXh0ZW5kcyBPYmplY3Qge1xuICAgIC8qKiBPdmVycmlkZSB0aGlzIG1ldGhvZCB0byBidWlsZCB5b3VyIGFwcC5cbiAgICAqL1xuICAgIHNldHVwKCkge1xuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKiBTdGFydCBhbmQgcnVuIHRoZSBhcHBsaWNhdGlvbi4gT3ZlcnJpZGUgdGhpcyBtZXRob2Qgd2l0aCBldmVyeXRoaW5nXG4gICAgdGhhdCBpcyBuZWVkZWQgdG8gbWFpbnRhaW4geW91ciBBcHAsIG1haW4gbG9vcHMsIGV0Yy5cbiAgICAqL1xuICAgIHJ1bigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKiogRGVmaW5lcyBhbGwgdGVzdCBzdWl0ZXMuIE92ZXJ3cml0ZSB0aGlzIG1ldGhvZCB0byBlbnN1cmUgdGhhdFxuICAgIGFsbCB0ZXN0YWJsZSBhc3BlY3RzIG9mIHlvdXIgQXBwIGFyZSBldmFsdWF0ZWQuXG4gICAgKi9cbiAgICBhbGxUZXN0cygpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ092ZXJ3cml0ZSBBcHAuYWxsVGVzdHMoKScpXG4gICAgfVxuXG4gICAgLyoqIFJ1biBhbGwgdGVzdHMuIFNob3VsZCByZXR1cm4gJ29rJyBhbmQgdGhlIGFtb3VudCBvZiB0aW1lIG5lZWRlZCB0b1xuICAgIHJ1biBBcHAuYWxsVGVzdHMoKSBvciBhIGZhaWx1cmUgbWVzc2FnZSB3aXRoIGRpYWdub3N0aWMgZXJyb3IgZGVjcmlwdGlvbi5cbiAgICBAcmV0dXJuIHthcnJheX0gLSBhcnJheSB3aXRoICdvaycgYXMgZmlyc3QgZWxlbWVudCBhbmQgbmVlZGVkIHRpbWUgYXNcbiAgICAgICAgICAgICAgICAgICAgICBzZWNvbmQgZWxlbWVudCBvciBcIlRlc3RzIGZhaWxlZFwiIGFuZCBhbiBlcnJvciBzdHJpbmdcbiAgICAqL1xuICAgIHJ1blRlc3RzKCkge1xuICAgICAgICB2YXIgc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5hbGxUZXN0cygpXG4gICAgICAgICAgICB2YXIgZW5kID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICAgICAgICAgIHJldHVybiBbJ29rJywgZW5kIC0gc3RhcnRdXG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2goZSkge1xuICAgICAgICAgICAgY29uc29sZS50cmFjZSgpXG4gICAgICAgICAgICByZXR1cm4gWydUZXN0cyBmYWlsZWQnLCBlLm1lc3NhZ2VdXG4gICAgICAgIH1cbiAgICB9XG59XG5cbklBcHAuaW1wbGVtZW50ZWRCeShBcHApXG4iLCIvLyBBbGxvd3MgYnJvd3NlcnMgdG8gcGVyZm9ybSBkb2N0ZXN0cy5cbi8vIFVzZXMgdGhlIGNvZGUgaGlnaGxpZ2h0IHBhY2thZ2UgZnJvbSBodHRwOi8vaGlnaGxpZ2h0anMucmVhZHRoZWRvY3MuaW9cbi8vIGlmIGF2YWlsYWJsZVxuXG52YXIgZG9jVGVzdExvZ01lc3NhZ2VzID0gW11cblxuQXJyYXkucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID09IGFycmF5Lmxlbmd0aCAmJlxuICAgICAgICAgdGhpcy5ldmVyeSggZnVuY3Rpb24odGhpc19pLGkpIHsgcmV0dXJuIHRoaXNfaSA9PSBhcnJheVtpXSB9IClcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRG9jdGVzdCB7XG5cbiAgICBzdGF0aWMgYXNzZXJ0KHZhbHVlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXNzZXJ0aW9uIHZpb2xhdGVkJylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBwcHJpbnQob2JqKSB7XG4gICAgICAgIGlmIChvYmogPT09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gJ251bGwnXG4gICAgICAgIGxldCBzdHJpbmdpZmllZCA9IG9iai50b1N0cmluZygpXG4gICAgICAgIGlmIChzdHJpbmdpZmllZCA9PSAnW29iamVjdCBPYmplY3RdJylcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShvYmopXG4gICAgICAgIHJldHVybiBzdHJpbmdpZmllZFxuICAgIH1cblxuICAgIHN0YXRpYyBleHBlY3QoZXhwciwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMucHByaW50KGV4cHIpICE9IHRoaXMucHByaW50KHZhbHVlKSkge1xuICAgICAgICAgICAgLy90aHJvdyBuZXcgRXJyb3IoXCJnb3QgYFwiICsgZXhwciArIFwiYCBidXQgZXhwZWN0ZWQgYFwiICsgdmFsdWUgKyBcImAuXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dvdCBgJyArIHRoaXMucHByaW50KGV4cHIpICsgJ2AgYnV0IGV4cGVjdGVkIGAnICsgdGhpcy5wcHJpbnQodmFsdWUpICsgJ2AuJylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBleHBlY3RFcnJvcihlcnJvciwgbWVzc2FnZSkge1xuICAgICAgICBsZXQgaW5kZXggPSBlcnJvci50b1N0cmluZygpLmluZGV4T2YobWVzc2FnZSlcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdnb3QgYCcgKyBtZXNzYWdlICsgJ2AgYnV0IGV4cGVjdGVkIGAnICsgZXJyb3IgKyAnYC4nKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIGV4cGVjdExvZyguLi5tZXNzYWdlcykge1xuICAgICAgIC8vIGlmICghZG9jVGVzdExvZ01lc3NhZ2VzLmVxdWFscyhtZXNzYWdlcykpIHtcbiAgICAgICAgICAgIGRvY1Rlc3RMb2dNZXNzYWdlcy5mb3JFYWNoKChtc2csIGkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobXNnICE9IG1lc3NhZ2VzW2ldKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgbG9nIG1lc3NhZ2U6IGAnICsgbWVzc2FnZXNbaV0gKyAnYC4nKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgLy8gICAgdGhyb3cgbmV3IEVycm9yKCdVdXBzJylcbiAgICAgICAgLy99XG4gICAgfVxuXG4gICAgc3RhdGljIGxvZyhtZXNzYWdlKSB7XG4gICAgICAgIGRvY1Rlc3RMb2dNZXNzYWdlcy5wdXNoKG1lc3NhZ2UpXG4gICAgfVxuXG4gICAgc3RhdGljIGhpZ2hsaWdodChjb2RlKSB7XG4gICAgICAgIGlmICh0eXBlb2YoaGxqcykgPT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgICAgICByZXR1cm4gY29kZVxuICAgICAgICByZXR1cm4gaGxqcy5oaWdobGlnaHQoJ2phdmFzY3JpcHQnLCBjb2RlKVxuICAgIH1cblxuICAgIHN0YXRpYyBzdHJpcExlYWRpbmdMaW5lcyhjb2RlKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBbXVxuICAgICAgICBsZXQgaW5mb3JtYXRpdmUgPSBmYWxzZVxuICAgICAgICBmb3IobGV0IGxpbmUgb2YgY29kZS5zcGxpdCgnXFxuJykpIHtcbiAgICAgICAgICAgIGlmIChsaW5lLnRyaW0oKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaW5mb3JtYXRpdmUgPSB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaW5mb3JtYXRpdmUpXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gobGluZSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0LmpvaW4oJ1xcbicpXG4gICAgfVxuXG4gICAgc3RhdGljIGV2ZW50KHR5cGU9J21vdXNlJywge2NsaWVudFggPSAwLCBjbGllbnRZID0gMH0gPSB7fSkge1xuICAgICAgICBpZiAodHlwZS5zdGFydHNXaXRoKCdtb3VzZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vdXNlRXZlbnQodHlwZSwgeyBjbGllbnRYLCBjbGllbnRZIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgdHlwZSwgY2xpZW50WCwgY2xpZW50WSB9XG4gICAgfVxuXG4gICAgc3RhdGljIHJ1bihyZXBsYWNlRXhwZWN0PWZhbHNlKSB7XG4gICAgICAgIGlmICh0eXBlb2YoaGxqcykgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGhsanMuaW5pdEhpZ2hsaWdodGluZygpXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGRvY3Rlc3RzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmRvY3Rlc3QnKVxuICAgICAgICBmb3IobGV0IGk9MDsgaTxkb2N0ZXN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGRvY3Rlc3QgPSBkb2N0ZXN0c1tpXVxuICAgICAgICAgICAgbGV0IGNvZGUgPSB0aGlzLnN0cmlwTGVhZGluZ0xpbmVzKGRvY3Rlc3QuaW5uZXJIVE1MKVxuICAgICAgICAgICAgbGV0IHRleHQgPSB0aGlzLmhpZ2hsaWdodChjb2RlKVxuICAgICAgICAgICAgbGV0IHByZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ByZScpXG4gICAgICAgICAgICAvLyBTZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDY4MjgwL2phdmFzY3JpcHQtcmVnZXgtbXVsdGlsaW5lLWZsYWctZG9lc250LXdvcmtcbiAgICAgICAgICAgIC8vIGxldCByZSA9IC9Eb2N0ZXN0XFwuZXhwZWN0XFwoKFtcXHNcXFNdKilbXFwsXFxzXFxTXSooW1xcc1xcU10qKVxcKS9nXG4gICAgICAgICAgICBsZXQgbGluZXMgPSB0ZXh0LnZhbHVlLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgbGV0IGJldHRlciA9IFtdXG4gICAgICAgICAgICBmb3IobGV0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVwbGFjZUV4cGVjdCAmJiBsaW5lLnRyaW0oKS5zdGFydHNXaXRoKCdEb2N0ZXN0LmV4cGVjdCgnKSkge1xuICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGluZS5yZXBsYWNlKC9Eb2N0ZXN0XFwuZXhwZWN0XFwoLywgJz4+PiAnKS50cmltKClcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmUuZW5kc1dpdGgoJyknKSB8fCBsaW5lLmVuZHNXaXRoKCcsJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lLnNsaWNlKDAsIC0xKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJldHRlci5wdXNoKGxpbmUpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmUuaW5uZXJIVE1MID0gYmV0dGVyLmpvaW4oJ1xcbicpIC8vIHRleHQudmFsdWUucmVwbGFjZShyZSwgXCI+Pj4gJDFcXG4kMlwiKVxuICAgICAgICAgICAgZG9jdGVzdC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChwcmUsIGRvY3Rlc3QpXG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIE5lZWRlZCB0byBtYWtlIERvY3Rlc3QgdmlzaWJsZSBpbiBtb2R1bGVzXG4vL3dpbmRvdy5Eb2N0ZXN0ID0gRG9jdGVzdFxuIiwidmFyIHJlY29yZGVkRXJyb3JzID0gbmV3IE1hcCgpXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVycm9ycyB7XG5cbiAgICBzdGF0aWMgY291bnRFcnJvcnMoKSB7XG4gICAgICAgIGxldCB0b3RhbCA9IDBcbiAgICAgICAgZm9yKGxldCBlcnJvciBvZiByZWNvcmRlZEVycm9ycy5rZXlzKCkpIHtcbiAgICAgICAgICAgIHRvdGFsICs9IHJlY29yZGVkRXJyb3JzLmdldChlcnJvcikuc2l6ZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0b3RhbFxuICAgIH1cblxuICAgIHN0YXRpYyBzZXRTdHlsZShlbGVtZW50LCBzdHlsZXMpIHtcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gc3R5bGVzKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW2tleV0gPSBzdHlsZXNba2V5XVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIGFwcGVuZEVycm9yKGVycm9yLCBzb3VyY2UpIHtcbiAgICAgICAgaWYgKHJlY29yZGVkRXJyb3JzLmhhcyhlcnJvcikpIHtcbiAgICAgICAgICAgIGxldCBzb3VyY2VzID0gcmVjb3JkZWRFcnJvcnMuZ2V0KGVycm9yKVxuICAgICAgICAgICAgc291cmNlcy5hZGQoc291cmNlKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVjb3JkZWRFcnJvcnMuc2V0KGVycm9yLCBuZXcgU2V0KFtzb3VyY2VdKSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBzaG93RXJyb3JzKCkge1xuICAgICAgICBpZiAodGhpcy5jb3VudEVycm9ycygpID09IDApIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGxldCBlcnJvcnMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncnVudGltZS1lcnJvcnMnKVxuICAgICAgICBpZiAoZXJyb3JzID09IG51bGwpIHtcbiAgICAgICAgICAgIGVycm9ycyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgICAgICAgICBlcnJvcnMuc2V0QXR0cmlidXRlKCdpZCcsICdydW50aW1lLWVycm9ycycpXG4gICAgICAgICAgICB0aGlzLnNldFN0eWxlKGRvY3VtZW50LmJvZHksIHtcbiAgICAgICAgICAgICAgICBib3JkZXI6ICcycHggc29saWQgcmVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuc2V0U3R5bGUoZXJyb3JzLCB7cG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgdG9wOiAnMHB4JyxcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAnOHB4JyxcbiAgICAgICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICdyZWQnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiAnd2hpdGUnfSlcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZXJyb3JzKVxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAgICAgICAgY291bnRlci5zZXRBdHRyaWJ1dGUoJ2lkJywgJ3J1bnRpbWUtZXJyb3JzLWNvdW50ZXInKVxuICAgICAgICAgICAgdGhpcy5zZXRTdHlsZShjb3VudGVyLCB7Ym9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgICAgICB3aWR0aDogJzMycHgnLFxuICAgICAgICAgICAgICAgIGhlaWdodDogJzMycHgnLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICd3aGl0ZScsXG4gICAgICAgICAgICAgICAgY29sb3I6ICdyZWQnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMThweCcsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBsaW5lSGVpZ2h0OiAnMzJweCcsXG4gICAgICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZSd9KVxuICAgICAgICAgICAgY291bnRlci5pbm5lckhUTUwgPSAnMSdcbiAgICAgICAgICAgIGVycm9ycy5hcHBlbmRDaGlsZChjb3VudGVyKVxuXG4gICAgICAgICAgICBsZXQgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgICAgIHRoaXMuc2V0U3R5bGUoaGVhZGVyLCB7cG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgdG9wOiAnNnB4JyxcbiAgICAgICAgICAgICAgICBsZWZ0OiAnNDhweCcsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAnNDRweCcsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6ICczMnB4J30pXG4gICAgICAgICAgICBoZWFkZXIuaW5uZXJIVE1MID0gJ1J1bnRpbWUgRXJyb3JzJ1xuICAgICAgICAgICAgZXJyb3JzLmFwcGVuZENoaWxkKGhlYWRlcilcbiAgICAgICAgICAgIGVycm9ycy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMudG9nZ2xlRXJyb3JzLmJpbmQodGhpcykpXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNvdW50ZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncnVudGltZS1lcnJvcnMtY291bnRlcicpXG4gICAgICAgIGNvdW50ZXIuaW5uZXJIVE1MID0gdGhpcy5jb3VudEVycm9ycygpXG4gICAgfVxuXG4gICAgc3RhdGljIGV4cGFuZEVycm9ycygpIHtcbiAgICAgICAgbGV0IGVycm9ycyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdydW50aW1lLWVycm9ycycpXG4gICAgICAgIGZvcihsZXQgZXJyb3Igb2YgcmVjb3JkZWRFcnJvcnMua2V5cygpKSB7XG4gICAgICAgICAgICBmb3IodmFyIHNvdXJjZSBvZiByZWNvcmRlZEVycm9ycy5nZXQoZXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZihzb3VyY2UpID09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZSA9ICdTZWUgY29uc29sZSBmb3IgZGV0YWlscydcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBpbmZvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgICAgICAgICBpbmZvLmNsYXNzTmFtZSA9ICdpbmZvJ1xuICAgICAgICAgICAgICAgIGluZm8uc3R5bGUud29yZFdyYXAgPSAnYnJlYWstd29yZCdcbiAgICAgICAgICAgICAgICBpbmZvLmlubmVySFRNTCA9IGVycm9yICsgYDxici8+PHNtYWxsPiR7c291cmNlfTwvc21hbGw+YFxuICAgICAgICAgICAgICAgIGVycm9ycy5hcHBlbmRDaGlsZChpbmZvKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIHRvZ2dsZUVycm9ycygpIHtcbiAgICAgICAgbGV0IGVycm9ycyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdydW50aW1lLWVycm9ycycpXG4gICAgICAgIGxldCBpbmZvcyA9IGVycm9ycy5xdWVyeVNlbGVjdG9yQWxsKCcuaW5mbycpXG4gICAgICAgIGlmIChpbmZvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpbmZvcy5mb3JFYWNoKChpbmZvKSA9PiBlcnJvcnMucmVtb3ZlQ2hpbGQoaW5mbykpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmV4cGFuZEVycm9ycygpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgcmVtb3ZlRXJyb3IoZXZlbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3JlbW92ZUVycm9yJywgZXZlbnQpXG4gICAgICAgIGlmIChyZWNvcmRlZEVycm9ycy5oYXMoZXZlbnQuZXJyb3IpKSB7XG4gICAgICAgICAgICBsZXQgc291cmNlcyA9IHJlY29yZGVkRXJyb3JzLmdldChldmVudC5lcnJvcilcbiAgICAgICAgICAgIHNvdXJjZXMuZGVsZXRlKGV2ZW50LnNvdXJjZSlcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzb3VyY2VzJywgc291cmNlcylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyByZWdpc3Rlckdsb2JhbEVycm9ySGFuZGxlcigpIHtcbiAgICAgICAgLy8gUmVnaXN0ZXIgbW9yZSBpbmZvcm1hdGl2ZSBlcnJvciBoYW5kbGVyXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIChldmVudCkgPT4ge1xuICAgICAgICAvLyAgICAgaWYgKHR5cGVvZihldmVudC5lcnJvcikgPT0gJ3VuZGVmaW5lZCcpIHtcbi8vICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJDYXRjaGVkIHVuZGVmaW5lZCBlcnJvclwiLCBldmVudClcbi8vICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYXBwZW5kRXJyb3IoZXZlbnQuZXJyb3IsIGV2ZW50LmZpbGVuYW1lKVxuICAgICAgICB9LCB0cnVlKVxuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0Vycm9ycygpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgc3RhdGljIHJlZ2lzdGVyRnJhbWVBd2FpdEVycm9ycygpIHtcbiAgICAgICAgbGV0IGlmcmFtZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaWZyYW1lJylcbiAgICAgICAgZm9yKGxldCBpPTA7IGk8aWZyYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHRhcmdldCA9IGlmcmFtZXNbaV1cbiAgICAgICAgICAgIHRhcmdldC5pZnJhbWVUaW1lb3V0ID0gc2V0VGltZW91dChcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwZW5kRXJyb3IoJ0Nhbm5vdCBsb2FkIGlmcmFtZScsIHRhcmdldC5zcmMpfSxcbiAgICAgICAgICAgICAgICBmcmFtZUVycm9yVGltZW91dClcbiAgICAgICAgICAgIHRhcmdldC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRhcmdldC5pZnJhbWVUaW1lb3V0KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5FcnJvcnMucmVnaXN0ZXJHbG9iYWxFcnJvckhhbmRsZXIoKVxuIiwiXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFdmVudHMge1xuXG4gICAgc3RhdGljIHN0b3AoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKVxuICAgIH1cblxuICAgIHN0YXRpYyBleHRyYWN0UG9pbnQoZXZlbnQpIHtcbiAgICAgICAgc3dpdGNoIChldmVudC5jb25zdHJ1Y3Rvci5uYW1lKSB7XG4gICAgICAgICAgICBjYXNlICdUb3VjaEV2ZW50JzpcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50LnRhcmdldFRvdWNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHQgPSBldmVudC50YXJnZXRUb3VjaGVzW2ldXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHg6IHQuY2xpZW50WCwgeTogdC5jbGllbnRZIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgeDogZXZlbnQuY2xpZW50WCwgeTogZXZlbnQuY2xpZW50WSB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgaXNDYXB0dXJlZChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuX19jYXB0dXJlZEJ5KVxuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgc3RhdGljIGNhcHR1cmVkQnkoZXZlbnQsIG9iaikge1xuICAgICAgICBldmVudC5fX2NhcHR1cmVkQnkgPSBvYmpcbiAgICB9XG5cbiAgICBzdGF0aWMgaXNNb3VzZURvd24oZXZlbnQpIHtcbiAgICAgICAgLy8gQXR0ZW1wdHMgdG8gY2xvbmUgdGhlIHdoaWNoIGF0dHJpYnV0ZSBvZiBldmVudHMgZmFpbGVkIGluIFdlYktpdC4gTWF5XG4gICAgICAgIC8vIGJlIHRoaXMgaXMgYSBidWcgb3IgYSBzZWN1cml0eSBmZWF0dXJlLiBXb3JrYXJvdW5kOiB3ZSBpbnRyb2R1Y2VcbiAgICAgICAgLy8gYSBtb3VzZURvd25TdWJzdGl0dXRlIGF0dHJpYnV0ZSB0aGF0IGNhbiBiZSBhc3NpZ25lZCB0byBjbG9uZWRcbiAgICAgICAgLy8gZXZlbnRzIGFmdGVyIGluc3RhbnRpYXRpb24uXG4gICAgICAgIGlmIChSZWZsZWN0LmhhcyhldmVudCwgJ21vdXNlRG93blN1YnN0aXR1dGUnKSlcbiAgICAgICAgICAgIHJldHVybiBldmVudC5tb3VzZURvd25TdWJzdGl0dXRlXG4gICAgICAgIHJldHVybiBldmVudC5idXR0b25zIHx8IGV2ZW50LndoaWNoXG4gICAgfVxuXG4gICAgc3RhdGljIGlzU2ltdWxhdGVkRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIFJlZmxlY3QuaGFzKGV2ZW50LCAnbW91c2VEb3duU3Vic3RpdHV0ZScpXG4gICAgfVxuXG4gICAgc3RhdGljIGlzTW91c2VSaWdodENsaWNrKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBldmVudC5idXR0b25zIHx8IGV2ZW50LndoaWNoXG4gICAgfVxuXG4gICAgc3RhdGljIGV4dHJhY3RUb3VjaGVzKHRhcmdldHMpIHtcbiAgICAgICAgbGV0IHRvdWNoZXMgPSBbXVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB0ID0gdGFyZ2V0c1tpXVxuICAgICAgICAgICAgdG91Y2hlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0YXJnZXRTZWxlY3RvcjogdGhpcy5zZWxlY3Rvcih0LnRhcmdldCksXG4gICAgICAgICAgICAgICAgaWRlbnRpZmllcjogdC5pZGVudGlmaWVyLFxuICAgICAgICAgICAgICAgIHNjcmVlblg6IHQuc2NyZWVuWCxcbiAgICAgICAgICAgICAgICBzY3JlZW5ZOiB0LnNjcmVlblksXG4gICAgICAgICAgICAgICAgY2xpZW50WDogdC5jbGllbnRYLFxuICAgICAgICAgICAgICAgIGNsaWVudFk6IHQuY2xpZW50WSxcbiAgICAgICAgICAgICAgICBwYWdlWDogdC5wYWdlWCxcbiAgICAgICAgICAgICAgICBwYWdlWTogdC5wYWdlWVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdG91Y2hlc1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVUb3VjaExpc3QodGFyZ2V0cykge1xuICAgICAgICBsZXQgdG91Y2hlcyA9IFtdXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHQgPSB0YXJnZXRzW2ldXG4gICAgICAgICAgICBsZXQgdG91Y2hUYXJnZXQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KHQucGFnZVgsIHQucGFnZVkpXG4gICAgICAgICAgICBsZXQgdG91Y2ggPSBuZXcgVG91Y2godW5kZWZpbmVkLCB0b3VjaFRhcmdldCwgdC5pZGVudGlmaWVyLFxuICAgICAgICAgICAgICAgIHQucGFnZVgsIHQucGFnZVksIHQuc2NyZWVuWCwgdC5zY3JlZW5ZKVxuICAgICAgICAgICAgdG91Y2hlcy5wdXNoKHRvdWNoKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVG91Y2hMaXN0KC4uLnRvdWNoZXMpXG4gICAgfVxuXG4gICAgc3RhdGljIGV4dHJhY3RFdmVudCh0aW1lc3RhbXAsIGV2ZW50KSB7XG4gICAgICAgIGxldCB0YXJnZXRTZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IoZXZlbnQudGFyZ2V0KVxuICAgICAgICBsZXQgaW5mb3MgPSB7XG4gICAgICAgICAgICB0eXBlOiBldmVudC50eXBlLFxuICAgICAgICAgICAgdGltZTogdGltZXN0YW1wLFxuICAgICAgICAgICAgY29uc3RydWN0b3I6IGV2ZW50LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHRhcmdldFNlbGVjdG9yOiB0YXJnZXRTZWxlY3RvcixcbiAgICAgICAgICAgICAgICB2aWV3OiBldmVudC52aWV3LFxuICAgICAgICAgICAgICAgIG1vdXNlRG93blN1YnN0aXR1dGU6IGV2ZW50LmJ1dHRvbnMgfHwgZXZlbnQud2hpY2gsIC8vIHdoaWNoIGNhbm5vdCBiZSBjbG9uZWQgZGlyZWN0bHlcbiAgICAgICAgICAgICAgICBidWJibGVzOiBldmVudC5idWJibGVzLFxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IGV2ZW50LmNhbmNlbGFibGUsXG4gICAgICAgICAgICAgICAgc2NyZWVuWDogZXZlbnQuc2NyZWVuWCxcbiAgICAgICAgICAgICAgICBzY3JlZW5ZOiBldmVudC5zY3JlZW5ZLFxuICAgICAgICAgICAgICAgIGNsaWVudFg6IGV2ZW50LmNsaWVudFgsXG4gICAgICAgICAgICAgICAgY2xpZW50WTogZXZlbnQuY2xpZW50WSxcbiAgICAgICAgICAgICAgICBsYXllclg6IGV2ZW50LmxheWVyWCxcbiAgICAgICAgICAgICAgICBsYXllclk6IGV2ZW50LmxheWVyWSxcbiAgICAgICAgICAgICAgICBwYWdlWDogZXZlbnQucGFnZVgsXG4gICAgICAgICAgICAgICAgcGFnZVk6IGV2ZW50LnBhZ2VZLFxuICAgICAgICAgICAgICAgIGN0cmxLZXk6IGV2ZW50LmN0cmxLZXksXG4gICAgICAgICAgICAgICAgYWx0S2V5OiBldmVudC5hbHRLZXksXG4gICAgICAgICAgICAgICAgc2hpZnRLZXk6IGV2ZW50LnNoaWZ0S2V5LFxuICAgICAgICAgICAgICAgIG1ldGFLZXk6IGV2ZW50Lm1ldGFLZXlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQudHlwZS5zdGFydHNXaXRoKCd0b3VjaCcpKSB7XG4gICAgICAgICAgICAvLyBPbiBTYWZhcmktV2ViS2l0IHRoZSBUb3VjaEV2ZW50IGhhcyBsYXllclgsIGxheWVyWSBjb29yZGluYXRlc1xuICAgICAgICAgICAgbGV0IGRhdGEgPSBpbmZvcy5kYXRhXG4gICAgICAgICAgICBkYXRhLnRhcmdldFRvdWNoZXMgPSB0aGlzLmV4dHJhY3RUb3VjaGVzKGV2ZW50LnRhcmdldFRvdWNoZXMpXG4gICAgICAgICAgICBkYXRhLmNoYW5nZWRUb3VjaGVzID0gdGhpcy5leHRyYWN0VG91Y2hlcyhldmVudC5jaGFuZ2VkVG91Y2hlcylcbiAgICAgICAgICAgIGRhdGEudG91Y2hlcyA9IHRoaXMuZXh0cmFjdFRvdWNoZXMoZXZlbnQudG91Y2hlcylcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQudHlwZS5zdGFydHNXaXRoKCdwb2ludGVyJykpIHtcbiAgICAgICAgICAgIGxldCBkYXRhID0gaW5mb3MuZGF0YVxuICAgICAgICAgICAgZGF0YS5wb2ludGVySWQgPSBldmVudC5wb2ludGVySWRcbiAgICAgICAgICAgIGRhdGEucG9pbnRlclR5cGUgPSBldmVudC5wb2ludGVyVHlwZVxuICAgICAgICB9XG4gICAgICAgIGlmIChFdmVudHMuZGVidWcpIHtcbiAgICAgICAgICAgIEV2ZW50cy5leHRyYWN0ZWQucHVzaCh0aGlzLnRvTGluZShldmVudCkpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluZm9zXG4gICAgfVxuXG4gICAgc3RhdGljIGNsb25lRXZlbnQodHlwZSwgY29uc3RydWN0b3IsIGRhdGEpIHtcbiAgICAgICAgaWYgKHR5cGUuc3RhcnRzV2l0aCgndG91Y2gnKSkge1xuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBmaW5kIHRhcmdldCBmcm9tIGxheWVyWCwgbGF5ZXJZXG4gICAgICAgICAgICAvL3ZhciB0YXJnZXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGRhdGEudGFyZ2V0U2VsZWN0b3IpXG4gICAgICAgICAgICAvLyBlbGVtZW50RnJvbVBvaW50KGRhdGEubGF5ZXJYLCBkYXRhLmxheWVyWSlcbiAgICAgICAgICAgIC8vZGF0YS50YXJnZXQgPSB0YXJnZXRcbiAgICAgICAgICAgIGRhdGEudGFyZ2V0VG91Y2hlcyA9IHRoaXMuY3JlYXRlVG91Y2hMaXN0KGRhdGEudGFyZ2V0VG91Y2hlcylcbiAgICAgICAgICAgIGRhdGEuY2hhbmdlZFRvdWNoZXMgPSB0aGlzLmNyZWF0ZVRvdWNoTGlzdChkYXRhLmNoYW5nZWRUb3VjaGVzKVxuICAgICAgICAgICAgZGF0YS50b3VjaGVzID0gdGhpcy5jcmVhdGVUb3VjaExpc3QoZGF0YS50b3VjaGVzKVxuICAgICAgICB9XG4gICAgICAgIC8vIFdlIG5lZWQgdG8gZmluZCB0YXJnZXQgZnJvbSBwYWdlWCwgcGFnZVkgd2hpY2ggYXJlIG9ubHlcbiAgICAgICAgLy8gYXZhaWxhYmxlIGFmdGVyIGNvbnN0cnVjdGlvbi4gVGhleSBzZWVtIHRvIGdldHRlciBpdGVtcy5cblxuICAgICAgICBsZXQgY2xvbmUgPSBSZWZsZWN0LmNvbnN0cnVjdChjb25zdHJ1Y3RvciwgW3R5cGUsIGRhdGFdKVxuICAgICAgICBjbG9uZS5tb3VzZURvd25TdWJzdGl0dXRlID0gZGF0YS5tb3VzZURvd25TdWJzdGl0dXRlXG4gICAgICAgIHJldHVybiBjbG9uZVxuICAgIH1cblxuICAgIHN0YXRpYyBzaW11bGF0ZUV2ZW50KHR5cGUsIGNvbnN0cnVjdG9yLCBkYXRhKSB7XG4gICAgICAgIGRhdGEudGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihkYXRhLnRhcmdldFNlbGVjdG9yKVxuICAgICAgICBsZXQgY2xvbmUgPSB0aGlzLmNsb25lRXZlbnQodHlwZSwgY29uc3RydWN0b3IsIGRhdGEpXG4gICAgICAgIGlmIChkYXRhLnRhcmdldCAhPSBudWxsKSB7XG4gICAgICAgICAgICBkYXRhLnRhcmdldC5kaXNwYXRjaEV2ZW50KGNsb25lKVxuICAgICAgICB9XG4gICAgICAgIGlmIChFdmVudHMuZGVidWcpIHtcbiAgICAgICAgICAgIEV2ZW50cy5zaW11bGF0ZWQucHVzaCh0aGlzLnRvTGluZShjbG9uZSkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgdG9MaW5lKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBgJHtldmVudC50eXBlfSAjJHtldmVudC50YXJnZXQuaWR9ICR7ZXZlbnQuY2xpZW50WH0gJHtldmVudC5jbGllbnRZfWBcbiAgICAgICAgbGV0IHJlc3VsdCA9IGV2ZW50LnR5cGVcbiAgICAgICAgbGV0IHNlbGVjdG9yID0gdGhpcy5zZWxlY3RvcihldmVudC50YXJnZXQpXG4gICAgICAgIHJlc3VsdCArPSAnIHNlbGVjdG9yOiAnICsgc2VsZWN0b3JcbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldCAhPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSlcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDYW5ub3QgcmVzb2x2ZScsIHNlbGVjdG9yKVxuICAgICAgICBsZXQga2V5cyA9IFsnbGF5ZXJYJywgJ2xheWVyWScsICdwYWdlWCcsICdwYWdlWScsICdjbGllbnRYJywgJ2NsaWVudFknXVxuICAgICAgICBmb3IgKGxldCBrZXkgb2Yga2V5cykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gJyAnICsga2V5ICsgJzonICsgZXZlbnRba2V5XVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnSW52YWxpZCBrZXk6ICcgKyBrZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIHN0YXRpYyBjb21wYXJlRXh0cmFjdGVkV2l0aFNpbXVsYXRlZCgpIHtcbiAgICAgICAgdmFyIGRpZmZzID0gMFxuICAgICAgICBpZiAodGhpcy5leHRyYWN0ZWQubGVuZ3RoICE9IHRoaXMuc2ltdWxhdGVkLmxlbmd0aCkge1xuICAgICAgICAgICAgYWxlcnQoJ1VuZXF1YWwgbGVuZ3RoIG9mIGV4dHJhY3RlZCBbJyArIHRoaXMuZXh0cmFjdGVkLmxlbmd0aCArXG4gICAgICAgICAgICAgICAgJ10gYW5kIHNpbXVsYXRlZCBldmVudHMgWycgKyB0aGlzLnNpbXVsYXRlZC5sZW5ndGggKyAnXS4nKVxuICAgICAgICAgICAgZGlmZnMgKz0gMVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmV4dHJhY3RlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBleHRyYWN0ZWQgPSB0aGlzLmV4dHJhY3RlZFtpXVxuICAgICAgICAgICAgICAgIHZhciBzaW11bGF0ZWQgPSB0aGlzLnNpbXVsYXRlZFtpXVxuICAgICAgICAgICAgICAgIGlmIChleHRyYWN0ZWQgIT0gc2ltdWxhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdFdmVudHMgZGlmZmVyOicgKyBleHRyYWN0ZWQgKyAnfCcgKyBzaW11bGF0ZWQpXG4gICAgICAgICAgICAgICAgICAgIGRpZmZzICs9IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgc2VsZWN0b3IoY29udGV4dCkge1xuICAgICAgICByZXR1cm4gT3B0aW1hbFNlbGVjdC5zZWxlY3QoY29udGV4dClcbiAgICB9XG5cbiAgICBzdGF0aWMgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuZXh0cmFjdGVkID0gW11cbiAgICAgICAgdGhpcy5zaW11bGF0ZWQgPSBbXVxuICAgIH1cblxuICAgIHN0YXRpYyByZXNldFNpbXVsYXRlZCgpIHtcbiAgICAgICAgdGhpcy5zaW11bGF0ZWQgPSBbXVxuICAgIH1cblxuICAgIHN0YXRpYyBzaG93RXh0cmFjdGVkRXZlbnRzKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBvcHVwID09IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgICAgIEVsZW1lbnRzLnNldFN0eWxlKGVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICAgICB3aWR0aDogJzQ4MHB4JyxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6ICc2NDBweCcsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICdsaWdodGdyYXknXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbGVtZW50KVxuICAgICAgICAgICAgdGhpcy5wb3B1cCA9IGVsZW1lbnRcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBvcHVwLmlubmVySFRNTCA9ICcnXG4gICAgICAgIGZvciAobGV0IGxpbmUgb2YgdGhpcy5leHRyYWN0ZWQpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAgICAgICAgZGl2LmlubmVySFRNTCA9IGxpbmVcbiAgICAgICAgICAgIHRoaXMucG9wdXAuYXBwZW5kQ2hpbGQoZGl2KVxuICAgICAgICB9XG4gICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAgICBkaXYuaW5uZXJIVE1MID0gJy0tLS0tLS0tLS0tLSBTaW11bGF0ZWQgLS0tLS0tLS0tLS0nXG4gICAgICAgIHRoaXMucG9wdXAuYXBwZW5kQ2hpbGQoZGl2KVxuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIHRoaXMuc2ltdWxhdGVkKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgICAgIGRpdi5pbm5lckhUTUwgPSBsaW5lXG4gICAgICAgICAgICB0aGlzLnBvcHVwLmFwcGVuZENoaWxkKGRpdilcbiAgICAgICAgfVxuICAgICAgICBFbGVtZW50cy5zZXRTdHlsZSh0aGlzLnBvcHVwLFxuICAgICAgICAgICAgeyBsZWZ0OiBldmVudC5jbGllbnRYICsgJ3B4JywgdG9wOiBldmVudC5jbGllbnRZICsgJ3B4JyB9KVxuICAgIH1cbn1cblxuRXZlbnRzLnBvcHVwID0gbnVsbFxuRXZlbnRzLmRlYnVnID0gdHJ1ZVxuRXZlbnRzLmV4dHJhY3RlZCA9IFtdXG5FdmVudHMuc2ltdWxhdGVkID0gW11cbkV2ZW50cy5zaW11bGF0aW9uUnVubmluZyA9IGZhbHNlXG5cbmV4cG9ydCBjbGFzcyBFdmVudFJlY29yZGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnJlY29yZGluZyA9IFtdXG4gICAgICAgIHRoaXMucmVjb3JkZWQgPSBbXVxuICAgICAgICB0aGlzLnN0ZXAgPSAwXG4gICAgfVxuXG4gICAgcmVjb3JkKGV2ZW50KSB7XG4gICAgICAgIGxldCBsZW5ndGggPSB0aGlzLnJlY29yZGluZy5sZW5ndGhcbiAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0VGltZSA9IGV2ZW50LnRpbWVTdGFtcFxuICAgICAgICAgICAgRXZlbnRzLnJlc2V0KClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBsYXN0ID0gdGhpcy5yZWNvcmRpbmdbbGVuZ3RoIC0gMV1cbiAgICAgICAgICAgIGlmIChldmVudC50aW1lU3RhbXAgPCBsYXN0LnRpbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnd2FybmluZzogd3JvbmcgdGVtcG9yYWwgb3JkZXInKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCB0ID0gZXZlbnQudGltZVN0YW1wIC0gdGhpcy5zdGFydFRpbWVcbiAgICAgICAgdGhpcy5yZWNvcmRpbmcucHVzaChFdmVudHMuZXh0cmFjdEV2ZW50KHQsIGV2ZW50KSlcbiAgICB9XG5cbiAgICBzdG9wUmVjb3JkaW5nKCkge1xuICAgICAgICB0aGlzLnJlY29yZGVkID0gdGhpcy5yZWNvcmRpbmdcbiAgICAgICAgdGhpcy5yZWNvcmRpbmcgPSBbXVxuICAgICAgICBjb25zb2xlLmxvZygnUmVjb3JkZWQgJyArIHRoaXMucmVjb3JkZWQubGVuZ3RoICsgJyBldmVudHMnKVxuICAgIH1cblxuICAgIHN0YXJ0UmVwbGF5KHdoaWxlQ29uZGl0aW9uID0gbnVsbCwgb25Db21wbGV0ZSA9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zdGVwID0gMFxuICAgICAgICBFdmVudHMucmVzZXRTaW11bGF0ZWQoKVxuICAgICAgICBjb25zb2xlLmxvZygnU3RhcnQgcmVwbGF5JylcbiAgICAgICAgRXZlbnRzLnNpbXVsYXRpb25SdW5uaW5nID0gdHJ1ZVxuICAgICAgICB0aGlzLnJlcGxheSh3aGlsZUNvbmRpdGlvbiwgb25Db21wbGV0ZSlcbiAgICB9XG5cbiAgICByZXBsYXkod2hpbGVDb25kaXRpb24gPSBudWxsLCBvbkNvbXBsZXRlID0gbnVsbCkge1xuICAgICAgICBpZiAodGhpcy5zdGVwIDwgdGhpcy5yZWNvcmRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGxldCB7IHR5cGUsIHRpbWUsIGNvbnN0cnVjdG9yLCBkYXRhIH0gPSB0aGlzLnJlY29yZGVkW3RoaXMuc3RlcF1cbiAgICAgICAgICAgIEV2ZW50cy5zaW11bGF0ZUV2ZW50KHR5cGUsIGNvbnN0cnVjdG9yLCBkYXRhKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnN0ZXAgKz0gMVxuICAgICAgICAgICAgbGV0IGR0ID0gMFxuICAgICAgICAgICAgaWYgKHRoaXMuc3RlcCA8IHRoaXMucmVjb3JkZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5leHQgPSB0aGlzLnJlY29yZGVkW3RoaXMuc3RlcF1cbiAgICAgICAgICAgICAgICBkdCA9IG5leHQudGltZSAtIHRpbWVcbiAgICAgICAgICAgICAgICBpZiAoZHQgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCd3YXJuaW5nOiB3cm9uZyB0ZW1wb3JhbCBvcmRlcicpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHdoaWxlQ29uZGl0aW9uID09IG51bGwgfHwgd2hpbGVDb25kaXRpb24oKSkge1xuICAgICAgICAgICAgICAgIGxldCBkZWx0YSA9IE1hdGgucm91bmQoZHQpXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlcGxheSh3aGlsZUNvbmRpdGlvbiwgb25Db21wbGV0ZSksIGRlbHRhKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1BsYXllZCAnICsgdGhpcy5zdGVwICsgJyBldmVudHMnICsgb25Db21wbGV0ZSlcbiAgICAgICAgICAgIEV2ZW50cy5zaW11bGF0aW9uUnVubmluZyA9IGZhbHNlXG4gICAgICAgICAgICBpZiAob25Db21wbGV0ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgb25Db21wbGV0ZSgpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvL0V2ZW50cy5jb21wYXJlRXh0cmFjdGVkV2l0aFNpbXVsYXRlZCgpXG4gICAgICAgIH1cbiAgICB9XG59XG5cbiIsIi8qIGdsb2JhbHMgV2ViS2l0UG9pbnQgKi9cblxuLyoqIFRlc3RzIHdoZXRoZXIgYW4gb2JqZWN0IGlzIGVtcHR5XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIC0gdGhlIG9iamVjdCB0byBiZSB0ZXN0ZWRcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VtcHR5KG9iaikge1xuICAgIC8vID4gaXNFbXB0eSh7fSlcbiAgICAvLyB0cnVlXG4gICAgZm9yIChsZXQgaSBpbiBvYmopIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG59XG5cbi8qKiBSZXR1cm5zIGEgdW5pdmVyc2FsIHVuaXF1ZSBpZFxuICogQHJldHVybiB7c3RyaW5nfVxuICogU2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNTAzNC9jcmVhdGUtZ3VpZC11dWlkLWluLWphdmFzY3JpcHQvMjE5NjMxMzYjMjE5NjMxMzZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHV1aWQoKSB7XG4gICAgcmV0dXJuICd4eHh4eHh4eC14eHh4LTR4eHgteXh4eC14eHh4eHh4eHh4eHgnLnJlcGxhY2UoL1t4eV0vZywgYyA9PiB7XG4gICAgICAgIGxldCByID0gKE1hdGgucmFuZG9tKCkgKiAxNikgfCAwLFxuICAgICAgICAgICAgdiA9IGMgPT0gJ3gnID8gciA6IChyICYgMHgzKSB8IDB4OFxuICAgICAgICByZXR1cm4gdi50b1N0cmluZygxNilcbiAgICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbGVycChzdGFydCwgc3RvcCwgYW10KSB7XG4gICAgcmV0dXJuIGFtdCAqIChzdG9wIC0gc3RhcnQpICsgc3RhcnRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbXBsZShwb3B1bGF0aW9uLCBrKSB7XG4gICAgLypcbiAgICAgICAgRnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xOTI2OTU0NS9ob3ctdG8tZ2V0LW4tbm8tZWxlbWVudHMtcmFuZG9tbHktZnJvbS1hbi1hcnJheS8zODU3MTEzMlxuICAgICAgICBcbiAgICAgICAgQ2hvb3NlcyBrIHVuaXF1ZSByYW5kb20gZWxlbWVudHMgZnJvbSBhIHBvcHVsYXRpb24gc2VxdWVuY2Ugb3Igc2V0LlxuXG4gICAgICAgIFJldHVybnMgYSBuZXcgbGlzdCBjb250YWluaW5nIGVsZW1lbnRzIGZyb20gdGhlIHBvcHVsYXRpb24gd2hpbGVcbiAgICAgICAgbGVhdmluZyB0aGUgb3JpZ2luYWwgcG9wdWxhdGlvbiB1bmNoYW5nZWQuICBUaGUgcmVzdWx0aW5nIGxpc3QgaXNcbiAgICAgICAgaW4gc2VsZWN0aW9uIG9yZGVyIHNvIHRoYXQgYWxsIHN1Yi1zbGljZXMgd2lsbCBhbHNvIGJlIHZhbGlkIHJhbmRvbVxuICAgICAgICBzYW1wbGVzLiAgVGhpcyBhbGxvd3MgcmFmZmxlIHdpbm5lcnMgKHRoZSBzYW1wbGUpIHRvIGJlIHBhcnRpdGlvbmVkXG4gICAgICAgIGludG8gZ3JhbmQgcHJpemUgYW5kIHNlY29uZCBwbGFjZSB3aW5uZXJzICh0aGUgc3Vic2xpY2VzKS5cblxuICAgICAgICBNZW1iZXJzIG9mIHRoZSBwb3B1bGF0aW9uIG5lZWQgbm90IGJlIGhhc2hhYmxlIG9yIHVuaXF1ZS4gIElmIHRoZVxuICAgICAgICBwb3B1bGF0aW9uIGNvbnRhaW5zIHJlcGVhdHMsIHRoZW4gZWFjaCBvY2N1cnJlbmNlIGlzIGEgcG9zc2libGVcbiAgICAgICAgc2VsZWN0aW9uIGluIHRoZSBzYW1wbGUuXG5cbiAgICAgICAgVG8gY2hvb3NlIGEgc2FtcGxlIGluIGEgcmFuZ2Ugb2YgaW50ZWdlcnMsIHVzZSByYW5nZSBhcyBhbiBhcmd1bWVudC5cbiAgICAgICAgVGhpcyBpcyBlc3BlY2lhbGx5IGZhc3QgYW5kIHNwYWNlIGVmZmljaWVudCBmb3Igc2FtcGxpbmcgZnJvbSBhXG4gICAgICAgIGxhcmdlIHBvcHVsYXRpb246ICAgc2FtcGxlKHJhbmdlKDEwMDAwMDAwKSwgNjApXG5cbiAgICAgICAgU2FtcGxpbmcgd2l0aG91dCByZXBsYWNlbWVudCBlbnRhaWxzIHRyYWNraW5nIGVpdGhlciBwb3RlbnRpYWxcbiAgICAgICAgc2VsZWN0aW9ucyAodGhlIHBvb2wpIGluIGEgbGlzdCBvciBwcmV2aW91cyBzZWxlY3Rpb25zIGluIGEgc2V0LlxuXG4gICAgICAgIFdoZW4gdGhlIG51bWJlciBvZiBzZWxlY3Rpb25zIGlzIHNtYWxsIGNvbXBhcmVkIHRvIHRoZVxuICAgICAgICBwb3B1bGF0aW9uLCB0aGVuIHRyYWNraW5nIHNlbGVjdGlvbnMgaXMgZWZmaWNpZW50LCByZXF1aXJpbmdcbiAgICAgICAgb25seSBhIHNtYWxsIHNldCBhbmQgYW4gb2NjYXNpb25hbCByZXNlbGVjdGlvbi4gIEZvclxuICAgICAgICBhIGxhcmdlciBudW1iZXIgb2Ygc2VsZWN0aW9ucywgdGhlIHBvb2wgdHJhY2tpbmcgbWV0aG9kIGlzXG4gICAgICAgIHByZWZlcnJlZCBzaW5jZSB0aGUgbGlzdCB0YWtlcyBsZXNzIHNwYWNlIHRoYW4gdGhlXG4gICAgICAgIHNldCBhbmQgaXQgZG9lc24ndCBzdWZmZXIgZnJvbSBmcmVxdWVudCByZXNlbGVjdGlvbnMuXG4gICAgKi9cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShwb3B1bGF0aW9uKSlcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlBvcHVsYXRpb24gbXVzdCBiZSBhbiBhcnJheS5cIilcbiAgICBsZXQgbiA9IHBvcHVsYXRpb24ubGVuZ3RoXG4gICAgaWYgKGsgPCAwIHx8IGsgPiBuKVxuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlNhbXBsZSBsYXJnZXIgdGhhbiBwb3B1bGF0aW9uIG9yIGlzIG5lZ2F0aXZlXCIpXG5cbiAgICBsZXQgcmVzdWx0ID0gbmV3IEFycmF5KGspXG4gICAgbGV0IHNldHNpemUgPSAyMSAgIC8vIHNpemUgb2YgYSBzbWFsbCBzZXQgbWludXMgc2l6ZSBvZiBhbiBlbXB0eSBsaXN0XG5cbiAgICBpZiAoayA+IDUpXG4gICAgICAgIHNldHNpemUgKz0gTWF0aC5wb3coNCwgTWF0aC5jZWlsKE1hdGgubG9nKGsgKiAzLCA0KSkpXG5cbiAgICBpZiAobiA8PSBzZXRzaXplKSB7XG4gICAgICAgIC8vIEFuIG4tbGVuZ3RoIGxpc3QgaXMgc21hbGxlciB0aGFuIGEgay1sZW5ndGggc2V0XG4gICAgICAgIGxldCBwb29sID0gcG9wdWxhdGlvbi5zbGljZSgpXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgazsgaSsrKSB7ICAgICAgICAgIC8vIGludmFyaWFudDogIG5vbi1zZWxlY3RlZCBhdCBbMCxuLWkpXG4gICAgICAgICAgICBsZXQgaiA9IE1hdGgucmFuZG9tKCkgKiAobiAtIGkpIHwgMFxuICAgICAgICAgICAgcmVzdWx0W2ldID0gcG9vbFtqXVxuICAgICAgICAgICAgcG9vbFtqXSA9IHBvb2xbbiAtIGkgLSAxXSAgICAgICAvLyBtb3ZlIG5vbi1zZWxlY3RlZCBpdGVtIGludG8gdmFjYW5jeVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IHNlbGVjdGVkID0gbmV3IFNldCgpXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgazsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgaiA9IE1hdGgucmFuZG9tKCkgKiAobiAtIGkpIHwgMFxuICAgICAgICAgICAgd2hpbGUgKHNlbGVjdGVkLmhhcyhqKSkge1xuICAgICAgICAgICAgICAgIGogPSBNYXRoLnJhbmRvbSgpICogKG4gLSBpKSB8IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGVjdGVkLmFkZChqKVxuICAgICAgICAgICAgcmVzdWx0W2ldID0gcG9wdWxhdGlvbltqXVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdFxufVxuXG5cbi8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgYXMgbG9uZyBhcyBpdCBjb250aW51ZXMgdG8gYmUgaW52b2tlZCwgd2lsbCBub3Rcbi8vIGJlIHRyaWdnZXJlZC4gVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGl0IHN0b3BzIGJlaW5nIGNhbGxlZCBmb3Jcbi8vIE4gbWlsbGlzZWNvbmRzLiBJZiBgaW1tZWRpYXRlYCBpcyBwYXNzZWQsIHRyaWdnZXIgdGhlIGZ1bmN0aW9uIG9uIHRoZVxuLy8gbGVhZGluZyBlZGdlLCBpbnN0ZWFkIG9mIHRoZSB0cmFpbGluZy5cbi8vIFRha2VuIGZyb206IGh0dHBzOi8vZGF2aWR3YWxzaC5uYW1lL2Vzc2VudGlhbC1qYXZhc2NyaXB0LWZ1bmN0aW9uc1xuZXhwb3J0IGZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQsIGltbWVkaWF0ZSkge1xuICAgIGxldCB0aW1lb3V0XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGNvbnRleHQgPSB0aGlzLFxuICAgICAgICAgICAgYXJncyA9IGFyZ3VtZW50c1xuICAgICAgICBsZXQgbGF0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aW1lb3V0ID0gbnVsbFxuICAgICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncylcbiAgICAgICAgfVxuICAgICAgICBsZXQgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhdGltZW91dFxuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpXG4gICAgICAgIGlmIChjYWxsTm93KSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpXG4gICAgfVxufVxuXG4vKiogUmV0dXJucyBhbiBpZCB0aGF0IGlzIGd1YXJhbnRlZWQgdG8gYmUgdW5pcXVlIHdpdGhpbiB0aGUgbGl2ZXRpbWUgb2YgdGhlXG4gKiBhcHBsaWNhdGlvblxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5sZXQgX2lkR2VuZXJhdG9yID0gMFxuZXhwb3J0IGZ1bmN0aW9uIGdldElkKCkge1xuICAgIHJldHVybiAnaWQnICsgX2lkR2VuZXJhdG9yKytcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbUludChtaW4gPSAwLCBtYXggPSAxMDApIHtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpICsgbWluKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tRmxvYXQobWluID0gMC4wLCBtYXggPSAxLjApIHtcbiAgICByZXR1cm4gTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4pICsgbWluXG59XG5cbmV4cG9ydCBjbGFzcyBEYXRlcyB7XG5cbiAgICBzdGF0aWMgY3JlYXRlKGZ1bGxZZWFyLCBtb250aCwgZGF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyhmdWxsWWVhciwgbW9udGgsIGRheSkpXG4gICAgfVxuXG4gICAgc3RhdGljIGRheXNJbk1vbnRoKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpICsgMSwgMCkuZ2V0RGF0ZSgpXG4gICAgfVxuXG4gICAgc3RhdGljIHN0YXJ0WWVhclJhbmdlKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKGRhdGUuZ2V0RnVsbFllYXIoKSAtIDEsIDExLCAzMSwgMjMsIDU5LCA1OSwgOTk5KSlcbiAgICB9XG5cbiAgICBzdGF0aWMgZW5kWWVhclJhbmdlKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKGRhdGUuZ2V0RnVsbFllYXIoKSArIDEsIDAsIDEpKVxuICAgIH1cblxuICAgIHN0YXRpYyBwcmV2WWVhcihkYXRlLCBvZmZzZXQgPSAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZShkYXRlLmdldEZ1bGxZZWFyKCkgLSBvZmZzZXQsIDAsIDEpXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHRZZWFyKGRhdGUsIG9mZnNldCA9IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSArIG9mZnNldCwgMCwgMSlcbiAgICB9XG5cbiAgICBzdGF0aWMgbmV4dE1vbnRoKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpICsgMSwgMSlcbiAgICB9XG5cbiAgICBzdGF0aWMgbmV4dERheShkYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgICAgICAgIGRhdGUuZ2V0RnVsbFllYXIoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0TW9udGgoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0RGF0ZSgpICsgMVxuICAgICAgICApXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHRIb3VyKGRhdGUpIHtcbiAgICAgICAgLy8gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA1MDcyMC9hZGRpbmctaG91cnMtdG8tamF2YXNjcmlwdC1kYXRlLW9iamVjdFxuICAgICAgICByZXR1cm4gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkgKyA2MCAqIDYwICogMTAwMClcbiAgICB9XG5cbiAgICBzdGF0aWMgbmV4dE1pbnV0ZShkYXRlKSB7XG4gICAgICAgIC8vIFNlZSBhYm92ZVxuICAgICAgICByZXR1cm4gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkgKyA2MCAqIDEwMDApXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHRTZWNvbmQoZGF0ZSkge1xuICAgICAgICAvLyBTZWUgYWJvdmVcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpICsgMTAwMClcbiAgICB9XG5cbiAgICBzdGF0aWMgbmV4dE1pbGxpc2Vjb25kKGRhdGUpIHtcbiAgICAgICAgLy8gU2VlIGFib3ZlXG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSArIDEpXG4gICAgfVxuXG4gICAgc3RhdGljICppdGVyWWVhcnMoc3RhcnQsIGVuZCkge1xuICAgICAgICBsZXQgZGF0ZSA9IHRoaXMuY3JlYXRlKHN0YXJ0LmdldEZ1bGxZZWFyKCksIDAsIDEpXG4gICAgICAgIHdoaWxlIChkYXRlIDw9IGVuZCkge1xuICAgICAgICAgICAgeWllbGQgZGF0ZVxuICAgICAgICAgICAgZGF0ZSA9IHRoaXMubmV4dFllYXIoZGF0ZSlcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCBkYXRlXG4gICAgfVxuXG4gICAgc3RhdGljICppdGVyTW9udGhzKHllYXIsIGxpbWl0ID0gMTIpIHtcbiAgICAgICAgbGV0IG1vbnRoID0gMFxuICAgICAgICB3aGlsZSAobW9udGggPCBsaW1pdCkge1xuICAgICAgICAgICAgbGV0IGRhdGUgPSB0aGlzLmNyZWF0ZSh5ZWFyLmdldEZ1bGxZZWFyKCksIG1vbnRoLCAxKVxuICAgICAgICAgICAgeWllbGQgZGF0ZVxuICAgICAgICAgICAgbW9udGggKz0gMVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljICppdGVyTW9udGhzT2ZZZWFycyh5ZWFycykge1xuICAgICAgICBmb3IgKGxldCB5ZWFyIG9mIHllYXJzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBtb250aCBvZiB0aGlzLml0ZXJNb250aHMoeWVhcikpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBtb250aFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljICppdGVyRGF5cyhtb250aCkge1xuICAgICAgICBsZXQgZGF5ID0gMVxuICAgICAgICBsZXQgbGltaXQgPSBEYXRlcy5kYXlzSW5Nb250aChtb250aClcbiAgICAgICAgd2hpbGUgKGRheSA8PSBsaW1pdCkge1xuICAgICAgICAgICAgbGV0IGRhdGUgPSB0aGlzLmNyZWF0ZShtb250aC5nZXRGdWxsWWVhcigpLCBtb250aC5nZXRNb250aCgpLCBkYXkpXG4gICAgICAgICAgICB5aWVsZCBkYXRlXG4gICAgICAgICAgICBkYXkgKz0gMVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljICppdGVyRGF5c09mTW9udGhzKG1vbnRocykge1xuICAgICAgICBmb3IgKGxldCBtb250aCBvZiBtb250aHMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGRheSBvZiB0aGlzLml0ZXJEYXlzKG1vbnRoKSkge1xuICAgICAgICAgICAgICAgIHlpZWxkIGRheVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLyogQ29sb3IgY29udmVyc2lvbiBmdW5jdGlvbnMgKi9cblxuZXhwb3J0IGNsYXNzIENvbG9ycyB7XG4gICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81NjIzODM4L3JnYi10by1oZXgtYW5kLWhleC10by1yZ2JcblxuICAgIHN0YXRpYyByZ2IybnVtKHJlZCwgZ3JlZW4sIGJsdWUpIHtcbiAgICAgICAgbGV0IHJnYiA9IGJsdWUgfCAoZ3JlZW4gPDwgOCkgfCAocmVkIDw8IDE2KVxuICAgICAgICByZXR1cm4gMHgwMDAwMDAgKyByZ2JcbiAgICB9XG5cbiAgICBzdGF0aWMgcmdiMmhleChyZWQsIGdyZWVuLCBibHVlKSB7XG4gICAgICAgIGxldCByZ2IgPSBibHVlIHwgKGdyZWVuIDw8IDgpIHwgKHJlZCA8PCAxNilcbiAgICAgICAgcmV0dXJuICcjJyArICgweDEwMDAwMDAgKyByZ2IpLnRvU3RyaW5nKDE2KS5zbGljZSgxKVxuICAgIH1cblxuICAgIHN0YXRpYyBoZXgycmdiKGhleCkge1xuICAgICAgICAvLyBsb25nIHZlcnNpb25cbiAgICAgICAgbGV0IHIgPSBoZXgubWF0Y2goL14jKFswLTlhLWZdezJ9KShbMC05YS1mXXsyfSkoWzAtOWEtZl17Mn0pJC9pKVxuICAgICAgICBpZiAocikge1xuICAgICAgICAgICAgcmV0dXJuIHIuc2xpY2UoMSwgNCkubWFwKHggPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh4LCAxNilcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgLy8gc2hvcnQgdmVyc2lvblxuICAgICAgICByID0gaGV4Lm1hdGNoKC9eIyhbMC05YS1mXSkoWzAtOWEtZl0pKFswLTlhLWZdKSQvaSlcbiAgICAgICAgaWYgKHIpIHtcbiAgICAgICAgICAgIHJldHVybiByLnNsaWNlKDEsIDQpLm1hcCh4ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMHgxMSAqIHBhcnNlSW50KHgsIDE2KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIHN0YXRpYyByZ2IociwgZywgYikge1xuICAgICAgICByZXR1cm4geyByLCBnLCBiIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgc3RyaW5nMmhleChzdHIpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KCcweCcgKyBzdHIuc2xpY2UoMSkpXG4gICAgfVxuXG4gICAgc3RhdGljIGxlcnAocmdiMSwgcmdiMiwgYW1vdW50KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiBNYXRoLnJvdW5kKGxlcnAocmdiMS5yLCByZ2IyLnIsIGFtb3VudCkpLFxuICAgICAgICAgICAgZzogTWF0aC5yb3VuZChsZXJwKHJnYjEuZywgcmdiMi5nLCBhbW91bnQpKSxcbiAgICAgICAgICAgIGI6IE1hdGgucm91bmQobGVycChyZ2IxLmIsIHJnYjIuYiwgYW1vdW50KSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBnZXQgdmlvbGV0KCkge1xuICAgICAgICByZXR1cm4gQ29sb3JzLnJnYjJudW0oODksIDM0LCAxMzEpXG4gICAgfVxuXG4gICAgc3RhdGljIGdldCBzdGVlbGJsdWUoKSB7XG4gICAgICAgIHJldHVybiBDb2xvcnMucmdiMm51bSgwLCAxMzAsIDE2NClcbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0IG9jaHJlKCkge1xuICAgICAgICByZXR1cm4gQ29sb3JzLnJnYjJudW0oMTgxLCAxNTcsIDApXG4gICAgfVxuXG4gICAgc3RhdGljIGdldCB0dXJxdW9pc2UoKSB7XG4gICAgICAgIHJldHVybiBDb2xvcnMucmdiMm51bSgzNCwgMTY0LCAxMzEpXG4gICAgfVxuXG4gICAgc3RhdGljIGdldCBlbWluZW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIENvbG9ycy5yZ2IybnVtKDE1MCwgNjAsIDEzNClcbiAgICB9XG5cbiAgICBzdGF0aWMgcmFuZG9tKCkge1xuICAgICAgICBsZXQgciA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDI1NSlcbiAgICAgICAgbGV0IGcgPSBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAyNTUpXG4gICAgICAgIGxldCBiID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogMjU1KVxuICAgICAgICByZXR1cm4gQ29sb3JzLnJnYjJudW0ociwgZywgYilcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBDeWNsZSBleHRlbmRzIEFycmF5IHtcbiAgICBjb25zdHJ1Y3RvciguLi5pdGVtcykge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIGZvciAobGV0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaChpdGVtKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5kZXggPSAwXG4gICAgfVxuXG4gICAgbmV4dCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaW5kZXggPT0gdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXggPSAwXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXNbdGhpcy5pbmRleCsrXVxuICAgIH1cblxuICAgIGN1cnJlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmluZGV4ID09PSB0aGlzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5pbmRleCA9IDBcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpc1t0aGlzLmluZGV4XVxuICAgIH1cbn1cblxuLyoqIFN0YXRpYyBtZXRob2RzIHRvIGNvbXB1dGUgMkQgcG9pbnRzIHdpdGggeCBhbmQgeSBjb29yZGluYXRlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFBvaW50cyB7XG4gICAgc3RhdGljIGxlbmd0aChhKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoYS54ICogYS54ICsgYS55ICogYS55KVxuICAgIH1cblxuICAgIHN0YXRpYyBub3JtYWxpemUocCkge1xuICAgICAgICBsZXQgbGVuID0gdGhpcy5sZW5ndGgocClcbiAgICAgICAgcmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIocCwgMSAvIGxlbilcbiAgICB9XG5cbiAgICBzdGF0aWMgbWVhbihhLCBiKSB7XG4gICAgICAgIHJldHVybiB7IHg6IChhLnggKyBiLngpIC8gMiwgeTogKGEueSArIGIueSkgLyAyIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgc3VidHJhY3QoYSwgYikge1xuICAgICAgICByZXR1cm4geyB4OiBhLnggLSBiLngsIHk6IGEueSAtIGIueSB9XG4gICAgfVxuXG4gICAgc3RhdGljIG11bHRpcGx5KGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHsgeDogYS54ICogYi54LCB5OiBhLnkgKiBiLnkgfVxuICAgIH1cblxuICAgIHN0YXRpYyBkaXZpZGUoYSwgYikge1xuICAgICAgICByZXR1cm4geyB4OiBhLnggLyBiLngsIHk6IGEueSAvIGIueSB9XG4gICAgfVxuXG4gICAgc3RhdGljIG11bHRpcGx5U2NhbGFyKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHsgeDogYS54ICogYiwgeTogYS55ICogYiB9XG4gICAgfVxuXG4gICAgc3RhdGljIGFkZChhLCBiKSB7XG4gICAgICAgIHJldHVybiB7IHg6IGEueCArIGIueCwgeTogYS55ICsgYi55IH1cbiAgICB9XG5cbiAgICBzdGF0aWMgbmVnYXRlKHApIHtcbiAgICAgICAgcmV0dXJuIHsgeDogLXAueCwgeTogLXAueSB9XG4gICAgfVxuXG4gICAgc3RhdGljIGFuZ2xlKHAxLCBwMikge1xuICAgICAgICByZXR1cm4gTWF0aC5hdGFuMihwMS55IC0gcDIueSwgcDEueCAtIHAyLngpXG4gICAgfVxuXG4gICAgc3RhdGljIG5vcm1hbGl6ZWRBbmdsZShwMSwgcDIpIHtcbiAgICAgICAgcmV0dXJuIEFuZ2xlLm5vcm1hbGl6ZSh0aGlzLmFuZ2xlKHAxLCBwMikpXG4gICAgfVxuXG4gICAgc3RhdGljIG5vcm1hbGl6ZWQyQW5nbGUocDEsIHAyKSB7XG4gICAgICAgIHJldHVybiBBbmdsZS5ub3JtYWxpemUyKHRoaXMuYW5nbGUocDEsIHAyKSlcbiAgICB9XG5cbiAgICBzdGF0aWMgYXJjKHAsIGFscGhhLCByYWRpdXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHAueCArIHJhZGl1cyAqIE1hdGguY29zKGFscGhhKSxcbiAgICAgICAgICAgIHk6IHAueSArIHJhZGl1cyAqIE1hdGguc2luKGFscGhhKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIGRpc3RhbmNlKGEsIGIpIHtcbiAgICAgICAgbGV0IGR4ID0gYS54IC0gYi54XG4gICAgICAgIGxldCBkeSA9IGEueSAtIGIueVxuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KVxuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tUGFnZVRvTm9kZShlbGVtZW50LCBwKSB7XG4gICAgICAgIC8vICAgIGlmICh3aW5kb3cud2Via2l0Q29udmVydFBvaW50RnJvbVBhZ2VUb05vZGUpIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy53ZWJraXRDb252ZXJ0UG9pbnRGcm9tUGFnZVRvTm9kZShlbGVtZW50LFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFdlYktpdFBvaW50KHAueCwgcC55KSlcbiAgICAgICAgLy8gICAgICAgICB9XG4gICAgICAgIHJldHVybiB3aW5kb3cuY29udmVydFBvaW50RnJvbVBhZ2VUb05vZGUoZWxlbWVudCwgcC54LCBwLnkpXG4gICAgfVxuXG4gICAgc3RhdGljIGZyb21Ob2RlVG9QYWdlKGVsZW1lbnQsIHApIHtcbiAgICAgICAgLy8gIGlmICh3aW5kb3cud2Via2l0Q29udmVydFBvaW50RnJvbU5vZGVUb1BhZ2UpIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy53ZWJraXRDb252ZXJ0UG9pbnRGcm9tTm9kZVRvUGFnZShlbGVtZW50LFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFdlYktpdFBvaW50KHAueCwgcC55KSlcbiAgICAgICAgLy8gICAgICAgICB9XG4gICAgICAgIHJldHVybiB3aW5kb3cuY29udmVydFBvaW50RnJvbU5vZGVUb1BhZ2UoZWxlbWVudCwgcC54LCBwLnkpXG4gICAgfVxufVxuXG4vKipcbiAqIEEgaGVscGVyIGNsYXNzIGZvciBjb21tb24gc2V0IG9wZXJhdGlvbnMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIFNldHNcbiAqL1xuZXhwb3J0IGNsYXNzIFNldHMge1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW50ZXJzZWN0aW9uIG9mIGFsbCBzZXRzXG4gICAgICogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzE5MzA4OTQvamF2YXNjcmlwdC1zZXQtZGF0YS1zdHJ1Y3R1cmUtaW50ZXJzZWN0XG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7Kn0gc2V0c1xuICAgICAqIEByZXR1cm5zXG4gICAgICogQG1lbWJlcm9mIFNldHNcbiAgICAgKi9cbiAgICBzdGF0aWMgaW50ZXJzZWN0KC4uLnNldHMpIHtcbiAgICAgICAgaWYgKCFzZXRzLmxlbmd0aCkgcmV0dXJuIG5ldyBTZXQoKVxuICAgICAgICBjb25zdCBpID0gc2V0cy5yZWR1Y2UoKG0sIHMsIGkpID0+IHMuc2l6ZSA8IHNldHNbbV0uc2l6ZSA/IGkgOiBtLCAwKVxuICAgICAgICBjb25zdCBbc21hbGxlc3RdID0gc2V0cy5zcGxpY2UoaSwgMSlcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFNldCgpXG4gICAgICAgIGZvciAobGV0IHZhbCBvZiBzbWFsbGVzdClcbiAgICAgICAgICAgIGlmIChzZXRzLmV2ZXJ5KHMgPT4gcy5oYXModmFsKSkpXG4gICAgICAgICAgICAgICAgcmVzLmFkZCh2YWwpXG4gICAgICAgIHJldHVybiByZXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB1bmlvbiBvZiBhbGwgc2V0c1xuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7Kn0gc2V0c1xuICAgICAqIEByZXR1cm5zXG4gICAgICogQG1lbWJlcm9mIFNldHNcbiAgICAgKi9cbiAgICBzdGF0aWMgdW5pb24oLi4uc2V0cykge1xuICAgICAgICBsZXQgcmVzdWx0ID0gbmV3IFNldCgpXG4gICAgICAgIGZvciAobGV0IHNldCBvZiBzZXRzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBtIG9mIHNldCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGUgZ2l2ZW4gc2V0cy4gU3RhcnRzIHdpdGggdGhlIGZpcnN0IHNldCBhbmQgcmVtb3ZpbmcgYWxsIGVsZW1lbnRzIG9mIHRoZSBmb2xsb3dpbmcgc2V0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyp9IHNldFxuICAgICAqIEBwYXJhbSB7Kn0gc2V0c1xuICAgICAqIEByZXR1cm5zXG4gICAgICogQG1lbWJlcm9mIFNldHNcbiAgICAgKi9cbiAgICBzdGF0aWMgZGlmZmVyZW5jZShzZXQsIC4uLnNldHMpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyBTZXQoKVxuICAgICAgICBmb3IgKGxldCBtIG9mIHNldCkge1xuICAgICAgICAgICAgcmVzdWx0LmFkZChtKVxuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IHMgb2Ygc2V0cykge1xuICAgICAgICAgICAgZm9yIChsZXQgbSBvZiBzKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LmRlbGV0ZShtKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG59XG5cbi8qKiBTdGF0aWMgbWV0aG9kcyB0byBjb21wdXRlIGFuZ2xlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEFuZ2xlIHtcblxuICAgIHN0YXRpYyBub3JtYWxpemUoYW5nbGUpIHtcbiAgICAgICAgbGV0IFRBVSA9IE1hdGguUEkgKiAyLjBcbiAgICAgICAgd2hpbGUgKGFuZ2xlID4gTWF0aC5QSSkge1xuICAgICAgICAgICAgYW5nbGUgLT0gVEFVXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGFuZ2xlIDwgLU1hdGguUEkpIHtcbiAgICAgICAgICAgIGFuZ2xlICs9IFRBVVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmdsZVxuICAgIH1cblxuICAgIHN0YXRpYyBub3JtYWxpemUyKGFuZ2xlKSB7XG4gICAgICAgIGxldCBUQVUgPSBNYXRoLlBJICogMi4wXG4gICAgICAgIHdoaWxlIChhbmdsZSA+IFRBVSkge1xuICAgICAgICAgICAgYW5nbGUgLT0gVEFVXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGFuZ2xlIDwgMCkge1xuICAgICAgICAgICAgYW5nbGUgKz0gVEFVXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFuZ2xlXG4gICAgfVxuXG4gICAgc3RhdGljIG5vcm1hbGl6ZURlZ3JlZShhbmdsZSkge1xuICAgICAgICBsZXQgZnVsbCA9IDM2MC4wXG4gICAgICAgIHdoaWxlIChhbmdsZSA+IDE4MC4wKSB7XG4gICAgICAgICAgICBhbmdsZSAtPSBmdWxsXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGFuZ2xlIDwgLTE4MC4wKSB7XG4gICAgICAgICAgICBhbmdsZSArPSBmdWxsXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFuZ2xlXG4gICAgfVxuXG4gICAgc3RhdGljIG5vcm1hbGl6ZWREaWZmKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsaXplKHRoaXMuZGlmZihhLCBiKSlcbiAgICB9XG5cbiAgICBzdGF0aWMgbm9ybWFsaXplZDJEaWZmKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsaXplMih0aGlzLmRpZmYoYSwgYikpXG4gICAgfVxuXG4gICAgc3RhdGljIGRpZmYoYSwgYikge1xuICAgICAgICByZXR1cm4gTWF0aC5hdGFuMihNYXRoLnNpbihhIC0gYiksIE1hdGguY29zKGEgLSBiKSlcbiAgICB9XG5cbiAgICBzdGF0aWMgZGVncmVlMnJhZGlhbihkZWdyZWUpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguUEkgKiBkZWdyZWUgLyAxODAuMFxuICAgIH1cblxuICAgIHN0YXRpYyByYWRpYW4yZGVncmVlKHJhZCkge1xuICAgICAgICByZXR1cm4gMTgwLjAgLyBNYXRoLlBJICogcmFkXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRWxlbWVudHMge1xuICAgIHN0YXRpYyBzZXRTdHlsZShlbGVtZW50LCBzdHlsZXMpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIHN0eWxlcykge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZVtrZXldID0gc3R5bGVzW2tleV1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBhZGRDbGFzcyhlbGVtZW50LCBjc3NDbGFzcykge1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY3NzQ2xhc3MpXG4gICAgfVxuXG4gICAgc3RhdGljIHJlbW92ZUNsYXNzKGVsZW1lbnQsIGNzc0NsYXNzKSB7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjc3NDbGFzcylcbiAgICB9XG5cbiAgICBzdGF0aWMgdG9nZ2xlQ2xhc3MoZWxlbWVudCwgY3NzQ2xhc3MpIHtcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKGNzc0NsYXNzKVxuICAgIH1cblxuICAgIHN0YXRpYyBoYXNDbGFzcyhlbGVtZW50LCBjc3NDbGFzcykge1xuICAgICAgICByZXR1cm4gZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoY3NzQ2xhc3MpXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgTWFwUHJveHkge1xuICAgIC8qIFRoaXMgY2xhc3MgaXMgbmVlZGVkIGlmIHdlIHdhbnQgdG8gdXNlIHRoZSBpbnRlcmFjdGlvbiBjbGFzc2VzXG4gICAgaW4gRmlyZWZveCA0NS44IGFuZCBtb2Rlcm4gQnJvd3NlcnMuXG5cbiAgICBBIHdvcmthcm91bmQgZm9yIGh0dHBzOi8vZ2l0aHViLmNvbS9iYWJlbC9iYWJlbC9pc3N1ZXMvMjMzNFxuICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLm1hcCA9IG5ldyBNYXAoKVxuICAgIH1cblxuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuc2l6ZVxuICAgIH1cblxuICAgIGdldChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChrZXkpXG4gICAgfVxuXG4gICAgc2V0KGtleSwgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLnNldChrZXksIHZhbHVlKVxuICAgIH1cblxuICAgIGRlbGV0ZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmRlbGV0ZShrZXkpXG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5jbGVhcigpXG4gICAgfVxuXG4gICAgaGFzKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuaGFzKGtleSlcbiAgICB9XG5cbiAgICBrZXlzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAua2V5cygpXG4gICAgfVxuXG4gICAgdmFsdWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAudmFsdWVzKClcbiAgICB9XG5cbiAgICBlbnRyaWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZW50cmllcygpXG4gICAgfVxuXG4gICAgZm9yRWFjaChmdW5jKSB7XG4gICAgICAgIHRoaXMubWFwLmZvckVhY2goZnVuYylcbiAgICB9XG59XG5cbi8qIEJhc2VkIG9tIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL2N3bGVvbmFyZC9lMTI0ZDYzMjM4YmRhN2EzY2JmYSAqL1xuZXhwb3J0IGNsYXNzIFBvbHlnb24ge1xuICAgIC8qXG4gICAgICogIFRoaXMgaXMgdGhlIFBvbHlnb24gY29uc3RydWN0b3IuIEFsbCBwb2ludHMgYXJlIGNlbnRlci1yZWxhdGl2ZS5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjZW50ZXIpIHtcbiAgICAgICAgdGhpcy5wb2ludHMgPSBuZXcgQXJyYXkoKVxuICAgICAgICB0aGlzLmNlbnRlciA9IGNlbnRlclxuICAgIH1cblxuICAgIC8qXG4gICAgICogIFBvaW50IHggYW5kIHkgdmFsdWVzIHNob3VsZCBiZSByZWxhdGl2ZSB0byB0aGUgY2VudGVyLlxuICAgICAqL1xuICAgIGFkZFBvaW50KHApIHtcbiAgICAgICAgdGhpcy5wb2ludHMucHVzaChwKVxuICAgIH1cblxuICAgIC8qXG4gICAgICogIFBvaW50IHggYW5kIHkgdmFsdWVzIHNob3VsZCBiZSBhYnNvbHV0ZSBjb29yZGluYXRlcy5cbiAgICAgKi9cbiAgICBhZGRBYnNvbHV0ZVBvaW50KHApIHtcbiAgICAgICAgdGhpcy5wb2ludHMucHVzaCh7IHg6IHAueCAtIHRoaXMuY2VudGVyLngsIHk6IHAueSAtIHRoaXMuY2VudGVyLnkgfSlcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBzaWRlcy4gRXF1YWwgdG8gdGhlIG51bWJlciBvZiB2ZXJ0aWNlcy5cbiAgICAgKi9cbiAgICBnZXROdW1iZXJPZlNpZGVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wb2ludHMubGVuZ3RoXG4gICAgfVxuXG4gICAgLypcbiAgICAgKiByb3RhdGUgdGhlIHBvbHlnb24gYnkgYSBudW1iZXIgb2YgcmFkaWFuc1xuICAgICAqL1xuICAgIHJvdGF0ZShyYWRzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB4ID0gdGhpcy5wb2ludHNbaV0ueFxuICAgICAgICAgICAgbGV0IHkgPSB0aGlzLnBvaW50c1tpXS55XG4gICAgICAgICAgICB0aGlzLnBvaW50c1tpXS54ID0gTWF0aC5jb3MocmFkcykgKiB4IC0gTWF0aC5zaW4ocmFkcykgKiB5XG4gICAgICAgICAgICB0aGlzLnBvaW50c1tpXS55ID0gTWF0aC5zaW4ocmFkcykgKiB4ICsgTWF0aC5jb3MocmFkcykgKiB5XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqICBUaGUgZHJhdyBmdW5jdGlvbiB0YWtlcyBhcyBhIHBhcmFtZXRlciBhIENvbnRleHQgb2JqZWN0IGZyb21cbiAgICAgKiAgYSBDYW52YXMgZWxlbWVudCBhbmQgZHJhd3MgdGhlIHBvbHlnb24gb24gaXQuXG4gICAgICovXG4gICAgZHJhdyhjb250ZXh0LCB7IGxpbmVXaWR0aCA9IDIsIHN0cm9rZSA9ICcjMDAwMDAwJywgZmlsbCA9IG51bGwgfSA9IHt9KSB7XG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKClcbiAgICAgICAgY29udGV4dC5tb3ZlVG8oXG4gICAgICAgICAgICB0aGlzLnBvaW50c1swXS54ICsgdGhpcy5jZW50ZXIueCxcbiAgICAgICAgICAgIHRoaXMucG9pbnRzWzBdLnkgKyB0aGlzLmNlbnRlci55XG4gICAgICAgIClcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCB0aGlzLnBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29udGV4dC5saW5lVG8oXG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludHNbaV0ueCArIHRoaXMuY2VudGVyLngsXG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludHNbaV0ueSArIHRoaXMuY2VudGVyLnlcbiAgICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpXG4gICAgICAgIGNvbnRleHQubGluZVdpZHRoID0gbGluZVdpZHRoXG4gICAgICAgIGlmIChzdHJva2UpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBzdHJva2VcbiAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKClcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsbCkge1xuICAgICAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBmaWxsXG4gICAgICAgICAgICBjb250ZXh0LmZpbGwoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYWJzb2x1dGVQb2ludHMoKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBuZXcgQXJyYXkoKVxuICAgICAgICBmb3IgKGxldCBwIG9mIHRoaXMucG9pbnRzKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChQb2ludHMuYWRkKHAsIHRoaXMuY2VudGVyKSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgZmxhdEFic29sdXRlUG9pbnRzKCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gbmV3IEFycmF5KClcbiAgICAgICAgZm9yIChsZXQgcCBvZiB0aGlzLnBvaW50cykge1xuICAgICAgICAgICAgbGV0IGEgPSBQb2ludHMuYWRkKHAsIHRoaXMuY2VudGVyKVxuICAgICAgICAgICAgcmVzdWx0LnB1c2goYS54KVxuICAgICAgICAgICAgcmVzdWx0LnB1c2goYS55KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICAvKlxuICAgICAqICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gcG9pbnQgaXMgaW5zaWRlIHRoZSBwb2x5Z29uLFxuICAgICAqICBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGNvbnRhaW5zUG9pbnQocG50KSB7XG4gICAgICAgIGxldCBudmVydCA9IHRoaXMucG9pbnRzLmxlbmd0aFxuICAgICAgICBsZXQgdGVzdHggPSBwbnQueFxuICAgICAgICBsZXQgdGVzdHkgPSBwbnQueVxuXG4gICAgICAgIGxldCB2ZXJ0eCA9IG5ldyBBcnJheSgpXG4gICAgICAgIGZvciAobGV0IHEgPSAwOyBxIDwgdGhpcy5wb2ludHMubGVuZ3RoOyBxKyspIHtcbiAgICAgICAgICAgIHZlcnR4LnB1c2godGhpcy5wb2ludHNbcV0ueCArIHRoaXMuY2VudGVyLngpXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmVydHkgPSBuZXcgQXJyYXkoKVxuICAgICAgICBmb3IgKGxldCB3ID0gMDsgdyA8IHRoaXMucG9pbnRzLmxlbmd0aDsgdysrKSB7XG4gICAgICAgICAgICB2ZXJ0eS5wdXNoKHRoaXMucG9pbnRzW3ddLnkgKyB0aGlzLmNlbnRlci55KVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGksXG4gICAgICAgICAgICBqID0gMFxuICAgICAgICBsZXQgYyA9IGZhbHNlXG4gICAgICAgIGZvciAoaSA9IDAsIGogPSBudmVydCAtIDE7IGkgPCBudmVydDsgaiA9IGkrKykge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHZlcnR5W2ldID4gdGVzdHkgIT0gdmVydHlbal0gPiB0ZXN0eSAmJlxuICAgICAgICAgICAgICAgIHRlc3R4IDxcbiAgICAgICAgICAgICAgICAodmVydHhbal0gLSB2ZXJ0eFtpXSkgKlxuICAgICAgICAgICAgICAgICh0ZXN0eSAtIHZlcnR5W2ldKSAvXG4gICAgICAgICAgICAgICAgKHZlcnR5W2pdIC0gdmVydHlbaV0pICtcbiAgICAgICAgICAgICAgICB2ZXJ0eFtpXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGMgPSAhY1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjXG4gICAgfVxuXG4gICAgbXVsdGlwbHlTY2FsYXIoc2NhbGUpIHtcbiAgICAgICAgbGV0IGNlbnRlciA9IFBvaW50cy5tdWx0aXBseVNjYWxhcih0aGlzLmNlbnRlciwgc2NhbGUpXG4gICAgICAgIGxldCBjbG9uZSA9IG5ldyBQb2x5Z29uKGNlbnRlcilcbiAgICAgICAgZm9yIChsZXQgcCBvZiB0aGlzLnBvaW50cykge1xuICAgICAgICAgICAgY2xvbmUuYWRkUG9pbnQoUG9pbnRzLm11bHRpcGx5U2NhbGFyKHAsIHNjYWxlKSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2xvbmVcbiAgICB9XG5cbiAgICAvKlxuICAgICAqICBUbyBkZXRlY3QgaW50ZXJzZWN0aW9uIHdpdGggYW5vdGhlciBQb2x5Z29uIG9iamVjdCwgdGhpc1xuICAgICAqICBmdW5jdGlvbiB1c2VzIHRoZSBTZXBhcmF0aW5nIEF4aXMgVGhlb3JlbS4gSXQgcmV0dXJucyBmYWxzZVxuICAgICAqICBpZiB0aGVyZSBpcyBubyBpbnRlcnNlY3Rpb24sIG9yIGFuIG9iamVjdCBpZiB0aGVyZSBpcy4gVGhlIG9iamVjdFxuICAgICAqICBjb250YWlucyAyIGZpZWxkcywgb3ZlcmxhcCBhbmQgYXhpcy4gTW92aW5nIHRoZSBwb2x5Z29uIGJ5IG92ZXJsYXBcbiAgICAgKiAgb24gYXhpcyB3aWxsIGdldCB0aGUgcG9seWdvbnMgb3V0IG9mIGludGVyc2VjdGlvbi5cbiAgICAgKi9cbiAgICBpbnRlcnNlY3RzV2l0aChvdGhlcikge1xuICAgICAgICBsZXQgYXhpcyA9IHsgeDogMCwgeTogMCB9XG4gICAgICAgIGxldCB0bXAsIG1pbkEsIG1heEEsIG1pbkIsIG1heEJcbiAgICAgICAgbGV0IHNpZGUsIGlcbiAgICAgICAgbGV0IHNtYWxsZXN0ID0gbnVsbFxuICAgICAgICBsZXQgb3ZlcmxhcCA9IDk5OTk5OTk5XG5cbiAgICAgICAgLyogdGVzdCBwb2x5Z29uIEEncyBzaWRlcyAqL1xuICAgICAgICBmb3IgKHNpZGUgPSAwOyBzaWRlIDwgdGhpcy5nZXROdW1iZXJPZlNpZGVzKCk7IHNpZGUrKykge1xuICAgICAgICAgICAgLyogZ2V0IHRoZSBheGlzIHRoYXQgd2Ugd2lsbCBwcm9qZWN0IG9udG8gKi9cbiAgICAgICAgICAgIGlmIChzaWRlID09IDApIHtcbiAgICAgICAgICAgICAgICBheGlzLnggPVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50c1t0aGlzLmdldE51bWJlck9mU2lkZXMoKSAtIDFdLnkgLVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50c1swXS55XG4gICAgICAgICAgICAgICAgYXhpcy55ID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb2ludHNbMF0ueCAtXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucG9pbnRzW3RoaXMuZ2V0TnVtYmVyT2ZTaWRlcygpIC0gMV0ueFxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBheGlzLnggPSB0aGlzLnBvaW50c1tzaWRlIC0gMV0ueSAtIHRoaXMucG9pbnRzW3NpZGVdLnlcbiAgICAgICAgICAgICAgICBheGlzLnkgPSB0aGlzLnBvaW50c1tzaWRlXS54IC0gdGhpcy5wb2ludHNbc2lkZSAtIDFdLnhcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyogbm9ybWFsaXplIHRoZSBheGlzICovXG4gICAgICAgICAgICB0bXAgPSBNYXRoLnNxcnQoYXhpcy54ICogYXhpcy54ICsgYXhpcy55ICogYXhpcy55KVxuICAgICAgICAgICAgYXhpcy54IC89IHRtcFxuICAgICAgICAgICAgYXhpcy55IC89IHRtcFxuXG4gICAgICAgICAgICAvKiBwcm9qZWN0IHBvbHlnb24gQSBvbnRvIGF4aXMgdG8gZGV0ZXJtaW5lIHRoZSBtaW4vbWF4ICovXG4gICAgICAgICAgICBtaW5BID0gbWF4QSA9IHRoaXMucG9pbnRzWzBdLnggKiBheGlzLnggKyB0aGlzLnBvaW50c1swXS55ICogYXhpcy55XG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgdGhpcy5nZXROdW1iZXJPZlNpZGVzKCk7IGkrKykge1xuICAgICAgICAgICAgICAgIHRtcCA9IHRoaXMucG9pbnRzW2ldLnggKiBheGlzLnggKyB0aGlzLnBvaW50c1tpXS55ICogYXhpcy55XG4gICAgICAgICAgICAgICAgaWYgKHRtcCA+IG1heEEpIG1heEEgPSB0bXBcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0bXAgPCBtaW5BKSBtaW5BID0gdG1wXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKiBjb3JyZWN0IGZvciBvZmZzZXQgKi9cbiAgICAgICAgICAgIHRtcCA9IHRoaXMuY2VudGVyLnggKiBheGlzLnggKyB0aGlzLmNlbnRlci55ICogYXhpcy55XG4gICAgICAgICAgICBtaW5BICs9IHRtcFxuICAgICAgICAgICAgbWF4QSArPSB0bXBcblxuICAgICAgICAgICAgLyogcHJvamVjdCBwb2x5Z29uIEIgb250byBheGlzIHRvIGRldGVybWluZSB0aGUgbWluL21heCAqL1xuICAgICAgICAgICAgbWluQiA9IG1heEIgPVxuICAgICAgICAgICAgICAgIG90aGVyLnBvaW50c1swXS54ICogYXhpcy54ICsgb3RoZXIucG9pbnRzWzBdLnkgKiBheGlzLnlcbiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCBvdGhlci5nZXROdW1iZXJPZlNpZGVzKCk7IGkrKykge1xuICAgICAgICAgICAgICAgIHRtcCA9IG90aGVyLnBvaW50c1tpXS54ICogYXhpcy54ICsgb3RoZXIucG9pbnRzW2ldLnkgKiBheGlzLnlcbiAgICAgICAgICAgICAgICBpZiAodG1wID4gbWF4QikgbWF4QiA9IHRtcFxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRtcCA8IG1pbkIpIG1pbkIgPSB0bXBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIGNvcnJlY3QgZm9yIG9mZnNldCAqL1xuICAgICAgICAgICAgdG1wID0gb3RoZXIuY2VudGVyLnggKiBheGlzLnggKyBvdGhlci5jZW50ZXIueSAqIGF4aXMueVxuICAgICAgICAgICAgbWluQiArPSB0bXBcbiAgICAgICAgICAgIG1heEIgKz0gdG1wXG5cbiAgICAgICAgICAgIC8qIHRlc3QgaWYgbGluZXMgaW50ZXJzZWN0LCBpZiBub3QsIHJldHVybiBmYWxzZSAqL1xuICAgICAgICAgICAgaWYgKG1heEEgPCBtaW5CIHx8IG1pbkEgPiBtYXhCKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBvID0gbWF4QSA+IG1heEIgPyBtYXhCIC0gbWluQSA6IG1heEEgLSBtaW5CXG4gICAgICAgICAgICAgICAgaWYgKG8gPCBvdmVybGFwKSB7XG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXAgPSBvXG4gICAgICAgICAgICAgICAgICAgIHNtYWxsZXN0ID0geyB4OiBheGlzLngsIHk6IGF4aXMueSB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyogdGVzdCBwb2x5Z29uIEIncyBzaWRlcyAqL1xuICAgICAgICBmb3IgKHNpZGUgPSAwOyBzaWRlIDwgb3RoZXIuZ2V0TnVtYmVyT2ZTaWRlcygpOyBzaWRlKyspIHtcbiAgICAgICAgICAgIC8qIGdldCB0aGUgYXhpcyB0aGF0IHdlIHdpbGwgcHJvamVjdCBvbnRvICovXG4gICAgICAgICAgICBpZiAoc2lkZSA9PSAwKSB7XG4gICAgICAgICAgICAgICAgYXhpcy54ID1cbiAgICAgICAgICAgICAgICAgICAgb3RoZXIucG9pbnRzW290aGVyLmdldE51bWJlck9mU2lkZXMoKSAtIDFdLnkgLVxuICAgICAgICAgICAgICAgICAgICBvdGhlci5wb2ludHNbMF0ueVxuICAgICAgICAgICAgICAgIGF4aXMueSA9XG4gICAgICAgICAgICAgICAgICAgIG90aGVyLnBvaW50c1swXS54IC1cbiAgICAgICAgICAgICAgICAgICAgb3RoZXIucG9pbnRzW290aGVyLmdldE51bWJlck9mU2lkZXMoKSAtIDFdLnhcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXhpcy54ID0gb3RoZXIucG9pbnRzW3NpZGUgLSAxXS55IC0gb3RoZXIucG9pbnRzW3NpZGVdLnlcbiAgICAgICAgICAgICAgICBheGlzLnkgPSBvdGhlci5wb2ludHNbc2lkZV0ueCAtIG90aGVyLnBvaW50c1tzaWRlIC0gMV0ueFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKiBub3JtYWxpemUgdGhlIGF4aXMgKi9cbiAgICAgICAgICAgIHRtcCA9IE1hdGguc3FydChheGlzLnggKiBheGlzLnggKyBheGlzLnkgKiBheGlzLnkpXG4gICAgICAgICAgICBheGlzLnggLz0gdG1wXG4gICAgICAgICAgICBheGlzLnkgLz0gdG1wXG5cbiAgICAgICAgICAgIC8qIHByb2plY3QgcG9seWdvbiBBIG9udG8gYXhpcyB0byBkZXRlcm1pbmUgdGhlIG1pbi9tYXggKi9cbiAgICAgICAgICAgIG1pbkEgPSBtYXhBID0gdGhpcy5wb2ludHNbMF0ueCAqIGF4aXMueCArIHRoaXMucG9pbnRzWzBdLnkgKiBheGlzLnlcbiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCB0aGlzLmdldE51bWJlck9mU2lkZXMoKTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdG1wID0gdGhpcy5wb2ludHNbaV0ueCAqIGF4aXMueCArIHRoaXMucG9pbnRzW2ldLnkgKiBheGlzLnlcbiAgICAgICAgICAgICAgICBpZiAodG1wID4gbWF4QSkgbWF4QSA9IHRtcFxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRtcCA8IG1pbkEpIG1pbkEgPSB0bXBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIGNvcnJlY3QgZm9yIG9mZnNldCAqL1xuICAgICAgICAgICAgdG1wID0gdGhpcy5jZW50ZXIueCAqIGF4aXMueCArIHRoaXMuY2VudGVyLnkgKiBheGlzLnlcbiAgICAgICAgICAgIG1pbkEgKz0gdG1wXG4gICAgICAgICAgICBtYXhBICs9IHRtcFxuXG4gICAgICAgICAgICAvKiBwcm9qZWN0IHBvbHlnb24gQiBvbnRvIGF4aXMgdG8gZGV0ZXJtaW5lIHRoZSBtaW4vbWF4ICovXG4gICAgICAgICAgICBtaW5CID0gbWF4QiA9XG4gICAgICAgICAgICAgICAgb3RoZXIucG9pbnRzWzBdLnggKiBheGlzLnggKyBvdGhlci5wb2ludHNbMF0ueSAqIGF4aXMueVxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IG90aGVyLmdldE51bWJlck9mU2lkZXMoKTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdG1wID0gb3RoZXIucG9pbnRzW2ldLnggKiBheGlzLnggKyBvdGhlci5wb2ludHNbaV0ueSAqIGF4aXMueVxuICAgICAgICAgICAgICAgIGlmICh0bXAgPiBtYXhCKSBtYXhCID0gdG1wXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodG1wIDwgbWluQikgbWluQiA9IHRtcFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyogY29ycmVjdCBmb3Igb2Zmc2V0ICovXG4gICAgICAgICAgICB0bXAgPSBvdGhlci5jZW50ZXIueCAqIGF4aXMueCArIG90aGVyLmNlbnRlci55ICogYXhpcy55XG4gICAgICAgICAgICBtaW5CICs9IHRtcFxuICAgICAgICAgICAgbWF4QiArPSB0bXBcblxuICAgICAgICAgICAgLyogdGVzdCBpZiBsaW5lcyBpbnRlcnNlY3QsIGlmIG5vdCwgcmV0dXJuIGZhbHNlICovXG4gICAgICAgICAgICBpZiAobWF4QSA8IG1pbkIgfHwgbWluQSA+IG1heEIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IG8gPSBtYXhBID4gbWF4QiA/IG1heEIgLSBtaW5BIDogbWF4QSAtIG1pbkJcbiAgICAgICAgICAgICAgICBpZiAobyA8IG92ZXJsYXApIHtcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxhcCA9IG9cbiAgICAgICAgICAgICAgICAgICAgc21hbGxlc3QgPSB7IHg6IGF4aXMueCwgeTogYXhpcy55IH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgb3ZlcmxhcDogb3ZlcmxhcCArIDAuMDAxLCBheGlzOiBzbWFsbGVzdCB9XG4gICAgfVxuXG4gICAgc3RhdGljIGZyb21Qb2ludHMocG9pbnRzKSB7XG4gICAgICAgIGxldCBtaW4gPSB7IHg6IE51bWJlci5NQVhfVkFMVUUsIHk6IE51bWJlci5NQVhfVkFMVUUgfVxuICAgICAgICBsZXQgbWF4ID0geyB4OiBOdW1iZXIuTUlOX1ZBTFVFLCB5OiBOdW1iZXIuTUlOX1ZBTFVFIH1cbiAgICAgICAgZm9yIChsZXQgcCBvZiBwb2ludHMpIHtcbiAgICAgICAgICAgIG1pbi54ID0gTWF0aC5taW4ocC54LCBtaW4ueClcbiAgICAgICAgICAgIG1heC54ID0gTWF0aC5tYXgocC54LCBtYXgueClcbiAgICAgICAgICAgIG1pbi55ID0gTWF0aC5taW4ocC55LCBtaW4ueSlcbiAgICAgICAgICAgIG1heC55ID0gTWF0aC5tYXgocC55LCBtYXgueSlcbiAgICAgICAgfVxuICAgICAgICBsZXQgY2VudGVyID0gUG9pbnRzLm1lYW4obWluLCBtYXgpXG4gICAgICAgIGxldCBwb2x5Z29uID0gbmV3IFBvbHlnb24oY2VudGVyKVxuICAgICAgICBmb3IgKGxldCBwIG9mIHBvaW50cykge1xuICAgICAgICAgICAgcG9seWdvbi5hZGRBYnNvbHV0ZVBvaW50KHApXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBvbHlnb25cbiAgICB9XG59XG5cblxuLyoqXG4gKiBVdGlsIGZ1bmN0aW9ucyB0byBkZWFsIHdpdGggRE9NUmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWN0IHtcblxuXG4gICAgLyoqXG4gICAgICogVGVzdCBpZiBhIGdpdmVuIHBvaW50IGlzIGNvbnRhaW5lZCBieSB0aGUgcHJvdmlkZWQgUmVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge0RPTVJlY3R9IHJlY3QgLSBSZWN0YW5nbGUgdG8gY2hlY2sgdGhlIGNvbGxpc2lvbiB3aXRoLlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHBvaW50IC0gUG9pbnQgdGhhdCBzaG91bGQgYmUgdGVzdGVkLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSAtIFRydWUgaWYgcG9pbnQgaXMgaW5zaWRlIG9mIHJlY3QsIG90aGVyd2lzZSBmYWxzZS5cbiAgICAgKiBAbWVtYmVyb2YgUmVjdFxuICAgICAqL1xuICAgIHN0YXRpYyBjb250YWlucyhyZWN0LCBwb2ludCkge1xuICAgICAgICByZXR1cm4gKHBvaW50LnggPiByZWN0LmxlZnQgJiZcbiAgICAgICAgICAgIHBvaW50LnggPCByZWN0LnggKyByZWN0LnJpZ2h0XG4gICAgICAgICAgICAmJiBwb2ludC55ID4gcmVjdC50b3AgJiYgcG9pbnQueSA8IHJlY3QuYm90dG9tKVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICpSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiBhbiByZWN0IGFzIHBvaW50IG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge1JlY3R9IHJlY3QgLSBUaGUgcmVjdGFuZ2xlIHdlIHdhbnQgdG8gZ2V0IHRoZSBwb3NpdGlvbiBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtQb2ludH0gLSBSZXR1cm5zIHRoZSBwb3NpdGlvbiBhcyBQb2ludC5cbiAgICAgKiBAbWVtYmVyb2YgUmVjdFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQb3NpdGlvbihyZWN0KSB7XG4gICAgICAgIHJldHVybiB7IHg6IHJlY3QueCwgeTogcmVjdC55IH1cbiAgICB9XG59XG5cbi8qKiBTdHJpbmcgdXRpbGl0eSBmdW5jdGlvbnMgKi9cblxuZXhwb3J0IGNsYXNzIFN0cmluZ3Mge1xuXG4gICAgc3RhdGljIHRvVXBwZXJDYXNlRmlyc3RDaGFyKHN0cikge1xuICAgICAgICByZXR1cm4gc3RyLnN1YnN0cigwLCAxKS50b1VwcGVyQ2FzZSgpICsgc3RyLnN1YnN0cigxKVxuICAgIH1cblxuICAgIHN0YXRpYyB0b0xvd2VyQ2FzZUZpcnN0Q2hhcihzdHIpIHtcbiAgICAgICAgcmV0dXJuIHN0ci5zdWJzdHIoMCwgMSkudG9Mb3dlckNhc2UoKSArIHN0ci5zdWJzdHIoMSlcbiAgICB9XG5cbiAgICBzdGF0aWMgdG9VcHBlckNhc2VFYWNoV29yZChzdHIsIGRlbGltID0gJyAnKSB7XG4gICAgICAgIHJldHVybiBzdHIuc3BsaXQoZGVsaW0pLm1hcCgodikgPT4gdi50b1VwcGVyQ2FzZUZpcnN0Q2hhcigpKS5qb2luKGRlbGltKVxuICAgIH1cblxuICAgIHN0YXRpYyB0b0xvd2VyQ2FzZUVhY2hXb3JkKHN0ciwgZGVsaW0gPSAnICcpIHtcbiAgICAgICAgcmV0dXJuIHN0ci5zcGxpdChkZWxpbSkubWFwKCh2KSA9PiB2LnRvTG93ZXJDYXNlRmlyc3RDaGFyKCkpLmpvaW4oZGVsaW0pXG4gICAgfVxuXG59XG5cblxuXG4iLCIvKiBnbG9iYWxzIEhhbW1lciwgcHJvcGFnYXRpbmcgKi9cbi8qZXNsaW50IG5vLWNvbnNvbGU6IFtcImVycm9yXCIsIHsgYWxsb3c6IFtcImxvZ1wiLCBcIndhcm5cIiwgXCJpbmZvXCIsIFwiZXJyb3JcIl0gfV0qL1xuXG5pbXBvcnQgSW50ZXJmYWNlIGZyb20gJy4vaW50ZXJmYWNlLmpzJ1xuaW1wb3J0IHsgUG9pbnRzLCBBbmdsZSwgTWFwUHJveHkgfSBmcm9tICcuL3V0aWxzLmpzJ1xuaW1wb3J0IEV2ZW50cyBmcm9tICcuL2V2ZW50cy5qcydcblxuLyoqIEludGVyYWN0aW9uIHBhdHRlcm5zXG5cbiAgICBTZWUgaW50ZXJhY3Rpb24uaHRtbCBmb3IgZXhwbGFuYXRpb25cbiovXG5cbmV4cG9ydCBjbGFzcyBJSW50ZXJhY3Rpb25UYXJnZXQgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuICAgIGNhcHR1cmUoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB0cnVlXG4gICAgfVxuXG4gICAgb25TdGFydChldmVudCwgaW50ZXJhY3Rpb24pIHsgfVxuICAgIG9uTW92ZShldmVudCwgaW50ZXJhY3Rpb24pIHsgfVxuICAgIG9uRW5kKGV2ZW50LCBpbnRlcmFjdGlvbikgeyB9XG5cbiAgICBvbk1vdXNlV2hlZWwoZXZlbnQpIHsgfVxufVxuXG5leHBvcnQgY2xhc3MgSUludGVyYWN0aW9uTWFwcGVyVGFyZ2V0IGV4dGVuZHMgSW50ZXJmYWNlIHtcbiAgICBjYXB0dXJlKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdHJ1ZVxuICAgIH1cblxuICAgIGZpbmRUYXJnZXQoZXZlbnQsIGxvY2FsLCBnbG9iYWwpIHtcbiAgICAgICAgcmV0dXJuIElJbnRlcmFjdGlvblRhcmdldFxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBvaW50TWFwIGV4dGVuZHMgTWFwUHJveHkge1xuICAgIC8vIENvbGxlY3RzIHRvdWNoIHBvaW50cywgbW91c2UgY29vcmRpbmF0ZXMsIGV0Yy4gYXMga2V5IHZhbHVlIHBhaXJzLlxuICAgIC8vIEtleXMgYXJlIHBvaW50ZXIgYW5kIHRvdWNoIGlkcywgdGhlIHNwZWNpYWwgXCJtb3VzZVwiIGtleS5cbiAgICAvLyBWYWx1ZXMgYXJlIHBvaW50cywgaS5lLiBhbGwgb2JqZWN0cyB3aXRoIG51bWVyaWMgeCBhbmQgeSBwcm9wZXJ0aWVzLlxuICAgIGNvbnN0cnVjdG9yKHBvaW50cyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgZm9yIChsZXQga2V5IGluIHBvaW50cykge1xuICAgICAgICAgICAgdGhpcy5zZXQoa2V5LCBwb2ludHNba2V5XSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgcG9pbnRzID0gW11cbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMua2V5cygpKSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLmdldChrZXkpXG4gICAgICAgICAgICBwb2ludHMucHVzaChgJHtrZXl9Ont4OiR7dmFsdWUueH0sIHk6JHt2YWx1ZS55fX1gKVxuICAgICAgICB9XG4gICAgICAgIGxldCBhdHRycyA9IHBvaW50cy5qb2luKCcsICcpXG4gICAgICAgIHJldHVybiBgW1BvaW50TWFwICR7YXR0cnN9XWBcbiAgICB9XG5cbiAgICBjbG9uZSgpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyBQb2ludE1hcCgpXG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmtleXMoKSkge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gdGhpcy5nZXQoa2V5KVxuICAgICAgICAgICAgcmVzdWx0LnNldChrZXksIHsgeDogdmFsdWUueCwgeTogdmFsdWUueSB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICBrZXlPZih2YWx1ZSkge1xuICAgICAgICBmb3IgKGxldCBrZXkgb2YgdGhpcy5rZXlzKCkpIHtcbiAgICAgICAgICAgIGxldCBwID0gdGhpcy5nZXQoa2V5KVxuICAgICAgICAgICAgaWYgKHAueCA9PSB2YWx1ZS54ICYmIHAueSA9PSB2YWx1ZS55KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgZmlyc3RLZXkoKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmtleXMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGtleVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgZmlyc3QoKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmtleXMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KGtleSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGZhcnRoZXN0cygpIHtcbiAgICAgICAgaWYgKHRoaXMuc2l6ZSA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIGxldCBwYWlycyA9IFtdXG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmtleXMoKSkge1xuICAgICAgICAgICAgbGV0IHAgPSB0aGlzLmdldChrZXkpXG4gICAgICAgICAgICBwLmtleSA9IGtleVxuICAgICAgICAgICAgZm9yIChsZXQgayBvZiB0aGlzLmtleXMoKSkge1xuICAgICAgICAgICAgICAgIGxldCBxID0gdGhpcy5nZXQoaylcbiAgICAgICAgICAgICAgICBxLmtleSA9IGtcbiAgICAgICAgICAgICAgICBwYWlycy5wdXNoKFtwLCBxXSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgc29ydGVkID0gcGFpcnMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFBvaW50cy5kaXN0YW5jZShiWzBdLCBiWzFdKSAtIFBvaW50cy5kaXN0YW5jZShhWzBdLCBhWzFdKVxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gc29ydGVkWzBdXG4gICAgfVxuXG4gICAgbWVhbigpIHtcbiAgICAgICAgaWYgKHRoaXMuc2l6ZSA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIGxldCB4ID0gMC4wLFxuICAgICAgICAgICAgeSA9IDAuMFxuICAgICAgICBmb3IgKGxldCBwIG9mIHRoaXMudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIHggKz0gcC54XG4gICAgICAgICAgICB5ICs9IHAueVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHg6IHggLyB0aGlzLnNpemUsIHk6IHkgLyB0aGlzLnNpemUgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEludGVyYWN0aW9uRGVsdGEge1xuICAgIGNvbnN0cnVjdG9yKHgsIHksIHpvb20sIHJvdGF0ZSwgYWJvdXQpIHtcbiAgICAgICAgdGhpcy54ID0geFxuICAgICAgICB0aGlzLnkgPSB5XG4gICAgICAgIHRoaXMuem9vbSA9IHpvb21cbiAgICAgICAgdGhpcy5yb3RhdGUgPSByb3RhdGVcbiAgICAgICAgdGhpcy5hYm91dCA9IGFib3V0XG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCB2YWx1ZXMgPSBbXVxuICAgICAgICBmb3IgKGxldCBrZXkgb2YgT2JqZWN0LmtleXModGhpcykpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IHRoaXNba2V5XVxuICAgICAgICAgICAgaWYgKGtleSA9PSAnYWJvdXQnKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goYCR7a2V5fTp7eDoke3ZhbHVlLnh9LCB5OiR7dmFsdWUueX19YClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goYCR7a2V5fToke3ZhbHVlfWApXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGF0dHJzID0gdmFsdWVzLmpvaW4oJywgJylcbiAgICAgICAgcmV0dXJuIGBbSW50ZXJhY3Rpb25EZWx0YSAke2F0dHJzfV1gXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW50ZXJhY3Rpb25Qb2ludHMge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCA9IG51bGwpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gbmV3IFBvaW50TWFwKClcbiAgICAgICAgdGhpcy5wcmV2aW91cyA9IG5ldyBQb2ludE1hcCgpXG4gICAgICAgIHRoaXMuc3RhcnQgPSBuZXcgUG9pbnRNYXAoKVxuICAgICAgICB0aGlzLmVuZGVkID0gbmV3IFBvaW50TWFwKClcbiAgICAgICAgdGhpcy50aW1lc3RhbXBzID0gbmV3IE1hcCgpXG4gICAgfVxuXG4gICAgbW92ZWQoa2V5KSB7XG4gICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5jdXJyZW50LmdldChrZXkpXG4gICAgICAgIGxldCBwcmV2aW91cyA9IHRoaXMucHJldmlvdXMuZ2V0KGtleSlcbiAgICAgICAgcmV0dXJuIFBvaW50cy5zdWJ0cmFjdChjdXJyZW50LCBwcmV2aW91cylcbiAgICB9XG5cbiAgICBtb3ZlKCkge1xuICAgICAgICBsZXQgY3VycmVudCA9IHRoaXMuY3VycmVudC5tZWFuKClcbiAgICAgICAgbGV0IHByZXZpb3VzID0gdGhpcy5wcmV2aW91cy5tZWFuKClcbiAgICAgICAgcmV0dXJuIFBvaW50cy5zdWJ0cmFjdChjdXJyZW50LCBwcmV2aW91cylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgZGVsdGEgYmV0d2VlbiBwcmV2aW91cyBhbmQgY3VycmVudCBhbmdsZXMuIENvcnJlY3RzXG4gICAgICogdmFsdWUgdGhhdCBhcmUgbGFyZ2VyIHRoYW4gNDXCsFxuICAgICAqIEBwYXJhbSB7Kn0gYVxuICAgICAqIEBwYXJhbSB7Kn0gYlxuICAgICAqIEByZXR1cm5zIGRlbHRhXG4gICAgICovXG4gICAgZGlmZkFuZ2xlKGEsIGIpIHtcbiAgICAgICAgbGV0IGFscGhhID0gTWF0aC5hdGFuMihNYXRoLnNpbihhIC0gYiksIE1hdGguY29zKGEgLSBiKSlcbiAgICAgICAgaWYgKE1hdGguYWJzKGFscGhhKSA+IE1hdGguUEkgLyA0KSB7XG4gICAgICAgICAgICBhbHBoYSAtPSBNYXRoLlBJXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFscGhhXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIGRlbHRhIGJldHdlZW4gaW50ZXJhY3Rpb24gcG9pbnRzIGF0IHQgYW5kIHQrMS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEludGVyYWN0aW9uRGVsdGFcbiAgICAgKiBAbWVtYmVyb2YgSW50ZXJhY3Rpb25Qb2ludHNcbiAgICAgKi9cbiAgICBkZWx0YSgpIHtcbiAgICAgICAgbGV0IGNzaXplID0gdGhpcy5jdXJyZW50LnNpemVcbiAgICAgICAgbGV0IHBzaXplID0gdGhpcy5wcmV2aW91cy5zaXplXG4gICAgICAgIGlmIChjc2l6ZSA+PSAyICYmIGNzaXplID09IHBzaXplKSB7XG4gICAgICAgICAgICAvLyBSZWR1Y2UgdG8gdGhlIHR3byBmYXJ0aGVzdHMgcG9pbnRzXG4gICAgICAgICAgICBsZXQgY3VycmVudCA9IHRoaXMuY3VycmVudC5mYXJ0aGVzdHMoKVxuXG4gICAgICAgICAgICBsZXQgYzEgPSBjdXJyZW50WzBdXG4gICAgICAgICAgICBsZXQgYzIgPSBjdXJyZW50WzFdXG5cbiAgICAgICAgICAgIGxldCBwMSA9IHRoaXMucHJldmlvdXMuZ2V0KGMxLmtleSlcbiAgICAgICAgICAgIGxldCBwMiA9IHRoaXMucHJldmlvdXMuZ2V0KGMyLmtleSlcblxuICAgICAgICAgICAgLy9sZXQgcDEgPSBwcmV2aW91c1swXVxuICAgICAgICAgICAgLy9sZXQgcDIgPSBwcmV2aW91c1sxXVxuXG4gICAgICAgICAgICBsZXQgZDEgPSBQb2ludHMuc3VidHJhY3QoYzEsIHAxKVxuICAgICAgICAgICAgbGV0IGQyID0gUG9pbnRzLnN1YnRyYWN0KGMyLCBwMilcbiAgICAgICAgICAgIGxldCBjbSA9IFBvaW50cy5tZWFuKGMxLCBjMilcbiAgICAgICAgICAgIC8vbGV0IHBtID0gUG9pbnRzLm1lYW4ocDEsIHAyKVxuICAgICAgICAgICAgLy8gVU86IFVzaW5nIHRoZSBtZWFuIGxlYWQgdG8ganVtcHMgYmV0d2VlbiB0aW1lIHNsaWNlcyB3aXRoIDMgYW5kIDIgZmluZ2Vyc1xuICAgICAgICAgICAgLy8gV2UgdXNlIHRoZSBtZWFuIG9mIGRlbHRhcyBpbnN0ZWFkXG4gICAgICAgICAgICBsZXQgZGVsdGEgPSBQb2ludHMubWVhbihkMSwgZDIpIC8vUG9pbnRzLnN1YnRyYWN0KGNtLCBwbSlcbiAgICAgICAgICAgIGxldCB6b29tID0gMS4wXG4gICAgICAgICAgICBsZXQgZGlzdGFuY2UxID0gUG9pbnRzLmRpc3RhbmNlKHAxLCBwMilcbiAgICAgICAgICAgIGxldCBkaXN0YW5jZTIgPSBQb2ludHMuZGlzdGFuY2UoYzEsIGMyKVxuICAgICAgICAgICAgaWYgKGRpc3RhbmNlMSAhPSAwICYmIGRpc3RhbmNlMiAhPSAwKSB7XG4gICAgICAgICAgICAgICAgem9vbSA9IGRpc3RhbmNlMiAvIGRpc3RhbmNlMVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGN1cnJlbnRBbmdsZSA9IFBvaW50cy5hbmdsZShjMSwgYzIpXG4gICAgICAgICAgICBsZXQgcHJldmlvdXNBbmdsZSA9IFBvaW50cy5hbmdsZShwMSwgcDIpXG4gICAgICAgICAgICBsZXQgYWxwaGEgPSB0aGlzLmRpZmZBbmdsZShjdXJyZW50QW5nbGUsIHByZXZpb3VzQW5nbGUpXG4gICAgICAgICAgICByZXR1cm4gbmV3IEludGVyYWN0aW9uRGVsdGEoZGVsdGEueCwgZGVsdGEueSwgem9vbSwgYWxwaGEsIGNtKVxuICAgICAgICB9IGVsc2UgaWYgKGNzaXplID09IDEgJiYgcHNpemUgPT0gMSAmJiB0aGlzLmN1cnJlbnQuZmlyc3RLZXkoKSA9PSB0aGlzLnByZXZpb3VzLmZpcnN0S2V5KCkpIHtcbiAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZW5zdXJlIHRoYXQgdGhlIGtleXMgYXJlIHRoZSBzYW1lXG4gICAgICAgICAgICBsZXQgY3VycmVudCA9IHRoaXMuY3VycmVudC5maXJzdCgpXG4gICAgICAgICAgICBsZXQgcHJldmlvdXMgPSB0aGlzLnByZXZpb3VzLmZpcnN0KClcbiAgICAgICAgICAgIGxldCBkZWx0YSA9IFBvaW50cy5zdWJ0cmFjdChjdXJyZW50LCBwcmV2aW91cylcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW50ZXJhY3Rpb25EZWx0YShkZWx0YS54LCBkZWx0YS55LCAxLjAsIDAuMCwgY3VycmVudClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIHN0YXJ0ZWQoa2V5LCBwb2ludCkge1xuICAgICAgICB0aGlzLmN1cnJlbnQuc2V0KGtleSwgcG9pbnQpXG4gICAgICAgIHRoaXMuc3RhcnQuc2V0KGtleSwgcG9pbnQpXG4gICAgICAgIHRoaXMucHJldmlvdXMuc2V0KGtleSwgcG9pbnQpXG4gICAgICAgIHRoaXMudGltZXN0YW1wcy5zZXQoa2V5LCBwZXJmb3JtYW5jZS5ub3coKSlcbiAgICB9XG5cbiAgICB1cGRhdGUoa2V5LCBwb2ludCkge1xuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWZmIHRoZSBrZXkgaXMgbmV3XG4gICAgICAgIHRoaXMuY3VycmVudC5zZXQoa2V5LCBwb2ludClcbiAgICAgICAgaWYgKCF0aGlzLnN0YXJ0LmhhcyhrZXkpKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0LnNldChrZXksIHBvaW50KVxuICAgICAgICAgICAgdGhpcy5wcmV2aW91cy5zZXQoa2V5LCBwb2ludClcbiAgICAgICAgICAgIHRoaXMudGltZXN0YW1wcy5zZXQoa2V5LCBwZXJmb3JtYW5jZS5ub3coKSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgdXBkYXRlUHJldmlvdXMoKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmN1cnJlbnQua2V5cygpKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzLnNldChrZXksIHRoaXMuY3VycmVudC5nZXQoa2V5KSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0b3Aoa2V5LCBwb2ludCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50LmhhcyhrZXkpKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQuZGVsZXRlKGtleSlcbiAgICAgICAgICAgIHRoaXMucHJldmlvdXMuZGVsZXRlKGtleSlcbiAgICAgICAgICAgIHRoaXMuZW5kZWQuc2V0KGtleSwgcG9pbnQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmaW5pc2goa2V5LCBwb2ludCkge1xuICAgICAgICB0aGlzLmN1cnJlbnQuZGVsZXRlKGtleSlcbiAgICAgICAgdGhpcy5wcmV2aW91cy5kZWxldGUoa2V5KVxuICAgICAgICB0aGlzLnN0YXJ0LmRlbGV0ZShrZXkpXG4gICAgICAgIHRoaXMudGltZXN0YW1wcy5kZWxldGUoa2V5KVxuICAgICAgICB0aGlzLmVuZGVkLmRlbGV0ZShrZXkpXG4gICAgfVxuXG4gICAgaXNGaW5pc2hlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudC5zaXplID09IDBcbiAgICB9XG5cbiAgICBpc05vTG9uZ2VyVHdvRmluZ2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcmV2aW91cy5zaXplID4gMSAmJiB0aGlzLmN1cnJlbnQuc2l6ZSA8IDJcbiAgICB9XG5cbiAgICBpc1RhcChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmlzVGFwKGtleSlcbiAgICB9XG5cbiAgICBpc0RvdWJsZVRhcChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmlzRG91YmxlVGFwKGtleSlcbiAgICB9XG5cbiAgICBpc0xvbmdQcmVzcyhrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmlzTG9uZ1ByZXNzKGtleSlcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJbnRlcmFjdGlvbiBleHRlbmRzIEludGVyYWN0aW9uUG9pbnRzIHtcbiAgICBjb25zdHJ1Y3Rvcih0YXBEaXN0YW5jZSA9IDEwLCB0YXBEdXJhdGlvbiA9IDI1MC4wLCBsb25nUHJlc3NUaW1lID0gNTAwLjApIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICB0aGlzLnRhcERpc3RhbmNlID0gdGFwRGlzdGFuY2VcbiAgICAgICAgdGhpcy50YXBDb3VudHMgPSBuZXcgTWFwKClcbiAgICAgICAgdGhpcy50YXBQb3NpdGlvbnMgPSBuZXcgTWFwKClcbiAgICAgICAgdGhpcy50YXBUaW1lc3RhbXBzID0gbmV3IE1hcCgpXG4gICAgICAgIHRoaXMudGFwRHVyYXRpb24gPSB0YXBEdXJhdGlvblxuICAgICAgICB0aGlzLmxvbmdQcmVzc1RpbWUgPSBsb25nUHJlc3NUaW1lXG4gICAgICAgIHRoaXMudGFyZ2V0cyA9IG5ldyBNYXAoKVxuICAgICAgICB0aGlzLnN1YkludGVyYWN0aW9ucyA9IG5ldyBNYXAoKSAvLyB0YXJnZXQ6T2JqZWN0IDogSW50ZXJhY3Rpb25Qb2ludHNcbiAgICB9XG5cbiAgICBzdG9wKGtleSwgcG9pbnQpIHtcbiAgICAgICAgc3VwZXIuc3RvcChrZXksIHBvaW50KVxuICAgICAgICBmb3IgKGxldCBwb2ludHMgb2YgdGhpcy5zdWJJbnRlcmFjdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIHBvaW50cy5zdG9wKGtleSwgcG9pbnQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZGRUYXJnZXQoa2V5LCB0YXJnZXQpIHtcbiAgICAgICAgdGhpcy50YXJnZXRzLnNldChrZXksIHRhcmdldClcbiAgICAgICAgdGhpcy5zdWJJbnRlcmFjdGlvbnMuc2V0KHRhcmdldCwgbmV3IEludGVyYWN0aW9uUG9pbnRzKHRoaXMpKVxuICAgIH1cblxuICAgIHJlbW92ZVRhcmdldChrZXkpIHtcbiAgICAgICAgbGV0IHRhcmdldCA9IHRoaXMudGFyZ2V0cy5nZXQoa2V5KVxuICAgICAgICB0aGlzLnRhcmdldHMuZGVsZXRlKGtleSlcbiAgICAgICAgLy8gT25seSByZW1vdmUgdGFyZ2V0IGlmIG5vIGtleXMgYXJlIHJlZmVyaW5nIHRvIHRoZSB0YXJnZXRcbiAgICAgICAgbGV0IHJlbW92ZSA9IHRydWVcbiAgICAgICAgZm9yIChsZXQgdCBvZiB0aGlzLnRhcmdldHMudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IHQpIHtcbiAgICAgICAgICAgICAgICByZW1vdmUgPSBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgIHRoaXMuc3ViSW50ZXJhY3Rpb25zLmRlbGV0ZSh0YXJnZXQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmaW5pc2goa2V5LCBwb2ludCkge1xuICAgICAgICBzdXBlci5maW5pc2goa2V5LCBwb2ludClcbiAgICAgICAgdGhpcy5yZW1vdmVUYXJnZXQoa2V5KVxuICAgIH1cblxuICAgIG1hcEludGVyYWN0aW9uKHBvaW50cywgYXNwZWN0cywgbWFwcGluZ0Z1bmMpIHtcbiAgICAgICAgLy8gTWFwIGNlbnRyYWxseSByZWdpc3RlcmVkIHBvaW50cyB0byB0YXJnZXQgaW50ZXJhY3Rpb25zXG4gICAgICAgIC8vIFJldHVybnMgYW4gYXJyYXkgb2YgW3RhcmdldCwgdXBkYXRlZCBzdWJJbnRlcmFjdGlvbl0gcGFpcnNcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyBNYXAoKVxuICAgICAgICBmb3IgKGxldCBrZXkgaW4gcG9pbnRzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXRzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRhcmdldCA9IHRoaXMudGFyZ2V0cy5nZXQoa2V5KVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN1YkludGVyYWN0aW9ucy5oYXModGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgaW50ZXJhY3Rpb24gPSB0aGlzLnN1YkludGVyYWN0aW9ucy5nZXQodGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBhc3BlY3Qgb2YgYXNwZWN0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBvaW50TWFwID0gdGhpc1thc3BlY3RdXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcG9pbnQgPSBwb2ludE1hcC5nZXQoa2V5KVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG1hcHBlZCA9IG1hcHBpbmdGdW5jKHBvaW50LCB0YXJnZXQpXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvblthc3BlY3RdLnNldChrZXksIG1hcHBlZClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0KHRhcmdldCwgaW50ZXJhY3Rpb24pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICByZWdpc3RlclRhcChrZXksIHBvaW50KSB7XG4gICAgICAgIGlmICh0aGlzLnRhcENvdW50cy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgbGV0IGNvdW50ID0gdGhpcy50YXBDb3VudHMuZ2V0KGtleSlcbiAgICAgICAgICAgIHRoaXMudGFwQ291bnRzLnNldChrZXksIGNvdW50KzEpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRhcENvdW50cy5zZXQoa2V5LCAxKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudGFwUG9zaXRpb25zLnNldChrZXksIHBvaW50KVxuICAgICAgICB0aGlzLnRhcFRpbWVzdGFtcHMuc2V0KGtleSwgcGVyZm9ybWFuY2Uubm93KCkpXG4gICAgfVxuXG4gICAgdW5yZWdpc3RlclRhcChrZXkpIHtcbiAgICAgICAgdGhpcy50YXBDb3VudHMuZGVsZXRlKGtleSlcbiAgICAgICAgdGhpcy50YXBQb3NpdGlvbnMuZGVsZXRlKGtleSlcbiAgICAgICAgdGhpcy50YXBUaW1lc3RhbXBzLmRlbGV0ZShrZXkpXG4gICAgfVxuXG4gICAgaXNUYXAoa2V5KSB7XG4gICAgICAgIGxldCBlbmRlZCA9IHRoaXMuZW5kZWQuZ2V0KGtleSlcbiAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5zdGFydC5nZXQoa2V5KVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBzdGFydCAmJlxuICAgICAgICAgICAgZW5kZWQgJiZcbiAgICAgICAgICAgIFBvaW50cy5kaXN0YW5jZShlbmRlZCwgc3RhcnQpIDwgdGhpcy50YXBEaXN0YW5jZVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGxldCB0MSA9IHRoaXMudGltZXN0YW1wcy5nZXQoa2V5KVxuICAgICAgICAgICAgbGV0IHRvb2tMb25nID0gcGVyZm9ybWFuY2Uubm93KCkgPiB0MSArIHRoaXMubG9uZ1ByZXNzVGltZVxuICAgICAgICAgICAgaWYgKHRvb2tMb25nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlzRG91YmxlVGFwKGtleSkge1xuICAgICAgICBsZXQgZW5kZWQgPSB0aGlzLmVuZGVkLmdldChrZXkpXG4gICAgICAgIGlmICh0aGlzLnRhcENvdW50cy5oYXMoa2V5KSAmJiB0aGlzLnRhcENvdW50cy5nZXQoa2V5KSA+IDIpIHtcbiAgICAgICAgICAgIHRoaXMudW5yZWdpc3RlclRhcChrZXkpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudGFwUG9zaXRpb25zLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICBsZXQgcG9zID0gdGhpcy50YXBQb3NpdGlvbnMuZ2V0KGtleSlcbiAgICAgICAgICAgIGlmIChQb2ludHMuZGlzdGFuY2UoZW5kZWQsIHBvcykgPiB0aGlzLnRhcERpc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51bnJlZ2lzdGVyVGFwKGtleSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50YXBUaW1lc3RhbXBzLmhhcyhrZXkpICYmIHBlcmZvcm1hbmNlLm5vdygpID4gdGhpcy50YXBUaW1lc3RhbXBzLmdldChrZXkpICsgdGhpcy50YXBEdXJhdGlvbikge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcInRhcCB0b28gbG9uZ1wiKVxuICAgICAgICAgICAgdGhpcy51bnJlZ2lzdGVyVGFwKGtleSlcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0ID0gZmFsc2VcbiAgICAgICAgaWYgKHRoaXMuaXNUYXAoa2V5KSkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyVGFwKGtleSwgZW5kZWQpXG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLnRhcENvdW50cy5nZXQoa2V5KSA9PSAyXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnVucmVnaXN0ZXJUYXAoa2V5KVxuICAgICAgICB9XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJpc0RvdWJsZVRhcFwiLCB0aGlzLnRhcENvdW50cy5nZXQoa2V5KSwgcmVzdWx0KVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgaXNBbnlUYXAoKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmVuZGVkLmtleXMoKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNUYXAoa2V5KSkgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpc0xvbmdQcmVzcyhrZXkpIHtcbiAgICAgICAgbGV0IGVuZGVkID0gdGhpcy5lbmRlZC5nZXQoa2V5KVxuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnN0YXJ0LmdldChrZXkpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHN0YXJ0ICYmXG4gICAgICAgICAgICBlbmRlZCAmJlxuICAgICAgICAgICAgUG9pbnRzLmRpc3RhbmNlKGVuZGVkLCBzdGFydCkgPCB0aGlzLnRhcERpc3RhbmNlXG4gICAgICAgICkge1xuICAgICAgICAgICAgbGV0IHQxID0gdGhpcy50aW1lc3RhbXBzLmdldChrZXkpXG4gICAgICAgICAgICBsZXQgdG9va0xvbmcgPSBwZXJmb3JtYW5jZS5ub3coKSA+IHQxICsgdGhpcy5sb25nUHJlc3NUaW1lXG4gICAgICAgICAgICBpZiAodG9va0xvbmcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaXNBbnlMb25nUHJlc3MoKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmVuZGVkLmtleXMoKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb25nUHJlc3Moa2V5KSkgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpc1N0eWx1cyhrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA9PT0gJ3N0eWx1cydcbiAgICB9XG59XG5cbi8qKlxuICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBtYWluIGRlbGVnYXRlIGZ1bmN0aW9uYWxpdHk6IEFsbCBuZWNlc3NhcnkgZXZlbnQgaGFuZGxlcnMgYXJlIHJlZ2lzdGVyZWQgZm9yIHRoZVxuICogZ2l2ZW4gZWxlbWVudC4gVXNlcyBQb2ludGVyRXZlbnRzIGlmIGF2YWlsYWJsZSBvciBUb3VjaEV2ZW50cyBvbiBpT1MuIFRoZSBmYWxsYmFjayBpcyBvbiBtb3VzZSBldmVudHMuXG4gKiBDb2xsZWN0cyB0aGUgZXZlbnRzIGlmIHRoZSBpbnRlcmFjdGlvbiB0YXJnZXQgY2FwdHVyZXMgdGhlIHN0YXJ0IGV2ZW50IChpLmUuIGRlY2xhcmVzIHRoYXRcbiAqIHRoZSB0YXJnZXQgd2FudHMgdGhlIHN0YXJ0IGV2ZW50IGFzIHdlbGwgYXMgYWxsIGZvbGxvd2luZyBtb3ZlIGFuZCBlbmQgZXZjZW50cy4pXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIEludGVyYWN0aW9uRGVsZWdhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIEludGVyYWN0aW9uRGVsZWdhdGUge1xuICAgIC8vIExvbmcgcHJlc3M6IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTkzMDg5NS9ob3ctbG9uZy1pcy10aGUtZXZlbnQtb25sb25ncHJlc3MtaW4tdGhlLWFuZHJvaWRcbiAgICAvLyBTdHlsdXMgc3VwcG9ydDogaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3RvdWNoLWV2ZW50cy9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgSW50ZXJhY3Rpb25EZWxlZ2F0ZS5cbiAgICAgKiBAcGFyYW0ge2FueX0gZWxlbWVudFxuICAgICAqIEBwYXJhbSB7YW55fSB0YXJnZXRcbiAgICAgKiBAcGFyYW0ge2FueX0gW3sgbW91c2VXaGVlbEVsZW1lbnQgPSBudWxsLCB1c2VDYXB0dXJlID0gdHJ1ZSwgY2FwdHVyZVBvaW50ZXJFdmVudHMgPSB0cnVlLCBkZWJ1ZyA9IGZhbHNlIH09e31dXG4gICAgICogQG1lbWJlcm9mIEludGVyYWN0aW9uRGVsZWdhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgZWxlbWVudCxcbiAgICAgICAgdGFyZ2V0LFxuICAgICAgICB7IG1vdXNlV2hlZWxFbGVtZW50ID0gbnVsbCwgdXNlQ2FwdHVyZSA9IHRydWUsIGNhcHR1cmVQb2ludGVyRXZlbnRzID0gdHJ1ZSwgY2FuY2VsT25XaW5kb3dPdXQgPSB0cnVlLCBkZWJ1ZyA9IGZhbHNlIH0gPSB7fVxuICAgICkge1xuICAgICAgICB0aGlzLmRlYnVnID0gZGVidWdcbiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbiA9IG5ldyBJbnRlcmFjdGlvbigpXG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnRcbiAgICAgICAgdGhpcy5tb3VzZVdoZWVsRWxlbWVudCA9IG1vdXNlV2hlZWxFbGVtZW50IHx8IGVsZW1lbnRcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXRcbiAgICAgICAgdGhpcy51c2VDYXB0dXJlID0gdXNlQ2FwdHVyZVxuICAgICAgICB0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzID0gY2FwdHVyZVBvaW50ZXJFdmVudHNcbiAgICAgICAgdGhpcy5jYW5jZWxPbldpbmRvd091dCA9IGNhbmNlbE9uV2luZG93T3V0XG4gICAgICAgIHRoaXMuc2V0dXBJbnRlcmFjdGlvbigpXG4gICAgfVxuXG4gICAgc2V0dXBJbnRlcmFjdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuZGVidWcpIHtcbiAgICAgICAgICAgIGxldCBlcnJvciA9IHRoaXMudGFyZ2V0SW50ZXJmYWNlLmltcGxlbWVudGF0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQuY29uc3RydWN0b3JcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGlmIChlcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBJSW50ZXJhY3Rpb25UYXJnZXQ6ICcgKyBlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldHVwVG91Y2hJbnRlcmFjdGlvbigpXG4gICAgICAgIHRoaXMuc2V0dXBNb3VzZVdoZWVsSW50ZXJhY3Rpb24oKVxuICAgIH1cblxuICAgIGdldCB0YXJnZXRJbnRlcmZhY2UoKSB7XG4gICAgICAgIHJldHVybiBJSW50ZXJhY3Rpb25UYXJnZXRcbiAgICB9XG5cbiAgICBzZXR1cFRvdWNoSW50ZXJhY3Rpb24oKSB7XG4gICAgICAgIGxldCBlbGVtZW50ID0gdGhpcy5lbGVtZW50XG4gICAgICAgIGxldCB1c2VDYXB0dXJlID0gdGhpcy51c2VDYXB0dXJlXG4gICAgICAgIGlmICh3aW5kb3cuUG9pbnRlckV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ1BvaW50ZXIgQVBJJyArIHdpbmRvdy5Qb2ludGVyRXZlbnQpXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3BvaW50ZXJkb3duJyxcbiAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdwb2ludGVyZG93bicsIGUucG9pbnRlcklkKVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXB0dXJlKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXB0dXJlUG9pbnRlckV2ZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uU3RhcnQoZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICdwb2ludGVybW92ZScsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygncG9pbnRlcm1vdmUnLCBlLnBvaW50ZXJJZClcblxuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnBvaW50ZXJUeXBlID09ICd0b3VjaCcgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChlLnBvaW50ZXJUeXBlID09ICdtb3VzZScgJiYgRXZlbnRzLmlzTW91c2VEb3duKGUpKVxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuY2FwdHVyZShlKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3BvaW50ZXJtb3ZlIGNhcHR1cmVkJywgZS5wb2ludGVySWQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTW92ZShlKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3BvaW50ZXJ1cCcsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygncG9pbnRlcnVwJylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVuZChlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXB0dXJlUG9pbnRlckV2ZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZClcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3BvaW50ZXJjYW5jZWwnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ3BvaW50ZXJjYW5jZWwnKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRW5kKGUpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzKVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jYXB0dXJlUG9pbnRlckV2ZW50cykge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgJ3BvaW50ZXJsZWF2ZScsXG4gICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdwb2ludGVybGVhdmUnKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUudGFyZ2V0ID09IGVsZW1lbnQpIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAncG9pbnRlcm91dCcsXG4gICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdwb2ludGVyb3V0JylcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLnRhcmdldCA9PSBlbGVtZW50KSB0aGlzLm9uRW5kKGUpXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNhbmNlbE9uV2luZG93T3V0KSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdwb2ludGVyb3V0JyxcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXQgPT0gZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlQ2FwdHVyZSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKHdpbmRvdy5Ub3VjaEV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ1RvdWNoIEFQSScpXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3RvdWNoc3RhcnQnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZylcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCd0b3VjaHN0YXJ0JywgdGhpcy50b3VjaFBvaW50cyhlKSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FwdHVyZShlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgdG91Y2ggb2YgZS5jaGFuZ2VkVG91Y2hlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25TdGFydCh0b3VjaClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICd0b3VjaG1vdmUnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZylcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCd0b3VjaG1vdmUnLCB0aGlzLnRvdWNoUG9pbnRzKGUpLCBlKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB0b3VjaCBvZiBlLmNoYW5nZWRUb3VjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTW92ZSh0b3VjaClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB0b3VjaCBvZiBlLnRhcmdldFRvdWNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Nb3ZlKHRvdWNoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3RvdWNoZW5kJyxcbiAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCd0b3VjaGVuZCcsIHRoaXMudG91Y2hQb2ludHMoZSkpXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHRvdWNoIG9mIGUuY2hhbmdlZFRvdWNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQodG91Y2gpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAndG91Y2hjYW5jZWwnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZylcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0b3VjaGNhbmNlbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50YXJnZXRUb3VjaGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmNoYW5nZWRUb3VjaGVzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB0b3VjaCBvZiBlLmNoYW5nZWRUb3VjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRW5kKHRvdWNoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ01vdXNlIEFQSScpXG5cbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAnbW91c2Vkb3duJyxcbiAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdtb3VzZWRvd24nLCBlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXB0dXJlKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uU3RhcnQoZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICdtb3VzZW1vdmUnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBEb3cgd2Ugb25seSB1c2UgbW92ZSBldmVudHMgaWYgdGhlIG1vdXNlIGlzIGRvd24/XG4gICAgICAgICAgICAgICAgICAgIC8vIEhPdmVyIGVmZmVjdHMgaGF2ZSB0byBiZSBpbXBsZW1lbnRlZCBieSBvdGhlciBtZWFuc1xuICAgICAgICAgICAgICAgICAgICAvLyAmJiBFdmVudHMuaXNNb3VzZURvd24oZSkpXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKEV2ZW50cy5pc01vdXNlRG93bihlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ21vdXNlbW92ZScsIGUpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTW92ZShlKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ21vdXNldXAnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ21vdXNldXAnLCBlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRW5kKGUpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jYXB0dXJlUG9pbnRlckV2ZW50cykge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgJ21vdXNlb3V0JyxcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXQgPT0gZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJTaG91bGRuJ3QgaGFwcGVuOiBtb3VzZW91dCBlbmRzIGludGVyYWN0aW9uXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmNhbmNlbE9uV2luZG93T3V0KSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdtb3VzZW91dCcsXG4gICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUudGFyZ2V0ID09IGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRW5kKGUpXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZUNhcHR1cmUpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0Rlc2NlbmRhbnQocGFyZW50LCBjaGlsZCkge1xuICAgICAgICBpZiAocGFyZW50ID09IGNoaWxkKSByZXR1cm4gdHJ1ZVxuICAgICAgICBsZXQgbm9kZSA9IGNoaWxkLnBhcmVudE5vZGVcbiAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKG5vZGUgPT0gcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICB0b3VjaFBvaW50cyhldmVudCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gW11cbiAgICAgICAgZm9yIChsZXQgdG91Y2ggb2YgZXZlbnQuY2hhbmdlZFRvdWNoZXMpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRoaXMuZXh0cmFjdFBvaW50KHRvdWNoKSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgc2V0dXBNb3VzZVdoZWVsSW50ZXJhY3Rpb24oKSB7XG4gICAgICAgIHRoaXMubW91c2VXaGVlbEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdtb3VzZXdoZWVsJyxcbiAgICAgICAgICAgIHRoaXMub25Nb3VzZVdoZWVsLmJpbmQodGhpcyksXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICAgICAgdGhpcy5tb3VzZVdoZWVsRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ0RPTU1vdXNlU2Nyb2xsJyxcbiAgICAgICAgICAgIHRoaXMub25Nb3VzZVdoZWVsLmJpbmQodGhpcyksXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9XG5cbiAgICBvbk1vdXNlV2hlZWwoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FwdHVyZShldmVudCkgJiYgdGhpcy50YXJnZXQub25Nb3VzZVdoZWVsKSB7XG4gICAgICAgICAgICB0aGlzLnRhcmdldC5vbk1vdXNlV2hlZWwoZXZlbnQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvL2NvbnNvbGUud2FybignVGFyZ2V0IGhhcyBubyBvbk1vdXNlV2hlZWwgY2FsbGJhY2snKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25TdGFydChldmVudCkge1xuICAgICAgICBsZXQgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0UG9pbnQoZXZlbnQpXG4gICAgICAgIHRoaXMuc3RhcnRJbnRlcmFjdGlvbihldmVudCwgZXh0cmFjdGVkKVxuICAgICAgICB0aGlzLnRhcmdldC5vblN0YXJ0KGV2ZW50LCB0aGlzLmludGVyYWN0aW9uKVxuICAgIH1cblxuICAgIG9uTW92ZShldmVudCkge1xuICAgICAgICBsZXQgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0UG9pbnQoZXZlbnQsICdhbGwnKVxuICAgICAgICB0aGlzLnVwZGF0ZUludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgICAgIHRoaXMudGFyZ2V0Lm9uTW92ZShldmVudCwgdGhpcy5pbnRlcmFjdGlvbilcbiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbi51cGRhdGVQcmV2aW91cygpXG4gICAgfVxuXG4gICAgb25FbmQoZXZlbnQpIHtcbiAgICAgICAgbGV0IGV4dHJhY3RlZCA9IHRoaXMuZXh0cmFjdFBvaW50KGV2ZW50LCAnY2hhbmdlZFRvdWNoZXMnKVxuICAgICAgICB0aGlzLmVuZEludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgICAgIHRoaXMudGFyZ2V0Lm9uRW5kKGV2ZW50LCB0aGlzLmludGVyYWN0aW9uKVxuICAgICAgICB0aGlzLmZpbmlzaEludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNrcyB0aGUgdGFyZ2V0IHdoZXRoZXIgdGhlIGV2ZW50IHNob3VsZCBiZSBjYXB0dXJlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHthbnl9IGV2ZW50XG4gICAgICogQHJldHVybnMge2Jvb2x9XG4gICAgICogQG1lbWJlcm9mIEludGVyYWN0aW9uRGVsZWdhdGVcbiAgICAgKi9cbiAgICBjYXB0dXJlKGV2ZW50KSB7XG4gICAgICAgIGlmIChFdmVudHMuaXNDYXB0dXJlZChldmVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGxldCBjYXB0dXJlZCA9IHRoaXMudGFyZ2V0LmNhcHR1cmUoZXZlbnQpXG4gICAgICAgIHJldHVybiBjYXB0dXJlZFxuICAgIH1cblxuICAgIGdldFBvc2l0aW9uKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiB7IHg6IGV2ZW50LmNsaWVudFgsIHk6IGV2ZW50LmNsaWVudFkgfVxuICAgIH1cblxuICAgIGV4dHJhY3RQb2ludChldmVudCwgdG91Y2hFdmVudEtleSA9ICdhbGwnKSB7XG4gICAgICAgIC8vICd0YXJnZXRUb3VjaGVzJ1xuICAgICAgICBsZXQgcmVzdWx0ID0ge31cbiAgICAgICAgc3dpdGNoIChldmVudC5jb25zdHJ1Y3Rvci5uYW1lKSB7XG4gICAgICAgICAgICBjYXNlICdNb3VzZUV2ZW50JzpcbiAgICAgICAgICAgICAgICBsZXQgYnV0dG9ucyA9IGV2ZW50LmJ1dHRvbnMgfHwgZXZlbnQud2hpY2hcbiAgICAgICAgICAgICAgICBpZiAoYnV0dG9ucykgcmVzdWx0Wydtb3VzZSddID0gdGhpcy5nZXRQb3NpdGlvbihldmVudClcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSAnUG9pbnRlckV2ZW50JzpcbiAgICAgICAgICAgICAgICByZXN1bHRbZXZlbnQucG9pbnRlcklkLnRvU3RyaW5nKCldID0gdGhpcy5nZXRQb3NpdGlvbihldmVudClcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSAnVG91Y2gnOlxuICAgICAgICAgICAgICAgIGxldCBpZCA9XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnRvdWNoVHlwZSA9PT0gJ3N0eWx1cydcbiAgICAgICAgICAgICAgICAgICAgICAgID8gJ3N0eWx1cydcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZXZlbnQuaWRlbnRpZmllci50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgcmVzdWx0W2lkXSA9IHRoaXMuZ2V0UG9zaXRpb24oZXZlbnQpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgIGNhc2UgJ1RvdWNoRXZlbnQnOlxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIC8vIE5lZWRzIHRvIGJlIG9ic2VydmVkOiBQZXJoYXBzIGNoYW5nZWRUb3VjaGVzIGFyZSBhbGwgd2UgbmVlZC4gSWYgc29cbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAvLyB3ZSBjYW4gcmVtb3ZlIHRoZSB0b3VjaEV2ZW50S2V5IGRlZmF1bHQgcGFyYW1ldGVyXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgaWYgKHRvdWNoRXZlbnRLZXkgPT0gJ2FsbCcpIHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgZm9yKGxldCB0IG9mIGV2ZW50LnRhcmdldFRvdWNoZXMpIHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFt0LmlkZW50aWZpZXIudG9TdHJpbmcoKV0gPSB0aGlzLmdldFBvc2l0aW9uKHQpXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgZm9yKGxldCB0IG9mIGV2ZW50LmNoYW5nZWRUb3VjaGVzKSB7XG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbdC5pZGVudGlmaWVyLnRvU3RyaW5nKCldID0gdGhpcy5nZXRQb3NpdGlvbih0KVxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICBmb3IobGV0IHQgb2YgZXZlbnQuY2hhbmdlZFRvdWNoZXMpIHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFt0LmlkZW50aWZpZXIudG9TdHJpbmcoKV0gPSB0aGlzLmdldFBvc2l0aW9uKHQpXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgaW50ZXJhY3Rpb25TdGFydGVkKGV2ZW50LCBrZXksIHBvaW50KSB7XG4gICAgICAgIC8vIENhbGxiYWNrOiBjYW4gYmUgb3ZlcndyaXR0ZW5cbiAgICB9XG5cbiAgICBpbnRlcmFjdGlvbkVuZGVkKGV2ZW50LCBrZXksIHBvaW50KSB7XG4gICAgICAgIC8vIENhbGxiYWNrOiBjYW4gYmUgb3ZlcndyaXR0ZW5cbiAgICB9XG5cbiAgICBpbnRlcmFjdGlvbkZpbmlzaGVkKGV2ZW50LCBrZXksIHBvaW50KSB7IH1cblxuICAgIHN0YXJ0SW50ZXJhY3Rpb24oZXZlbnQsIGV4dHJhY3RlZCkge1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gZXh0cmFjdGVkKSB7XG4gICAgICAgICAgICBsZXQgcG9pbnQgPSBleHRyYWN0ZWRba2V5XVxuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbi5zdGFydGVkKGtleSwgcG9pbnQpXG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uU3RhcnRlZChldmVudCwga2V5LCBwb2ludClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZUludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIGV4dHJhY3RlZCkge1xuICAgICAgICAgICAgbGV0IHBvaW50ID0gZXh0cmFjdGVkW2tleV1cbiAgICAgICAgICAgIGxldCB1cGRhdGVkID0gdGhpcy5pbnRlcmFjdGlvbi51cGRhdGUoa2V5LCBwb2ludClcbiAgICAgICAgICAgIGlmICh1cGRhdGVkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwibmV3IHBvaW50ZXIgaW4gdXBkYXRlSW50ZXJhY3Rpb24gc2hvdWxkbid0IGhhcHBlblwiKVxuICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25TdGFydGVkKGV2ZW50LCBrZXksIHBvaW50KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZW5kSW50ZXJhY3Rpb24oZXZlbnQsIGVuZGVkKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBlbmRlZCkge1xuICAgICAgICAgICAgbGV0IHBvaW50ID0gZW5kZWRba2V5XVxuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbi5zdG9wKGtleSwgcG9pbnQpXG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uRW5kZWQoZXZlbnQsIGtleSwgcG9pbnQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmaW5pc2hJbnRlcmFjdGlvbihldmVudCwgZW5kZWQpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIGVuZGVkKSB7XG4gICAgICAgICAgICBsZXQgcG9pbnQgPSBlbmRlZFtrZXldXG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uLmZpbmlzaChrZXksIHBvaW50KVxuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbkZpbmlzaGVkKGV2ZW50LCBrZXksIHBvaW50KVxuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBBIHNwZWNpYWwgSW50ZXJhY3Rpb25EZWxlZ2F0ZSB0aGF0IG1hcHMgZXZlbnRzIHRvIHNwZWNpZmljIHBhcnRzIG9mXG4gKiB0aGUgaW50ZXJhY3Rpb24gdGFyZ2V0LiBUaGUgSW50ZXJhY3Rpb25UYXJnZXQgbXVzdCBpbXBsZW1lbnQgYSBmaW5kVGFyZ2V0XG4gKiBtZXRob2QgdGhhdCByZXR1cm5zIGFuIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhlIElJbnRlcmFjdGlvblRhcmdldCBpbnRlcmZhY2UuXG4gKlxuICogSWYgdGhlIEludGVyYWN0aW9uVGFyZ2V0IGFsc28gaW1wbGVtZW50cyBhIG1hcFBvc2l0aW9uVG9Qb2ludCBtZXRob2QgdGhpc1xuICogaXMgdXNlZCB0byBtYXAgdGhlIHBvaW50cyB0byB0aGUgbG9jYWwgY29vcmRpbmF0ZSBzcGFjZSBvZiB0aGUgdGhlIHRhcmdldC5cbiAqXG4gKiBUaGlzIG1ha2VzIGl0IGVhc2llciB0byBsb29rdXAgZWxlbWVudHMgYW5kIHJlbGF0ZSBldmVudHMgdG8gbG9jYWxcbiAqIHBvc2l0aW9ucy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgSW50ZXJhY3Rpb25NYXBwZXJcbiAqIEBleHRlbmRzIHtJbnRlcmFjdGlvbkRlbGVnYXRlfVxuICovXG5leHBvcnQgY2xhc3MgSW50ZXJhY3Rpb25NYXBwZXIgZXh0ZW5kcyBJbnRlcmFjdGlvbkRlbGVnYXRlIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHsgdGFwRGlzdGFuY2UgPSAxMCwgbG9uZ1ByZXNzVGltZSA9IDUwMC4wLCB1c2VDYXB0dXJlID0gdHJ1ZSwgbW91c2VXaGVlbEVsZW1lbnQgPSBudWxsIH0gPSB7fVxuICAgICkge1xuICAgICAgICBzdXBlcihlbGVtZW50LCB0YXJnZXQsIHsgdGFwRGlzdGFuY2UsIHVzZUNhcHR1cmUsIGxvbmdQcmVzc1RpbWUsIG1vdXNlV2hlZWxFbGVtZW50IH0pXG4gICAgfVxuXG4gICAgZ2V0IHRhcmdldEludGVyZmFjZSgpIHtcbiAgICAgICAgcmV0dXJuIElJbnRlcmFjdGlvbk1hcHBlclRhcmdldFxuICAgIH1cblxuICAgIG1hcFBvc2l0aW9uVG9Qb2ludChwb2ludCwgZWxlbWVudCA9IG51bGwpIHtcbiAgICAgICAgaWYgKHRoaXMudGFyZ2V0Lm1hcFBvc2l0aW9uVG9Qb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFyZ2V0Lm1hcFBvc2l0aW9uVG9Qb2ludChwb2ludCwgZWxlbWVudClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcG9pbnRcbiAgICB9XG5cbiAgICBpbnRlcmFjdGlvblN0YXJ0ZWQoZXZlbnQsIGtleSwgcG9pbnQpIHtcbiAgICAgICAgaWYgKHRoaXMudGFyZ2V0LmZpbmRUYXJnZXQpIHtcbiAgICAgICAgICAgIGxldCBsb2NhbCA9IHRoaXMubWFwUG9zaXRpb25Ub1BvaW50KHBvaW50KVxuICAgICAgICAgICAgbGV0IGZvdW5kID0gdGhpcy50YXJnZXQuZmluZFRhcmdldChldmVudCwgbG9jYWwsIHBvaW50KVxuICAgICAgICAgICAgaWYgKGZvdW5kICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uLmFkZFRhcmdldChrZXksIGZvdW5kKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb3VzZVdoZWVsKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmNhcHR1cmUoZXZlbnQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQuZmluZFRhcmdldCkge1xuICAgICAgICAgICAgICAgIGxldCBwb2ludCA9IHRoaXMuZ2V0UG9zaXRpb24oZXZlbnQpXG4gICAgICAgICAgICAgICAgbGV0IGxvY2FsID0gdGhpcy5tYXBQb3NpdGlvblRvUG9pbnQocG9pbnQpXG4gICAgICAgICAgICAgICAgbGV0IGZvdW5kID0gdGhpcy50YXJnZXQuZmluZFRhcmdldChldmVudCwgbG9jYWwsIHBvaW50KVxuICAgICAgICAgICAgICAgIGlmIChmb3VuZCAhPSBudWxsICYmIGZvdW5kLm9uTW91c2VXaGVlbCkge1xuICAgICAgICAgICAgICAgICAgICBmb3VuZC5vbk1vdXNlV2hlZWwoZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldC5vbk1vdXNlV2hlZWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5vbk1vdXNlV2hlZWwoZXZlbnQpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vY29uc29sZS53YXJuKCdUYXJnZXQgaGFzIG5vIG9uTW91c2VXaGVlbCBjYWxsYmFjaycsIHRoaXMudGFyZ2V0KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25TdGFydChldmVudCkge1xuICAgICAgICBsZXQgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0UG9pbnQoZXZlbnQpXG4gICAgICAgIHRoaXMuc3RhcnRJbnRlcmFjdGlvbihldmVudCwgZXh0cmFjdGVkKVxuICAgICAgICBsZXQgbWFwcGVkID0gdGhpcy5pbnRlcmFjdGlvbi5tYXBJbnRlcmFjdGlvbihcbiAgICAgICAgICAgIGV4dHJhY3RlZCxcbiAgICAgICAgICAgIFsnY3VycmVudCcsICdzdGFydCddLFxuICAgICAgICAgICAgdGhpcy5tYXBQb3NpdGlvblRvUG9pbnQuYmluZCh0aGlzKVxuICAgICAgICApXG4gICAgICAgIGZvciAobGV0IFt0YXJnZXQsIGludGVyYWN0aW9uXSBvZiBtYXBwZWQuZW50cmllcygpKSB7XG4gICAgICAgICAgICB0YXJnZXQub25TdGFydChldmVudCwgaW50ZXJhY3Rpb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbk1vdmUoZXZlbnQpIHtcbiAgICAgICAgbGV0IGV4dHJhY3RlZCA9IHRoaXMuZXh0cmFjdFBvaW50KGV2ZW50LCAnYWxsJylcbiAgICAgICAgdGhpcy51cGRhdGVJbnRlcmFjdGlvbihldmVudCwgZXh0cmFjdGVkKVxuICAgICAgICBsZXQgbWFwcGVkID0gdGhpcy5pbnRlcmFjdGlvbi5tYXBJbnRlcmFjdGlvbihcbiAgICAgICAgICAgIGV4dHJhY3RlZCxcbiAgICAgICAgICAgIFsnY3VycmVudCcsICdwcmV2aW91cyddLFxuICAgICAgICAgICAgdGhpcy5tYXBQb3NpdGlvblRvUG9pbnQuYmluZCh0aGlzKVxuICAgICAgICApXG4gICAgICAgIGZvciAobGV0IFt0YXJnZXQsIGludGVyYWN0aW9uXSBvZiBtYXBwZWQuZW50cmllcygpKSB7XG4gICAgICAgICAgICB0YXJnZXQub25Nb3ZlKGV2ZW50LCBpbnRlcmFjdGlvbilcbiAgICAgICAgICAgIGludGVyYWN0aW9uLnVwZGF0ZVByZXZpb3VzKClcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmludGVyYWN0aW9uLnVwZGF0ZVByZXZpb3VzKClcbiAgICB9XG5cbiAgICBvbkVuZChldmVudCkge1xuICAgICAgICBsZXQgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0UG9pbnQoZXZlbnQsICdjaGFuZ2VkVG91Y2hlcycpXG4gICAgICAgIHRoaXMuZW5kSW50ZXJhY3Rpb24oZXZlbnQsIGV4dHJhY3RlZClcbiAgICAgICAgbGV0IG1hcHBlZCA9IHRoaXMuaW50ZXJhY3Rpb24ubWFwSW50ZXJhY3Rpb24oXG4gICAgICAgICAgICBleHRyYWN0ZWQsXG4gICAgICAgICAgICBbJ2VuZGVkJ10sXG4gICAgICAgICAgICB0aGlzLm1hcFBvc2l0aW9uVG9Qb2ludC5iaW5kKHRoaXMpXG4gICAgICAgIClcbiAgICAgICAgZm9yIChsZXQgW3RhcmdldCwgaW50ZXJhY3Rpb25dIG9mIG1hcHBlZC5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIHRhcmdldC5vbkVuZChldmVudCwgaW50ZXJhY3Rpb24pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5maW5pc2hJbnRlcmFjdGlvbihldmVudCwgZXh0cmFjdGVkKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IHR5cGVzIC0gQW4gZXZlbnQgdHlwZSwgYW4gYXJyYXkgb2YgZXZlbnQgdHlwZXMgb3IgZXZlbnQgdHlwZXMgc2VwZXJhdGVkIGJ5IGEgc3BhY2Ugc2lnbi4gVGhlIGZvbGxvd2luZ1xuICAgICAqICAgICBldmVudHMgYXJlIHBvc3NpYmxlOlxuICAgICAqICAgICAgICAgcGFuLCBwYW5zdGFydCwgcGFubW92ZSwgcGFuZW5kLCBwYW5jYW5jZWwsIHBhbmxlZnQsIHBhbnJpZ2h0LCBwYW51cCwgcGFuZG93blxuICAgICAqICAgICAgICAgcGluY2gsIHBpbmNoc3RhcnQsIHBpbmNobW92ZSwgcGluY2hlbmQsIHBpbmNoY2FuY2VsLCBwaW5jaGluLCBwaW5jaG91dFxuICAgICAqICAgICAgICAgcHJlc3MsIHByZXNzdXBcbiAgICAgKiAgICAgICAgIHJvdGF0ZSwgcm90YXRlc3RhcnQsIHJvdGF0ZW1vdmUsIHJvdGF0ZWVuZCwgcm90YXRlY2FuY2VsXG4gICAgICogICAgICAgICBzd2lwZSwgc3dpcGVsZWZ0LCBzd2lwZXJpZ2h0LCBzd2lwZXVwLCBzd2lwZWRvd25cbiAgICAgKiAgICAgICAgIHRhcFxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8SFRNTEVsZW1lbnRbXX0gZWxlbWVudHMgLSBBbiBIVE1MIGVsZW1lbnQgb3IgYW4gYXJyYXkgb2YgSFRNTCBlbGVtZW50cy5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbY2JdIC0gVGhlIGNhbGxiYWNrLiBBIGZ1bmN0aW9uIHdoaWNoIGlzIGV4ZWN1dGVkIGFmdGVyIHRoZSBldmVudCBvY2N1cnMuIFJlY2VpdmVzIHRoZSBldmVudCBvYmplY3QgYXMgdGhlXG4gICAgICogICAgIGZpcnN0IHBhcmFtdGVyXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0LiBTZWUgdGhlIGhhbW1lciBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICovXG4gICAgc3RhdGljIG9uKHR5cGVzLCBlbGVtZW50cywgY2IsIG9wdHMgPSB7fSkge1xuICAgICAgICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgaWYgKHR5cGVvZiBIYW1tZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdIYW1tZXIuanMgbm90IGZvdW5kIScpXG4gICAgICAgICAgICByZXR1cm4gdGhpc1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY29udmVydCB0byBhcnJheVxuICAgICAgICB0eXBlcyA9IEFycmF5LmlzQXJyYXkodHlwZXMpID8gdHlwZXMgOiB0eXBlcy5zcGxpdCgvXFxzLylcbiAgICAgICAgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgTm9kZUxpc3QgfHwgZWxlbWVudHMgaW5zdGFuY2VvZiBIVE1MQ29sbGVjdGlvbikge1xuICAgICAgICAgICAgZWxlbWVudHMgPSBBcnJheS5mcm9tKGVsZW1lbnRzKVxuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnRzID0gQXJyYXkuaXNBcnJheShlbGVtZW50cykgPyBlbGVtZW50cyA6IFtlbGVtZW50c11cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB0eXBlc1tpXS50b0xvd2VyQ2FzZSgpXG5cbiAgICAgICAgICAgIC8vIGxpc3Qgb2YgaGFtbWVyIGV2ZW50c1xuICAgICAgICAgICAgY29uc3QgdXNlSGFtbWVyID0gL14odGFwfGRvdWJsZXRhcHxwcmVzc3xwYW58c3dpcGV8cGluY2h8cm90YXRlKS4qJC8udGVzdCh0eXBlKVxuXG4gICAgICAgICAgICAvLyBpZiBpdCBpcyBhIGhhbW1lciBldmVudFxuICAgICAgICAgICAgaWYgKHVzZUhhbW1lcikge1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBlbGVtZW50cy5sZW5ndGg7IGorKykge1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmKGVsZW1lbnRzW2pdLnRhZ05hbWUgPT0gXCJzdmdcIikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBoYW1tZXIgPSBuZXcgSGFtbWVyKGVsZW1lbnRzW2pdLCBvcHRzKVxuXG4gICAgICAgICAgICAgICAgICAgIGlmICh3aW5kb3cucHJvcGFnYXRpbmcgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW1tZXIgPSBwcm9wYWdhdGluZyhoYW1tZXIpXG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyByZWNvZ25pemVyc1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS5zdGFydHNXaXRoKCdwYW4nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFtbWVyLmdldCgncGFuJykuc2V0KE9iamVjdC5hc3NpZ24oeyBkaXJlY3Rpb246IEhhbW1lci5ESVJFQ1RJT05fQUxMIH0sIG9wdHMpKVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUuc3RhcnRzV2l0aCgncGluY2gnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFtbWVyLmdldCgncGluY2gnKS5zZXQoT2JqZWN0LmFzc2lnbih7IGVuYWJsZTogdHJ1ZSB9LCBvcHRzKSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3ByZXNzJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbW1lci5nZXQoJ3ByZXNzJykuc2V0KG9wdHMpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZS5zdGFydHNXaXRoKCdyb3RhdGUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFtbWVyLmdldCgncm90YXRlJykuc2V0KE9iamVjdC5hc3NpZ24oeyBlbmFibGU6IHRydWUgfSwgb3B0cykpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZS5zdGFydHNXaXRoKCdzd2lwZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW1tZXIuZ2V0KCdzd2lwZScpLnNldChPYmplY3QuYXNzaWduKHsgZGlyZWN0aW9uOiBIYW1tZXIuRElSRUNUSU9OX0FMTCB9LCBvcHRzKSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3RhcCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW1tZXIuZ2V0KCd0YXAnKS5zZXQob3B0cylcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGhhbW1lci5vbih0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYihldmVudClcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsZW1lbnRzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIEhhbW1lci5vbihlbGVtZW50c1tqXSwgdHlwZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2IoZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG59XG5cbndpbmRvdy5JbnRlcmFjdGlvbk1hcHBlciA9IEludGVyYWN0aW9uTWFwcGVyXG4iLCIvKiogUmVwb3J0IGNhcGFiaWxpdGllcyB3aXRoIGd1YXJhbnRlZWQgdmFsdWVzLlxuICovXG5leHBvcnQgY2xhc3MgQ2FwYWJpbGl0aWVzIHtcblxuICAgIC8qKiBSZXR1cm5zIHRoZSBicm93c2VyIHVzZXJBZ2VudC5cbiAgICBAcmV0dXJuIHtzdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHVzZXJBZ2VudCgpIHtcbiAgICAgICAgcmV0dXJuIG5hdmlnYXRvci51c2VyQWdlbnQgfHwgJ1Vua25vd24gQWdlbnQnXG4gICAgfVxuXG4gICAgLyoqIFRlc3RzIHdoZXRoZXIgdGhlIGFwcCBpcyBydW5uaW5nIG9uIGEgbW9iaWxlIGRldmljZS5cbiAgICBJbXBsZW1lbnRlZCBhcyBhIHJlYWRvbmx5IGF0dHJpYnV0ZS5cbiAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICovXG4gICAgc3RhdGljIGdldCBpc01vYmlsZSgpIHtcbiAgICAgICAgcmV0dXJuICgvTW9iaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSlcbiAgICB9XG5cbiAgICAvKiogVGVzdHMgd2hldGhlciB0aGUgYXBwIGlzIHJ1bm5pbmcgb24gYSBpT1MgZGV2aWNlLlxuICAgIEltcGxlbWVudGVkIGFzIGEgcmVhZG9ubHkgYXR0cmlidXRlLlxuICAgIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IGlzSU9TKCkge1xuICAgICAgICByZXR1cm4gKC9pUGFkfGlQaG9uZXxpUG9kLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSAmJiAhd2luZG93Lk1TU3RyZWFtXG4gICAgfVxuXG4gICAgLyoqIFRlc3RzIHdoZXRoZXIgdGhlIGFwcCBpcyBydW5uaW5nIGluIGEgU2FmYXJpIGVudmlyb25tZW50LlxuICAgIFNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83OTQ0NDYwL2RldGVjdC1zYWZhcmktYnJvd3NlclxuICAgIEltcGxlbWVudGVkIGFzIGEgcmVhZG9ubHkgYXR0cmlidXRlLlxuICAgIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IGlzU2FmYXJpKCkge1xuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnZlbmRvciAmJiBuYXZpZ2F0b3IudmVuZG9yLmluZGV4T2YoJ0FwcGxlJykgPiAtMSAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmICFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKCdDcmlPUycpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzdGluY3RzIGlmIHRoZSBhcHAgaXMgcnVubmluZyBpbnNpZGUgZWxlY3Ryb24gb3Igbm90LlxuICAgICAqIFxuICAgICAqIHNvdXJjZTogaHR0cHM6Ly9kaXNjdXNzLmF0b20uaW8vdC9kZXRlY3QtZWxlY3Ryb24tb3Itd2ViLXBhZ2UtcnVubmluZy8zMzE4MC8zXG4gICAgICovXG4gICAgc3RhdGljIGdldCBpc0VsZWN0cm9uKCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2Nlc3MgIT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy52ZXJzaW9ucyAmJiBwcm9jZXNzLnZlcnNpb25zLmVsZWN0cm9uICE9PSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0aGUgZGlzcGxheSByZXNvbHV0aW9uLiBOZWNlc3NhcnkgZm9yIHJldGluYSBkaXNwbGF5cy5cbiAgICBAcmV0dXJuIHtudW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IGRldmljZVBpeGVsUmF0aW8oKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxXG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZGV2aWNlIGlzIGEgbXVsdGktdG91Y2ggdGFibGUuIFRoaXMgbWV0aG9kIGlzIGN1cnJlbnRseSBub3QgdW5pdmVyc2FsIHVzYWJsZSBhbmQgbm90IHN1cmUhXG4gICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgaXNNdWx0aVRvdWNoVGFibGUoKSB7XG4gICAgICAgIHJldHVybiBDYXBhYmlsaXRpZXMuZGV2aWNlUGl4ZWxSYXRpbyA+IDIgJiYgQ2FwYWJpbGl0aWVzLmlzTW9iaWxlID09PSBmYWxzZSAmJiAvV2luZG93cy9pLnRlc3QoQ2FwYWJpbGl0aWVzLnVzZXJBZ2VudClcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIG1vdXNlIGV2ZW50cyBhcmUgc3VwcG9ydGVkXG4gICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuICAgIHN0YXRpYyBzdXBwb3J0c01vdXNlRXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mKHdpbmRvdy5Nb3VzZUV2ZW50KSAhPSAndW5kZWZpbmVkJ1xuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdG91Y2ggZXZlbnRzIGFyZSBzdXBwb3J0ZWRcbiAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICovXG4gICAgc3RhdGljIHN1cHBvcnRzVG91Y2hFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2Yod2luZG93LlRvdWNoRXZlbnQpICE9ICd1bmRlZmluZWQnXG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiBwb2ludGVyIGV2ZW50cyBhcmUgc3VwcG9ydGVkXG4gICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuICAgIHN0YXRpYyBzdXBwb3J0c1BvaW50ZXJFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2Yod2luZG93LlBvaW50ZXJFdmVudCkgIT0gJ3VuZGVmaW5lZCdcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIERPTSB0ZW1wbGF0ZXMgYXJlIHN1cHBvcnRlZFxuICAgIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgKi9cbiAgICBzdGF0aWMgc3VwcG9ydHNUZW1wbGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuICdjb250ZW50JyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xuICAgIH1cbn1cblxuLyoqIEJhc2ljIHRlc3RzIGZvciBDYXBhYmlsaXRpZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYXBhYmlsaXRpZXNUZXN0cyB7XG5cbiAgICBzdGF0aWMgdGVzdENvbmZpcm0oKSB7XG4gICAgICAgIGxldCBib29sID0gY29uZmlybSgnUGxlYXNlIGNvbmZpcm0nKVxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVtbycpLmlubmVySFRNTCA9IChib29sKSA/ICdDb25maXJtZWQnIDogJ05vdCBjb25maXJtZWQnXG4gICAgfVxuXG4gICAgc3RhdGljIHRlc3RQcm9tcHQoKSB7XG4gICAgICAgIGxldCBwZXJzb24gPSBwcm9tcHQoJ1BsZWFzZSBlbnRlciB5b3VyIG5hbWUnLCAnSGFycnkgUG90dGVyJylcbiAgICAgICAgaWYgKHBlcnNvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICBkZW1vLmlubmVySFRNTCA9XG4gICAgICAgICAgICAnSGVsbG8gJyArIHBlcnNvbiArICchIEhvdyBhcmUgeW91IHRvZGF5PydcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyB0ZXN0VXNlckFnZW50KCkge1xuICAgICAgICBsZXQgYWdlbnQgPSAnVXNlci1hZ2VudDogJyArIENhcGFiaWxpdGllcy51c2VyQWdlbnRcbiAgICAgICAgdXNlcl9hZ2VudC5pbm5lckhUTUwgPSBhZ2VudFxuICAgIH1cblxuICAgIHN0YXRpYyB0ZXN0RGV2aWNlUGl4ZWxSYXRpbygpIHtcbiAgICAgICAgbGV0IHZhbHVlID0gJ0RldmljZSBQaXhlbCBSYXRpbzogJyArIENhcGFiaWxpdGllcy5kZXZpY2VQaXhlbFJhdGlvXG4gICAgICAgIGRldmljZV9waXhlbF9yYXRpby5pbm5lckhUTUwgPSB2YWx1ZVxuICAgIH1cblxuICAgIHN0YXRpYyB0ZXN0TXVsdGlUb3VjaFRhYmxlKCkge1xuICAgICAgICBsZXQgdmFsdWUgPSAnSXMgdGhlIGRldmljZSBhIG11bHRpLXRvdWNoIHRhYmxlPyAnICsgQ2FwYWJpbGl0aWVzLmlzTXVsdGlUb3VjaFRhYmxlXG4gICAgICAgIG11bHRpX3RvdWNoX3RhYmxlLmlubmVySFRNTCA9IHZhbHVlXG4gICAgfVxuXG4gICAgc3RhdGljIHRlc3RTdXBwb3J0ZWRFdmVudHMoKSB7XG4gICAgICAgIGxldCBldmVudHMgPSBbXVxuICAgICAgICBpZiAoQ2FwYWJpbGl0aWVzLnN1cHBvcnRzTW91c2VFdmVudHMoKSkge1xuICAgICAgICAgICAgZXZlbnRzLnB1c2goJ01vdXNlRXZlbnRzJylcbiAgICAgICAgfVxuICAgICAgICBpZiAoQ2FwYWJpbGl0aWVzLnN1cHBvcnRzVG91Y2hFdmVudHMoKSkge1xuICAgICAgICAgICAgZXZlbnRzLnB1c2goJ1RvdWNoRXZlbnRzJylcbiAgICAgICAgfVxuICAgICAgICBpZiAoQ2FwYWJpbGl0aWVzLnN1cHBvcnRzUG9pbnRlckV2ZW50cygpKSB7XG4gICAgICAgICAgICBldmVudHMucHVzaCgnUG9pbnRlckV2ZW50cycpXG4gICAgICAgIH1cbiAgICAgICAgc3VwcG9ydGVkX2V2ZW50cy5pbm5lckhUTUwgPSAnU3VwcG9ydGVkIEV2ZW50czogJyArIGV2ZW50cy5qb2luKCcsICcpXG4gICAgfVxuXG4gICAgc3RhdGljIHRlc3RBbGwoKSB7XG4gICAgICAgIHRoaXMudGVzdFVzZXJBZ2VudCgpXG4gICAgICAgIHRoaXMudGVzdERldmljZVBpeGVsUmF0aW8oKVxuICAgICAgICB0aGlzLnRlc3RNdWx0aVRvdWNoVGFibGUoKVxuICAgICAgICB0aGlzLnRlc3RTdXBwb3J0ZWRFdmVudHMoKVxuICAgIH1cbn1cblxuLyogT3B0aW9uYWwgZ2xvYmFsIHZhcmlhYmxlcywgbmVlZGVkIGluIERvY1Rlc3RzLiAqL1xud2luZG93LkNhcGFiaWxpdGllcyA9IENhcGFiaWxpdGllc1xud2luZG93LkNhcGFiaWxpdGllc1Rlc3RzID0gQ2FwYWJpbGl0aWVzVGVzdHNcbiIsImltcG9ydCB7IFBvaW50cywgUG9seWdvbiwgQW5nbGUsIEVsZW1lbnRzIH0gZnJvbSAnLi91dGlscy5qcydcbmltcG9ydCBFdmVudHMgZnJvbSAnLi9ldmVudHMuanMnXG5pbXBvcnQgeyBJbnRlcmFjdGlvbk1hcHBlciB9IGZyb20gJy4vaW50ZXJhY3Rpb24uanMnXG5pbXBvcnQgeyBDYXBhYmlsaXRpZXMgfSBmcm9tICcuL2NhcGFiaWxpdGllcy5qcydcblxuLyoqXG4gKiBBIGJhc2UgY2xhc3MgZm9yIHNjYXR0ZXIgc3BlY2lmaWMgZXZlbnRzLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtuYW1lfSBTdHJpbmcgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnRcbiAqIEBwYXJhbSB7dGFyZ2V0fSBPYmplY3QgLSBUaGUgdGFyZ2V0IG9mIHRoZSBldmVudFxuICovXG5leHBvcnQgY2xhc3MgQmFzZUV2ZW50IHtcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCB0YXJnZXQpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZVxuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldFxuICAgIH1cbn1cblxuLy8gRXZlbnQgdHlwZXNcbmNvbnN0IFNUQVJUID0gJ29uU3RhcnQnXG5jb25zdCBVUERBVEUgPSAnb25VcGRhdGUnXG5jb25zdCBFTkQgPSAnb25FbmQnXG5jb25zdCBaT09NID0gJ29uWm9vbSdcbmNvbnN0IE1PVkUgPSAnb25Nb3ZlJ1xuXG4vKipcbiAqIEEgc2NhdHRlciBldmVudCB0aGF0IGRlc2NyaWJlcyBob3cgdGhlIHNjYXR0ZXIgaGFzIGNoYW5nZWQuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge3RhcmdldH0gT2JqZWN0IC0gVGhlIHRhcmdldCBzY2F0dGVyIG9mIHRoZSBldmVudFxuICogQHBhcmFtIHtvcHRpb25hbH0gT2JqZWN0IC0gT3B0aW9uYWwgcGFyYW1ldGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2F0dGVyRXZlbnQgZXh0ZW5kcyBCYXNlRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyYW5zbGF0ZSA9IHsgeDogMCwgeTogMCB9LFxuICAgICAgICAgICAgc2NhbGUgPSBudWxsLFxuICAgICAgICAgICAgcm90YXRlID0gMCxcbiAgICAgICAgICAgIGFib3V0ID0gbnVsbCxcbiAgICAgICAgICAgIGZhc3QgPSBmYWxzZSxcbiAgICAgICAgICAgIHR5cGUgPSBudWxsXG4gICAgICAgIH0gPSB7fVxuICAgICkge1xuICAgICAgICBzdXBlcignc2NhdHRlclRyYW5zZm9ybWVkJywgeyB0YXJnZXQ6IHRhcmdldCB9KVxuICAgICAgICB0aGlzLnRyYW5zbGF0ZSA9IHRyYW5zbGF0ZVxuICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGVcbiAgICAgICAgdGhpcy5yb3RhdGUgPSByb3RhdGVcbiAgICAgICAgdGhpcy5hYm91dCA9IGFib3V0XG4gICAgICAgIHRoaXMuZmFzdCA9IGZhc3RcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZVxuICAgIH1cblxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgXCJFdmVudCgnc2NhdHRlclRyYW5zZm9ybWVkJywgc2NhbGU6IFwiICtcbiAgICAgICAgICAgIHRoaXMuc2NhbGUgK1xuICAgICAgICAgICAgJyBhYm91dDogJyArXG4gICAgICAgICAgICB0aGlzLmFib3V0LnggK1xuICAgICAgICAgICAgJywgJyArXG4gICAgICAgICAgICB0aGlzLmFib3V0LnkgK1xuICAgICAgICAgICAgJyknXG4gICAgICAgIClcbiAgICB9XG59XG5cbi8qKlxuICogQSBzY2F0dGVyIHJlc2l6ZSBldmVudCB0aGF0IGRlc2NyaWJlcyBob3cgdGhlIHNjYXR0ZXIgaGFzIGNoYW5nZWQuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge3RhcmdldH0gT2JqZWN0IC0gVGhlIHRhcmdldCBzY2F0dGVyIG9mIHRoZSBldmVudFxuICogQHBhcmFtIHtvcHRpb25hbH0gT2JqZWN0IC0gT3B0aW9uYWwgcGFyYW1ldGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXNpemVFdmVudCBleHRlbmRzIEJhc2VFdmVudCB7XG4gICAgY29uc3RydWN0b3IodGFyZ2V0LCB7IHdpZHRoID0gMCwgaGVpZ2h0ID0gMCB9ID0ge30pIHtcbiAgICAgICAgc3VwZXIoJ3NjYXR0ZXJSZXNpemVkJywgeyB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0IH0pXG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aFxuICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodFxuICAgIH1cblxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgJ0V2ZW50KHNjYXR0ZXJSZXNpemVkIHdpZHRoOiAnICtcbiAgICAgICAgICAgIHRoaXMud2lkdGggK1xuICAgICAgICAgICAgJ2hlaWdodDogJyArXG4gICAgICAgICAgICB0aGlzLmhlaWdodCArXG4gICAgICAgICAgICAnKSdcbiAgICAgICAgKVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIGFic3RyYWN0IGJhc2UgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSB0aHJvd2FibGUgYmVoYXZpb3Igb2YgYSBzY2F0dGVyXG4gKiBvYmplY3QuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmNsYXNzIFRocm93YWJsZSB7XG4gICAgY29uc3RydWN0b3Ioe1xuICAgICAgICBtb3ZhYmxlWCA9IHRydWUsXG4gICAgICAgIG1vdmFibGVZID0gdHJ1ZSxcbiAgICAgICAgdGhyb3dWaXNpYmlsaXR5ID0gNDQsXG4gICAgICAgIHRocm93RGFtcGluZyA9IDAuOTUsXG4gICAgICAgIGF1dG9UaHJvdyA9IHRydWUsXG4gICAgICAgIG9uVGhyb3dGaW5pc2hlZCA9IG51bGxcbiAgICB9ID0ge30pIHtcbiAgICAgICAgdGhpcy5tb3ZhYmxlWCA9IG1vdmFibGVYXG4gICAgICAgIHRoaXMubW92YWJsZVkgPSBtb3ZhYmxlWVxuICAgICAgICB0aGlzLnRocm93VmlzaWJpbGl0eSA9IHRocm93VmlzaWJpbGl0eVxuICAgICAgICB0aGlzLnRocm93RGFtcGluZyA9IHRocm93RGFtcGluZ1xuICAgICAgICB0aGlzLmF1dG9UaHJvdyA9IGF1dG9UaHJvd1xuICAgICAgICB0aGlzLnZlbG9jaXRpZXMgPSBbXVxuICAgICAgICB0aGlzLnZlbG9jaXR5ID0gbnVsbFxuICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IG51bGxcbiAgICAgICAgdGhpcy5vblRocm93RmluaXNoZWQgPSBvblRocm93RmluaXNoZWRcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIm9uVGhyb3dGaW5pc2hlZFwiLCBvblRocm93RmluaXNoZWQpXG4gICAgfVxuXG4gICAgb2JzZXJ2ZVZlbG9jaXR5KCkge1xuICAgICAgICB0aGlzLmxhc3RmcmFtZSA9IHBlcmZvcm1hbmNlLm5vdygpXG4gICAgfVxuXG4gICAgYWRkVmVsb2NpdHkoZGVsdGEsIGJ1ZmZlciA9IDUpIHtcbiAgICAgICAgbGV0IHQgPSBwZXJmb3JtYW5jZS5ub3coKVxuICAgICAgICBsZXQgZHQgPSB0IC0gdGhpcy5sYXN0ZnJhbWVcbiAgICAgICAgdGhpcy5sYXN0ZnJhbWUgPSB0XG4gICAgICAgIGlmIChkdCA+IDApIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIGRpdmlzaW9uIGJ5IHplcm8gZXJyb3JzIGxhdGVyIG9uXG4gICAgICAgICAgICBsZXQgdmVsb2NpdHkgPSB7IHQ6IHQsIGR0OiBkdCwgZHg6IGRlbHRhLngsIGR5OiBkZWx0YS55IH1cbiAgICAgICAgICAgIHRoaXMudmVsb2NpdGllcy5wdXNoKHZlbG9jaXR5KVxuICAgICAgICAgICAgd2hpbGUgKHRoaXMudmVsb2NpdGllcy5sZW5ndGggPiBidWZmZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZlbG9jaXRpZXMuc2hpZnQoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbWVhblZlbG9jaXR5KG1pbGxpc2Vjb25kcyA9IDMwKSB7XG4gICAgICAgIHRoaXMuYWRkVmVsb2NpdHkoeyB4OiAwLCB5OiAwIH0pXG4gICAgICAgIGxldCBzdW0gPSB7IHg6IDAsIHk6IDAgfVxuICAgICAgICBsZXQgY291bnQgPSAwXG4gICAgICAgIGxldCB0ID0gMFxuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy52ZWxvY2l0aWVzLmxlbmd0aCAtIDE7IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCB2ID0gdGhpcy52ZWxvY2l0aWVzW2ldXG4gICAgICAgICAgICB0ICs9IHYuZHRcbiAgICAgICAgICAgIGxldCBudiA9IHsgeDogdi5keCAvIHYuZHQsIHk6IHYuZHkgLyB2LmR0IH1cbiAgICAgICAgICAgIHN1bSA9IFBvaW50cy5hZGQoc3VtLCBudilcbiAgICAgICAgICAgIGNvdW50ICs9IDFcbiAgICAgICAgICAgIGlmICh0ID4gbWlsbGlzZWNvbmRzKSB7XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY291bnQgPT09IDApIHJldHVybiBzdW0gLy8gZW1wdHkgdmVjdG9yXG4gICAgICAgIHJldHVybiBQb2ludHMubXVsdGlwbHlTY2FsYXIoc3VtLCAxIC8gY291bnQpXG4gICAgfVxuXG4gICAga2lsbEFuaW1hdGlvbigpIHtcbiAgICAgICAgdGhpcy52ZWxvY2l0eSA9IG51bGxcbiAgICAgICAgdGhpcy52ZWxvY2l0aWVzID0gW11cbiAgICB9XG5cbiAgICBzdGFydFRocm93KCkge1xuICAgICAgICB0aGlzLnZlbG9jaXR5ID0gdGhpcy5tZWFuVmVsb2NpdHkoKVxuICAgICAgICBpZiAodGhpcy52ZWxvY2l0eSAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyBDYWxsIG5leHQgdmVsb2NpdHkgdG8gYW5zdXJlIHRoYXQgc3BlY2lhbGl6YXRpb25zXG4gICAgICAgICAgICAvLyB0aGF0IHVzZSBrZWVwT25TdGFnZSBhcmUgY2FsbGVkXG4gICAgICAgICAgICB0aGlzLnZlbG9jaXR5ID0gdGhpcy5uZXh0VmVsb2NpdHkodGhpcy52ZWxvY2l0eSlcbiAgICAgICAgICAgIGlmICh0aGlzLmF1dG9UaHJvdykgdGhpcy5hbmltYXRlVGhyb3cocGVyZm9ybWFuY2Uubm93KCkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm9uRHJhZ0NvbXBsZXRlKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFuaW1hdGVUaHJvdyh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLnZlbG9jaXR5ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGxldCB0ID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICAgICAgICAgIGxldCBkdCA9IHQgLSB0aGlzLmxhc3RmcmFtZVxuICAgICAgICAgICAgdGhpcy5sYXN0ZnJhbWUgPSB0XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcImFuaW1hdGVUaHJvd1wiLCBkdClcbiAgICAgICAgICAgIGxldCBuZXh0ID0gdGhpcy5uZXh0VmVsb2NpdHkodGhpcy52ZWxvY2l0eSlcbiAgICAgICAgICAgIGxldCBwcmV2TGVuZ3RoID0gUG9pbnRzLmxlbmd0aCh0aGlzLnZlbG9jaXR5KVxuICAgICAgICAgICAgbGV0IG5leHRMZW5ndGggPSBQb2ludHMubGVuZ3RoKG5leHQpXG4gICAgICAgICAgICBpZiAobmV4dExlbmd0aCA+IHByZXZMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZmFjdG9yID0gbmV4dExlbmd0aCAvIHByZXZMZW5ndGhcbiAgICAgICAgICAgICAgICBuZXh0ID0gUG9pbnRzLm11bHRpcGx5U2NhbGFyKG5leHQsIDEgLyBmYWN0b3IpXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1ByZXZlbnQgYWNjZWxlcmF0aW9uJywgZmFjdG9yLCB0aGlzLnZlbG9jaXR5LCBuZXh0KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eSA9IG5leHRcbiAgICAgICAgICAgIGxldCBkID0gUG9pbnRzLm11bHRpcGx5U2NhbGFyKHRoaXMudmVsb2NpdHksIGR0KVxuICAgICAgICAgICAgdGhpcy5fbW92ZShkKVxuXG4gICAgICAgICAgICB0aGlzLm9uRHJhZ1VwZGF0ZShkKVxuICAgICAgICAgICAgaWYgKGR0ID09IDAgfHwgdGhpcy5uZWVkc0FuaW1hdGlvbigpKSB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0ZVRocm93LmJpbmQodGhpcykpXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzT3V0c2lkZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGVUaHJvdy5iaW5kKHRoaXMpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbkRyYWdDb21wbGV0ZSgpXG4gICAgICAgIGlmICh0aGlzLm9uVGhyb3dGaW5pc2hlZCAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm9uVGhyb3dGaW5pc2hlZCgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZWVkc0FuaW1hdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMudmVsb2NpdHkgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBvaW50cy5sZW5ndGgodGhpcy52ZWxvY2l0eSkgPiAwLjAxXG4gICAgfVxuXG4gICAgbmV4dFZlbG9jaXR5KHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIE11c3QgYmUgb3ZlcndyaXR0ZW46IGNvbXB1dGVzIHRoZSBjaGFuZ2VkIHZlbG9jaXR5LiBJbXBsZW1lbnRcbiAgICAgICAgLy8gZGFtcGluZywgY29sbGlzb24gZGV0ZWN0aW9uLCBldGMuIGhlcmVcbiAgICAgICAgbGV0IG5leHQgPSBQb2ludHMubXVsdGlwbHlTY2FsYXIodmVsb2NpdHksIHRoaXMudGhyb3dEYW1waW5nKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogKHRoaXMubW92YWJsZVgpID8gbmV4dC54IDogMCxcbiAgICAgICAgICAgIHk6ICh0aGlzLm1vdmFibGVZKSA/IG5leHQueSA6IDBcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9tb3ZlKGRlbHRhKSB7XG4gICAgICAgIC8vIE92ZXJ3cml0ZSBpZiBuZWNlc3NhcnlcbiAgICB9XG5cbiAgICBvbkRyYWdDb21wbGV0ZSgpIHtcbiAgICAgICAgLy8gT3ZlcndyaXRlIGlmIG5lY2Vzc2FyeVxuICAgIH1cblxuICAgIG9uRHJhZ1VwZGF0ZShkZWx0YSkge1xuICAgICAgICAvLyBPdmVyd3JpdGUgaWYgbmVjZXNzYXJ5XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQWJzdHJhY3RTY2F0dGVyIGV4dGVuZHMgVGhyb3dhYmxlIHtcbiAgICBjb25zdHJ1Y3Rvcih7XG4gICAgICAgIG1pblNjYWxlID0gMC4xLFxuICAgICAgICBtYXhTY2FsZSA9IDEuMCxcbiAgICAgICAgc3RhcnRTY2FsZSA9IDEuMCxcbiAgICAgICAgYXV0b0JyaW5nVG9Gcm9udCA9IHRydWUsXG4gICAgICAgIGF1dG9UaHJvdyA9IHRydWUsXG4gICAgICAgIHRyYW5zbGF0YWJsZSA9IHRydWUsXG4gICAgICAgIHNjYWxhYmxlID0gdHJ1ZSxcbiAgICAgICAgcm90YXRhYmxlID0gdHJ1ZSxcbiAgICAgICAgcmVzaXphYmxlID0gZmFsc2UsXG4gICAgICAgIG1vdmFibGVYID0gdHJ1ZSxcbiAgICAgICAgbW92YWJsZVkgPSB0cnVlLFxuICAgICAgICB0aHJvd1Zpc2liaWxpdHkgPSA0NCxcbiAgICAgICAgdGhyb3dEYW1waW5nID0gMC45NSxcbiAgICAgICAgb3ZlcmRvU2NhbGluZyA9IDEsXG4gICAgICAgIG1vdXNlWm9vbUZhY3RvciA9IDEuMSxcbiAgICAgICAgcm90YXRpb25EZWdyZWVzID0gbnVsbCxcbiAgICAgICAgcm90YXRpb24gPSBudWxsLFxuICAgICAgICBvblRyYW5zZm9ybSA9IG51bGwsXG4gICAgICAgIGludGVyYWN0aXZlID0gdHJ1ZSxcbiAgICAgICAgb25DbG9zZSA9IG51bGwsXG4gICAgICAgIG9uVGhyb3dGaW5pc2hlZCA9IG51bGwsXG4gICAgICAgIHNjYWxlQXV0b0Nsb3NlID0gZmFsc2UsXG4gICAgICAgIHNjYWxlQ2xvc2VUaHJlc2hvbGQgPSAwLjEwLFxuICAgICAgICBzY2FsZUNsb3NlQnVmZmVyID0gMC4wNVxuICAgIH0gPSB7fSkge1xuICAgICAgICBpZiAocm90YXRpb25EZWdyZWVzICE9IG51bGwgJiYgcm90YXRpb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVc2Ugcm90YXRpb25EZWdyZWVzIG9yIHJvdGF0aW9uIGJ1dCBub3QgYm90aCcpXG4gICAgICAgIH0gZWxzZSBpZiAocm90YXRpb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgcm90YXRpb25EZWdyZWVzID0gQW5nbGUucmFkaWFuMmRlZ3JlZShyb3RhdGlvbilcbiAgICAgICAgfSBlbHNlIGlmIChyb3RhdGlvbkRlZ3JlZXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgcm90YXRpb25EZWdyZWVzID0gMFxuICAgICAgICB9XG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIG1vdmFibGVYLFxuICAgICAgICAgICAgbW92YWJsZVksXG4gICAgICAgICAgICB0aHJvd1Zpc2liaWxpdHksXG4gICAgICAgICAgICB0aHJvd0RhbXBpbmcsXG4gICAgICAgICAgICBhdXRvVGhyb3csXG4gICAgICAgICAgICBvblRocm93RmluaXNoZWRcbiAgICAgICAgfSlcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2xvc2VzIHRoZSBjYXJkIHdoZW4gdGhlIG1pblNjYWxlIGlzIHJlYWNoZWQgYW5kIHRoZSBcbiAgICAgICAgICogY2FyZCBpcyByZWxlYXNlZC4gQ2FyZCBjYW4gYmUgc2F2ZWQgYnkgc2NhbGluZyBpdCB1cCBhZ2Fpbi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuc2NhbGVBdXRvQ2xvc2UgPSBzY2FsZUF1dG9DbG9zZVxuICAgICAgICB0aGlzLnNjYWxlQ2xvc2VUaHJlc2hvbGQgPSBzY2FsZUNsb3NlVGhyZXNob2xkXG4gICAgICAgIHRoaXMuc2NhbGVDbG9zZUJ1ZmZlciA9IHNjYWxlQ2xvc2VCdWZmZXJcbiAgICAgICAgdGhpcy5zY2FsZUF1dG9DbG9zZVRpbWVvdXQgPSBudWxsXG5cbiAgICAgICAgdGhpcy5pbnRlcmFjdGl2ZSA9IGludGVyYWN0aXZlXG4gICAgICAgIHRoaXMuc3RhcnRSb3RhdGlvbkRlZ3JlZXMgPSByb3RhdGlvbkRlZ3JlZXNcbiAgICAgICAgdGhpcy5zdGFydFNjYWxlID0gc3RhcnRTY2FsZSAvLyBOZWVkZWQgdG8gcmVzZXQgb2JqZWN0XG4gICAgICAgIHRoaXMubWluU2NhbGUgPSBtaW5TY2FsZVxuICAgICAgICB0aGlzLm1heFNjYWxlID0gbWF4U2NhbGVcbiAgICAgICAgdGhpcy5vdmVyZG9TY2FsaW5nID0gb3ZlcmRvU2NhbGluZ1xuICAgICAgICB0aGlzLnRyYW5zbGF0YWJsZSA9IHRyYW5zbGF0YWJsZVxuICAgICAgICBpZiAoIXRyYW5zbGF0YWJsZSkge1xuICAgICAgICAgICAgdGhpcy5tb3ZhYmxlWCA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLm1vdmFibGVZID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNjYWxhYmxlID0gc2NhbGFibGVcbiAgICAgICAgdGhpcy5yb3RhdGFibGUgPSByb3RhdGFibGVcbiAgICAgICAgdGhpcy5yZXNpemFibGUgPSByZXNpemFibGVcbiAgICAgICAgdGhpcy5tb3VzZVpvb21GYWN0b3IgPSBtb3VzZVpvb21GYWN0b3JcbiAgICAgICAgdGhpcy5hdXRvQnJpbmdUb0Zyb250ID0gYXV0b0JyaW5nVG9Gcm9udFxuICAgICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2VcbiAgICAgICAgdGhpcy5vblRyYW5zZm9ybSA9IG9uVHJhbnNmb3JtICE9IG51bGwgPyBbb25UcmFuc2Zvcm1dIDogbnVsbFxuICAgICAgICB0aGlzLm9uQ2xvc2UgPSBvbkNsb3NlICE9IG51bGwgPyBbb25DbG9zZV0gOiBudWxsXG4gICAgfVxuXG4gICAgYWRkQ2xvc2VFdmVudENhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLm9uQ2xvc2UgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5vbkNsb3NlID0gW11cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uQ2xvc2UucHVzaChjYWxsYmFjaylcbiAgICB9XG5cbiAgICBhZGRUcmFuc2Zvcm1FdmVudENhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtID09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0gPSBbXVxuICAgICAgICB9XG4gICAgICAgIHRoaXMub25UcmFuc2Zvcm0ucHVzaChjYWxsYmFjaylcbiAgICB9XG5cbiAgICBzdGFydEdlc3R1cmUoaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQoKVxuICAgICAgICB0aGlzLmtpbGxBbmltYXRpb24oKVxuICAgICAgICB0aGlzLm9ic2VydmVWZWxvY2l0eSgpXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLm9uQ2xvc2UpIHtcbiAgICAgICAgICAgIHRoaXMub25DbG9zZS5mb3JFYWNoKGNhbGxiYWNrID0+IGNhbGxiYWNrKHRoaXMpKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2VzdHVyZShpbnRlcmFjdGlvbikge1xuICAgICAgICBsZXQgZGVsdGEgPSBpbnRlcmFjdGlvbi5kZWx0YSgpXG4gICAgICAgIC8vY29uc29sZS5sb2coXCJnZXN0dXJlXCIsIGRlbHRhKVxuICAgICAgICBpZiAoZGVsdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5hZGRWZWxvY2l0eShkZWx0YSlcbiAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtKGRlbHRhLCBkZWx0YS56b29tLCBkZWx0YS5yb3RhdGUsIGRlbHRhLmFib3V0KVxuICAgICAgICAgICAgaWYgKGRlbHRhLnpvb20gIT0gMSkgdGhpcy5pbnRlcmFjdGlvbkFuY2hvciA9IGRlbHRhLmFib3V0XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgcG9seWdvbigpIHtcbiAgICAgICAgbGV0IHcyID0gdGhpcy53aWR0aCAqIHRoaXMuc2NhbGUgLyAyXG4gICAgICAgIGxldCBoMiA9IHRoaXMuaGVpZ2h0ICogdGhpcy5zY2FsZSAvIDJcbiAgICAgICAgbGV0IGNlbnRlciA9IHRoaXMuY2VudGVyXG4gICAgICAgIGxldCBwb2x5Z29uID0gbmV3IFBvbHlnb24oY2VudGVyKVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogLXcyLCB5OiAtaDIgfSlcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IHcyLCB5OiAtaDIgfSlcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IHcyLCB5OiBoMiB9KVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogLXcyLCB5OiBoMiB9KVxuICAgICAgICBwb2x5Z29uLnJvdGF0ZSh0aGlzLnJvdGF0aW9uKVxuICAgICAgICByZXR1cm4gcG9seWdvblxuICAgIH1cblxuICAgIGlzT3V0c2lkZSgpIHtcbiAgICAgICAgbGV0IHN0YWdlUG9seWdvbiA9IHRoaXMuY29udGFpbmVyUG9seWdvblxuICAgICAgICBpZiAoc3RhZ2VQb2x5Z29uID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgbGV0IHBvbHlnb24gPSB0aGlzLnBvbHlnb25cbiAgICAgICAgaWYgKHBvbHlnb24gPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICBsZXQgcmVzdWx0ID0gc3RhZ2VQb2x5Z29uLmludGVyc2VjdHNXaXRoKHBvbHlnb24pXG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IGZhbHNlIHx8IHJlc3VsdC5vdmVybGFwIDwgdGhpcy50aHJvd1Zpc2liaWxpdHlcbiAgICB9XG5cbiAgICByZWNlbnRlcigpIHtcbiAgICAgICAgLy8gUmV0dXJuIGEgc21hbGwgdmVjdG9yIHRoYXQgZ3VhcmFudGVlcyB0aGF0IHRoZSBzY2F0dGVyIGlzIG1vdmluZ1xuICAgICAgICAvLyB0b3dhcmRzIHRoZSBjZW50ZXIgb2YgdGhlIHN0YWdlXG4gICAgICAgIGxldCBjZW50ZXIgPSB0aGlzLmNlbnRlclxuICAgICAgICBsZXQgdGFyZ2V0ID0gdGhpcy5jb250YWluZXIuY2VudGVyXG4gICAgICAgIGxldCBkZWx0YSA9IFBvaW50cy5zdWJ0cmFjdCh0YXJnZXQsIGNlbnRlcilcbiAgICAgICAgcmV0dXJuIFBvaW50cy5ub3JtYWxpemUoZGVsdGEpXG4gICAgfVxuXG4gICAgbmV4dFZlbG9jaXR5KHZlbG9jaXR5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmtlZXBPblN0YWdlKHZlbG9jaXR5KVxuICAgIH1cblxuICAgIGJvdW5jaW5nKCkge1xuICAgICAgICAvLyBJbXBsZW1lbnRzIHRoZSBib3VuY2luZyBiZWhhdmlvciBvZiB0aGUgc2NhdHRlci4gTW92ZXMgdGhlIHNjYXR0ZXJcbiAgICAgICAgLy8gdG8gdGhlIGNlbnRlciBvZiB0aGUgc3RhZ2UgaWYgdGhlIHNjYXR0ZXIgaXMgb3V0c2lkZSB0aGUgc3RhZ2Ugb3JcbiAgICAgICAgLy8gbm90IHdpdGhpbiB0aGUgbGltaXRzIG9mIHRoZSB0aHJvd1Zpc2liaWxpdHkuXG5cbiAgICAgICAgbGV0IHN0YWdlUG9seWdvbiA9IHRoaXMuY29udGFpbmVyUG9seWdvblxuICAgICAgICBsZXQgcG9seWdvbiA9IHRoaXMucG9seWdvblxuICAgICAgICBsZXQgcmVzdWx0ID0gc3RhZ2VQb2x5Z29uLmludGVyc2VjdHNXaXRoKHBvbHlnb24pXG4gICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlIHx8IHJlc3VsdC5vdmVybGFwIDwgdGhpcy50aHJvd1Zpc2liaWxpdHkpIHtcbiAgICAgICAgICAgIGxldCBjdiA9IHRoaXMucmVjZW50ZXIoKVxuICAgICAgICAgICAgbGV0IHJlY2VudGVyZWQgPSBmYWxzZVxuICAgICAgICAgICAgd2hpbGUgKHJlc3VsdCA9PT0gZmFsc2UgfHwgcmVzdWx0Lm92ZXJsYXAgPCB0aGlzLnRocm93VmlzaWJpbGl0eSkge1xuICAgICAgICAgICAgICAgIHBvbHlnb24uY2VudGVyLnggKz0gY3YueFxuICAgICAgICAgICAgICAgIHBvbHlnb24uY2VudGVyLnkgKz0gY3YueVxuICAgICAgICAgICAgICAgIHRoaXMuX21vdmUoY3YpXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gc3RhZ2VQb2x5Z29uLmludGVyc2VjdHNXaXRoKHBvbHlnb24pXG4gICAgICAgICAgICAgICAgcmVjZW50ZXJlZCA9IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZWNlbnRlcmVkXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAga2VlcE9uU3RhZ2UodmVsb2NpdHksIGNvbGxpc2lvbiA9IDAuNSkge1xuICAgICAgICBsZXQgc3RhZ2VQb2x5Z29uID0gdGhpcy5jb250YWluZXJQb2x5Z29uXG4gICAgICAgIGlmICghc3RhZ2VQb2x5Z29uKSByZXR1cm5cbiAgICAgICAgbGV0IHBvbHlnb24gPSB0aGlzLnBvbHlnb25cbiAgICAgICAgbGV0IGJvdW5jZWQgPSB0aGlzLmJvdW5jaW5nKClcbiAgICAgICAgaWYgKGJvdW5jZWQpIHtcbiAgICAgICAgICAgIGxldCBzdGFnZSA9IHRoaXMuY29udGFpbmVyQm91bmRzXG4gICAgICAgICAgICBsZXQgeCA9IHRoaXMuY2VudGVyLnhcbiAgICAgICAgICAgIGxldCB5ID0gdGhpcy5jZW50ZXIueVxuICAgICAgICAgICAgbGV0IGR4ID0gdGhpcy5tb3ZhYmxlWCA/IHZlbG9jaXR5LnggOiAwXG4gICAgICAgICAgICBsZXQgZHkgPSB0aGlzLm1vdmFibGVZID8gdmVsb2NpdHkueSA6IDBcbiAgICAgICAgICAgIGxldCBmYWN0b3IgPSB0aGlzLnRocm93RGFtcGluZ1xuICAgICAgICAgICAgLy8gaWYgKHJlY2VudGVyZWQpIHtcbiAgICAgICAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICAgICAgICAgIGR4ID0gLWR4XG4gICAgICAgICAgICAgICAgZmFjdG9yID0gY29sbGlzaW9uXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeCA+IHN0YWdlLndpZHRoKSB7XG4gICAgICAgICAgICAgICAgZHggPSAtZHhcbiAgICAgICAgICAgICAgICBmYWN0b3IgPSBjb2xsaXNpb25cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh5IDwgMCkge1xuICAgICAgICAgICAgICAgIGR5ID0gLWR5XG4gICAgICAgICAgICAgICAgZmFjdG9yID0gY29sbGlzaW9uXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeSA+IHN0YWdlLmhlaWdodCkge1xuICAgICAgICAgICAgICAgIGR5ID0gLWR5XG4gICAgICAgICAgICAgICAgZmFjdG9yID0gY29sbGlzaW9uXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICByZXR1cm4gUG9pbnRzLm11bHRpcGx5U2NhbGFyKHsgeDogZHgsIHk6IGR5IH0sIGZhY3RvcilcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwZXIubmV4dFZlbG9jaXR5KHZlbG9jaXR5KVxuICAgIH1cblxuICAgIGVuZEdlc3R1cmUoaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5zdGFydFRocm93KClcbiAgICAgICAgdGhpcy5fY2hlY2tBdXRvQ2xvc2UoKVxuICAgIH1cblxuICAgIF9jaGVja0F1dG9DbG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2NhbGVBdXRvQ2xvc2UpXG4gICAgICAgICAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMubWluU2NhbGUgKyB0aGlzLnNjYWxlQ2xvc2VUaHJlc2hvbGQgLSB0aGlzLnNjYWxlQ2xvc2VCdWZmZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnpvb20odGhpcy5taW5TY2FsZSwgeyBhbmltYXRlOiAwLjIsIG9uQ29tcGxldGU6IHRoaXMuY2xvc2UuYmluZCh0aGlzKSB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNjYWxlIDwgdGhpcy5taW5TY2FsZSArIHRoaXMuc2NhbGVDbG9zZVRocmVzaG9sZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuem9vbSh0aGlzLm1pblNjYWxlICsgdGhpcy5zY2FsZUNsb3NlVGhyZXNob2xkLCB7IGFuaW1hdGU6IDAuNCB9KVxuICAgICAgICAgICAgfVxuICAgIH1cblxuICAgIHJvdGF0ZURlZ3JlZXMoZGVncmVlcywgYW5jaG9yKSB7XG4gICAgICAgIGxldCByYWQgPSBBbmdsZS5kZWdyZWUycmFkaWFuKGRlZ3JlZXMpXG4gICAgICAgIHRoaXMucm90YXRlKHJhZCwgYW5jaG9yKVxuICAgIH1cblxuICAgIHJvdGF0ZShyYWQsIGFuY2hvcikge1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSh7IHg6IDAsIHk6IDAgfSwgMS4wLCByYWQsIGFuY2hvcilcbiAgICB9XG5cbiAgICBtb3ZlKGQsIHsgYW5pbWF0ZSA9IDAgfSA9IHt9KSB7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zbGF0YWJsZSkge1xuICAgICAgICAgICAgaWYgKGFuaW1hdGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0UG9zID0gdGhpcy5wb3NpdGlvblxuICAgICAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLCBhbmltYXRlLCB7XG4gICAgICAgICAgICAgICAgICAgIHg6ICcrPScgKyBkLngsXG4gICAgICAgICAgICAgICAgICAgIHk6ICcrPScgKyBkLnksXG4gICAgICAgICAgICAgICAgICAgIC8qIHNjYWxlOiBzY2FsZSwgdW86IG5vdCBkZWZpbmVkLCB3aHkgd2FzIHRoaXMgaGVyZT8gKi9cbiAgICAgICAgICAgICAgICAgICAgb25VcGRhdGU6IGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHAgPSB0aGlzLnBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZHggPSBwLnggLSBzdGFydFBvcy54XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZHkgPSBwLnggLSBzdGFydFBvcy55XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTW92ZWQoZHgsIGR5KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbW92ZShkKVxuICAgICAgICAgICAgICAgIHRoaXMub25Nb3ZlZChkLngsIGQueSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG1vdmVUbyhwLCB7IGFuaW1hdGUgPSAwIH0gPSB7fSkge1xuICAgICAgICBsZXQgYyA9IHRoaXMub3JpZ2luXG4gICAgICAgIGxldCBkZWx0YSA9IFBvaW50cy5zdWJ0cmFjdChwLCBjKVxuICAgICAgICB0aGlzLm1vdmUoZGVsdGEsIHsgYW5pbWF0ZTogYW5pbWF0ZSB9KVxuICAgIH1cblxuICAgIGNlbnRlckF0KHAsIHsgYW5pbWF0ZSA9IDAgfSA9IHt9KSB7XG4gICAgICAgIGxldCBjID0gdGhpcy5jZW50ZXJcbiAgICAgICAgbGV0IGRlbHRhID0gUG9pbnRzLnN1YnRyYWN0KHAsIGMpXG4gICAgICAgIHRoaXMubW92ZShkZWx0YSwgeyBhbmltYXRlOiBhbmltYXRlIH0pXG4gICAgfVxuXG4gICAgem9vbShcbiAgICAgICAgc2NhbGUsXG4gICAgICAgIHtcbiAgICAgICAgICAgIGFuaW1hdGUgPSAwLFxuICAgICAgICAgICAgYWJvdXQgPSBudWxsLFxuICAgICAgICAgICAgZGVsYXkgPSAwLFxuICAgICAgICAgICAgeCA9IG51bGwsXG4gICAgICAgICAgICB5ID0gbnVsbCxcbiAgICAgICAgICAgIG9uQ29tcGxldGUgPSBudWxsXG4gICAgICAgIH0gPSB7fVxuICAgICkge1xuICAgICAgICBsZXQgYW5jaG9yID0gYWJvdXQgfHwgdGhpcy5jZW50ZXJcbiAgICAgICAgaWYgKHNjYWxlICE9IHRoaXMuc2NhbGUpIHtcbiAgICAgICAgICAgIGlmIChhbmltYXRlID4gMCkge1xuICAgICAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLCBhbmltYXRlLCB7XG4gICAgICAgICAgICAgICAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgZGVsYXk6IGRlbGF5LFxuICAgICAgICAgICAgICAgICAgICBvbkNvbXBsZXRlOiBvbkNvbXBsZXRlLFxuICAgICAgICAgICAgICAgICAgICBvblVwZGF0ZTogdGhpcy5vblpvb21lZC5iaW5kKHRoaXMpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zY2FsZSA9IHNjYWxlXG4gICAgICAgICAgICAgICAgdGhpcy5vblpvb21lZChhbmNob3IpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfbW92ZShkZWx0YSkge1xuICAgICAgICB0aGlzLnggKz0gdGhpcy5tb3ZhYmxlWCA/IGRlbHRhLnggOiAwXG4gICAgICAgIHRoaXMueSArPSB0aGlzLm1vdmFibGVYID8gZGVsdGEueSA6IDBcbiAgICB9XG5cbiAgICB0cmFuc2Zvcm0odHJhbnNsYXRlLCB6b29tLCByb3RhdGUsIGFuY2hvcikge1xuICAgICAgICBsZXQgZGVsdGEgPSB7XG4gICAgICAgICAgICB4OiB0aGlzLm1vdmFibGVYID8gdHJhbnNsYXRlLnggOiAwLFxuICAgICAgICAgICAgeTogdGhpcy5tb3ZhYmxlWSA/IHRyYW5zbGF0ZS55IDogMFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJlc2l6YWJsZSkgdmFyIHZ6b29tID0gem9vbVxuICAgICAgICBpZiAoIXRoaXMudHJhbnNsYXRhYmxlKSBkZWx0YSA9IHsgeDogMCwgeTogMCB9XG4gICAgICAgIGlmICghdGhpcy5yb3RhdGFibGUpIHJvdGF0ZSA9IDBcbiAgICAgICAgaWYgKCF0aGlzLnNjYWxhYmxlKSB6b29tID0gMS4wXG4gICAgICAgIGlmICh6b29tID09IDEuMCAmJiByb3RhdGUgPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbW92ZShkZWx0YSlcbiAgICAgICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlOiBkZWx0YSxcbiAgICAgICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIHJvdGF0ZTogMCxcbiAgICAgICAgICAgICAgICAgICAgYWJvdXQ6IGFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgZmFzdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFVQREFURVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgdGhpcy5vblRyYW5zZm9ybS5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGxldCBvcmlnaW4gPSB0aGlzLnJvdGF0aW9uT3JpZ2luXG4gICAgICAgIGxldCBiZXRhID0gUG9pbnRzLmFuZ2xlKG9yaWdpbiwgYW5jaG9yKVxuICAgICAgICBsZXQgZGlzdGFuY2UgPSBQb2ludHMuZGlzdGFuY2Uob3JpZ2luLCBhbmNob3IpXG4gICAgICAgIGxldCB7IHNjYWxlOiBuZXdTY2FsZSwgem9vbTogdGhyZXNob2xkZWRab29tIH0gPSB0aGlzLmNhbGN1bGF0ZVNjYWxlKHpvb20pXG5cbiAgICAgICAgbGV0IG5ld09yaWdpbiA9IFBvaW50cy5hcmMoYW5jaG9yLCBiZXRhICsgcm90YXRlLCBkaXN0YW5jZSAqIHRocmVzaG9sZGVkWm9vbSlcbiAgICAgICAgbGV0IGV4dHJhID0gUG9pbnRzLnN1YnRyYWN0KG5ld09yaWdpbiwgb3JpZ2luKVxuICAgICAgICBsZXQgb2Zmc2V0ID0gUG9pbnRzLnN1YnRyYWN0KGFuY2hvciwgb3JpZ2luKVxuICAgICAgICB0aGlzLl9tb3ZlKG9mZnNldClcbiAgICAgICAgdGhpcy5zY2FsZSA9IG5ld1NjYWxlXG4gICAgICAgIHRoaXMucm90YXRpb24gKz0gcm90YXRlXG4gICAgICAgIG9mZnNldCA9IFBvaW50cy5uZWdhdGUob2Zmc2V0KVxuICAgICAgICBvZmZzZXQgPSBQb2ludHMuYWRkKG9mZnNldCwgZXh0cmEpXG4gICAgICAgIG9mZnNldCA9IFBvaW50cy5hZGQob2Zmc2V0LCB0cmFuc2xhdGUpXG4gICAgICAgIHRoaXMuX21vdmUob2Zmc2V0KVxuXG4gICAgICAgIGRlbHRhLnggKz0gZXh0cmEueFxuICAgICAgICBkZWx0YS55ICs9IGV4dHJhLnlcbiAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gIT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlOiBkZWx0YSxcbiAgICAgICAgICAgICAgICBzY2FsZTogbmV3U2NhbGUsXG4gICAgICAgICAgICAgICAgcm90YXRlOiByb3RhdGUsXG4gICAgICAgICAgICAgICAgYWJvdXQ6IGFuY2hvclxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJlc2l6YWJsZSkge1xuICAgICAgICAgICAgdGhpcy5yZXNpemVBZnRlclRyYW5zZm9ybSh2em9vbSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvciBhIGdpdmVuIHpvb20sIGEgbmV3IHNjYWxlIGlzIGNhbGN1bGF0ZWQsIHRha2luZ1xuICAgICAqIG1pbiBhbmQgbWF4IHNjYWxlIGludG8gYWNjb3VudC5cbiAgICAgKiBcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gem9vbSAtIFRoZSB6b29tIGZhY3RvciwgdG8gc2NhbGUgdGhlIG9iamVjdCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IC0gUmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgYSB2YWx1ZSBmb3IgYSB2YWxpZCBzY2FsZSBhbmQgdGhlIGNvcnJlY3RlZCB6b29tIGZhY3Rvci5cbiAgICAgKi9cbiAgICBjYWxjdWxhdGVTY2FsZSh6b29tKSB7XG4gICAgICAgIGxldCBzY2FsZSA9IHRoaXMuc2NhbGUgKiB6b29tXG5cbiAgICAgICAgbGV0IG1pblNjYWxlID0gdGhpcy5taW5TY2FsZSAvIHRoaXMub3ZlcmRvU2NhbGluZ1xuICAgICAgICBsZXQgbWF4U2NhbGUgPSB0aGlzLm1heFNjYWxlICogdGhpcy5vdmVyZG9TY2FsaW5nXG4gICAgICAgIGlmIChzY2FsZSA8IG1pblNjYWxlKSB7XG4gICAgICAgICAgICBzY2FsZSA9IG1pblNjYWxlXG4gICAgICAgICAgICB6b29tID0gc2NhbGUgLyB0aGlzLnNjYWxlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjYWxlID4gbWF4U2NhbGUpIHtcbiAgICAgICAgICAgIHNjYWxlID0gbWF4U2NhbGVcbiAgICAgICAgICAgIHpvb20gPSBzY2FsZSAvIHRoaXMuc2NhbGVcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNjYWxlQXV0b0Nsb3NlKVxuICAgICAgICAgICAgdGhpcy5fdXBkYXRlVHJhbnNwYXJlbmN5KClcblxuICAgICAgICByZXR1cm4geyB6b29tLCBzY2FsZSB9XG4gICAgfVxuXG4gICAgX3VwZGF0ZVRyYW5zcGFyZW5jeSgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2NhbGUgPCB0aGlzLm1pblNjYWxlICsgdGhpcy5zY2FsZUNsb3NlVGhyZXNob2xkKSB7XG4gICAgICAgICAgICBsZXQgdHJhbnNwYXJlbmN5ID0gdGhpcy5jYWxjdWxhdGVTY2FsZVRyYW5zcGFyZW5jeSgpXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUub3BhY2l0eSA9IHRyYW5zcGFyZW5jeVxuICAgICAgICB9IGVsc2UgdGhpcy5lbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAxXG4gICAgfVxuXG4gICAgY2FsY3VsYXRlU2NhbGVUcmFuc3BhcmVuY3koKSB7XG4gICAgICAgIGxldCB0cmFuc3BhcmVuY3kgPSAodGhpcy5zY2FsZSAtIHRoaXMubWluU2NhbGUpIC8gdGhpcy5zY2FsZUNsb3NlVGhyZXNob2xkXG4gICAgICAgIHRyYW5zcGFyZW5jeSA9ICh0cmFuc3BhcmVuY3kgPiAxKSA/IDEgOiAodHJhbnNwYXJlbmN5IDwgMCkgPyAwIDogdHJhbnNwYXJlbmN5XG4gICAgICAgIHJldHVybiB0cmFuc3BhcmVuY3lcbiAgICB9XG5cbiAgICByZXNpemVBZnRlclRyYW5zZm9ybSh6b29tKSB7XG4gICAgICAgIC8vIE92ZXJ3cml0ZSB0aGlzIGluIHN1YmNsYXNzZXMuXG4gICAgfVxuXG4gICAgdmFsaWRTY2FsZShzY2FsZSkge1xuICAgICAgICBzY2FsZSA9IE1hdGgubWF4KHNjYWxlLCB0aGlzLm1pblNjYWxlKVxuICAgICAgICBzY2FsZSA9IE1hdGgubWluKHNjYWxlLCB0aGlzLm1heFNjYWxlKVxuICAgICAgICByZXR1cm4gc2NhbGVcbiAgICB9XG5cbiAgICBhbmltYXRlWm9vbUJvdW5jZShkdCA9IDEpIHtcbiAgICAgICAgaWYgKHRoaXMuem9vbUFuY2hvciAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgem9vbSA9IDFcbiAgICAgICAgICAgIGxldCBhbW91bnQgPSBNYXRoLm1pbigwLjAxLCAwLjMgKiBkdCAvIDEwMDAwMC4wKVxuICAgICAgICAgICAgaWYgKHRoaXMuc2NhbGUgPCB0aGlzLm1pblNjYWxlKSB6b29tID0gMSArIGFtb3VudFxuICAgICAgICAgICAgaWYgKHRoaXMuc2NhbGUgPiB0aGlzLm1heFNjYWxlKSB6b29tID0gMSAtIGFtb3VudFxuICAgICAgICAgICAgaWYgKHpvb20gIT0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtKHsgeDogMCwgeTogMCB9LCB6b29tLCAwLCB0aGlzLnpvb21BbmNob3IpXG4gICAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGR0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbmltYXRlWm9vbUJvdW5jZShkdClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy56b29tQW5jaG9yID0gbnVsbFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2hlY2tTY2FsaW5nKGFib3V0LCBkZWxheSA9IDApIHtcbiAgICAgICAgdGhpcy56b29tQW5jaG9yID0gYWJvdXRcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuYW5pbWF0ZVpvb21Cb3VuY2UuYmluZCh0aGlzKSlcbiAgICAgICAgc2V0VGltZW91dCh0aGlzLmFuaW1hdGVab29tQm91bmNlLmJpbmQodGhpcyksIGRlbGF5KVxuICAgIH1cblxuICAgIG9uTW91c2VXaGVlbChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuY2xhaW1lZEJ5U2NhdHRlcikge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmNsYWltZWRCeVNjYXR0ZXIgIT0gdGhpcykgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5raWxsQW5pbWF0aW9uKClcbiAgICAgICAgdGhpcy50YXJnZXRTY2FsZSA9IG51bGxcbiAgICAgICAgbGV0IGRpcmVjdGlvbiA9IGV2ZW50LmRldGFpbCA8IDAgfHwgZXZlbnQud2hlZWxEZWx0YSA+IDBcbiAgICAgICAgbGV0IGdsb2JhbFBvaW50ID0geyB4OiBldmVudC5jbGllbnRYLCB5OiBldmVudC5jbGllbnRZIH1cbiAgICAgICAgbGV0IGNlbnRlclBvaW50ID0gdGhpcy5tYXBQb3NpdGlvblRvQ29udGFpbmVyUG9pbnQoZ2xvYmFsUG9pbnQpXG4gICAgICAgIGlmIChldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgbGV0IGRlZ3JlZXMgPSBkaXJlY3Rpb24gPyA1IDogLTVcbiAgICAgICAgICAgIGxldCByYWQgPSBBbmdsZS5kZWdyZWUycmFkaWFuKGRlZ3JlZXMpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oeyB4OiAwLCB5OiAwIH0sIDEuMCwgcmFkLCBjZW50ZXJQb2ludClcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB6b29tRmFjdG9yID0gdGhpcy5tb3VzZVpvb21GYWN0b3JcbiAgICAgICAgbGV0IHpvb20gPSBkaXJlY3Rpb24gPyB6b29tRmFjdG9yIDogMSAvIHpvb21GYWN0b3JcbiAgICAgICAgdGhpcy50cmFuc2Zvcm0oeyB4OiAwLCB5OiAwIH0sIHpvb20sIDAsIGNlbnRlclBvaW50KVxuICAgICAgICB0aGlzLmNoZWNrU2NhbGluZyhjZW50ZXJQb2ludCwgMjAwKVxuXG4gICAgICAgIGlmICh0aGlzLnNjYWxlQXV0b0Nsb3NlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zY2FsZSA8PSB0aGlzLm1pblNjYWxlICsgdGhpcy5zY2FsZUNsb3NlVGhyZXNob2xkKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zY2FsZUF1dG9DbG9zZVRpbWVvdXQpIGNsZWFyVGltZW91dCh0aGlzLnNjYWxlQXV0b0Nsb3NlVGltZW91dClcbiAgICAgICAgICAgICAgICB0aGlzLnNjYWxlQXV0b0Nsb3NlVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja0F1dG9DbG9zZSgpXG4gICAgICAgICAgICAgICAgfSwgNjAwKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fdXBkYXRlVHJhbnNwYXJlbmN5KClcbiAgICAgICAgfVxuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtICE9IG51bGwpIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgIC8vICAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IHt4OiAwLCB5OiAwfSxcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIHNjYWxlOiB0aGlzLnNjYWxlLFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgcm90YXRlOiAwLFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgYWJvdXQ6IG51bGwsXG4gICAgICAgIC8vICAgICAgICAgICAgICAgICBmYXN0OiBmYWxzZSxcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIHR5cGU6IFpPT01cbiAgICAgICAgLy8gICAgICAgICAgICAgfSlcbiAgICAgICAgLy8gICAgICAgICAgICAgdGhpcy5vblRyYW5zZm9ybS5mb3JFYWNoKGZ1bmN0aW9uKGYpIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgIC8vICAgICAgICAgICAgIH0pXG4gICAgICAgIC8vICAgICAgICAgfVxuICAgIH1cblxuICAgIG9uU3RhcnQoZXZlbnQsIGludGVyYWN0aW9uKSB7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhcnRHZXN0dXJlKGludGVyYWN0aW9uKSkge1xuICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IHRydWVcbiAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25BbmNob3IgPSBudWxsXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gIT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlOiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgICAgICByb3RhdGU6IDAsXG4gICAgICAgICAgICAgICAgYWJvdXQ6IG51bGwsXG4gICAgICAgICAgICAgICAgZmFzdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHlwZTogU1RBUlRcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBmKGV2ZW50KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTW92ZShldmVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgLyoqIEFzIGxvbmcgYXMgbW91c2VvdXQgJiYgbW91c2VsZWF2ZSBpbnRlcnJ1cHQgd2UgY2Fubm90IGJlIHN1cmUgdGhhdFxuICAgICAgICAgKiBkcmFnZ2luZyByZW1haW5zIGNvcnJlY3QuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAodGhpcy5kcmFnZ2luZykge1xuICAgICAgICAgICAgdGhpcy5nZXN0dXJlKGludGVyYWN0aW9uKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25FbmQoZXZlbnQsIGludGVyYWN0aW9uKSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJTY2F0dGVyLm9uRW5kXCIsIHRoaXMuZHJhZ2dpbmcpXG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5pc0ZpbmlzaGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZW5kR2VzdHVyZShpbnRlcmFjdGlvbilcbiAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZVxuICAgICAgICAgICAgZm9yIChsZXQga2V5IG9mIGludGVyYWN0aW9uLmVuZGVkLmtleXMoKSkge1xuICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdGlvbi5pc1RhcChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBwb2ludCA9IGludGVyYWN0aW9uLmVuZGVkLmdldChrZXkpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25UYXAoZXZlbnQsIGludGVyYWN0aW9uLCBwb2ludClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZTogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgICAgICAgICAgICAgIHNjYWxlOiB0aGlzLnNjYWxlLFxuICAgICAgICAgICAgICAgICAgICByb3RhdGU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGFib3V0OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBmYXN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogRU5EXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgZihldmVudClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBhYm91dCA9IHRoaXMuaW50ZXJhY3Rpb25BbmNob3JcbiAgICAgICAgaWYgKGFib3V0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tTY2FsaW5nKGFib3V0LCAxMDApXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblRhcChldmVudCwgaW50ZXJhY3Rpb24sIHBvaW50KSB7IH1cblxuICAgIG9uRHJhZ1VwZGF0ZShkZWx0YSkge1xuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICBmYXN0OiB0cnVlLFxuICAgICAgICAgICAgICAgIHRyYW5zbGF0ZTogZGVsdGEsXG4gICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICAgICAgYWJvdXQ6IHRoaXMuY3VycmVudEFib3V0LFxuICAgICAgICAgICAgICAgIHR5cGU6IG51bGxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBmKGV2ZW50KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uRHJhZ0NvbXBsZXRlKCkge1xuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSkge1xuICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICAgICAgYWJvdXQ6IHRoaXMuY3VycmVudEFib3V0LFxuICAgICAgICAgICAgICAgIGZhc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6IG51bGxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBmKGV2ZW50KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTW92ZWQoZHgsIGR5LCBhYm91dCkge1xuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IHsgeDogZHgsIHk6IGR5IH0sXG4gICAgICAgICAgICAgICAgYWJvdXQ6IGFib3V0LFxuICAgICAgICAgICAgICAgIGZhc3Q6IHRydWUsXG4gICAgICAgICAgICAgICAgdHlwZTogbnVsbFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25SZXNpemluZygpIHtcbiAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gIT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICAgICAgZmFzdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHlwZTogbnVsbFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBmKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25ab29tZWQoYWJvdXQpIHtcblxuICAgICAgICBpZiAodGhpcy5zY2FsZUF1dG9DbG9zZSlcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVRyYW5zcGFyZW5jeSgpXG5cbiAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gIT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGV2ZW50ID0gbmV3IFNjYXR0ZXJFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICAgICAgYWJvdXQ6IGFib3V0LFxuICAgICAgICAgICAgICAgIGZhc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6IG51bGxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBmKGV2ZW50KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqIEEgY29udGFpbmVyIGZvciBzY2F0dGVyIG9iamVjdHMsIHdoaWNoIHVzZXMgYSBzaW5nbGUgSW50ZXJhY3Rpb25NYXBwZXJcbiAqIGZvciBhbGwgY2hpbGRyZW4uIFRoaXMgcmVkdWNlcyB0aGUgbnVtYmVyIG9mIHJlZ2lzdGVyZWQgZXZlbnQgaGFuZGxlcnNcbiAqIGFuZCBjb3ZlcnMgdGhlIGNvbW1vbiB1c2UgY2FzZSB0aGF0IG11bHRpcGxlIG9iamVjdHMgYXJlIHNjYXR0ZXJlZFxuICogb24gdGhlIHNhbWUgbGV2ZWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBET01TY2F0dGVyQ29udGFpbmVyIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0RPTSBub2RlfSBlbGVtZW50IC0gRE9NIGVsZW1lbnQgdGhhdCByZWNlaXZlcyBldmVudHNcbiAgICAgKiBAcGFyYW0ge0Jvb2x9IHN0b3BFdmVudHMgLSAgV2hldGhlciBldmVudHMgc2hvdWxkIGJlIHN0b3BwZWQgb3IgcHJvcGFnYXRlZFxuICAgICAqIEBwYXJhbSB7Qm9vbH0gY2xhaW1FdmVudHMgLSBXaGV0aGVyIGV2ZW50cyBzaG91bGQgYmUgbWFya2VkIGFzIGNsYWltZWRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmluZFRhcmdldCByZXR1cm4gYXMgbm9uLW51bGwgdmFsdWUuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IFt0b3VjaEFjdGlvbj1ub25lXSAtIENTUyB0byBzZXQgdG91Y2ggYWN0aW9uIHN0eWxlLCBuZWVkZWQgdG8gcHJldmVudFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRlciBjYW5jZWwgZXZlbnRzLiBVc2UgbnVsbCBpZiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSB0b3VjaCBhY3Rpb24gc2hvdWxkIG5vdCBiZSBzZXQuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHsgc3RvcEV2ZW50cyA9ICdhdXRvJywgY2xhaW1FdmVudHMgPSB0cnVlLCB1c2VDYXB0dXJlID0gdHJ1ZSwgdG91Y2hBY3Rpb24gPSAnbm9uZScgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHRoaXMub25DYXB0dXJlID0gbnVsbFxuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50XG4gICAgICAgIGlmIChzdG9wRXZlbnRzID09PSAnYXV0bycpIHtcbiAgICAgICAgICAgIGlmIChDYXBhYmlsaXRpZXMuaXNTYWZhcmkpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAndG91Y2htb3ZlJyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPT4gdGhpcy5wcmV2ZW50UGluY2goZXZlbnQpLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBzdG9wRXZlbnRzID0gZmFsc2VcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcEV2ZW50cyA9IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0b3BFdmVudHMgPSBzdG9wRXZlbnRzXG4gICAgICAgIHRoaXMuY2xhaW1FdmVudHMgPSBjbGFpbUV2ZW50c1xuICAgICAgICBpZiAodG91Y2hBY3Rpb24gIT09IG51bGwpIHtcbiAgICAgICAgICAgIEVsZW1lbnRzLnNldFN0eWxlKGVsZW1lbnQsIHsgdG91Y2hBY3Rpb24gfSlcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNjYXR0ZXIgPSBuZXcgTWFwKClcbiAgICAgICAgdGhpcy5kZWxlZ2F0ZSA9IG5ldyBJbnRlcmFjdGlvbk1hcHBlcihlbGVtZW50LCB0aGlzLCB7XG4gICAgICAgICAgICB1c2VDYXB0dXJlLFxuICAgICAgICAgICAgbW91c2VXaGVlbEVsZW1lbnQ6IHdpbmRvd1xuICAgICAgICB9KVxuXG4gICAgICAgIGlmICh0eXBlb2YgZGVidWdDYW52YXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZHQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd1RvdWNoZXMoZHQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2hvd1RvdWNoZXMoZHQpIHtcbiAgICAgICAgbGV0IHJlc29sdXRpb24gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpb1xuICAgICAgICBsZXQgY2FudmFzID0gZGVidWdDYW52YXNcbiAgICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzLmRlbGVnYXRlLmludGVyYWN0aW9uLmN1cnJlbnRcbiAgICAgICAgbGV0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKVxuICAgICAgICBsZXQgcmFkaXVzID0gMjAgKiByZXNvbHV0aW9uXG4gICAgICAgIGNvbnRleHQuY2xlYXJSZWN0KDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodClcbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSAncmdiYSgwLCAwLCAwLCAwLjMpJ1xuICAgICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IDJcbiAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9ICcjMDAzMzAwJ1xuICAgICAgICBmb3IgKGxldCBba2V5LCBwb2ludF0gb2YgY3VycmVudC5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIGxldCBsb2NhbCA9IHBvaW50XG4gICAgICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpXG4gICAgICAgICAgICBjb250ZXh0LmFyYyhcbiAgICAgICAgICAgICAgICBsb2NhbC54ICogcmVzb2x1dGlvbixcbiAgICAgICAgICAgICAgICBsb2NhbC55ICogcmVzb2x1dGlvbixcbiAgICAgICAgICAgICAgICByYWRpdXMsXG4gICAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgICAyICogTWF0aC5QSSxcbiAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgY29udGV4dC5maWxsKClcbiAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKClcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZHQgPT4ge1xuICAgICAgICAgICAgdGhpcy5zaG93VG91Y2hlcyhkdClcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwcmV2ZW50UGluY2goZXZlbnQpIHtcbiAgICAgICAgZXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50XG4gICAgICAgIGlmIChldmVudC5zY2FsZSAhPT0gMSkge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYWRkKHNjYXR0ZXIpIHtcbiAgICAgICAgdGhpcy5zY2F0dGVyLnNldChzY2F0dGVyLmVsZW1lbnQsIHNjYXR0ZXIpXG4gICAgfVxuXG4gICAgY2FwdHVyZShldmVudCkge1xuICAgICAgICBpZiAodGhpcy5vbkNhcHR1cmUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9uQ2FwdHVyZShldmVudClcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQudGFyZ2V0ID09IHRoaXMuZWxlbWVudCAmJiB0aGlzLnN0b3BFdmVudHMpIHtcbiAgICAgICAgICAgIEV2ZW50cy5zdG9wKGV2ZW50KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgbWFwUG9zaXRpb25Ub1BvaW50KHBvaW50KSB7XG4gICAgICAgIHJldHVybiBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5lbGVtZW50LCBwb2ludClcbiAgICB9XG5cbiAgICBpc0Rlc2NlbmRhbnQocGFyZW50LCBjaGlsZCwgY2xpY2thYmxlID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKHBhcmVudCA9PSBjaGlsZCkgcmV0dXJuIHRydWVcbiAgICAgICAgbGV0IG5vZGUgPSBjaGlsZC5wYXJlbnROb2RlXG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICghY2xpY2thYmxlICYmIG5vZGUub25jbGljaykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vZGUgPT0gcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBmaW5kVGFyZ2V0KGV2ZW50LCBsb2NhbCwgZ2xvYmFsKSB7XG4gICAgICAgIC8qKiogTm90ZSB0aGF0IGVsZW1lbnRGcm9tUG9pbnQgd29ya3Mgd2l0aCBjbGllbnRYLCBjbGllbnRZLCBub3QgcGFnZVgsIHBhZ2VZXG4gICAgICAgIFRoZSBpbXBvcnRhbnQgcG9pbnQgaXMgdGhhdCBldmVudCBzaG91bGQgbm90IGJlIHVzZWQsIHNpbmNlIHRoZSBUb3VjaEV2ZW50XG4gICAgICAgIHBvaW50cyBhcmUgaGlkZGVuIGluIHN1YiBvYmplY3RzLlxuICAgICAgICAqKiovXG4gICAgICAgIGxldCBmb3VuZCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZ2xvYmFsLngsIGdsb2JhbC55KVxuICAgICAgICBmb3IgKGxldCB0YXJnZXQgb2YgdGhpcy5zY2F0dGVyLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBpZiAodGFyZ2V0LmludGVyYWN0aXZlICYmIHRoaXMuaXNEZXNjZW5kYW50KHRhcmdldC5lbGVtZW50LCBmb3VuZCkpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdG9wRXZlbnRzKSBFdmVudHMuc3RvcChldmVudClcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jbGFpbUV2ZW50cykgZXZlbnQuY2xhaW1lZEJ5U2NhdHRlciA9IHRhcmdldFxuICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGdldCBjZW50ZXIoKSB7XG4gICAgICAgIGxldCByID0gdGhpcy5ib3VuZHNcbiAgICAgICAgbGV0IHcyID0gci53aWR0aCAvIDJcbiAgICAgICAgbGV0IGgyID0gci5oZWlnaHQgLyAyXG4gICAgICAgIHJldHVybiB7IHg6IHcyLCB5OiBoMiB9XG4gICAgfVxuXG4gICAgZ2V0IGJvdW5kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIH1cblxuICAgIGdldCBwb2x5Z29uKCkge1xuICAgICAgICBsZXQgciA9IHRoaXMuYm91bmRzXG4gICAgICAgIGxldCB3MiA9IHIud2lkdGggLyAyXG4gICAgICAgIGxldCBoMiA9IHIuaGVpZ2h0IC8gMlxuICAgICAgICBsZXQgY2VudGVyID0geyB4OiB3MiwgeTogaDIgfVxuICAgICAgICBsZXQgcG9seWdvbiA9IG5ldyBQb2x5Z29uKGNlbnRlcilcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IC13MiwgeTogLWgyIH0pXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiB3MiwgeTogLWgyIH0pXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiB3MiwgeTogaDIgfSlcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IC13MiwgeTogaDIgfSlcbiAgICAgICAgcmV0dXJuIHBvbHlnb25cbiAgICB9XG59XG5cblxuZXhwb3J0IGNsYXNzIERPTVNjYXR0ZXIgZXh0ZW5kcyBBYnN0cmFjdFNjYXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICBjb250YWluZXIsXG4gICAgICAgIHtcbiAgICAgICAgICAgIHN0YXJ0U2NhbGUgPSAxLjAsXG4gICAgICAgICAgICBtaW5TY2FsZSA9IDAuMSxcbiAgICAgICAgICAgIG1heFNjYWxlID0gMS4wLFxuICAgICAgICAgICAgb3ZlcmRvU2NhbGluZyA9IDEuNSxcbiAgICAgICAgICAgIGF1dG9CcmluZ1RvRnJvbnQgPSB0cnVlLFxuICAgICAgICAgICAgdHJhbnNsYXRhYmxlID0gdHJ1ZSxcbiAgICAgICAgICAgIHNjYWxhYmxlID0gdHJ1ZSxcbiAgICAgICAgICAgIHJvdGF0YWJsZSA9IHRydWUsXG4gICAgICAgICAgICBtb3ZhYmxlWCA9IHRydWUsXG4gICAgICAgICAgICBtb3ZhYmxlWSA9IHRydWUsXG4gICAgICAgICAgICByb3RhdGlvbkRlZ3JlZXMgPSBudWxsLFxuICAgICAgICAgICAgcm90YXRpb24gPSBudWxsLFxuICAgICAgICAgICAgb25UcmFuc2Zvcm0gPSBudWxsLFxuICAgICAgICAgICAgdHJhbnNmb3JtT3JpZ2luID0gJ2NlbnRlciBjZW50ZXInLFxuICAgICAgICAgICAgLy8gZXh0cmFzIHdoaWNoIGFyZSBpbiBwYXJ0IG5lZWRlZFxuICAgICAgICAgICAgeCA9IDAsXG4gICAgICAgICAgICB5ID0gMCxcbiAgICAgICAgICAgIHdpZHRoID0gbnVsbCwgLy8gcmVxdWlyZWRcbiAgICAgICAgICAgIGhlaWdodCA9IG51bGwsICAvLyByZXF1aXJlZFxuICAgICAgICAgICAgcmVzaXphYmxlID0gZmFsc2UsXG4gICAgICAgICAgICBzaW11bGF0ZUNsaWNrID0gZmFsc2UsXG4gICAgICAgICAgICB2ZXJib3NlID0gdHJ1ZSxcbiAgICAgICAgICAgIG9uUmVzaXplID0gbnVsbCxcbiAgICAgICAgICAgIHRvdWNoQWN0aW9uID0gJ25vbmUnLFxuICAgICAgICAgICAgdGhyb3dWaXNpYmlsaXR5ID0gNDQsXG4gICAgICAgICAgICB0aHJvd0RhbXBpbmcgPSAwLjk1LFxuICAgICAgICAgICAgYXV0b1Rocm93ID0gdHJ1ZSxcbiAgICAgICAgICAgIHNjYWxlQXV0b0Nsb3NlID0gZmFsc2UsXG4gICAgICAgICAgICBvbkNsb3NlID0gbnVsbCxcbiAgICAgICAgICAgIHNjYWxlQ2xvc2VUaHJlc2hvbGQgPSAwLjEwLFxuICAgICAgICAgICAgc2NhbGVDbG9zZUJ1ZmZlciA9IDAuMDVcbiAgICAgICAgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIG1pblNjYWxlLFxuICAgICAgICAgICAgbWF4U2NhbGUsXG4gICAgICAgICAgICBzdGFydFNjYWxlLFxuICAgICAgICAgICAgb3ZlcmRvU2NhbGluZyxcbiAgICAgICAgICAgIGF1dG9CcmluZ1RvRnJvbnQsXG4gICAgICAgICAgICB0cmFuc2xhdGFibGUsXG4gICAgICAgICAgICBzY2FsYWJsZSxcbiAgICAgICAgICAgIHJvdGF0YWJsZSxcbiAgICAgICAgICAgIG1vdmFibGVYLFxuICAgICAgICAgICAgbW92YWJsZVksXG4gICAgICAgICAgICByZXNpemFibGUsXG4gICAgICAgICAgICByb3RhdGlvbkRlZ3JlZXMsXG4gICAgICAgICAgICByb3RhdGlvbixcbiAgICAgICAgICAgIG9uVHJhbnNmb3JtLFxuICAgICAgICAgICAgdGhyb3dWaXNpYmlsaXR5LFxuICAgICAgICAgICAgdGhyb3dEYW1waW5nLFxuICAgICAgICAgICAgYXV0b1Rocm93LFxuICAgICAgICAgICAgc2NhbGVBdXRvQ2xvc2UsXG4gICAgICAgICAgICBzY2FsZUNsb3NlVGhyZXNob2xkLFxuICAgICAgICAgICAgc2NhbGVDbG9zZUJ1ZmZlcixcbiAgICAgICAgICAgIG9uQ2xvc2VcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKGNvbnRhaW5lciA9PSBudWxsIHx8IHdpZHRoID09IG51bGwgfHwgaGVpZ2h0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB2YWx1ZTogbnVsbCcpXG4gICAgICAgIH1cbiAgICAgICAgZWxlbWVudC5zY2F0dGVyID0gdGhpc1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50XG4gICAgICAgIHRoaXMueCA9IHhcbiAgICAgICAgdGhpcy55ID0geVxuICAgICAgICB0aGlzLm9sZFggPSAwXG4gICAgICAgIHRoaXMub2xkWSA9IDBcbiAgICAgICAgdGhpcy5tZWFuWCA9IHhcbiAgICAgICAgdGhpcy5tZWFuWSA9IHlcbiAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoXG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0XG4gICAgICAgIHRoaXMudGhyb3dWaXNpYmlsaXR5ID0gTWF0aC5taW4od2lkdGgsIGhlaWdodCwgdGhyb3dWaXNpYmlsaXR5KVxuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lclxuICAgICAgICB0aGlzLnNpbXVsYXRlQ2xpY2sgPSBzaW11bGF0ZUNsaWNrXG4gICAgICAgIHRoaXMuc2NhbGUgPSBzdGFydFNjYWxlXG4gICAgICAgIHRoaXMucm90YXRpb25EZWdyZWVzID0gdGhpcy5zdGFydFJvdGF0aW9uRGVncmVlc1xuICAgICAgICB0aGlzLnRyYW5zZm9ybU9yaWdpbiA9IHRyYW5zZm9ybU9yaWdpblxuICAgICAgICB0aGlzLmluaXRpYWxWYWx1ZXMgPSB7XG4gICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgICAgc2NhbGU6IHN0YXJ0U2NhbGUsXG4gICAgICAgICAgICByb3RhdGlvbjogdGhpcy5zdGFydFJvdGF0aW9uRGVncmVlcyxcbiAgICAgICAgICAgIHRyYW5zZm9ybU9yaWdpbjogdHJhbnNmb3JtT3JpZ2luXG4gICAgICAgIH1cblxuXG4gICAgICAgIC8vIEZvciB0d2VlbmxpdGUgd2UgbmVlZCBpbml0aWFsIHZhbHVlcyBpbiBfZ3NUcmFuc2Zvcm1cbiAgICAgICAgVHdlZW5MaXRlLnNldChlbGVtZW50LCB0aGlzLmluaXRpYWxWYWx1ZXMpXG4gICAgICAgIHRoaXMub25SZXNpemUgPSBvblJlc2l6ZVxuICAgICAgICB0aGlzLnZlcmJvc2UgPSB2ZXJib3NlXG4gICAgICAgIGlmICh0b3VjaEFjdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgRWxlbWVudHMuc2V0U3R5bGUoZWxlbWVudCwgeyB0b3VjaEFjdGlvbiB9KVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVzaXplQnV0dG9uID0gbnVsbFxuICAgICAgICBpZiAocmVzaXphYmxlKSB7XG4gICAgICAgICAgICBsZXQgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKVxuICAgICAgICAgICAgYnV0dG9uLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiXG4gICAgICAgICAgICBidXR0b24uc3R5bGUucmlnaHQgPSBcIjBweFwiXG4gICAgICAgICAgICBidXR0b24uc3R5bGUuYm90dG9tID0gXCIwcHhcIlxuICAgICAgICAgICAgYnV0dG9uLnN0eWxlLndpZHRoID0gXCI1MHB4XCI7XG4gICAgICAgICAgICBidXR0b24uc3R5bGUuaGVpZ2h0ID0gXCI1MHB4XCI7XG4gICAgICAgICAgICAvLyBidXR0b24uc3R5bGUuYm9yZGVyUmFkaXVzID0gXCIxMDAlIDBweCAwcHggMHB4XCI7XG4gICAgICAgICAgICAvLyBidXR0b24uc3R5bGUuYmFja2dyb3VuZCA9IHRoaXMuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3JcbiAgICAgICAgICAgIGJ1dHRvbi5jbGFzc05hbWUgPSBcImludGVyYWN0aXZlRWxlbWVudFwiXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoYnV0dG9uKVxuXG4gICAgICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRSZXNpemUoZSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoZSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcFJlc2l6ZShlKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplQnV0dG9uID0gYnV0dG9uXG4gICAgICAgIH1cbiAgICAgICAgY29udGFpbmVyLmFkZCh0aGlzKVxuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIGdlb21ldHJ5IGRhdGEgYXMgb2JqZWN0LiAqKi9cbiAgICBnZXRTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNjYWxlOiB0aGlzLnNjYWxlLFxuICAgICAgICAgICAgeDogdGhpcy54LFxuICAgICAgICAgICAgeTogdGhpcy55LFxuICAgICAgICAgICAgcm90YXRpb246IHRoaXMucm90YXRpb25cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsb3NlKCkge1xuICAgICAgICBzdXBlci5jbG9zZSgpXG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLmVsZW1lbnQucGFyZW50Tm9kZVxuICAgICAgICBpZiAocGFyZW50KSBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5lbGVtZW50KVxuICAgIH1cblxuICAgIGdldCByb3RhdGlvbk9yaWdpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2VudGVyXG4gICAgfVxuXG4gICAgZ2V0IHgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl94XG4gICAgfVxuXG4gICAgZ2V0IHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl95XG4gICAgfVxuXG4gICAgc2V0IHgodmFsdWUpIHtcbiAgICAgICAgdGhpcy5feCA9IHZhbHVlXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHg6IHZhbHVlIH0pXG4gICAgfVxuXG4gICAgc2V0IHkodmFsdWUpIHtcbiAgICAgICAgdGhpcy5feSA9IHZhbHVlXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHk6IHZhbHVlIH0pXG4gICAgfVxuXG4gICAgZ2V0IHBvc2l0aW9uKCkge1xuICAgICAgICBsZXQgdHJhbnNmb3JtID0gdGhpcy5lbGVtZW50Ll9nc1RyYW5zZm9ybVxuICAgICAgICBsZXQgeCA9IHRyYW5zZm9ybS54XG4gICAgICAgIGxldCB5ID0gdHJhbnNmb3JtLnlcbiAgICAgICAgcmV0dXJuIHsgeCwgeSB9XG4gICAgfVxuXG4gICAgZ2V0IG9yaWdpbigpIHtcbiAgICAgICAgbGV0IHAgPSB0aGlzLmZyb21Ob2RlVG9QYWdlKDAsIDApXG4gICAgICAgIHJldHVybiBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5jb250YWluZXIuZWxlbWVudCwgcClcbiAgICB9XG5cbiAgICBnZXQgYm91bmRzKCkge1xuICAgICAgICBsZXQgc3RhZ2UgPSB0aGlzLmNvbnRhaW5lci5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIGxldCByZWN0ID0gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0b3A6IHJlY3QudG9wIC0gc3RhZ2UudG9wLFxuICAgICAgICAgICAgbGVmdDogcmVjdC5sZWZ0IC0gc3RhZ2UubGVmdCxcbiAgICAgICAgICAgIHdpZHRoOiByZWN0LndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiByZWN0LmhlaWdodFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IGNlbnRlcigpIHtcbiAgICAgICAgbGV0IHIgPSB0aGlzLmJvdW5kc1xuICAgICAgICBsZXQgdzIgPSByLndpZHRoIC8gMlxuICAgICAgICBsZXQgaDIgPSByLmhlaWdodCAvIDJcbiAgICAgICAgLy8gICBpZiAodGhpcy5yZXNpemFibGUpIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgdzIgKj0gdGhpcy5zY2FsZVxuICAgICAgICAvLyAgICAgICAgICAgICBoMiAqPSB0aGlzLnNjYWxlXG4gICAgICAgIC8vICAgICAgICAgfVxuICAgICAgICB2YXIgeCA9IHIubGVmdCArIHcyXG4gICAgICAgIHZhciB5ID0gci50b3AgKyBoMlxuICAgICAgICByZXR1cm4geyB4LCB5IH1cbiAgICB9XG5cbiAgICBzZXQgcm90YXRpb24ocmFkaWFucykge1xuICAgICAgICBsZXQgcmFkID0gcmFkaWFucyAvLyBBbmdsZS5ub3JtYWxpemUocmFkaWFucylcbiAgICAgICAgbGV0IGRlZ3JlZXMgPSBBbmdsZS5yYWRpYW4yZGVncmVlKHJhZClcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgcm90YXRpb246IGRlZ3JlZXMgfSlcbiAgICAgICAgdGhpcy5fcm90YXRpb24gPSByYWRcbiAgICB9XG5cbiAgICBzZXQgcm90YXRpb25EZWdyZWVzKGRlZ3JlZXMpIHtcbiAgICAgICAgbGV0IGRlZyA9IGRlZ3JlZXMgLy8gQW5nbGUubm9ybWFsaXplRGVncmVlKGRlZ3JlZXMpXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHJvdGF0aW9uOiBkZWcgfSlcbiAgICAgICAgdGhpcy5fcm90YXRpb24gPSBBbmdsZS5kZWdyZWUycmFkaWFuKGRlZylcbiAgICB9XG5cbiAgICBnZXQgcm90YXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb3RhdGlvblxuICAgIH1cblxuICAgIGdldCByb3RhdGlvbkRlZ3JlZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb3RhdGlvblxuICAgIH1cblxuICAgIHNldCBzY2FsZShzY2FsZSkge1xuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuZWxlbWVudCwge1xuICAgICAgICAgICAgc2NhbGU6IHNjYWxlLFxuICAgICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiB0aGlzLnRyYW5zZm9ybU9yaWdpblxuICAgICAgICB9KVxuICAgICAgICB0aGlzLl9zY2FsZSA9IHNjYWxlXG4gICAgfVxuXG4gICAgZ2V0IHNjYWxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NhbGVcbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyQm91bmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXIuYm91bmRzXG4gICAgfVxuXG4gICAgZ2V0IGNvbnRhaW5lclBvbHlnb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5wb2x5Z29uXG4gICAgfVxuXG4gICAgbWFwUG9zaXRpb25Ub0NvbnRhaW5lclBvaW50KHBvaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5tYXBQb3NpdGlvblRvUG9pbnQocG9pbnQpXG4gICAgfVxuXG4gICAgY2FwdHVyZShldmVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuZWxlbWVudCwgdGhpcy5pbml0aWFsVmFsdWVzKVxuICAgIH1cblxuICAgIGhpZGUoKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmVsZW1lbnQsIDAuMSwge1xuICAgICAgICAgICAgZGlzcGxheTogJ25vbmUnLFxuICAgICAgICAgICAgb25Db21wbGV0ZTogZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5lbGVtZW50KVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHNob3coKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IGRpc3BsYXk6ICdibG9jaycgfSlcbiAgICB9XG5cbiAgICBzaG93QXQocCwgcm90YXRpb25EZWdyZWVzKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snLFxuICAgICAgICAgICAgeDogcC54LFxuICAgICAgICAgICAgeTogcC55LFxuICAgICAgICAgICAgcm90YXRpb246IHJvdGF0aW9uRGVncmVlcyxcbiAgICAgICAgICAgIHRyYW5zZm9ybU9yaWdpbjogdGhpcy50cmFuc2Zvcm1PcmlnaW5cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBicmluZ1RvRnJvbnQoKSB7XG4gICAgICAgIC8vIHRoaXMuZWxlbWVudC5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudClcbiAgICAgICAgLy8gdW86IE9uIENob21lIGFuZCBFbGVjdG9uIGFwcGVuZENoaWxkIGxlYWRzIHRvIGZsaWNrZXJcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgekluZGV4OiBET01TY2F0dGVyLnpJbmRleCsrIH0pXG4gICAgfVxuXG4gICAgdG9nZ2xlVmlkZW8oZWxlbWVudCkge1xuICAgICAgICBpZiAoZWxlbWVudC5wYXVzZWQpIHtcbiAgICAgICAgICAgIGVsZW1lbnQucGxheSgpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbGVtZW50LnBhdXNlKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uVGFwKGV2ZW50LCBpbnRlcmFjdGlvbiwgcG9pbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuc2ltdWxhdGVDbGljaykge1xuICAgICAgICAgICAgbGV0IHAgPSBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5lbGVtZW50LCBwb2ludClcbiAgICAgICAgICAgIGxldCBpZnJhbWUgPSB0aGlzLmVsZW1lbnQucXVlcnlTZWxlY3RvcignaWZyYW1lJylcbiAgICAgICAgICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZG9jID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnRcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvYy5lbGVtZW50RnJvbVBvaW50KHAueCwgcC55KVxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZWxlbWVudC50YWdOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ1ZJREVPJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVsZW1lbnQuY3VycmVudFNyYylcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChQb3B1cE1lbnUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3B1cE1lbnUub3BlbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVsbHNjcmVlbjogKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cub3BlbihlbGVtZW50LmN1cnJlbnRTcmMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGxheTogKCkgPT4gZWxlbWVudC5wbGF5KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyB4LCB5IH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlVmlkZW8oZWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmNsaWNrKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0Rlc2NlbmRhbnQocGFyZW50LCBjaGlsZCkge1xuICAgICAgICBsZXQgbm9kZSA9IGNoaWxkLnBhcmVudE5vZGVcbiAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKG5vZGUgPT0gcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBmcm9tUGFnZVRvTm9kZSh4LCB5KSB7XG4gICAgICAgIHJldHVybiBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5lbGVtZW50LCB7IHgsIHkgfSlcbiAgICB9XG5cbiAgICBmcm9tTm9kZVRvUGFnZSh4LCB5KSB7XG4gICAgICAgIHJldHVybiBQb2ludHMuZnJvbU5vZGVUb1BhZ2UodGhpcy5lbGVtZW50LCB7IHgsIHkgfSlcbiAgICB9XG5cbiAgICBfbW92ZShkZWx0YSkge1xuICAgICAgICAvLyBVTzogV2UgbmVlZCB0byBrZWVwIFR3ZWVuTGl0ZSdzIF9nc1RyYW5zZm9ybSBhbmQgdGhlIHByaXZhdGVcbiAgICAgICAgLy8gX3ggYW5kIF95IGF0dHJpYnV0ZXMgYWxpZ25lZFxuICAgICAgICBsZXQgeCA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0ueFxuICAgICAgICBsZXQgeSA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0ueVxuICAgICAgICBpZiAodGhpcy5tb3ZhYmxlWCkge1xuICAgICAgICAgICAgeCArPSBkZWx0YS54XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubW92YWJsZVkpIHtcbiAgICAgICAgICAgIHkgKz0gZGVsdGEueVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3ggPSB4XG4gICAgICAgIHRoaXMuX3kgPSB5XG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHg6IHgsIHk6IHkgfSlcbiAgICB9XG5cbiAgICByZXNpemVBZnRlclRyYW5zZm9ybSh6b29tKSB7XG4gICAgICAgIC8vICBsZXQgdyA9IHRoaXMud2lkdGggKiB0aGlzLnNjYWxlXG4gICAgICAgIC8vICAgICAgICAgbGV0IGggPSB0aGlzLmhlaWdodCAqIHRoaXMuc2NhbGVcbiAgICAgICAgLy8gICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuZWxlbWVudCwgeyB3aWR0aDogdywgaGVpZ2h0OiBoIH0pXG4gICAgICAgIGlmICh0aGlzLm9uUmVzaXplKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgUmVzaXplRXZlbnQodGhpcywgeyB3aWR0aDogdywgaGVpZ2h0OiBoIH0pXG4gICAgICAgICAgICB0aGlzLm9uUmVzaXplKGV2ZW50KVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJlc2l6ZUJ1dHRvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyB0aGlzLnJlc2l6ZUJ1dHRvbi5zdHlsZS53aWR0aCA9IDUwL3RoaXMuc2NhbGUrXCJweFwiXG4gICAgICAgICAgICAvLyB0aGlzLnJlc2l6ZUJ1dHRvbi5zdHlsZS5oZWlnaHQgPSA1MC90aGlzLnNjYWxlK1wicHhcIlxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhcnRSZXNpemUoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgbGV0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCdyZXNpemVTdGFydGVkJylcblxuICAgICAgICBsZXQgb2xkUG9zdGl0aW9uID0geyB4OiAkKHRoaXMuZWxlbWVudCkucG9zaXRpb24oKS5sZWZ0LCB5OiAkKHRoaXMuZWxlbWVudCkucG9zaXRpb24oKS50b3AgfVxuICAgICAgICB0aGlzLmJyaW5nVG9Gcm9udCgpXG5cbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IFwiMCUgMCVcIlxuXG4gICAgICAgIGxldCBuZXdQb3N0aXRpb24gPSB7IHg6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLmxlZnQsIHk6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLnRvcCB9XG5cbiAgICAgICAgbGV0IG9mZnNldCA9IFBvaW50cy5zdWJ0cmFjdChvbGRQb3N0aXRpb24sIG5ld1Bvc3RpdGlvbilcblxuICAgICAgICB0aGlzLm9sZFggPSBlLmNsaWVudFhcbiAgICAgICAgdGhpcy5vbGRZID0gZS5jbGllbnRZXG5cbiAgICAgICAgZS50YXJnZXQuc2V0QXR0cmlidXRlKCdyZXNpemluZycsIFwidHJ1ZVwiKVxuICAgICAgICBlLnRhcmdldC5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZClcblxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5lbGVtZW50LCAwLCB7IGNzczogeyBsZWZ0OiBcIis9XCIgKyBvZmZzZXQueCArIFwicHhcIiB9IH0pXG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmVsZW1lbnQsIDAsIHsgY3NzOiB7IHRvcDogXCIrPVwiICsgb2Zmc2V0LnkgKyBcInB4XCIgfSB9KVxuXG4gICAgICAgIHRoaXMuZWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICB9XG5cbiAgICByZXNpemUoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcblxuICAgICAgICBsZXQgcm90YXRpb24gPSBBbmdsZS5yYWRpYW4yZGVncmVlKHRoaXMucm90YXRpb24pXG4gICAgICAgIHJvdGF0aW9uID0gKHJvdGF0aW9uICsgMzYwKSAlIDM2MFxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ3Jlc2l6ZWQnKVxuICAgICAgICBpZiAoZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdyZXNpemluZycpID09IFwidHJ1ZVwiKSB7XG5cbiAgICAgICAgICAgIGxldCBkZWx0YVggPSAoZS5jbGllbnRYIC0gdGhpcy5vbGRYKVxuICAgICAgICAgICAgbGV0IGRlbHRhWSA9IChlLmNsaWVudFkgLSB0aGlzLm9sZFkpXG5cbiAgICAgICAgICAgIGxldCByID0gTWF0aC5zcXJ0KE1hdGgucG93KGRlbHRhWCwgMikgKyBNYXRoLnBvdyhkZWx0YVksIDIpKVxuICAgICAgICAgICAgbGV0IHBoaSA9IEFuZ2xlLnJhZGlhbjJkZWdyZWUoTWF0aC5hdGFuMihkZWx0YVgsIGRlbHRhWSkpXG5cbiAgICAgICAgICAgIHBoaSA9ICgocGhpKSArIDYzMCkgJSAzNjBcbiAgICAgICAgICAgIGxldCByb3QgPSAoKHJvdGF0aW9uICsgOTApICsgNjMwKSAlIDM2MFxuXG4gICAgICAgICAgICBsZXQgZGlmZkFuZ2xlID0gKCgwICsgcm90KSArIDM2MCkgJSAzNjBcbiAgICAgICAgICAgIGxldCBwaGlDb3JyZWN0ZWQgPSAocGhpICsgZGlmZkFuZ2xlICsgMzYwKSAlIDM2MFxuXG4gICAgICAgICAgICBsZXQgcmVzaXplVyA9IHIgKiBNYXRoLmNvcyhBbmdsZS5kZWdyZWUycmFkaWFuKHBoaUNvcnJlY3RlZCkpXG4gICAgICAgICAgICBsZXQgcmVzaXplSCA9IC1yICogTWF0aC5zaW4oQW5nbGUuZGVncmVlMnJhZGlhbihwaGlDb3JyZWN0ZWQpKVxuXG4gICAgICAgICAgICBpZiAodGhpcy5lbGVtZW50Lm9mZnNldFdpZHRoICsgcmVzaXplVyAvIHRoaXMuc2NhbGUgPiB0aGlzLndpZHRoICogMC4zICYmIHRoaXMuZWxlbWVudC5vZmZzZXRIZWlnaHQgKyByZXNpemVIIC8gdGhpcy5zY2FsZSA+IHRoaXMuaGVpZ2h0ICogMC4zKSBUd2VlbkxpdGUudG8odGhpcy5lbGVtZW50LCAwLCB7IHdpZHRoOiB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGggKyByZXNpemVXIC8gdGhpcy5zY2FsZSwgaGVpZ2h0OiB0aGlzLmVsZW1lbnQub2Zmc2V0SGVpZ2h0ICsgcmVzaXplSCAvIHRoaXMuc2NhbGUgfSk7XG5cbiAgICAgICAgICAgIHRoaXMub2xkWCA9IGUuY2xpZW50WFxuICAgICAgICAgICAgdGhpcy5vbGRZID0gZS5jbGllbnRZXG4gICAgICAgICAgICB0aGlzLm9uUmVzaXppbmcoKVxuXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdG9wUmVzaXplKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICAgICAgbGV0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCdyZXNpemVFbmRlZCcpXG4gICAgICAgIGxldCBvbGRQb3N0aXRpb24gPSB7IHg6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLmxlZnQsIHk6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLnRvcCB9XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBcIjUwJSA1MCVcIlxuICAgICAgICBsZXQgbmV3UG9zdGl0aW9uID0geyB4OiAkKHRoaXMuZWxlbWVudCkucG9zaXRpb24oKS5sZWZ0LCB5OiAkKHRoaXMuZWxlbWVudCkucG9zaXRpb24oKS50b3AgfVxuICAgICAgICBsZXQgb2Zmc2V0ID0gUG9pbnRzLnN1YnRyYWN0KG9sZFBvc3RpdGlvbiwgbmV3UG9zdGl0aW9uKVxuXG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmVsZW1lbnQsIDAsIHsgY3NzOiB7IGxlZnQ6IFwiKz1cIiArIG9mZnNldC54ICsgXCJweFwiIH0gfSlcbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuZWxlbWVudCwgMCwgeyBjc3M6IHsgdG9wOiBcIis9XCIgKyBvZmZzZXQueSArIFwicHhcIiB9IH0pXG5cbiAgICAgICAgZS50YXJnZXQuc2V0QXR0cmlidXRlKCdyZXNpemluZycsIFwiZmFsc2VcIilcblxuICAgICAgICB0aGlzLmVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgfVxufVxuXG5ET01TY2F0dGVyLnpJbmRleCA9IDEwMDBcbiIsImltcG9ydCB7IGdldElkIH0gZnJvbSAnLi91dGlscy5qcydcbmltcG9ydCB7IERPTVNjYXR0ZXIgfSBmcm9tICcuL3NjYXR0ZXIuanMnXG5pbXBvcnQgeyBJbnRlcmFjdGlvbk1hcHBlciB9IGZyb20gJy4vaW50ZXJhY3Rpb24uanMnXG5cbmV4cG9ydCBjbGFzcyBDYXJkTG9hZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgc3JjLFxuICAgICAgICB7XG4gICAgICAgICAgICB4ID0gMCxcbiAgICAgICAgICAgIHkgPSAwLFxuICAgICAgICAgICAgd2lkdGggPSAxMDAwLFxuICAgICAgICAgICAgaGVpZ2h0ID0gODAwLFxuICAgICAgICAgICAgbWF4V2lkdGggPSBudWxsLFxuICAgICAgICAgICAgbWF4SGVpZ2h0ID0gbnVsbCxcbiAgICAgICAgICAgIHNjYWxlID0gMSxcbiAgICAgICAgICAgIG1pblNjYWxlID0gMC41LFxuICAgICAgICAgICAgbWF4U2NhbGUgPSAxLjUsXG4gICAgICAgICAgICByb3RhdGlvbiA9IDBcbiAgICAgICAgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHRoaXMuc3JjID0gc3JjXG4gICAgICAgIHRoaXMueCA9IHhcbiAgICAgICAgdGhpcy55ID0geVxuICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGVcbiAgICAgICAgdGhpcy5yb3RhdGlvbiA9IDBcbiAgICAgICAgdGhpcy5tYXhTY2FsZSA9IG1heFNjYWxlXG4gICAgICAgIHRoaXMubWluU2NhbGUgPSBtaW5TY2FsZVxuICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gd2lkdGhcbiAgICAgICAgdGhpcy53YW50ZWRIZWlnaHQgPSBoZWlnaHRcbiAgICAgICAgdGhpcy5tYXhXaWR0aCA9IG1heFdpZHRoICE9IG51bGwgPyBtYXhXaWR0aCA6IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICAgIHRoaXMubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0ICE9IG51bGwgPyBtYXhIZWlnaHQgOiB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICAgICAgdGhpcy5hZGRlZE5vZGUgPSBudWxsXG4gICAgICAgIGNvbnNvbGUubG9nKHtcbiAgICAgICAgIFxuICAgICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgICBtYXhXaWR0aCxcbiAgICAgICAgICAgIG1heEhlaWdodCxcbiAgICAgICAgICAgXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgdW5sb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5hZGRlZE5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkZWROb2RlLnJlbW92ZSgpXG4gICAgICAgICAgICB0aGlzLmFkZGVkTm9kZSA9IG51bGxcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBERkxvYWRlciBleHRlbmRzIENhcmRMb2FkZXIge1xuICAgIGNvbnN0cnVjdG9yKHNyYywgeyB3aWR0aCA9IDE2NDAsIGhlaWdodCA9IDgwMCwgc2NhbGUgPSAxIH0gPSB7fSkge1xuICAgICAgICBzdXBlcihzcmMsIHsgd2lkdGgsIGhlaWdodCwgc2NhbGUgfSlcbiAgICAgICAgaWYgKHR5cGVvZiBQREZKUyA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgYWxlcnQoJ1BERi5qcyBuZWVkZWQnKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZChkb21Ob2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBQREZKUy5nZXREb2N1bWVudCh0aGlzLnNyYykudGhlbihwZGYgPT4ge1xuICAgICAgICAgICAgICAgIHBkZi5nZXRQYWdlKDEpLnRoZW4ocGFnZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzY2FsZSA9IHRoaXMuc2NhbGUgKiBhcHAucmVuZGVyZXIucmVzb2x1dGlvblxuICAgICAgICAgICAgICAgICAgICBsZXQgaW52U2NhbGUgPSAxIC8gc2NhbGVcbiAgICAgICAgICAgICAgICAgICAgbGV0IHZpZXdwb3J0ID0gcGFnZS5nZXRWaWV3cG9ydChzY2FsZSlcblxuICAgICAgICAgICAgICAgICAgICAvLyBQcmVwYXJlIGNhbnZhcyB1c2luZyBQREYgcGFnZSBkaW1lbnNpb25zLlxuICAgICAgICAgICAgICAgICAgICBsZXQgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJylcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKVxuICAgICAgICAgICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gdmlld3BvcnQuaGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHZpZXdwb3J0LndpZHRoXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVuZGVyIFBERiBwYWdlIGludG8gY2FudmFzIGNvbnRleHQuXG4gICAgICAgICAgICAgICAgICAgIGxldCByZW5kZXJDb250ZXh0ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FudmFzQ29udGV4dDogY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0OiB2aWV3cG9ydFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHBhZ2UucmVuZGVyKHJlbmRlckNvbnRleHQpXG4gICAgICAgICAgICAgICAgICAgIGRvbU5vZGUuYXBwZW5kQ2hpbGQoY2FudmFzKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gY2FudmFzLndpZHRoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2FudGVkSGVpZ2h0ID0gY2FudmFzLmhlaWdodFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNjYWxlID0gaW52U2NhbGVcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRlZE5vZGUgPSBjYW52YXNcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEltYWdlTG9hZGVyIGV4dGVuZHMgQ2FyZExvYWRlciB7XG4gICAgbG9hZChkb21Ob2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgaXNJbWFnZSA9IGRvbU5vZGUgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50XG4gICAgICAgICAgICBsZXQgaW1hZ2UgPSBpc0ltYWdlID8gZG9tTm9kZSA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpXG4gICAgICAgICAgICBpbWFnZS5vbmxvYWQgPSBlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzSW1hZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tTm9kZS5hcHBlbmRDaGlsZChpbWFnZSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRlZE5vZGUgPSBpbWFnZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gaW1hZ2UubmF0dXJhbFdpZHRoXG4gICAgICAgICAgICAgICAgdGhpcy53YW50ZWRIZWlnaHQgPSBpbWFnZS5uYXR1cmFsSGVpZ2h0XG5cbiAgICAgICAgICAgICAgICBsZXQgc2NhbGVXID0gdGhpcy5tYXhXaWR0aCAvIGltYWdlLm5hdHVyYWxXaWR0aFxuICAgICAgICAgICAgICAgIGxldCBzY2FsZUggPSB0aGlzLm1heEhlaWdodCAvIGltYWdlLm5hdHVyYWxIZWlnaHRcbiAgICAgICAgICAgICAgICB0aGlzLnNjYWxlID0gTWF0aC5taW4odGhpcy5tYXhTY2FsZSwgTWF0aC5taW4oc2NhbGVXLCBzY2FsZUgpKVxuICAgICAgICAgICAgICAgIGltYWdlLnNldEF0dHJpYnV0ZSgnZHJhZ2dhYmxlJywgZmFsc2UpXG4gICAgICAgICAgICAgICAgaW1hZ2Uud2lkdGggPSBpbWFnZS5uYXR1cmFsV2lkdGhcbiAgICAgICAgICAgICAgICBpbWFnZS5oZWlnaHQgPSBpbWFnZS5uYXR1cmFsSGVpZ2h0XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW1hZ2Uub25lcnJvciA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdCh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW1hZ2Uuc3JjID0gdGhpcy5zcmNcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGcmFtZUxvYWRlciBleHRlbmRzIENhcmRMb2FkZXIge1xuICAgIGxvYWQoZG9tTm9kZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IGlzRnJhbWUgPSBkb21Ob2RlIGluc3RhbmNlb2YgSFRNTElGcmFtZUVsZW1lbnRcbiAgICAgICAgICAgIGxldCBpZnJhbWUgPSBpc0ZyYW1lID8gZG9tTm9kZSA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnRnJhbWVMb2FkZXIubG9hZCcsIGlzRnJhbWUsIGlmcmFtZSwgdGhpcy5zcmMpXG4gICAgICAgICAgICBpZnJhbWUuZnJhbWVCb3JkZXIgPSAwXG4gICAgICAgICAgICBpZnJhbWUuc3R5bGUuc2Nyb2xsaW5nID0gZmFsc2VcbiAgICAgICAgICAgIGlmcmFtZS53aWR0aCA9IHRoaXMud2FudGVkV2lkdGhcbiAgICAgICAgICAgIGlmcmFtZS5oZWlnaHQgPSB0aGlzLndhbnRlZEhlaWdodFxuICAgICAgICAgICAgaWYgKCFpc0ZyYW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gVW5saWtlIGltZyBvbmxvYWQgaXMgb25seSB0cmlnZ2VyZWQgaWYgdGhlIGlmcmFtZSBpcyBwYXJ0IG9mIHRoZSBET00gdHJlZVxuICAgICAgICAgICAgICAgIGRvbU5vZGUuYXBwZW5kQ2hpbGQoaWZyYW1lKVxuICAgICAgICAgICAgICAgIHRoaXMuYWRkZWROb2RlID0gaWZyYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZnJhbWUub25sb2FkID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWZyYW1lLm9uZXJyb3IgPSBlID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QodGhpcylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmcmFtZS5zcmMgPSB0aGlzLnNyY1xuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEhUTUxMb2FkZXIgZXh0ZW5kcyBDYXJkTG9hZGVyIHtcbiAgICBsb2FkKGRvbU5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKVxuICAgICAgICAgICAgeGhyLm9wZW4oJ0dFVCcsIHRoaXMuc3JjLCBmYWxzZSlcbiAgICAgICAgICAgIHhoci5vbmxvYWQgPSBlID0+IHtcbiAgICAgICAgICAgICAgICBkb21Ob2RlLmlubmVySFRNTCA9IHhoci5yZXNwb25zZVxuICAgICAgICAgICAgICAgIHRoaXMuYWRkZWROb2RlID0gZG9tTm9kZS5maXJzdEVsZW1lbnRDaGlsZFxuICAgICAgICAgICAgICAgIGxldCB7IHdpZHRoLCBoZWlnaHQgfSA9IHRoaXMuc2l6ZSh0aGlzLmFkZGVkTm9kZSlcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkhUTUxMb2FkZXIubG9hZFwiLCB7IGFkZGVkOiB0aGlzLmFkZGVkTm9kZSwgd2lkdGgsIGhlaWdodCB9KVxuICAgICAgICAgICAgICAgIGlmICh3aWR0aClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53YW50ZWRXaWR0aCA9IHdpZHRoIHx8IHRoaXMud2FudGVkV2lkdGhcbiAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0KVxuICAgICAgICAgICAgICAgICAgICB0aGlzLndhbnRlZEhlaWdodCA9IGhlaWdodCB8fCB0aGlzLndhbnRlZEhlaWdodFxuICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHhoci5vbmVycm9yID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB4aHIuc2VuZCgpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZXMgdG8gZGV0ZXJtaW5lIHRoZSBzaXplIG9mIHRoZSBhZGRlZE5vZGUuXG4gICAgICogQ2hlY2tzIGZvciBleHBsaWNpdCB3aWR0aCBhbmQgaGVpZ2h0IHN0eWxlIGF0dHJpYnV0ZXMuXG4gICAgICogXG4gICAgICogT3ZlcndyaXRlIHRoaXMgbWV0aG9kIGlmIHlvdSB3YW50IHRvIGV4dHJhY3QgdmFsdWVzIGZyb20gb3RoZXIgaW5mb3MuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7IHdpZHRoOiBpbnQsIGhlaWdodDogaW50IH1cbiAgICAgKiBAbWVtYmVyb2YgSFRNTExvYWRlclxuICAgICAqL1xuICAgIHNpemUobm9kZSkge1xuICAgICAgICBsZXQgd2lkdGggPSBwYXJzZUludChub2RlLnN0eWxlLndpZHRoKSB8fCBudWxsXG4gICAgICAgIGxldCBoZWlnaHQgPSBwYXJzZUludChub2RlLnN0eWxlLmhlaWdodCkgfHwgbnVsbFxuICAgICAgICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0IH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBET01GbGlwIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgZG9tU2NhdHRlckNvbnRhaW5lcixcbiAgICAgICAgZmxpcFRlbXBsYXRlLFxuICAgICAgICBmcm9udExvYWRlcixcbiAgICAgICAgYmFja0xvYWRlcixcbiAgICAgICAge1xuICAgICAgICAgICAgY2xvc2VPbk1pblNjYWxlID0gZmFsc2UsXG4gICAgICAgICAgICBmbGlwRHVyYXRpb24gPSAxLFxuICAgICAgICAgICAgZmFkZUR1cmF0aW9uID0gMC4yLFxuICAgICAgICAgICAgb3ZlcmRvU2NhbGluZyA9IDEsXG4gICAgICAgICAgICBhdXRvTG9hZCA9IGZhbHNlLFxuICAgICAgICAgICAgY2VudGVyID0gbnVsbCxcbiAgICAgICAgICAgIHByZWxvYWRCYWNrID0gZmFsc2UsXG4gICAgICAgICAgICB0cmFuc2xhdGFibGUgPSB0cnVlLFxuICAgICAgICAgICAgc2NhbGFibGUgPSB0cnVlLFxuICAgICAgICAgICAgcm90YXRhYmxlID0gdHJ1ZSxcbiAgICAgICAgICAgIG9uRnJvbnQgPSBudWxsLFxuICAgICAgICAgICAgb25CYWNrID0gbnVsbCxcbiAgICAgICAgICAgIG9uQ2xvc2UgPSBudWxsLFxuICAgICAgICAgICAgb25VcGRhdGUgPSBudWxsLFxuICAgICAgICAgICAgb25SZW1vdmVkID0gbnVsbCxcbiAgICAgICAgICAgIG9uTG9hZGVkID0gbnVsbFxuICAgICAgICB9ID0ge31cbiAgICApIHtcbiAgICAgICAgdGhpcy5kb21TY2F0dGVyQ29udGFpbmVyID0gZG9tU2NhdHRlckNvbnRhaW5lclxuICAgICAgICB0aGlzLmlkID0gZ2V0SWQoKVxuICAgICAgICB0aGlzLmZsaXBEdXJhdGlvbiA9IGZsaXBEdXJhdGlvblxuICAgICAgICB0aGlzLmZhZGVEdXJhdGlvbiA9IGZhZGVEdXJhdGlvblxuICAgICAgICB0aGlzLmNsb3NlT25NaW5TY2FsZSA9IGNsb3NlT25NaW5TY2FsZVxuICAgICAgICB0aGlzLmZsaXBUZW1wbGF0ZSA9IGZsaXBUZW1wbGF0ZVxuICAgICAgICB0aGlzLmZyb250TG9hZGVyID0gZnJvbnRMb2FkZXJcbiAgICAgICAgdGhpcy5iYWNrTG9hZGVyID0gYmFja0xvYWRlclxuICAgICAgICB0aGlzLnRyYW5zbGF0YWJsZSA9IHRyYW5zbGF0YWJsZVxuICAgICAgICB0aGlzLnNjYWxhYmxlID0gc2NhbGFibGVcbiAgICAgICAgdGhpcy5yb3RhdGFibGUgPSByb3RhdGFibGVcbiAgICAgICAgdGhpcy5vbkZyb250RmxpcHBlZCA9IG9uRnJvbnRcbiAgICAgICAgdGhpcy5vbkJhY2tGbGlwcGVkID0gb25CYWNrXG4gICAgICAgIHRoaXMub25DbG9zZSA9IG9uQ2xvc2VcbiAgICAgICAgdGhpcy5vblJlbW92ZWQgPSBvblJlbW92ZWRcbiAgICAgICAgdGhpcy5vblVwZGF0ZSA9IG9uVXBkYXRlXG4gICAgICAgIHRoaXMub25Mb2FkZWQgPSBvbkxvYWRlZFxuICAgICAgICB0aGlzLmNlbnRlciA9IGNlbnRlclxuICAgICAgICB0aGlzLnByZWxvYWRCYWNrID0gcHJlbG9hZEJhY2tcbiAgICAgICAgdGhpcy5vdmVyZG9TY2FsaW5nID0gb3ZlcmRvU2NhbGluZ1xuICAgICAgICBpZiAoYXV0b0xvYWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZCgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsb2FkKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IHQgPSB0aGlzLmZsaXBUZW1wbGF0ZVxuICAgICAgICAgICAgbGV0IGRvbSA9IHRoaXMuZG9tU2NhdHRlckNvbnRhaW5lci5lbGVtZW50XG4gICAgICAgICAgICBsZXQgd3JhcHBlciA9IHQuY29udGVudC5xdWVyeVNlbGVjdG9yKCcuZmxpcFdyYXBwZXInKVxuICAgICAgICAgICAgd3JhcHBlci5pZCA9IHRoaXMuaWRcbiAgICAgICAgICAgIGxldCBjbG9uZSA9IGRvY3VtZW50LmltcG9ydE5vZGUodC5jb250ZW50LCB0cnVlKVxuICAgICAgICAgICAgZG9tLmFwcGVuZENoaWxkKGNsb25lKVxuICAgICAgICAgICAgLy8gV2UgY2Fubm90IHVzZSB0aGUgZG9jdW1lbnQgZnJhZ21lbnQgaXRzZWxmIGJlY2F1c2UgaXRcbiAgICAgICAgICAgIC8vIGlzIG5vdCBwYXJ0IG9mIHRoZSBtYWluIGRvbSB0cmVlLiBBZnRlciB0aGUgYXBwZW5kQ2hpbGRcbiAgICAgICAgICAgIC8vIGNhbGwgd2UgY2FuIGFjY2VzcyB0aGUgbmV3IGRvbSBlbGVtZW50IGJ5IGlkXG4gICAgICAgICAgICB0aGlzLmNhcmRXcmFwcGVyID0gZG9tLnF1ZXJ5U2VsZWN0b3IoJyMnICsgdGhpcy5pZClcbiAgICAgICAgICAgIGxldCBmcm9udCA9IHRoaXMuY2FyZFdyYXBwZXIucXVlcnlTZWxlY3RvcignLmZyb250JylcbiAgICAgICAgICAgIHRoaXMuZnJvbnRMb2FkZXIubG9hZChmcm9udCkudGhlbihsb2FkZXIgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZnJvbnRMb2FkZWQobG9hZGVyKS50aGVuKChvYmopID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25Mb2FkZWQpIHRoaXMub25Mb2FkZWQoKVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgZnJvbnRMb2FkZWQobG9hZGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgc2NhdHRlciA9IG5ldyBET01TY2F0dGVyKFxuICAgICAgICAgICAgICAgIHRoaXMuY2FyZFdyYXBwZXIsXG4gICAgICAgICAgICAgICAgdGhpcy5kb21TY2F0dGVyQ29udGFpbmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgeDogbG9hZGVyLngsXG4gICAgICAgICAgICAgICAgICAgIHk6IGxvYWRlci55LFxuICAgICAgICAgICAgICAgICAgICBzdGFydFNjYWxlOiBsb2FkZXIuc2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIHNjYWxlOiBsb2FkZXIuc2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIG1heFNjYWxlOiBsb2FkZXIubWF4U2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIG1pblNjYWxlOiBsb2FkZXIubWluU2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiBsb2FkZXIud2FudGVkV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogbG9hZGVyLndhbnRlZEhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgcm90YXRpb246IGxvYWRlci5yb3RhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRhYmxlOiB0aGlzLnRyYW5zbGF0YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgc2NhbGFibGU6IHRoaXMuc2NhbGFibGUsXG4gICAgICAgICAgICAgICAgICAgIHJvdGF0YWJsZTogdGhpcy5yb3RhdGFibGUsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJkb1NjYWxpbmc6IHRoaXMub3ZlcmRvU2NhbGluZ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIClcblxuICAgICAgICAgICAgaWYgKHRoaXMuY2VudGVyKSB7XG4gICAgICAgICAgICAgICAgc2NhdHRlci5jZW50ZXJBdCh0aGlzLmNlbnRlcilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY2xvc2VPbk1pblNjYWxlKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCByZW1vdmVPbk1pblNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NhdHRlci5zY2FsZSA8PSBzY2F0dGVyLm1pblNjYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZsaXBwYWJsZS5jbG9zZSgpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICdEaXNhYmxlJyBvdmVyZG9zY2FsaW5nIHRvIGF2b2lkIHdlaXJkIGp1bXBzIG9uIGNsb3NlLlxuICAgICAgICAgICAgICAgICAgICAgICAgc2NhdHRlci5taW5TY2FsZSAvPSBzY2F0dGVyLm92ZXJkb1NjYWxpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjYXR0ZXIub3ZlcmRvU2NhbGluZyA9IDFcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2F0dGVyLm9uVHJhbnNmb3JtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNhbGxiYWNrSWR4ID0gc2NhdHRlci5vblRyYW5zZm9ybS5pbmRleE9mKHJlbW92ZU9uTWluU2NhbGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhdHRlci5vblRyYW5zZm9ybS5zcGxpY2UoY2FsbGJhY2tJZHgsIDEpXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKVxuXG5cblxuICAgICAgICAgICAgICAgIHNjYXR0ZXIuYWRkVHJhbnNmb3JtRXZlbnRDYWxsYmFjayhyZW1vdmVPbk1pblNjYWxlKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZmxpcHBhYmxlID0gbmV3IERPTUZsaXBwYWJsZSh0aGlzLmNhcmRXcmFwcGVyLCBzY2F0dGVyLCB0aGlzKVxuICAgICAgICAgICAgbGV0IGJhY2sgPSB0aGlzLmNhcmRXcmFwcGVyLnF1ZXJ5U2VsZWN0b3IoJy5iYWNrJylcblxuICAgICAgICAgICAgaWYgKHRoaXMucHJlbG9hZEJhY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJhY2tMb2FkZXIubG9hZChiYWNrKS50aGVuKGxvYWRlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dXBGbGlwcGFibGUoZmxpcHBhYmxlLCBsb2FkZXIpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmxpcHBhYmxlID0gZmxpcHBhYmxlXG4gICAgICAgICAgICByZXNvbHZlKHRoaXMpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgY2VudGVyQXQocCkge1xuICAgICAgICB0aGlzLmNlbnRlciA9IHBcbiAgICAgICAgdGhpcy5mbGlwcGFibGUuY2VudGVyQXQocClcbiAgICB9XG5cbiAgICB6b29tKHNjYWxlKSB7XG4gICAgICAgIHRoaXMuZmxpcHBhYmxlLnpvb20oc2NhbGUpXG4gICAgfVxuXG4gICAgc2V0dXBGbGlwcGFibGUoZmxpcHBhYmxlLCBsb2FkZXIpIHtcbiAgICAgICAgZmxpcHBhYmxlLndhbnRlZFdpZHRoID0gbG9hZGVyLndhbnRlZFdpZHRoXG4gICAgICAgIGZsaXBwYWJsZS53YW50ZWRIZWlnaHQgPSBsb2FkZXIud2FudGVkSGVpZ2h0XG4gICAgICAgIGZsaXBwYWJsZS53YW50ZWRTY2FsZSA9IGxvYWRlci5zY2FsZVxuICAgICAgICBmbGlwcGFibGUubWluU2NhbGUgPSBsb2FkZXIubWluU2NhbGVcbiAgICAgICAgZmxpcHBhYmxlLm1heFNjYWxlID0gbG9hZGVyLm1heFNjYWxlXG4gICAgICAgIGZsaXBwYWJsZS5zY2FsZUJ1dHRvbnMoKVxuICAgIH1cblxuICAgIHN0YXJ0KHsgdGFyZ2V0Q2VudGVyID0gbnVsbCB9ID0ge30pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ0RPTUZsaXAuc3RhcnQnLCB0YXJnZXRDZW50ZXIpXG4gICAgICAgIGlmICh0aGlzLnByZWxvYWRCYWNrKSB0aGlzLmZsaXBwYWJsZS5zdGFydCh7IGR1cmF0aW9uOiB0aGlzLmZsaXBEdXJhdGlvbiwgdGFyZ2V0Q2VudGVyIH0pXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IGJhY2sgPSB0aGlzLmNhcmRXcmFwcGVyLnF1ZXJ5U2VsZWN0b3IoJy5iYWNrJylcbiAgICAgICAgICAgIGxldCBmbGlwcGFibGUgPSB0aGlzLmZsaXBwYWJsZVxuICAgICAgICAgICAgdGhpcy5iYWNrTG9hZGVyLmxvYWQoYmFjaykudGhlbihsb2FkZXIgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0dXBGbGlwcGFibGUoZmxpcHBhYmxlLCBsb2FkZXIpXG4gICAgICAgICAgICAgICAgZmxpcHBhYmxlLnN0YXJ0KHsgZHVyYXRpb246IHRoaXMuZmxpcER1cmF0aW9uLCB0YXJnZXRDZW50ZXIgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmYWRlT3V0QW5kUmVtb3ZlKCkge1xuICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jYXJkV3JhcHBlciwgdGhpcy5mYWRlRHVyYXRpb24sIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkV3JhcHBlci5yZW1vdmUoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIGNsb3NlZCgpIHtcbiAgICAgICAgdGhpcy51bmxvYWQoKVxuICAgIH1cblxuICAgIHVubG9hZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByZWxvYWRCYWNrKSB7XG4gICAgICAgICAgICB0aGlzLmJhY2tMb2FkZXIudW5sb2FkKClcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIERPTUZsaXBwYWJsZSB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2NhdHRlciwgZmxpcCkge1xuICAgICAgICAvLyBTZXQgbG9nIHRvIGNvbnNvbGUubG9nIG9yIGEgY3VzdG9tIGxvZyBmdW5jdGlvblxuICAgICAgICAvLyBkZWZpbmUgZGF0YSBzdHJ1Y3R1cmVzIHRvIHN0b3JlIG91ciB0b3VjaHBvaW50cyBpblxuXG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnRcbiAgICAgICAgdGhpcy5mbGlwID0gZmxpcFxuICAgICAgICB0aGlzLmNhcmQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5mbGlwQ2FyZCcpXG4gICAgICAgIHRoaXMuZnJvbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5mcm9udCcpXG4gICAgICAgIHRoaXMuYmFjayA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmJhY2snKVxuICAgICAgICB0aGlzLmZsaXBwZWQgPSBmYWxzZVxuICAgICAgICB0aGlzLnNjYXR0ZXIgPSBzY2F0dGVyXG4gICAgICAgIHRoaXMub25Gcm9udEZsaXBwZWQgPSBmbGlwLm9uRnJvbnRGbGlwcGVkXG4gICAgICAgIHRoaXMub25CYWNrRmxpcHBlZCA9IGZsaXAub25CYWNrRmxpcHBlZFxuICAgICAgICB0aGlzLm9uQ2xvc2UgPSBmbGlwLm9uQ2xvc2VcbiAgICAgICAgdGhpcy5vblJlbW92ZWQgPSBmbGlwLm9uUmVtb3ZlZFxuICAgICAgICB0aGlzLm9uVXBkYXRlID0gZmxpcC5vblVwZGF0ZVxuXG4gICAgICAgIHRoaXMuZmxpcER1cmF0aW9uID0gZmxpcC5mbGlwRHVyYXRpb25cbiAgICAgICAgdGhpcy5mYWRlRHVyYXRpb24gPSBmbGlwLmZhZGVEdXJhdGlvblxuICAgICAgICBzY2F0dGVyLmFkZFRyYW5zZm9ybUV2ZW50Q2FsbGJhY2sodGhpcy5zY2F0dGVyVHJhbnNmb3JtZWQuYmluZCh0aGlzKSlcbiAgICAgICAgY29uc29sZS5sb2coJ2xpYi5ET01GbGlwcGFibGUnLCA1MDAwKVxuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuZWxlbWVudCwgeyBwZXJzcGVjdGl2ZTogNTAwMCB9KVxuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuY2FyZCwgeyB0cmFuc2Zvcm1TdHlsZTogJ3ByZXNlcnZlLTNkJyB9KVxuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuYmFjaywgeyByb3RhdGlvblk6IC0xODAgfSlcbiAgICAgICAgVHdlZW5MaXRlLnNldChbdGhpcy5iYWNrLCB0aGlzLmZyb250XSwge1xuICAgICAgICAgICAgYmFja2ZhY2VWaXNpYmlsaXR5OiAnaGlkZGVuJyxcbiAgICAgICAgICAgIHBlcnNwZWN0aXZlOiA1MDAwXG4gICAgICAgIH0pXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5mcm9udCwgeyB2aXNpYmlsaXR5OiAndmlzaWJsZScgfSlcbiAgICAgICAgdGhpcy5pbmZvQnRuID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuaW5mb0J0bicpXG4gICAgICAgIHRoaXMuYmFja0J0biA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmJhY2tCdG4nKVxuICAgICAgICB0aGlzLmNsb3NlQnRuID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuY2xvc2VCdG4nKVxuICAgICAgICAvKiBCdXR0b25zIGFyZSBub3QgZ3VhcmFudGVlZCB0byBleGlzdC4gKi9cbiAgICAgICAgaWYgKHRoaXMuaW5mb0J0bikge1xuICAgICAgICAgICAgSW50ZXJhY3Rpb25NYXBwZXIub24oJ3RhcCcsIHRoaXMuaW5mb0J0biwgZXZlbnQgPT4gdGhpcy5mbGlwLnN0YXJ0KCkpXG5cbiAgICAgICAgICAgIHRoaXMuZW5hYmxlKHRoaXMuaW5mb0J0bilcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5iYWNrQnRuKSB7XG4gICAgICAgICAgICBJbnRlcmFjdGlvbk1hcHBlci5vbigndGFwJywgdGhpcy5iYWNrQnRuLCBldmVudCA9PiB0aGlzLnN0YXJ0KCkpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY2xvc2VCdG4pIHtcbiAgICAgICAgICAgIEludGVyYWN0aW9uTWFwcGVyLm9uKCd0YXAnLCB0aGlzLmNsb3NlQnRuLCBldmVudCA9PiB0aGlzLmNsb3NlKCkpXG4gICAgICAgICAgICB0aGlzLmVuYWJsZSh0aGlzLmNsb3NlQnRuKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2NhbGVCdXR0b25zKClcbiAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQoKVxuICAgIH1cblxuICAgIGNsb3NlKCkge1xuICAgICAgICB0aGlzLmRpc2FibGUodGhpcy5pbmZvQnRuKVxuICAgICAgICB0aGlzLmRpc2FibGUodGhpcy5jbG9zZUJ0bilcbiAgICAgICAgaWYgKHRoaXMub25DbG9zZSkge1xuICAgICAgICAgICAgdGhpcy5vbkNsb3NlKHRoaXMpXG4gICAgICAgICAgICB0aGlzLmZsaXAuY2xvc2VkKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2NhdHRlci56b29tKDAuMSwge1xuICAgICAgICAgICAgICAgIGFuaW1hdGU6IHRoaXMuZmFkZUR1cmF0aW9uLFxuICAgICAgICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZSgpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmxpcC5jbG9zZWQoKVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vblJlbW92ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25SZW1vdmVkLmNhbGwodGhpcylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG93RnJvbnQoKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5mcm9udCwgeyB2aXNpYmlsaXR5OiAndmlzaWJsZScgfSlcbiAgICB9XG5cbiAgICBjZW50ZXJBdChwKSB7XG4gICAgICAgIHRoaXMuc2NhdHRlci5jZW50ZXJBdChwKVxuICAgIH1cblxuICAgIHpvb20oc2NhbGUpIHtcbiAgICAgICAgdGhpcy5zY2F0dGVyLnpvb20oc2NhbGUpXG4gICAgfVxuXG4gICAgZ2V0IGJ1dHRvblNjYWxlKCkge1xuICAgICAgICBsZXQgaXNjYWxlID0gMS4wXG5cbiAgICAgICAgaWYgKHRoaXMuc2NhdHRlciAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgc2NhbGUgPSB0aGlzLnNjYXR0ZXIuc2NhbGUgfHwgMVxuICAgICAgICAgICAgaXNjYWxlID0gMS4wIC8gc2NhbGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNjYWxlXG4gICAgfVxuXG4gICAgc2NhbGVCdXR0b25zKCkge1xuICAgICAgICAvL1RoaXMgYWxzbyB3b3JrcyBmb3Igc3Zncy5cbiAgICAgICAgLy8gaWYgKHRoaXMuaW5mb0J0bilcbiAgICAgICAgLy8gICAgIHRoaXMuaW5mb0J0bi5zdHlsZS50cmFuc2Zvcm0gPSBcInNjYWxlKFwiICsgdGhpcy5idXR0b25TY2FsZSArIFwiKVwiXG5cbiAgICAgICAgLy8gaWYgKHRoaXMuYmFja0J0bilcbiAgICAgICAgLy8gICAgIHRoaXMuYmFja0J0bi5zdHlsZS50cmFuc2Zvcm0gPSBcInNjYWxlKFwiICsgdGhpcy5idXR0b25TY2FsZSArIFwiKVwiXG5cbiAgICAgICAgLy8gaWYgKHRoaXMuY2xvc2VCdG4pXG4gICAgICAgIC8vICAgICB0aGlzLmNsb3NlQnRuLnN0eWxlLnRyYW5zZm9ybSA9IFwic2NhbGUoXCIgKyB0aGlzLmJ1dHRvblNjYWxlICsgXCIpXCJcblxuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmJ1dHRvblNjYWxlKVxuICAgICAgICAvLy8vIFRoaXMgZGlkIG5vdCB3b3JrIHdpdGggc3ZncyFcbiAgICAgICAgVHdlZW5MaXRlLnNldChbdGhpcy5pbmZvQnRuLCB0aGlzLmJhY2tCdG4sIHRoaXMuY2xvc2VCdG5dLCB7XG4gICAgICAgICAgICBzY2FsZTogdGhpcy5idXR0b25TY2FsZVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIGJyaW5nVG9Gcm9udCgpIHtcbiAgICAgICAgdGhpcy5zY2F0dGVyLmJyaW5nVG9Gcm9udCgpXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHpJbmRleDogRE9NU2NhdHRlci56SW5kZXgrKyB9KVxuICAgIH1cblxuICAgIGNsaWNrSW5mbygpIHtcbiAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQoKVxuICAgICAgICB0aGlzLmluZm9CdG4uY2xpY2soKVxuICAgIH1cblxuICAgIHNjYXR0ZXJUcmFuc2Zvcm1lZChldmVudCkge1xuICAgICAgICB0aGlzLnNjYWxlQnV0dG9ucygpXG4gICAgfVxuXG4gICAgdGFyZ2V0Um90YXRpb24oYWxwaGEpIHtcbiAgICAgICAgbGV0IG9ydGhvID0gOTBcbiAgICAgICAgbGV0IHJlc3QgPSBhbHBoYSAlIG9ydGhvXG4gICAgICAgIGxldCBkZWx0YSA9IDAuMFxuICAgICAgICBpZiAocmVzdCA+IG9ydGhvIC8gMi4wKSB7XG4gICAgICAgICAgICBkZWx0YSA9IG9ydGhvIC0gcmVzdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsdGEgPSAtcmVzdFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWx0YVxuICAgIH1cblxuICAgIGluZm9WYWx1ZXMoaW5mbykge1xuICAgICAgICBsZXQgc3RhcnRYID0gdGhpcy5lbGVtZW50Ll9nc1RyYW5zZm9ybS54XG4gICAgICAgIGxldCBzdGFydFkgPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnlcbiAgICAgICAgbGV0IHN0YXJ0QW5nbGUgPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnJvdGF0aW9uXG4gICAgICAgIGxldCBzdGFydFNjYWxlID0gdGhpcy5lbGVtZW50Ll9nc1RyYW5zZm9ybS5zY2FsZVhcbiAgICAgICAgbGV0IHcgPSB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGhcbiAgICAgICAgbGV0IGggPSB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0XG4gICAgICAgIGNvbnNvbGUubG9nKGluZm8sIHN0YXJ0WCwgc3RhcnRZLCBzdGFydEFuZ2xlLCBzdGFydFNjYWxlLCB3LCBoKVxuICAgIH1cblxuICAgIHNob3coZWxlbWVudCwgZHVyYXRpb24gPSAwLCBhbHBoYSA9IDEpIHtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIFR3ZWVuTGl0ZS50byhlbGVtZW50LCBkdXJhdGlvbiwgeyBhdXRvQWxwaGE6IGFscGhhIH0pIC8vIHZpc2liaWxpdHk6ICd2aXNpYmxlJywgZGlzcGxheTogJ2luaXRpYWwnfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGhpZGUoZWxlbWVudCwgZHVyYXRpb24gPSAwLCBhbHBoYSA9IDApIHtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIFR3ZWVuTGl0ZS50byhlbGVtZW50LCBkdXJhdGlvbiwgeyBhdXRvQWxwaGE6IGFscGhhIH0pIC8vIHt2aXNpYmlsaXR5OiAnaGlkZGVuJywgZGlzcGxheTogJ25vbmUnfSlcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbiAgICBlbmFibGUoYnV0dG9uKSB7XG4gICAgICAgIHRoaXMuc2hvdyhidXR0b24sIHRoaXMuZmFkZUR1cmF0aW9uKVxuICAgICAgICBpZiAoYnV0dG9uKSB7XG4gICAgICAgICAgICBUd2VlbkxpdGUuc2V0KGJ1dHRvbiwgeyBwb2ludGVyRXZlbnRzOiAnYXV0bycgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpc2FibGUoYnV0dG9uKSB7XG4gICAgICAgIHRoaXMuaGlkZShidXR0b24sIHRoaXMuZmFkZUR1cmF0aW9uKVxuICAgICAgICBpZiAoYnV0dG9uKSB7XG4gICAgICAgICAgICBUd2VlbkxpdGUuc2V0KGJ1dHRvbiwgeyBwb2ludGVyRXZlbnRzOiAnbm9uZScgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXJ0KHsgdGFyZ2V0Q2VudGVyID0gbnVsbCB9ID0ge30pIHtcbiAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQoKVxuICAgICAgICBpZiAoIXRoaXMuZmxpcHBlZCkge1xuICAgICAgICAgICAgdGhpcy5zdGFydFggPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnhcbiAgICAgICAgICAgIHRoaXMuc3RhcnRZID0gdGhpcy5lbGVtZW50Ll9nc1RyYW5zZm9ybS55XG4gICAgICAgICAgICB0aGlzLnN0YXJ0QW5nbGUgPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnJvdGF0aW9uXG4gICAgICAgICAgICB0aGlzLnN0YXJ0U2NhbGUgPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnNjYWxlWFxuICAgICAgICAgICAgdGhpcy5zdGFydFdpZHRoID0gdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoXG4gICAgICAgICAgICB0aGlzLnN0YXJ0SGVpZ2h0ID0gdGhpcy5lbGVtZW50LnN0eWxlLmhlaWdodFxuICAgICAgICAgICAgdGhpcy5zY2F0dGVyU3RhcnRXaWR0aCA9IHRoaXMuc2NhdHRlci53aWR0aFxuICAgICAgICAgICAgdGhpcy5zY2F0dGVyU3RhcnRIZWlnaHQgPSB0aGlzLnNjYXR0ZXIuaGVpZ2h0XG4gICAgICAgICAgICB0aGlzLnNob3codGhpcy5iYWNrKVxuICAgICAgICAgICAgdGhpcy5kaXNhYmxlKHRoaXMuaW5mb0J0bilcbiAgICAgICAgICAgIHRoaXMuZGlzYWJsZSh0aGlzLmNsb3NlQnRuKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zaG93KHRoaXMuZnJvbnQsIHRoaXMuZmFkZUR1cmF0aW9uKVxuICAgICAgICAgICAgdGhpcy5kaXNhYmxlKHRoaXMuYmFja0J0bilcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyBzY2FsYWJsZSwgdHJhbnNsYXRhYmxlLCByb3RhdGFibGUgfSA9IHRoaXMuc2NhdHRlclxuICAgICAgICB0aGlzLnNhdmVkID0geyBzY2FsYWJsZSwgdHJhbnNsYXRhYmxlLCByb3RhdGFibGUgfVxuICAgICAgICB0aGlzLnNjYXR0ZXIuc2NhbGFibGUgPSBmYWxzZVxuICAgICAgICB0aGlzLnNjYXR0ZXIudHJhbnNsYXRhYmxlID0gZmFsc2VcbiAgICAgICAgdGhpcy5zY2F0dGVyLnJvdGF0YWJsZSA9IGZhbHNlXG4gICAgICAgIHRoaXMuc2NhdHRlci5raWxsQW5pbWF0aW9uKClcblxuICAgICAgICB0aGlzLmZsaXBwZWQgPSAhdGhpcy5mbGlwcGVkXG4gICAgICAgIGxldCB0YXJnZXRZID0gdGhpcy5mbGlwcGVkID8gMTgwIDogMFxuICAgICAgICBsZXQgdGFyZ2V0WiA9IHRoaXMuZmxpcHBlZFxuICAgICAgICAgICAgPyB0aGlzLnN0YXJ0QW5nbGUgKyB0aGlzLnRhcmdldFJvdGF0aW9uKHRoaXMuc3RhcnRBbmdsZSlcbiAgICAgICAgICAgIDogdGhpcy5zdGFydEFuZ2xlXG4gICAgICAgIGxldCB0YXJnZXRTY2FsZSA9IHRoaXMuZmxpcHBlZCA/IHRoaXMud2FudGVkU2NhbGUgOiB0aGlzLnN0YXJ0U2NhbGVcbiAgICAgICAgbGV0IHcgPSB0aGlzLmZsaXBwZWQgPyB0aGlzLndhbnRlZFdpZHRoIDogdGhpcy5zdGFydFdpZHRoXG4gICAgICAgIGxldCBoID0gdGhpcy5mbGlwcGVkID8gdGhpcy53YW50ZWRIZWlnaHQgOiB0aGlzLnN0YXJ0SGVpZ2h0XG4gICAgICAgIGxldCBkdyA9IHRoaXMud2FudGVkV2lkdGggLSB0aGlzLnNjYXR0ZXIud2lkdGhcbiAgICAgICAgbGV0IGRoID0gdGhpcy53YW50ZWRIZWlnaHQgLSB0aGlzLnNjYXR0ZXIuaGVpZ2h0XG4gICAgICAgIGxldCB0YyA9IHRhcmdldENlbnRlclxuICAgICAgICBsZXQgeHggPSB0YyAhPSBudWxsID8gdGMueCAtIHcgLyAyIDogdGhpcy5zdGFydFggLSBkdyAvIDJcbiAgICAgICAgbGV0IHl5ID0gdGMgIT0gbnVsbCA/IHRjLnkgLSBoIC8gMiA6IHRoaXMuc3RhcnRZIC0gZGggLyAyXG4gICAgICAgIGxldCB4ID0gdGhpcy5mbGlwcGVkID8geHggOiB0aGlzLnN0YXJ0WFxuICAgICAgICBsZXQgeSA9IHRoaXMuZmxpcHBlZCA/IHl5IDogdGhpcy5zdGFydFlcblxuICAgICAgICBjb25zb2xlLmxvZyhcIkRPTUZsaXBwYWJsZS5zdGFydFwiLCB0aGlzLmZsaXBwZWQsIHRhcmdldENlbnRlciwgeCwgeSwgdGhpcy5zYXZlZClcbiAgICAgICAgbGV0IG9uVXBkYXRlID0gdGhpcy5vblVwZGF0ZSAhPT0gbnVsbCA/ICgpID0+IHRoaXMub25VcGRhdGUodGhpcykgOiBudWxsXG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMuZmxpcER1cmF0aW9uKVxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jYXJkLCB0aGlzLmZsaXBEdXJhdGlvbiwge1xuICAgICAgICAgICAgcm90YXRpb25ZOiB0YXJnZXRZLFxuICAgICAgICAgICAgZWFzZTogUG93ZXIxLmVhc2VPdXQsXG4gICAgICAgICAgICB0cmFuc2Zvcm1PcmlnaW46ICc1MCUgNTAlJyxcbiAgICAgICAgICAgIG9uVXBkYXRlLFxuICAgICAgICAgICAgb25Db21wbGV0ZTogZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmxpcHBlZCkge1xuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuaGlkZSh0aGlzLmZyb250KVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZSh0aGlzLmJhY2tCdG4pXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvdyh0aGlzLmJhY2tCdG4pXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25Gcm9udEZsaXBwZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Gcm9udEZsaXBwZWQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25CYWNrRmxpcHBlZCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZSh0aGlzLmluZm9CdG4sIHRoaXMuZmFkZUR1cmF0aW9uKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbmFibGUodGhpcy5jbG9zZUJ0biwgdGhpcy5mYWRlRHVyYXRpb24pXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQmFja0ZsaXBwZWQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZsaXAudW5sb2FkKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zY2F0dGVyLnNjYWxlID0gdGFyZ2V0U2NhbGVcbiAgICAgICAgICAgICAgICB0aGlzLnNjYWxlQnV0dG9ucygpXG4gICAgICAgICAgICAgICAgdGhpcy5zY2F0dGVyLnJvdGF0aW9uRGVncmVlcyA9IHRhcmdldFpcbiAgICAgICAgICAgICAgICB0aGlzLnNjYXR0ZXIud2lkdGggPSB0aGlzLmZsaXBwZWQgPyB3IDogdGhpcy5zY2F0dGVyU3RhcnRXaWR0aFxuICAgICAgICAgICAgICAgIHRoaXMuc2NhdHRlci5oZWlnaHQgPSB0aGlzLmZsaXBwZWQgPyBoIDogdGhpcy5zY2F0dGVyU3RhcnRIZWlnaHRcblxuICAgICAgICAgICAgICAgIGxldCB7IHNjYWxhYmxlLCB0cmFuc2xhdGFibGUsIHJvdGF0YWJsZSB9ID0gdGhpcy5zYXZlZFxuICAgICAgICAgICAgICAgIHRoaXMuc2NhdHRlci5zY2FsYWJsZSA9IHNjYWxhYmxlXG4gICAgICAgICAgICAgICAgdGhpcy5zY2F0dGVyLnRyYW5zbGF0YWJsZSA9IHRyYW5zbGF0YWJsZVxuICAgICAgICAgICAgICAgIHRoaXMuc2NhdHRlci5yb3RhdGFibGUgPSByb3RhdGFibGVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmb3JjZTNEOiB0cnVlXG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9mb3J1bXMvdG9waWMvNzk5Ny1yb3RhdGUtdGhlLXNob3J0ZXN0LXdheS9cbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuZWxlbWVudCwgdGhpcy5mbGlwRHVyYXRpb24gLyAyLCB7XG4gICAgICAgICAgICBzY2FsZTogdGFyZ2V0U2NhbGUsXG4gICAgICAgICAgICBlYXNlOiBQb3dlcjEuZWFzZU91dCxcbiAgICAgICAgICAgIHJvdGF0aW9uWjogdGFyZ2V0WiArICdfc2hvcnQnLFxuICAgICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiAnNTAlIDUwJScsXG4gICAgICAgICAgICB3aWR0aDogdyxcbiAgICAgICAgICAgIGhlaWdodDogaCxcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgb25Db21wbGV0ZTogZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmxpcHBlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhpZGUodGhpcy5mcm9udClcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5oaWRlKHRoaXMuaW5mb0J0bilcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhpZGUodGhpcy5iYWNrKVxuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLnNob3codGhpcy5pbmZvQnRuKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG59XG4iLCJpbXBvcnQge0NhcGFiaWxpdGllc30gZnJvbSAnLi9jYXBhYmlsaXRpZXMuanMnXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEluZGV4IHtcblxuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlLCBwYWdlcywgbm90Zm91bmQ9J3RodW1ibmFpbHMvbm90Zm91bmQucG5nJykge1xuICAgICAgICB0aGlzLnRlbXBsYXRlID0gdGVtcGxhdGVcbiAgICAgICAgdGhpcy5wYWdlcyA9IHBhZ2VzXG4gICAgICAgIHRoaXMubm90Zm91bmQgPSBub3Rmb3VuZFxuICAgIH1cblxuICAgIHNldHVwKCkge1xuICAgICAgICBmb3IobGV0IHBhaXIgb2YgdGhpcy5wYWdlcykge1xuICAgICAgICAgICAgbGV0IFt0aXRsZSwgc3JjXSA9IHBhaXJcbiAgICAgICAgICAgIGxldCBpZCA9IGdldElkKClcbiAgICAgICAgICAgIHBhaXIucHVzaChpZClcbiAgICAgICAgICAgIGxldCB0ID0gdGhpcy50ZW1wbGF0ZVxuICAgICAgICAgICAgbGV0IHdyYXBwZXIgPSB0LmNvbnRlbnQucXVlcnlTZWxlY3RvcignLndyYXBwZXInKVxuICAgICAgICAgICAgd3JhcHBlci5pZCA9IGlkXG4gICAgICAgICAgICBsZXQgY2xvbmUgPSBkb2N1bWVudC5pbXBvcnROb2RlKHQuY29udGVudCwgdHJ1ZSlcbiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChjbG9uZSlcbiAgICAgICAgICAgIHdyYXBwZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignIycraWQpXG5cbiAgICAgICAgICAgIGxldCBpY29uID0gd3JhcHBlci5xdWVyeVNlbGVjdG9yKCcuaWNvbicpXG5cbiAgICAgICAgICAgIGljb24ub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubm90Zm91bmQpXG4gICAgICAgICAgICAgICAgICAgIGljb24uc3JjID0gdGhpcy5ub3Rmb3VuZFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGljb25TcmMgPSBzcmMucmVwbGFjZSgnLmh0bWwnLCAnLnBuZycpXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiaWNvblNyY1wiLCBpY29uU3JjKVxuICAgICAgICAgICAgaWYgKGljb25TcmMuZW5kc1dpdGgoJ2luZGV4LnBuZycpKSB7XG4gICAgICAgICAgICAgICAgaWNvbi5zcmMgPSBpY29uU3JjLnJlcGxhY2UoJ2luZGV4LnBuZycsICd0aHVtYm5haWwucG5nJylcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaWNvblNyYy5lbmRzV2l0aCgndGVzdC5wbmcnKSkge1xuICAgICAgICAgICAgICAgIGljb24uc3JjID0gaWNvblNyYy5yZXBsYWNlKCd0ZXN0LnBuZycsICd0aHVtYm5haWwudGVzdC5wbmcnKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpY29uLnNyYyA9ICd0aHVtYm5haWxzLycgKyBpY29uU3JjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3cmFwcGVyLmhyZWYgPSBzcmNcbiAgICAgICAgICAgIGxldCB0aXRsZURpdiA9IHdyYXBwZXIucXVlcnlTZWxlY3RvcignLnRpdGxlJylcbiAgICAgICAgICAgIHRpdGxlRGl2LmlubmVyVGV4dCA9IHRpdGxlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmcmFtZXMoKSB7XG4gICAgICAgIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIGxldCBbdGl0bGUsIHNyYywgaWRdID0gdGhpcy5wYWdlcy5zaGlmdCgpXG4gICAgICAgIGxldCBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKVxuICAgICAgICBpZnJhbWUuZnJhbWVib3JkZXIgPSAwXG4gICAgICAgIGxldCB3cmFwcGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpXG4gICAgICAgIGxldCBpY29uID0gd3JhcHBlci5xdWVyeVNlbGVjdG9yKCcuaWNvbicpXG5cbiAgICAgICAgaWNvbi5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChpZnJhbWUsIGljb24pXG4gICAgICAgIGlmcmFtZS5vbmxvYWQgPSAoZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mcmFtZXMoKVxuICAgICAgICB9XG4gICAgICAgIGlmcmFtZS5zcmMgPSBzcmMgKyB3aW5kb3cubG9jYXRpb24uc2VhcmNoXG4gICAgfVxuXG4gICAgbG9hZCgpIHtcbiAgICAgICAgdGhpcy5zZXR1cCgpXG4gICAgICAgIGlmICh3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN0YXJ0c1dpdGgoJz90ZXN0JykpXG4gICAgICAgICAgICB0aGlzLmZyYW1lcygpXG4gICAgfVxuXG4gICAgbG9hZEFuZFRlc3QoKSB7XG4gICAgICAgIHRoaXMuc2V0dXAoKVxuICAgICAgICBpZiAoIUNhcGFiaWxpdGllcy5pc01vYmlsZSlcbiAgICAgICAgICAgIHRoaXMuZnJhbWVzKClcbiAgICB9XG59XG4iLCIvKiogQmFzaWMgY2xhc3MgZm9yIHBvcHBhYmxlIGVsZW1lbnRzIHRoYXQgbmVlZCB0byBiZSBjbG9zZWQgYXMgc29vbiBhcyBvbmUgcG9wcGFibGUgaXNcbiAqIHNob3duLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQb3BwYWJsZSB7XG5cbiAgICAvKiogUmVnaXN0ZXIgdGhlIHBvcHBhYmxlIGVsZW1lbnQgaW4gYSBjb250ZXh0LiBDbG9zZXMgcHJldmlvdXNseSByZWdpc3RlcmVkIG9uZXMuXG4gICAgICogQHBhcmFtIHsqfSBjb250ZXh0IFxuICAgICAqL1xuICAgIHJlZ2lzdGVyKGNvbnRleHQpIHtcbiAgICAgICAgbGV0IHJlZ2lzdGVyZWQgPSBQb3BwYWJsZS5nZXQoY29udGV4dClcbiAgICAgICAgaWYgKHJlZ2lzdGVyZWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVnaXN0ZXJlZC5jbG9zZSgpXG4gICAgICAgIH1cbiAgICAgICAgUG9wcGFibGUuc2V0KGNvbnRleHQsIHRoaXMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5yZWdpc3RlciBvYmplY3QgZnJvbSBjb250ZXh0XG4gICAgICogQHBhcmFtIHsqfSBjb250ZXh0IFxuICAgICAqL1xuICAgIHVucmVnaXN0ZXIoY29udGV4dCkge1xuICAgICAgICBQb3BwYWJsZS5kZWxldGUoY29udGV4dClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBnaXZlbiBwb3BwYWJsZSBpbiBhIGNvbnRleHRcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHsqfSBjb250ZXh0XG4gICAgICogQHJldHVybnNcbiAgICAgKiBAbWVtYmVyb2YgUG9wcGFibGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0KGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIFBvcHBhYmxlLnJlZ2lzdHJhdGlvbnMuZ2V0KGNvbnRleHQpXG4gICAgfVxuXG4gICAgLyoqIFNldHMgdGhlIHBvcHBhYmxlIGluIHRoZSBnaXZlbiBjb250ZXh0IFxuICAgICogQHN0YXRpY1xuICAgICogQHBhcmFtIHsqfSBjb250ZXh0XG4gICAgKiBAcGFyYW0geyp9IHBvcHBhYmxlXG4gICAgKiBAcmV0dXJuc1xuICAgICogQG1lbWJlcm9mIFBvcHBhYmxlXG4gICAgKi9cbiAgICBzdGF0aWMgc2V0KGNvbnRleHQsIHBvcHBhYmxlKSB7XG4gICAgICAgIHJldHVybiBQb3BwYWJsZS5yZWdpc3RyYXRpb25zLnNldChjb250ZXh0LCBwb3BwYWJsZSlcbiAgICB9XG5cbiAgICAvKiogVGVzdCB3aGV0aGVyIGEgcG9wcGFibGUgZXhpc3RzIGluIHRoZSBnaXZlbiBjb250ZXh0XG4gICAgICogXG4gICAgICogQHBhcmFtIHsqfSBjb250ZXh0IFxuICAgICAqL1xuICAgIHN0YXRpYyBoYXMoY29udGV4dCkge1xuICAgICAgICByZXR1cm4gUG9wcGFibGUucmVnaXN0cmF0aW9ucy5oYXMoY29udGV4dClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSBwb3BwYWJsZSBmcm9tIHRoZSBnaXZlbiBjb250ZXh0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7Kn0gY29udGV4dFxuICAgICAqIEBtZW1iZXJvZiBQb3BwYWJsZVxuICAgICAqL1xuICAgIHN0YXRpYyBkZWxldGUoY29udGV4dCkge1xuICAgICAgICBQb3BwYWJsZS5yZWdpc3RyYXRpb25zLmRlbGV0ZShjb250ZXh0KVxuICAgIH1cblxuICAgIC8qKiBBbGwgcG9wcGFibGUgbXVzdCBpbXBsZW1lbnQgYSBjbG9zZSBtZXRob2QuICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJNdXN0IGJlIGltcGxlbWVudGVkXCIpXG4gICAgfVxufVxuXG5Qb3BwYWJsZS5yZWdpc3RyYXRpb25zID0gbmV3IE1hcCgpIiwiaW1wb3J0IHsgRWxlbWVudHMgfSBmcm9tIFwiLi91dGlscy5qc1wiXG5pbXBvcnQgUG9wcGFibGUgZnJvbSBcIi4vcG9wcGFibGUuanNcIlxuXG4vKiogQSBQb3B1cCB0aGF0IHNob3dzIHRleHQgbGFiZWxzLCBpbWFnZXMsIG9yIGh0bWxcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9wdXAgZXh0ZW5kcyBQb3BwYWJsZSB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBQb3B1cC5cbiAgICAgKiBAcGFyYW0ge2FueX0gW3tcbiAgICAgKiAgICAgcGFyZW50ID0gbnVsbCwgICAgIC0gVGhlIERPTSBwYXJlbnQgZWxlbWVudC5cbiAgICAgKiAgICAgY29udGVudCA9IG51bGwsICAgIC0gQSBkaWN0IG9iamVjdCB3aXRoIHR5cGUgc3RyaW5ncyAodGV4dCwgaW1nLCBodG1sKSBhcyBrZXlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIGFuZCBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKiAgICAgY29udGV4dCA9IHdpbmRvdywgICAgLSBBIGNvbnRleHQgb2JqZWN0IGZvciBwb3BwYWJsZSBlbGVtZW50c1xuICAgICAqICAgICBmb250U2l6ZSA9IFwiMWVtXCIsICAtIERlc2NyaWJlcyB0aGUgZm9udCBzaXplIGFzIENTUyB2YWx1ZVxuICAgICAqICAgICBmb250RmFtaWx5ID0gXCJBcmlhbFwiLCAtIERlc2NyaWJlcyB0aGUgZm9udCBmYW1pbHkgYXMgQ1NTIHZhbHVlXG4gICAgICogICAgIHBhZGRpbmcgPSAxNiwgICAgICAtIHtudW1iZXIgfHwgc3RyaW5nfSBwYWRkaW5nIC0gRGVzY3JpYmVzIHRoZSBwYWRkaW5nIGFzIENTUyB2YWx1ZVxuICAgICAqICAgICBub3RjaFNpemUgPSAxMCwgICAgLSB7bnVtYmVyIHx8IHN0cmluZ30gbm90Y2hTaXplIC0gRGVzY3JpYmVzIHRoZSBzaXplIG9mIHRoZSBub3RjaCAoY2FsbG91dCkgYXMgQ1NTIHZhbHVlXG4gICAgICogICAgIHN3aXRjaFBvcyA9IGZhbHNlLFxuICAgICAqICAgICBtaW5XaWR0aCA9IG51bGwsXG4gICAgICogICAgIG1heFdpZHRoID0gODAwLFxuICAgICAqICAgICBiYWNrZ3JvdW5kQ29sb3IgPSBcIiNFRUVcIiwgIC0gVGhlIGNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kIGFzIENTUyB2YWx1ZVxuICAgICAqICAgICBub3JtYWxDb2xvciA9IFwiIzQ0NFwiLCAtIG5vcm1hbENvbG9yICAtIFRoZSBjb2xvciBvZiB0ZXh0aXRlbXMgYXMgQ1NTIHZhbHVlXG4gICAgICogICAgIG5vdGNoUG9zaXRpb24gPSBcImJvdHRvbUxlZnRcIixcbiAgICAgKiAgICAgekluZGV4ID0gMCxcbiAgICAgKiAgICAga2VlcFdpdGhpbiA9IG51bGwsIC0gRW5zdXJlIHRoYXQgcG9wdXAgaXMgdmlzaWJsZSB3aXRoaW4gdGhlIGJvdW5kcyBvZiB0aGUgZ2l2ZW4gY29udGFpbmVyXG4gICAgICogICAgIGF1dG9DbG9zZSA9IHRydWUsICAtIEF1dG9jbG9zZSB0aGUgUG9wdXAgb24gdGFwXG4gICAgICogICAgIGNsb3NlSWNvbiA9IG51bGwsXG4gICAgICogICAgIHJlc2l6ZUljb24gPSBudWxsLFxuICAgICAqICAgICBjbG9zZUNvbW1hbmQgPSBudWxsLFxuICAgICAqICAgICBkcmFnZ2FibGUgPSBmYWxzZVxuICAgICAqICAgICAgbm9TdHlsZSA9IGZhbHNlIC0gV2hlbiB0cnVlLCBwcmV2ZW50cyB0aGUgcG9wdXAgZnJvbSBkb2luZyBhbnkgYWVzdGhldGljIG1hbmlwdWxhdGlvbnMgdG8gdGhlIERPTSBsZWF2aW5nIHRoZSBzdHlsaW5nIGNvbXBsZXRlbHkgdG8gdGhlIHN0eWxlIHNoZWV0cy5cbiAgICAgKiB9PXt9XVxuICAgICAqIEBtZW1iZXJvZiBQb3B1cFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHtcbiAgICAgICAgcGFyZW50ID0gbnVsbCxcbiAgICAgICAgY29udGVudCA9IG51bGwsXG4gICAgICAgIGNvbnRleHQgPSB3aW5kb3csXG4gICAgICAgIGZvbnRTaXplID0gXCIxZW1cIixcbiAgICAgICAgZm9udEZhbWlseSA9IFwiQXJpYWxcIixcbiAgICAgICAgcGFkZGluZyA9IDE2LFxuICAgICAgICBub3RjaFNpemUgPSAxMCxcbiAgICAgICAgc3dpdGNoUG9zID0gZmFsc2UsXG4gICAgICAgIG1pbldpZHRoID0gbnVsbCxcbiAgICAgICAgbWF4V2lkdGggPSA4MDAsXG4gICAgICAgIGJhY2tncm91bmRDb2xvciA9IFwiI0VFRVwiLFxuICAgICAgICBub3JtYWxDb2xvciA9IFwiIzQ0NFwiLFxuICAgICAgICBub3RjaFBvc2l0aW9uID0gXCJib3R0b21DZW50ZXJcIixcbiAgICAgICAgekluZGV4ID0gMCxcbiAgICAgICAga2VlcFdpdGhpbiA9IG51bGwsXG4gICAgICAgIGF1dG9DbG9zZSA9IHRydWUsXG4gICAgICAgIGNsb3NlSWNvbiA9IG51bGwsXG4gICAgICAgIHJlc2l6ZUljb24gPSBudWxsLFxuICAgICAgICBjbG9zZUNvbW1hbmQgPSBudWxsLFxuICAgICAgICBkcmFnZ2FibGUgPSBmYWxzZSxcbiAgICAgICAgcG9zT2Zmc2V0ID0gMCxcbiAgICAgICAgdGFyZ2V0Qm91bmRpbmdCb3ggPSBudWxsLFxuICAgICAgICB1c2VFdmVudFBvc1dpdGhCb3VuZGluZ0JveCA9IGZhbHNlLFxuICAgICAgICBpbnRlcmFjdGl2ZSA9IGZhbHNlLFxuICAgICAgICBvblJlc2l6ZSA9IG51bGwsXG4gICAgICAgIG9uTW92ZSA9IG51bGwsXG4gICAgICAgIG5vU3R5bGUgPSBmYWxzZSxcbiAgICAgICAgaGlkZU9uVXAgPSB0cnVlLFxuICAgIH0gPSB7fSkge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICAgICAgdGhpcy5ub1N0eWxlID0gbm9TdHlsZVxuICAgICAgICB0aGlzLmhpZGVPblVwID0gaGlkZU9uVXBcbiAgICAgICAgdGhpcy5wYWRkaW5nID0gcGFkZGluZ1xuICAgICAgICB0aGlzLm5vdGNoUG9zaXRpb24gPSBub3RjaFBvc2l0aW9uXG4gICAgICAgIHRoaXMubm90Y2hTaXplID0gbm90Y2hTaXplXG4gICAgICAgIHRoaXMuc3dpdGNoUG9zID0gc3dpdGNoUG9zXG4gICAgICAgIHRoaXMuZm9udFNpemUgPSBmb250U2l6ZVxuICAgICAgICB0aGlzLmZvbnRGYW1pbHkgPSBmb250RmFtaWx5XG4gICAgICAgIHRoaXMubWluV2lkdGggPSBtaW5XaWR0aFxuICAgICAgICB0aGlzLm1heFdpZHRoID0gbWF4V2lkdGhcbiAgICAgICAgdGhpcy5ub3JtYWxDb2xvciA9IG5vcm1hbENvbG9yXG4gICAgICAgIHRoaXMuYmFja2dyb3VuZENvbG9yID0gYmFja2dyb3VuZENvbG9yXG4gICAgICAgIHRoaXMua2VlcFdpdGhpbiA9IGtlZXBXaXRoaW5cbiAgICAgICAgdGhpcy5hdXRvQ2xvc2UgPSBhdXRvQ2xvc2VcbiAgICAgICAgdGhpcy5yZXNpemVJY29uID0gcmVzaXplSWNvblxuICAgICAgICB0aGlzLmNsb3NlSWNvbiA9IGNsb3NlSWNvblxuICAgICAgICB0aGlzLmNsb3NlQ29tbWFuZCA9IGNsb3NlQ29tbWFuZFxuICAgICAgICB0aGlzLnpJbmRleCA9IHpJbmRleFxuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudCB8fCBkb2N1bWVudC5ib2R5XG4gICAgICAgIHRoaXMuZHJhZ2dhYmxlID0gZHJhZ2dhYmxlXG4gICAgICAgIHRoaXMucG9zT2Zmc2V0ID0gcG9zT2Zmc2V0XG4gICAgICAgIHRoaXMudGFyZ2V0Qm91bmRpbmdCb3ggPSB0YXJnZXRCb3VuZGluZ0JveFxuICAgICAgICB0aGlzLnVzZUV2ZW50UG9zV2l0aEJvdW5kaW5nQm94ID0gdXNlRXZlbnRQb3NXaXRoQm91bmRpbmdCb3hcbiAgICAgICAgdGhpcy5jdXJyZW50UG9zID0gbnVsbFxuICAgICAgICB0aGlzLmluc2VydGVkTm9kZSA9IG51bGxcbiAgICAgICAgdGhpcy5sb2FkZWQgPSBmYWxzZVxuICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gaW50ZXJhY3RpdmVcbiAgICAgICAgdGhpcy5vbmxvYWQgPSBudWxsXG4gICAgICAgIHRoaXMub25SZXNpemUgPSBvblJlc2l6ZVxuICAgICAgICB0aGlzLm9uTW92ZSA9IG9uTW92ZVxuICAgICAgICBpZiAoY29udGVudCkge1xuICAgICAgICAgICAgdGhpcy5zaG93KGNvbnRlbnQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogU2V0dXAgcG9wdXAgd2l0aCBhIGRpY3Rpb25hcnkgb2YgY29udGVudCB0eXBlcyBhbmQgY29udGVudHMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRlbnQgLSBBIGRpY3Qgb2JqZWN0IHdpdGggdHlwZSBzdHJpbmdzICh0ZXh0LCBpbWcsIGh0bWwpIGFzIGtleXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICogQHJldHVybiB7UG9wdXB9IHRoaXNcbiAgICAgKi9cbiAgICBzZXR1cChjb250ZW50KSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJQb3B1cC5zZXR1cFwiLCB0aGlzLmRyYWdnYWJsZSlcbiAgICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudFxuICAgICAgICB0aGlzLml0ZW1zID0ge31cbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKVxuICAgICAgICB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmFkZChcInBvcHVwXCIpXG4gICAgICAgIHRoaXMuc2V0QWxwaGEodGhpcy5lbGVtZW50LCAwKVxuICAgICAgICAvLyB0aGlzLmVsZW1lbnQuc3R5bGUub3BhY2l0eSA9IDBcbiAgICAgICAgRWxlbWVudHMuYWRkQ2xhc3ModGhpcy5lbGVtZW50LCBcInVuc2VsZWN0YWJsZVwiKVxuICAgICAgICB0aGlzLm5vdGNoID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKVxuICAgICAgICBFbGVtZW50cy5zZXRTdHlsZSh0aGlzLm5vdGNoLCB0aGlzLm5vdGNoU3R5bGUoKSlcbiAgICAgICAgdGhpcy5ub3RjaC5jbGFzc05hbWUgPSBcIm5vdGNoXCJcbiAgICAgICAgdGhpcy5zZXR1cERyYWdnYWJsZSgpXG4gICAgICAgIGlmICh0aGlzLmNsb3NlSWNvbikge1xuICAgICAgICAgICAgbGV0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIilcbiAgICAgICAgICAgIGltZy5zZXRBdHRyaWJ1dGUoXCJkcmFnZ2FibGVcIiwgZmFsc2UpXG4gICAgICAgICAgICBpbWcuc3JjID0gdGhpcy5jbG9zZUljb25cbiAgICAgICAgICAgIGltZy5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIlxuICAgICAgICAgICAgaW1nLnN0eWxlLnJpZ2h0ID0gXCIwcHhcIlxuICAgICAgICAgICAgaW1nLnN0eWxlLnRvcCA9IFwiMHB4XCJcbiAgICAgICAgICAgIGltZy5zdHlsZS53aWR0aCA9IFwiMTZweFwiXG4gICAgICAgICAgICBpbWcuc3R5bGUuaGVpZ2h0ID0gXCIxNnB4XCJcbiAgICAgICAgICAgIGltZy5vbmNsaWNrID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoaW1nKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJlc2l6ZUljb24pIHtcbiAgICAgICAgICAgIGxldCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpXG4gICAgICAgICAgICBpbWcuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCJcbiAgICAgICAgICAgIGltZy5zdHlsZS5yaWdodCA9IFwiMHB4XCJcbiAgICAgICAgICAgIGltZy5zdHlsZS5ib3R0b20gPSBcIjBweFwiXG4gICAgICAgICAgICBpbWcuc3R5bGUud2lkdGggPSBcIjE2cHhcIlxuICAgICAgICAgICAgaW1nLnN0eWxlLmhlaWdodCA9IFwiMTZweFwiXG4gICAgICAgICAgICBpbWcuc3JjID0gdGhpcy5yZXNpemVJY29uXG4gICAgICAgICAgICBpbWcuc2V0QXR0cmlidXRlKFwiZHJhZ2dhYmxlXCIsIHRydWUpXG4gICAgICAgICAgICBpbWcub25kcmFnc3RhcnQgPSBlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRQb3MgPSB7IHg6IGUuY2xpZW50WCwgeTogZS5jbGllbnRZIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW1nLm9uZHJhZyA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHRhcmdldCA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiaWZyYW1lXCIpIHx8IHRoaXMuZWxlbWVudFxuICAgICAgICAgICAgICAgIGxldCBkZWx0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogZS5jbGllbnRYIC0gdGhpcy5jdXJyZW50UG9zLngsXG4gICAgICAgICAgICAgICAgICAgIHk6IGUuY2xpZW50WSAtIHRoaXMuY3VycmVudFBvcy55XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50UG9zID0geyB4OiBlLmNsaWVudFgsIHk6IGUuY2xpZW50WSB9XG4gICAgICAgICAgICAgICAgaWYgKGRlbHRhLnggPT0gMCAmJiBkZWx0YS55ID09IDApXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuXG4gICAgICAgICAgICAgICAgbGV0IHJlY3QgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgICAgICAgICBsZXQgd2lkdGggPSByZWN0LndpZHRoICsgZGVsdGEueFxuICAgICAgICAgICAgICAgIGxldCBoZWlnaHQgPSByZWN0LmhlaWdodCArIGRlbHRhLnlcbiAgICAgICAgICAgICAgICB0YXJnZXQuc3R5bGUud2lkdGggPSB3aWR0aCArIFwicHhcIlxuICAgICAgICAgICAgICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyBcInB4XCJcblxuICAgICAgICAgICAgICAgIHN3aXRjaCAodGhpcy5ub3RjaFBvc2l0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJib3R0b21MZWZ0XCI6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJib3R0b21DZW50ZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBib3R0b20gPSBwYXJzZUZsb2F0KHRoaXMuZWxlbWVudC5zdHlsZS5ib3R0b20pXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYm90dG9tID0gYm90dG9tIC0gZGVsdGEueSArIFwicHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJvblJlc2l6ZVwiLCB0aGlzLm9uUmVzaXplKVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9uUmVzaXplKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25SZXNpemUoeyB0YXJnZXQsIGRlbHRhLCB3aWR0aCwgaGVpZ2h0IH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW1nLm9uZHJhZ2VuZCA9IGUgPT4geyB9XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoaW1nKVxuICAgICAgICB9XG5cblxuICAgICAgICBmb3IgKGxldCBrZXkgaW4gY29udGVudCkge1xuICAgICAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwic2VsZWN0b3JcIjpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICAgICAgICAgICAgICBsZXQgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0ZXh0KVxuICAgICAgICAgICAgICAgICAgICB0ZXh0LmlubmVySFRNTCA9IGNvbnRlbnRba2V5XVxuICAgICAgICAgICAgICAgICAgICBFbGVtZW50cy5zZXRTdHlsZSh0ZXh0LCB7IGNvbG9yOiB0aGlzLm5vcm1hbENvbG9yIH0pXG4gICAgICAgICAgICAgICAgICAgIEVsZW1lbnRzLmFkZENsYXNzKHRleHQsIFwidW5zZWxlY3RhYmxlXCIpXG4gICAgICAgICAgICAgICAgICAgIEVsZW1lbnRzLmFkZENsYXNzKHRleHQsIFwiUG9wdXBDb250ZW50XCIpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0ZWROb2RlID0gdGV4dFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIFwiaW1nXCI6XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFwiaW1nIHRvIGJlIGltcGxlbWVudGVkXCIpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSBcImlmcmFtZVwiOlxuICAgICAgICAgICAgICAgICAgICBsZXQgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlmcmFtZVwiKVxuICAgICAgICAgICAgICAgICAgICBpZnJhbWUuc2V0QXR0cmlidXRlKFwiZnJhbWVCb3JkZXJcIiwgMClcbiAgICAgICAgICAgICAgICAgICAgaWZyYW1lLnNyYyA9IGNvbnRlbnRba2V5XVxuICAgICAgICAgICAgICAgICAgICBpZnJhbWUub25sb2FkID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgYm9keSA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50LmJvZHlcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlmcmFtZUNoYW5nZWQoaWZyYW1lKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9ic2VydmUoaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnRyZWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlckRhdGE6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdyA9IE1hdGgubWF4KGJvZHkuc2Nyb2xsV2lkdGgsIGJvZHkub2Zmc2V0V2lkdGgpXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgaCA9IE1hdGgubWF4KGJvZHkuc2Nyb2xsSGVpZ2h0LCBib2R5Lm9mZnNldEhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmcmFtZS5zdHlsZS53aWR0aCA9IHcgKyBcInB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmcmFtZS5zdHlsZS5oZWlnaHQgPSBoICsgXCJweFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxheW91dEFmdGVySW5zZXJ0KClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9ubG9hZCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbmxvYWQoKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGlmcmFtZSlcbiAgICAgICAgICAgICAgICAgICAgRWxlbWVudHMuYWRkQ2xhc3MoaWZyYW1lLCBcIlBvcHVwQ29udGVudFwiKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydEludG9ET00oKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICBjYXNlIFwiaHRtbFwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCA9IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpXG4gICAgICAgICAgICAgICAgICAgIEVsZW1lbnRzLmFkZENsYXNzKGRpdiwgXCJQb3B1cENvbnRlbnRcIilcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGRpdilcbiAgICAgICAgICAgICAgICAgICAgZGl2LmlubmVySFRNTCA9IGNvbnRlbnQuaHRtbFxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiaW5zZXJ0XCIsIGNvbnRlbnQpXG4gICAgICAgICAgICAgICAgICAgIGxldCBzZWxlY3RvciA9IGNvbnRlbnQuc2VsZWN0b3JcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydGVkTm9kZSA9IGRpdi5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaW5zZXJ0ZWROb2RlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gYDxwIHN0eWxlPVwiY29sb3I6cmVkO1wiPlBvcHVwIGNvbnRlbnQgbm90IGZvdW5kLiBNaXNzaW5nICR7c2VsZWN0b3J9PC9wPmBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydGVkTm9kZSA9IGRpdi5maXJzdEVsZW1lbnRDaGlsZFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnNlcnRlZE5vZGUgPSBkaXYuZmlyc3RFbGVtZW50Q2hpbGQgfHwgZGl2XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRBbHBoYSh0aGlzLmluc2VydGVkTm9kZSwgMClcbiAgICAgICAgICAgICAgICAgICAgbGV0IGltYWdlcyA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbWcnKVxuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbWFnZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaW1hZ2Ugb2YgaW1hZ2VzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpbWFnZS5jb21wbGV0ZSAmJiAhaW1hZ2Uuc3JjLnN0YXJ0c1dpdGgoJ2RhdGE6JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcImltYWdlIG5vdCBjb21wbGV0ZVwiLCBpbWFnZS5zcmMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlLm9ubG9hZCA9IGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09IHRvdGFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25sb2FkICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbmxvYWQoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodG90YWwgPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIFwibm9kZVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgRWxlbWVudHMuYWRkQ2xhc3MoY29udGVudC5ub2RlLCBcIlBvcHVwQ29udGVudFwiKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGVudC5ub2RlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydGVkTm9kZSA9IGNvbnRlbnQubm9kZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFscGhhKHRoaXMuaW5zZXJ0ZWROb2RlLCAwKVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFwiVW5leHBlY3RlZCBjb250ZW50IHR5cGU6IFwiICsga2V5KVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5zZXJ0SW50b0RPTSgpXG4gICAgICAgIHRoaXMubGF5b3V0QWZ0ZXJJbnNlcnQoKVxuICAgICAgICB0aGlzLnNldHVwRXZlbnRIYW5kbGVyKClcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBoYW5kbGVDbG9zZShlKSB7XG4gICAgICAgIGxldCBjbG9zaW5nID0gdGhpcy5jbG9zaW5nRXZlbnQoZSlcbiAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXR1cENsb3NlSGFuZGxlcigpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXR1cENsb3NlSGFuZGxlcigpIHtcbiAgICAgICAgbGV0IGNsb3NlID0gdGhpcy5oYW5kbGVDbG9zZVxuICAgICAgICBpZiAodGhpcy5oaWRlT25VcCkge1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnQuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCBjbG9zZS5iaW5kKHRoaXMpLCB7IGNhcHR1cmU6IHRydWUsIG9uY2U6IHRydWUgfSlcbiAgICAgICAgICAgIGVsc2UgaWYgKHdpbmRvdy5Ub3VjaEV2ZW50KVxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBjbG9zZS5iaW5kKHRoaXMpLCB7IGNhcHR1cmU6IHRydWUsIG9uY2U6IHRydWUgfSlcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBjbG9zZS5iaW5kKHRoaXMpLCB7IGNhcHR1cmU6IHRydWUsIG9uY2U6IHRydWUgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh3aW5kb3cuUG9pbnRlckV2ZW50KVxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJwb2ludGVyZG93blwiLCBjbG9zZS5iaW5kKHRoaXMpLCB7IGNhcHR1cmU6IHRydWUsIG9uY2U6IHRydWUgfSlcbiAgICAgICAgICAgIGVsc2UgaWYgKHdpbmRvdy5Ub3VjaEV2ZW50KVxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIGNsb3NlLmJpbmQodGhpcyksIHsgY2FwdHVyZTogdHJ1ZSwgb25jZTogdHJ1ZSB9KVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgY2xvc2UuYmluZCh0aGlzKSwgeyBjYXB0dXJlOiB0cnVlLCBvbmNlOiB0cnVlIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXR1cEV2ZW50SGFuZGxlcigpIHtcbiAgICAgICAgaWYgKHRoaXMuYXV0b0Nsb3NlKSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwQ2xvc2VIYW5kbGVyKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsb3NpbmdFdmVudChlKSB7XG4gICAgICAgIGlmICh0aGlzLmludGVyYWN0aXZlKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGUudGFyZ2V0LmNsb3Nlc3QoXCIuUG9wdXBDb250ZW50XCIpXG4gICAgICAgICAgICByZXR1cm4gbm9kZSA9PSBudWxsXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZnJhbWVDaGFuZ2VkKGlmcmFtZSkge1xuICAgICAgICBsZXQgYm9keSA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50LmJvZHlcbiAgICAgICAgbGV0IHcgPSBNYXRoLm1heChib2R5LnNjcm9sbFdpZHRoLCBib2R5Lm9mZnNldFdpZHRoKVxuICAgICAgICBsZXQgaCA9IE1hdGgubWF4KGJvZHkuc2Nyb2xsSGVpZ2h0LCBib2R5Lm9mZnNldEhlaWdodClcbiAgICAgICAgaWZyYW1lLnN0eWxlLndpZHRoID0gdyArIFwicHhcIlxuICAgICAgICBpZnJhbWUuc3R5bGUuaGVpZ2h0ID0gaCArIFwicHhcIlxuICAgIH1cblxuICAgIHNldHVwRHJhZ2dhYmxlKCkge1xuICAgICAgICBpZiAodGhpcy5kcmFnZ2FibGUpIHtcbiAgICAgICAgICAgIGxldCB0YXJnZXQgPSB0aGlzLmVsZW1lbnRcbiAgICAgICAgICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJkcmFnZ2FibGVcIiwgdHJ1ZSlcbiAgICAgICAgICAgIHRhcmdldC5vbmRyYWdzdGFydCA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFBvcyA9IHsgeDogZS5jbGllbnRYLCB5OiBlLmNsaWVudFkgfVxuICAgICAgICAgICAgICAgIHZhciBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKVxuICAgICAgICAgICAgICAgIGltZy5zcmMgPSAnZGF0YTppbWFnZS9naWZiYXNlNjQsUjBsR09EbGhBUUFCQUlBQUFBQUFBUC8vL3lINUJBRUFBQUFBTEFBQUFBQUJBQUVBQUFJQlJBQTcnXG4gICAgICAgICAgICAgICAgZS5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlKGltZywgMCwgMClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRhcmdldC5vbmRyYWcgPSBlID0+IHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICBsZXQgZGVsdGEgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGUuY2xpZW50WCAtIHRoaXMuY3VycmVudFBvcy54LFxuICAgICAgICAgICAgICAgICAgICB5OiBlLmNsaWVudFkgLSB0aGlzLmN1cnJlbnRQb3MueVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRQb3MgPSB7IHg6IGUuY2xpZW50WCwgeTogZS5jbGllbnRZIH1cbiAgICAgICAgICAgICAgICBsZXQgbGVmdCA9IHBhcnNlRmxvYXQodGFyZ2V0LnN0eWxlLmxlZnQpXG4gICAgICAgICAgICAgICAgbGV0IHRvcCA9IHBhcnNlRmxvYXQodGFyZ2V0LnN0eWxlLnRvcClcblxuICAgICAgICAgICAgICAgIHRhcmdldC5zdHlsZS5sZWZ0ID0gbGVmdCArIGRlbHRhLnggKyAncHgnXG4gICAgICAgICAgICAgICAgdGFyZ2V0LnN0eWxlLnRvcCA9IHRvcCArIGRlbHRhLnkgKyAncHgnXG5cbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiUG9wdXAub25kcmFnXCIsIHRhcmdldCwgZXZlbnQudGFyZ2V0KVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9uTW92ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTW92ZSh7IHRhcmdldCwgZGVsdGEgfSlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmxhc3REcmFnID0geyBsZWZ0LCB0b3AgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGFyZ2V0Lm9uZHJhZ2VuZCA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIHRhcmdldC5zdHlsZS5sZWZ0ID0gdGhpcy5sYXN0RHJhZy5sZWZ0ICsgJ3B4J1xuICAgICAgICAgICAgICAgIHRhcmdldC5zdHlsZS50b3AgPSB0aGlzLmxhc3REcmFnLnRvcCArICdweCdcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRQb3MgPSBudWxsXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBtb3ZlRHJhZ2dlZCh0YXJnZXQpIHtcblxuICAgIH1cblxuICAgIGluc2VydEludG9ET00obGF5b3V0ID0gdHJ1ZSkge1xuICAgICAgICB0aGlzLnNldEFscGhhKHRoaXMuaW5zZXJ0ZWROb2RlLCAwKVxuICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5ub3RjaClcbiAgICAgICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KVxuICAgIH1cblxuICAgIGxheW91dEFmdGVySW5zZXJ0KCkge1xuICAgICAgICBFbGVtZW50cy5zZXRTdHlsZSh0aGlzLmVsZW1lbnQsIHRoaXMuZGVmYXVsdFN0eWxlKCkpXG4gICAgICAgIHRoaXMubGF5b3V0KClcbiAgICAgICAgLy90aGlzLmVsZW1lbnQuc3R5bGUub3BhY2l0eSA9IDFcbiAgICB9XG5cbiAgICAvKiogTGF5b3V0IHRoZSBtZW51IGl0ZW1zLiBOZWVkZWQgb25seSBpbiB0aGUgc3ViY2xhc3MuXG4gICAgICovXG4gICAgbGF5b3V0KCkgeyB9XG5cblxuICAgIHJlbW92ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50LmNvbnRhaW5zKHRoaXMuZWxlbWVudCkpXG4gICAgICAgICAgICB0aGlzLnBhcmVudC5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpXG4gICAgICAgIHRoaXMudW5yZWdpc3Rlcih0aGlzLmNvbnRleHQpXG4gICAgfVxuXG4gICAgLyoqIENsb3NlIGFuZCByZW1vdmUgdGhlIFBvcHVwIGZyb20gdGhlIERPTSB0cmVlLlxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICAvL2NvbnNvbGUubG9nKFwiUG9wdXAuY2xvc2VcIiwgdGhpcy5jbG9zZUNvbW1hbmQpXG4gICAgICAgIHRoaXMudW5yZWdpc3Rlcih0aGlzLmNvbnRleHQpXG4gICAgICAgIGlmICh0aGlzLmNsb3NlQ29tbWFuZCkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUNvbW1hbmQodGhpcywgKCkgPT4gdGhpcy5yZW1vdmUoKSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYWxwaGEgdmFsdWUgdG8gc2hvdyBvciBoaWRlIHRoZSBwb3B1cC4gVXNlcyBDU1MgdHJhbnNpdGlvbnMuXG4gICAgICogKEEgZm9ybWVyIGRlcGVuZGVuY3kgb24gVHdlZW5MaXRlIGhhcyBiZWVlbiByZW1vdmVkLilcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdGFyZ2V0c1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAbWVtYmVyb2YgUG9wdXBcbiAgICAgKi9cbiAgICBzZXRBbHBoYSh0YXJnZXRzLCB2YWx1ZSkge1xuICAgICAgICBsZXQgb2JqcyA9ICh0YXJnZXRzIGluc3RhbmNlb2YgQXJyYXkpID8gdGFyZ2V0cyA6IFt0YXJnZXRzXVxuICAgICAgICBmb3IgKGxldCBvYmogb2Ygb2Jqcykge1xuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgb2JqLnN0eWxlLnRyYW5zaXRpb24gPSBcIm9wYWNpdHkgMC4ycyBlYXNlLWluXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9iai5zdHlsZS5vcGFjaXR5ID0gdmFsdWVcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiAodmFsdWUpIHtcbiAgICAgICAgLy8gICAgIFR3ZWVuTGl0ZS50byh0YXJnZXRzLCAwLjIsICB7IGF1dG9BbHBoYTogdmFsdWUgfSlcbiAgICAgICAgLy8gfVxuICAgICAgICAvLyBlbHNlIHtcbiAgICAgICAgLy8gICAgIFR3ZWVuTGl0ZS5zZXQodGFyZ2V0cywgeyBhdXRvQWxwaGE6IDAgfSlcbiAgICAgICAgLy8gfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyBhIGZhZGUgaW4gYW5pbWF0aW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIFBvcHVwXG4gICAgICovXG4gICAgZmFkZUluKCkge1xuICAgICAgICB0aGlzLnNldEFscGhhKFt0aGlzLmVsZW1lbnQsIHRoaXMuaW5zZXJ0ZWROb2RlXSwgMSlcbiAgICB9XG5cbiAgICAvKiogU2hvd3MgdGhlIFBvcHVwIHdpdGggdGhlIGdpdmVuIGNvbW1hbmRzIGF0IHRoZSBzcGVjaWZpZWQgcG9pbnQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRlbnQgLSBBIGRpY3Qgb2JqZWN0IHdpdGggdHlwZSBzdHJpbmdzICh0ZXh0LCBpbWcsIGh0bWwpIGFzIGtleXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtQb2ludH0gcG9pbnQgLSBUaGUgcG9zaXRpb24gYXMgeCwgeSBjb29yZGluYXRlcyB7cHh9LlxuICAgICAqIEByZXR1cm4ge1BvcHVwfSB0aGlzXG4gICAgICovXG4gICAgc2hvd0F0KGNvbnRlbnQsIHBvaW50KSB7XG4gICAgICAgIHRoaXMuc2V0dXAoY29udGVudClcbiAgICAgICAgY29uc29sZS5sb2coXCJzaG93QXRcIiwgdGhpcy5sb2FkZWQpXG4gICAgICAgIGlmICh0aGlzLmxvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5wbGFjZUF0KHBvaW50KVxuICAgICAgICAgICAgdGhpcy5mYWRlSW4oKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRBbHBoYShbdGhpcy5lbGVtZW50LCB0aGlzLmluc2VydGVkTm9kZV0sIDApXG4gICAgICAgICAgICB0aGlzLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dEFmdGVySW5zZXJ0KClcbiAgICAgICAgICAgICAgICB0aGlzLnBsYWNlQXQocG9pbnQpXG4gICAgICAgICAgICAgICAgdGhpcy5mYWRlSW4oKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogIFBsYWNlIHRoZSBvcmlnaW4sIGkuZS4gdGhlIHVwcGVyIGxlZnQgY29ybmVyIGF0IHRoZSBnaXZlbiBwb3NpdGlvbiB1c2luZyBDU1Mgc3R5bGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHthbnl9IHhcbiAgICAgKiBAcGFyYW0ge2FueX0geVxuICAgICAqIEBtZW1iZXJvZiBQb3B1cFxuICAgICAqL1xuICAgIHBsYWNlT3JpZ2luKHgsIHkpIHtcbiAgICAgICAgRWxlbWVudHMuc2V0U3R5bGUodGhpcy5lbGVtZW50LCB7IGxlZnQ6IHggKyBcInB4XCIsIHRvcDogeSArIFwicHhcIiB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSB0aGUgbG9jYWwgY29vcmRpbmF0ZXMgd2l0aGluIHRoZSBrZWVwV2l0aGluIGNvbnRhaW5lci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7YW55fSB4XG4gICAgICogQHBhcmFtIHthbnl9IHlcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqIEBtZW1iZXJvZiBQb3B1cFxuICAgICAqL1xuICAgIGxvY2FsUG9pbnRXaXRoaW4oeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgICBsZXQgcHQgPSB7IHgsIHkgfVxuICAgICAgICByZXR1cm4gcHRcbiAgICB9XG5cbiAgICB3aXRoaW5EaW1lbnNpb25zKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2lkdGg6IHRoaXMua2VlcFdpdGhpbi5vZmZzZXRXaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5rZWVwV2l0aGluLm9mZnNldEhlaWdodFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9jYWxEaW1lbnNpb25zKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2lkdGg6IHRoaXMuZWxlbWVudC5vZmZzZXRXaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbm90Y2ggcG9zaXRpb24gZGVwZW5kaW5nIG9uIHRoZSBsb2NhbCBjb29yZGluYXRlcyB3aXRoaW4gdGhlIGtlZXBXaXRoaW4gY29udGFpbmVyXG4gICAgICogRGl2aWRlcyB0aGUgc3BhY2UgdmVydGljYWxseSBpbnRvIHRvcCwgY2VudGVyLCBib3R0b20gYW5kIGhvcml6b250YWxseSBpbnRvIGxlZnQsIGNlbnRlciwgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7YW55fSB4XG4gICAgICogQHBhcmFtIHthbnl9IHlcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqIEBtZW1iZXJvZiBQb3B1cFxuICAgICAqL1xuICAgIG5vdGNoUG9zaXRpb25XaXRoaW4oeCwgeSkge1xuICAgICAgICBsZXQgaG9yaXpvbnRhbCA9IFwiQ2VudGVyXCJcbiAgICAgICAgbGV0IHZlcnRpY2FsID0gXCJjZW50ZXJcIlxuICAgICAgICBsZXQgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLndpdGhpbkRpbWVuc2lvbnMoKVxuICAgICAgICBsZXQgbG9jYWwgPSB0aGlzLmxvY2FsUG9pbnRXaXRoaW4oeCwgeSwgd2lkdGgsIGhlaWdodClcbiAgICAgICAgaWYgKGxvY2FsLnkgPCBoZWlnaHQgKiAwLjMzKSB7XG4gICAgICAgICAgICB2ZXJ0aWNhbCA9IFwidG9wXCJcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWwueSA+IGhlaWdodCAqIDAuNjYpIHtcbiAgICAgICAgICAgIHZlcnRpY2FsID0gXCJib3R0b21cIlxuICAgICAgICB9XG4gICAgICAgIGlmIChsb2NhbC54IDwgd2lkdGggKiAwLjMzKSB7XG4gICAgICAgICAgICBob3Jpem9udGFsID0gXCJMZWZ0XCJcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWwueCA+IHdpZHRoICogMC42Nikge1xuICAgICAgICAgICAgaG9yaXpvbnRhbCA9IFwiUmlnaHRcIlxuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHQgPSB2ZXJ0aWNhbCArIGhvcml6b250YWxcbiAgICAgICAgaWYgKHJlc3VsdCA9PSBcImNlbnRlckNlbnRlclwiKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm90Y2hQb3NpdGlvblxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgcGxhY2VBdChwb2ludCkge1xuICAgICAgICBsZXQgeCA9IHBvaW50LnhcbiAgICAgICAgbGV0IHkgPSBwb2ludC55XG4gICAgICAgIGxldCBub3RjaFBvc2l0aW9uID0gdGhpcy5ub3RjaFBvc2l0aW9uXG4gICAgICAgIGlmICh0aGlzLmtlZXBXaXRoaW4gIT0gbnVsbCkge1xuICAgICAgICAgICAgbm90Y2hQb3NpdGlvbiA9IHRoaXMubm90Y2hQb3NpdGlvbldpdGhpbih4LCB5KVxuICAgICAgICB9XG4gICAgICAgIEVsZW1lbnRzLnNldFN0eWxlKHRoaXMubm90Y2gsIHRoaXMubm90Y2hTdHlsZShub3RjaFBvc2l0aW9uKSlcbiAgICAgICAgdGhpcy5ub3RjaC5jbGFzc05hbWUgPSBcIm5vdGNoIFwiICsgbm90Y2hQb3NpdGlvblxuICAgICAgICBsZXQgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLmxvY2FsRGltZW5zaW9ucygpXG5cbiAgICAgICAgLy9pZiB0YXJnZXRCb3VuZGluZ0JveCBpcyBzZXQsIHBvcHVwIGlzIHBsYWNlZCBuZXh0IHRvIHRoZSByZWN0YW5nbGVcbiAgICAgICAgaWYgKHRoaXMudGFyZ2V0Qm91bmRpbmdCb3gpIHtcbiAgICAgICAgICAgIGxldCBiYlRvcCA9IHRoaXMudGFyZ2V0Qm91bmRpbmdCb3gueVxuICAgICAgICAgICAgbGV0IGJiQm90dG9tID0gdGhpcy50YXJnZXRCb3VuZGluZ0JveC55ICsgdGhpcy50YXJnZXRCb3VuZGluZ0JveC5oZWlnaHRcbiAgICAgICAgICAgIGxldCBiYkxlZnQgPSB0aGlzLnRhcmdldEJvdW5kaW5nQm94LnhcbiAgICAgICAgICAgIGxldCBiYlJpZ2h0ID0gdGhpcy50YXJnZXRCb3VuZGluZ0JveC54ICsgdGhpcy50YXJnZXRCb3VuZGluZ0JveC53aWR0aFxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcInBsYWNlIHBvcHVwIHdpdGggYmIgc2V0OlwiLCB4LCB5LCBiYlRvcCwgYmJCb3R0b20sIGJiTGVmdCwgYmJSaWdodClcbiAgICAgICAgICAgIHN3aXRjaCAobm90Y2hQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJib3R0b21MZWZ0XCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcImJvdHRvbVJpZ2h0XCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcImJvdHRvbUNlbnRlclwiOlxuICAgICAgICAgICAgICAgICAgICB5ID0gYmJUb3BcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnVzZUV2ZW50UG9zV2l0aEJvdW5kaW5nQm94KVxuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IChiYkxlZnQgKyBiYlJpZ2h0KSAvIDJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIFwidG9wTGVmdFwiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJ0b3BSaWdodFwiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJ0b3BDZW50ZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgeSA9IGJiQm90dG9tXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy51c2VFdmVudFBvc1dpdGhCb3VuZGluZ0JveClcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAoYmJMZWZ0ICsgYmJSaWdodCkgLyAyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSBcImNlbnRlclJpZ2h0XCI6XG4gICAgICAgICAgICAgICAgICAgIHggPSBiYkxlZnRcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnVzZUV2ZW50UG9zV2l0aEJvdW5kaW5nQm94KVxuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IChiYlRvcCArIGJiQm90dG9tKSAvIDJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIFwiY2VudGVyTGVmdFwiOlxuICAgICAgICAgICAgICAgICAgICB4ID0gYmJSaWdodFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMudXNlRXZlbnRQb3NXaXRoQm91bmRpbmdCb3gpXG4gICAgICAgICAgICAgICAgICAgICAgICB5ID0gKGJiVG9wICsgYmJCb3R0b20pIC8gMlxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvL2NhbGN1bGF0ZSBwb3NpdGlvbiBkZXBlbmRpbmcgb24gc2V2ZXJhbCAob3B0aW9uYWwpIHBhcmFtZXRlcnNcbiAgICAgICAgc3dpdGNoIChub3RjaFBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIFwiYm90dG9tTGVmdFwiOlxuICAgICAgICAgICAgICAgIHggLT0gdGhpcy5wYWRkaW5nXG4gICAgICAgICAgICAgICAgeCAtPSB0aGlzLm5vdGNoU2l6ZVxuICAgICAgICAgICAgICAgIHkgLT0gaGVpZ2h0XG4gICAgICAgICAgICAgICAgeSAtPSB0aGlzLm5vdGNoU2l6ZSAqIDJcbiAgICAgICAgICAgICAgICB5IC09IHRoaXMucG9zT2Zmc2V0XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgXCJib3R0b21SaWdodFwiOlxuICAgICAgICAgICAgICAgIHggLT0gd2lkdGhcbiAgICAgICAgICAgICAgICB4ICs9IHRoaXMucGFkZGluZ1xuICAgICAgICAgICAgICAgIHggKz0gdGhpcy5ub3RjaFNpemVcbiAgICAgICAgICAgICAgICB5IC09IGhlaWdodFxuICAgICAgICAgICAgICAgIHkgLT0gdGhpcy5ub3RjaFNpemUgKiAyXG4gICAgICAgICAgICAgICAgeSAtPSB0aGlzLnBvc09mZnNldFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIFwiYm90dG9tQ2VudGVyXCI6XG4gICAgICAgICAgICAgICAgeCAtPSB3aWR0aCAvIDJcbiAgICAgICAgICAgICAgICB5IC09IGhlaWdodFxuICAgICAgICAgICAgICAgIHkgLT0gdGhpcy5ub3RjaFNpemUgKiAyXG4gICAgICAgICAgICAgICAgeSAtPSB0aGlzLnBvc09mZnNldFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIFwidG9wTGVmdFwiOlxuICAgICAgICAgICAgICAgIHggLT0gdGhpcy5wYWRkaW5nXG4gICAgICAgICAgICAgICAgeCAtPSB0aGlzLm5vdGNoU2l6ZVxuICAgICAgICAgICAgICAgIHkgKz0gdGhpcy5ub3RjaFNpemUgKiAyXG4gICAgICAgICAgICAgICAgeSArPSB0aGlzLnBvc09mZnNldFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIFwidG9wUmlnaHRcIjpcbiAgICAgICAgICAgICAgICB4IC09IHdpZHRoXG4gICAgICAgICAgICAgICAgeCArPSB0aGlzLnBhZGRpbmdcbiAgICAgICAgICAgICAgICB4ICs9IHRoaXMubm90Y2hTaXplXG4gICAgICAgICAgICAgICAgeSArPSB0aGlzLm5vdGNoU2l6ZSAqIDJcbiAgICAgICAgICAgICAgICB5ICs9IHRoaXMucG9zT2Zmc2V0XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgXCJ0b3BDZW50ZXJcIjpcbiAgICAgICAgICAgICAgICB4IC09IHdpZHRoIC8gMlxuICAgICAgICAgICAgICAgIHkgKz0gdGhpcy5ub3RjaFNpemUgKiAyXG4gICAgICAgICAgICAgICAgeSArPSB0aGlzLnBvc09mZnNldFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIFwiY2VudGVyUmlnaHRcIjpcbiAgICAgICAgICAgICAgICB4IC09IHdpZHRoICsgdGhpcy5ub3RjaFNpemUgKiAyXG4gICAgICAgICAgICAgICAgeCAtPSB0aGlzLnBvc09mZnNldFxuICAgICAgICAgICAgICAgIHkgLT0gaGVpZ2h0IC8gMlxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIFwiY2VudGVyTGVmdFwiOlxuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJoZWlnaHRcIiwgaGVpZ2h0KVxuICAgICAgICAgICAgICAgIHkgLT0gaGVpZ2h0IC8gMlxuICAgICAgICAgICAgICAgIHggKz0gdGhpcy5ub3RjaFNpemUgKiAyXG4gICAgICAgICAgICAgICAgeCArPSB0aGlzLnBvc09mZnNldFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wbGFjZU9yaWdpbih4LCB5KVxuICAgIH1cblxuICAgIC8qKiBTaG93cyB0aGUgUG9wdXAgd2l0aCB0aGUgZ2l2ZW4gY29tbWFuZHMgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRlbnQgLSBBIGRpY3Qgb2JqZWN0IHdpdGggdHlwZSBzdHJpbmdzICh0ZXh0LCBpbWcsIGh0bWwpIGFzIGtleXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICogQHJldHVybiB7UG9wdXB9IHRoaXNcbiAgICAgKi9cbiAgICBzaG93KGNvbnRlbnQpIHtcbiAgICAgICAgdGhpcy5zZXR1cChjb250ZW50KVxuICAgICAgICB0aGlzLmZhZGVJbigpXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqIENvbmZpZ3VyYXRpb24gb2JqZWN0LiBSZXR1cm4gZGVmYXVsdCBzdHlsZXMgYXMgQ1NTIHZhbHVlcy5cbiAgICAgKi9cbiAgICBkZWZhdWx0U3R5bGUoKSB7XG4gICAgICAgIGxldCBwYWRkaW5nID0gdGhpcy5wYWRkaW5nXG4gICAgICAgIGxldCBzdHlsZSA9IHtcbiAgICAgICAgICAgIG1heFdpZHRoOiB0aGlzLm1heFdpZHRoICsgXCJweFwiLFxuICAgICAgICAgICAgekluZGV4OiB0aGlzLnpJbmRleCxcbiAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubWluV2lkdGgpIHtcbiAgICAgICAgICAgIHN0eWxlLm1pbldpZHRoID0gdGhpcy5taW5XaWR0aCArIFwicHhcIlxuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5ub1N0eWxlKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHN0eWxlLCB7XG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiBNYXRoLnJvdW5kKHRoaXMucGFkZGluZyAvIDIpICsgXCJweFwiLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgICAgICAgcGFkZGluZzogdGhpcy5wYWRkaW5nICsgXCJweFwiLFxuICAgICAgICAgICAgICAgIGJveFNoYWRvdzogXCIwIDEwcHggMTVweCByZ2JhKDAsIDAsIDAsIDAuMylcIixcbiAgICAgICAgICAgICAgICBmb250RmFtaWx5OiB0aGlzLmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgZm9udFNpemU6IHRoaXMuZm9udFNpemUsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBcImJsYWNrXCIsXG4gICAgICAgICAgICAgICAgZmlsbDogXCJ3aGl0ZVwiXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHN0eWxlXG4gICAgfVxuXG4gICAgLyoqIENvbmZpZ3VyYXRpb24gb2JqZWN0LiBSZXR1cm4gbm90Y2ggc3R5bGVzIGFzIENTUyB2YWx1ZXMuXG4gICAgICovXG4gICAgbm90Y2hTdHlsZShub3RjaFBvc2l0aW9uID0gbnVsbCkge1xuICAgICAgICBpZiAobm90Y2hQb3NpdGlvbiA9PSBudWxsKSB7XG4gICAgICAgICAgICBub3RjaFBvc2l0aW9uID0gdGhpcy5ub3RjaFBvc2l0aW9uXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHdpZHRoID0gMFxuICAgICAgICBsZXQgaGVpZ2h0ID0gMFxuICAgICAgICBsZXQgbGVmdCA9IHRoaXMucGFkZGluZ1xuICAgICAgICBsZXQgc2l6ZSA9IHRoaXMubG9jYWxEaW1lbnNpb25zKClcbiAgICAgICAgaWYgKG5vdGNoUG9zaXRpb24uZW5kc1dpdGgoXCJSaWdodFwiKSkge1xuICAgICAgICAgICAgbGVmdCA9IHNpemUud2lkdGggLSB0aGlzLnBhZGRpbmcgLSB0aGlzLm5vdGNoU2l6ZSAqIDJcbiAgICAgICAgfVxuICAgICAgICBpZiAobm90Y2hQb3NpdGlvbi5lbmRzV2l0aChcIkNlbnRlclwiKSkge1xuICAgICAgICAgICAgbGVmdCA9IHNpemUud2lkdGggLyAyIC0gdGhpcy5ub3RjaFNpemVcbiAgICAgICAgfVxuICAgICAgICBsZWZ0ID0gTWF0aC5yb3VuZChsZWZ0KSArICdweCdcbiAgICAgICAgbGV0IGJvcmRlckJvdHRvbSA9IDBcbiAgICAgICAgbGV0IGJvcmRlclRvcCA9IDBcblxuICAgICAgICBpZiAobm90Y2hQb3NpdGlvbi5zdGFydHNXaXRoKFwiYm90dG9tXCIpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5ub1N0eWxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgbGVmdCxcbiAgICAgICAgICAgICAgICAgICAgYm90dG9tOiAtdGhpcy5ub3RjaFNpemUgKyBcInB4XCIsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlclN0eWxlOiBcInNvbGlkXCIsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlclRvcFdpZHRoOiB0aGlzLm5vdGNoU2l6ZSArIFwicHhcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyUmlnaHQ6IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiLFxuICAgICAgICAgICAgICAgICAgICBib3JkZXJMZWZ0OiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgdHJhbnNwYXJlbnRcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyQm90dG9tOiAwXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgICAgICAgICAgIGJveFNoYWRvdzogXCIwIDEycHggMTVweCByZ2JhKDAsIDAsIDAsIDAuMSlcIixcbiAgICAgICAgICAgICAgICAgICAgYm90dG9tOiAtdGhpcy5ub3RjaFNpemUgKyBcInB4XCIsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlclRvcDogdGhpcy5ub3RjaFNpemUgKyBcInB4IHNvbGlkIFwiICsgdGhpcy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlclJpZ2h0OiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgdHJhbnNwYXJlbnRcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyTGVmdDogdGhpcy5ub3RjaFNpemUgKyBcInB4IHNvbGlkIHRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlckJvdHRvbTogMFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobm90Y2hQb3NpdGlvbi5zdGFydHNXaXRoKFwidG9wXCIpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5ub1N0eWxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgbGVmdCxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAtdGhpcy5ub3RjaFNpemUgKyBcInB4XCIsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlclN0eWxlOiBcInNvbGlkXCIsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlckJvdHRvbVdpZHRoOiB0aGlzLm5vdGNoU2l6ZSArIFwicHhcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyUmlnaHQ6IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiLFxuICAgICAgICAgICAgICAgICAgICBib3JkZXJMZWZ0OiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgdHJhbnNwYXJlbnRcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyVG9wOiAwXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICBsZWZ0LFxuICAgICAgICAgICAgICAgICAgICB0b3A6IC10aGlzLm5vdGNoU2l6ZSArIFwicHhcIixcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyQm90dG9tOiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgXCIgKyB0aGlzLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyUmlnaHQ6IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiLFxuICAgICAgICAgICAgICAgICAgICBib3JkZXJMZWZ0OiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgdHJhbnNwYXJlbnRcIixcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyVG9wOiAwXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubm9TdHlsZSkge1xuXG4gICAgICAgICAgICBpZiAobm90Y2hQb3NpdGlvbi5lbmRzV2l0aChcIkxlZnRcIikpIHtcbiAgICAgICAgICAgICAgICBsZWZ0ID0gLXRoaXMubm90Y2hTaXplICogMiArIFwicHhcIlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobm90Y2hQb3NpdGlvbi5lbmRzV2l0aChcIlJpZ2h0XCIpKSB7XG4gICAgICAgICAgICAgICAgbGVmdCA9IHNpemUud2lkdGggKyBcInB4XCJcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICBsZXQgdG9wID0gc2l6ZS5oZWlnaHQgLyAyIC0gdGhpcy5ub3RjaFNpemVcbiAgICAgICAgICAgIHRvcCA9IE1hdGgucm91bmQodG9wKSArICdweCdcblxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICAgICAgICBsZWZ0LFxuICAgICAgICAgICAgICAgIHRvcCxcbiAgICAgICAgICAgICAgICBib3JkZXJSaWdodFdpZHRoOiB0aGlzLm5vdGNoU2l6ZSxcbiAgICAgICAgICAgICAgICBib3JkZXJMZWZ0V2lkdGg6IHRoaXMubm90Y2hTaXplLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgICAgICAgICAgYm9yZGVyVG9wOiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgdHJhbnNwYXJlbnRcIixcbiAgICAgICAgICAgICAgICBib3JkZXJCb3R0b206IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBib3JkZXJSaWdodCA9IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiXG4gICAgICAgICAgICBsZXQgYm9yZGVyTGVmdCA9IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiXG4gICAgICAgICAgICBsZXQgdG9wID0gc2l6ZS5oZWlnaHQgLyAyIC0gdGhpcy5ub3RjaFNpemVcbiAgICAgICAgICAgIGlmIChub3RjaFBvc2l0aW9uLmVuZHNXaXRoKFwiTGVmdFwiKSkge1xuICAgICAgICAgICAgICAgIGxlZnQgPSAtdGhpcy5ub3RjaFNpemUgKiAyICsgXCJweFwiXG4gICAgICAgICAgICAgICAgYm9yZGVyUmlnaHQgPSB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgXCIgKyB0aGlzLmJhY2tncm91bmRDb2xvclxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5ib3hTaGFkb3cgPSBcIjE1cHggMTBweCAxNXB4ICByZ2JhKDAsIDAsIDAsIDAuMylcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vdGNoUG9zaXRpb24uZW5kc1dpdGgoXCJSaWdodFwiKSkge1xuICAgICAgICAgICAgICAgIGxlZnQgPSBzaXplLndpZHRoICsgXCJweFwiXG4gICAgICAgICAgICAgICAgYm9yZGVyTGVmdCA9IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCBcIiArIHRoaXMuYmFja2dyb3VuZENvbG9yXG4gICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmJveFNoYWRvdyA9IFwiMTVweCA1cHggMTVweCByZ2JhKDAsIDAsIDAsIDAuMylcIlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0b3AgPSBNYXRoLnJvdW5kKHRvcCkgKyAncHgnXG5cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgICAgICAgbGVmdCxcbiAgICAgICAgICAgICAgICB0b3AsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmlnaHQsXG4gICAgICAgICAgICAgICAgYm9yZGVyTGVmdCxcbiAgICAgICAgICAgICAgICAvLyAgYm94U2hhZG93LFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgICAgICAgICAgYm9yZGVyVG9wOiB0aGlzLm5vdGNoU2l6ZSArIFwicHggc29saWQgdHJhbnNwYXJlbnRcIixcbiAgICAgICAgICAgICAgICBib3JkZXJCb3R0b206IHRoaXMubm90Y2hTaXplICsgXCJweCBzb2xpZCB0cmFuc3BhcmVudFwiXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQ29udmVuaWVudCBzdGF0aWMgbWV0aG9kcyB0byBzaG93IGFuZCByZXVzZSBhIFBvcHVwIGltcGxlbWVudGVkXG4gICAgICogYXMgYSBjbGFzcyB2YXJpYWJsZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGVudCAtIEEgZGljdCBvYmplY3Qgd2l0aCB0eXBlIHN0cmluZ3MgKHRleHQsIGltZywgaHRtbCkgYXMga2V5c1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwb2ludCAtIFRoZSBwb3NpdGlvbiBhcyB4LCB5IGNvb3JkaW5hdGVzIHtweH0uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhdXRvQ2xvc2UgLSBBdXRvY2xvc2UgdGhlIG1lbnUgYWZ0ZXIgc2VsZWN0aW5nIGFuIGl0ZW0uXG4gICAgICovXG4gICAgc3RhdGljIG9wZW4oXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIHBvaW50LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXJlbnQgPSBudWxsLFxuICAgICAgICAgICAgY29udGV4dCA9IHdpbmRvdyxcbiAgICAgICAgICAgIGZvbnRTaXplID0gXCIxZW1cIixcbiAgICAgICAgICAgIGZvbnRGYW1pbHkgPSBcIkFyaWFsXCIsXG4gICAgICAgICAgICBwYWRkaW5nID0gMTYsXG4gICAgICAgICAgICBub3RjaFNpemUgPSAxMCxcbiAgICAgICAgICAgIHN3aXRjaFBvcyA9IGZhbHNlLFxuICAgICAgICAgICAgbWluV2lkdGggPSBudWxsLFxuICAgICAgICAgICAgbWF4V2lkdGggPSA4MDAsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3IgPSBcIiNFRUVcIixcbiAgICAgICAgICAgIHpJbmRleCA9IDAsXG4gICAgICAgICAgICBub3JtYWxDb2xvciA9IFwiIzQ0NFwiLFxuICAgICAgICAgICAgY2xvc2VJY29uID0gbnVsbCxcbiAgICAgICAgICAgIHJlc2l6ZUljb24gPSBudWxsLFxuICAgICAgICAgICAgY2xvc2VDb21tYW5kID0gbnVsbCxcbiAgICAgICAgICAgIGF1dG9DbG9zZSA9IHRydWUsXG4gICAgICAgICAgICBrZWVwV2l0aGluID0gbnVsbCxcbiAgICAgICAgICAgIGRyYWdnYWJsZSA9IGZhbHNlLFxuICAgICAgICAgICAgcG9zT2Zmc2V0ID0gMCxcbiAgICAgICAgICAgIHRhcmdldEJvdW5kaW5nQm94ID0gbnVsbCxcbiAgICAgICAgICAgIHVzZUV2ZW50UG9zV2l0aEJvdW5kaW5nQm94ID0gZmFsc2UsXG4gICAgICAgICAgICBpbnRlcmFjdGl2ZSA9IGZhbHNlLFxuICAgICAgICAgICAgb25SZXNpemUgPSBudWxsLFxuICAgICAgICAgICAgb25Nb3ZlID0gbnVsbFxuICAgICAgICB9ID0ge31cbiAgICApIHtcblxuXG4gICAgICAgIGxldCBub3RjaFBvc2l0aW9uID0gKHN3aXRjaFBvcyAmJiBwb2ludC55IDwgNTApID8gXCJ0b3BDZW50ZXJcIiA6IFwiYm90dG9tQ2VudGVyXCJcbiAgICAgICAgbGV0IHBvcHVwID0gbmV3IFBvcHVwKHtcbiAgICAgICAgICAgIHBhcmVudCxcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBmb250RmFtaWx5LFxuICAgICAgICAgICAgZm9udFNpemUsXG4gICAgICAgICAgICBwYWRkaW5nLFxuICAgICAgICAgICAgbm90Y2hTaXplLFxuICAgICAgICAgICAgc3dpdGNoUG9zLFxuICAgICAgICAgICAgbWluV2lkdGgsXG4gICAgICAgICAgICBtYXhXaWR0aCxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIG5vcm1hbENvbG9yLFxuICAgICAgICAgICAgbm90Y2hQb3NpdGlvbixcbiAgICAgICAgICAgIHpJbmRleCxcbiAgICAgICAgICAgIGF1dG9DbG9zZSxcbiAgICAgICAgICAgIGtlZXBXaXRoaW4sXG4gICAgICAgICAgICBjbG9zZUNvbW1hbmQsXG4gICAgICAgICAgICBjbG9zZUljb24sXG4gICAgICAgICAgICByZXNpemVJY29uLFxuICAgICAgICAgICAgZHJhZ2dhYmxlLFxuICAgICAgICAgICAgcG9zT2Zmc2V0LFxuICAgICAgICAgICAgdGFyZ2V0Qm91bmRpbmdCb3gsXG4gICAgICAgICAgICB1c2VFdmVudFBvc1dpdGhCb3VuZGluZ0JveCxcbiAgICAgICAgICAgIGludGVyYWN0aXZlLFxuICAgICAgICAgICAgb25SZXNpemUsXG4gICAgICAgICAgICBvbk1vdmVcbiAgICAgICAgfSlcbiAgICAgICAgcG9wdXAucmVnaXN0ZXIoY29udGV4dClcbiAgICAgICAgcG9wdXAuc2hvd0F0KGNvbnRlbnQsIHBvaW50KVxuICAgICAgICByZXR1cm4gcG9wdXBcbiAgICB9XG5cbiAgICAvKiogQ29udmVuaWVudCBzdGF0aWMgbWV0aG9kIHRvIGNsb3NlIHRoZSBQb3B1cCBpbXBsZW1lbnRlZFxuICAgICAqIGFzIGEgY2xhc3MgdmFyaWFibGUuIENhbGxzIHRoZSBjbG9zZSBjb21tYW5kLlxuICAgICAqL1xuICAgIHN0YXRpYyBjbG9zZVBvcHVwKGNvbnRleHQgPSB3aW5kb3cpIHtcbiAgICAgICAgbGV0IHBvcHVwID0gUG9wcGFibGUucmVnaXN0cmF0aW9ucy5nZXQoY29udGV4dClcbiAgICAgICAgaWYgKHBvcHVwICE9IG51bGwpIHtcbiAgICAgICAgICAgIHBvcHVwLmNsb3NlKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBDb252ZW5pZW50IHN0YXRpYyBtZXRob2RzIHRvIHJlbW92ZSB0aGUgUG9wdXAgaW1wbGVtZW50ZWRcbiAgICAgKiBhcyBhIGNsYXNzIHZhcmlhYmxlLiBSZW1vdmVzIHRoZSBwb3B1cCB3aXRob3V0IHBlcmZvcm1pbmcgdGhlIGNsb3NlIGNvbW1hbmQuXG4gICAgICovXG4gICAgc3RhdGljIHJlbW92ZShjb250ZXh0ID0gd2luZG93KSB7XG4gICAgICAgIGxldCBwb3B1cCA9IFBvcHBhYmxlLnJlZ2lzdHJhdGlvbnMuZ2V0KGNvbnRleHQpXG4gICAgICAgIGlmIChwb3B1cCAhPSBudWxsKSB7XG4gICAgICAgICAgICBwb3B1cC5yZW1vdmUoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVuaWVudCBzdGF0aWMgbWV0aG9kIHRvIGNvbXB1dGUgdGhlIGNsaWNrZWQgcmVjdCBvZiBvYmplY3RzIHRoYXQgaGF2ZSBtdWx0aXBsZSBjbGllbnRzIHJlY3RzLlxuICAgICAqIE5lZWRlZCB0byBwb3NpdGlvbiBwb3B1cHMgY29ycmVjdGx5IGFib3ZlIG9iamVjdHMgd2l0aCBsaW5lIGJyZWFrcywgZS5nLiBzcGFuc1xuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7Kn0gZXZlbnRcbiAgICAgKiBAcmV0dXJucyB7Kn0gRE9NUmVjdFxuICAgICAqIEBtZW1iZXJvZiBQb3B1cFxuICAgICAqL1xuICAgIHN0YXRpYyB0YXJnZXRSZWN0KGV2ZW50KSB7XG4gICAgICAgIGxldCB0YXJnZXQgPSBldmVudC50YXJnZXRcbiAgICAgICAgbGV0IHggPSBldmVudC5wYWdlWFxuICAgICAgICBsZXQgeSA9IGV2ZW50LnBhZ2VZXG4gICAgICAgIGZvciAobGV0IHJlY3Qgb2YgdGFyZ2V0LmdldENsaWVudFJlY3RzKCkpIHtcbiAgICAgICAgICAgIGxldCB3aXRoaW5YID0geCA+PSByZWN0LmxlZnQgJiYgeCA8PSByZWN0LmxlZnQgKyByZWN0LndpZHRoXG4gICAgICAgICAgICBsZXQgd2l0aGluWSA9IHkgPj0gcmVjdC50b3AgJiYgeSA8PSByZWN0LnRvcCArIHJlY3QuaGVpZ2h0XG4gICAgICAgICAgICBpZiAod2l0aGluWCAmJiB3aXRoaW5ZKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlY3RcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlbmllbnQgc3RhdGljIG1ldGhvZCB0byBjb21wdXRlIHRoZSBjZW50ZXIgb2Ygb2JqZWN0cyB0aGF0IGhhdmUgbXVsdGlwbGUgY2xpZW50cyByZWN0cy5cbiAgICAgKiBOZWVkZWQgdG8gcG9zaXRpb24gcG9wdXBzIGNvcnJlY3RseSBhYm92ZSBvYmplY3RzIHdpdGggbGluZSBicmVha3MsIGUuZy4gc3BhbnNcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyp9IGV2ZW50XG4gICAgICogQHJldHVybnMgeyp9IFBvaW50XG4gICAgICogQG1lbWJlcm9mIFBvcHVwXG4gICAgICovXG4gICAgc3RhdGljIHRhcmdldENlbnRlcihldmVudCkge1xuICAgICAgICBsZXQgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0XG4gICAgICAgIGxldCB4ID0gZXZlbnQucGFnZVhcbiAgICAgICAgbGV0IHkgPSBldmVudC5wYWdlWVxuICAgICAgICBsZXQgcmVjdCA9IFBvcHVwLnRhcmdldFJlY3QoZXZlbnQpXG4gICAgICAgIGlmIChyZWN0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHggPSByZWN0LmxlZnQgKyByZWN0LndpZHRoIC8gMlxuICAgICAgICAgICAgeSA9IHJlY3QudG9wICsgcmVjdC5oZWlnaHQgLyAyXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgeCwgeSB9XG4gICAgfVxufVxuIiwiaW1wb3J0IFBvcHBhYmxlIGZyb20gJy4vcG9wcGFibGUuanMnXG5pbXBvcnQgUG9wdXAgZnJvbSAnLi9wb3B1cC5qcydcbmltcG9ydCB7IEVsZW1lbnRzIH0gZnJvbSAnLi91dGlscy5qcydcblxuLyoqIEEgUG9wdXAgTWVudSB0aGF0IHNob3dzIHRleHQgbGFiZWxzIGluIGEgdmVydGljYWwgcm93LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQb3B1cE1lbnUgZXh0ZW5kcyBQb3B1cCB7XG4gICAgLyoqXG4gICAgKiBUaGUgY29uc3RydWN0b3IuXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7RE9NIEVsZW1lbnR9IHBhcmVudCAtIFRoZSBET00gcGFyZW50IGVsZW1lbnQuXG4gICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZHMgLSBBIGRpY3Qgb2JqZWN0IHdpdGggY29tbWFuZCBsYWJlbCBzdHJpbmdzIGFzIGtleXNcbiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCBjb21tYW5kIGZ1bmN0aW9ucyBhcyB2YWx1ZXMuXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gZm9udFNpemUgLSBEZXNjcmliZXMgdGhlIGZvbnQgc2l6ZSBhcyBDU1MgdmFsdWVcbiAgICAqIEBwYXJhbSB7bnVtYmVyIHx8IHN0cmluZ30gcGFkZGluZyAtIERlc2NyaWJlcyB0aGUgcGFkZGluZyBhcyBDU1MgdmFsdWVcbiAgICAqIEBwYXJhbSB7bnVtYmVyIHx8IHN0cmluZ30gbm90Y2hTaXplIC0gRGVzY3JpYmVzIHRoZSBzaXplIG9mIHRoZSBub3RjaCAoY2FsbG91dCkgYXMgQ1NTIHZhbHVlXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gaGlnaGxpZ2h0Q29sb3IgIC0gVGhlIGNvbG9yIG9mIGhpZ2hsaWdodGVkIG1lbnUgaXRlbXMgYXMgQ1NTIHZhbHVlXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gYmFja2dyb3VuZENvbG9yICAtIFRoZSBjb2xvciBvZiB0aGUgYmFja2dyb3VuZCBhcyBDU1MgdmFsdWVcbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBub3JtYWxDb2xvciAgLSBUaGUgY29sb3Igb2Ygbm9ybWFsIG1lbnUgaXRlbXMgYXMgQ1NTIHZhbHVlXG4gICAgKiBAcGFyYW0ge0RPTSBFbGVtZW50fSBrZWVwV2l0aGluICAtIFRoZSBjb250YWluZXIgdG8gc3RheSB3aXRoaW5cbiAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXV0b0Nsb3NlICAtIEF1dG9jbG9zZSB0aGUgbWVudSBhZnRlciBzZWxlY3RpbmcgYW4gaXRlbVxuICAgICovXG4gICAgY29uc3RydWN0b3IoeyBwYXJlbnQgPSBudWxsLFxuICAgICAgICBjb21tYW5kcyA9IG51bGwsXG4gICAgICAgIGZvbnRTaXplID0gJzFlbScsXG4gICAgICAgIGZvbnRGYW1pbHkgPSAnQXJpYWwnLFxuICAgICAgICBwYWRkaW5nID0gMTYsXG4gICAgICAgIHpJbmRleCA9IDEsXG4gICAgICAgIHNwYWNpbmcgPSAnMHB4JyxcbiAgICAgICAgc3dpdGNoUG9zID0gZmFsc2UsXG4gICAgICAgIG5vdGNoU2l6ZSA9IDEwLFxuICAgICAgICBtYXhXaWR0aCA9IDgwMCxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yID0gJyNFRUUnLFxuICAgICAgICBub3JtYWxDb2xvciA9ICcjNDQ0JyxcbiAgICAgICAgaGlnaGxpZ2h0Q29sb3IgPSAnYmxhY2snLFxuICAgICAgICBub3RjaFBvc2l0aW9uID0gJ2JvdHRvbUxlZnQnLFxuICAgICAgICBrZWVwV2l0aGluID0gbnVsbCxcbiAgICAgICAgYXV0b0Nsb3NlID0gdHJ1ZSB9ID0ge30pIHtcbiAgICAgICAgc3VwZXIoeyBwYXJlbnQsIGZvbnRTaXplLCBmb250RmFtaWx5LCBwYWRkaW5nLCBub3RjaFNpemUsIG5vdGNoUG9zaXRpb24sIGJhY2tncm91bmRDb2xvciwga2VlcFdpdGhpbiwgbm9ybWFsQ29sb3IsIGF1dG9DbG9zZSB9KVxuICAgICAgICB0aGlzLmNvbW1hbmRzID0gY29tbWFuZHNcbiAgICAgICAgdGhpcy56SW5kZXggPSB6SW5kZXhcbiAgICAgICAgdGhpcy5zd2l0Y2hQb3MgPSBzd2l0Y2hQb3NcbiAgICAgICAgdGhpcy5zcGFjaW5nID0gc3BhY2luZ1xuICAgICAgICB0aGlzLmhpZ2hsaWdodENvbG9yID0gaGlnaGxpZ2h0Q29sb3JcbiAgICB9XG5cbiAgICAvKiogU2V0dXAgbWVudSB3aXRoIGEgZGljdGlvbmFyeSBvZiBjb21tYW5kIGxhYmVscyBhbmQgY29tbWFuZCBmdW5jdGlvbnMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmRzIC0gQSBkaWN0IG9iamVjdCB3aXRoIGNvbW1hbmQgbGFiZWwgc3RyaW5ncyBhcyBrZXlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGNvbW1hbmQgZnVuY3Rpb25zIGFzIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJuIHtQb3B1cE1lbnV9IHRoaXNcbiAgICAgKi9cbiAgICBzZXR1cChjb21tYW5kcykge1xuXG4gICAgICAgIHRoaXMuY29tbWFuZHMgPSBjb21tYW5kc1xuICAgICAgICB0aGlzLml0ZW1zID0ge31cbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnpJbmRleCA9IHRoaXMuekluZGV4XG4gICAgICAgIEVsZW1lbnRzLmFkZENsYXNzKHRoaXMuZWxlbWVudCwgJ3Vuc2VsZWN0YWJsZScpXG4gICAgICAgIHRoaXMubm90Y2ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAgICBFbGVtZW50cy5zZXRTdHlsZSh0aGlzLm5vdGNoLCB0aGlzLm5vdGNoU3R5bGUoKSlcbiAgICAgICAgZm9yIChsZXQga2V5IGluIGNvbW1hbmRzKSB7XG4gICAgICAgICAgICBsZXQgaXRlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoaXRlbSlcbiAgICAgICAgICAgIGl0ZW0uaW5uZXJIVE1MID0ga2V5XG4gICAgICAgICAgICBpdGVtLnN0eWxlLnBhZGRpbmdCb3R0b20gPSBpdGVtLnN0eWxlLnBhZGRpbmdUb3AgPSB0aGlzLnNwYWNpbmdcbiAgICAgICAgICAgIEVsZW1lbnRzLnNldFN0eWxlKGl0ZW0sIHsgY29sb3I6IHRoaXMubm9ybWFsQ29sb3IsIGN1cnNvcjogJ2RlZmF1bHQnIH0pXG4gICAgICAgICAgICBFbGVtZW50cy5hZGRDbGFzcyhpdGVtLCAndW5zZWxlY3RhYmxlJylcbiAgICAgICAgICAgIEVsZW1lbnRzLmFkZENsYXNzKGl0ZW0sICdwb3B1cE1lbnVJdGVtJylcbiAgICAgICAgICAgIHRoaXMuaXRlbXNba2V5XSA9IGl0ZW1cbiAgICAgICAgICAgIGl0ZW0ub25jbGljayA9IChldmVudCkgPT4geyB0aGlzLnBlcmZvcm0oa2V5KSB9XG4gICAgICAgICAgICBpdGVtLm9udGFwID0gKGV2ZW50KSA9PiB7IHRoaXMucGVyZm9ybShrZXkpIH1cbiAgICAgICAgICAgIGl0ZW0ub25tb3VzZW92ZXIgPSAoZXZlbnQpID0+IHsgdGhpcy5vdmVyKGV2ZW50LCBrZXkpIH1cbiAgICAgICAgICAgIGl0ZW0ub25tb3VzZW91dCA9IChldmVudCkgPT4geyB0aGlzLm91dChldmVudCwga2V5KSB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5ub3RjaClcbiAgICAgICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KVxuICAgICAgICB0aGlzLmluc2VydGVkTm9kZSA9IHRoaXMuZWxlbWVudFxuICAgICAgICBFbGVtZW50cy5zZXRTdHlsZSh0aGlzLmVsZW1lbnQsIHRoaXMuZGVmYXVsdFN0eWxlKCkpXG4gICAgICAgIHRoaXMubGF5b3V0KClcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKiogRXhlY3V0ZSBhIG1lbnUgY29tbWFuZC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIHNlbGVjdGVkIGtleS5cbiAgICAgKi9cbiAgICBwZXJmb3JtKGtleSkge1xuICAgICAgICBsZXQgZnVuYyA9IHRoaXMuY29tbWFuZHNba2V5XVxuICAgICAgICBpZiAodGhpcy5hdXRvQ2xvc2UpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKVxuICAgICAgICB9XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZnVuYy5jYWxsKClcbiAgICAgICAgfSwgMjApXG4gICAgfVxuXG4gICAgLyoqIFVwZGF0ZSB0aGUgbWVudSBpdGVtIGRlbm90ZWQgYnkga2V5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgc2VsZWN0ZWQga2V5LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaGlnaGxpZ2h0IC0gU2hvdyB0aGUgaXRlbSBoaWdobGlnaHRlZC5cbiAgICAgKi9cbiAgICB1cGRhdGUoa2V5LCBoaWdobGlnaHQgPSBmYWxzZSkge1xuICAgICAgICBsZXQgdGV4dCA9IHRoaXMuaXRlbXNba2V5XVxuICAgICAgICB0ZXh0LnN0eWxlLmNvbG9yID0gKGhpZ2hsaWdodCkgPyB0aGlzLmhpZ2hsaWdodENvbG9yIDogdGhpcy5ub3JtYWxDb2xvclxuICAgIH1cblxuICAgIC8qKiBNb3VzZSBvdmVyIGhhbmTDtmVyLlxuICAgICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IC0gVGhlIG1vdXNlIGV2ZW50LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0ga2V5IC0gVGhlIHNlbGVjdGVkIGtleS5cbiAgICAgKi9cbiAgICBvdmVyKGV2ZW50LCBrZXkpIHtcbiAgICAgICAgZm9yIChsZXQgayBpbiB0aGlzLml0ZW1zKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZShrLCBrID09IGtleSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBNb3VzZSBvdXQgaGFuZMO2ZXIuXG4gICAgICogQHBhcmFtIHtFdmVudH0gZXZlbnQgLSBUaGUgbW91c2UgZXZlbnQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBrZXkgLSBUaGUgc2VsZWN0ZWQga2V5LlxuICAgICAqL1xuICAgIG91dChldmVudCwga2V5KSB7XG4gICAgICAgIHRoaXMudXBkYXRlKGtleSlcbiAgICB9XG5cbiAgICAvKiogU2hvd3MgdGhlIFBvcHVwTWVudSB3aXRoIHRoZSBnaXZlbiBjb21tYW5kcyBhdCB0aGUgc3BlY2lmaWVkIHBvaW50LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kcyAtIEEgZGljdCBvYmplY3Qgd2l0aCBjb21tYW5kIGxhYmVsIHN0cmluZ3MgYXMga2V5c1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCBjb21tYW5kIGZ1bmN0aW9ucyBhcyB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtQb2ludH0gcG9pbnQgLSBUaGUgcG9zaXRpb24gYXMgeCwgeSBjb29yZGluYXRlcyB7cHh9LlxuICAgICAqIEByZXR1cm4ge1BvcHVwTWVudX0gdGhpc1xuICAgICovXG4gICAgc2hvd0F0KGNvbW1hbmRzLCBwb2ludCkge1xuICAgICAgICB0aGlzLnNob3coY29tbWFuZHMpXG4gICAgICAgIHRoaXMucGxhY2VBdChwb2ludClcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKiogQ29udmVuaWVudCBzdGF0aWMgbWV0aG9kcyB0byBzaG93IGFuZCByZXVzZSBhIFBvcHVwTWVudSBpbXBsZW1lbnRlZFxuICAgICAqIGFzIGEgY2xhc3MgdmFyaWFibGUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmRzIC0gQSBkaWN0IG9iamVjdCB3aXRoIGNvbW1hbmQgbGFiZWwgc3RyaW5ncyBhcyBrZXlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGNvbW1hbmQgZnVuY3Rpb25zIGFzIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwb2ludCAtIFRoZSBwb3NpdGlvbiBhcyB4LCB5IGNvb3JkaW5hdGVzIHtweH0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZvbnRTaXplIC0gRGVzY3JpYmVzIHRoZSBmb250IHNpemUgYXMgQ1NTIHZhbHVlXG4gICAgICogQHBhcmFtIHtudW1iZXIgfHwgc3RyaW5nfSBwYWRkaW5nIC0gRGVzY3JpYmVzIHRoZSBwYWRkaW5nIGFzIENTUyB2YWx1ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyIHx8IHN0cmluZ30gbm90Y2hTaXplIC0gRGVzY3JpYmVzIHRoZSBzaXplIG9mIHRoZSBub3RjaCAoY2FsbG91dCkgYXMgQ1NTIHZhbHVlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGhpZ2hsaWdodENvbG9yICAtIFRoZSBjb2xvciBvZiBoaWdobGlnaHRlZCBtZW51IGl0ZW1zIGFzIENTUyB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiYWNrZ3JvdW5kQ29sb3IgIC0gVGhlIGNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kIGFzIENTUyB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBub3JtYWxDb2xvciAgLSBUaGUgY29sb3Igb2Ygbm9ybWFsIG1lbnUgaXRlbXMgYXMgQ1NTIHZhbHVlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhdXRvQ2xvc2UgIC0gQXV0b2Nsb3NlIHRoZSBtZW51IGFmdGVyIHNlbGVjdGluZyBhbiBpdGVtXG4gICAgICovXG4gICAgc3RhdGljIG9wZW4oY29tbWFuZHMsIHBvaW50LCB7IHBhcmVudCA9IG51bGwsXG4gICAgICAgIGNvbnRleHQgPSB3aW5kb3csXG4gICAgICAgIGZvbnRTaXplID0gJzFlbScsXG4gICAgICAgIGZvbnRGYW1pbHkgPSAnQXJpYWwnLFxuICAgICAgICBwYWRkaW5nID0gMTYsXG4gICAgICAgIHpJbmRleCA9IDEsXG4gICAgICAgIHNwYWNpbmcgPSAnMHB4JyxcbiAgICAgICAgc3dpdGNoUG9zID0gZmFsc2UsXG4gICAgICAgIG5vdGNoU2l6ZSA9IDEwLFxuICAgICAgICBtYXhXaWR0aCA9IDgwMCxcbiAgICAgICAga2VlcFdpdGhpbiA9IG51bGwsXG4gICAgICAgIGJhY2tncm91bmRDb2xvciA9ICcjRUVFJyxcbiAgICAgICAgbm9ybWFsQ29sb3IgPSAnIzQ0NCcsXG4gICAgICAgIGF1dG9DbG9zZSA9IHRydWUgfSA9IHt9KSB7XG5cbiAgICAgICAgbGV0IHJlZ2lzdGVyZWQgPSBQb3BwYWJsZS5nZXQoY29udGV4dClcbiAgICAgICAgaWYgKHJlZ2lzdGVyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VQb3B1cCgpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhcIm9wZW5cIiwgcG9pbnQpXG4gICAgICAgIGxldCBub3RjaFBvc2l0aW9uID0gKHBvaW50LnkgPCA1MCAmJiBzd2l0Y2hQb3MpID8gJ3RvcENlbnRlcicgOiAnYm90dG9tQ2VudGVyJ1xuICAgICAgICBsZXQgcG9wdXAgPSBuZXcgUG9wdXBNZW51KHtcbiAgICAgICAgICAgIHBhcmVudCwgZm9udFNpemUsIHBhZGRpbmcsIHpJbmRleCwgc3BhY2luZywgc3dpdGNoUG9zLCBub3RjaFNpemUsXG4gICAgICAgICAgICBub3RjaFBvc2l0aW9uLFxuICAgICAgICAgICAgbWF4V2lkdGgsIGJhY2tncm91bmRDb2xvciwgbm9ybWFsQ29sb3IsXG4gICAgICAgICAgICBub3RjaFBvc2l0aW9uLCBrZWVwV2l0aGluLCBhdXRvQ2xvc2VcbiAgICAgICAgfSlcbiAgICAgICAgcG9wdXAuc2hvd0F0KGNvbW1hbmRzLCBwb2ludClcbiAgICAgICAgcG9wdXAucmVnaXN0ZXIoY29udGV4dClcbiAgICAgICAgcG9wdXAuY2xvc2VFdmVudExpc3RlbmVyID0gKGUpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmV2ZW50T3V0c2lkZShlKSlcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlUG9wdXAoY29udGV4dClcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXV0b0Nsb3NlKSB7XG4gICAgICAgICAgICBjb250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHBvcHVwLmNsb3NlRXZlbnRMaXN0ZW5lciwgdHJ1ZSlcbiAgICAgICAgICAgIGNvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHBvcHVwLmNsb3NlRXZlbnRMaXN0ZW5lciwgdHJ1ZSlcbiAgICAgICAgICAgIGNvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBwb3B1cC5jbG9zZUV2ZW50TGlzdGVuZXIsIHRydWUpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgZXZlbnRPdXRzaWRlKGUpIHtcbiAgICAgICAgcmV0dXJuICFFbGVtZW50cy5oYXNDbGFzcyhlLnRhcmdldCwgJ3BvcHVwTWVudUl0ZW0nKVxuICAgIH1cblxuICAgIC8qKiBDb252ZW5pZW50IHN0YXRpYyBtZXRob2RzIHRvIGNsb3NlIHRoZSBQb3B1cE1lbnUgaW1wbGVtZW50ZWRcbiAgICAgKiBhcyBhIGNsYXNzIHZhcmlhYmxlLlxuICAgICAqL1xuICAgIHN0YXRpYyBjbG9zZVBvcHVwKGNvbnRleHQ9d2luZG93KSB7XG4gICAgICAgIGxldCByZWdpc3RlcmVkID0gUG9wcGFibGUuZ2V0KGNvbnRleHQpXG4gICAgICAgIGlmIChyZWdpc3RlcmVkKSB7XG4gICAgICAgICAgICByZWdpc3RlcmVkLmNsb3NlKClcbiAgICAgICAgICAgIGNvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgcmVnaXN0ZXJlZC5jbG9zZUV2ZW50TGlzdGVuZXIpXG4gICAgICAgICAgICBjb250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCByZWdpc3RlcmVkLmNsb3NlRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgICAgIGNvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCByZWdpc3RlcmVkLmNsb3NlRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7UG9pbnRzfSBmcm9tICcuL3V0aWxzLmpzJ1xuaW1wb3J0IHtDYXBhYmlsaXRpZXN9IGZyb20gJy4vY2FwYWJpbGl0aWVzLmpzJ1xuXG5leHBvcnQgY2xhc3MgRnJhbWVDb250YWluZXIge1xuXG4gICAgY29uc3RydWN0b3IoZWxlbWVudCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50XG4gICAgICAgIHRoaXMuZGVsZWdhdGUgPSBuZXcgSW50ZXJhY3Rpb25NYXBwZXIoZWxlbWVudCwgdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IG1vdXNlV2hlZWxFbGVtZW50OiB3aW5kb3d9KVxuICAgIH1cblxuICAgIGNhcHR1cmUoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBmaW5kVGFyZ2V0KGV2ZW50LCBsb2NhbCwgZ2xvYmFsKSB7XG4gICAgICAgIGxldCBmb3VuZCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZ2xvYmFsLngsIGdsb2JhbC55KVxuICAgICAgICBsZXQgaWZyYW1lID0gZm91bmQucXVlcnlTZWxlY3RvcignaWZyYW1lJylcbiAgICAgICAgaWYgKGlmcmFtZSkge1xuICAgICAgICAgICAgbGV0IHAgPSBQb2ludHMuZnJvbVBhZ2VUb05vZGUoZm91bmQsIGdsb2JhbClcbiAgICAgICAgICAgIGxldCBkb2MgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudFxuICAgICAgICAgICAgbGV0IHRhcmdldCA9IGRvYy5lbGVtZW50RnJvbVBvaW50KHAueCwgcC55KVxuICAgICAgICAgICAgaWYgKHRhcmdldCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2lmcmFtZSBlbGVtZW50JywgdGFyZ2V0KVxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnJhbWVUYXJnZXQoaWZyYW1lLCB0YXJnZXQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGcmFtZVRhcmdldCB7XG5cbiAgICBjb25zdHJ1Y3RvcihmcmFtZSwgdGFyZ2V0LCBkZWJ1Zz1mYWxzZSkge1xuICAgICAgICB0aGlzLmZyYW1lID0gZnJhbWVcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXRcbiAgICAgICAgdGhpcy5kZWJ1ZyA9IGRlYnVnXG4gICAgfVxuXG4gICAgY2FwdHVyZShldmVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHNpbXVsYXRlTW91c2VFdmVudCh0eXBlLCBwb2ludCkge1xuICAgICAgICBsZXQgcCA9IFBvaW50cy5mcm9tUGFnZVRvTm9kZSh0aGlzLmZyYW1lLCBwb2ludClcbiAgICAgICAgbGV0IGV2ZW50ID0gbmV3IE1vdXNlRXZlbnQodHlwZSwge1xuICAgICAgICAgICAgdmlldzogdGhpcy5mcmFtZS5jb250ZW50V2luZG93LFxuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWUsXG4gICAgICAgICAgICBjbGllbnRYOiBwLngsXG4gICAgICAgICAgICBjbGllbnRZOiBwLnl9KVxuICAgICAgICB0aGlzLnRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KVxuICAgIH1cblxuICAgIGNyZWF0ZVRvdWNoTGlzdChwb2ludE1hcCkge1xuICAgICAgICBsZXQgdG91Y2hlcyA9IFtdXG4gICAgICAgIGxldCBkb2MgPSB0aGlzLmZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnRcbiAgICAgICAgZm9yKGxldCBrZXkgb2YgcG9pbnRNYXAua2V5cygpKSB7XG4gICAgICAgICAgICBsZXQgcG9pbnQgPSBwb2ludE1hcC5nZXQoa2V5KVxuICAgICAgICAgICAgbGV0IHAgPSBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5mcmFtZSwgcG9pbnQpXG4gICAgICAgICAgICBsZXQgdG91Y2hUYXJnZXQgPSBkb2MuZWxlbWVudEZyb21Qb2ludChwLngsIHAueSlcbiAgICAgICAgICAgIGxldCB0b3VjaCA9IG5ldyBUb3VjaCh1bmRlZmluZWQsIHRvdWNoVGFyZ2V0LCBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC54LCBwLnksIHAueCwgcC55KVxuICAgICAgICAgICAgdG91Y2hlcy5wdXNoKHRvdWNoKVxuICAgICAgICB9XG4gICAgICAgcmV0dXJuIG5ldyBUb3VjaExpc3QoLi4udG91Y2hlcylcbiAgICB9XG5cbiAgICBzaW11bGF0ZVRvdWNoRXZlbnRDaHJvbWUodHlwZSwgcG9pbnQsIHBvaW50TWFwKSB7XG4gICAgICAgIGxldCBkb2MgPSB0aGlzLmZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnRcbiAgICAgICAgbGV0IHAgPSBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5mcmFtZSwgcG9pbnQpXG4gICAgICAgIGxldCB0b3VjaFRhcmdldCA9IGRvYy5lbGVtZW50RnJvbVBvaW50KHAueCwgcC55KVxuICAgICAgICBjb25zdCB0b3VjaE9iaiA9IG5ldyBUb3VjaCh7XG4gICAgICAgICAgICBpZGVudGlmaWVyOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgdGFyZ2V0OiB0b3VjaFRhcmdldCxcbiAgICAgICAgICAgIGNsaWVudFg6IHAueCxcbiAgICAgICAgICAgIGNsaWVudFk6IHAueSxcbiAgICAgICAgICAgIHBhZ2VYOiBwLngsXG4gICAgICAgICAgICBwYWdlWTogcC55LFxuICAgICAgICAgICAgcmFkaXVzWDogMi41LFxuICAgICAgICAgICAgcmFkaXVzWTogMi41LFxuICAgICAgICAgICAgcm90YXRpb25BbmdsZTogMTAsXG4gICAgICAgICAgICBmb3JjZTogMC41LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0b3VjaEV2ZW50ID0gbmV3IFRvdWNoRXZlbnQodHlwZSwge1xuICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICB0b3VjaGVzOiBbdG91Y2hPYmpdLFxuICAgICAgICAgICAgdGFyZ2V0VG91Y2hlczogW3RvdWNoT2JqXSxcbiAgICAgICAgICAgIGNoYW5nZWRUb3VjaGVzOiBbdG91Y2hPYmpdLFxuICAgICAgICAgICAgc2hpZnRLZXk6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKFwic2ltdWxhdGVUb3VjaEV2ZW50Q2hyb21lXCIsIHRvdWNoRXZlbnQpXG4gICAgICAgIHRoaXMudGFyZ2V0LmRpc3BhdGNoRXZlbnQodG91Y2hFdmVudCk7XG4gICAgfVxuXG4gICAgc2ltdWxhdGVUb3VjaEV2ZW50U2FmYXJpKHR5cGUsIHBvaW50LCBwb2ludE1hcCwgdG91Y2hFdmVudEtleT0ndGFyZ2V0VG91Y2hlcycpIHtcbiAgICAgICAgbGV0IHAgPSBQb2ludHMuZnJvbVBhZ2VUb05vZGUodGhpcy5mcmFtZSwgcG9pbnQpXG4gICAgICAgIGxldCBkYXRhID0geyB2aWV3OiB0aGlzLmZyYW1lLmNvbnRlbnRXaW5kb3csXG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsaWVudFg6IHAueCxcbiAgICAgICAgICAgIGNsaWVudFk6IHAueX1cbiAgICAgICAgZGF0YVt0b3VjaEV2ZW50S2V5XSA9IHRoaXMuY3JlYXRlVG91Y2hMaXN0KHBvaW50TWFwKVxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgVG91Y2hFdmVudCh0eXBlLCBkYXRhKVxuICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coXCJzaW11bGF0ZVRvdWNoRXZlbnRDaHJvbWVcIiwgdG91Y2hFdmVudClcbiAgICAgICAgdGhpcy50YXJnZXQuZGlzcGF0Y2hFdmVudChldmVudClcbiAgICB9XG5cbiAgICBzaW11bGF0ZVRvdWNoRXZlbnQodHlwZSwgcG9pbnQsIHBvaW50TWFwLCB0b3VjaEV2ZW50S2V5PSd0YXJnZXRUb3VjaGVzJykge1xuICAgICAgICBpZiAoQ2FwYWJpbGl0aWVzLmlzU2FmYXJpKSB7XG4gICAgICAgICAgICB0aGlzLnNpbXVsYXRlVG91Y2hFdmVudFNhZmFyaSh0eXBlLCBwb2ludCwgcG9pbnRNYXAsIHRvdWNoRXZlbnRLZXkpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNpbXVsYXRlVG91Y2hFdmVudENocm9tZSh0eXBlLCBwb2ludCwgcG9pbnRNYXApXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc01vdXNlTGlrZUV2ZW50KGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBldmVudC50eXBlLnN0YXJ0c1dpdGgoJ21vdXNlJykgfHwgZXZlbnQudHlwZS5zdGFydHNXaXRoKCdwb2ludGVyJylcbiAgICB9XG5cbiAgICBvblN0YXJ0KGV2ZW50LCBpbnRlcmFjdGlvbikge1xuICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ29uU3RhcnQnLCB0aGlzLmZyYW1lLnBhcmVudE5vZGUpXG4gICAgICAgIGZvcihsZXQgW2tleSwgcG9pbnRdIG9mIGludGVyYWN0aW9uLmN1cnJlbnQuZW50cmllcygpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc01vdXNlTGlrZUV2ZW50KGV2ZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2ltdWxhdGVNb3VzZUV2ZW50KCdtb3VzZWRvd24nLCBwb2ludClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2ltdWxhdGVUb3VjaEV2ZW50KCd0b3VjaHN0YXJ0JywgcG9pbnQsXG4gICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmN1cnJlbnQpXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbk1vdmUoZXZlbnQsIGludGVyYWN0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnb25Nb3ZlJylcbiAgICAgICAgZm9yKGxldCBba2V5LCBwb2ludF0gb2YgaW50ZXJhY3Rpb24uY3VycmVudC5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTW91c2VMaWtlRXZlbnQoZXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaW11bGF0ZU1vdXNlRXZlbnQoJ21vdXNlbW92ZScsIHBvaW50KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaW11bGF0ZVRvdWNoRXZlbnQoJ3RvdWNobW92ZScsIHBvaW50LFxuICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5jdXJyZW50KVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25FbmQoZXZlbnQsIGludGVyYWN0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnb25FbmQnKVxuICAgICAgICBmb3IobGV0IFtrZXksIHBvaW50XSBvZiBpbnRlcmFjdGlvbi5jdXJyZW50LmVudHJpZXMoKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNNb3VzZUxpa2VFdmVudChldmVudCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNpbXVsYXRlTW91c2VFdmVudCgnbW91c2VlbmQnLCBwb2ludClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2ltdWxhdGVUb3VjaEV2ZW50KCd0b3VjaGVuZCcsIHBvaW50LFxuICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5lbmRlZCwgJ2NoYW5nZWRUb3VjaGVzJylcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImV4cG9ydCBjbGFzcyBJbnNwZWN0IHtcbiAgICAvLyBDb2RlIGluc3BlY3Rpb24gZnVuY3Rpb25zXG5cbiAgICBzdGF0aWMgYWxsU2NyaXB0U291cmNlcygpXG4gICAge1xuICAgICAgICBsZXQgc291cmNlcyA9IFtdXG4gICAgICAgIGxldCBzY3JpcHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2NyaXB0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc29sZS5kaXIoc2NyaXB0c1tpXSlcbiAgICAgICAgICAgIHNvdXJjZXMucHVzaChzY3JpcHRzW2ldKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2VzXG4gICAgfVxufVxuIiwiLyogZ2xvYmFscyBQb3dlcjAgKi9cbi8qIGVzbGludCBuby1jb25zb2xlOiBbXCJlcnJvclwiLCB7IGFsbG93OiBbXCJsb2dcIiwgXCJpbmZvXCIsIFwid2FyblwiLCBcImVycm9yXCJdIH1dICovXG5cbi8qKlxuICogSW1wb3J0c1xuICovXG5cbi8qKlxuICogQSBjbGFzcyB0aGF0IGNhbiBiZSB1c2VkIHRvIHBlcmZvcm0gYXV0b21hdGVkIHVzZXIgaW50ZXJmYWNlIHRlc3RzLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIFVJVGVzdCBvYmplY3RcbiAqIGNvbnN0IHRlc3QgPSBuZXcgVUlUZXN0KHtcbiAqICAgICB0aW1lU2NhbGU6IDJcbiAqIH0pXG4gKlxuICogLy8gQWRkIGFuIGFjdGlvbiB0byB0aGUgdGVzdCBjYXNlXG4gKiB0ZXN0LnRhcChidXR0b24sIHtldmVudFR5cGU6ICdjbGljayd9KVxuICogXG4gKiAvLyBTdGFydCB0aGUgdGVzdCBjYXNlXG4gKiB0ZXN0LnN0YXJ0KClcbiAqXG4gKiBAY2xhc3NcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lml3bS10dWViaW5nZW4uZGUvaXdtYnJvd3Nlci9saWIvcGl4aS91aXRlc3QuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBVSVRlc3Qge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhbiBVSVRlc3QuXG4gICAgICogXG4gICAgICogSW4gdGhlIGJhY2tncm91bmQsIHRoZSBjbGFzcyBVSVRlc3QgdXNlcyB0aGUgR3JlZW5zb2NrIFRpbWVsaW5lTWF4IGNsYXNzLiBUaGUgb3B0cyBvYmplY3QgaXMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBUaW1lbGluZU1heCBjbGFzcywgc28gaXQgY2FuIHVzZSBhbnkga2V5IHRoYXQgdXNlcyB0aGUgVGltZWxpbmVNYXggY2xhc3MuXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0aGUgYmVoYXZpb3VyIG9mIHRoZSB0ZXN0IGNhc2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnRpbWVTY2FsZT0xXSAtIFRoZSBzcGVlZCBhdCB3aGljaCB0aGUgdGVzdCBzaG91bGQgcnVuLCBzZWUgaHR0cHM6Ly9ncmVlbnNvY2suY29tL2RvY3MvVGltZWxpbmVNYXgvdGltZVNjYWxlKCkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmV2ZW50VHlwZT1hdXRvXSAtIFRoZSB0eXBlIG9mIGV2ZW50cyB3aGljaCBzaG91bGQgYmUgdXNlZC4gUG9zc2libGUgdmFsdWVzOiBwb2ludGVyLCB0b3VjaCwgbW91c2UsIGF1dG8uIElmIHNldCB0byBhdXRvLCB0aGUgZXZlbnRUeXBlIGlzIHNldCBkZXBlbmRpbmcgb24gdGhlIHN1cHBvcnQgb2YgdGhlIGJyb3dzZXIgdXNlZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmRlYnVnPWZhbHNlXSAtIElmIHNldCB0byB0cnVlLCBtdWx0aXBsZSBpbmZvcm1hdGlvbnMgd2lsbCBiZSBwcmludCB0byB0aGUgY29uc29sZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZGVmYXVsdEludGVydmFsXSAtIFRoZSBpbnRlcnZhbCB1c2VkIHdoZW4gbm8gYWN0aW9uIGlzIHNwZWNpZmllZCBmb3IgYW4gYWN0aW9uLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdHMgPSB7fSkge1xuXG4gICAgICAgIHRoaXMub3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHtcbiAgICAgICAgICAgIHRpbWVTY2FsZTogMSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogJ2F1dG8nLFxuICAgICAgICAgICAgZGVidWc6IGZhbHNlLFxuICAgICAgICAgICAgZGVmYXVsdEludGVydmFsOiBudWxsXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgLy8gdGltZWxpbmVcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLl90aW1lbGluZSA9IG5ldyBUaW1lbGluZU1heChPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBwYXVzZWQ6IHRydWVcbiAgICAgICAgfSwgdGhpcy5vcHRzKSlcbiAgICAgICAgdGhpcy5fdGltZWxpbmUudGltZVNjYWxlKHRoaXMub3B0cy50aW1lU2NhbGUpXG5cbiAgICAgICAgLy8gZXZlbnRUeXBlXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKHRoaXMub3B0cy5ldmVudFR5cGUgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdHMuZXZlbnRUeXBlID0gJ3BvaW50ZXInXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdykge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0cy5ldmVudFR5cGUgPSAndG91Y2gnXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0cy5ldmVudFR5cGUgPSAnbW91c2UnXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5vcHRzLmRlYnVnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgRXZlbnQgdHlwZTogJHt0aGlzLm9wdHMuZXZlbnRUeXBlfWApXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl90aW1lbGluZVBvc2l0aW9ucyA9IFswXVxuICAgICAgICB0aGlzLl9hY3Rpb25zID0gMFxuXG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXR1cCgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIHRoZSByZXF1aXJlZCBzdHJ1Y3R1cmUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1VJVGVzdH0gQSByZWZlcmVuY2UgdG8gdGhlIFVJVGVzdCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0dXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgR3JlZW5zb2NrIFRpbWVsaW5lTWF4IG9iamVjdCwgdXNlZCBpbiB0aGUgYmFja2dyb3VuZCBvZiBVSVRlc3QuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyIHtUaW1lbGluZU1heH1cbiAgICAgKi9cbiAgICBnZXQgdGltZWxpbmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgdGVzdCBjYXNlIGFuZCBleGVjdXRlcyB0aGUgY29ycmVzcG9uZGluZyBzdGF0ZW1lbnRzIGluIHRoZSBzcGVjaWZpZWQgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtVSVRlc3R9IEEgcmVmZXJlbmNlIHRvIHRoZSBVSVRlc3QgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHN0YXJ0KCkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5wbGF5KClcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdG9wcyB0aGUgdGVzdCBjYXNlIGFuZCBzdG9wcyBleGVjdXRpbmcgYW55IGZ1cnRoZXIgaW5zdHJ1Y3Rpb25zLlxuICAgICAqXG4gICAgICogQHJldHVybiB7VUlUZXN0fSBBIHJlZmVyZW5jZSB0byB0aGUgVUlUZXN0IGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzdG9wKCkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5wYXVzZSgpXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGFsbCBpbnN0cnVjdGlvbnMgb2YgdGhlIHRlc3QgY2FzZS5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtVSVRlc3R9IEEgcmVmZXJlbmNlIHRvIHRoZSBVSVRlc3QgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5jbGVhcigpXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdGFydHMgdGhlIHRlc3QgY2FzZS5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtVSVRlc3R9IEEgcmVmZXJlbmNlIHRvIHRoZSBVSVRlc3QgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHJlc3RhcnQoKSB7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLnJlc3RhcnQoKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIGEgdGFwIGV2ZW50IChwb2ludGVyZG93biwgcG9pbnRlcnVwKSBvbiBhIHNwZWNpZmljIGVsZW1lbnQuXG4gICAgICogXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudHxzdHJpbmd9IGVsZW1lbnQgLSBUaGUgSFRNTCBlbGVtZW50IG9uIHdoaWNoIHRoZSBldmVudCBpcyB0byBiZSBleGVjdXRlZCwgZS5nLiBidXR0b24sIGRvY3VtZW50LCBoMiwgY2FudmFzLCBldGMuIG9yIGFuIHNlbGVjdG9yIHN0cmluZy4gSWYgYSBzZWxlY3RvciBoYXMgYmVlbiBzcGVjaWZpZWQsIGl0IGlzIGV2YWx1YXRlZCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGV2ZW50IGlzIGNhbGxlZCB1c2luZyB0aGUgcXVlcnlTZWxlY3RvciBtZXRob2QuXG4gICAgICogQHBhcmFtIHtudW1iZXJbXXxvYmplY3R8UElYSS5EaXNwbGF5T2JqZWN0fSBbcG9zaXRpb249VGhlIGNlbnRlciBvZiB0aGUgZWxlbWVudC5dIC0gVGhlIGxvY2FsIHBvc2l0aW9uIG9mIHRoZSBldmVudCBpbiB0aGUgY29udGV4dCBvZiB0aGUgc3BlY2lmaWVkIEhUTUwgZWxlbWVudC4gSWYgbm8gcG9zaXRpb24gaXMgc3BlY2lmaWVkLCB0aGUgY2VudGVyIG9mIHRoZSBIVE1MIGVsZW1lbnQgaXMgdXNlZC4gVGhlIHBvc2l0aW9uIGNhbiBiZSBzcGVjaWZpZWQgYXMgYW4gYXJyYXkgb2YgbnVtYmVycywgYXMgYW4gb2JqZWN0IHdpdGggdGhlIHR3byBwcm9wZXJ0aWVzIHggYW5kIHksIG9yIGFzIGEgUElYSS5EaXNwbGF5IG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3RpbWVsaW5lUG9zaXRpb249T25lIHNlY29uZCBhZnRlciB0aGUgbGFzdCBhY3Rpb24uXSAtIFRoZSBwb3NpdGlvbiBpbiBzZWNvbmRzIHdoZW4gdGhlIGV2ZW50IHNob3VsZCBiZSB0cmlnZ2VyZWQsIHNlZSBzaHR0cHM6Ly9ncmVlbnNvY2suY29tL2RvY3MvVGltZWxpbmVNYXgvYWRkQ2FsbGJhY2soKS5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0aGUgYmVoYXZpb3VyIG9mIHRoZSBhY3Rpb24uXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gW29wdHMub25TdGFydF0gLSBBIGZ1bmN0aW9uIHRoYXQgcnVucyBhZnRlciB0aGUgZmlyc3QgZXZlbnQgaXMgZmlyZWQuIFdpbGwgbm90IGJlIGZpcmVkIGlmIG9ubHkgb25lIGV2ZW50IGlzIHJ1bm5pbmcgKGZvciBleGFtcGxlLCBhIGNsaWNrIGV2ZW50KS4gUmVjZWl2ZXMgdGhlIGZpcmVkIGV2ZW50IG9iamVjdCBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyLiBUaGUgdGVzdCBjYXNlIChVSVRlc3QpIGlzIGJvdW5kIHRvIHRoaXMuXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gW29wdHMub25Db21wbGV0ZV0gLSBBIGZ1bmN0aW9uIHRoYXQgcnVucyBhZnRlciB0aGUgc2Vjb25kIGV2ZW50IGlzIGZpcmVkLiBBbHdheXMgZmlyZWQsIGV2ZW4gaWYgb25seSBvbmUgZXZlbnQgaXMgcnVubmluZyAoZm9yIGV4YW1wbGUsIGEgY2xpY2sgZXZlbnQpLiBSZWNlaXZlcyB0aGUgZmlyZWQgZXZlbnQgb2JqZWN0IGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIuIFRoZSB0ZXN0IGNhc2UgKFVJVGVzdCkgaXMgYm91bmQgdG8gdGhpcy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbb3B0cy5ldmVudFR5cGVzPVsncG9pbnRlcmRvd24nLCAncG9pbnRlcnVwJ11dIC0gVGhlIGV2ZW50IHR5cGVzIHRvIHVzZS4gSWYgbm8gdHlwZXMgYXJlIHNwZWNpZmllZCwgdGhlIGV2ZW50IHR5cGVzIHNwZWNpZmllZCBpbiB0aGUgVUlUZXN0IGNvbnN0cnVjdG9yIGFyZSB1c2VkIChvciBhdXRvIGlmIG5vdCBzcGVjaWZpZWQpLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5ldmVudFR5cGVdIC0gSWYgeW91IHdhbnQgdGhlIHRhcCBtZXRob2QgdG8gZmlyZSBvbmx5IG9uZSBldmVudCAoZm9yIGV4YW1wbGUsIGEgY2xpY2sgZXZlbnQpLCB5b3UgY2FuIHNwZWNpZnkgdGhlIG9wdHMuZXZlbnRUeXBlIHBhcmFtZXRlci4gSWYgZXZlbnRUeXBlIGlzIG5vdCBudWxsLCB0aGUgcGFyYW1ldGVyIG9wdHMuZXZlbnRUeXBlcyBpcyBpZ25vcmVkLlxuICAgICAqIEBwYXJhbSB7V2luZG93fEZyYW1lfSBbb3B0cy5jb250ZXh0PXdpbmRvd10gLSBUaGUgY29udGV4dCB3aXRoaW4gd2hpY2ggdGhlIG9wdGlvbmFsbHkgc3BlY2lmaWVkIGVsZW1lbnQgc2VsZWN0b3Igc2hvdWxkIGJlIGV4ZWN1dGVkLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuYnViYmxlcz10cnVlXSAtIFRoZSBFdmVudCBwcm9wZXJ0eSBidWJibGVzIGluZGljYXRlcyB3aGV0aGVyIHRoZSBldmVudCBidWJibGVzIHVwIHRocm91Z2ggdGhlIERPTSBvciBub3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5jYW5jZWxhYmxlPXRydWVdIC0gRXZlbnRzJyBjYW5jZWxhYmxlIHByb3BlcnR5IGluZGljYXRlcyBpZiB0aGUgZXZlbnQgY2FuIGJlIGNhbmNlbGVkLCBhbmQgdGhlcmVmb3JlIHByZXZlbnRlZCBhcyBpZiB0aGUgZXZlbnQgbmV2ZXIgaGFwcGVuZWQuIElmIHRoZSBldmVudCBpcyBub3QgY2FuY2VsYWJsZSwgdGhlbiBpdHMgY2FuY2VsYWJsZSBwcm9wZXJ0eSB3aWxsIGJlIGZhbHNlIGFuZCB0aGUgZXZlbnQgbGlzdGVuZXIgY2Fubm90IHN0b3AgdGhlIGV2ZW50IGZyb20gb2NjdXJyaW5nLlxuICAgICAqL1xuICAgIHRhcChlbGVtZW50LCBwb3NpdGlvbiwgdGltZWxpbmVQb3NpdGlvbiwgb3B0cyA9IHt9KSB7XG4gICAgICAgIFxuICAgICAgICAvLyBhcmd1bWVudHNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBbcG9zaXRpb24sIHRpbWVsaW5lUG9zaXRpb24sIG9wdHNdID0gdGhpcy5yZW9yZGVyQXJndW1lbnRzKGFyZ3VtZW50cylcbiAgICAgICAgdGhpcy5fdGltZWxpbmVQb3NpdGlvbnMucHVzaCh0aW1lbGluZVBvc2l0aW9uKVxuXG4gICAgICAgIC8vIGRlYnVnXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKHRoaXMub3B0cy5kZWJ1ZykgY29uc29sZS5sb2coJ3RhcCBwYXJhbXMnLCB7ZWxlbWVudCwgcG9zaXRpb24sIHRpbWVsaW5lUG9zaXRpb24sIG9wdHN9KVxuXG4gICAgICAgIC8vIG9wdHNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgb25TdGFydDogbnVsbCxcbiAgICAgICAgICAgIG9uQ29tcGxldGU6IG51bGwsXG4gICAgICAgICAgICBldmVudFR5cGVzOiB0aGlzLnJlc29sdmVFdmVudHMoWydkb3duJywgJ3VwJ10pLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBudWxsLFxuICAgICAgICAgICAgY29udGV4dDogd2luZG93LFxuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICBpZiAob3B0cy5ldmVudFR5cGUpIHtcbiAgICAgICAgICAgIG9wdHMuZXZlbnRUeXBlcyA9IG9wdHMuZXZlbnRUeXBlXG4gICAgICAgIH1cbiAgICAgICAgb3B0cy5ldmVudFR5cGVzID0gQXJyYXkuaXNBcnJheShvcHRzLmV2ZW50VHlwZXMpID8gb3B0cy5ldmVudFR5cGVzIDogW29wdHMuZXZlbnRUeXBlc11cblxuICAgICAgICAvLyB0aW1lbGluZVxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmFkZENhbGxiYWNrKHBvc2l0aW9uID0+IHtcblxuICAgICAgICAgICAgLy8gZWxlbWVudFxuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgY29uc3QgZWxlbSA9IFV0aWwuZXh0cmFjdEVsZW1lbnQob3B0cy5jb250ZXh0LCBlbGVtZW50KVxuXG4gICAgICAgICAgICAvLyBwb3NpdGlvblxuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IFtyZWN0LndpZHRoIC8gMiwgcmVjdC5oZWlnaHQgLyAyXVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjb29yZHNcbiAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9IFV0aWwuZXh0cmFjdFBvc2l0aW9uKHBvc2l0aW9uKVxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kZWJ1ZykgY29uc29sZS5sb2coJ2xvY2FsIGNvb3JkcycsIGNvb3JkcylcblxuICAgICAgICAgICAgLy8gZXZlbnRUeXBlc1xuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgaWYgKG9wdHMuZXZlbnRUeXBlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICBvcHRzLmV2ZW50VHlwZXMudW5zaGlmdChudWxsKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBldmVudCBvcHRzXG4gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICBjb25zdCBldmVudE9wdHMgPSB7YnViYmxlczogb3B0cy5idWJibGVzLCBjYW5jZWxhYmxlOiBvcHRzLmNhbmNlbGFibGV9XG5cbiAgICAgICAgICAgIGlmIChvcHRzLmV2ZW50VHlwZXNbMF0pIHtcblxuICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgZGlzcGF0Y2ggZXZlbnRcbiAgICAgICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnRTdGFydCA9IEV2ZW50LmNyZWF0ZShlbGVtLCBjb29yZHMsIG9wdHMuZXZlbnRUeXBlc1swXSwgZXZlbnRPcHRzKVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZGVidWcpIGNvbnNvbGUubG9nKCdkaXNwYXRjaCBldmVudCcsIGV2ZW50U3RhcnQpXG4gICAgICAgICAgICAgICAgZWxlbS5kaXNwYXRjaEV2ZW50KGV2ZW50U3RhcnQpXG5cbiAgICAgICAgICAgICAgICAvLyBvblN0YXJ0XG4gICAgICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uU3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0cy5vblN0YXJ0LmNhbGwodGhpcywgZXZlbnRTdGFydClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgZGlzcGF0Y2ggZXZlbnRcbiAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgIGNvbnN0IGV2ZW50Q29tcGxldGUgPSBFdmVudC5jcmVhdGUoZWxlbSwgY29vcmRzLCBvcHRzLmV2ZW50VHlwZXNbMV0sIGV2ZW50T3B0cylcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZGVidWcpIGNvbnNvbGUubG9nKCdkaXNwYXRjaCBldmVudCcsIGV2ZW50Q29tcGxldGUpXG4gICAgICAgICAgICBlbGVtLmRpc3BhdGNoRXZlbnQoZXZlbnRDb21wbGV0ZSlcblxuICAgICAgICAgICAgLy8gb25Db21wbGV0ZVxuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgaWYgKG9wdHMub25Db21wbGV0ZSkge1xuICAgICAgICAgICAgICAgIG9wdHMub25Db21wbGV0ZS5jYWxsKHRoaXMsIGV2ZW50Q29tcGxldGUpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgfSwgdGltZWxpbmVQb3NpdGlvbiwgW3Bvc2l0aW9uXSlcblxuICAgICAgICB0aGlzLl9hY3Rpb25zKytcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIGEgcGFuIGV2ZW50IChwb2ludGVyZG93biwgcG9pbnRlcm1vdmUsIHBvaW50ZXJ1cCkgb24gYSBzcGVjaWZpYyBlbGVtZW50LlxuICAgICAqIFxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8c3RyaW5nfSBlbGVtZW50IC0gVGhlIEhUTUwgZWxlbWVudCBvbiB3aGljaCB0aGUgZXZlbnQgaXMgdG8gYmUgZXhlY3V0ZWQsIGUuZy4gYnV0dG9uLCBkb2N1bWVudCwgaDIsIGNhbnZhcywgZXRjLiBvciBhbiBzZWxlY3RvciBzdHJpbmcuIElmIGEgc2VsZWN0b3IgaGFzIGJlZW4gc3BlY2lmaWVkLCBpdCBpcyBldmFsdWF0ZWQgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBldmVudCBpcyBjYWxsZWQgdXNpbmcgdGhlIHF1ZXJ5U2VsZWN0b3IgbWV0aG9kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyW118b2JqZWN0fFBJWEkuRGlzcGxheU9iamVjdH0gW3Bvc2l0aW9uPVRoZSBjZW50ZXIgb2YgdGhlIGVsZW1lbnQuXSAtIFRoZSBsb2NhbCBwb3NpdGlvbiBvZiB0aGUgZXZlbnQgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCBIVE1MIGVsZW1lbnQuIElmIG5vIHBvc2l0aW9uIGlzIHNwZWNpZmllZCwgdGhlIGNlbnRlciBvZiB0aGUgSFRNTCBlbGVtZW50IGlzIHVzZWQuIFRoZSBwb3NpdGlvbiBjYW4gYmUgc3BlY2lmaWVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIGFzIGFuIG9iamVjdCB3aXRoIHRoZSB0d28gcHJvcGVydGllcyB4IGFuZCB5LCBvciBhcyBhIFBJWEkuRGlzcGxheSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt0aW1lbGluZVBvc2l0aW9uPU9uZSBzZWNvbmQgYWZ0ZXIgdGhlIGxhc3QgYWN0aW9uLl0gLSBUaGUgcG9zaXRpb24gaW4gc2Vjb25kcyB3aGVuIHRoZSBldmVudCBzaG91bGQgYmUgdHJpZ2dlcmVkLCBzZWUgc2h0dHBzOi8vZ3JlZW5zb2NrLmNvbS9kb2NzL1RpbWVsaW5lTWF4L2FkZENhbGxiYWNrKCkuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IHRvIHNwZWNpZnkgdGhlIGJlaGF2aW91ciBvZiB0aGUgYWN0aW9uLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRzLm9uU3RhcnRdIC0gQSBmdW5jdGlvbiB0aGF0IHJ1bnMgYWZ0ZXIgdGhlIGZpcnN0IGV2ZW50IGlzIGZpcmVkLiBSZWNlaXZlcyB0aGUgZmlyZWQgZXZlbnQgb2JqZWN0IGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIuIFRoZSB0ZXN0IGNhc2UgKFVJVGVzdCkgaXMgYm91bmQgdG8gdGhpcy5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0cy5vblVwZGF0ZV0gLSBBIGZ1bmN0aW9uIHRoYXQgcnVucyBhZnRlciBlYWNoIGV4ZWN1dGlvbiBvZiB0aGUgc2Vjb25kIGV2ZW50LiBSZWNlaXZlcyB0aGUgZmlyZWQgZXZlbnQgb2JqZWN0IGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIuIFRoZSB0ZXN0IGNhc2UgKFVJVGVzdCkgaXMgYm91bmQgdG8gdGhpcy5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0cy5vbkNvbXBsZXRlXSAtIEEgZnVuY3Rpb24gdGhhdCBydW5zIGFmdGVyIHRoZSB0aGlyZCBldmVudCBpcyBmaXJlZC4gUmVjZWl2ZXMgdGhlIGZpcmVkIGV2ZW50IG9iamVjdCBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyLiBUaGUgdGVzdCBjYXNlIChVSVRlc3QpIGlzIGJvdW5kIHRvIHRoaXMuXG4gICAgICogQHBhcmFtIHtudW1iZXJbXXxvYmplY3R8UElYSS5EaXNwbGF5T2JqZWN0fSBbb3B0cy50bz17eDogMCwgeTogMH1dIC0gVGhlIHRhcmdldCBvZiB0aGUgcGFuIHByb2Nlc3MuIFRoZSBwb3NpdGlvbiBjYW4gYmUgc3BlY2lmaWVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIGFzIGFuIG9iamVjdCB3aXRoIHRoZSB0d28gcHJvcGVydGllcyB4IGFuZCB5LCBvciBhcyBhIFBJWEkuRGlzcGxheSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmR1cmF0aW9uPTFdIC0gVGhlIGR1cmF0aW9uIG9mIHRoZSBwYW4gYW5pbWF0aW9uIGluIHNlY29uZHMsIHNlZSBodHRwczovL2dyZWVuc29jay5jb20vZG9jcy9Ud2VlbkxpdGUvZHVyYXRpb24oKS5cbiAgICAgKiBAcGFyYW0ge0Vhc2V9IFtvcHRzLmVhc2U9UG93ZXIwLmVhc2VOb25lXSAtIFRoZSBlYXNpbmcgb2YgdGhlIHBhbiBhbmltYXRpb24sIHNlZSBodHRwczovL2dyZWVuc29jay5jb20vZG9jcy9FYXNpbmcuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gW29wdHMuZXZlbnRUeXBlcz1bJ3BvaW50ZXJkb3duJywgJ3BvaW50ZXJtb3ZlJywgJ3BvaW50ZXJ1cCddXSAtIFRoZSBldmVudCB0eXBlcyB0byB1c2UuIElmIG5vIHR5cGVzIGFyZSBzcGVjaWZpZWQsIHRoZSBldmVudCB0eXBlcyBzcGVjaWZpZWQgaW4gdGhlIFVJVGVzdCBjb25zdHJ1Y3RvciBhcmUgdXNlZCAob3IgYXV0byBpZiBub3Qgc3BlY2lmaWVkKS5cbiAgICAgKiBAcGFyYW0ge1dpbmRvd3xGcmFtZX0gW29wdHMuY29udGV4dD13aW5kb3ddIC0gVGhlIGNvbnRleHQgd2l0aGluIHdoaWNoIHRoZSBvcHRpb25hbGx5IHNwZWNpZmllZCBlbGVtZW50IHNlbGVjdG9yIHNob3VsZCBiZSBleGVjdXRlZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmJ1YmJsZXM9dHJ1ZV0gLSBUaGUgRXZlbnQgcHJvcGVydHkgYnViYmxlcyBpbmRpY2F0ZXMgd2hldGhlciB0aGUgZXZlbnQgYnViYmxlcyB1cCB0aHJvdWdoIHRoZSBET00gb3Igbm90LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuY2FuY2VsYWJsZT10cnVlXSAtIEV2ZW50cycgY2FuY2VsYWJsZSBwcm9wZXJ0eSBpbmRpY2F0ZXMgaWYgdGhlIGV2ZW50IGNhbiBiZSBjYW5jZWxlZCwgYW5kIHRoZXJlZm9yZSBwcmV2ZW50ZWQgYXMgaWYgdGhlIGV2ZW50IG5ldmVyIGhhcHBlbmVkLiBJZiB0aGUgZXZlbnQgaXMgbm90IGNhbmNlbGFibGUsIHRoZW4gaXRzIGNhbmNlbGFibGUgcHJvcGVydHkgd2lsbCBiZSBmYWxzZSBhbmQgdGhlIGV2ZW50IGxpc3RlbmVyIGNhbm5vdCBzdG9wIHRoZSBldmVudCBmcm9tIG9jY3VycmluZy5cbiAgICAgKi9cbiAgICBwYW4oZWxlbWVudCwgcG9zaXRpb24sIHRpbWVsaW5lUG9zaXRpb24sIG9wdHMgPSB7fSkge1xuXG4gICAgICAgIC8vIGFyZ3VtZW50c1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIFtwb3NpdGlvbiwgdGltZWxpbmVQb3NpdGlvbiwgb3B0c10gPSB0aGlzLnJlb3JkZXJBcmd1bWVudHMoYXJndW1lbnRzKVxuICAgICAgICB0aGlzLl90aW1lbGluZVBvc2l0aW9ucy5wdXNoKHRpbWVsaW5lUG9zaXRpb24pXG5cbiAgICAgICAgLy8gZGVidWdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmRlYnVnKSBjb25zb2xlLmxvZygndGFwIHBhcmFtcycsIHtlbGVtZW50LCBwb3NpdGlvbiwgdGltZWxpbmVQb3NpdGlvbiwgb3B0c30pXG5cbiAgICAgICAgLy8gb3B0c1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBvblN0YXJ0OiBudWxsLFxuICAgICAgICAgICAgb25VcGRhdGU6IG51bGwsXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiBudWxsLFxuICAgICAgICAgICAgdG86IHt4OiAwLCB5OiAwfSxcbiAgICAgICAgICAgIGR1cmF0aW9uOiAxLFxuICAgICAgICAgICAgZWFzZTogUG93ZXIwLmVhc2VOb25lLFxuICAgICAgICAgICAgZXZlbnRUeXBlczogdGhpcy5yZXNvbHZlRXZlbnRzKFsnZG93bicsICdtb3ZlJywgJ3VwJ10pLFxuICAgICAgICAgICAgY29udGV4dDogd2luZG93LFxuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICAvLyB0aW1lbGluZVxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmFkZENhbGxiYWNrKHBvc2l0aW9uID0+IHtcblxuICAgICAgICAgICAgLy8gZWxlbWVudFxuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgY29uc3QgZWxlbSA9IFV0aWwuZXh0cmFjdEVsZW1lbnQob3B0cy5jb250ZXh0LCBlbGVtZW50KVxuXG4gICAgICAgICAgICAvLyBjb29yZHNcbiAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgIGNvbnN0IGZyb20gPSBVdGlsLmV4dHJhY3RQb3NpdGlvbihwb3NpdGlvbilcblxuICAgICAgICAgICAgLy8gZXZlbnQgb3B0c1xuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgY29uc3QgZXZlbnRPcHRzID0ge2J1YmJsZXM6IG9wdHMuYnViYmxlcywgY2FuY2VsYWJsZTogb3B0cy5jYW5jZWxhYmxlfVxuXG4gICAgICAgICAgICBjb25zdCBnc09wdHMgPSB7XG4gICAgICAgICAgICAgICAgZWFzZTogb3B0cy5lYXNlLFxuICAgICAgICAgICAgICAgIG9uU3RhcnQ6ICgpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYW5kIGRpc3BhdGNoIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBFdmVudC5jcmVhdGUoZWxlbSwgZnJvbSwgb3B0cy5ldmVudFR5cGVzWzBdLCBldmVudE9wdHMpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZGVidWcpIGNvbnNvbGUubG9nKCdkaXNwYXRjaCBldmVudCcsIGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICBlbGVtLmRpc3BhdGNoRXZlbnQoZXZlbnQpXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gb25TdGFydFxuICAgICAgICAgICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uU3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdHMub25TdGFydC5jYWxsKHRoaXMsIGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBvblVwZGF0ZTogKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgZGlzcGF0Y2ggZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBldmVudCA9IEV2ZW50LmNyZWF0ZShlbGVtLCBmcm9tLCBvcHRzLmV2ZW50VHlwZXNbMV0sIGV2ZW50T3B0cylcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kZWJ1ZykgY29uc29sZS5sb2coJ2Rpc3BhdGNoIGV2ZW50JywgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgIGVsZW0uZGlzcGF0Y2hFdmVudChldmVudClcblxuICAgICAgICAgICAgICAgICAgICAvLyBvblVwZGF0ZVxuICAgICAgICAgICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uVXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRzLm9uVXBkYXRlLmNhbGwodGhpcywgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYW5kIGRpc3BhdGNoIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBFdmVudC5jcmVhdGUoZWxlbSwgZnJvbSwgb3B0cy5ldmVudFR5cGVzWzJdLCBldmVudE9wdHMpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZGVidWcpIGNvbnNvbGUubG9nKCdkaXNwYXRjaCBldmVudCcsIGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICBlbGVtLmRpc3BhdGNoRXZlbnQoZXZlbnQpXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gb25Db21wbGV0ZVxuICAgICAgICAgICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uQ29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdHMub25Db21wbGV0ZS5jYWxsKHRoaXMsIGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyB0b1xuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgY29uc3Qgb2JqZWN0ID0gVXRpbC5leHRyYWN0VG8ob3B0cylcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oZ3NPcHRzLCBvYmplY3QpXG5cbiAgICAgICAgICAgIC8vIGRyYWcgYW5pbWF0aW9uXG4gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICBUd2Vlbk1heC50byhmcm9tLCBvcHRzLmR1cmF0aW9uLCBnc09wdHMpXG5cbiAgICAgICAgfSwgdGltZWxpbmVQb3NpdGlvbiwgW3Bvc2l0aW9uXSlcbiAgICAgICAgXG4gICAgICAgIHRoaXMuX2FjdGlvbnMrK1xuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgYSBwaW5jaCBldmVudCAocG9pbnRlcmRvd24sIHBvaW50ZXJtb3ZlLCBwb2ludGVydXApIG9uIGEgc3BlY2lmaWMgZWxlbWVudCB3aXRoIHR3byBcImZpbmdlcnNcIiBzaW11bHRhbmVvdXNseS5cbiAgICAgKiBcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fHN0cmluZ30gZWxlbWVudCAtIFRoZSBIVE1MIGVsZW1lbnQgb24gd2hpY2ggdGhlIGV2ZW50IGlzIHRvIGJlIGV4ZWN1dGVkLCBlLmcuIGJ1dHRvbiwgZG9jdW1lbnQsIGgyLCBjYW52YXMsIGV0Yy4gb3IgYW4gc2VsZWN0b3Igc3RyaW5nLiBJZiBhIHNlbGVjdG9yIGhhcyBiZWVuIHNwZWNpZmllZCwgaXQgaXMgZXZhbHVhdGVkIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZXZlbnQgaXMgY2FsbGVkIHVzaW5nIHRoZSBxdWVyeVNlbGVjdG9yIG1ldGhvZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdfG9iamVjdHxQSVhJLkRpc3BsYXlPYmplY3R9IFtwb3NpdGlvbj1UaGUgY2VudGVyIG9mIHRoZSBlbGVtZW50Ll0gLSBUaGUgbG9jYWwgcG9zaXRpb24gb2YgdGhlIGV2ZW50IGluIHRoZSBjb250ZXh0IG9mIHRoZSBzcGVjaWZpZWQgSFRNTCBlbGVtZW50LiBJZiBubyBwb3NpdGlvbiBpcyBzcGVjaWZpZWQsIHRoZSBjZW50ZXIgb2YgdGhlIEhUTUwgZWxlbWVudCBpcyB1c2VkLiBUaGUgcG9zaXRpb24gY2FuIGJlIHNwZWNpZmllZCBhcyBhbiBhcnJheSBvZiBudW1iZXJzLCBhcyBhbiBvYmplY3Qgd2l0aCB0aGUgdHdvIHByb3BlcnRpZXMgeCBhbmQgeSwgb3IgYXMgYSBQSVhJLkRpc3BsYXkgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZWxpbmVQb3NpdGlvbj1PbmUgc2Vjb25kIGFmdGVyIHRoZSBsYXN0IGFjdGlvbi5dIC0gVGhlIHBvc2l0aW9uIGluIHNlY29uZHMgd2hlbiB0aGUgZXZlbnQgc2hvdWxkIGJlIHRyaWdnZXJlZCwgc2VlIHNodHRwczovL2dyZWVuc29jay5jb20vZG9jcy9UaW1lbGluZU1heC9hZGRDYWxsYmFjaygpLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0c10gLSBBbiBvcHRpb25zIG9iamVjdCB0byBzcGVjaWZ5IHRoZSBiZWhhdmlvdXIgb2YgdGhlIGFjdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0cy5vblN0YXJ0XSAtIEEgZnVuY3Rpb24gdGhhdCBydW5zIGFmdGVyIHRoZSBmaXJzdCBldmVudHMgYXJlIGZpcmVkLiBSZWNlaXZlcyB0aGUgZmlyZWQgZXZlbnQgb2JqZWN0IGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIuIFRoZSB0ZXN0IGNhc2UgKFVJVGVzdCkgaXMgYm91bmQgdG8gdGhpcy5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0cy5vblVwZGF0ZV0gLSBBIGZ1bmN0aW9uIHRoYXQgcnVucyBhZnRlciBlYWNoIGV4ZWN1dGlvbiBvZiB0aGUgc2Vjb25kIGV2ZW50cy4gUmVjZWl2ZXMgdGhlIGZpcmVkIGV2ZW50IG9iamVjdCBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyLiBUaGUgdGVzdCBjYXNlIChVSVRlc3QpIGlzIGJvdW5kIHRvIHRoaXMuXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gW29wdHMub25Db21wbGV0ZV0gLSBBIGZ1bmN0aW9uIHRoYXQgcnVucyBhZnRlciB0aGUgdGhpcmQgZXZlbnRzIGFyZSBmaXJlZC4gUmVjZWl2ZXMgdGhlIGZpcmVkIGV2ZW50IG9iamVjdCBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyLiBUaGUgdGVzdCBjYXNlIChVSVRlc3QpIGlzIGJvdW5kIHRvIHRoaXMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5kb3VibGVDYWxsYmFja3M9ZmFsc2VdIC0gVGhlIGNhbGxiYWNrcyBvblN0YXJ0LCBvblVwZGF0ZSBhbmQgb25Db21wbGV0ZSB3aWxsIGJlIGZpcmVkIG9ubHkgZm9yIG9uZSBmaW5nZXIuIElmIHNldCB0byB0cnVlLCB0aGUgZXZlbnRzIHdpbGwgYmUgZmlyZWQgZm9yIGJvdGggZmluZ2Vycy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZGlzdGFuY2U9MTAwXSAtIFRoZSBkaXN0YW5jZSBpbiBwaXhlbHMsIGhvdyBmYXIgdGhlIHR3byBcImZpbmdlcnNcIiBzaG91bGQgbW92ZSBhcGFydC4gSWYgdG8gb3IgYmV6aWVyIHNwZWNpZmllZCwgZGlzdGFuY2UgaXMgaWdub3JlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdW118b2JqZWN0W118UElYSS5EaXNwbGF5T2JqZWN0W119IFtvcHRzLnRvXSAtIFRoZSB0YXJnZXRzIG9mIHRoZSBwaW5jaCBwcm9jZXNzLiBUaGUgcG9zaXRpb24gbXVzdCBiZSBhbiBhcnJheSB3aXRoIHR3byBlbnRyaWVzLiBBbiBlbnRyeSBjYW4gYmUgc3BlY2lmaWVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIGFzIGFuIG9iamVjdCB3aXRoIHRoZSB0d28gcHJvcGVydGllcyB4IGFuZCB5LCBvciBhcyBhIFBJWEkuRGlzcGxheSBvYmplY3QuIElmIGJlemllciBpcyBzcGVjaWZpZWQsIHRvIGlzIGlnbm9yZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJbXVtdfG9iamVjdFtdfFBJWEkuRGlzcGxheU9iamVjdFtdfSBbb3B0cy5iZXppZXJdIC0gVGhlIHRhcmdldHMgb2YgdGhlIHBpbmNoIHByb2Nlc3MuIFRoZSBwb3NpdGlvbiBtdXN0IGJlIGFuIGFycmF5IHdpdGggdHdvIGVudHJpZXMuIEFuIGVudHJ5IG1heSBiZSBhbiBhcnJheSBvZiBwb3NpdGlvbnMgb3IgYSBiZXppZXIgb2JqZWN0IChodHRwczovL2dyZWVuc29jay5jb20vZG9jcy9QbHVnaW5zL0JlemllclBsdWdpbikuIEEgcG9zaXRpb24gaW4gdGhlIGFycmF5IG9yIHRoZSB2YWx1ZXMgYXJyYXkgb2YgdGhlIGJlemllciBvYmplY3QgY2FuIGJlIHNwZWNpZmllZCBhcyBhbiBhcnJheSBvZiBudW1iZXJzLCBhcyBhbiBvYmplY3Qgd2l0aCB0aGUgdHdvIHByb3BlcnRpZXMgeCBhbmQgeSwgb3IgYXMgYSBQSVhJLkRpc3BsYXkgb2JqZWN0LiBJZiBiZXppZXIgaXMgc3BlY2lmaWVkLCB0byBpcyBpZ25vcmVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5kdXJhdGlvbj0xXSAtIFRoZSBkdXJhdGlvbiBvZiB0aGUgcGFuIGFuaW1hdGlvbiBpbiBzZWNvbmRzLCBzZWUgaHR0cHM6Ly9ncmVlbnNvY2suY29tL2RvY3MvVHdlZW5MaXRlL2R1cmF0aW9uKCkuXG4gICAgICogQHBhcmFtIHtFYXNlfSBbb3B0cy5lYXNlPVBvd2VyMC5lYXNlTm9uZV0gLSBUaGUgZWFzaW5nIG9mIHRoZSBwYW4gYW5pbWF0aW9uLCBzZWUgaHR0cHM6Ly9ncmVlbnNvY2suY29tL2RvY3MvRWFzaW5nLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IFtvcHRzLmV2ZW50VHlwZXM9Wydwb2ludGVyZG93bicsICdwb2ludGVybW92ZScsICdwb2ludGVydXAnXV0gLSBUaGUgZXZlbnQgdHlwZXMgdG8gdXNlLiBJZiBubyB0eXBlcyBhcmUgc3BlY2lmaWVkLCB0aGUgZXZlbnQgdHlwZXMgc3BlY2lmaWVkIGluIHRoZSBVSVRlc3QgY29uc3RydWN0b3IgYXJlIHVzZWQgKG9yIGF1dG8gaWYgbm90IHNwZWNpZmllZCkuXG4gICAgICogQHBhcmFtIHtXaW5kb3d8RnJhbWV9IFtvcHRzLmNvbnRleHQ9d2luZG93XSAtIFRoZSBjb250ZXh0IHdpdGhpbiB3aGljaCB0aGUgb3B0aW9uYWxseSBzcGVjaWZpZWQgZWxlbWVudCBzZWxlY3RvciBzaG91bGQgYmUgZXhlY3V0ZWQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5idWJibGVzPXRydWVdIC0gVGhlIEV2ZW50IHByb3BlcnR5IGJ1YmJsZXMgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGV2ZW50IGJ1YmJsZXMgdXAgdGhyb3VnaCB0aGUgRE9NIG9yIG5vdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmNhbmNlbGFibGU9dHJ1ZV0gLSBFdmVudHMnIGNhbmNlbGFibGUgcHJvcGVydHkgaW5kaWNhdGVzIGlmIHRoZSBldmVudCBjYW4gYmUgY2FuY2VsZWQsIGFuZCB0aGVyZWZvcmUgcHJldmVudGVkIGFzIGlmIHRoZSBldmVudCBuZXZlciBoYXBwZW5lZC4gSWYgdGhlIGV2ZW50IGlzIG5vdCBjYW5jZWxhYmxlLCB0aGVuIGl0cyBjYW5jZWxhYmxlIHByb3BlcnR5IHdpbGwgYmUgZmFsc2UgYW5kIHRoZSBldmVudCBsaXN0ZW5lciBjYW5ub3Qgc3RvcCB0aGUgZXZlbnQgZnJvbSBvY2N1cnJpbmcuXG4gICAgICovXG4gICAgcGluY2goZWxlbWVudCwgcG9zaXRpb24sIHRpbWVsaW5lUG9zaXRpb24sIG9wdHMgPSB7fSkge1xuXG4gICAgICAgIC8vIGFyZ3VtZW50c1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIFtwb3NpdGlvbiwgdGltZWxpbmVQb3NpdGlvbiwgb3B0c10gPSB0aGlzLnJlb3JkZXJBcmd1bWVudHMoYXJndW1lbnRzKVxuICAgICAgICB0aGlzLl90aW1lbGluZVBvc2l0aW9ucy5wdXNoKHRpbWVsaW5lUG9zaXRpb24pXG5cbiAgICAgICAgLy8gZGVidWdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmRlYnVnKSBjb25zb2xlLmxvZygndGFwIHBhcmFtcycsIHtlbGVtZW50LCBwb3NpdGlvbiwgdGltZWxpbmVQb3NpdGlvbiwgb3B0c30pXG5cbiAgICAgICAgLy8gb3B0c1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBvblN0YXJ0OiBudWxsLFxuICAgICAgICAgICAgb25VcGRhdGU6IG51bGwsXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiBudWxsLFxuICAgICAgICAgICAgZG91YmxlQ2FsbGJhY2tzOiBmYWxzZSxcbiAgICAgICAgICAgIGR1cmF0aW9uOiAxLFxuICAgICAgICAgICAgZGlzdGFuY2U6IDEwMCxcbiAgICAgICAgICAgIHRvOiBudWxsLFxuICAgICAgICAgICAgYmV6aWVyOiBudWxsLFxuICAgICAgICAgICAgZWFzZTogUG93ZXIwLmVhc2VOb25lLFxuICAgICAgICAgICAgZXZlbnRUeXBlczogdGhpcy5yZXNvbHZlRXZlbnRzKFsnZG93bicsICdtb3ZlJywgJ3VwJ10pLFxuICAgICAgICAgICAgY29udGV4dDogd2luZG93LFxuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICAvLyB0aW1lbGluZVxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmFkZENhbGxiYWNrKHBvc2l0aW9uID0+IHtcblxuICAgICAgICAgICAgLy8gZWxlbWVudFxuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgY29uc3QgZWxlbSA9IFV0aWwuZXh0cmFjdEVsZW1lbnQob3B0cy5jb250ZXh0LCBlbGVtZW50KVxuXG4gICAgICAgICAgICAvLyBmcm9tXG4gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICBsZXQgZnJvbTEgPSBudWxsXG4gICAgICAgICAgICBsZXQgZnJvbTIgPSBudWxsXG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHBvc2l0aW9uKSAmJiAhVXRpbC5pc051bWJlcihwb3NpdGlvblswXSkpIHtcbiAgICAgICAgICAgICAgICBmcm9tMSA9IFV0aWwuZXh0cmFjdFBvc2l0aW9uKHBvc2l0aW9uWzBdKVxuICAgICAgICAgICAgICAgIGZyb20yID0gVXRpbC5leHRyYWN0UG9zaXRpb24ocG9zaXRpb25bMV0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZyb20xID0gVXRpbC5leHRyYWN0UG9zaXRpb24ocG9zaXRpb24pXG4gICAgICAgICAgICAgICAgZnJvbTIgPSB7eDogZnJvbTEueCwgeTogZnJvbTEueX1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdG9cbiAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgIGxldCBnc09wdHMxID0ge31cbiAgICAgICAgICAgIGxldCBnc09wdHMyID0ge31cblxuICAgICAgICAgICAgaWYgKG9wdHMudG8gfHwgb3B0cy5iZXppZXIpIHtcbiAgICAgICAgICAgICAgICBbZ3NPcHRzMSwgZ3NPcHRzMl0gPSBVdGlsLmV4dHJhY3RNdWx0aVRvKG9wdHMpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlID0gb3B0cy5kaXN0YW5jZSAhPSBudWxsID8gb3B0cy5kaXN0YW5jZSA6IDEwMFxuICAgICAgICAgICAgICAgIGdzT3B0czEueCA9IGZyb20xLnggLSBkaXN0YW5jZSAvIDJcbiAgICAgICAgICAgICAgICBnc09wdHMxLnkgPSBmcm9tMS55XG4gICAgICAgICAgICAgICAgZ3NPcHRzMi54ID0gZnJvbTIueCArIGRpc3RhbmNlIC8gMlxuICAgICAgICAgICAgICAgIGdzT3B0czIueSA9IGZyb20yLnlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gcG9pbnRlcnNcbiAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgIGNvbnN0IHBvaW50ZXJzID0gbmV3IE1hcCgpXG4gICAgICAgICAgICBwb2ludGVycy5zZXQoMCwge2VsZW1lbnQ6IGZyb20xLCBnc09wdHM6IGdzT3B0czF9KVxuICAgICAgICAgICAgcG9pbnRlcnMuc2V0KDEsIHtlbGVtZW50OiBmcm9tMiwgZ3NPcHRzOiBnc09wdHMyfSlcblxuICAgICAgICAgICAgLy8gbG9vcFxuICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgcG9pbnRlcnMuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuXG4gICAgICAgICAgICAgICAgLy8gZnJvbVxuICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICBjb25zdCBmcm9tID0gdmFsdWUuZWxlbWVudFxuXG4gICAgICAgICAgICAgICAgLy8gZXZlbnQgb3B0c1xuICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICBjb25zdCBldmVudE9wdHMgPSB7YnViYmxlczogb3B0cy5idWJibGVzLCBjYW5jZWxhYmxlOiBvcHRzLmNhbmNlbGFibGUsIHBvaW50ZXJJZDoga2V5LCBpc1ByaW1hcnk6IGtleSA9PT0gMH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGdzT3B0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgZWFzZTogb3B0cy5lYXNlLFxuICAgICAgICAgICAgICAgICAgICBvblN0YXJ0OiAoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgZGlzcGF0Y2ggZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gRXZlbnQuY3JlYXRlKGVsZW0sIGZyb20sIG9wdHMuZXZlbnRUeXBlc1swXSwgZXZlbnRPcHRzKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kZWJ1ZykgY29uc29sZS5sb2coJ2Rpc3BhdGNoIGV2ZW50JywgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmRpc3BhdGNoRXZlbnQoZXZlbnQpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9uU3RhcnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uU3RhcnQgJiYgKG9wdHMuZG91YmxlQ2FsbGJhY2tzIHx8IGtleSA9PT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRzLm9uU3RhcnQuY2FsbCh0aGlzLCBldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgb25VcGRhdGU6ICgpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIGFuZCBkaXNwYXRjaCBldmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBFdmVudC5jcmVhdGUoZWxlbSwgZnJvbSwgb3B0cy5ldmVudFR5cGVzWzFdLCBldmVudE9wdHMpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRzLmRlYnVnKSBjb25zb2xlLmxvZygnZGlzcGF0Y2ggZXZlbnQnLCBldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uZGlzcGF0Y2hFdmVudChldmVudClcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25VcGRhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uVXBkYXRlICYmIChvcHRzLmRvdWJsZUNhbGxiYWNrcyB8fCBrZXkgPT09IDApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0cy5vblVwZGF0ZS5jYWxsKHRoaXMsIGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBvbkNvbXBsZXRlOiAoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgZGlzcGF0Y2ggZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gRXZlbnQuY3JlYXRlKGVsZW0sIGZyb20sIG9wdHMuZXZlbnRUeXBlc1syXSwgZXZlbnRPcHRzKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kZWJ1ZykgY29uc29sZS5sb2coJ2Rpc3BhdGNoIGV2ZW50JywgZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmRpc3BhdGNoRXZlbnQoZXZlbnQpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9uQ29tcGxldGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLm9uQ29tcGxldGUgJiYgKG9wdHMuZG91YmxlQ2FsbGJhY2tzIHx8IGtleSA9PT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRzLm9uQ29tcGxldGUuY2FsbCh0aGlzLCBldmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHRvXG4gICAgICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oZ3NPcHRzLCB2YWx1ZS5nc09wdHMpXG5cbiAgICAgICAgICAgICAgICAvLyBkcmFnIGFuaW1hdGlvblxuICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgICAgICAgICBUd2Vlbk1heC50byhmcm9tLCBvcHRzLmR1cmF0aW9uLCBnc09wdHMpXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0sIHRpbWVsaW5lUG9zaXRpb24sIFtwb3NpdGlvbl0pXG4gICAgICAgIFxuICAgICAgICB0aGlzLl9hY3Rpb25zKytcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8vIC8qKlxuICAgIC8vICAqIEFkZHMgYSB0YXAgZXZlbnQgdG8gdGhlIHRpbWVsaW5lLlxuICAgIC8vICAqXG4gICAgLy8gICogQHJldHVybiB7VUlUZXN0fSBBIHJlZmVyZW5jZSB0byB0aGUgdWl0ZXN0IGZvciBjaGFpbmluZy5cbiAgICAvLyAgKi9cbiAgICAvLyByb3RhdGUoKSB7XG4gICAgLy8gICAgIHJldHVybiB0aGlzXG4gICAgLy8gfVxuXG4gICAgLy8gLyoqXG4gICAgLy8gICogQWRkcyBhIHRhcCBldmVudCB0byB0aGUgdGltZWxpbmUuXG4gICAgLy8gICpcbiAgICAvLyAgKiBAcmV0dXJuIHtVSVRlc3R9IEEgcmVmZXJlbmNlIHRvIHRoZSB1aXRlc3QgZm9yIGNoYWluaW5nLlxuICAgIC8vICAqL1xuICAgIC8vIHN3aXBlKCkge1xuICAgIC8vICAgICByZXR1cm4gdGhpc1xuICAgIC8vIH1cblxuICAgIC8vIC8qKlxuICAgIC8vICAqIEFkZHMgYSB0YXAgZXZlbnQgdG8gdGhlIHRpbWVsaW5lLlxuICAgIC8vICAqXG4gICAgLy8gICogQHJldHVybiB7VUlUZXN0fSBBIHJlZmVyZW5jZSB0byB0aGUgdWl0ZXN0IGZvciBjaGFpbmluZy5cbiAgICAvLyAgKi9cbiAgICAvLyBwcmVzcygpIHtcbiAgICAvLyAgICAgcmV0dXJuIHRoaXNcbiAgICAvLyB9XG5cbiAgICAvLyAvKipcbiAgICAvLyAgKiBBZGRzIGEgdGFwIGV2ZW50IHRvIHRoZSB0aW1lbGluZS5cbiAgICAvLyAgKlxuICAgIC8vICAqIEByZXR1cm4ge1VJVGVzdH0gQSByZWZlcmVuY2UgdG8gdGhlIHVpdGVzdCBmb3IgY2hhaW5pbmcuXG4gICAgLy8gICovXG4gICAgLy8gZXZlbnQoKSB7XG4gICAgLy8gICAgIHJldHVybiB0aGlzXG4gICAgLy8gfVxuXG4gICAgLyoqXG4gICAgICogU29ydHMgdGhlIHBhcmFtZXRlcnMgc28gdGhhdCB0aGUgc2Vjb25kLCB0aGlyZCwgYW5kIGZvdXJ0aCBwYXJhbWV0ZXJzIGNhbiBiZSBvcHRpb25hbCAoYW5kIHBvc3NpYmx5IHNsaXAgZm9yd2FyZCkuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2FyZ3VtZW50c30gcGFyYW1zIC0gVGhlIGFyZ3VtZW50cyB3aGljaCB3ZXJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge2FycmF5fSAtIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHBvc2l0aW9uLCB0aGUgdGltZWxpbmVQb3NpdGlvbiBhbmQgdGhlIG9wdHMgb2JqZWN0LlxuICAgICAqL1xuICAgIHJlb3JkZXJBcmd1bWVudHMocGFyYW1zKSB7XG5cbiAgICAgICAgLy8gZmlyc3QgcGFyYW1ldGVyXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHBhcmFtc1swXVxuXG4gICAgICAgIC8vIG90aGVyIHBhcmFtZXRlclxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGxldCBwb3NpdGlvbiA9IG51bGxcbiAgICAgICAgbGV0IHRpbWVsaW5lUG9zaXRpb24gPSBudWxsXG4gICAgICAgIGxldCBvcHRzID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgLy8gc2Vjb25kIHBhcmFtZXRlclxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmIChVdGlsLmlzTnVtYmVyKHBhcmFtc1sxXSkpIHtcbiAgICAgICAgICAgIHRpbWVsaW5lUG9zaXRpb24gPSBwYXJhbXNbMV1cbiAgICAgICAgfSBlbHNlIGlmIChVdGlsLmlzT2JqZWN0KHBhcmFtc1sxXSkgJiYgIVV0aWwuaXNQaXhpRGlzcGxheU9iamVjdChwYXJhbXNbMV0pICYmIChwYXJhbXNbMV0ueCA9PSBudWxsIHx8IHBhcmFtc1sxXS55ID09IG51bGwpKSB7XG4gICAgICAgICAgICBvcHRzID0gcGFyYW1zWzFdXG4gICAgICAgIH0gZWxzZSBpZiAocGFyYW1zWzFdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gcGFyYW1zWzFdXG4gICAgICAgIH1cblxuICAgICAgICAvLyB0aGlyZCBwYXJhbWV0ZXJcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAoVXRpbC5pc051bWJlcihwYXJhbXNbMl0pKSB7XG4gICAgICAgICAgICB0aW1lbGluZVBvc2l0aW9uID0gcGFyYW1zWzJdXG4gICAgICAgIH0gZWxzZSBpZiAoVXRpbC5pc09iamVjdChwYXJhbXNbMl0pKSB7XG4gICAgICAgICAgICBvcHRzID0gcGFyYW1zWzJdXG4gICAgICAgIH1cblxuICAgICAgICAvLyBmb3VydGggcGFyYW1ldGVyXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKFV0aWwuaXNPYmplY3QocGFyYW1zWzNdKSkge1xuICAgICAgICAgICAgb3B0cyA9IHBhcmFtc1szXVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZGVmYXVsdHNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAocG9zaXRpb24gPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIHdpbGwgbGF0ZXIgYmUgZmlsbGVkLi4uXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGltZWxpbmVQb3NpdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kZWZhdWx0SW50ZXJ2YWwgPT09IG51bGwgJiYgdGhpcy5fYWN0aW9ucyA+IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGV4ZWN1dGlvbiB0aW1lIHdhcyBzcGVjaWZpZWQgZm9yIHRoaXMgYWN0aW9uLCBhbmQgYSBkZWZhdWx0IGludGVydmFsIHdhcyBub3Qgc2V0IGluIHRoZSBjbGFzcyBjb25zdHJ1Y3RvciEnKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGltZWxpbmVQb3NpdGlvbiA9IE1hdGgubWF4KC4uLnRoaXMuX3RpbWVsaW5lUG9zaXRpb25zKSArICh0aGlzLm9wdHMuZGVmYXVsdEludGVydmFsIHx8IDEpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgb3B0cyA9IHt9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW3Bvc2l0aW9uLCB0aW1lbGluZVBvc2l0aW9uLCBvcHRzXVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGV2ZW50IHR5cGUgc2hvcnRjdXRzIHRvIHJlYWwgZXZlbnQgbmFtZXMuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBldmVudHMgLSBBbiBhcnJheSBvZiBldmVudCB0eXBlcy5cbiAgICAgKi9cbiAgICByZXNvbHZlRXZlbnRzKGV2ZW50cykge1xuICAgICAgICBcbiAgICAgICAgY29uc3QgZGF0YSA9IFtdXG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5ldmVudFR5cGUgPT09ICdwb2ludGVyJykge1xuICAgICAgICAgICAgZXZlbnRzLmZvckVhY2goaXQgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpdCA9PT0gJ2Rvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHVzaCgncG9pbnRlcmRvd24nKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXQgPT09ICdtb3ZlJykge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLnB1c2goJ3BvaW50ZXJtb3ZlJylcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ID09PSAndXAnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHVzaCgncG9pbnRlcnVwJylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMub3B0cy5ldmVudFR5cGUgPT09ICd0b3VjaCcpIHtcbiAgICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKGl0ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXQgPT09ICdkb3duJykge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLnB1c2goJ3RvdWNoc3RhcnQnKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXQgPT09ICdtb3ZlJykge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLnB1c2goJ3RvdWNobW92ZScpXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpdCA9PT0gJ3VwJykge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLnB1c2goJ3RvdWNoZW5kJylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXZlbnRzLmZvckVhY2goaXQgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpdCA9PT0gJ2Rvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHVzaCgnbW91c2Vkb3duJylcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ID09PSAnbW92ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKCdtb3VzZW1vdmUnKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXQgPT09ICd1cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKCdtb3VzZXVwJylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGFcbiAgICB9XG59XG5cbi8qKlxuICogSGVscGVyIGNsYXNzLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDaGVja3MgaWYgYSB0aGluZyBpcyBhIG51bWJlci5cbiAqIGNvbnN0IG51bSA9IFV0aWwuaXNOdW1iZXIoMjApXG4gKlxuICogQHByaXZhdGVcbiAqIEBpZ25vcmVcbiAqIEBjbGFzc1xuICovXG5jbGFzcyBVdGlsIHtcblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSBlbGVtZW50IGZyb20gYSBzcGVjaWZpYyBjb250ZXh0LlxuICAgICAqIFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge1dpbmRvd3xGcmFtZX0gY29udGV4dCAtIFRoZSBjb250ZXh0IHdpdGhpbiB3aGljaCB0aGUgb3B0aW9uYWxseSBzcGVjaWZpZWQgZWxlbWVudCBzZWxlY3RvciBzaG91bGQgYmUgZXhlY3V0ZWQuXG4gICAgICogQHJldHVybiB7SFRNTEVsZW1lbnR8c3RyaW5nfSBlbGVtZW50IC0gVGhlIEhUTUwgZWxlbWVudCBvbiB3aGljaCB0aGUgZXZlbnQgaXMgdG8gYmUgZXhlY3V0ZWQsIGUuZy4gYnV0dG9uLCBkb2N1bWVudCwgaDIsIGNhbnZhcywgZXRjLiBvciBhbiBzZWxlY3RvciBzdHJpbmcuIElmIGEgc2VsZWN0b3IgaGFzIGJlZW4gc3BlY2lmaWVkLCBpdCBpcyBldmFsdWF0ZWQgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBldmVudCBpcyBjYWxsZWQgdXNpbmcgdGhlIHF1ZXJ5U2VsZWN0b3IgbWV0aG9kLlxuICAgICAqL1xuICAgIHN0YXRpYyBleHRyYWN0RWxlbWVudChjb250ZXh0LCBlbGVtZW50KSB7XG5cbiAgICAgICAgY29uc3QgY29udCA9IFV0aWwuaXNGcmFtZShjb250ZXh0KSA/IGNvbnRleHQuY29udGVudERvY3VtZW50IDogY29udGV4dC5kb2N1bWVudFxuICAgICAgICBjb25zdCBlbGVtID0gVXRpbC5pc1N0cmluZyhlbGVtZW50KSA/IGNvbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KSA6IGVsZW1lbnRcblxuICAgICAgICByZXR1cm4gZWxlbVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc2Vjb25kIHBhcmFtZXRlci5cbiAgICAgKiBcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG9iamVjdCAtIFNvbWV0aGluZyB3ZXJlIHRoZSBjb29yZHMgc2hvdWxkIGJlIGV4dHJhY3RlZC5cbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IC0gUmV0dXJucyBhbiBvYmplY3Qgd2l0aCB0aGUga2V5cyB4IGFuZCB5LlxuICAgICAqL1xuICAgIHN0YXRpYyBleHRyYWN0UG9zaXRpb24ob2JqZWN0KSB7XG5cbiAgICAgICAgLy8gZXZlbnQgY29vcmRzXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB7eDogMCwgeTogMH1cblxuICAgICAgICAvLyBnZXQgdGhlIHBvc2l0aW9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKCFvYmplY3QpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggPSAwXG4gICAgICAgICAgICBwb3NpdGlvbi55ID0gMFxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZ2V0Qm91bmRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb25zdCBib3VuZHMgPSBvYmplY3QuZ2V0Qm91bmRzKClcbiAgICAgICAgICAgIHBvc2l0aW9uLnggPSBib3VuZHMueCArIGJvdW5kcy53aWR0aCAvIDJcbiAgICAgICAgICAgIHBvc2l0aW9uLnkgPSBib3VuZHMueSArIGJvdW5kcy5oZWlnaHQgLyAyXG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgICAgICAgICBwb3NpdGlvbi54ID0gb2JqZWN0WzBdXG4gICAgICAgICAgICBwb3NpdGlvbi55ID0gb2JqZWN0WzFdXG4gICAgICAgIH0gZWxzZSBpZiAob2JqZWN0LnggIT0gbnVsbCAmJiBvYmplY3QueSAhPSBudWxsKSB7XG4gICAgICAgICAgICBwb3NpdGlvbi54ID0gb2JqZWN0LnhcbiAgICAgICAgICAgIHBvc2l0aW9uLnkgPSBvYmplY3QueVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBvc2l0aW9uXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHRvIG9yIGJlemllciBrZXkuXG4gICAgICogXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRzIC0gQW4gb3B0aW9ucyBvYmplY3Qgd2hlcmUgdG8gb3IgYmV6aWVyIHNob3VsZCBiZSBleHRyYWN0ZWQuXG4gICAgICogQHJldHVybiB7b2JqZWN0fSAtIFJldHVybnMgYW4gb2JqZWN0IHdpdGggdGhlIHRvIG9yIGJlemllciBrZXlzLlxuICAgICAqL1xuICAgIHN0YXRpYyBleHRyYWN0VG8ob3B0cykge1xuXG4gICAgICAgIGNvbnN0IG9iamVjdCA9IHt9XG5cbiAgICAgICAgaWYgKG9wdHMuYmV6aWVyKSB7XG5cbiAgICAgICAgICAgIGxldCBiZXppZXIgPSBudWxsXG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9wdHMuYmV6aWVyKSkge1xuICAgICAgICAgICAgICAgIGJlemllciA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBvcHRzLmJlemllci5tYXAoaXQgPT4gVXRpbC5leHRyYWN0UG9zaXRpb24oaXQpKSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RocnUnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvcHRzLmJlemllci52YWx1ZXMgPSBvcHRzLmJlemllci52YWx1ZXMubWFwKGl0ID0+IFV0aWwuZXh0cmFjdFBvc2l0aW9uKGl0KSlcbiAgICAgICAgICAgICAgICBiZXppZXIgPSBvcHRzLmJlemllclxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBvYmplY3QuYmV6aWVyID0gYmV6aWVyXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0byA9IFV0aWwuZXh0cmFjdFBvc2l0aW9uKG9wdHMudG8pXG4gICAgICAgICAgICBvYmplY3QueCA9IHRvLnhcbiAgICAgICAgICAgIG9iamVjdC55ID0gdG8ueVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9iamVjdFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIG11bHRpcGxlIHRvIG9yIGJlemllciBrZXlzLlxuICAgICAqIFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gb3B0cyAtIEFuIG9wdGlvbnMgb2JqZWN0IHdoZXJlIHRvIG9yIGJlemllciBzaG91bGQgYmUgZXh0cmFjdGVkLlxuICAgICAqIEByZXR1cm4ge29iamVjdFtdfSAtIFJldHVybnMgYW4gYXJyYXkgb2Ygb2JqZWN0cyB3aXRoIHRoZSBrZXlzIHggYW5kIHkuXG4gICAgICovXG4gICAgc3RhdGljIGV4dHJhY3RNdWx0aVRvKG9wdHMpIHtcblxuICAgICAgICBjb25zdCBvYmplY3RzID0gW11cblxuICAgICAgICBpZiAob3B0cy5iZXppZXIpIHtcblxuICAgICAgICAgICAgb3B0cy5iZXppZXIuZm9yRWFjaChpdCA9PiB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYmV6aWVyID0gbnVsbFxuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJlemllciA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlczogaXQubWFwKGl0ID0+IFV0aWwuZXh0cmFjdFBvc2l0aW9uKGl0KSksXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGhydSdcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGl0LnZhbHVlcyA9IGl0LnZhbHVlcy5tYXAoaXQgPT4gVXRpbC5leHRyYWN0UG9zaXRpb24oaXQpKVxuICAgICAgICAgICAgICAgICAgICBiZXppZXIgPSBpdFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9iamVjdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGJlemllclxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIG9wdHMudG8uZm9yRWFjaChpdCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG8gPSBVdGlsLmV4dHJhY3RQb3NpdGlvbihpdClcbiAgICAgICAgICAgICAgICBvYmplY3RzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB4OiB0by54LFxuICAgICAgICAgICAgICAgICAgICB5OiB0by55XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2JqZWN0c1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIHRoaW5nIGlzIGEgc3RyaW5nLlxuICAgICAqIFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0IC0gVGhlIG9iamVjdCB0byB0ZXN0IGZvci5cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSAtIHRydWUgaWYgdGhlIHRoaW5nIGlzIGEgc3RyaW5nLCBvdGhlcndpc2UgZmFsc2UuXG4gICAgICovXG4gICAgc3RhdGljIGlzU3RyaW5nKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ3N0cmluZydcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSB0aGluZyBpcyBhIG51bWJlci5cbiAgICAgKiBcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG9iamVjdCAtIFRoZSBvYmplY3QgdG8gdGVzdCBmb3IuXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn0gLSB0cnVlIGlmIHRoZSB0aGluZyBpcyBhIG51bWJlciwgb3RoZXJ3aXNlIGZhbHNlLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc051bWJlcihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdudW1iZXInXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgdGhpbmcgaXMgYW4gb2JqZWN0LlxuICAgICAqIFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0IC0gVGhlIG9iamVjdCB0byB0ZXN0IGZvci5cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSAtIHRydWUgaWYgdGhlIHRoaW5nIGlzIGFuIG9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc09iamVjdChvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KG9iamVjdClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSB0aGluZyBpcyBhbiBQSVhJLkRpc3BsYXlPYmplY3QuXG4gICAgICogXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvYmplY3QgLSBUaGUgb2JqZWN0IHRvIHRlc3QgZm9yLlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IC0gdHJ1ZSBpZiB0aGUgdGhpbmcgaXMgYSBQSVhJLkRpc3BsYXlPYmplY3QsIG90aGVyd2lzZSBmYWxzZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNQaXhpRGlzcGxheU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmplY3QuZ2V0Qm91bmRzID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBvYmplY3QucmVuZGVyV2ViR0wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG9iamVjdC5zZXRUcmFuc2Zvcm0gPT09ICdmdW5jdGlvbidcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSB0aGluZyBpcyBhIGZyYW1lLlxuICAgICAqIFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0IC0gVGhlIG9iamVjdCB0byB0ZXN0IGZvci5cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSAtIHRydWUgaWYgdGhlIHRoaW5nIGlzIGEgZnJhbWUsIG90aGVyd2lzZSBmYWxzZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNGcmFtZShvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdC5jb250ZW50RG9jdW1lbnQgIT0gbnVsbFxuICAgIH1cbn1cblxuLyoqXG4gKiBFdmVudCBoZWxwZXIgY2xhc3MuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZXMgYW4gZXZlbnQgb2JqZWN0LlxuICogY29uc3QgZXZlbnQgPSBFdmVudC5jcmVhdGUoaDIsIHt4OiA1LCB5OiAxMH0sICd0b3VjaHN0YXJ0JylcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGlnbm9yZVxuICogQGNsYXNzXG4gKi9cbmNsYXNzIEV2ZW50IHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gZXZlbnQgb2JqZWN0LlxuICAgICAqIFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0YXJnZXQgLSBUaGUgZWxlbWVudCBvbiB3aGljaCB0aGUgZXZlbnQgc2hvdWxkIGJlIGV4ZWN1dGVkLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBwb3NpdGlvbiAtIFRoZSBsb2NhbCBwb3NpdGlvbiBvZiB0aGUgZXZlbnQgaW4gcmVsYXRpb24gdG8gdGhlIHRhcmdldC4gVGhlIG9iamVjdCBtdXN0IGhhdmUgdGhlIGtleXMgeCBhbmQgeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBldmVudCwgc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0V2ZW50c1xuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRzIC0gQW4gb3B0aW9ucyBvYmplY3QuIEV2ZXJ5IHBhcmFtdGVyIG9mIHRoZSBldmVudCBvYmplY3QgY2FuIGJlIG92ZXJyaWRkZW4sIHNlZSBlLmcuIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0FQSS9Nb3VzZUV2ZW50IGZvciBhbGwgdGhlIHByb3BlcnRpZXMuXG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZSh0YXJnZXQsIHBvc2l0aW9uID0ge3g6IDAsIHk6IDB9LCB0eXBlID0gJ3BvaW50ZXJ1cCcsIG9wdHMgPSB7fSkge1xuXG4gICAgICAgIGNvbnN0IHJlY3QgPSB0eXBlb2YgdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCA9PT0gJ2Z1bmN0aW9uJyA/IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA6IHt4OiAwLCB5OiAwfVxuXG4gICAgICAgIC8vIEV2ZW50SW5pdFxuICAgICAgICBjb25zdCBldmVudE9wdHMgPSB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNvbXBvc2VkOiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVUlFdmVudEluaXRcbiAgICAgICAgY29uc3QgdWlFdmVudE9wdHMgPSB7XG4gICAgICAgICAgICBkZXRhaWw6IDAsXG4gICAgICAgICAgICB2aWV3OiB3aW5kb3dcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE1vdXNlRXZlbnRcbiAgICAgICAgY29uc3QgbW91c2VFdmVudE9wdHMgPSB7XG4gICAgICAgICAgICBzY3JlZW5YOiB3aW5kb3cuc2NyZWVuWCArIHRhcmdldC5vZmZzZXRMZWZ0ICsgcG9zaXRpb24ueCxcbiAgICAgICAgICAgIHNjcmVlblk6IHdpbmRvdy5zY3JlZW5ZICsgdGFyZ2V0Lm9mZnNldFRvcCArIHBvc2l0aW9uLnksXG4gICAgICAgICAgICBjbGllbnRYOiByZWN0LnggKyBwb3NpdGlvbi54LFxuICAgICAgICAgICAgY2xpZW50WTogcmVjdC55ICsgcG9zaXRpb24ueSxcbiAgICAgICAgICAgIGN0cmxLZXk6IGZhbHNlLFxuICAgICAgICAgICAgc2hpZnRLZXk6IGZhbHNlLFxuICAgICAgICAgICAgYWx0S2V5OiBmYWxzZSxcbiAgICAgICAgICAgIG1ldGFLZXk6IGZhbHNlLFxuICAgICAgICAgICAgYnV0dG9uOiAwLFxuICAgICAgICAgICAgYnV0dG9uczogMSxcbiAgICAgICAgICAgIHJlbGF0ZWRUYXJnZXQ6IG51bGwsXG4gICAgICAgICAgICByZWdpb246IG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRvdWNoRXZlbnRcbiAgICAgICAgY29uc3QgdG91Y2hFdmVudE9wdHMgPSB7XG4gICAgICAgICAgICB0b3VjaGVzOiBbXSxcbiAgICAgICAgICAgIHRhcmdldFRvdWNoZXM6IFtdLFxuICAgICAgICAgICAgY2hhbmdlZFRvdWNoZXM6IFtdLFxuICAgICAgICAgICAgY3RybEtleTogZmFsc2UsXG4gICAgICAgICAgICBzaGlmdEtleTogZmFsc2UsXG4gICAgICAgICAgICBhbHRLZXk6IGZhbHNlLFxuICAgICAgICAgICAgbWV0YUtleTogZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvaW50ZXJFdmVudFxuICAgICAgICBjb25zdCBwb2ludGVyRXZlbnRPcHRzID0ge1xuICAgICAgICAgICAgcG9pbnRlcklkOiAwLFxuICAgICAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgICAgICBoZWlnaHQ6IDEsXG4gICAgICAgICAgICBwcmVzc3VyZTogMCxcbiAgICAgICAgICAgIHRhbmdlbnRpYWxQcmVzc3VyZTogMCxcbiAgICAgICAgICAgIHRpbHRYOiAwLFxuICAgICAgICAgICAgdGlsdFk6IDAsXG4gICAgICAgICAgICB0d2lzdDogMCxcbiAgICAgICAgICAgIHBvaW50ZXJUeXBlOiAndG91Y2gnLFxuICAgICAgICAgICAgaXNQcmltYXJ5OiB0cnVlXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZS5zdGFydHNXaXRoKCdwb2ludGVyJykpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUG9pbnRlckV2ZW50KHR5cGUsIE9iamVjdC5hc3NpZ24oe30sIGV2ZW50T3B0cywgdWlFdmVudE9wdHMsIG1vdXNlRXZlbnRPcHRzLCBwb2ludGVyRXZlbnRPcHRzLCBvcHRzKSlcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3RvdWNoJykpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVG91Y2hFdmVudCh0eXBlLCBPYmplY3QuYXNzaWduKHt9LCBldmVudE9wdHMsIHVpRXZlbnRPcHRzLCB0b3VjaEV2ZW50T3B0cywgb3B0cykpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vdXNlRXZlbnQodHlwZSwgT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRPcHRzLCB1aUV2ZW50T3B0cywgbW91c2VFdmVudE9wdHMsIG9wdHMpKVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IEFwcCBmcm9tICcuL2FwcC5qcydcbmltcG9ydCBEb2N0ZXN0IGZyb20gJy4vZG9jdGVzdC5qcydcbmltcG9ydCBFcnJvcnMgZnJvbSAnLi9lcnJvcnMuanMnXG5pbXBvcnQgRXZlbnRzIGZyb20gJy4vZXZlbnRzLmpzJ1xuaW1wb3J0IHtET01GbGlwLCBET01GbGlwcGFibGUsIENhcmRMb2FkZXIsIFBERkxvYWRlciwgSW1hZ2VMb2FkZXIsIEZyYW1lTG9hZGVyLCBIVE1MTG9hZGVyfSBmcm9tICcuL2ZsaXBwYWJsZS5qcydcbmltcG9ydCBJbmRleCBmcm9tICcuL2luZGV4LmpzJ1xuaW1wb3J0IEludGVyZmFjZSBmcm9tICcuL2ludGVyZmFjZS5qcydcbmltcG9ydCBQb3BwYWJsZSBmcm9tICcuL3BvcHBhYmxlLmpzJ1xuaW1wb3J0IFBvcHVwTWVudSBmcm9tICcuL3BvcHVwbWVudS5qcydcbmltcG9ydCBQb3B1cCBmcm9tICcuL3BvcHVwLmpzJ1xuaW1wb3J0IHtJQXBwfSBmcm9tICcuL2FwcC5qcydcbmltcG9ydCB7Q2FwYWJpbGl0aWVzLCBDYXBhYmlsaXRpZXNUZXN0c30gZnJvbSAnLi9jYXBhYmlsaXRpZXMuanMnXG5pbXBvcnQge0V2ZW50UmVjb3JkZXJ9IGZyb20gJy4vZXZlbnRzLmpzJ1xuaW1wb3J0IHtGcmFtZUNvbnRhaW5lciwgRnJhbWVUYXJnZXR9IGZyb20gJy4vZnJhbWVzLmpzJ1xuaW1wb3J0IHtJbnNwZWN0fSBmcm9tICcuL2luc3BlY3QuanMnXG5pbXBvcnQge1BvaW50TWFwLCBJbnRlcmFjdGlvblBvaW50cywgSW50ZXJhY3Rpb24sIElJbnRlcmFjdGlvblRhcmdldCwgSW50ZXJhY3Rpb25EZWx0YSwgSW50ZXJhY3Rpb25NYXBwZXIsIEludGVyYWN0aW9uRGVsZWdhdGUsIElJbnRlcmFjdGlvbk1hcHBlclRhcmdldH0gZnJvbSAnLi9pbnRlcmFjdGlvbi5qcydcbmltcG9ydCB7UmVzaXplRXZlbnQsIERPTVNjYXR0ZXJDb250YWluZXIsIEFic3RyYWN0U2NhdHRlciwgRE9NU2NhdHRlciwgU2NhdHRlckV2ZW50LCBCYXNlRXZlbnR9IGZyb20gJy4vc2NhdHRlci5qcydcbmltcG9ydCB7Q3ljbGUsIENvbG9ycywgRWxlbWVudHMsIEFuZ2xlLCBEYXRlcywgUG9pbnRzLCBQb2x5Z29uLCBSZWN0LCBTZXRzLCBTdHJpbmdzLCBpc0VtcHR5LCBnZXRJZCwgbGVycCwgZGVib3VuY2UsIHJhbmRvbUludCwgcmFuZG9tRmxvYXR9IGZyb20gJy4vdXRpbHMuanMnXG5pbXBvcnQgVUlUZXN0IGZyb20gJy4vdWl0ZXN0LmpzJ1xuXG4vKiBOZWVkZWQgdG8gZW5zdXJlIHRoYXQgcm9sbHVwLmpzIGluY2x1ZGVzIGNsYXNzIGRlZmluaXRpb25zIGFuZCB0aGUgY2xhc3Nlc1xuYXJlIHZpc2libGUgaW5zaWRlIGRvY3Rlc3RzLlxuKi9cblxud2luZG93LkFic3RyYWN0U2NhdHRlciA9IEFic3RyYWN0U2NhdHRlclxud2luZG93LkFuZ2xlID0gQW5nbGVcbndpbmRvdy5BcHAgPSBBcHBcbndpbmRvdy5CYXNlRXZlbnQgPSBCYXNlRXZlbnRcbndpbmRvdy5DYXBhYmlsaXRpZXMgPSBDYXBhYmlsaXRpZXNcbndpbmRvdy5DYXBhYmlsaXRpZXNUZXN0cyA9IENhcGFiaWxpdGllc1Rlc3RzXG53aW5kb3cuQ29sb3JzID0gQ29sb3JzXG53aW5kb3cuQ3ljbGUgPSBDeWNsZVxuXG53aW5kb3cuRE9NRmxpcCA9IERPTUZsaXBcbndpbmRvdy5ET01GbGlwcGFibGUgPSBET01GbGlwcGFibGVcbndpbmRvdy5DYXJkTG9hZGVyID0gQ2FyZExvYWRlclxud2luZG93LlBERkxvYWRlciA9IFBERkxvYWRlclxud2luZG93LkhUTUxMb2FkZXIgPSBIVE1MTG9hZGVyXG53aW5kb3cuSW1hZ2VMb2FkZXIgPSBJbWFnZUxvYWRlclxud2luZG93LkZyYW1lTG9hZGVyID0gRnJhbWVMb2FkZXJcblxud2luZG93LkRPTVNjYXR0ZXIgPSBET01TY2F0dGVyXG53aW5kb3cuRE9NU2NhdHRlckNvbnRhaW5lciA9IERPTVNjYXR0ZXJDb250YWluZXJcbndpbmRvdy5EYXRlcyA9IERhdGVzXG53aW5kb3cuRG9jdGVzdCA9IERvY3Rlc3RcbndpbmRvdy5FbGVtZW50cyA9IEVsZW1lbnRzXG53aW5kb3cuRXJyb3JzID0gRXJyb3JzXG53aW5kb3cuRXZlbnRSZWNvcmRlciA9IEV2ZW50UmVjb3JkZXJcbndpbmRvdy5FdmVudHMgPSBFdmVudHNcbndpbmRvdy5GcmFtZUNvbnRhaW5lciA9IEZyYW1lQ29udGFpbmVyXG53aW5kb3cuRnJhbWVUYXJnZXQgPSBGcmFtZVRhcmdldFxud2luZG93LklBcHAgPSBJQXBwXG53aW5kb3cuSUludGVyYWN0aW9uTWFwcGVyVGFyZ2V0ID0gSUludGVyYWN0aW9uTWFwcGVyVGFyZ2V0XG53aW5kb3cuSUludGVyYWN0aW9uVGFyZ2V0ID0gSUludGVyYWN0aW9uVGFyZ2V0XG53aW5kb3cuSW5kZXggPSBJbmRleFxud2luZG93Lkluc3BlY3QgPSBJbnNwZWN0XG53aW5kb3cuSW50ZXJhY3Rpb24gPSBJbnRlcmFjdGlvblxud2luZG93LkludGVyYWN0aW9uRGVsZWdhdGUgPSBJbnRlcmFjdGlvbkRlbGVnYXRlXG53aW5kb3cuSW50ZXJhY3Rpb25EZWx0YSA9IEludGVyYWN0aW9uRGVsdGFcbndpbmRvdy5JbnRlcmFjdGlvbk1hcHBlciA9IEludGVyYWN0aW9uTWFwcGVyXG53aW5kb3cuSW50ZXJhY3Rpb25Qb2ludHMgPSBJbnRlcmFjdGlvblBvaW50c1xud2luZG93LkludGVyZmFjZSA9IEludGVyZmFjZVxud2luZG93LlBvaW50TWFwID0gUG9pbnRNYXBcbndpbmRvdy5SZWN0ID0gUmVjdFxud2luZG93LlBvaW50cyA9IFBvaW50c1xud2luZG93LlBvbHlnb24gPSBQb2x5Z29uXG53aW5kb3cuUG9wcGFibGUgPSBQb3BwYWJsZVxud2luZG93LlBvcHVwID0gUG9wdXBcbndpbmRvdy5Qb3B1cE1lbnUgPSBQb3B1cE1lbnVcbndpbmRvdy5SZXNpemVFdmVudCA9IFJlc2l6ZUV2ZW50XG53aW5kb3cuU2NhdHRlckV2ZW50ID0gU2NhdHRlckV2ZW50XG53aW5kb3cuU2V0cyA9IFNldHNcbndpbmRvdy5TdHJpbmdzID0gU3RyaW5nc1xud2luZG93LlVJVGVzdCA9IFVJVGVzdFxud2luZG93LmdldElkID0gZ2V0SWRcbndpbmRvdy5pc0VtcHR5ID0gaXNFbXB0eVxud2luZG93LmxlcnAgPSBsZXJwXG53aW5kb3cuZGVib3VuY2UgPSBkZWJvdW5jZVxud2luZG93LnJhbmRvbUludCA9IHJhbmRvbUludFxud2luZG93LnJhbmRvbUZsb2F0ID0gcmFuZG9tRmxvYXRcbiJdLCJuYW1lcyI6WyJnZXRJZCIsIkVsZW1lbnRzIiwiSW50ZXJhY3Rpb25NYXBwZXIiLCJQb3B1cE1lbnUiXSwibWFwcGluZ3MiOiI7OztJQUFBOztBQUVBLElBQWUsTUFBTSxTQUFTLENBQUM7SUFDL0I7SUFDQTs7SUFFQSxJQUFJLE9BQU8sbUJBQW1CLENBQUMsS0FBSyxFQUFFO0lBQ3RDLFFBQVEsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDO0lBQzNELFFBQVEsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFDO0lBQ3hELFFBQVEsSUFBSSxJQUFJLEdBQUcsSUFBSSxhQUFhLEVBQUU7SUFDdEMsWUFBWSxJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBQztJQUNuRCxZQUFZLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFDO0lBQ2hELFlBQVksSUFBSSxPQUFPLFNBQVMsQ0FBQyxJQUFJLFdBQVc7SUFDaEQsZ0JBQWdCLE9BQU8sVUFBVSxHQUFHLEdBQUc7SUFDdkMsU0FBUztJQUNULFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7O0lBRUwsSUFBSSxPQUFPLGFBQWEsQ0FBQyxLQUFLLEVBQUU7SUFDaEM7SUFDQTtJQUNBLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBQztJQUNuRCxRQUFRLE9BQU8sS0FBSyxJQUFJLElBQUk7SUFDNUIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBLENBQUM7O0lDM0JEO0lBQ0E7SUFDQTtJQUNBOztBQUVBLElBQU8sTUFBTSxJQUFJLFNBQVMsU0FBUyxDQUFDO0lBQ3BDO0lBQ0E7SUFDQTtJQUNBLElBQUksS0FB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QyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDL0MsS0FBSzs7SUFFTCxJQUFJLE9BQU8sSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDdEIsUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDM0QsS0FBSzs7SUFFTCxJQUFJLE9BQU8sYUFBYSxDQUFDLE1BQU0sRUFBRTtJQUNqQyxRQUFRLE9BQU8sSUFBSSxDQUFDLEVBQUUsR0FBRyxNQUFNLEdBQUcsS0FBSztJQUN2QyxLQUFLOztJQUVMLElBQUksT0FBTyxhQUFhLENBQUMsR0FBRyxFQUFFO0lBQzlCLFFBQVEsT0FBTyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHO0lBQ3BDLEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTUMsVUFBUSxDQUFDO0lBQ3RCLElBQUksT0FBTyxRQUFRLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRTtJQUNyQyxRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksTUFBTSxFQUFFO0lBQ2hDLFlBQVksT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFDO0lBQzVDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRTtJQUN2QyxRQUFRLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBQztJQUN2QyxLQUFLOztJQUVMLElBQUksT0FBTyxXQUFXLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRTtJQUMxQyxRQUFRLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBQztJQUMxQyxLQUFLOztJQUVMLElBQUksT0FBTyxXQUFXLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRTtJQUMxQyxRQUFR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TDtJQUNBO0lBQ0E7SUFDQSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7SUFDakIsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDckQsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDcEMsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDcEMsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDdEUsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDdEUsU0FBUztJQUNULEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEdBQUcsQ0FBQyxFQUFFLE1BQU0sR0FBRyxTQUFTLEVBQUUsSUFBSSxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUMzRSxRQUFRLE9BQU8sQ0FBQyxTQUFTLEdBQUU7SUFDM0IsUUFBUSxPQUFPLENBQUMsTUFBTTtJQUN0QixZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QyxZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QyxVQUFTO0lBQ1QsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDckQsWUFBWSxPQUFPLENBQUMsTUFBTTtJQUMxQixnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2hELGdCQUFnQixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEQsY0FBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLE9BQU8sQ0FBQyxTQUFTLEdBQUU7SUFDM0IsUUFBUSxPQUFPLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDckMsUUFBUSxJQUFJLE1BQU0sRUFBRTtJQUNwQixZQUFZLE9BQU8sQ0FBQyxXQUFXLEdBQUcsT0FBTTtJQUN4QyxZQUFZLE9BQU8sQ0FBQyxNQUFNLEdBQUU7SUFDNUIsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLEVBQUU7SUFDbEIsWUFBWSxPQUFPLENBQUMsU0FBUyxHQUFHLEtBQUk7SUFDcEMsWUFBWSxPQUFPLENBQUMsSUFBSSxHQUFFO0lBQzFCLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksY0FBYyxHQUFHO0lBQ3JCLFFBQVEsSUFBSSxNQUFNLEdBQUcsSUFBSSxLQUFLLEdBQUU7SUFDaEMsUUFBUSxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDbkMsWUFBWSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBQztJQUNuRCxTQUFTO0lBQ1QsUUFBUSxPQUFPLE1BQU07SUFDckIsS0FBSzs7SUFFTCxJQUFJLGtCQUFrQixHQUFHO0lBQ3pCLFFBQVEsSUFBSSxNQUFNLEdBQUcsSUFBSSxLQUFLLEdBQUU7SUFDaEMsUUFBUSxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDbkMsWUFBWSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFDO0lBQzlDLFlBQVksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQzVCLFlBQVksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQzVCLFNBQVM7SUFDVCxRQUFRLE9BQU8sTUFBTTtJQUNyQixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxhQUFhLENBQUMsR0FBRyxFQUFFO0lBQ3ZCLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFNO0lBQ3RDLFFBQVEsSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDLEVBQUM7SUFDekIsUUFBUSxJQUFJLEtBQUssR0FBRyxHQUFHLENBQUMsRUFBQzs7SUFFekIsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLEtBQUssR0FBRTtJQUMvQixRQUFRLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUNyRCxZQUFZLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUM7SUFDeEQsU0FBUzs7SUFFVCxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksS0FBSyxHQUFFO0lBQy9CLFFBQVEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQ3JELFlBQVksS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQztJQUN4RCxTQUFTOztJQUVULFFBQVEsSUFBSSxDQUFDO0lBQ2IsWUFBWSxDQUFDLEdBQUcsRUFBQztJQUNqQixRQUFRLElBQUksQ0FBQyxHQUFHLE1BQUs7SUFDckIsUUFBUSxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUU7SUFDdkQsWUFBWTtJQUNaLGdCQUFnQixLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLO0lBQ3BELGdCQUFnQixLQUFLO0lBQ3JCLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLGlCQUFpQixLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLGlCQUFpQixLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLGdCQUFnQixLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3hCO0lBQ0EsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEVBQUM7SUFDdEIsU0FBUztJQUNULFFBQVEsT0FBTyxDQUFDO0lBQ2hCLEtBQUs7O0lBRUwsSUFBSSxjQUFjLENBQUMsS0FBSyxFQUFFO0lBQzFCLFFBQVEsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBQztJQUM5RCxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBQztJQUN2QyxRQUFRLEtBQUssSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtJQUNuQyxZQUFZLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUM7SUFDM0QsU0FBUztJQUNULFFBQVEsT0FBTyxLQUFLO0lBQ3BCLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLGNBQWMsQ0FBQyxLQUFLLEVBQUU7SUFDMUIsUUFBUSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRTtJQUNqQyxRQUFRLElBQUksR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUk7SUFDdkMsUUFBUSxJQUFJLElBQUksRUFBRSxFQUFDO0lBQ25CLFFBQVEsSUFBSSxRQUFRLEdBQUcsS0FBSTtJQUMzQixRQUFRLElBQUksT0FBTyxHQUFHLFNBQVE7O0lBRTlCO0lBQ0EsUUFBUSxLQUFLLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFO0lBQy9EO0lBQ0EsWUFBWSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUU7SUFDM0IsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO0lBQ3RCLG9CQUFvQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUQsb0JBQW9CLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUNwQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7SUFDdEIsb0JBQW9CLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQyxvQkFBb0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQzlELGFBQWEsTUFBTTtJQUNuQixnQkFBZ0IsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDO0lBQ3RFLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDdEUsYUFBYTs7SUFFYjtJQUNBLFlBQVksR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBQztJQUM5RCxZQUFZLElBQUksQ0FBQyxDQUFDLElBQUksSUFBRztJQUN6QixZQUFZLElBQUksQ0FBQyxDQUFDLElBQUksSUFBRzs7SUFFekI7SUFDQSxZQUFZLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBQztJQUMvRSxZQUFZLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDMUQsZ0JBQWdCLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFDO0lBQzNFLGdCQUFnQixJQUFJLEdBQUcsR0FBRyxJQUFJLEVBQUUsSUFBSSxHQUFHLElBQUc7SUFDMUMscUJBQXFCLElBQUksR0FBRyxHQUFHLElBQUksRUFBRSxJQUFJLEdBQUcsSUFBRztJQUMvQyxhQUFhO0lBQ2I7SUFDQSxZQUFZLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFDO0lBQ2pFLFlBQVksSUFBSSxJQUFJLElBQUc7SUFDdkIsWUFBWSxJQUFJLElBQUksSUFBRzs7SUFFdkI7SUFDQSxZQUFZLElBQUksR0FBRyxJQUFJO0lBQ3ZCLGdCQUFnQixLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFDO0lBQ3ZFLFlBQVksS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUMzRCxnQkFBZ0IsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUM7SUFDN0UsZ0JBQWdCLElBQUksR0FBRyxHQUFHLElBQUksRUFBRSxJQUFJLEdBQUcsSUFBRztJQUMxQyxxQkFBcUIsSUFBSSxHQUFHLEdBQUcsSUFBSSxFQUFFLElBQUksR0FBRyxJQUFHO0lBQy9DLGFBQWE7SUFDYjtJQUNBLFlBQVksR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUM7SUFDbkUsWUFBWSxJQUFJLElBQUksSUFBRztJQUN2QixZQUFZLElBQUksSUFBSSxJQUFHOztJQUV2QjtJQUNBLFlBQVksSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUU7SUFDNUMsZ0JBQWdCLE9BQU8sS0FBSztJQUM1QixhQUFhLE1BQU07SUFDbkIsZ0JBQWdCLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSTtJQUMvRCxnQkFBZ0IsSUFBSSxDQUFDLEdBQUcsT0FBTyxFQUFFO0lBQ2pDLG9CQUFvQixPQUFPLEdBQUcsRUFBQztJQUMvQixvQkFBb0IsUUFBUSxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUU7SUFDdkQsaUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixTQUFTOztJQUVUO0lBQ0EsUUFBUSxLQUFLLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFO0lBQ2hFO0lBQ0EsWUFBWSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUU7SUFDM0IsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO0lBQ3RCLG9CQUFvQixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEUsb0JBQW9CLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUNyQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7SUFDdEIsb0JBQW9CLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyQyxvQkFBb0IsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQ2hFLGFBQWEsTUFBTTtJQUNuQixnQkFBZ0IsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDO0lBQ3hFLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDeEUsYUFBYTs7SUFFYjtJQUNBLFlBQVksR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBQztJQUM5RCxZQUFZLElBQUksQ0FBQyxDQUFDLElBQUksSUFBRztJQUN6QixZQUFZLElBQUksQ0FBQyxDQUFDLElBQUksSUFBRzs7SUFFekI7SUFDQSxZQUFZLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBQztJQUMvRSxZQUFZLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDMUQsZ0JBQWdCLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFDO0lBQzNFLGdCQUFnQixJQUFJLEdBQUcsR0FBRyxJQUFJLEVBQUUsSUFBSSxHQUFHLElBQUc7SUFDMUMscUJBQXFCLElBQUksR0FBRyxHQUFHLElBQUksRUFBRSxJQUFJLEdBQUcsSUFBRztJQUMvQyxhQUFhO0lBQ2I7SUFDQSxZQUFZLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFDO0lBQ2pFLFlBQVksSUFBSSxJQUFJLElBQUc7SUFDdkIsWUFBWSxJQUFJLElBQUksSUFBRzs7SUFFdkI7SUFDQSxZQUFZLElBQUksR0FBRyxJQUFJO0lBQ3ZCLGdCQUFnQixLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFDO0lBQ3ZFLFlBQVksS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUMzRCxnQkFBZ0IsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUM7SUFDN0UsZ0JBQWdCLElBQUksR0FBRyxHQUFHLElBQUksRUFBRSxJQUFJLEdBQUcsSUFBRztJQUMxQyxxQkFBcUIsSUFBSSxHQUFHLEdBQUcsSUFBSSxFQUFFLElBQUksR0FBRyxJQUFHO0lBQy9DLGFBQWE7SUFDYjtJQUNBLFlBQVksR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUM7SUFDbkUsWUFBWSxJQUFJLElBQUksSUFBRztJQUN2QixZQUFZLElBQUksSUFBSSxJQUFHOztJQUV2QjtJQUNBLFlBQVksSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUU7SUFDNUMsZ0JBQWdCLE9BQU8sS0FBSztJQUM1QixhQUFhLE1BQU07SUFDbkIsZ0JBQWdCLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSTtJQUMvRCxnQkFBZ0IsSUFBSSxDQUFDLEdBQUcsT0FBTyxFQUFFO0lBQ2pDLG9CQUFvQixPQUFPLEdBQUcsRUFBQztJQUMvQixvQkFBb0IsUUFBUSxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUU7SUFDdkQsaUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sR0FBRyxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtJQUMzRCxLQUFLOztJQUVMLElBQUksT0FBTyxVQUFVLENBQUMsTUFBTSxFQUFFO0lBQzlCLFFBQVEsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLFNBQVMsR0FBRTtJQUM5RCxRQUFRLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEdBQUU7SUFDOUQsUUFBUSxLQUFLLElBQUksQ0FBQyxJQUFJLE1BQU0sRUFBRTtJQUM5QixZQUFZLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUM7SUFDeEMsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFDO0lBQ3hDLFlBQVksR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBQztJQUN4QyxZQUFZLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUM7SUFDeEMsU0FBUztJQUNULFFBQVEsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQzFDLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFDO0lBQ3pDLFFBQVEsS0FBSyxJQUFJLENBQUMsSUFBSSxNQUFNLEVBQUU7SUFDOUIsWUFBWSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxFQUFDO0lBQ3ZDLFNBQVM7SUFDVCxRQUFRLE9BQU8sT0FBTztJQUN0QixLQUFLO0lBQ0wsQ0FBQzs7O0lBR0Q7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNLElBQUksQ0FBQzs7O0lBR2xCO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtJQUNqQyxRQUFRLFFBQVEsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSTtJQUNuQyxZQUFZLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSztJQUN6QyxlQUFlLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDM0QsS0FBSzs7O0lBR0w7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxXQUFXLENBQUMsSUFBSSxFQUFFO0lBQzdCLFFBQVEsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFO0lBQ3ZDLEtBQUs7SUFDTCxDQUFDOztJQUVEOztBQUVBLElBQU8sTUFBTSxPQUFPLENBQUM7O0lBRXJCLElBQUksT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUU7SUFDckMsUUFBUSxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzdELEtBQUs7O0lBRUwsSUFBSSxPQUFPLG9CQUFvQixDQUFDLEdBQUcsRUFBRTtJQUNyQyxRQUFRLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDN0QsS0FBSzs7SUFFTCxJQUFJLE9BQU8sbUJBQW1CLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyxHQUFHLEVBQUU7SUFDakQsUUFBUSxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNoRixLQUFLOztJQUVMLElBQUksT0FBTyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsS0FBSyxHQUFHLEdBQUcsRUFBRTtJQUNqRCxRQUFRLE9BQU8sR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ2hGLEtBQUs7O0lBRUwsQ0FBQzs7SUNoOEJEO0FBQ0EsQUFLQTtJQUNBOztJQUVBO0lBQ0E7O0FBRUEsSUFBTyxNQUFNLGtCQUFrQixTQUFTLFNBQVMsQ0FBQztJQUNsRCxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7SUFDbkIsUUFBUSxPQUFPLE9BQU8sSUFBSTtJQUMxQixLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsR0FBRztJQUNuQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLEdBQUc7SUFDbEMsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxHQUFHOztJQUVqQyxJQUFJLFlBQVksQ0FBQyxLQUFLLEVBQUUsR0FBRztJQUMzQixDQUFDOztBQUVELElBQU8sTUFBTSx3QkFBd0IsU0FBUyxTQUFTLENBQUM7SUFDeEQsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO0lBQ25CLFFBQVEsT0FBTyxPQUFPLElBQUk7SUFDMUIsS0FBSzs7SUFFTCxJQUFJLFVBQVUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtJQUNyQyxRQUFRLE9BQU8sa0JBQWtCO0lBQ2pDLEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxRQUFRLFNBQVMsUUFBUSxDQUFDO0lBQ3ZDO0lBQ0E7SUFDQTtJQUNBLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUU7SUFDN0IsUUFBUSxLQUFLLEdBQUU7SUFDZixRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksTUFBTSxFQUFFO0lBQ2hDLFlBQVksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFDO0lBQ3RDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksUUFBUSxHQUFHO0lBQ2YsUUFBUSxJQUFJLE1BQU0sR0FBRyxHQUFFO0lBQ3ZCLFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDckMsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUNyQyxZQUFZLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUM5RCxTQUFTO0lBQ1QsUUFBUSxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQztJQUNyQyxRQUFRLE9BQU8sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNwQyxLQUFLOztJQUVMLElBQUksS0FBSyxHQUFHO0lBQ1osUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLFFBQVEsR0FBRTtJQUNuQyxRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFO0lBQ3JDLFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDckMsWUFBWSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUM7SUFDdkQsU0FBUztJQUNULFFBQVEsT0FBTyxNQUFNO0lBQ3JCLEtBQUs7O0lBRUwsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO0lBQ2pCLFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDckMsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUNqQyxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsRUFBRTtJQUNsRCxnQkFBZ0IsT0FBTyxHQUFHO0lBQzFCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLFFBQVEsR0FBRztJQUNmLFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDckMsWUFBWSxPQUFPLEdBQUc7SUFDdEIsU0FBUztJQUNULFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7O0lBRUwsSUFBSSxLQUFLLEdBQUc7SUFDWixRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFO0lBQ3JDLFlBQVksT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUNoQyxTQUFTO0lBQ1QsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLFNBQVMsR0FBRztJQUNoQixRQUFRLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUU7SUFDNUIsWUFBWSxPQUFPLElBQUk7SUFDdkIsU0FBUztJQUNULFFBQVEsSUFBSSxLQUFLLEdBQUcsR0FBRTtJQUN0QixRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFO0lBQ3JDLFlBQVksSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDakMsWUFBWSxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUc7SUFDdkIsWUFBWSxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRTtJQUN2QyxnQkFBZ0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUM7SUFDbkMsZ0JBQWdCLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBQztJQUN6QixnQkFBZ0IsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQztJQUNsQyxhQUFhO0lBQ2IsU0FBUztJQUNULFFBQVEsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUs7SUFDMUMsWUFBWSxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1RSxTQUFTLEVBQUM7SUFDVixRQUFRLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN4QixLQUFLOztJQUVMLElBQUksSUFBSSxHQUFHO0lBQ1gsUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxFQUFFO0lBQzVCLFlBQVksT0FBTyxJQUFJO0lBQ3ZCLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxHQUFHLEdBQUc7SUFDbkIsWUFBWSxDQUFDLEdBQUcsSUFBRztJQUNuQixRQUFRLEtBQUssSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFO0lBQ3JDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDO0lBQ3BCLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDO0lBQ3BCLFNBQVM7SUFDVCxRQUFRLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFO0lBQ3JELEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxnQkFBZ0IsQ0FBQztJQUM5QixJQUFJLFdBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO0lBQzNDLFFBQVEsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFDO0lBQ2xCLFFBQVEsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFDO0lBQ2xCLFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ3hCLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFNO0lBQzVCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQzFCLEtBQUs7O0lBRUwsSUFBSSxRQUFRLEdBQUc7SUFDZixRQUFRLElBQUksTUFBTSxHQUFHLEdBQUU7SUFDdkIsUUFBUSxLQUFLLElBQUksR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7SUFDM0MsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFDO0lBQ2pDLFlBQVksSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFO0lBQ2hDLGdCQUFnQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDbEUsYUFBYSxNQUFNO0lBQ25CLGdCQUFnQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUM7SUFDOUMsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFDO0lBQ3JDLFFBQVEsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDNUMsS0FBSztJQUNMLENBQUM7O0FBRUQsSUFBTyxNQUFNLGlCQUFpQixDQUFDO0lBQy9CLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUU7SUFDL0IsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDNUIsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksUUFBUSxHQUFFO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsR0FBRTtJQUN0QyxRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxRQUFRLEdBQUU7SUFDbkMsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksUUFBUSxHQUFFO0lBQ25DLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUNuQyxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEdBQUcsRUFBRTtJQUNmLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQzNDLFFBQVEsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQzdDLFFBQVEsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUM7SUFDakQsS0FBSzs7SUFFTCxJQUFJLElBQUksR0FBRztJQUNYLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUU7SUFDekMsUUFBUSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksR0FBRTtJQUMzQyxRQUFRLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDO0lBQ2pELEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0lBQ3BCLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQztJQUNoRSxRQUFRLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRTtJQUMzQyxZQUFZLEtBQUssSUFBSSxJQUFJLENBQUMsR0FBRTtJQUM1QixTQUFTO0lBQ1QsUUFBUSxPQUFPLEtBQUs7SUFDcEIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLEtBQUssR0FBRztJQUNaLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFJO0lBQ3JDLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFJO0lBQ3RDLFFBQVEsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxLQUFLLEVBQUU7SUFDMUM7SUFDQSxZQUFZLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFFOztJQUVsRCxZQUFZLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLEVBQUM7SUFDL0IsWUFBWSxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsQ0FBQyxFQUFDOztJQUUvQixZQUFZLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUM7SUFDOUMsWUFBWSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFDOztJQUU5QztJQUNBOztJQUVBLFlBQVksSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQzVDLFlBQVksSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQzVDLFlBQVksSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQ3hDO0lBQ0E7SUFDQTtJQUNBLFlBQVksSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQzNDLFlBQVksSUFBSSxJQUFJLEdBQUcsSUFBRztJQUMxQixZQUFZLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBQztJQUNuRCxZQUFZLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBQztJQUNuRCxZQUFZLElBQUksU0FBUyxJQUFJLENBQUMsSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFO0lBQ2xELGdCQUFnQixJQUFJLEdBQUcsU0FBUyxHQUFHLFVBQVM7SUFDNUMsYUFBYTtJQUNiLFlBQVksSUFBSSxZQUFZLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQ25ELFlBQVksSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQ3BELFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsYUFBYSxFQUFDO0lBQ25FLFlBQVksT0FBTyxJQUFJLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztJQUMxRSxTQUFTLE1BQU0sSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFO0lBQ3BHO0lBQ0EsWUFBWSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRTtJQUM5QyxZQUFZLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxHQUFFO0lBQ2hELFlBQVksSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFDO0lBQzFELFlBQVksT0FBTyxJQUFJLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQztJQUM1RSxTQUFTO0lBQ1QsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO0lBQ3hCLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBQztJQUNwQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDbEMsUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsRUFBQztJQUNuRCxLQUFLOztJQUVMLElBQUksTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUU7SUFDdkI7SUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDcEMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDbEMsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ3RDLFlBQVksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBQztJQUN6QyxZQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUM7SUFDdkQsWUFBWSxPQUFPLElBQUk7SUFDdkIsU0FBUztJQUNULFFBQVEsT0FBTyxLQUFLO0lBQ3BCLEtBQUs7O0lBRUwsSUFBSSxjQUFjLEdBQUc7SUFDckIsUUFBUSxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDN0MsWUFBWSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUM7SUFDekQsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRTtJQUNyQixRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDbkMsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDcEMsWUFBWSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDckMsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ3RDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUU7SUFDdkIsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDaEMsUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDakMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDOUIsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDbkMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDOUIsS0FBSzs7SUFFTCxJQUFJLFVBQVUsR0FBRztJQUNqQixRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQztJQUNyQyxLQUFLOztJQUVMLElBQUksbUJBQW1CLEdBQUc7SUFDMUIsUUFBUSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDO0lBQzlELEtBQUs7O0lBRUwsSUFBSSxLQUFLLENBQUMsR0FBRyxFQUFFO0lBQ2YsUUFBUSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztJQUNyQyxLQUFLOztJQUVMLElBQUksV0FBVyxDQUFDLEdBQUcsRUFBRTtJQUNyQixRQUFRLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDO0lBQzNDLEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsR0FBRyxFQUFFO0lBQ3JCLFFBQVEsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUM7SUFDM0MsS0FBSztJQUNMLENBQUM7O0FBRUQsSUFBTyxNQUFNLFdBQVcsU0FBUyxpQkFBaUIsQ0FBQztJQUNuRCxJQUFJLFdBQVcsQ0FBQyxXQUFXLEdBQUcsRUFBRSxFQUFFLFdBQVcsR0FBRyxLQUFLLEVBQUUsYUFBYSxHQUFHLEtBQUssRUFBRTtJQUM5RSxRQUFRLEtBQUssR0FBRTtJQUNmLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUNsQyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEdBQUU7SUFDckMsUUFBUSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksR0FBRyxHQUFFO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxjQUFhO0lBQzFDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUNoQyxRQUFRLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxHQUFHLEdBQUU7SUFDeEMsS0FBSzs7SUFFTCxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO0lBQ3JCLFFBQVEsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQzlCLFFBQVEsS0FBSyxJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxFQUFFO0lBQzFELFlBQVksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ25DLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksU0FBUyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFDO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUM7SUFDckUsS0FBSzs7SUFFTCxJQUFJLFlBQVksQ0FBQyxHQUFHLEVBQUU7SUFDdEIsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDMUMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDaEM7SUFDQSxRQUFRLElBQUksTUFBTSxHQUFHLEtBQUk7SUFDekIsUUFBUSxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUU7SUFDN0MsWUFBWSxJQUFJLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFDOUIsZ0JBQWdCLE1BQU0sR0FBRyxNQUFLO0lBQzlCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxJQUFJLE1BQU0sRUFBRTtJQUNwQixZQUFZLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBQztJQUMvQyxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO0lBQ3ZCLFFBQVEsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUM7SUFDOUIsS0FBSzs7SUFFTCxJQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRTtJQUNqRDtJQUNBO0lBQ0EsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUM5QixRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksTUFBTSxFQUFFO0lBQ2hDLFlBQVksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUN2QyxnQkFBZ0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQ2xELGdCQUFnQixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0lBQ3RELG9CQUFvQixJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUM7SUFDdEUsb0JBQW9CLEtBQUssSUFBSSxNQUFNLElBQUksT0FBTyxFQUFFO0lBQ2hELHdCQUF3QixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFDO0lBQ25ELHdCQUF3QixJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUNyRCx3QkFBd0IsSUFBSSxNQUFNLEdBQUcsV0FBVyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUM7SUFDL0Qsd0JBQXdCLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBQztJQUM1RCxxQkFBcUI7SUFDckIsb0JBQW9CLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBQztJQUNuRCxpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLE9BQU8sTUFBTTtJQUNyQixLQUFLOztJQUVMLElBQUksV0FBVyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUU7SUFDNUIsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0lBQ3JDLFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQy9DLFlBQVksSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUM7SUFDNUMsU0FBUztJQUNULGFBQWE7SUFDYixZQUFZLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUM7SUFDdEMsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBQztJQUN6QyxRQUFRLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUM7SUFDdEQsS0FBSzs7SUFFTCxJQUFJLGFBQWEsQ0FBQyxHQUFHLEVBQUU7SUFDdkIsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDbEMsUUFBUSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDckMsUUFBUSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDdEMsS0FBSzs7SUFFTCxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUU7SUFDZixRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUN2QyxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUN2QyxRQUFRO0lBQ1IsWUFBWSxLQUFLO0lBQ2pCLFlBQVksS0FBSztJQUNqQixZQUFZLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXO0lBQzVELFVBQVU7SUFDVixZQUFZLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUM3QyxZQUFZLElBQUksUUFBUSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGNBQWE7SUFDdEUsWUFBWSxJQUFJLFFBQVEsRUFBRTtJQUMxQixnQkFBZ0IsT0FBTyxLQUFLO0lBQzVCLGFBQWE7SUFDYixZQUFZLE9BQU8sSUFBSTtJQUN2QixTQUFTO0lBQ1QsUUFBUSxPQUFPLEtBQUs7SUFDcEIsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxHQUFHLEVBQUU7SUFDckIsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDdkMsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUNwRSxZQUFZLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFDO0lBQ25DLFNBQVM7SUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDeEMsWUFBWSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDaEQsWUFBWSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUU7SUFDaEUsZ0JBQWdCLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFDO0lBQ3ZDLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFO0lBQy9HO0lBQ0EsWUFBWSxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBQztJQUNuQyxTQUFTO0lBQ1QsUUFBUSxJQUFJLE1BQU0sR0FBRyxNQUFLO0lBQzFCLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0lBQzdCO0lBQ0EsWUFBWSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDeEMsWUFBWSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBQztJQUNqRCxTQUFTO0lBQ1QsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUM7SUFDbkMsU0FBUztJQUNUO0lBQ0EsUUFBUSxPQUFPLE1BQU07SUFDckIsS0FBSzs7SUFFTCxJQUFJLFFBQVEsR0FBRztJQUNmLFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFO0lBQzNDLFlBQVksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE9BQU8sSUFBSTtJQUM1QyxTQUFTO0lBQ1QsUUFBUSxPQUFPLEtBQUs7SUFDcEIsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxHQUFHLEVBQUU7SUFDckIsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDdkMsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDdkMsUUFBUTtJQUNSLFlBQVksS0FBSztJQUNqQixZQUFZLEtBQUs7SUFDakIsWUFBWSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVztJQUM1RCxVQUFVO0lBQ1YsWUFBWSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDN0MsWUFBWSxJQUFJLFFBQVEsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxjQUFhO0lBQ3RFLFlBQVksSUFBSSxRQUFRLEVBQUU7SUFDMUIsZ0JBQWdCLE9BQU8sSUFBSTtJQUMzQixhQUFhO0lBQ2IsWUFBWSxPQUFPLEtBQUs7SUFDeEIsU0FBUztJQUNULFFBQVEsT0FBTyxLQUFLO0lBQ3BCLEtBQUs7O0lBRUwsSUFBSSxjQUFjLEdBQUc7SUFDckIsUUFBUSxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDM0MsWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxJQUFJO0lBQ2xELFNBQVM7SUFDVCxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMLElBQUksUUFBUSxDQUFDLEdBQUcsRUFBRTtJQUNsQixRQUFRLE9BQU8sR0FBRyxLQUFLLFFBQVE7SUFDL0IsS0FBSztJQUNMLENBQUM7O0lBRUQ7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNLG1CQUFtQixDQUFDO0lBQ2pDO0lBQ0E7O0lBRUE7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLFdBQVc7SUFDZixRQUFRLE9BQU87SUFDZixRQUFRLE1BQU07SUFDZCxRQUFRLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxFQUFFLFVBQVUsR0FBRyxJQUFJLEVBQUUsb0JBQW9CLEdBQUcsSUFBSSxFQUFFLGlCQUFpQixHQUFHLElBQUksRUFBRSxLQUFLLEdBQUcsS0FBSyxFQUFFLEdBQUcsRUFBRTtJQUNsSSxNQUFNO0lBQ04sUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxHQUFFO0lBQzVDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGlCQUFpQixJQUFJLFFBQU87SUFDN0QsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDNUIsUUFBUSxJQUFJLENBQUMsVUFBVSxHQUFHLFdBQVU7SUFDcEMsUUFBUSxJQUFJLENBQUMsb0JBQW9CLEdBQUcscUJBQW9CO0lBQ3hELFFBQVEsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGtCQUFpQjtJQUNsRCxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsR0FBRTtJQUMvQixLQUFLOztJQUVMLElBQUksZ0JBQWdCLEdBQUc7SUFDdkIsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7SUFDeEIsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLG1CQUFtQjtJQUNoRSxnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXO0lBQ3ZDLGNBQWE7SUFDYixZQUFZLElBQUksS0FBSyxJQUFJLElBQUksRUFBRTtJQUMvQixnQkFBZ0IsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsR0FBRyxLQUFLLENBQUM7SUFDeEUsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxxQkFBcUIsR0FBRTtJQUNwQyxRQUFRLElBQUksQ0FBQywwQkFBMEIsR0FBRTtJQUN6QyxLQUFLOztJQUVMLElBQUksSUFBSSxlQUFlLEdBQUc7SUFDMUIsUUFBUSxPQUFPLGtCQUFrQjtJQUNqQyxLQUFLOztJQUVMLElBQUkscUJBQXFCLEdBQUc7SUFDNUIsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNsQyxRQUFRLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQ3hDLFFBQVEsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO0lBQ2pDLFlBQVksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxZQUFZLEVBQUM7SUFDNUUsWUFBWSxPQUFPLENBQUMsZ0JBQWdCO0lBQ3BDLGdCQUFnQixhQUFhO0lBQzdCLGdCQUFnQixDQUFDLElBQUk7SUFDckIsb0JBQW9CLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsU0FBUyxFQUFDO0lBQzNFLG9CQUFvQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDekMsd0JBQXdCLElBQUksSUFBSSxDQUFDLG9CQUFvQixFQUFFO0lBQ3ZELDRCQUE0QixJQUFJO0lBQ2hDLGdDQUFnQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBQztJQUN0RSw2QkFBNkIsQ0FBQyxPQUFPLENBQUMsRUFBRSxHQUFHO0lBQzNDLHlCQUF5QjtJQUN6Qix3QkFBd0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUM7SUFDdkMscUJBQXFCO0lBQ3JCLGlCQUFpQjtJQUNqQixnQkFBZ0IsVUFBVTtJQUMxQixjQUFhO0lBQ2IsWUFBWSxPQUFPLENBQUMsZ0JBQWdCO0lBQ3BDLGdCQUFnQixhQUFhO0lBQzdCLGdCQUFnQixDQUFDLElBQUk7SUFDckIsb0JBQW9CLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsU0FBUyxFQUFDOztJQUUzRSxvQkFBb0I7SUFDcEIsd0JBQXdCLENBQUMsQ0FBQyxXQUFXLElBQUksT0FBTztJQUNoRCx5QkFBeUIsQ0FBQyxDQUFDLFdBQVcsSUFBSSxPQUFPLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzRSxzQkFBc0I7SUFDdEI7SUFDQSx3QkFBd0IsSUFBSSxJQUFJLENBQUMsS0FBSztJQUN0Qyw0QkFBNEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLENBQUMsU0FBUyxFQUFDO0lBQzVFLHdCQUF3QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQztJQUN0QyxxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGdCQUFnQixVQUFVO0lBQzFCLGNBQWE7SUFDYixZQUFZLE9BQU8sQ0FBQyxnQkFBZ0I7SUFDcEMsZ0JBQWdCLFdBQVc7SUFDM0IsZ0JBQWdCLENBQUMsSUFBSTtJQUNyQixvQkFBb0IsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFDO0lBQzVELG9CQUFvQixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQztJQUNqQyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7SUFDbkQsd0JBQXdCLElBQUk7SUFDNUIsNEJBQTRCLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFDO0lBQ3RFLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUc7SUFDdkMscUJBQXFCO0lBQ3JCLGlCQUFpQjtJQUNqQixnQkFBZ0IsVUFBVTtJQUMxQixjQUFhO0lBQ2IsWUFBWSxPQUFPLENBQUMsZ0JBQWdCO0lBQ3BDLGdCQUFnQixlQUFlO0lBQy9CLGdCQUFnQixDQUFDLElBQUk7SUFDckIsb0JBQW9CLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBQztJQUNoRSxvQkFBb0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUM7SUFDakMsb0JBQW9CLElBQUksSUFBSSxDQUFDLG9CQUFvQjtJQUNqRCx3QkFBd0IsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUM7SUFDbEUsaUJBQWlCO0lBQ2pCLGdCQUFnQixVQUFVO0lBQzFCLGNBQWE7O0lBRWIsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFO0lBQzVDLGdCQUFnQixPQUFPLENBQUMsZ0JBQWdCO0lBQ3hDLG9CQUFvQixjQUFjO0lBQ2xDLG9CQUFvQixDQUFDLElBQUk7SUFDekIsd0JBQXdCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBQztJQUNuRSx3QkFBd0IsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQztJQUM5RCxxQkFBcUI7SUFDckIsb0JBQW9CLFVBQVU7SUFDOUIsa0JBQWlCO0lBQ2pCLGFBQWE7O0lBRWIsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFO0lBQzVDLGdCQUFnQixPQUFPLENBQUMsZ0JBQWdCO0lBQ3hDLG9CQUFvQixZQUFZO0lBQ2hDLG9CQUFvQixDQUFDLElBQUk7SUFDekIsd0JBQXdCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBQztJQUNqRSx3QkFBd0IsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQztJQUM5RCxxQkFBcUI7SUFDckIsb0JBQW9CLFVBQVU7SUFDOUIsa0JBQWlCO0lBQ2pCLGFBQWE7O0lBRWIsWUFBWSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtJQUN4QyxnQkFBZ0IsTUFBTSxDQUFDLGdCQUFnQjtJQUN2QyxvQkFBb0IsWUFBWTtJQUNoQyxvQkFBb0IsQ0FBQyxJQUFJO0lBQ3pCLHdCQUF3QixJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksT0FBTyxFQUFFO0lBQ2pELDRCQUE0QixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQztJQUN6Qyx5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLG9CQUFvQixVQUFVLEVBQUM7SUFDL0IsYUFBYTs7SUFFYixTQUFTLE1BQU0sSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO0lBQ3RDLFlBQVksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFDO0lBQ3BELFlBQVksT0FBTyxDQUFDLGdCQUFnQjtJQUNwQyxnQkFBZ0IsWUFBWTtJQUM1QixnQkFBZ0IsQ0FBQyxJQUFJO0lBQ3JCLG9CQUFvQixJQUFJLElBQUksQ0FBQyxLQUFLO0lBQ2xDLHdCQUF3QixPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQ3RFLG9CQUFvQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDekMsd0JBQXdCLEtBQUssSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDLGNBQWMsRUFBRTtJQUM1RCw0QkFBNEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUM7SUFDL0MseUJBQXlCO0lBQ3pCLHFCQUFxQjtJQUNyQixpQkFBaUI7SUFDakIsZ0JBQWdCLFVBQVU7SUFDMUIsY0FBYTtJQUNiLFlBQVksT0FBTyxDQUFDLGdCQUFnQjtJQUNwQyxnQkFBZ0IsV0FBVztJQUMzQixnQkFBZ0IsQ0FBQyxJQUFJO0lBQ3JCLG9CQUFvQixJQUFJLElBQUksQ0FBQyxLQUFLO0lBQ2xDLHdCQUF3QixPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUN4RSxvQkFBb0IsS0FBSyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsY0FBYyxFQUFFO0lBQ3hELHdCQUF3QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBQztJQUMxQyxxQkFBcUI7SUFDckIsb0JBQW9CLEtBQUssSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDLGFBQWEsRUFBRTtJQUN2RCx3QkFBd0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUM7SUFDMUMscUJBQXFCO0lBQ3JCLGlCQUFpQjtJQUNqQixnQkFBZ0IsVUFBVTtJQUMxQixjQUFhO0lBQ2IsWUFBWSxPQUFPLENBQUMsZ0JBQWdCO0lBQ3BDLGdCQUFnQixVQUFVO0lBQzFCLGdCQUFnQixDQUFDLElBQUk7SUFDckIsb0JBQW9CLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQ2hGLG9CQUFvQixLQUFLLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxjQUFjLEVBQUU7SUFDeEQsd0JBQXdCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDO0lBQ3pDLHFCQUFxQjtJQUNyQixpQkFBaUI7SUFDakIsZ0JBQWdCLFVBQVU7SUFDMUIsY0FBYTtJQUNiLFlBQVksT0FBTyxDQUFDLGdCQUFnQjtJQUNwQyxnQkFBZ0IsYUFBYTtJQUM3QixnQkFBZ0IsQ0FBQyxJQUFJO0lBQ3JCLG9CQUFvQixJQUFJLElBQUksQ0FBQyxLQUFLO0lBQ2xDLHdCQUF3QixPQUFPLENBQUMsR0FBRztJQUNuQyw0QkFBNEIsYUFBYTtJQUN6Qyw0QkFBNEIsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNO0lBQ2xELDRCQUE0QixDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU07SUFDbkQsMEJBQXlCO0lBQ3pCLG9CQUFvQixLQUFLLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxjQUFjLEVBQUU7SUFDeEQsd0JBQXdCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDO0lBQ3pDLHFCQUFxQjtJQUNyQixpQkFBaUI7SUFDakIsZ0JBQWdCLFVBQVU7SUFDMUIsY0FBYTtJQUNiLFNBQVMsTUFBTTtJQUNmLFlBQVksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFDOztJQUVwRCxZQUFZLE9BQU8sQ0FBQyxnQkFBZ0I7SUFDcEMsZ0JBQWdCLFdBQVc7SUFDM0IsZ0JBQWdCLENBQUMsSUFBSTtJQUNyQixvQkFBb0IsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBQztJQUMvRCxvQkFBb0IsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQ3pDLHdCQUF3QixJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBQztJQUN2QyxxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGdCQUFnQixVQUFVO0lBQzFCLGNBQWE7SUFDYixZQUFZLE9BQU8sQ0FBQyxnQkFBZ0I7SUFDcEMsZ0JBQWdCLFdBQVc7SUFDM0IsZ0JBQWdCLENBQUMsSUFBSTtJQUNyQjtJQUNBO0lBQ0E7O0lBRUEsb0JBQW9CLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtJQUMvQyx3QkFBd0IsSUFBSSxJQUFJLENBQUMsS0FBSztJQUN0Qyw0QkFBNEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFDO0lBQ3ZELHdCQUF3QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQztJQUN0QyxxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGdCQUFnQixVQUFVO0lBQzFCLGNBQWE7SUFDYixZQUFZLE9BQU8sQ0FBQyxnQkFBZ0I7SUFDcEMsZ0JBQWdCLFNBQVM7SUFDekIsZ0JBQWdCLENBQUMsSUFBSTtJQUNyQixvQkFBb0IsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBQztJQUM3RCxvQkFBb0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUM7SUFDakMsaUJBQWlCO0lBQ2pCLGdCQUFnQixJQUFJO0lBQ3BCLGNBQWE7O0lBRWIsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFO0lBQzVDLGdCQUFnQixPQUFPLENBQUMsZ0JBQWdCO0lBQ3hDLG9CQUFvQixVQUFVO0lBQzlCLG9CQUFvQixDQUFDLElBQUk7SUFDekIsd0JBQXdCLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxPQUFPLEVBQUU7SUFDakQsNEJBQTRCLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFDO0lBQ3pDLDRCQUE0QixPQUFPLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxFQUFDO0lBQ3ZGLHlCQUF5Qjs7SUFFekIscUJBQXFCO0lBQ3JCLG9CQUFvQixVQUFVO0lBQzlCLGtCQUFpQjtJQUNqQixhQUFhO0lBQ2IsWUFBWSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtJQUN4QyxnQkFBZ0IsTUFBTSxDQUFDLGdCQUFnQjtJQUN2QyxvQkFBb0IsVUFBVTtJQUM5QixvQkFBb0IsQ0FBQyxJQUFJO0lBQ3pCLHdCQUF3QixJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksT0FBTyxFQUFFO0lBQ2pELDRCQUE0QixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQztJQUN6Qyx5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLG9CQUFvQixVQUFVLEVBQUM7SUFDL0IsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDaEMsUUFBUSxJQUFJLE1BQU0sSUFBSSxLQUFLLEVBQUUsT0FBTyxJQUFJO0lBQ3hDLFFBQVEsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLFdBQVU7SUFDbkMsUUFBUSxPQUFPLElBQUksSUFBSSxJQUFJLEVBQUU7SUFDN0IsWUFBWSxJQUFJLElBQUksSUFBSSxNQUFNLEVBQUU7SUFDaEMsZ0JBQWdCLE9BQU8sSUFBSTtJQUMzQixhQUFhO0lBQ2IsWUFBWSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVU7SUFDbEMsU0FBUztJQUNULFFBQVEsT0FBTyxLQUFLO0lBQ3BCLEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFO0lBQ3ZCLFFBQVEsSUFBSSxNQUFNLEdBQUcsR0FBRTtJQUN2QixRQUFRLEtBQUssSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRTtJQUNoRCxZQUFZLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBQztJQUNqRCxTQUFTO0lBQ1QsUUFBUSxPQUFPLE1BQU07SUFDckIsS0FBSzs7SUFFTCxJQUFJLDBCQUEwQixHQUFHO0lBQ2pDLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQjtJQUMvQyxZQUFZLFlBQVk7SUFDeEIsWUFBWSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDeEMsWUFBWSxJQUFJO0lBQ2hCLFVBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0I7SUFDL0MsWUFBWSxnQkFBZ0I7SUFDNUIsWUFBWSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDeEMsWUFBWSxJQUFJO0lBQ2hCLFVBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLEtBQUssRUFBRTtJQUN4QixRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTtJQUM3RCxZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBQztJQUMzQyxTQUFTLEFBRUE7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRTtJQUNuQixRQUFRLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFDO0lBQ2hELFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUM7SUFDL0MsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBQztJQUNwRCxLQUFLOztJQUVMLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRTtJQUNsQixRQUFRLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBQztJQUN2RCxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFDO0lBQ2hELFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUM7SUFDbkQsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsR0FBRTtJQUN6QyxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtJQUNqQixRQUFRLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO0lBQ2xFLFFBQVEsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFDO0lBQzdDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUM7SUFDbEQsUUFBUSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQztJQUNoRCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO0lBQ25CLFFBQVEsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQ3RDLFlBQVksT0FBTyxLQUFLO0lBQ3hCLFNBQVM7SUFDVCxRQUFRLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBQztJQUNqRCxRQUFRLE9BQU8sUUFBUTtJQUN2QixLQUFLOztJQUVMLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRTtJQUN2QixRQUFRLE9BQU8sRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRTtJQUNyRCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLEtBQUssRUFBRSxhQUFhLEdBQUcsS0FBSyxFQUFFO0lBQy9DO0lBQ0EsUUFBUSxJQUFJLE1BQU0sR0FBRyxHQUFFO0lBQ3ZCLFFBQVEsUUFBUSxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUk7SUFDdEMsWUFBWSxLQUFLLFlBQVk7SUFDN0IsZ0JBQWdCLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLE1BQUs7SUFDMUQsZ0JBQWdCLElBQUksT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBQztJQUN0RSxnQkFBZ0IsS0FBSztJQUNyQixZQUFZLEtBQUssY0FBYztJQUMvQixnQkFBZ0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBQztJQUM1RSxnQkFBZ0IsS0FBSztJQUNyQixZQUFZLEtBQUssT0FBTztJQUN4QixnQkFBZ0IsSUFBSSxFQUFFO0lBQ3RCLG9CQUFvQixLQUFLLENBQUMsU0FBUyxLQUFLLFFBQVE7SUFDaEQsMEJBQTBCLFFBQVE7SUFDbEMsMEJBQTBCLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxHQUFFO0lBQ3JELGdCQUFnQixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUM7SUFDcEQsZ0JBQWdCLEtBQUs7SUFDckI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLFlBQVk7SUFDWixnQkFBZ0IsS0FBSztJQUNyQixTQUFTO0lBQ1QsUUFBUSxPQUFPLE1BQU07SUFDckIsS0FBSzs7SUFFTCxJQUFJLGtCQUFrQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFO0lBQzFDO0lBQ0EsS0FBSzs7SUFFTCxJQUFJLGdCQUFnQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFO0lBQ3hDO0lBQ0EsS0FBSzs7SUFFTCxJQUFJLG1CQUFtQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUc7O0lBRTlDLElBQUksZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRTtJQUN2QyxRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksU0FBUyxFQUFFO0lBQ25DLFlBQVksSUFBSSxLQUFLLEdBQUcsU0FBUyxDQUFDLEdBQUcsRUFBQztJQUN0QyxZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDaEQsWUFBWSxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDdEQsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFO0lBQ3hDLFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxTQUFTLEVBQUU7SUFDbkMsWUFBWSxJQUFJLEtBQUssR0FBRyxTQUFTLENBQUMsR0FBRyxFQUFDO0lBQ3RDLFlBQVksSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBQztJQUM3RCxZQUFZLElBQUksT0FBTyxFQUFFO0lBQ3pCLGdCQUFnQixPQUFPLENBQUMsSUFBSSxDQUFDLG1EQUFtRCxFQUFDO0lBQ2pGLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDMUQsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUU7SUFDakMsUUFBUSxLQUFLLElBQUksR0FBRyxJQUFJLEtBQUssRUFBRTtJQUMvQixZQUFZLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUM7SUFDbEMsWUFBWSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQzdDLFlBQVksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ3BELFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksaUJBQWlCLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRTtJQUNwQyxRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksS0FBSyxFQUFFO0lBQy9CLFlBQVksSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBQztJQUNsQyxZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDL0MsWUFBWSxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUM7SUFDdkQsU0FBUztJQUNULEtBQUs7SUFDTCxDQUFDO0lBQ0Q7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNQyxtQkFBaUIsU0FBUyxtQkFBbUIsQ0FBQzs7SUFFM0QsSUFBSSxXQUFXO0lBQ2YsUUFBUSxPQUFPO0lBQ2YsUUFBUSxNQUFNO0lBQ2QsUUFBUSxFQUFFLFdBQVcsR0FBRyxFQUFFLEVBQUUsYUFBYSxHQUFHLEtBQUssRUFBRSxVQUFVLEdBQUcsSUFBSSxFQUFFLGlCQUFpQixHQUFHLElBQUksRUFBRSxHQUFHLEVBQUU7SUFDckcsTUFBTTtJQUNOLFFBQVEsS0FBSyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxFQUFDO0lBQzdGLEtBQUs7O0lBRUwsSUFBSSxJQUFJLGVBQWUsR0FBRztJQUMxQixRQUFRLE9BQU8sd0JBQXdCO0lBQ3ZDLEtBQUs7O0lBRUwsSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxHQUFHLElBQUksRUFBRTtJQUM5QyxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRTtJQUM1QyxZQUFZLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDO0lBQ2pFLFNBQVM7SUFDVCxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMLElBQUksa0JBQWtCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUU7SUFDMUMsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO0lBQ3BDLFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBQztJQUN0RCxZQUFZLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFDO0lBQ25FLFlBQVksSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFO0lBQy9CLGdCQUFnQixJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO0lBQ3RELGFBQWE7SUFDYixTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLFlBQVksQ0FBQyxLQUFLLEVBQUU7SUFDeEIsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7SUFDakMsWUFBWSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO0lBQ3hDLGdCQUFnQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBQztJQUNuRCxnQkFBZ0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBQztJQUMxRCxnQkFBZ0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUM7SUFDdkUsZ0JBQWdCLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLENBQUMsWUFBWSxFQUFFO0lBQ3pELG9CQUFvQixLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBQztJQUM3QyxvQkFBb0IsTUFBTTtJQUMxQixpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTtJQUMxQyxnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFDO0lBQy9DLGFBQWEsQUFFQTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRTtJQUNuQixRQUFRLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFDO0lBQ2hELFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUM7SUFDL0MsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWM7SUFDcEQsWUFBWSxTQUFTO0lBQ3JCLFlBQVksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDO0lBQ2hDLFlBQVksSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDOUMsVUFBUztJQUNULFFBQVEsS0FBSyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUM1RCxZQUFZLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBQztJQUM5QyxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUU7SUFDbEIsUUFBUSxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUM7SUFDdkQsUUFBUSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQztJQUNoRCxRQUFRLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYztJQUNwRCxZQUFZLFNBQVM7SUFDckIsWUFBWSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUM7SUFDbkMsWUFBWSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztJQUM5QyxVQUFTO0lBQ1QsUUFBUSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxFQUFFO0lBQzVELFlBQVksTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFDO0lBQzdDLFlBQVksV0FBVyxDQUFDLGNBQWMsR0FBRTtJQUN4QyxTQUFTO0lBQ1QsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsR0FBRTtJQUN6QyxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtJQUNqQixRQUFRLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO0lBQ2xFLFFBQVEsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFDO0lBQzdDLFFBQVEsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjO0lBQ3BELFlBQVksU0FBUztJQUNyQixZQUFZLENBQUMsT0FBTyxDQUFDO0lBQ3JCLFlBQVksSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDOUMsVUFBUztJQUNULFFBQVEsS0FBSyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUM1RCxZQUFZLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBQztJQUM1QyxTQUFTO0lBQ1QsUUFBUSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQztJQUNoRCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUU7SUFDOUMsUUFBUSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUU7O0lBRWpDLFNBQVMsRUFBRSxJQUFJLEVBQUM7O0lBRWhCLFFBQVEsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUU7SUFDM0MsWUFBWSxPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFDO0lBQ2pELFlBQVksT0FBTyxJQUFJO0lBQ3ZCLFNBQVM7O0lBRVQ7SUFDQSxRQUFRLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksRUFBQztJQUNoRSxRQUFRLElBQUksUUFBUSxZQUFZLFFBQVEsSUFBSSxRQUFRLFlBQVksY0FBYyxFQUFFO0lBQ2hGLFlBQVksUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQzNDLFNBQVM7SUFDVCxRQUFRLFFBQVEsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLFFBQVEsR0FBRyxDQUFDLFFBQVEsRUFBQzs7SUFFbEUsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTs7SUFFL0MsWUFBWSxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFFOztJQUUvQztJQUNBLFlBQVksTUFBTSxTQUFTLEdBQUcsa0RBQWtELENBQUMsSUFBSSxDQUFDLElBQUksRUFBQzs7SUFFM0Y7SUFDQSxZQUFZLElBQUksU0FBUyxFQUFFOztJQUUzQixnQkFBZ0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O0lBRTFEOztJQUVBLG9CQUFvQixJQUFJLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFDOztJQUU5RCxvQkFBb0IsSUFBSSxNQUFNLENBQUMsV0FBVyxLQUFLLFdBQVcsRUFBRTtJQUM1RCx3QkFBd0IsTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUM7SUFDcEQscUJBQXFCOztJQUVyQjtJQUNBLG9CQUFvQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUU7SUFDaEQsd0JBQXdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLGFBQWEsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFDO0lBQ3ZHLHFCQUFxQixNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUN6RCx3QkFBd0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBQztJQUN0RixxQkFBcUIsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDekQsd0JBQXdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBQztJQUNyRCxxQkFBcUIsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUU7SUFDMUQsd0JBQXdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUM7SUFDdkYscUJBQXFCLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ3pELHdCQUF3QixNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxhQUFhLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBQztJQUN6RyxxQkFBcUIsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUU7SUFDdkQsd0JBQXdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBQztJQUNuRCxxQkFBcUI7O0lBRXJCLG9CQUFvQixNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLElBQUk7SUFDN0Msd0JBQXdCLEVBQUUsQ0FBQyxLQUFLLEVBQUM7SUFDakMscUJBQXFCLEVBQUM7SUFDdEIsaUJBQWlCOztJQUVqQixhQUFhLE1BQU07O0lBRW5CLGdCQUFnQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUMxRCxvQkFBb0IsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssSUFBSTtJQUMxRCx3QkFBd0IsRUFBRSxDQUFDLEtBQUssRUFBQztJQUNqQyxxQkFBcUIsRUFBQztJQUN0QixpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFNBQVM7O0lBRVQsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSztJQUNMLENBQUM7O0lBRUQsTUFBTSxDQUFDLGlCQUFpQixHQUFHQTs7SUMvakMzQjtJQUNBO0FBQ0EsSUFBTyxNQUFNLFlBQVksQ0FBQzs7SUFFMUI7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLFNBQVMsR0FBRztJQUMzQixRQUFRLE9BQU8sU0FBUyxDQUFDLFNBQVMsSUFBSSxlQUFlO0lBQ3JELEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLFdBQVcsUUFBUSxHQUFHO0lBQzFCLFFBQVEsUUFBUSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNqRCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLEtBQUssR0FBRztJQUN2QixRQUFRLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVE7SUFDakYsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLFFBQVEsR0FBRztJQUMxQixRQUFRLE9BQU8sU0FBUyxDQUFDLE1BQU0sSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUMsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQ3ZJLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksV0FBVyxVQUFVLEdBQUc7SUFDNUIsUUFBUSxPQUFPLE9BQU8sT0FBTyxJQUFJLFdBQVcsSUFBSSxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxLQUFLLFNBQVM7SUFDM0csS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQSxJQUFJLFdBQVcsZ0JBQWdCLEdBQUc7SUFDbEMsUUFBUSxPQUFPLE1BQU0sQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDO0lBQzNDLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLGlCQUFpQixHQUFHO0lBQ25DLFFBQVEsT0FBTyxZQUFZLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxJQUFJLFlBQVksQ0FBQyxRQUFRLEtBQUssS0FBSyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQztJQUM5SCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxtQkFBbUIsR0FBRztJQUNqQyxRQUFRLE9BQU8sT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksV0FBVztJQUN2RCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxtQkFBbUIsR0FBRztJQUNqQyxRQUFRLE9BQU8sT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksV0FBVztJQUN2RCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxxQkFBcUIsR0FBRztJQUNuQyxRQUFRLE9BQU8sT0FBTyxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksV0FBVztJQUN6RCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxnQkFBZ0IsR0FBRztJQUM5QixRQUFRLE9BQU8sU0FBUyxJQUFJLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0QsS0FBSztJQUNMLENBQUM7O0lBRUQ7SUFDQTtBQUNBLElBQU8sTUFBTSxpQkFBaUIsQ0FBQzs7SUFFL0IsSUFBSSxPQUFPLFdBQVcsR0FBRztJQUN6QixRQUFRLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBQztJQUM1QyxRQUFRLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxJQUFJLFdBQVcsR0FBRyxnQkFBZTtJQUMxRixLQUFLOztJQUVMLElBQUksT0FBTyxVQUFVLEdBQUc7SUFDeEIsUUFBUSxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsd0JBQXdCLEVBQUUsY0FBYyxFQUFDO0lBQ3JFLFFBQVEsSUFBSSxNQUFNLElBQUksSUFBSSxFQUFFO0lBQzVCLFlBQVksSUFBSSxDQUFDLFNBQVM7SUFDMUIsWUFBWSxRQUFRLEdBQUcsTUFBTSxHQUFHLHVCQUFzQjtJQUN0RCxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLE9BQU8sYUFBYSxHQUFHO0lBQzNCLFFBQVEsSUFBSSxLQUFLLEdBQUcsY0FBYyxHQUFHLFlBQVksQ0FBQyxVQUFTO0lBQzNELFFBQVEsVUFBVSxDQUFDLFNBQVMsR0FBRyxNQUFLO0lBQ3BDLEtBQUs7O0lBRUwsSUFBSSxPQUFPLG9CQUFvQixHQUFHO0lBQ2xDLFFBQVEsSUFBSSxLQUFLLEdBQUcsc0JBQXNCLEdBQUcsWUFBWSxDQUFDLGlCQUFnQjtJQUMxRSxRQUFRLGtCQUFrQixDQUFDLFNBQVMsR0FBRyxNQUFLO0lBQzVDLEtBQUs7O0lBRUwsSUFBSSxPQUFPLG1CQUFtQixHQUFHO0lBQ2pDLFFBQVEsSUFBSSxLQUFLLEdBQUcscUNBQXFDLEdBQUcsWUFBWSxDQUFDLGtCQUFpQjtJQUMxRixRQUFRLGlCQUFpQixDQUFDLFNBQVMsR0FBRyxNQUFLO0lBQzNDLEtBQUs7O0lBRUwsSUFBSSxPQUFPLG1CQUFtQixHQUFHO0lBQ2pDLFFBQVEsSUFBSSxNQUFNLEdBQUcsR0FBRTtJQUN2QixRQUFRLElBQUksWUFBWSxDQUFDLG1CQUFtQixFQUFFLEVBQUU7SUFDaEQsWUFBWSxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBQztJQUN0QyxTQUFTO0lBQ1QsUUFBUSxJQUFJLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxFQUFFO0lBQ2hELFlBQVksTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUM7SUFDdEMsU0FBUztJQUNULFFBQVEsSUFBSSxZQUFZLENBQUMscUJBQXFCLEVBQUUsRUFBRTtJQUNsRCxZQUFZLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFDO0lBQ3hDLFNBQVM7SUFDVCxRQUFRLGdCQUFnQixDQUFDLFNBQVMsR0FBRyxvQkFBb0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQztJQUM3RSxLQUFLOztJQUVMLElBQUksT0FBTyxPQUFPLEdBQUc7SUFDckIsUUFBUSxJQUFJLENBQUMsYUFBYSxHQUFFO0lBQzVCLFFBQVEsSUFBSSxDQUFDLG9CQUFvQixHQUFFO0lBQ25DLFFBQVEsSUFBSSxDQUFDLG1CQUFtQixHQUFFO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLG1CQUFtQixHQUFFO0lBQ2xDLEtBQUs7SUFDTCxDQUFDOztJQUVEO0lBQ0EsTUFBTSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ2xDLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUI7O0lDM0k1QztJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUNBLElBQU8sTUFBTSxTQUFTLENBQUM7SUFDdkIsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRTtJQUM5QixRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSTtJQUN4QixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTTtJQUM1QixLQUFLO0lBQ0wsQ0FBQzs7SUFFRDtJQUNBLE1BQU0sS0FBSyxHQUFHLFVBQVM7SUFDdkIsTUFBTSxNQUFNLEdBQUcsV0FBVTtJQUN6QixNQUFNLEdBQUcsR0FBRyxRQUFPO0FBQ25CLEFBRUE7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUNBLElBQU8sTUFBTSxZQUFZLFNBQVMsU0FBUyxDQUFDO0lBQzVDLElBQUksV0FBVztJQUNmLFFBQVEsTUFBTTtJQUNkLFFBQVE7SUFDUixZQUFZLFNBQVMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtJQUN0QyxZQUFZLEtBQUssR0FBRyxJQUFJO0lBQ3hCLFlBQVksTUFBTSxHQUFHLENBQUM7SUFDdEIsWUFBWSxLQUFLLEdBQUcsSUFBSTtJQUN4QixZQUFZLElBQUksR0FBRyxLQUFLO0lBQ3hCLFlBQVksSUFBSSxHQUFHLElBQUk7SUFDdkIsU0FBUyxHQUFHLEVBQUU7SUFDZCxNQUFNO0lBQ04sUUFBUSxLQUFLLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUM7SUFDdkQsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDbEMsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDNUIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUk7SUFDeEIsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUk7SUFDeEIsS0FBSzs7SUFFTCxJQUFJLFFBQVEsR0FBRztJQUNmLFFBQVE7SUFDUixZQUFZLHFDQUFxQztJQUNqRCxZQUFZLElBQUksQ0FBQyxLQUFLO0lBQ3RCLFlBQVksVUFBVTtJQUN0QixZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QixZQUFZLElBQUk7SUFDaEIsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEIsWUFBWSxHQUFHO0lBQ2YsU0FBUztJQUNULEtBQUs7SUFDTCxDQUFDOztJQUVEO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNLFdBQVcsU0FBUyxTQUFTLENBQUM7SUFDM0MsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFO0lBQ3hELFFBQVEsS0FBSyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUM7SUFDakUsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDNUIsS0FBSzs7SUFFTCxJQUFJLFFBQVEsR0FBRztJQUNmLFFBQVE7SUFDUixZQUFZLDhCQUE4QjtJQUMxQyxZQUFZLElBQUksQ0FBQyxLQUFLO0lBQ3RCLFlBQVksVUFBVTtJQUN0QixZQUFZLElBQUksQ0FBQyxNQUFNO0lBQ3ZCLFlBQVksR0FBRztJQUNmLFNBQVM7SUFDVCxLQUFLO0lBQ0wsQ0FBQzs7SUFFRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxNQUFNLFNBQVMsQ0FBQztJQUNoQixJQUFJLFdBQVcsQ0FBQztJQUNoQixRQUFRLFFBQVEsR0FBRyxJQUFJO0lBQ3ZCLFFBQVEsUUFBUSxHQUFHLElBQUk7SUFDdkIsUUFBUSxlQUFlLEdBQUcsRUFBRTtJQUM1QixRQUFRLFlBQVksR0FBRyxJQUFJO0lBQzNCLFFBQVEsU0FBUyxHQUFHLElBQUk7SUFDeEIsUUFBUSxlQUFlLEdBQUcsSUFBSTtJQUM5QixLQUFLLEdBQUcsRUFBRSxFQUFFO0lBQ1osUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLGdCQUFlO0lBQzlDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFFO0lBQzVCLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFJO0lBQzVCLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFJO0lBQzdCLFFBQVEsSUFBSSxDQUFDLGVBQWUsR0FBRyxnQkFBZTtJQUM5QztJQUNBLEtBQUs7O0lBRUwsSUFBSSxlQUFlLEdBQUc7SUFDdEIsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEdBQUU7SUFDMUMsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRTtJQUNuQyxRQUFRLElBQUksQ0FBQyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEdBQUU7SUFDakMsUUFBUSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVM7SUFDbkMsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUM7SUFDMUIsUUFBUSxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUU7SUFDcEI7SUFDQSxZQUFZLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxHQUFFO0lBQ3JFLFlBQVksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQzFDLFlBQVksT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxNQUFNLEVBQUU7SUFDcEQsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFFO0lBQ3ZDLGFBQWE7SUFDYixTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLFlBQVksQ0FBQyxZQUFZLEdBQUcsRUFBRSxFQUFFO0lBQ3BDLFFBQVEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFDO0lBQ3hDLFFBQVEsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUU7SUFDaEMsUUFBUSxJQUFJLEtBQUssR0FBRyxFQUFDO0lBQ3JCLFFBQVEsSUFBSSxDQUFDLEdBQUcsRUFBQztJQUNqQixRQUFRLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDN0QsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBQztJQUN0QyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRTtJQUNyQixZQUFZLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFFO0lBQ3ZELFlBQVksR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBQztJQUNyQyxZQUFZLEtBQUssSUFBSSxFQUFDO0lBQ3RCLFlBQVksSUFBSSxDQUFDLEdBQUcsWUFBWSxFQUFFO0lBQ2xDLGdCQUFnQixLQUFLO0lBQ3JCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUUsT0FBTyxHQUFHO0lBQ25DLFFBQVEsT0FBTyxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3BELEtBQUs7O0lBRUwsSUFBSSxhQUFhLEdBQUc7SUFDcEIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUk7SUFDNUIsUUFBUSxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUU7SUFDNUIsS0FBSzs7SUFFTCxJQUFJLFVBQVUsR0FBRztJQUNqQixRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRTtJQUMzQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLEVBQUU7SUFDbkM7SUFDQTtJQUNBLFlBQVksSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7SUFDNUQsWUFBWSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUM7SUFDcEUsU0FBUyxNQUFNO0lBQ2YsWUFBWSxJQUFJLENBQUMsY0FBYyxHQUFFO0lBQ2pDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtJQUN2QixRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLEVBQUU7SUFDbkMsWUFBWSxJQUFJLENBQUMsR0FBRyxXQUFXLENBQUMsR0FBRyxHQUFFO0lBQ3JDLFlBQVksSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFTO0lBQ3ZDLFlBQVksSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFDO0lBQzlCO0lBQ0EsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7SUFDdkQsWUFBWSxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7SUFDekQsWUFBWSxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBQztJQUNoRCxZQUFZLElBQUksVUFBVSxHQUFHLFVBQVUsRUFBRTtJQUN6QyxnQkFBZ0IsSUFBSSxNQUFNLEdBQUcsVUFBVSxHQUFHLFdBQVU7SUFDcEQsZ0JBQWdCLElBQUksR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFDO0lBQzlELGdCQUFnQixPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksRUFBQztJQUNoRixhQUFhO0lBQ2IsWUFBWSxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUk7SUFDaEMsWUFBWSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFDO0lBQzVELFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUM7O0lBRXpCLFlBQVksSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLEVBQUM7SUFDaEMsWUFBWSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFO0lBQ2xELGdCQUFnQixxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBQztJQUNuRSxnQkFBZ0IsTUFBTTtJQUN0QixhQUFhLE1BQU07SUFDbkIsZ0JBQWdCLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFO0lBQ3RDLG9CQUFvQixxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBQztJQUN2RSxvQkFBb0IsTUFBTTtJQUMxQixpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUU7SUFDN0IsUUFBUSxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxFQUFFO0lBQzFDLFlBQVksSUFBSSxDQUFDLGVBQWUsR0FBRTtJQUNsQyxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLGNBQWMsR0FBRztJQUNyQixRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLEVBQUU7SUFDbkMsWUFBWSxPQUFPLEtBQUs7SUFDeEIsU0FBUztJQUNULFFBQVEsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJO0lBQ2xELEtBQUs7O0lBRUwsSUFBSSxZQUFZLENBQUMsUUFBUSxFQUFFO0lBQzNCO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDckUsUUFBUSxPQUFPO0lBQ2YsWUFBWSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUMzQyxZQUFZLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzNDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtJQUNqQjtJQUNBLEtBQUs7O0lBRUwsSUFBSSxjQUFjLEdBQUc7SUFDckI7SUFDQSxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLEtBQUssRUFBRTtJQUN4QjtJQUNBLEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxlQUFlLFNBQVMsU0FBUyxDQUFDO0lBQy9DLElBQUksV0FBVyxDQUFDO0lBQ2hCLFFBQVEsUUFBUSxHQUFHLEdBQUc7SUFDdEIsUUFBUSxRQUFRLEdBQUcsR0FBRztJQUN0QixRQUFRLFVBQVUsR0FBRyxHQUFHO0lBQ3hCLFFBQVEsZ0JBQWdCLEdBQUcsSUFBSTtJQUMvQixRQUFRLFNBQVMsR0FBRyxJQUFJO0lBQ3hCLFFBQVEsWUFBWSxHQUFHLElBQUk7SUFDM0IsUUFBUSxRQUFRLEdBQUcsSUFBSTtJQUN2QixRQUFRLFNBQVMsR0FBRyxJQUFJO0lBQ3hCLFFBQVEsU0FBUyxHQUFHLEtBQUs7SUFDekIsUUFBUSxRQUFRLEdBQUcsSUFBSTtJQUN2QixRQUFRLFFBQVEsR0FBRyxJQUFJO0lBQ3ZCLFFBQVEsZUFBZSxHQUFHLEVBQUU7SUFDNUIsUUFBUSxZQUFZLEdBQUcsSUFBSTtJQUMzQixRQUFRLGFBQWEsR0FBRyxDQUFDO0lBQ3pCLFFBQVEsZUFBZSxHQUFHLEdBQUc7SUFDN0IsUUFBUSxlQUFlLEdBQUcsSUFBSTtJQUM5QixRQUFRLFFBQVEsR0FBRyxJQUFJO0lBQ3ZCLFFBQVEsV0FBVyxHQUFHLElBQUk7SUFDMUIsUUFBUSxXQUFXLEdBQUcsSUFBSTtJQUMxQixRQUFRLE9BQU8sR0FBRyxJQUFJO0lBQ3RCLFFBQVEsZUFBZSxHQUFHLElBQUk7SUFDOUIsUUFBUSxjQUFjLEdBQUcsS0FBSztJQUM5QixRQUFRLG1CQUFtQixHQUFHLElBQUk7SUFDbEMsUUFBUSxnQkFBZ0IsR0FBRyxJQUFJO0lBQy9CLEtBQUssR0FBRyxFQUFFLEVBQUU7SUFDWixRQUFRLElBQUksZUFBZSxJQUFJLElBQUksSUFBSSxRQUFRLElBQUksSUFBSSxFQUFFO0lBQ3pELFlBQVksTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQztJQUMzRSxTQUFTLE1BQU0sSUFBSSxRQUFRLElBQUksSUFBSSxFQUFFO0lBQ3JDLFlBQVksZUFBZSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQzNELFNBQVMsTUFBTSxJQUFJLGVBQWUsSUFBSSxJQUFJLEVBQUU7SUFDNUMsWUFBWSxlQUFlLEdBQUcsRUFBQztJQUMvQixTQUFTO0lBQ1QsUUFBUSxLQUFLLENBQUM7SUFDZCxZQUFZLFFBQVE7SUFDcEIsWUFBWSxRQUFRO0lBQ3BCLFlBQVksZUFBZTtJQUMzQixZQUFZLFlBQVk7SUFDeEIsWUFBWSxTQUFTO0lBQ3JCLFlBQVksZUFBZTtJQUMzQixTQUFTLEVBQUM7O0lBRVY7SUFDQTtJQUNBO0lBQ0E7SUFDQSxRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUcsZUFBYztJQUM1QyxRQUFRLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxvQkFBbUI7SUFDdEQsUUFBUSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsaUJBQWdCO0lBQ2hELFFBQVEsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEtBQUk7O0lBRXpDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGdCQUFlO0lBQ25ELFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFVO0lBQ3BDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxjQUFhO0lBQzFDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLFlBQVksRUFBRTtJQUMzQixZQUFZLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBSztJQUNqQyxZQUFZLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBSztJQUNqQyxTQUFTO0lBQ1QsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDbEMsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDbEMsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLGdCQUFlO0lBQzlDLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGlCQUFnQjtJQUNoRCxRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBSztJQUM3QixRQUFRLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxJQUFJLElBQUksR0FBRyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEtBQUk7SUFDckUsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFJO0lBQ3pELEtBQUs7O0lBRUwsSUFBSSxxQkFBcUIsQ0FBQyxRQUFRLEVBQUU7SUFDcEMsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO0lBQ2xDLFlBQVksSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFFO0lBQzdCLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztJQUNuQyxLQUFLOztJQUVMLElBQUkseUJBQXlCLENBQUMsUUFBUSxFQUFFO0lBQ3hDLFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksRUFBRTtJQUN0QyxZQUFZLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRTtJQUNqQyxTQUFTO0lBQ1QsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUM7SUFDdkMsS0FBSzs7SUFFTCxJQUFJLFlBQVksQ0FBQyxXQUFXLEVBQUU7SUFDOUIsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFFO0lBQzNCLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRTtJQUM1QixRQUFRLElBQUksQ0FBQyxlQUFlLEdBQUU7SUFDOUIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLEtBQUssR0FBRztJQUNaLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQzFCLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBQztJQUM1RCxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUU7SUFDekIsUUFBUSxJQUFJLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxHQUFFO0lBQ3ZDO0lBQ0EsUUFBUSxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7SUFDM0IsWUFBWSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBQztJQUNuQyxZQUFZLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFDO0lBQ3hFLFlBQVksSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDLE1BQUs7SUFDckUsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxJQUFJLE9BQU8sR0FBRztJQUNsQixRQUFRLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFDO0lBQzVDLFFBQVEsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUM7SUFDN0MsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTTtJQUNoQyxRQUFRLElBQUksT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBQztJQUN6QyxRQUFRLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUM7SUFDNUMsUUFBUSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBQztJQUMzQyxRQUFRLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBQztJQUMxQyxRQUFRLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFDO0lBQzNDLFFBQVEsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQ3JDLFFBQVEsT0FBTyxPQUFPO0lBQ3RCLEtBQUs7O0lBRUwsSUFBSSxTQUFTLEdBQUc7SUFDaEIsUUFBUSxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWdCO0lBQ2hELFFBQVEsSUFBSSxZQUFZLElBQUksSUFBSTtJQUNoQyxZQUFZLE9BQU8sS0FBSztJQUN4QixRQUFRLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFPO0lBQ2xDLFFBQVEsSUFBSSxPQUFPLElBQUksSUFBSTtJQUMzQixZQUFZLE9BQU8sS0FBSztJQUN4QixRQUFRLElBQUksTUFBTSxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFDO0lBQ3pELFFBQVEsT0FBTyxNQUFNLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWU7SUFDeEUsS0FBSzs7SUFFTCxJQUFJLFFBQVEsR0FBRztJQUNmO0lBQ0E7SUFDQSxRQUFRLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFNO0lBQ2hDLFFBQVEsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFNO0lBQzFDLFFBQVEsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFDO0lBQ25ELFFBQVEsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUN0QyxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLFFBQVEsRUFBRTtJQUMzQixRQUFRLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUM7SUFDekMsS0FBSzs7SUFFTCxJQUFJLFFBQVEsR0FBRztJQUNmO0lBQ0E7SUFDQTs7SUFFQSxRQUFRLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBZ0I7SUFDaEQsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNsQyxRQUFRLElBQUksTUFBTSxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFDO0lBQ3pELFFBQVEsSUFBSSxNQUFNLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRTtJQUN2RSxZQUFZLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUU7SUFDcEMsWUFBWSxJQUFJLFVBQVUsR0FBRyxNQUFLO0lBQ2xDLFlBQVksT0FBTyxNQUFNLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRTtJQUM5RSxnQkFBZ0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUM7SUFDeEMsZ0JBQWdCLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFDO0lBQ3hDLGdCQUFnQixJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBQztJQUM5QixnQkFBZ0IsTUFBTSxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFDO0lBQzdELGdCQUFnQixVQUFVLEdBQUcsS0FBSTtJQUNqQyxhQUFhO0lBQ2IsWUFBWSxPQUFPLFVBQVU7SUFDN0IsU0FBUztJQUNULFFBQVEsT0FBTyxLQUFLO0lBQ3BCLEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLFNBQVMsR0FBRyxHQUFHLEVBQUU7SUFDM0MsUUFBUSxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWdCO0lBQ2hELFFBQVEsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNO0lBQ2pDLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQU87SUFDbEMsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFFO0lBQ3JDLFFBQVEsSUFBSSxPQUFPLEVBQUU7SUFDckIsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWU7SUFDNUMsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUM7SUFDakMsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUM7SUFDakMsWUFBWSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsRUFBQztJQUNuRCxZQUFZLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxFQUFDO0lBQ25ELFlBQVksSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQVk7SUFDMUM7SUFDQSxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUN2QixnQkFBZ0IsRUFBRSxHQUFHLENBQUMsR0FBRTtJQUN4QixnQkFBZ0IsTUFBTSxHQUFHLFVBQVM7SUFDbEMsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRTtJQUNqQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsR0FBRTtJQUN4QixnQkFBZ0IsTUFBTSxHQUFHLFVBQVM7SUFDbEMsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO0lBQ3ZCLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxHQUFFO0lBQ3hCLGdCQUFnQixNQUFNLEdBQUcsVUFBUztJQUNsQyxhQUFhO0lBQ2IsWUFBWSxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFO0lBQ2xDLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxHQUFFO0lBQ3hCLGdCQUFnQixNQUFNLEdBQUcsVUFBUztJQUNsQyxhQUFhO0lBQ2I7SUFDQSxZQUFZLE9BQU8sTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQztJQUNsRSxTQUFTO0lBQ1QsUUFBUSxPQUFPLEtBQUssQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDO0lBQzNDLEtBQUs7O0lBRUwsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFO0lBQzVCLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRTtJQUN6QixRQUFRLElBQUksQ0FBQyxlQUFlLEdBQUU7SUFDOUIsS0FBSzs7SUFFTCxJQUFJLGVBQWUsR0FBRztJQUN0QixRQUFRLElBQUksSUFBSSxDQUFDLGNBQWM7SUFDL0IsWUFBWSxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFO0lBQy9GLGdCQUFnQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFDO0lBQzdGLGFBQWEsTUFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUU7SUFDOUUsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUM7SUFDckYsYUFBYTtJQUNiLEtBQUs7O0lBRUwsSUFBSSxhQUFhLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRTtJQUNuQyxRQUFRLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFDO0lBQzlDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFDO0lBQ2hDLEtBQUs7O0lBRUwsSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRTtJQUN4QixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBQztJQUN4RCxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUU7SUFDbEMsUUFBUSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7SUFDL0IsWUFBWSxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUU7SUFDN0IsZ0JBQWdCLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFRO0lBQzVDLGdCQUFnQixTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUU7SUFDNUMsb0JBQW9CLENBQUMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDakMsb0JBQW9CLENBQUMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDakM7SUFDQSxvQkFBb0IsUUFBUSxFQUFFLENBQUMsSUFBSTtJQUNuQyx3QkFBd0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVE7SUFDN0Msd0JBQXdCLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEVBQUM7SUFDakQsd0JBQXdCLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEVBQUM7SUFDakQsd0JBQXdCLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBQztJQUM1QyxxQkFBcUI7SUFDckIsaUJBQWlCLEVBQUM7SUFDbEIsYUFBYSxNQUFNO0lBQ25CLGdCQUFnQixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQztJQUM3QixnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDdEMsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUU7SUFDcEMsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTTtJQUMzQixRQUFRLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUN6QyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFDO0lBQzlDLEtBQUs7O0lBRUwsSUFBSSxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUN0QyxRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFNO0lBQzNCLFFBQVEsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQ3pDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUM7SUFDOUMsS0FBSzs7SUFFTCxJQUFJLElBQUk7SUFDUixRQUFRLEtBQUs7SUFDYixRQUFRO0lBQ1IsWUFBWSxPQUFPLEdBQUcsQ0FBQztJQUN2QixZQUFZLEtBQUssR0FBRyxJQUFJO0lBQ3hCLFlBQVksS0FBSyxHQUFHLENBQUM7SUFDckIsWUFBWSxDQUFDLEdBQUcsSUFBSTtJQUNwQixZQUFZLENBQUMsR0FBRyxJQUFJO0lBQ3BCLFlBQVksVUFBVSxHQUFHLElBQUk7SUFDN0IsU0FBUyxHQUFHLEVBQUU7SUFDZCxNQUFNO0lBQ04sUUFBUSxJQUFJLE1BQU0sR0FBRyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU07SUFDekMsUUFBUSxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO0lBQ2pDLFlBQVksSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFO0lBQzdCLGdCQUFnQixTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUU7SUFDNUMsb0JBQW9CLEtBQUssRUFBRSxLQUFLO0lBQ2hDLG9CQUFvQixLQUFLLEVBQUUsS0FBSztJQUNoQyxvQkFBb0IsVUFBVSxFQUFFLFVBQVU7SUFDMUMsb0JBQW9CLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDdEQsaUJBQWlCLEVBQUM7SUFDbEIsYUFBYSxNQUFNO0lBQ25CLGdCQUFnQixJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDbEMsZ0JBQWdCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFDO0lBQ3JDLGFBQWE7SUFDYixTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUU7SUFDakIsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFDO0lBQzdDLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBQztJQUM3QyxLQUFLOztJQUVMLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtJQUMvQyxRQUFRLElBQUksS0FBSyxHQUFHO0lBQ3BCLFlBQVksQ0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzlDLFlBQVksQ0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzlDLFVBQVM7SUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEtBQUssR0FBRyxLQUFJO0lBQzVDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFFO0lBQ3RELFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxHQUFHLEVBQUM7SUFDdkMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLEdBQUcsSUFBRztJQUN0QyxRQUFRLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxNQUFNLElBQUksQ0FBQyxFQUFFO0lBQ3hDLFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUM7SUFDN0IsWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxFQUFFO0lBQzFDLGdCQUFnQixJQUFJLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUU7SUFDbkQsb0JBQW9CLFNBQVMsRUFBRSxLQUFLO0lBQ3BDLG9CQUFvQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDckMsb0JBQW9CLE1BQU0sRUFBRSxDQUFDO0lBQzdCLG9CQUFvQixLQUFLLEVBQUUsTUFBTTtJQUNqQyxvQkFBb0IsSUFBSSxFQUFFLEtBQUs7SUFDL0Isb0JBQW9CLElBQUksRUFBRSxNQUFNO0lBQ2hDLGlCQUFpQixFQUFDO0lBQ2xCLGdCQUFnQixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRTtJQUN0RCxvQkFBb0IsQ0FBQyxDQUFDLEtBQUssRUFBQztJQUM1QixpQkFBaUIsRUFBQztJQUNsQixhQUFhO0lBQ2IsWUFBWSxNQUFNO0lBQ2xCLFNBQVM7SUFDVCxRQUFRLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFjO0lBQ3hDLFFBQVEsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFDO0lBQy9DLFFBQVEsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFDO0lBQ3RELFFBQVEsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFDOztJQUVsRixRQUFRLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksR0FBRyxNQUFNLEVBQUUsUUFBUSxHQUFHLGVBQWUsRUFBQztJQUNyRixRQUFRLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBQztJQUN0RCxRQUFRLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBQztJQUNwRCxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFDO0lBQzFCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxTQUFRO0lBQzdCLFFBQVEsSUFBSSxDQUFDLFFBQVEsSUFBSSxPQUFNO0lBQy9CLFFBQVEsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFDO0lBQ3RDLFFBQVEsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBQztJQUMxQyxRQUFRLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUM7SUFDOUMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBQzs7SUFFMUIsUUFBUSxLQUFLLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFDO0lBQzFCLFFBQVEsS0FBSyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBQztJQUMxQixRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLEVBQUU7SUFDdEMsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUU7SUFDL0MsZ0JBQWdCLFNBQVMsRUFBRSxLQUFLO0lBQ2hDLGdCQUFnQixLQUFLLEVBQUUsUUFBUTtJQUMvQixnQkFBZ0IsTUFBTSxFQUFFLE1BQU07SUFDOUIsZ0JBQWdCLEtBQUssRUFBRSxNQUFNO0lBQzdCLGFBQWEsRUFBQztJQUNkLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7SUFDbEQsZ0JBQWdCLENBQUMsQ0FBQyxLQUFLLEVBQUM7SUFDeEIsYUFBYSxFQUFDO0lBQ2QsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQzVCLFlBQVksSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBQztJQUM1QyxTQUFTO0lBQ1QsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksY0FBYyxDQUFDLElBQUksRUFBRTtJQUN6QixRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSTs7SUFFckMsUUFBUSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFhO0lBQ3pELFFBQVEsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYTtJQUN6RCxRQUFRLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRTtJQUM5QixZQUFZLEtBQUssR0FBRyxTQUFRO0lBQzVCLFlBQVksSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBSztJQUNyQyxTQUFTO0lBQ1QsUUFBUSxJQUFJLEtBQUssR0FBRyxRQUFRLEVBQUU7SUFDOUIsWUFBWSxLQUFLLEdBQUcsU0FBUTtJQUM1QixZQUFZLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQUs7SUFDckMsU0FBUzs7SUFFVCxRQUFRLElBQUksSUFBSSxDQUFDLGNBQWM7SUFDL0IsWUFBWSxJQUFJLENBQUMsbUJBQW1CLEdBQUU7O0lBRXRDLFFBQVEsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUU7SUFDOUIsS0FBSzs7SUFFTCxJQUFJLG1CQUFtQixHQUFHO0lBQzFCLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFO0lBQ25FLFlBQVksSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixHQUFFO0lBQ2hFLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLGFBQVk7SUFDckQsU0FBUyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFDO0lBQzdDLEtBQUs7O0lBRUwsSUFBSSwwQkFBMEIsR0FBRztJQUNqQyxRQUFRLElBQUksWUFBWSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxvQkFBbUI7SUFDbEYsUUFBUSxZQUFZLEdBQUcsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLGFBQVk7SUFDckYsUUFBUSxPQUFPLFlBQVk7SUFDM0IsS0FBSzs7SUFFTCxJQUFJLG9CQUFvQixDQUFDLElBQUksRUFBRTtJQUMvQjtJQUNBLEtBQUs7O0lBRUwsSUFBSSxVQUFVLENBQUMsS0FBSyxFQUFFO0lBQ3RCLFFBQVEsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUM7SUFDOUMsUUFBUSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBQztJQUM5QyxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMLElBQUksaUJBQWlCLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRTtJQUM5QixRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLEVBQUU7SUFDckMsWUFBWSxJQUFJLElBQUksR0FBRyxFQUFDO0lBQ3hCLFlBQVksSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxHQUFHLEVBQUUsR0FBRyxRQUFRLEVBQUM7SUFDNUQsWUFBWSxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLE9BQU07SUFDN0QsWUFBWSxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLE9BQU07SUFDN0QsWUFBWSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUU7SUFDM0IsZ0JBQWdCLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUM7SUFDeEUsZ0JBQWdCLHFCQUFxQixDQUFDLEVBQUUsSUFBSTtJQUM1QyxvQkFBb0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsRUFBQztJQUM5QyxpQkFBaUIsRUFBQztJQUNsQixnQkFBZ0IsTUFBTTtJQUN0QixhQUFhO0lBQ2IsWUFBWSxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUk7SUFDbEMsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxZQUFZLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUU7SUFDbkMsUUFBUSxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQUs7SUFDL0IsUUFBUSxZQUFZLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBQztJQUN2RCxRQUFRLFVBQVUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBQztJQUM1RCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLEtBQUssRUFBRTtJQUN4QixRQUFRLElBQUksS0FBSyxDQUFDLGdCQUFnQixFQUFFO0lBQ3BDLFlBQVksSUFBSSxLQUFLLENBQUMsZ0JBQWdCLElBQUksSUFBSSxFQUFFLE1BQU07SUFDdEQsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRTtJQUM1QixRQUFRLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSTtJQUMvQixRQUFRLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxVQUFVLEdBQUcsRUFBQztJQUNoRSxRQUFRLElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPLEdBQUU7SUFDaEUsUUFBUSxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsV0FBVyxFQUFDO0lBQ3ZFLFFBQVEsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFO0lBQzVCLFlBQVksSUFBSSxPQUFPLEdBQUcsU0FBUyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUM7SUFDNUMsWUFBWSxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBQztJQUNsRCxZQUFZLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDO0lBQ3hFLFNBQVM7SUFDVCxRQUFRLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZTtJQUMvQyxRQUFRLElBQUksSUFBSSxHQUFHLFNBQVMsR0FBRyxVQUFVLEdBQUcsQ0FBQyxHQUFHLFdBQVU7SUFDMUQsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUM7SUFDNUQsUUFBUSxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUM7O0lBRTNDLFFBQVEsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO0lBQ2pDLFlBQVksSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFOztJQUV4RSxnQkFBZ0IsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBQztJQUN4RixnQkFBZ0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLFVBQVUsQ0FBQyxNQUFNO0lBQzlELG9CQUFvQixJQUFJLENBQUMsZUFBZSxHQUFFO0lBQzFDLGlCQUFpQixFQUFFLEdBQUcsRUFBQztJQUN2QixhQUFhO0lBQ2IsWUFBWSxJQUFJLENBQUMsbUJBQW1CLEdBQUU7SUFDdEMsU0FBUztJQUNUO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7O0lBRWhDLFFBQVEsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFO0lBQzVDLFlBQVksSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFJO0lBQ2hDLFlBQVksSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUk7SUFDekMsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksRUFBRTtJQUN0QyxZQUFZLElBQUksS0FBSyxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtJQUMvQyxnQkFBZ0IsU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0lBQ3pDLGdCQUFnQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDakMsZ0JBQWdCLE1BQU0sRUFBRSxDQUFDO0lBQ3pCLGdCQUFnQixLQUFLLEVBQUUsSUFBSTtJQUMzQixnQkFBZ0IsSUFBSSxFQUFFLEtBQUs7SUFDM0IsZ0JBQWdCLElBQUksRUFBRSxLQUFLO0lBQzNCLGFBQWEsRUFBQztJQUNkLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7SUFDbEQsZ0JBQWdCLENBQUMsQ0FBQyxLQUFLLEVBQUM7SUFDeEIsYUFBYSxFQUFDO0lBQ2QsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtJQUMvQjtJQUNBO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFDO0lBQ3JDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7SUFDOUI7SUFDQSxRQUFRLElBQUksV0FBVyxDQUFDLFVBQVUsRUFBRSxFQUFFO0lBQ3RDLFlBQVksSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUM7SUFDeEMsWUFBWSxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQUs7SUFDakMsWUFBWSxLQUFLLElBQUksR0FBRyxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDdEQsZ0JBQWdCLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUM1QyxvQkFBb0IsSUFBSSxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQzFELG9CQUFvQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFDO0lBQ3pELGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxFQUFFO0lBQzFDLGdCQUFnQixJQUFJLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUU7SUFDbkQsb0JBQW9CLFNBQVMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtJQUM3QyxvQkFBb0IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0lBQ3JDLG9CQUFvQixNQUFNLEVBQUUsQ0FBQztJQUM3QixvQkFBb0IsS0FBSyxFQUFFLElBQUk7SUFDL0Isb0JBQW9CLElBQUksRUFBRSxLQUFLO0lBQy9CLG9CQUFvQixJQUFJLEVBQUUsR0FBRztJQUM3QixpQkFBaUIsRUFBQztJQUNsQixnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7SUFDdEQsb0JBQW9CLENBQUMsQ0FBQyxLQUFLLEVBQUM7SUFDNUIsaUJBQWlCLEVBQUM7SUFDbEIsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxrQkFBaUI7SUFDMUMsUUFBUSxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7SUFDM0IsWUFBWSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUM7SUFDekMsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsR0FBRzs7SUFFeEMsSUFBSSxZQUFZLENBQUMsS0FBSyxFQUFFO0lBQ3hCLFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksRUFBRTtJQUN0QyxZQUFZLElBQUksS0FBSyxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtJQUMvQyxnQkFBZ0IsSUFBSSxFQUFFLElBQUk7SUFDMUIsZ0JBQWdCLFNBQVMsRUFBRSxLQUFLO0lBQ2hDLGdCQUFnQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDakMsZ0JBQWdCLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWTtJQUN4QyxnQkFBZ0IsSUFBSSxFQUFFLElBQUk7SUFDMUIsYUFBYSxFQUFDO0lBQ2QsWUFBWSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRTtJQUNsRCxnQkFBZ0IsQ0FBQyxDQUFDLEtBQUssRUFBQztJQUN4QixhQUFhLEVBQUM7SUFDZCxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLGNBQWMsR0FBRztJQUNyQixRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtJQUM5QixZQUFZLElBQUksS0FBSyxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtJQUMvQyxnQkFBZ0IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0lBQ2pDLGdCQUFnQixLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVk7SUFDeEMsZ0JBQWdCLElBQUksRUFBRSxLQUFLO0lBQzNCLGdCQUFnQixJQUFJLEVBQUUsSUFBSTtJQUMxQixhQUFhLEVBQUM7SUFDZCxZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO0lBQ2xELGdCQUFnQixDQUFDLENBQUMsS0FBSyxFQUFDO0lBQ3hCLGFBQWEsRUFBQztJQUNkLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFO0lBQzNCLFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksRUFBRTtJQUN0QyxZQUFZLElBQUksS0FBSyxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtJQUMvQyxnQkFBZ0IsU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFO0lBQzNDLGdCQUFnQixLQUFLLEVBQUUsS0FBSztJQUM1QixnQkFBZ0IsSUFBSSxFQUFFLElBQUk7SUFDMUIsZ0JBQWdCLElBQUksRUFBRSxJQUFJO0lBQzFCLGFBQWEsRUFBQztJQUNkLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7SUFDbEQsZ0JBQWdCLENBQUMsQ0FBQyxLQUFLLEVBQUM7SUFDeEIsYUFBYSxFQUFDO0lBQ2QsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxVQUFVLEdBQUc7SUFDakIsUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxFQUFFO0lBQ3RDLFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxFQUFFO0lBQy9DLGdCQUFnQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDakMsZ0JBQWdCLElBQUksRUFBRSxLQUFLO0lBQzNCLGdCQUFnQixJQUFJLEVBQUUsSUFBSTtJQUMxQixhQUFhLENBQUMsQ0FBQztJQUNmLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7SUFDbEQsZ0JBQWdCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixhQUFhLENBQUMsQ0FBQztJQUNmLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRTs7SUFFcEIsUUFBUSxJQUFJLElBQUksQ0FBQyxjQUFjO0lBQy9CLFlBQVksSUFBSSxDQUFDLG1CQUFtQixHQUFFOztJQUV0QyxRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLEVBQUU7SUFDdEMsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUU7SUFDL0MsZ0JBQWdCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztJQUNqQyxnQkFBZ0IsS0FBSyxFQUFFLEtBQUs7SUFDNUIsZ0JBQWdCLElBQUksRUFBRSxLQUFLO0lBQzNCLGdCQUFnQixJQUFJLEVBQUUsSUFBSTtJQUMxQixhQUFhLEVBQUM7SUFDZCxZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO0lBQ2xELGdCQUFnQixDQUFDLENBQUMsS0FBSyxFQUFDO0lBQ3hCLGFBQWEsRUFBQztJQUNkLFNBQVM7SUFDVCxLQUFLO0lBQ0wsQ0FBQzs7SUFFRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNLG1CQUFtQixDQUFDO0lBQ2pDO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXO0lBQ2YsUUFBUSxPQUFPO0lBQ2YsUUFBUSxFQUFFLFVBQVUsR0FBRyxNQUFNLEVBQUUsV0FBVyxHQUFHLElBQUksRUFBRSxVQUFVLEdBQUcsSUFBSSxFQUFFLFdBQVcsR0FBRyxNQUFNLEVBQUUsR0FBRyxFQUFFO0lBQ2pHLE1BQU07SUFDTixRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSTtJQUM3QixRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRTtJQUNuQyxZQUFZLElBQUksWUFBWSxDQUFDLFFBQVEsRUFBRTtJQUN2QyxnQkFBZ0IsUUFBUSxDQUFDLGdCQUFnQjtJQUN6QyxvQkFBb0IsV0FBVztJQUMvQixvQkFBb0IsS0FBSyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDO0lBQ3JELG9CQUFvQixLQUFLO0lBQ3pCLGtCQUFpQjtJQUNqQixnQkFBZ0IsVUFBVSxHQUFHLE1BQUs7SUFDbEMsYUFBYSxNQUFNO0lBQ25CLGdCQUFnQixVQUFVLEdBQUcsS0FBSTtJQUNqQyxhQUFhO0lBQ2IsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFVO0lBQ3BDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFO0lBQ2xDLFlBQVlELFVBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUM7SUFDdkQsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUNoQyxRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSUMsbUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRTtJQUM3RCxZQUFZLFVBQVU7SUFDdEIsWUFBWSxpQkFBaUIsRUFBRSxNQUFNO0lBQ3JDLFNBQVMsRUFBQzs7SUFFVixRQUFRLElBQUksT0FBTyxXQUFXLEtBQUssV0FBVyxFQUFFO0lBQ2hELFlBQVkscUJBQXFCLENBQUMsRUFBRSxJQUFJO0lBQ3hDLGdCQUFnQixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBQztJQUNwQyxhQUFhLEVBQUM7SUFDZCxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxFQUFFLEVBQUU7SUFDcEIsUUFBUSxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsaUJBQWdCO0lBQ2hELFFBQVEsSUFBSSxNQUFNLEdBQUcsWUFBVztJQUNoQyxRQUFRLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLFFBQU87SUFDdkQsUUFBUSxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksRUFBQztJQUM3QyxRQUFRLElBQUksTUFBTSxHQUFHLEVBQUUsR0FBRyxXQUFVO0lBQ3BDLFFBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBQztJQUM1RCxRQUFRLE9BQU8sQ0FBQyxTQUFTLEdBQUcscUJBQW9CO0lBQ2hELFFBQVEsT0FBTyxDQUFDLFNBQVMsR0FBRyxFQUFDO0lBQzdCLFFBQVEsT0FBTyxDQUFDLFdBQVcsR0FBRyxVQUFTO0lBQ3ZDLFFBQVEsS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUNwRCxZQUFZLElBQUksS0FBSyxHQUFHLE1BQUs7SUFDN0IsWUFBWSxPQUFPLENBQUMsU0FBUyxHQUFFO0lBQy9CLFlBQVksT0FBTyxDQUFDLEdBQUc7SUFDdkIsZ0JBQWdCLEtBQUssQ0FBQyxDQUFDLEdBQUcsVUFBVTtJQUNwQyxnQkFBZ0IsS0FBSyxDQUFDLENBQUMsR0FBRyxVQUFVO0lBQ3BDLGdCQUFnQixNQUFNO0lBQ3RCLGdCQUFnQixDQUFDO0lBQ2pCLGdCQUFnQixDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUU7SUFDM0IsZ0JBQWdCLEtBQUs7SUFDckIsY0FBYTtJQUNiLFlBQVksT0FBTyxDQUFDLElBQUksR0FBRTtJQUMxQixZQUFZLE9BQU8sQ0FBQyxNQUFNLEdBQUU7SUFDNUIsU0FBUztJQUNULFFBQVEscUJBQXFCLENBQUMsRUFBRSxJQUFJO0lBQ3BDLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUM7SUFDaEMsU0FBUyxFQUFDO0lBQ1YsS0FBSzs7SUFFTCxJQUFJLFlBQVksQ0FBQyxLQUFLLEVBQUU7SUFDeEIsUUFBUSxLQUFLLEdBQUcsS0FBSyxDQUFDLGFBQWEsSUFBSSxNQUFLO0lBQzVDLFFBQVEsSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLENBQUMsRUFBRTtJQUMvQixZQUFZLEtBQUssQ0FBQyxjQUFjLEdBQUU7SUFDbEMsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFO0lBQ2pCLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUM7SUFDbEQsS0FBSzs7SUFFTCxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7SUFDbkIsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDNUIsWUFBWSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO0lBQ3hDLFNBQVM7SUFDVCxRQUFRLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7SUFDN0QsWUFBWSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUM5QixTQUFTO0lBQ1QsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLGtCQUFrQixDQUFDLEtBQUssRUFBRTtJQUM5QixRQUFRLE9BQU8sTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQztJQUN6RCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxHQUFHLEtBQUssRUFBRTtJQUNuRCxRQUFRLElBQUksTUFBTSxJQUFJLEtBQUssRUFBRSxPQUFPLElBQUk7SUFDeEMsUUFBUSxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsV0FBVTtJQUNuQyxRQUFRLE9BQU8sSUFBSSxJQUFJLElBQUksRUFBRTtJQUM3QixZQUFZLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUM1QyxnQkFBZ0IsT0FBTyxLQUFLO0lBQzVCLGFBQWE7SUFDYixZQUFZLElBQUksSUFBSSxJQUFJLE1BQU0sRUFBRTtJQUNoQyxnQkFBZ0IsT0FBTyxJQUFJO0lBQzNCLGFBQWE7SUFDYixZQUFZLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVTtJQUNsQyxTQUFTO0lBQ1QsUUFBUSxPQUFPLEtBQUs7SUFDcEIsS0FBSzs7SUFFTCxJQUFJLFVBQVUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtJQUNyQztJQUNBO0lBQ0E7SUFDQTtJQUNBLFFBQVEsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBQztJQUNqRSxRQUFRLEtBQUssSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRTtJQUNsRCxZQUFZLElBQUksTUFBTSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUU7SUFDaEYsZ0JBQWdCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUN2RCxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxnQkFBZ0IsR0FBRyxPQUFNO0lBQ3JFLGdCQUFnQixPQUFPLE1BQU07SUFDN0IsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLE9BQU8sSUFBSTtJQUNuQixLQUFLOztJQUVMLElBQUksSUFBSSxNQUFNLEdBQUc7SUFDakIsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTTtJQUMzQixRQUFRLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBQztJQUM1QixRQUFRLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsRUFBQztJQUM3QixRQUFRLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUU7SUFDL0IsS0FBSzs7SUFFTCxJQUFJLElBQUksTUFBTSxHQUFHO0lBQ2pCLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFO0lBQ25ELEtBQUs7O0lBRUwsSUFBSSxJQUFJLE9BQU8sR0FBRztJQUNsQixRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFNO0lBQzNCLFFBQVEsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFDO0lBQzVCLFFBQVEsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxFQUFDO0lBQzdCLFFBQVEsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUU7SUFDckMsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUM7SUFDekMsUUFBUSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFDO0lBQzVDLFFBQVEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUM7SUFDM0MsUUFBUSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUM7SUFDMUMsUUFBUSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBQztJQUMzQyxRQUFRLE9BQU8sT0FBTztJQUN0QixLQUFLO0lBQ0wsQ0FBQzs7O0FBR0QsSUFBTyxNQUFNLFVBQVUsU0FBUyxlQUFlLENBQUM7SUFDaEQsSUFBSSxXQUFXO0lBQ2YsUUFBUSxPQUFPO0lBQ2YsUUFBUSxTQUFTO0lBQ2pCLFFBQVE7SUFDUixZQUFZLFVBQVUsR0FBRyxHQUFHO0lBQzVCLFlBQVksUUFBUSxHQUFHLEdBQUc7SUFDMUIsWUFBWSxRQUFRLEdBQUcsR0FBRztJQUMxQixZQUFZLGFBQWEsR0FBRyxHQUFHO0lBQy9CLFlBQVksZ0JBQWdCLEdBQUcsSUFBSTtJQUNuQyxZQUFZLFlBQVksR0FBRyxJQUFJO0lBQy9CLFlBQVksUUFBUSxHQUFHLElBQUk7SUFDM0IsWUFBWSxTQUFTLEdBQUcsSUFBSTtJQUM1QixZQUFZLFFBQVEsR0FBRyxJQUFJO0lBQzNCLFlBQVksUUFBUSxHQUFHLElBQUk7SUFDM0IsWUFBWSxlQUFlLEdBQUcsSUFBSTtJQUNsQyxZQUFZLFFBQVEsR0FBRyxJQUFJO0lBQzNCLFlBQVksV0FBVyxHQUFHLElBQUk7SUFDOUIsWUFBWSxlQUFlLEdBQUcsZUFBZTtJQUM3QztJQUNBLFlBQVksQ0FBQyxHQUFHLENBQUM7SUFDakIsWUFBWSxDQUFDLEdBQUcsQ0FBQztJQUNqQixZQUFZLEtBQUssR0FBRyxJQUFJO0lBQ3hCLFlBQVksTUFBTSxHQUFHLElBQUk7SUFDekIsWUFBWSxTQUFTLEdBQUcsS0FBSztJQUM3QixZQUFZLGFBQWEsR0FBRyxLQUFLO0lBQ2pDLFlBQVksT0FBTyxHQUFHLElBQUk7SUFDMUIsWUFBWSxRQUFRLEdBQUcsSUFBSTtJQUMzQixZQUFZLFdBQVcsR0FBRyxNQUFNO0lBQ2hDLFlBQVksZUFBZSxHQUFHLEVBQUU7SUFDaEMsWUFBWSxZQUFZLEdBQUcsSUFBSTtJQUMvQixZQUFZLFNBQVMsR0FBRyxJQUFJO0lBQzVCLFlBQVksY0FBYyxHQUFHLEtBQUs7SUFDbEMsWUFBWSxPQUFPLEdBQUcsSUFBSTtJQUMxQixZQUFZLG1CQUFtQixHQUFHLElBQUk7SUFDdEMsWUFBWSxnQkFBZ0IsR0FBRyxJQUFJO0lBQ25DLFNBQVMsR0FBRyxFQUFFO0lBQ2QsTUFBTTtJQUNOLFFBQVEsS0FBSyxDQUFDO0lBQ2QsWUFBWSxRQUFRO0lBQ3BCLFlBQVksUUFBUTtJQUNwQixZQUFZLFVBQVU7SUFDdEIsWUFBWSxhQUFhO0lBQ3pCLFlBQVksZ0JBQWdCO0lBQzVCLFlBQVksWUFBWTtJQUN4QixZQUFZLFFBQVE7SUFDcEIsWUFBWSxTQUFTO0lBQ3JCLFlBQVksUUFBUTtJQUNwQixZQUFZLFFBQVE7SUFDcEIsWUFBWSxTQUFTO0lBQ3JCLFlBQVksZUFBZTtJQUMzQixZQUFZLFFBQVE7SUFDcEIsWUFBWSxXQUFXO0lBQ3ZCLFlBQVksZUFBZTtJQUMzQixZQUFZLFlBQVk7SUFDeEIsWUFBWSxTQUFTO0lBQ3JCLFlBQVksY0FBYztJQUMxQixZQUFZLG1CQUFtQjtJQUMvQixZQUFZLGdCQUFnQjtJQUM1QixZQUFZLE9BQU87SUFDbkIsU0FBUyxFQUFDO0lBQ1YsUUFBUSxJQUFJLFNBQVMsSUFBSSxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxNQUFNLElBQUksSUFBSSxFQUFFO0lBQ2xFLFlBQVksTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQztJQUNsRCxTQUFTO0lBQ1QsUUFBUSxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUk7SUFDOUIsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLFFBQU87SUFDOUIsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDbEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDbEIsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUM7SUFDckIsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUM7SUFDckIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUM7SUFDdEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUM7SUFDdEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDNUIsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUM7SUFDdkUsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDbEMsUUFBUSxJQUFJLENBQUMsYUFBYSxHQUFHLGNBQWE7SUFDMUMsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLFdBQVU7SUFDL0IsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxxQkFBb0I7SUFDeEQsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLGdCQUFlO0lBQzlDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRztJQUM3QixZQUFZLENBQUMsRUFBRSxDQUFDO0lBQ2hCLFlBQVksQ0FBQyxFQUFFLENBQUM7SUFDaEIsWUFBWSxLQUFLLEVBQUUsS0FBSztJQUN4QixZQUFZLE1BQU0sRUFBRSxNQUFNO0lBQzFCLFlBQVksS0FBSyxFQUFFLFVBQVU7SUFDN0IsWUFBWSxRQUFRLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtJQUMvQyxZQUFZLGVBQWUsRUFBRSxlQUFlO0lBQzVDLFVBQVM7OztJQUdUO0lBQ0EsUUFBUSxTQUFTLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFDO0lBQ2xELFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFO0lBQ2xDLFlBQVlELFVBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUM7SUFDdkQsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFJO0lBQ2hDLFFBQVEsSUFBSSxTQUFTLEVBQUU7SUFDdkIsWUFBWSxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBQztJQUN0RCxZQUFZLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFdBQVU7SUFDOUMsWUFBWSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQ3RDLFlBQVksTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBSztJQUN2QyxZQUFZLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztJQUN4QyxZQUFZLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN6QztJQUNBO0lBQ0EsWUFBWSxNQUFNLENBQUMsU0FBUyxHQUFHLHFCQUFvQjtJQUNuRCxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBQzs7SUFFNUMsWUFBWSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxLQUFLO0lBQzFELGdCQUFnQixJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBQztJQUNuQyxhQUFhLEVBQUM7O0lBRWQsWUFBWSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxLQUFLO0lBQzFELGdCQUFnQixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQztJQUM5QixhQUFhLEVBQUM7O0lBRWQsWUFBWSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxLQUFLO0lBQ3hELGdCQUFnQixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBQztJQUNsQyxhQUFhLEVBQUM7SUFDZCxZQUFZLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTTtJQUN0QyxTQUFTO0lBQ1QsUUFBUSxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBQztJQUMzQixLQUFLOztJQUVMO0lBQ0EsSUFBSSxRQUFRLEdBQUc7SUFDZixRQUFRLE9BQU87SUFDZixZQUFZLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztJQUM3QixZQUFZLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyQixZQUFZLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyQixZQUFZLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtJQUNuQyxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLEtBQUssR0FBRztJQUNaLFFBQVEsS0FBSyxDQUFDLEtBQUssR0FBRTtJQUNyQixRQUFRLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVTtJQUM1QyxRQUFRLElBQUksTUFBTSxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNwRCxLQUFLOztJQUVMLElBQUksSUFBSSxjQUFjLEdBQUc7SUFDekIsUUFBUSxPQUFPLElBQUksQ0FBQyxNQUFNO0lBQzFCLEtBQUs7O0lBRUwsSUFBSSxJQUFJLENBQUMsR0FBRztJQUNaLFFBQVEsT0FBTyxJQUFJLENBQUMsRUFBRTtJQUN0QixLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLEdBQUc7SUFDWixRQUFRLE9BQU8sSUFBSSxDQUFDLEVBQUU7SUFDdEIsS0FBSzs7SUFFTCxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtJQUNqQixRQUFRLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBSztJQUN2QixRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBQztJQUNqRCxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFO0lBQ2pCLFFBQVEsSUFBSSxDQUFDLEVBQUUsR0FBRyxNQUFLO0lBQ3ZCLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFDO0lBQ2pELEtBQUs7O0lBRUwsSUFBSSxJQUFJLFFBQVEsR0FBRztJQUNuQixRQUFRLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBWTtJQUNqRCxRQUFRLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxFQUFDO0lBQzNCLFFBQVEsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDLEVBQUM7SUFDM0IsUUFBUSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtJQUN2QixLQUFLOztJQUVMLElBQUksSUFBSSxNQUFNLEdBQUc7SUFDakIsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDekMsUUFBUSxPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQy9ELEtBQUs7O0lBRUwsSUFBSSxJQUFJLE1BQU0sR0FBRztJQUNqQixRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLHFCQUFxQixHQUFFO0lBQ2xFLFFBQVEsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsR0FBRTtJQUN2RCxRQUFRLE9BQU87SUFDZixZQUFZLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHO0lBQ3JDLFlBQVksSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUk7SUFDeEMsWUFBWSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDN0IsWUFBWSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07SUFDL0IsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxJQUFJLE1BQU0sR0FBRztJQUNqQixRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFNO0lBQzNCLFFBQVEsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFDO0lBQzVCLFFBQVEsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxFQUFDO0lBQzdCO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsUUFBUSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUU7SUFDMUIsUUFBUSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtJQUN2QixLQUFLOztJQUVMLElBQUksSUFBSSxRQUFRLENBQUMsT0FBTyxFQUFFO0lBQzFCLFFBQVEsSUFBSSxHQUFHLEdBQUcsUUFBTztJQUN6QixRQUFRLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFDO0lBQzlDLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUFDO0lBQzFELFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFHO0lBQzVCLEtBQUs7O0lBRUwsSUFBSSxJQUFJLGVBQWUsQ0FBQyxPQUFPLEVBQUU7SUFDakMsUUFBUSxJQUFJLEdBQUcsR0FBRyxRQUFPO0lBQ3pCLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxFQUFDO0lBQ3RELFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBQztJQUNqRCxLQUFLOztJQUVMLElBQUksSUFBSSxRQUFRLEdBQUc7SUFDbkIsUUFBUSxPQUFPLElBQUksQ0FBQyxTQUFTO0lBQzdCLEtBQUs7O0lBRUwsSUFBSSxJQUFJLGVBQWUsR0FBRztJQUMxQixRQUFRLE9BQU8sSUFBSSxDQUFDLFNBQVM7SUFDN0IsS0FBSzs7SUFFTCxJQUFJLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtJQUNyQixRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNwQyxZQUFZLEtBQUssRUFBRSxLQUFLO0lBQ3hCLFlBQVksZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO0lBQ2pELFNBQVMsRUFBQztJQUNWLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFLO0lBQzNCLEtBQUs7O0lBRUwsSUFBSSxJQUFJLEtBQUssR0FBRztJQUNoQixRQUFRLE9BQU8sSUFBSSxDQUFDLE1BQU07SUFDMUIsS0FBSzs7SUFFTCxJQUFJLElBQUksZUFBZSxHQUFHO0lBQzFCLFFBQVEsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU07SUFDcEMsS0FBSzs7SUFFTCxJQUFJLElBQUksZ0JBQWdCLEdBQUc7SUFDM0IsUUFBUSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTztJQUNyQyxLQUFLOztJQUVMLElBQUksMkJBQTJCLENBQUMsS0FBSyxFQUFFO0lBQ3ZDLFFBQVEsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQztJQUN2RCxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRTtJQUNuQixRQUFRLE9BQU8sSUFBSTtJQUNuQixLQUFLOztJQUVMLElBQUksS0FBSyxHQUFHO0lBQ1osUUFBUSxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBQztJQUN2RCxLQUFLOztJQUVMLElBQUksSUFBSSxHQUFHO0lBQ1gsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO0lBQ3hDLFlBQVksT0FBTyxFQUFFLE1BQU07SUFDM0IsWUFBWSxVQUFVLEVBQUUsQ0FBQyxJQUFJO0lBQzdCLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNqRSxhQUFhO0lBQ2IsU0FBUyxFQUFDO0lBQ1YsS0FBSzs7SUFFTCxJQUFJLElBQUksR0FBRztJQUNYLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFDO0lBQ3pELEtBQUs7O0lBRUwsSUFBSSxNQUFNLENBQUMsQ0FBQyxFQUFFLGVBQWUsRUFBRTtJQUMvQixRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNwQyxZQUFZLE9BQU8sRUFBRSxPQUFPO0lBQzVCLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLFlBQVksUUFBUSxFQUFFLGVBQWU7SUFDckMsWUFBWSxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7SUFDakQsU0FBUyxFQUFDO0lBQ1YsS0FBSzs7SUFFTCxJQUFJLFlBQVksR0FBRztJQUNuQjtJQUNBO0lBQ0EsUUFBUSxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUM7SUFDcEUsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUU7SUFDekIsUUFBUSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7SUFDNUIsWUFBWSxPQUFPLENBQUMsSUFBSSxHQUFFO0lBQzFCLFNBQVMsTUFBTTtJQUNmLFlBQVksT0FBTyxDQUFDLEtBQUssR0FBRTtJQUMzQixTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRTtJQUNyQyxRQUFRLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtJQUNoQyxZQUFZLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUM7SUFDOUQsWUFBWSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUM7SUFDN0QsWUFBWSxJQUFJLE1BQU0sRUFBRTtJQUN4QixnQkFBZ0IsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFRO0lBQ3ZELGdCQUFnQixJQUFJLE9BQU8sR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQzVELGdCQUFnQixJQUFJLE9BQU8sSUFBSSxJQUFJLEVBQUU7SUFDckMsb0JBQW9CLE1BQU07SUFDMUIsaUJBQWlCO0lBQ2pCLGdCQUFnQixRQUFRLE9BQU8sQ0FBQyxPQUFPO0lBQ3ZDLG9CQUFvQixLQUFLLE9BQU87SUFDaEMsd0JBQXdCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBQztJQUN2RCx3QkFBd0IsSUFBSSxTQUFTLEVBQUU7SUFDdkMsNEJBQTRCLFNBQVMsQ0FBQyxJQUFJO0lBQzFDLGdDQUFnQztJQUNoQyxvQ0FBb0MsVUFBVSxFQUFFO0lBQ2hELHdDQUF3QyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7SUFDdkUsb0NBQW9DLElBQUksRUFBRSxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUU7SUFDOUQsaUNBQWlDO0lBQ2pDLGdDQUFnQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDeEMsOEJBQTZCO0lBQzdCLHlCQUF5QixNQUFNO0lBQy9CLDRCQUE0QixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBQztJQUNyRCx5QkFBeUI7SUFDekIsd0JBQXdCLEtBQUs7SUFDN0Isb0JBQW9CO0lBQ3BCLHdCQUF3QixPQUFPLENBQUMsS0FBSyxHQUFFO0lBQ3ZDLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtJQUNoQyxRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxXQUFVO0lBQ25DLFFBQVEsT0FBTyxJQUFJLElBQUksSUFBSSxFQUFFO0lBQzdCLFlBQVksSUFBSSxJQUFJLElBQUksTUFBTSxFQUFFO0lBQ2hDLGdCQUFnQixPQUFPLElBQUk7SUFDM0IsYUFBYTtJQUNiLFlBQVksSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQ2xDLFNBQVM7SUFDVCxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMLElBQUksY0FBYyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDekIsUUFBUSxPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM1RCxLQUFLOztJQUVMLElBQUksY0FBYyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDekIsUUFBUSxPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM1RCxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtJQUNqQjtJQUNBO0lBQ0EsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFDO0lBQzNDLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBQztJQUMzQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBQztJQUN4QixTQUFTO0lBQ1QsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7SUFDM0IsWUFBWSxDQUFDLElBQUksS0FBSyxDQUFDLEVBQUM7SUFDeEIsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFDO0lBQ25CLFFBQVEsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFDO0lBQ25CLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUM7SUFDbkQsS0FBSzs7SUFFTCxJQUFJLG9CQUFvQixDQUFDLElBQUksRUFBRTtJQUMvQjtJQUNBO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLElBQUksS0FBSyxHQUFHLElBQUksV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFDO0lBQ3RFLFlBQVksSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUM7SUFDaEMsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksRUFBRSxDQUc5QjtJQUNULEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsQ0FBQyxFQUFFO0lBQ25CLFFBQVEsQ0FBQyxDQUFDLGNBQWMsR0FBRTtJQUMxQixRQUFRLElBQUksS0FBSyxHQUFHLElBQUksV0FBVyxDQUFDLGVBQWUsRUFBQzs7SUFFcEQsUUFBUSxJQUFJLFlBQVksR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLEdBQUU7SUFDcEcsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFFOztJQUUzQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxRQUFPOztJQUVwRCxRQUFRLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsR0FBRTs7SUFFcEcsUUFBUSxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUM7O0lBRWhFLFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsUUFBTztJQUM3QixRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQU87O0lBRTdCLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQztJQUNqRCxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBQzs7SUFFL0MsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUM7SUFDaEYsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUM7O0lBRS9FLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUMsS0FBSzs7SUFFTCxJQUFJLE1BQU0sQ0FBQyxDQUFDLEVBQUU7SUFDZCxRQUFRLENBQUMsQ0FBQyxjQUFjLEdBQUU7O0lBRTFCLFFBQVEsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQ3pELFFBQVEsUUFBUSxHQUFHLENBQUMsUUFBUSxHQUFHLEdBQUcsSUFBSSxJQUFHO0lBQ3pDLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFDO0lBQzlDLFFBQVEsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxNQUFNLEVBQUU7O0lBRXpELFlBQVksSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFDO0lBQ2hELFlBQVksSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFDOztJQUVoRCxZQUFZLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUM7SUFDeEUsWUFBWSxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFDOztJQUVyRSxZQUFZLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxJQUFHO0lBQ3JDLFlBQVksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLFFBQVEsR0FBRyxFQUFFLElBQUksR0FBRyxJQUFJLElBQUc7O0lBRW5ELFlBQVksSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJLElBQUc7SUFDbkQsWUFBWSxJQUFJLFlBQVksR0FBRyxDQUFDLEdBQUcsR0FBRyxTQUFTLEdBQUcsR0FBRyxJQUFJLElBQUc7O0lBRTVELFlBQVksSUFBSSxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsRUFBQztJQUN6RSxZQUFZLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsRUFBQzs7SUFFMUUsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQzs7SUFFaFQsWUFBWSxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxRQUFPO0lBQ2pDLFlBQVksSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsUUFBTztJQUNqQyxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUU7O0lBRTdCLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUMsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxVQUFVLENBQUMsQ0FBQyxFQUFFO0lBQ2xCLFFBQVEsQ0FBQyxDQUFDLGNBQWMsR0FBRTs7SUFFMUIsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLFdBQVcsQ0FBQyxhQUFhLEVBQUM7SUFDbEQsUUFBUSxJQUFJLFlBQVksR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLEdBQUU7SUFDcEcsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsVUFBUztJQUN0RCxRQUFRLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsR0FBRTtJQUNwRyxRQUFRLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBQzs7SUFFaEUsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUM7SUFDaEYsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUM7O0lBRS9FLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBQzs7SUFFbEQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxLQUFLO0lBQ0wsQ0FBQzs7SUFFRCxVQUFVLENBQUMsTUFBTSxHQUFHLElBQUk7O0lDaDdDakIsTUFBTSxVQUFVLENBQUM7SUFDeEIsSUFBSSxXQUFXO0lBQ2YsUUFBUSxHQUFHO0lBQ1gsUUFBUTtJQUNSLFlBQVksQ0FBQyxHQUFHLENBQUM7SUFDakIsWUFBWSxDQUFDLEdBQUcsQ0FBQztJQUNqQixZQUFZLEtBQUssR0FBRyxJQUFJO0lBQ3hCLFlBQVksTUFBTSxHQUFHLEdBQUc7SUFDeEIsWUFBWSxRQUFRLEdBQUcsSUFBSTtJQUMzQixZQUFZLFNBQVMsR0FBRyxJQUFJO0lBQzVCLFlBQVksS0FBSyxHQUFHLENBQUM7SUFDckIsWUFBWSxRQUFRLEdBQUcsR0FBRztJQUMxQixZQUFZLFFBQVEsR0FBRyxHQUFHO0lBQzFCLFlBQVksUUFBUSxHQUFHLENBQUM7SUFDeEIsU0FBUyxHQUFHLEVBQUU7SUFDZCxNQUFNO0lBQ04sUUFBUSxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUc7SUFDdEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDbEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDbEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUM7SUFDekIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQUs7SUFDaEMsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU07SUFDbEMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsSUFBSSxJQUFJLEdBQUcsUUFBUSxHQUFHLE1BQU0sQ0FBQyxXQUFVO0lBQ3ZFLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLElBQUksSUFBSSxHQUFHLFNBQVMsR0FBRyxNQUFNLENBQUMsWUFBVztJQUMzRSxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSTtJQUM3QixRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUM7SUFDcEI7SUFDQSxZQUFZLEtBQUs7SUFDakIsWUFBWSxNQUFNO0lBQ2xCLFlBQVksUUFBUTtJQUNwQixZQUFZLFNBQVM7SUFDckI7SUFDQSxTQUFTLEVBQUM7SUFDVixLQUFLOztJQUVMLElBQUksTUFBTSxHQUFHO0lBQ2IsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDNUIsWUFBWSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRTtJQUNuQyxZQUFZLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSTtJQUNqQyxTQUFTO0lBQ1QsS0FBSztJQUNMLENBQUM7O0FBRUQsSUFBTyxNQUFNLFNBQVMsU0FBUyxVQUFVLENBQUM7SUFDMUMsSUFBSSxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxHQUFHLElBQUksRUFBRSxNQUFNLEdBQUcsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUU7SUFDckUsUUFBUSxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBQztJQUM1QyxRQUFRLElBQUksT0FBTyxLQUFLLElBQUksV0FBVyxFQUFFO0lBQ3pDLFlBQVksS0FBSyxDQUFDLGVBQWUsRUFBQztJQUNsQyxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDbEIsUUFBUSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sS0FBSztJQUNoRCxZQUFZLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUk7SUFDcEQsZ0JBQWdCLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSTtJQUM1QyxvQkFBb0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFdBQVU7SUFDcEUsb0JBQW9CLElBQUksUUFBUSxHQUFHLENBQUMsR0FBRyxNQUFLO0lBQzVDLG9CQUFvQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBQzs7SUFFMUQ7SUFDQSxvQkFBb0IsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUM7SUFDakUsb0JBQW9CLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFDO0lBQ3pELG9CQUFvQixNQUFNLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxPQUFNO0lBQ25ELG9CQUFvQixNQUFNLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFLOztJQUVqRDtJQUNBLG9CQUFvQixJQUFJLGFBQWEsR0FBRztJQUN4Qyx3QkFBd0IsYUFBYSxFQUFFLE9BQU87SUFDOUMsd0JBQXdCLFFBQVEsRUFBRSxRQUFRO0lBQzFDLHNCQUFxQjtJQUNyQixvQkFBb0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUM7SUFDOUMsb0JBQW9CLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFDO0lBQy9DLG9CQUFvQixJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxNQUFLO0lBQ25ELG9CQUFvQixJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxPQUFNO0lBQ3JELG9CQUFvQixJQUFJLENBQUMsS0FBSyxHQUFHLFNBQVE7SUFDekMsb0JBQW9CLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTTtJQUMzQyxvQkFBb0IsT0FBTyxDQUFDLElBQUksRUFBQztJQUNqQyxpQkFBaUIsRUFBQztJQUNsQixhQUFhLEVBQUM7SUFDZCxTQUFTLENBQUM7SUFDVixLQUFLO0lBQ0wsQ0FBQzs7QUFFRCxJQUFPLE1BQU0sV0FBVyxTQUFTLFVBQVUsQ0FBQztJQUM1QyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDbEIsUUFBUSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sS0FBSztJQUNoRCxZQUFZLElBQUksT0FBTyxHQUFHLE9BQU8sWUFBWSxpQkFBZ0I7SUFDN0QsWUFBWSxJQUFJLEtBQUssR0FBRyxPQUFPLEdBQUcsT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDO0lBQ3pFLFlBQVksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUk7SUFDaEMsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDOUIsb0JBQW9CLE9BQU8sQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFDO0lBQzlDLG9CQUFvQixJQUFJLENBQUMsU0FBUyxHQUFHLE1BQUs7SUFDMUMsaUJBQWlCO0lBQ2pCLGdCQUFnQixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxhQUFZO0lBQ3JELGdCQUFnQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxjQUFhOztJQUV2RCxnQkFBZ0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsYUFBWTtJQUMvRCxnQkFBZ0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsY0FBYTtJQUNqRSxnQkFBZ0IsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLEVBQUM7SUFDOUUsZ0JBQWdCLEtBQUssQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBQztJQUN0RCxnQkFBZ0IsS0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsYUFBWTtJQUNoRCxnQkFBZ0IsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsY0FBYTtJQUNsRCxnQkFBZ0IsT0FBTyxDQUFDLElBQUksRUFBQztJQUM3QixjQUFhO0lBQ2IsWUFBWSxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSTtJQUNqQyxnQkFBZ0IsTUFBTSxDQUFDLElBQUksRUFBQztJQUM1QixjQUFhO0lBQ2IsWUFBWSxLQUFLLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFHO0lBQ2hDLFNBQVMsQ0FBQztJQUNWLEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxXQUFXLFNBQVMsVUFBVSxDQUFDO0lBQzVDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNsQixRQUFRLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxLQUFLO0lBQ2hELFlBQVksSUFBSSxPQUFPLEdBQUcsT0FBTyxZQUFZLGtCQUFpQjtJQUM5RCxZQUFZLElBQUksTUFBTSxHQUFHLE9BQU8sR0FBRyxPQUFPLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUM7SUFDN0UsWUFBWSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBQztJQUN0RSxZQUFZLE1BQU0sQ0FBQyxXQUFXLEdBQUcsRUFBQztJQUNsQyxZQUFZLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLE1BQUs7SUFDMUMsWUFBWSxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFXO0lBQzNDLFlBQVksTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBWTtJQUM3QyxZQUFZLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDMUI7SUFDQSxnQkFBZ0IsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUM7SUFDM0MsZ0JBQWdCLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTTtJQUN2QyxhQUFhO0lBQ2IsWUFBWSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSTtJQUNqQyxnQkFBZ0IsT0FBTyxDQUFDLElBQUksRUFBQztJQUM3QixjQUFhO0lBQ2IsWUFBWSxNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSTtJQUNsQyxnQkFBZ0IsTUFBTSxDQUFDLElBQUksRUFBQztJQUM1QixjQUFhO0lBQ2IsWUFBWSxNQUFNLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFHO0lBQ2pDLFNBQVMsQ0FBQztJQUNWLEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxVQUFVLFNBQVMsVUFBVSxDQUFDO0lBQzNDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNsQixRQUFRLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxLQUFLO0lBQ2hELFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxjQUFjLEdBQUU7SUFDMUMsWUFBWSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBQztJQUM1QyxZQUFZLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJO0lBQzlCLGdCQUFnQixPQUFPLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxTQUFRO0lBQ2hELGdCQUFnQixJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBaUI7SUFDMUQsZ0JBQWdCLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDO0lBQ2pFLGdCQUFnQixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFDO0lBQ3hGLGdCQUFnQixJQUFJLEtBQUs7SUFDekIsb0JBQW9CLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxJQUFJLElBQUksQ0FBQyxZQUFXO0lBQ2hFLGdCQUFnQixJQUFJLE1BQU07SUFDMUIsb0JBQW9CLElBQUksQ0FBQyxZQUFZLEdBQUcsTUFBTSxJQUFJLElBQUksQ0FBQyxhQUFZO0lBQ25FLGdCQUFnQixPQUFPLENBQUMsSUFBSSxFQUFDO0lBQzdCLGNBQWE7SUFDYixZQUFZLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJO0lBQy9CLGdCQUFnQixNQUFNLENBQUMsSUFBSSxFQUFDO0lBQzVCLGNBQWE7SUFDYixZQUFZLEdBQUcsQ0FBQyxJQUFJLEdBQUU7SUFDdEIsU0FBUyxDQUFDO0lBQ1YsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7SUFDZixRQUFRLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUk7SUFDdEQsUUFBUSxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFJO0lBQ3hELFFBQVEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7SUFDaEMsS0FBSztJQUNMLENBQUM7O0FBRUQsSUFBTyxNQUFNLE9BQU8sQ0FBQztJQUNyQixJQUFJLFdBQVc7SUFDZixRQUFRLG1CQUFtQjtJQUMzQixRQUFRLFlBQVk7SUFDcEIsUUFBUSxXQUFXO0lBQ25CLFFBQVEsVUFBVTtJQUNsQixRQUFRO0lBQ1IsWUFBWSxlQUFlLEdBQUcsS0FBSztJQUNuQyxZQUFZLFlBQVksR0FBRyxDQUFDO0lBQzVCLFlBQVksWUFBWSxHQUFHLEdBQUc7SUFDOUIsWUFBWSxhQUFhLEdBQUcsQ0FBQztJQUM3QixZQUFZLFFBQVEsR0FBRyxLQUFLO0lBQzVCLFlBQVksTUFBTSxHQUFHLElBQUk7SUFDekIsWUFBWSxXQUFXLEdBQUcsS0FBSztJQUMvQixZQUFZLFlBQVksR0FBRyxJQUFJO0lBQy9CLFlBQVksUUFBUSxHQUFHLElBQUk7SUFDM0IsWUFBWSxTQUFTLEdBQUcsSUFBSTtJQUM1QixZQUFZLE9BQU8sR0FBRyxJQUFJO0lBQzFCLFlBQVksTUFBTSxHQUFHLElBQUk7SUFDekIsWUFBWSxPQUFPLEdBQUcsSUFBSTtJQUMxQixZQUFZLFFBQVEsR0FBRyxJQUFJO0lBQzNCLFlBQVksU0FBUyxHQUFHLElBQUk7SUFDNUIsWUFBWSxRQUFRLEdBQUcsSUFBSTtJQUMzQixTQUFTLEdBQUcsRUFBRTtJQUNkLE1BQU07SUFDTixRQUFRLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxvQkFBbUI7SUFDdEQsUUFBUSxJQUFJLENBQUMsRUFBRSxHQUFHRCxPQUFLLEdBQUU7SUFDekIsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLGFBQVk7SUFDeEMsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLGFBQVk7SUFDeEMsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLGdCQUFlO0lBQzlDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFVO0lBQ3BDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFPO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFNO0lBQ25DLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFNO0lBQzVCLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxjQUFhO0lBQzFDLFFBQVEsSUFBSSxRQUFRLEVBQUU7SUFDdEIsWUFBWSxJQUFJLENBQUMsSUFBSSxHQUFFO0lBQ3ZCLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksSUFBSSxHQUFHO0lBQ1gsUUFBUSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sS0FBSztJQUNoRCxZQUFZLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFZO0lBQ3JDLFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQU87SUFDdEQsWUFBWSxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUM7SUFDakUsWUFBWSxPQUFPLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFFO0lBQ2hDLFlBQVksSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLElBQUksRUFBQztJQUM1RCxZQUFZLEdBQUcsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFDO0lBQ2xDO0lBQ0E7SUFDQTtJQUNBLFlBQVksSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFDO0lBQy9ELFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQ2hFLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSTtJQUN4RCxnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUs7SUFDdkQsb0JBQW9CLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxHQUFFO0lBQ3RELG9CQUFvQixPQUFPLENBQUMsSUFBSSxFQUFDO0lBQ2pDLGlCQUFpQixFQUFDO0lBQ2xCLGFBQWEsRUFBQztJQUNkLFNBQVMsQ0FBQztJQUNWLEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFO0lBQ3hCLFFBQVEsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEtBQUs7SUFDaEQsWUFBWSxJQUFJLE9BQU8sR0FBRyxJQUFJLFVBQVU7SUFDeEMsZ0JBQWdCLElBQUksQ0FBQyxXQUFXO0lBQ2hDLGdCQUFnQixJQUFJLENBQUMsbUJBQW1CO0lBQ3hDLGdCQUFnQjtJQUNoQixvQkFBb0IsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQy9CLG9CQUFvQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0Isb0JBQW9CLFVBQVUsRUFBRSxNQUFNLENBQUMsS0FBSztJQUM1QyxvQkFBb0IsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO0lBQ3ZDLG9CQUFvQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7SUFDN0Msb0JBQW9CLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtJQUM3QyxvQkFBb0IsS0FBSyxFQUFFLE1BQU0sQ0FBQyxXQUFXO0lBQzdDLG9CQUFvQixNQUFNLEVBQUUsTUFBTSxDQUFDLFlBQVk7SUFDL0Msb0JBQW9CLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtJQUM3QyxvQkFBb0IsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO0lBQ25ELG9CQUFvQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7SUFDM0Msb0JBQW9CLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztJQUM3QyxvQkFBb0IsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO0lBQ3JELGlCQUFpQjtJQUNqQixjQUFhOztJQUViLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0lBQzdCLGdCQUFnQixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUM7SUFDN0MsYUFBYTs7SUFFYixZQUFZLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTs7SUFFdEMsZ0JBQWdCLE1BQU0sZ0JBQWdCLEdBQUcsWUFBWTtJQUNyRCxvQkFBb0IsSUFBSSxPQUFPLENBQUMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7SUFDM0Qsd0JBQXdCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFFOztJQUU5QztJQUNBLHdCQUF3QixPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxjQUFhO0lBQ2pFLHdCQUF3QixPQUFPLENBQUMsYUFBYSxHQUFHLEVBQUM7O0lBRWpEO0lBQ0Esd0JBQXdCLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtJQUNqRCw0QkFBNEIsSUFBSSxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUM7SUFDM0YsNEJBQTRCLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUM7SUFDdEUseUJBQXlCO0lBQ3pCLHFCQUFxQjs7SUFFckIsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQzs7OztJQUk1QixnQkFBZ0IsT0FBTyxDQUFDLHlCQUF5QixDQUFDLGdCQUFnQixFQUFDO0lBQ25FLGFBQWE7O0lBRWIsWUFBWSxJQUFJLFNBQVMsR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUM7SUFDN0UsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUM7O0lBRTlELFlBQVksSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO0lBQ2xDLGdCQUFnQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJO0lBQzFELG9CQUFvQixJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUM7SUFDMUQsaUJBQWlCLEVBQUM7SUFDbEIsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ3RDLFlBQVksT0FBTyxDQUFDLElBQUksRUFBQztJQUN6QixTQUFTLENBQUM7SUFDVixLQUFLOztJQUVMLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBQztJQUN2QixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBQztJQUNsQyxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUNsQyxLQUFLOztJQUVMLElBQUksY0FBYyxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUU7SUFDdEMsUUFBUSxTQUFTLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxZQUFXO0lBQ2xELFFBQVEsU0FBUyxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsYUFBWTtJQUNwRCxRQUFRLFNBQVMsQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLE1BQUs7SUFDNUMsUUFBUSxTQUFTLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFRO0lBQzVDLFFBQVEsU0FBUyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUTtJQUM1QyxRQUFRLFNBQVMsQ0FBQyxZQUFZLEdBQUU7SUFDaEMsS0FBSzs7SUFFTCxJQUFJLEtBQUssQ0FBQyxFQUFFLFlBQVksR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7SUFDeEMsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUM7SUFDbEQsUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsRUFBQztJQUNqRyxhQUFhO0lBQ2IsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUM7SUFDOUQsWUFBWSxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBUztJQUMxQyxZQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUk7SUFDdEQsZ0JBQWdCLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBQztJQUN0RCxnQkFBZ0IsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRSxFQUFDO0lBQzlFLGFBQWEsRUFBQztJQUNkLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksZ0JBQWdCLEdBQUc7SUFDdkIsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRTtJQUMxRCxZQUFZLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLFlBQVksVUFBVSxFQUFFLE1BQU07SUFDOUIsZ0JBQWdCLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFFO0lBQ3pDLGFBQWE7SUFDYixTQUFTLEVBQUM7SUFDVixLQUFLOztJQUVMLElBQUksTUFBTSxHQUFHO0lBQ2IsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFFO0lBQ3JCLEtBQUs7O0lBRUwsSUFBSSxNQUFNLEdBQUc7SUFDYixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO0lBQy9CLFlBQVksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUU7SUFDcEMsU0FBUztJQUNULEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxZQUFZLENBQUM7SUFDMUIsSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUU7SUFDeEM7SUFDQTs7SUFFQSxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSTtJQUN4QixRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUM7SUFDdEQsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQ3BELFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBQztJQUNsRCxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBSztJQUM1QixRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWM7SUFDakQsUUFBUSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxjQUFhO0lBQy9DLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNuQyxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVM7SUFDdkMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFROztJQUVyQyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQVk7SUFDN0MsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFZO0lBQzdDLFFBQVEsT0FBTyxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUM7SUFDN0UsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLElBQUksRUFBQztJQUM3QyxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsRUFBQztJQUMxRCxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsRUFBQztJQUNuRSxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFDO0lBQ3JELFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQy9DLFlBQVksa0JBQWtCLEVBQUUsUUFBUTtJQUN4QyxZQUFZLFdBQVcsRUFBRSxJQUFJO0lBQzdCLFNBQVMsRUFBQztJQUNWLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFDO0lBQzVELFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBQztJQUN4RCxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUM7SUFDeEQsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFDO0lBQzFEO0lBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDMUIsWUFBWUUsbUJBQWlCLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFDOztJQUVqRixZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNyQyxTQUFTO0lBQ1QsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDMUIsWUFBWUEsbUJBQWlCLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUM7SUFDNUUsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO0lBQzNCLFlBQVlBLG1CQUFpQixDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFDO0lBQzdFLFlBQVksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQ3RDLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFFO0lBQzNCLEtBQUs7O0lBRUwsSUFBSSxLQUFLLEdBQUc7SUFDWixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNsQyxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztJQUNuQyxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUMxQixZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDO0lBQzlCLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDOUIsU0FBUyxNQUFNO0lBQ2YsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDbkMsZ0JBQWdCLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWTtJQUMxQyxnQkFBZ0IsVUFBVSxFQUFFLE1BQU07SUFDbEMsb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFFO0lBQ3pDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRTtJQUN0QyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQ3hDLHdCQUF3QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUM7SUFDakQscUJBQXFCO0lBQ3JCLGlCQUFpQjtJQUNqQixhQUFhLEVBQUM7SUFDZCxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLFNBQVMsR0FBRztJQUNoQixRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBQztJQUM1RCxLQUFLOztJQUVMLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBQztJQUNoQyxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUNoQyxLQUFLOztJQUVMLElBQUksSUFBSSxXQUFXLEdBQUc7SUFDdEIsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFHOztJQUV4QixRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLEVBQUU7SUFDbEMsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFDO0lBQy9DLFlBQVksTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFLO0lBQ2hDLFNBQVM7SUFDVCxRQUFRLE9BQU8sTUFBTTtJQUNyQixLQUFLOztJQUVMLElBQUksWUFBWSxHQUFHO0lBQ25CO0lBQ0E7SUFDQTs7SUFFQTtJQUNBOztJQUVBO0lBQ0E7O0lBRUEsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUM7SUFDckM7SUFDQSxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO0lBQ25FLFlBQVksS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXO0lBQ25DLFNBQVMsRUFBQztJQUNWLEtBQUs7O0lBRUwsSUFBSSxZQUFZLEdBQUc7SUFDbkIsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksR0FBRTtJQUNuQyxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBQztJQUNwRSxLQUFLOztJQUVMLElBQUksU0FBUyxHQUFHO0lBQ2hCLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRTtJQUMzQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFFO0lBQzVCLEtBQUs7O0lBRUwsSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7SUFDOUIsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFFO0lBQzNCLEtBQUs7O0lBRUwsSUFBSSxjQUFjLENBQUMsS0FBSyxFQUFFO0lBQzFCLFFBQVEsSUFBSSxLQUFLLEdBQUcsR0FBRTtJQUN0QixRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxNQUFLO0lBQ2hDLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBRztJQUN2QixRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxHQUFHLEVBQUU7SUFDaEMsWUFBWSxLQUFLLEdBQUcsS0FBSyxHQUFHLEtBQUk7SUFDaEMsU0FBUyxNQUFNO0lBQ2YsWUFBWSxLQUFLLEdBQUcsQ0FBQyxLQUFJO0lBQ3pCLFNBQVM7SUFDVCxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMLElBQUksVUFBVSxDQUFDLElBQUksRUFBRTtJQUNyQixRQUFRLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUM7SUFDaEQsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFDO0lBQ2hELFFBQVEsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUTtJQUMzRCxRQUFRLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU07SUFDekQsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFLO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTTtJQUN6QyxRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQ3ZFLEtBQUs7O0lBRUwsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRTtJQUMzQyxRQUFRLElBQUksT0FBTyxFQUFFO0lBQ3JCLFlBQVksU0FBUyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFDO0lBQ2pFLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUU7SUFDM0MsUUFBUSxJQUFJLE9BQU8sRUFBRTtJQUNyQixZQUFZLFNBQVMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBQztJQUNqRSxTQUFTO0lBQ1QsS0FBSzs7OztJQUlMLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtJQUNuQixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDNUMsUUFBUSxJQUFJLE1BQU0sRUFBRTtJQUNwQixZQUFZLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxFQUFDO0lBQzVELFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRTtJQUNwQixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDNUMsUUFBUSxJQUFJLE1BQU0sRUFBRTtJQUNwQixZQUFZLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxFQUFDO0lBQzVELFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEVBQUUsWUFBWSxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUN4QyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUMzQixZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBQztJQUNyRCxZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBQztJQUNyRCxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUTtJQUNoRSxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTTtJQUM5RCxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBSztJQUN0RCxZQUFZLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTTtJQUN4RCxZQUFZLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQUs7SUFDdkQsWUFBWSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFNO0lBQ3pELFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFDO0lBQ2hDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQ3RDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQ3ZDLFNBQVMsTUFBTTtJQUNmLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDcEQsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUM7SUFDdEMsU0FBUztJQUNULFFBQVEsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQU87SUFDaEUsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEdBQUU7SUFDMUQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsR0FBRyxNQUFLO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEdBQUcsTUFBSztJQUN6QyxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLE1BQUs7SUFDdEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsR0FBRTs7SUFFcEMsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQU87SUFDcEMsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsR0FBRyxFQUFDO0lBQzVDLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU87SUFDbEMsY0FBYyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUNwRSxjQUFjLElBQUksQ0FBQyxXQUFVO0lBQzdCLFFBQVEsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQzNFLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQ2pFLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFXO0lBQ25FLFFBQVEsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQUs7SUFDdEQsUUFBUSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTTtJQUN4RCxRQUFRLElBQUksRUFBRSxHQUFHLGFBQVk7SUFDN0IsUUFBUSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQ2pFLFFBQVEsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEdBQUcsRUFBQztJQUNqRSxRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFNO0lBQy9DLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU07O0lBRS9DLFFBQVEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUM7SUFDdkYsUUFBUSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSTtJQUNoRixRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBQztJQUN0QyxRQUFRLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFO0lBQ25ELFlBQVksU0FBUyxFQUFFLE9BQU87SUFDOUIsWUFBWSxJQUFJLEVBQUUsTUFBTSxDQUFDLE9BQU87SUFDaEMsWUFBWSxlQUFlLEVBQUUsU0FBUztJQUN0QyxZQUFZLFFBQVE7SUFDcEIsWUFBWSxVQUFVLEVBQUUsQ0FBQyxJQUFJO0lBQzdCLGdCQUFnQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDbEM7SUFDQSxvQkFBb0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQzdDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUM7O0lBRTNDLG9CQUFvQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7SUFDN0Msd0JBQXdCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFDO0lBQ2pELHFCQUFxQjtJQUNyQixpQkFBaUIsTUFBTTs7SUFFdkIsb0JBQW9CLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLEVBQUU7SUFDcEQsd0JBQXdCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFDO0lBQ3BFLHdCQUF3QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBQztJQUNyRSxxQkFBcUIsTUFBTTtJQUMzQix3QkFBd0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUM7SUFDaEQscUJBQXFCO0lBQ3JCLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRTtJQUN0QyxpQkFBaUI7SUFDakIsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLFlBQVc7SUFDaEQsZ0JBQWdCLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxHQUFHLFFBQU87SUFDdEQsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBaUI7SUFDOUUsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxtQkFBa0I7O0lBRWhGLGdCQUFnQixJQUFJLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBSztJQUN0RSxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsU0FBUTtJQUNoRCxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEdBQUcsYUFBWTtJQUN4RCxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsVUFBUztJQUNsRCxhQUFhO0lBQ2IsWUFBWSxPQUFPLEVBQUUsSUFBSTtJQUN6QixTQUFTLEVBQUM7O0lBRVY7SUFDQSxRQUFRLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsRUFBRTtJQUMxRCxZQUFZLEtBQUssRUFBRSxXQUFXO0lBQzlCLFlBQVksSUFBSSxFQUFFLE1BQU0sQ0FBQyxPQUFPO0lBQ2hDLFlBQVksU0FBUyxFQUFFLE9BQU8sR0FBRyxRQUFRO0lBQ3pDLFlBQVksZUFBZSxFQUFFLFNBQVM7SUFDdEMsWUFBWSxLQUFLLEVBQUUsQ0FBQztJQUNwQixZQUFZLE1BQU0sRUFBRSxDQUFDO0lBQ3JCLFlBQVksQ0FBQyxFQUFFLENBQUM7SUFDaEIsWUFBWSxDQUFDLEVBQUUsQ0FBQztJQUNoQixZQUFZLFVBQVUsRUFBRSxDQUFDLElBQUk7SUFDN0IsZ0JBQWdCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNsQyxvQkFBb0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDO0lBQ3pDO0lBQ0EsaUJBQWlCLE1BQU07SUFDdkIsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQztJQUN4QztJQUNBLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsU0FBUyxFQUFDO0lBQ1YsS0FBSztJQUNMLENBQUM7O0lDcm9CYyxNQUFNLEtBQUssQ0FBQzs7SUFFM0IsSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMseUJBQXlCLEVBQUU7SUFDckUsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsS0FBSzs7SUFFTCxJQUFJLEtBQUssR0FBRztJQUNaLFFBQVEsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO0lBQ3BDLFlBQVksSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxLQUFJO0lBQ25DLFlBQVksSUFBSSxFQUFFLEdBQUcsS0FBSyxHQUFFO0lBQzVCLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUM7SUFDekIsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUTtJQUNqQyxZQUFZLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBQztJQUM3RCxZQUFZLE9BQU8sQ0FBQyxFQUFFLEdBQUcsR0FBRTtJQUMzQixZQUFZLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUM7SUFDNUQsWUFBWSxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBQztJQUN4QyxZQUFZLE9BQU8sR0FBRyxTQUFTLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUM7O0lBRXJELFlBQVksSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUM7O0lBRXJELFlBQVksSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsS0FBSztJQUNsQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsUUFBUTtJQUNqQyxvQkFBb0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUTtJQUM1QyxjQUFhO0lBQ2IsWUFBWSxJQUFJLE9BQU8sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUM7SUFDdEQ7SUFDQSxZQUFZLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRTtJQUMvQyxnQkFBZ0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxlQUFlLEVBQUM7SUFDeEUsYUFBYSxNQUFNLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRTtJQUNyRCxnQkFBZ0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxvQkFBb0IsRUFBQztJQUM1RSxhQUFhLE1BQU07SUFDbkIsZ0JBQWdCLElBQUksQ0FBQyxHQUFHLEdBQUcsYUFBYSxHQUFHLFFBQU87SUFDbEQsYUFBYTtJQUNiLFlBQVksT0FBTyxDQUFDLElBQUksR0FBRyxJQUFHO0lBQzlCLFlBQVksSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUM7SUFDMUQsWUFBWSxRQUFRLENBQUMsU0FBUyxHQUFHLE1BQUs7SUFDdEMsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxNQUFNLEdBQUc7SUFDYixRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQztJQUNsQyxZQUFZLE1BQU07SUFDbEIsUUFBUSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRTtJQUNqRCxRQUFRLElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQ3JELFFBQVEsTUFBTSxDQUFDLFdBQVcsR0FBRyxFQUFDO0lBQzlCLFFBQVEsSUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUM7SUFDakQsUUFBUSxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBQzs7SUFFakQsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFDO0lBQ2xELFFBQVEsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSztJQUMvQixZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDekIsVUFBUztJQUNULFFBQVEsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFNO0lBQ2pELEtBQUs7O0lBRUwsSUFBSSxJQUFJLEdBQUc7SUFDWCxRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUU7SUFDcEIsUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7SUFDdEQsWUFBWSxJQUFJLENBQUMsTUFBTSxHQUFFO0lBQ3pCLEtBQUs7O0lBRUwsSUFBSSxXQUFXLEdBQUc7SUFDbEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFFO0lBQ3BCLFFBQVEsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRO0lBQ2xDLFlBQVksSUFBSSxDQUFDLE1BQU0sR0FBRTtJQUN6QixLQUFLO0lBQ0wsQ0FBQzs7SUN0RUQ7SUFDQTtJQUNBO0FBQ0EsSUFBZSxNQUFNLFFBQVEsQ0FBQzs7SUFFOUI7SUFDQTtJQUNBO0lBQ0EsSUFBSSxRQUFRLENBQUMsT0FBTyxFQUFFO0lBQ3RCLFFBQVEsSUFBSSxVQUFVLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUM7SUFDOUMsUUFBUSxJQUFJLFVBQVUsSUFBSSxJQUFJLEVBQUU7SUFDaEMsWUFBWSxVQUFVLENBQUMsS0FBSyxHQUFFO0lBQzlCLFNBQVM7SUFDVCxRQUFRLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksRUFBQztJQUNuQyxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxVQUFVLENBQUMsT0FBTyxFQUFFO0lBQ3hCLFFBQVEsUUFBUSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUM7SUFDaEMsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxFQUFFO0lBQ3hCLFFBQVEsT0FBTyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7SUFDbEQsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRTtJQUNsQyxRQUFRLE9BQU8sUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQztJQUM1RCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLEdBQUcsQ0FBQyxPQUFPLEVBQUU7SUFDeEIsUUFBUSxPQUFPLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztJQUNsRCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLE1BQU0sQ0FBQyxPQUFPLEVBQUU7SUFDM0IsUUFBUSxRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUM7SUFDOUMsS0FBSzs7SUFFTDtJQUNBLElBQUksS0FBSyxHQUFHO0lBQ1osUUFBUSxPQUFPLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFDO0lBQzVDLEtBQUs7SUFDTCxDQUFDOztJQUVELFFBQVEsQ0FBQyxhQUFhLEdBQUcsSUFBSSxHQUFHOztzQ0FBRSxsQ0NwRWxDO0lBQ0E7QUFDQSxJQUFlLE1BQU0sS0FBSyxTQUFTLFFBQVEsQ0FBQztJQUM1QztJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksV0FBVyxDQUFDO0lBQ2hCLFFBQVEsTUFBTSxHQUFHLElBQUk7SUFDckIsUUFBUSxPQUFPLEdBQUcsSUFBSTtJQUN0QixRQUFRLE9BQU8sR0FBRyxNQUFNO0lBQ3hCLFFBQVEsUUFBUSxHQUFHLEtBQUs7SUFDeEIsUUFBUSxVQUFVLEdBQUcsT0FBTztJQUM1QixRQUFRLE9BQU8sR0FBRyxFQUFFO0lBQ3BCLFFBQVEsU0FBUyxHQUFHLEVBQUU7SUFDdEIsUUFBUSxTQUFTLEdBQUcsS0FBSztJQUN6QixRQUFRLFFBQVEsR0FBRyxJQUFJO0lBQ3ZCLFFBQVEsUUFBUSxHQUFHLEdBQUc7SUFDdEIsUUFBUSxlQUFlLEdBQUcsTUFBTTtJQUNoQyxRQUFRLFdBQVcsR0FBRyxNQUFNO0lBQzVCLFFBQVEsYUFBYSxHQUFHLGNBQWM7SUFDdEMsUUFBUSxNQUFNLEdBQUcsQ0FBQztJQUNsQixRQUFRLFVBQVUsR0FBRyxJQUFJO0lBQ3pCLFFBQVEsU0FBUyxHQUFHLElBQUk7SUFDeEIsUUFBUSxTQUFTLEdBQUcsSUFBSTtJQUN4QixRQUFRLFVBQVUsR0FBRyxJQUFJO0lBQ3pCLFFBQVEsWUFBWSxHQUFHLElBQUk7SUFDM0IsUUFBUSxTQUFTLEdBQUcsS0FBSztJQUN6QixRQUFRLFNBQVMsR0FBRyxDQUFDO0lBQ3JCLFFBQVEsaUJBQWlCLEdBQUcsSUFBSTtJQUNoQyxRQUFRLDBCQUEwQixHQUFHLEtBQUs7SUFDMUMsUUFBUSxXQUFXLEdBQUcsS0FBSztJQUMzQixRQUFRLFFBQVEsR0FBRyxJQUFJO0lBQ3ZCLFFBQVEsTUFBTSxHQUFHLElBQUk7SUFDckIsUUFBUSxPQUFPLEdBQUcsS0FBSztJQUN2QixRQUFRLFFBQVEsR0FBRyxJQUFJO0lBQ3ZCLEtBQUssR0FBRyxFQUFFLEVBQUU7SUFDWixRQUFRLEtBQUssR0FBRTtJQUNmLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxjQUFhO0lBQzFDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFVO0lBQ3BDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLGVBQWUsR0FBRyxnQkFBZTtJQUM5QyxRQUFRLElBQUksQ0FBQyxVQUFVLEdBQUcsV0FBVTtJQUNwQyxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBUztJQUNsQyxRQUFRLElBQUksQ0FBQyxVQUFVLEdBQUcsV0FBVTtJQUNwQyxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBUztJQUNsQyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUcsYUFBWTtJQUN4QyxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTTtJQUM1QixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJLFFBQVEsQ0FBQyxLQUFJO0lBQzdDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGtCQUFpQjtJQUNsRCxRQUFRLElBQUksQ0FBQywwQkFBMEIsR0FBRywyQkFBMEI7SUFDcEUsUUFBUSxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUk7SUFDOUIsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUk7SUFDaEMsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQUs7SUFDM0IsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLFlBQVc7SUFDdEMsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUk7SUFDMUIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDNUIsUUFBUSxJQUFJLE9BQU8sRUFBRTtJQUNyQixZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQzlCLFNBQVM7SUFDVCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUU7SUFDbkI7SUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRTtJQUN2QixRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUM7SUFDcEQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFDO0lBQzNDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBQztJQUN0QztJQUNBLFFBQVFELFVBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUM7SUFDdkQsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDO0lBQ2xELFFBQVFBLFVBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUM7SUFDeEQsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxRQUFPO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLGNBQWMsR0FBRTtJQUM3QixRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtJQUM1QixZQUFZLElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDO0lBQ25ELFlBQVksR0FBRyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFDO0lBQ2hELFlBQVksR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsVUFBUztJQUNwQyxZQUFZLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFdBQVU7SUFDM0MsWUFBWSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQ25DLFlBQVksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsTUFBSztJQUNqQyxZQUFZLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE9BQU07SUFDcEMsWUFBWSxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFNO0lBQ3JDLFlBQVksR0FBRyxDQUFDLE9BQU8sR0FBRyxDQUFDLElBQUk7SUFDL0IsZ0JBQWdCLElBQUksQ0FBQyxLQUFLLEdBQUU7SUFDNUIsY0FBYTtJQUNiLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFDO0lBQ3pDLFNBQVM7SUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtJQUM3QixZQUFZLElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDO0lBQ25ELFlBQVksR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsV0FBVTtJQUMzQyxZQUFZLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDbkMsWUFBWSxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFLO0lBQ3BDLFlBQVksR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTTtJQUNwQyxZQUFZLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDckMsWUFBWSxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQ3JDLFlBQVksR0FBRyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFDO0lBQy9DLFlBQVksR0FBRyxDQUFDLFdBQVcsR0FBRyxDQUFDLElBQUk7SUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sR0FBRTtJQUNoRSxnQkFBZ0IsT0FBTyxJQUFJO0lBQzNCLGNBQWE7SUFDYixZQUFZLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJO0lBQzlCLGdCQUFnQixDQUFDLENBQUMsY0FBYyxHQUFFOztJQUVsQyxnQkFBZ0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQU87SUFDakYsZ0JBQWdCLElBQUksS0FBSyxHQUFHO0lBQzVCLG9CQUFvQixDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDcEQsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNwRCxrQkFBaUI7O0lBRWpCLGdCQUFnQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLEdBQUU7SUFDaEUsZ0JBQWdCLElBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2hELG9CQUFvQixNQUFNOztJQUUxQixnQkFBZ0IsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixHQUFFO0lBQ3pELGdCQUFnQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxFQUFDO0lBQ2hELGdCQUFnQixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxFQUFDO0lBQ2xELGdCQUFnQixNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLEdBQUcsS0FBSTtJQUNqRCxnQkFBZ0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLEtBQUk7O0lBRW5ELGdCQUFnQixRQUFRLElBQUksQ0FBQyxhQUFhO0lBQzFDLG9CQUFvQixLQUFLLFlBQVksQ0FBQztJQUN0QyxvQkFBb0IsS0FBSyxjQUFjO0lBQ3ZDLHdCQUF3QixJQUFJLE1BQU0sR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFDO0lBQzFFLHdCQUF3QixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSTtJQUMzRSx3QkFBd0IsS0FBSztJQUM3QixvQkFBb0I7SUFDcEIsd0JBQXdCLEtBQUs7SUFDN0IsaUJBQWlCO0lBQ2pCO0lBQ0EsZ0JBQWdCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxvQkFBb0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFDO0lBQ25FLGlCQUFpQjtJQUNqQixjQUFhO0lBQ2IsWUFBWSxHQUFHLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxJQUFHO0lBQ3BDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFDO0lBQ3pDLFNBQVM7OztJQUdULFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUU7SUFDakMsWUFBWSxRQUFRLEdBQUc7SUFDdkIsZ0JBQWdCLEtBQUssVUFBVTtJQUMvQixvQkFBb0IsS0FBSztJQUN6QixnQkFBZ0IsS0FBSyxNQUFNO0lBQzNCLG9CQUFvQixJQUFJLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBQztJQUM3RCxvQkFBb0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFDO0lBQ2xELG9CQUFvQixJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUM7SUFDakQsb0JBQW9CQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUM7SUFDeEUsb0JBQW9CQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUM7SUFDM0Qsb0JBQW9CQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUM7SUFDM0Qsb0JBQW9CLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSTtJQUM1QyxvQkFBb0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFJO0lBQ3RDLG9CQUFvQixLQUFLO0lBQ3pCLGdCQUFnQixLQUFLLEtBQUs7SUFDMUIsb0JBQW9CLEtBQUssQ0FBQyx1QkFBdUIsRUFBQztJQUNsRCxvQkFBb0IsS0FBSztJQUN6QixnQkFBZ0IsS0FBSyxRQUFRO0lBQzdCLG9CQUFvQixJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBQztJQUNqRSxvQkFBb0IsTUFBTSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFDO0lBQ3pELG9CQUFvQixNQUFNLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUM7SUFDN0Msb0JBQW9CLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJO0lBQ3pDLHdCQUF3QixJQUFJLElBQUksR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxLQUFJO0lBQ3JFLHdCQUF3QixJQUFJLFFBQVEsR0FBRyxJQUFJLGdCQUFnQixDQUFDLE1BQU07SUFDbEUsNEJBQTRCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFDO0lBQ3RELHlCQUF5QixFQUFDO0lBQzFCLHdCQUF3QixRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFO0lBQ3hFLDRCQUE0QixVQUFVLEVBQUUsSUFBSTtJQUM1Qyw0QkFBNEIsT0FBTyxFQUFFLElBQUk7SUFDekMsNEJBQTRCLFNBQVMsRUFBRSxJQUFJO0lBQzNDLDRCQUE0QixhQUFhLEVBQUUsSUFBSTtJQUMvQyx5QkFBeUIsRUFBQztJQUMxQix3QkFBd0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUM7SUFDNUUsd0JBQXdCLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFDO0lBQzlFLHdCQUF3QixNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcsS0FBSTtJQUNyRCx3QkFBd0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLEtBQUk7SUFDdEQsd0JBQXdCLElBQUksQ0FBQyxpQkFBaUIsR0FBRTtJQUNoRCx3QkFBd0IsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksRUFBRTtJQUNqRCw0QkFBNEIsSUFBSSxDQUFDLE1BQU0sR0FBRTtJQUN6Qyx5QkFBeUI7SUFDekIsd0JBQXdCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSTtJQUMxQyxzQkFBcUI7SUFDckIsb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBQztJQUNwRCxvQkFBb0JBLFVBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztJQUM3RCxvQkFBb0IsSUFBSSxDQUFDLGFBQWEsR0FBRTtJQUN4QyxvQkFBb0IsTUFBTTtJQUMxQixnQkFBZ0IsS0FBSyxNQUFNO0lBQzNCLG9CQUFvQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQUs7SUFDdkMsb0JBQW9CLElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDO0lBQzNELG9CQUFvQkEsVUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsY0FBYyxFQUFDO0lBQzFELG9CQUFvQixJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUM7SUFDakQsb0JBQW9CLEdBQUcsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUk7SUFDaEQ7SUFDQSxvQkFBb0IsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLFNBQVE7SUFDbkQsb0JBQW9CLElBQUksUUFBUSxFQUFFO0lBQ2xDLHdCQUF3QixJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQ3ZFLHdCQUF3QixJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxFQUFFO0lBQ3ZELDRCQUE0QixHQUFHLENBQUMsU0FBUyxHQUFHLENBQUMsdURBQXVELEVBQUUsUUFBUSxDQUFDLElBQUksRUFBQztJQUNwSCw0QkFBNEIsSUFBSSxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsa0JBQWlCO0lBQ3JFLHlCQUF5QjtJQUN6QixxQkFBcUI7SUFDckIseUJBQXlCO0lBQ3pCLHdCQUF3QixJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxpQkFBaUIsSUFBSSxJQUFHO0lBQ3hFLHFCQUFxQjtJQUNyQixvQkFBb0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBQztJQUN2RCxvQkFBb0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUM7SUFDckUsb0JBQW9CLElBQUksS0FBSyxHQUFHLEVBQUM7SUFDakMsb0JBQW9CLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7SUFDM0Msd0JBQXdCLElBQUksS0FBSyxHQUFHLEVBQUM7SUFDckMsd0JBQXdCLEtBQUssSUFBSSxLQUFLLElBQUksTUFBTSxFQUFFO0lBQ2xELDRCQUE0QixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ25GLGdDQUFnQyxLQUFLLElBQUksRUFBQztJQUMxQyxnQ0FBZ0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFDO0lBQzVFLGdDQUFnQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSTtJQUNwRCxvQ0FBb0MsS0FBSyxJQUFJLEVBQUM7SUFDOUMsb0NBQW9DLElBQUksS0FBSyxJQUFJLEtBQUssRUFBRTtJQUN4RCx3Q0FBd0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFJO0lBQzFELHdDQUF3QyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxFQUFFO0lBQ2pFLDRDQUE0QyxJQUFJLENBQUMsTUFBTSxHQUFFO0lBQ3pELHlDQUF5QztJQUN6QyxxQ0FBcUM7SUFDckMsa0NBQWlDO0lBQ2pDLDZCQUE2QjtJQUM3Qix5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLG9CQUFvQixJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUU7SUFDcEMsd0JBQXdCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSTtJQUMxQyxxQkFBcUI7SUFDckIsb0JBQW9CLEtBQUs7SUFDekIsZ0JBQWdCLEtBQUssTUFBTTtJQUMzQixvQkFBb0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFJO0lBQ3RDLG9CQUFvQkEsVUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBQztJQUNuRSxvQkFBb0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksRUFBQztJQUMxRCxvQkFBb0IsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsS0FBSTtJQUNwRCxvQkFBb0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBQztJQUN2RCxvQkFBb0IsS0FBSztJQUN6QixnQkFBZ0I7SUFDaEIsb0JBQW9CLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxHQUFHLEVBQUM7SUFDNUQsb0JBQW9CLEtBQUs7SUFDekIsYUFBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxhQUFhLEdBQUU7SUFDNUIsUUFBUSxJQUFJLENBQUMsaUJBQWlCLEdBQUU7SUFDaEMsUUFBUSxJQUFJLENBQUMsaUJBQWlCLEdBQUU7SUFDaEMsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxDQUFDLEVBQUU7SUFDbkIsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBQztJQUMxQyxRQUFRLElBQUksT0FBTyxFQUFFO0lBQ3JCLFlBQVksSUFBSSxDQUFDLEtBQUssR0FBRTtJQUN4QixTQUFTO0lBQ1QsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLGlCQUFpQixHQUFFO0lBQ3BDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksaUJBQWlCLEdBQUc7SUFDeEIsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBVztJQUNwQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLElBQUksTUFBTSxDQUFDLFlBQVk7SUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBQztJQUMxRyxpQkFBaUIsSUFBSSxNQUFNLENBQUMsVUFBVTtJQUN0QyxnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFDO0lBQ3pHO0lBQ0EsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBQztJQUN4RyxTQUFTLE1BQU07SUFDZixZQUFZLElBQUksTUFBTSxDQUFDLFlBQVk7SUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBQztJQUM1RyxpQkFBaUIsSUFBSSxNQUFNLENBQUMsVUFBVTtJQUN0QyxnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFDO0lBQzNHO0lBQ0EsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBQztJQUMxRyxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLGlCQUFpQixHQUFHO0lBQ3hCLFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQzVCLFlBQVksSUFBSSxDQUFDLGlCQUFpQixHQUFFO0lBQ3BDLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksWUFBWSxDQUFDLENBQUMsRUFBRTtJQUNwQixRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtJQUM5QixZQUFZLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBQztJQUN4RCxZQUFZLE9BQU8sSUFBSSxJQUFJLElBQUk7SUFDL0IsU0FBUztJQUNULFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7O0lBRUwsSUFBSSxhQUFhLENBQUMsTUFBTSxFQUFFO0lBQzFCLFFBQVEsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsS0FBSTtJQUNyRCxRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFDO0lBQzVELFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDOUQsUUFBUSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcsS0FBSTtJQUNyQyxRQUFRLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxLQUFJO0lBQ3RDLEtBQUs7O0lBRUwsSUFBSSxjQUFjLEdBQUc7SUFDckIsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDNUIsWUFBWSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNyQyxZQUFZLE1BQU0sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLElBQUksRUFBQztJQUNsRCxZQUFZLE1BQU0sQ0FBQyxXQUFXLEdBQUcsQ0FBQyxJQUFJO0lBQ3RDLGdCQUFnQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLEdBQUU7SUFDaEUsZ0JBQWdCLElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDO0lBQ3ZELGdCQUFnQixHQUFHLENBQUMsR0FBRyxHQUFHLGdGQUErRTtJQUN6RyxnQkFBZ0IsQ0FBQyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDdEQsY0FBYTtJQUNiLFlBQVksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUk7SUFDakMsZ0JBQWdCLENBQUMsQ0FBQyxjQUFjLEdBQUU7SUFDbEMsZ0JBQWdCLElBQUksS0FBSyxHQUFHO0lBQzVCLG9CQUFvQixDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDcEQsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNwRCxrQkFBaUI7SUFDakIsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sR0FBRTtJQUNoRSxnQkFBZ0IsSUFBSSxJQUFJLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFDO0lBQ3hELGdCQUFnQixJQUFJLEdBQUcsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUM7O0lBRXRELGdCQUFnQixNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFJO0lBQ3pELGdCQUFnQixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFJOztJQUV2RDtJQUNBLGdCQUFnQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDakMsb0JBQW9CLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUM7SUFDbEQsaUJBQWlCOztJQUVqQixnQkFBZ0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEdBQUU7SUFDN0MsY0FBYTtJQUNiLFlBQVksTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLElBQUk7SUFDcEMsZ0JBQWdCLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLEtBQUk7SUFDN0QsZ0JBQWdCLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLEtBQUk7SUFDM0QsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSTtJQUN0QyxjQUFhO0lBQ2IsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFOztJQUV4QixLQUFLOztJQUVMLElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUU7SUFDakMsUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFDO0lBQzNDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUM1QyxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUM7SUFDN0MsS0FBSzs7SUFFTCxJQUFJLGlCQUFpQixHQUFHO0lBQ3hCLFFBQVFBLFVBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUM7SUFDNUQsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFFO0lBQ3JCO0lBQ0EsS0FBSzs7SUFFTDtJQUNBO0lBQ0EsSUFBSSxNQUFNLEdBQUcsR0FBRzs7O0lBR2hCLElBQUksTUFBTSxHQUFHO0lBQ2IsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDOUMsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQ2pELFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQ3JDLEtBQUs7O0lBRUw7SUFDQTtJQUNBLElBQUksS0FBSyxHQUFHO0lBQ1o7SUFDQSxRQUFRLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNyQyxRQUFRLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtJQUMvQixZQUFZLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFDO0lBQ3hELFNBQVM7SUFDVCxhQUFhO0lBQ2IsWUFBWSxJQUFJLENBQUMsTUFBTSxHQUFFO0lBQ3pCLFNBQVM7SUFDVCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLFFBQVEsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFO0lBQzdCLFFBQVEsSUFBSSxJQUFJLEdBQUcsQ0FBQyxPQUFPLFlBQVksS0FBSyxJQUFJLE9BQU8sR0FBRyxDQUFDLE9BQU8sRUFBQztJQUNuRSxRQUFRLEtBQUssSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFO0lBQzlCLFlBQVksSUFBSSxLQUFLLEVBQUU7SUFDdkIsZ0JBQWdCLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLHVCQUFzQjtJQUM3RCxhQUFhO0lBQ2IsWUFBWSxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFLO0lBQ3JDLFNBQVM7SUFDVDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE1BQU0sR0FBRztJQUNiLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBQztJQUMzRCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBQztJQUMzQixRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7SUFDMUMsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDekIsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBQztJQUMvQixZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDekIsU0FBUztJQUNULGFBQWE7SUFDYixZQUFZLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDL0QsWUFBWSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU07SUFDaEMsZ0JBQWdCLElBQUksQ0FBQyxpQkFBaUIsR0FBRTtJQUN4QyxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUM7SUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDN0IsY0FBYTtJQUNiLFNBQVM7SUFDVCxRQUFRLE9BQU8sSUFBSTtJQUNuQixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtJQUN0QixRQUFRQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFDO0lBQzFFLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksZ0JBQWdCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzFDLFFBQVEsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFFO0lBQ3pCLFFBQVEsT0FBTyxFQUFFO0lBQ2pCLEtBQUs7O0lBRUwsSUFBSSxnQkFBZ0IsR0FBRztJQUN2QixRQUFRLE9BQU87SUFDZixZQUFZLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVc7SUFDOUMsWUFBWSxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZO0lBQ2hELFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksZUFBZSxHQUFHO0lBQ3RCLFFBQVEsT0FBTztJQUNmLFlBQVksS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVztJQUMzQyxZQUFZLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVk7SUFDN0MsU0FBUztJQUNULEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxtQkFBbUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0lBQzlCLFFBQVEsSUFBSSxVQUFVLEdBQUcsU0FBUTtJQUNqQyxRQUFRLElBQUksUUFBUSxHQUFHLFNBQVE7SUFDL0IsUUFBUSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsR0FBRTtJQUN2RCxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUM7SUFDOUQsUUFBUSxJQUFJLEtBQUssQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLElBQUksRUFBRTtJQUNyQyxZQUFZLFFBQVEsR0FBRyxNQUFLO0lBQzVCLFNBQVM7SUFDVCxRQUFRLElBQUksS0FBSyxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsSUFBSSxFQUFFO0lBQ3JDLFlBQVksUUFBUSxHQUFHLFNBQVE7SUFDL0IsU0FBUztJQUNULFFBQVEsSUFBSSxLQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEVBQUU7SUFDcEMsWUFBWSxVQUFVLEdBQUcsT0FBTTtJQUMvQixTQUFTO0lBQ1QsUUFBUSxJQUFJLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksRUFBRTtJQUNwQyxZQUFZLFVBQVUsR0FBRyxRQUFPO0lBQ2hDLFNBQVM7SUFDVCxRQUFRLElBQUksTUFBTSxHQUFHLFFBQVEsR0FBRyxXQUFVO0lBQzFDLFFBQVEsSUFBSSxNQUFNLElBQUksY0FBYztJQUNwQyxZQUFZLE9BQU8sSUFBSSxDQUFDLGFBQWE7SUFDckMsUUFBUSxPQUFPLE1BQU07SUFDckIsS0FBSzs7SUFFTCxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7SUFDbkIsUUFBUSxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBQztJQUN2QixRQUFRLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFDO0lBQ3ZCLFFBQVEsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLGNBQWE7SUFDOUMsUUFBUSxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxFQUFFO0lBQ3JDLFlBQVksYUFBYSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQzFELFNBQVM7SUFDVCxRQUFRQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsRUFBQztJQUNyRSxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLFFBQVEsR0FBRyxjQUFhO0lBQ3ZELFFBQVEsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxHQUFFOztJQUV0RDtJQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7SUFDcEMsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBQztJQUNoRCxZQUFZLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU07SUFDbkYsWUFBWSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBQztJQUNqRCxZQUFZLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQUs7SUFDakY7SUFDQSxZQUFZLFFBQVEsYUFBYTtJQUNqQyxnQkFBZ0IsS0FBSyxZQUFZLENBQUM7SUFDbEMsZ0JBQWdCLEtBQUssYUFBYSxDQUFDO0lBQ25DLGdCQUFnQixLQUFLLGNBQWM7SUFDbkMsb0JBQW9CLENBQUMsR0FBRyxNQUFLO0lBQzdCLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLDBCQUEwQjtJQUN4RCx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLE9BQU8sSUFBSSxFQUFDO0lBQ2xELG9CQUFvQixLQUFLO0lBQ3pCLGdCQUFnQixLQUFLLFNBQVMsQ0FBQztJQUMvQixnQkFBZ0IsS0FBSyxVQUFVLENBQUM7SUFDaEMsZ0JBQWdCLEtBQUssV0FBVztJQUNoQyxvQkFBb0IsQ0FBQyxHQUFHLFNBQVE7SUFDaEMsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCO0lBQ3hELHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsT0FBTyxJQUFJLEVBQUM7SUFDbEQsb0JBQW9CLEtBQUs7SUFDekIsZ0JBQWdCLEtBQUssYUFBYTtJQUNsQyxvQkFBb0IsQ0FBQyxHQUFHLE9BQU07SUFDOUIsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCO0lBQ3hELHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsUUFBUSxJQUFJLEVBQUM7SUFDbEQsb0JBQW9CLEtBQUs7SUFDekIsZ0JBQWdCLEtBQUssWUFBWTtJQUNqQyxvQkFBb0IsQ0FBQyxHQUFHLFFBQU87SUFDL0Isb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCO0lBQ3hELHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsUUFBUSxJQUFJLEVBQUM7SUFDbEQsb0JBQW9CLEtBQUs7SUFDekIsZ0JBQWdCO0lBQ2hCLG9CQUFvQixLQUFLO0lBQ3pCLGFBQWE7SUFDYixTQUFTOztJQUVUO0lBQ0EsUUFBUSxRQUFRLGFBQWE7SUFDN0IsWUFBWSxLQUFLLFlBQVk7SUFDN0IsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBTztJQUNqQyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFTO0lBQ25DLGdCQUFnQixDQUFDLElBQUksT0FBTTtJQUMzQixnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBQztJQUN2QyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFTO0lBQ25DLGdCQUFnQixLQUFLO0lBQ3JCLFlBQVksS0FBSyxhQUFhO0lBQzlCLGdCQUFnQixDQUFDLElBQUksTUFBSztJQUMxQixnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFPO0lBQ2pDLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFVBQVM7SUFDbkMsZ0JBQWdCLENBQUMsSUFBSSxPQUFNO0lBQzNCLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFDO0lBQ3ZDLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFVBQVM7SUFDbkMsZ0JBQWdCLEtBQUs7SUFDckIsWUFBWSxLQUFLLGNBQWM7SUFDL0IsZ0JBQWdCLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBQztJQUM5QixnQkFBZ0IsQ0FBQyxJQUFJLE9BQU07SUFDM0IsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUM7SUFDdkMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBUztJQUNuQyxnQkFBZ0IsS0FBSztJQUNyQixZQUFZLEtBQUssU0FBUztJQUMxQixnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFPO0lBQ2pDLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFVBQVM7SUFDbkMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUM7SUFDdkMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBUztJQUNuQyxnQkFBZ0IsS0FBSztJQUNyQixZQUFZLEtBQUssVUFBVTtJQUMzQixnQkFBZ0IsQ0FBQyxJQUFJLE1BQUs7SUFDMUIsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBTztJQUNqQyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFTO0lBQ25DLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFDO0lBQ3ZDLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFVBQVM7SUFDbkMsZ0JBQWdCLEtBQUs7SUFDckIsWUFBWSxLQUFLLFdBQVc7SUFDNUIsZ0JBQWdCLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBQztJQUM5QixnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBQztJQUN2QyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFTO0lBQ25DLGdCQUFnQixLQUFLO0lBQ3JCLFlBQVksS0FBSyxhQUFhO0lBQzlCLGdCQUFnQixDQUFDLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBQztJQUMvQyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFTO0lBQ25DLGdCQUFnQixDQUFDLElBQUksTUFBTSxHQUFHLEVBQUM7SUFDL0IsZ0JBQWdCLEtBQUs7SUFDckIsWUFBWSxLQUFLLFlBQVk7SUFDN0I7SUFDQSxnQkFBZ0IsQ0FBQyxJQUFJLE1BQU0sR0FBRyxFQUFDO0lBQy9CLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFDO0lBQ3ZDLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLFVBQVM7SUFDbkMsZ0JBQWdCLEtBQUs7SUFDckIsWUFBWTtJQUNaLGdCQUFnQixLQUFLO0lBQ3JCLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUM5QixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDbEIsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBQztJQUMzQixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDckIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0EsSUFBSSxZQUFZLEdBQUc7SUFDbkIsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNsQyxRQUFRLElBQUksS0FBSyxHQUFHO0lBQ3BCLFlBQVksUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSTtJQUMxQyxZQUFZLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtJQUMvQixZQUFZLFFBQVEsRUFBRSxVQUFVO0lBQ2hDLFVBQVM7SUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFJO0lBQ2pELFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQzNCLFlBQVksTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7SUFDakMsZ0JBQWdCLFlBQVksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSTtJQUNqRSxnQkFBZ0IsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO0lBQ3JELGdCQUFnQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJO0lBQzVDLGdCQUFnQixTQUFTLEVBQUUsZ0NBQWdDO0lBQzNELGdCQUFnQixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7SUFDM0MsZ0JBQWdCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtJQUN2QyxnQkFBZ0IsTUFBTSxFQUFFLE9BQU87SUFDL0IsZ0JBQWdCLElBQUksRUFBRSxPQUFPO0lBQzdCLGFBQWEsRUFBQztJQUNkLFNBQVM7O0lBRVQsUUFBUSxPQUFPLEtBQUs7SUFDcEIsS0FBSzs7SUFFTDtJQUNBO0lBQ0EsSUFBSSxVQUFVLENBQUMsYUFBYSxHQUFHLElBQUksRUFBRTtJQUNyQyxRQUFRLElBQUksYUFBYSxJQUFJLElBQUksRUFBRTtJQUNuQyxZQUFZLGFBQWEsR0FBRyxJQUFJLENBQUMsY0FBYTtJQUM5QyxTQUFTO0lBQ1QsUUFBUSxJQUFJLEtBQUssR0FBRyxFQUFDO0lBQ3JCLFFBQVEsSUFBSSxNQUFNLEdBQUcsRUFBQztJQUN0QixRQUFRLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFPO0lBQy9CLFFBQVEsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLGVBQWUsR0FBRTtJQUN6QyxRQUFRLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUM3QyxZQUFZLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFDO0lBQ2pFLFNBQVM7SUFDVCxRQUFRLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRTtJQUM5QyxZQUFZLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBUztJQUNsRCxTQUFTO0lBQ1QsUUFBUSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFJO0FBQ3RDLEFBRUE7SUFDQSxRQUFRLElBQUksYUFBYSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRTtJQUNoRCxZQUFZLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUM5QixnQkFBZ0IsT0FBTztJQUN2QixvQkFBb0IsS0FBSztJQUN6QixvQkFBb0IsTUFBTTtJQUMxQixvQkFBb0IsSUFBSTtJQUN4QixvQkFBb0IsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJO0lBQ2xELG9CQUFvQixRQUFRLEVBQUUsVUFBVTtJQUN4QyxvQkFBb0IsV0FBVyxFQUFFLE9BQU87SUFDeEMsb0JBQW9CLGNBQWMsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUk7SUFDekQsb0JBQW9CLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLHNCQUFzQjtJQUN4RSxvQkFBb0IsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsc0JBQXNCO0lBQ3ZFLG9CQUFvQixZQUFZLEVBQUUsQ0FBQztJQUNuQyxpQkFBaUI7O0lBRWpCLGFBQWEsTUFBTTtJQUNuQixnQkFBZ0IsT0FBTztJQUN2QixvQkFBb0IsS0FBSztJQUN6QixvQkFBb0IsTUFBTTtJQUMxQixvQkFBb0IsSUFBSTtJQUN4QixvQkFBb0IsU0FBUyxFQUFFLGdDQUFnQztJQUMvRCxvQkFBb0IsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJO0lBQ2xELG9CQUFvQixRQUFRLEVBQUUsVUFBVTtJQUN4QyxvQkFBb0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQyxlQUFlO0lBQ2xGLG9CQUFvQixXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxzQkFBc0I7SUFDeEUsb0JBQW9CLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLHNCQUFzQjtJQUN2RSxvQkFBb0IsWUFBWSxFQUFFLENBQUM7SUFDbkMsaUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxJQUFJLGFBQWEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUU7SUFDN0MsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDOUIsZ0JBQWdCLE9BQU87SUFDdkIsb0JBQW9CLEtBQUs7SUFDekIsb0JBQW9CLE1BQU07SUFDMUIsb0JBQW9CLElBQUk7SUFDeEIsb0JBQW9CLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSTtJQUMvQyxvQkFBb0IsUUFBUSxFQUFFLFVBQVU7SUFDeEMsb0JBQW9CLFdBQVcsRUFBRSxPQUFPO0lBQ3hDLG9CQUFvQixpQkFBaUIsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUk7SUFDNUQsb0JBQW9CLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLHNCQUFzQjtJQUN4RSxvQkFBb0IsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsc0JBQXNCO0lBQ3ZFLG9CQUFvQixTQUFTLEVBQUUsQ0FBQztJQUNoQyxpQkFBaUI7SUFDakIsYUFBYSxNQUFNO0lBQ25CLGdCQUFnQixPQUFPO0lBQ3ZCLG9CQUFvQixLQUFLO0lBQ3pCLG9CQUFvQixNQUFNO0lBQzFCLG9CQUFvQixJQUFJO0lBQ3hCLG9CQUFvQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUk7SUFDL0Msb0JBQW9CLFFBQVEsRUFBRSxVQUFVO0lBQ3hDLG9CQUFvQixZQUFZLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWU7SUFDckYsb0JBQW9CLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLHNCQUFzQjtJQUN4RSxvQkFBb0IsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsc0JBQXNCO0lBQ3ZFLG9CQUFvQixTQUFTLEVBQUUsQ0FBQztJQUNoQyxpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFNBQVM7O0lBRVQsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7O0lBRTFCLFlBQVksSUFBSSxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO0lBQ2hELGdCQUFnQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsR0FBRyxLQUFJO0lBQ2pELGFBQWE7O0lBRWIsWUFBWSxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDakQsZ0JBQWdCLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUk7SUFDeEMsYUFBYTs7O0lBR2IsWUFBWSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBUztJQUN0RCxZQUFZLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUk7OztJQUd4QyxZQUFZLE9BQU87SUFDbkIsZ0JBQWdCLEtBQUs7SUFDckIsZ0JBQWdCLE1BQU07SUFDdEIsZ0JBQWdCLElBQUk7SUFDcEIsZ0JBQWdCLEdBQUc7SUFDbkIsZ0JBQWdCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxTQUFTO0lBQ2hELGdCQUFnQixlQUFlLEVBQUUsSUFBSSxDQUFDLFNBQVM7SUFDL0MsZ0JBQWdCLFFBQVEsRUFBRSxVQUFVO0lBQ3BDLGdCQUFnQixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxzQkFBc0I7SUFDbEUsZ0JBQWdCLFlBQVksRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLHNCQUFzQjtJQUNyRSxhQUFhOztJQUViLFNBQVMsTUFBTTtJQUNmLFlBQVksSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyx1QkFBc0I7SUFDckUsWUFBWSxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLHVCQUFzQjtJQUNwRSxZQUFZLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFTO0lBQ3RELFlBQVksSUFBSSxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO0lBQ2hELGdCQUFnQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsR0FBRyxLQUFJO0lBQ2pELGdCQUFnQixXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFlO0lBQ2pGLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcscUNBQW9DO0lBQ25GLGFBQWE7SUFDYixZQUFZLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUNqRCxnQkFBZ0IsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSTtJQUN4QyxnQkFBZ0IsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQyxnQkFBZTtJQUNoRixnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLG1DQUFrQztJQUNqRixhQUFhOztJQUViLFlBQVksR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSTs7O0lBR3hDLFlBQVksT0FBTztJQUNuQixnQkFBZ0IsS0FBSztJQUNyQixnQkFBZ0IsTUFBTTtJQUN0QixnQkFBZ0IsSUFBSTtJQUNwQixnQkFBZ0IsR0FBRztJQUNuQixnQkFBZ0IsV0FBVztJQUMzQixnQkFBZ0IsVUFBVTtJQUMxQjtJQUNBLGdCQUFnQixRQUFRLEVBQUUsVUFBVTtJQUNwQyxnQkFBZ0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsc0JBQXNCO0lBQ2xFLGdCQUFnQixZQUFZLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxzQkFBc0I7SUFDckUsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLElBQUk7SUFDZixRQUFRLE9BQU87SUFDZixRQUFRLEtBQUs7SUFDYixRQUFRO0lBQ1IsWUFBWSxNQUFNLEdBQUcsSUFBSTtJQUN6QixZQUFZLE9BQU8sR0FBRyxNQUFNO0lBQzVCLFlBQVksUUFBUSxHQUFHLEtBQUs7SUFDNUIsWUFBWSxVQUFVLEdBQUcsT0FBTztJQUNoQyxZQUFZLE9BQU8sR0FBRyxFQUFFO0lBQ3hCLFlBQVksU0FBUyxHQUFHLEVBQUU7SUFDMUIsWUFBWSxTQUFTLEdBQUcsS0FBSztJQUM3QixZQUFZLFFBQVEsR0FBRyxJQUFJO0lBQzNCLFlBQVksUUFBUSxHQUFHLEdBQUc7SUFDMUIsWUFBWSxlQUFlLEdBQUcsTUFBTTtJQUNwQyxZQUFZLE1BQU0sR0FBRyxDQUFDO0lBQ3RCLFlBQVksV0FBVyxHQUFHLE1BQU07SUFDaEMsWUFBWSxTQUFTLEdBQUcsSUFBSTtJQUM1QixZQUFZLFVBQVUsR0FBRyxJQUFJO0lBQzdCLFlBQVksWUFBWSxHQUFHLElBQUk7SUFDL0IsWUFBWSxTQUFTLEdBQUcsSUFBSTtJQUM1QixZQUFZLFVBQVUsR0FBRyxJQUFJO0lBQzdCLFlBQVksU0FBUyxHQUFHLEtBQUs7SUFDN0IsWUFBWSxTQUFTLEdBQUcsQ0FBQztJQUN6QixZQUFZLGlCQUFpQixHQUFHLElBQUk7SUFDcEMsWUFBWSwwQkFBMEIsR0FBRyxLQUFLO0lBQzlDLFlBQVksV0FBVyxHQUFHLEtBQUs7SUFDL0IsWUFBWSxRQUFRLEdBQUcsSUFBSTtJQUMzQixZQUFZLE1BQU0sR0FBRyxJQUFJO0lBQ3pCLFNBQVMsR0FBRyxFQUFFO0lBQ2QsTUFBTTs7O0lBR04sUUFBUSxJQUFJLGFBQWEsR0FBRyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxXQUFXLEdBQUcsZUFBYztJQUN0RixRQUFRLElBQUksS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDO0lBQzlCLFlBQVksTUFBTTtJQUNsQixZQUFZLE9BQU87SUFDbkIsWUFBWSxVQUFVO0lBQ3RCLFlBQVksUUFBUTtJQUNwQixZQUFZLE9BQU87SUFDbkIsWUFBWSxTQUFTO0lBQ3JCLFlBQVksU0FBUztJQUNyQixZQUFZLFFBQVE7SUFDcEIsWUFBWSxRQUFRO0lBQ3BCLFlBQVksZUFBZTtJQUMzQixZQUFZLFdBQVc7SUFDdkIsWUFBWSxhQUFhO0lBQ3pCLFlBQVksTUFBTTtJQUNsQixZQUFZLFNBQVM7SUFDckIsWUFBWSxVQUFVO0lBQ3RCLFlBQVksWUFBWTtJQUN4QixZQUFZLFNBQVM7SUFDckIsWUFBWSxVQUFVO0lBQ3RCLFlBQVksU0FBUztJQUNyQixZQUFZLFNBQVM7SUFDckIsWUFBWSxpQkFBaUI7SUFDN0IsWUFBWSwwQkFBMEI7SUFDdEMsWUFBWSxXQUFXO0lBQ3ZCLFlBQVksUUFBUTtJQUNwQixZQUFZLE1BQU07SUFDbEIsU0FBUyxFQUFDO0lBQ1YsUUFBUSxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBQztJQUMvQixRQUFRLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBQztJQUNwQyxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxVQUFVLENBQUMsT0FBTyxHQUFHLE1BQU0sRUFBRTtJQUN4QyxRQUFRLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBQztJQUN2RCxRQUFRLElBQUksS0FBSyxJQUFJLElBQUksRUFBRTtJQUMzQixZQUFZLEtBQUssQ0FBQyxLQUFLLEdBQUU7SUFDekIsU0FBUztJQUNULEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTSxFQUFFO0lBQ3BDLFFBQVEsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFDO0lBQ3ZELFFBQVEsSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFO0lBQzNCLFlBQVksS0FBSyxDQUFDLE1BQU0sR0FBRTtJQUMxQixTQUFTO0lBQ1QsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRTtJQUM3QixRQUFRLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFNO0lBQ2pDLFFBQVEsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQUs7SUFDM0IsUUFBUSxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBSztJQUMzQixRQUFRLEtBQUssSUFBSSxJQUFJLElBQUksTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFFO0lBQ2xELFlBQVksSUFBSSxPQUFPLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQUs7SUFDdkUsWUFBWSxJQUFJLE9BQU8sR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTTtJQUN0RSxZQUFZLElBQUksT0FBTyxJQUFJLE9BQU8sRUFBRTtJQUNwQyxnQkFBZ0IsT0FBTyxJQUFJO0lBQzNCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sWUFBWSxDQUFDLEtBQUssRUFBRTtJQUMvQixRQUFRLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFNO0lBQ2pDLFFBQVEsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQUs7SUFDM0IsUUFBUSxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBSztJQUMzQixRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFDO0lBQzFDLFFBQVEsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFO0lBQzFCLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFDO0lBQzFDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFDO0lBQzFDLFNBQVM7SUFDVCxRQUFRLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0lBQ3ZCLEtBQUs7SUFDTCxDQUFDOztJQ2w4QkQ7SUFDQTtBQUNBLElBQWUsTUFBTUUsV0FBUyxTQUFTLEtBQUssQ0FBQztJQUM3QztJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLFdBQVcsQ0FBQyxFQUFFLE1BQU0sR0FBRyxJQUFJO0lBQy9CLFFBQVEsUUFBUSxHQUFHLElBQUk7SUFDdkIsUUFBUSxRQUFRLEdBQUcsS0FBSztJQUN4QixRQUFRLFVBQVUsR0FBRyxPQUFPO0lBQzVCLFFBQVEsT0FBTyxHQUFHLEVBQUU7SUFDcEIsUUFBUSxNQUFNLEdBQUcsQ0FBQztJQUNsQixRQUFRLE9BQU8sR0FBRyxLQUFLO0lBQ3ZCLFFBQVEsU0FBUyxHQUFHLEtBQUs7SUFDekIsUUFBUSxTQUFTLEdBQUcsRUFBRTtJQUN0QixRQUFRLFFBQVEsR0FBRyxHQUFHO0lBQ3RCLFFBQVEsZUFBZSxHQUFHLE1BQU07SUFDaEMsUUFBUSxXQUFXLEdBQUcsTUFBTTtJQUM1QixRQUFRLGNBQWMsR0FBRyxPQUFPO0lBQ2hDLFFBQVEsYUFBYSxHQUFHLFlBQVk7SUFDcEMsUUFBUSxVQUFVLEdBQUcsSUFBSTtJQUN6QixRQUFRLFNBQVMsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7SUFDakMsUUFBUSxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsRUFBQztJQUN2SSxRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUTtJQUNoQyxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTTtJQUM1QixRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBUztJQUNsQyxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUcsZUFBYztJQUM1QyxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUU7O0lBRXBCLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFFO0lBQ3ZCLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBQztJQUNwRCxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTTtJQUMvQyxRQUFRRixVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxFQUFDO0lBQ3ZELFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBQztJQUNsRCxRQUFRQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFDO0lBQ3hELFFBQVEsS0FBSyxJQUFJLEdBQUcsSUFBSSxRQUFRLEVBQUU7SUFDbEMsWUFBWSxJQUFJLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBQztJQUNwRCxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksRUFBQztJQUMxQyxZQUFZLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBRztJQUNoQyxZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFPO0lBQzNFLFlBQVlBLFVBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFDO0lBQ25GLFlBQVlBLFVBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBQztJQUNuRCxZQUFZQSxVQUFRLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUM7SUFDcEQsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUk7SUFDbEMsWUFBWSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUMsR0FBRTtJQUMzRCxZQUFZLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxLQUFLLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBQyxHQUFFO0lBQ3pELFlBQVksSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLEtBQUssS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxHQUFFO0lBQ25FLFlBQVksSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLEtBQUssS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxHQUFFO0lBQ2pFLFNBQVM7O0lBRVQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDO0lBQzVDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUM3QyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQU87SUFDeEMsUUFBUUEsVUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBQztJQUM1RCxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDckIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUU7SUFDakIsUUFBUSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBQztJQUNyQyxRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtJQUM1QixZQUFZLElBQUksQ0FBQyxLQUFLLEdBQUU7SUFDeEIsU0FBUztJQUNULFFBQVEsVUFBVSxDQUFDLE1BQU07SUFDekIsWUFBWSxJQUFJLENBQUMsSUFBSSxHQUFFO0lBQ3ZCLFNBQVMsRUFBRSxFQUFFLEVBQUM7SUFDZCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFLFNBQVMsR0FBRyxLQUFLLEVBQUU7SUFDbkMsUUFBUSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBQztJQUNsQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFlBQVc7SUFDL0UsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7SUFDckIsUUFBUSxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7SUFDbEMsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxFQUFDO0lBQ3BDLFNBQVM7SUFDVCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRTtJQUNwQixRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFDO0lBQ3hCLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRTtJQUM1QixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQzNCLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUM7SUFDM0IsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLE1BQU0sR0FBRyxJQUFJO0lBQ2hELFFBQVEsT0FBTyxHQUFHLE1BQU07SUFDeEIsUUFBUSxRQUFRLEdBQUcsS0FBSztJQUN4QixRQUFRLFVBQVUsR0FBRyxPQUFPO0lBQzVCLFFBQVEsT0FBTyxHQUFHLEVBQUU7SUFDcEIsUUFBUSxNQUFNLEdBQUcsQ0FBQztJQUNsQixRQUFRLE9BQU8sR0FBRyxLQUFLO0lBQ3ZCLFFBQVEsU0FBUyxHQUFHLEtBQUs7SUFDekIsUUFBUSxTQUFTLEdBQUcsRUFBRTtJQUN0QixRQUFRLFFBQVEsR0FBRyxHQUFHO0lBQ3RCLFFBQVEsVUFBVSxHQUFHLElBQUk7SUFDekIsUUFBUSxlQUFlLEdBQUcsTUFBTTtJQUNoQyxRQUFRLFdBQVcsR0FBRyxNQUFNO0lBQzVCLFFBQVEsU0FBUyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTs7SUFFakMsUUFBUSxJQUFJLFVBQVUsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBQztJQUM5QyxRQUFRLElBQUksVUFBVSxFQUFFO0lBQ3hCLFlBQVksSUFBSSxDQUFDLFVBQVUsR0FBRTtJQUM3QixZQUFZLE1BQU07SUFDbEIsU0FBUztJQUNULFFBQVEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFDO0lBQ2xDLFFBQVEsSUFBSSxhQUFhLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxTQUFTLElBQUksV0FBVyxHQUFHLGVBQWM7SUFDdEYsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJRSxXQUFTLENBQUM7SUFDbEMsWUFBWSxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTO0lBQzVFLFlBQVksYUFBYTtJQUN6QixZQUFZLFFBQVEsRUFBRSxlQUFlLEVBQUUsV0FBVztJQUNsRCxZQUFZLGFBQWEsRUFBRSxVQUFVLEVBQUUsU0FBUztJQUNoRCxTQUFTLEVBQUM7SUFDVixRQUFRLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBQztJQUNyQyxRQUFRLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFDO0lBQy9CLFFBQVEsS0FBSyxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQyxLQUFLO0lBQzFDLFlBQVksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUNwQyxnQkFBZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUM7SUFDeEMsVUFBUztJQUNULFFBQVEsSUFBSSxTQUFTLEVBQUU7SUFDdkIsWUFBWSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUM7SUFDakYsWUFBWSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUM7SUFDbEYsWUFBWSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUM7SUFDbkYsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxPQUFPLFlBQVksQ0FBQyxDQUFDLEVBQUU7SUFDM0IsUUFBUSxPQUFPLENBQUNGLFVBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUM7SUFDNUQsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sVUFBVSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7SUFDdEMsUUFBUSxJQUFJLFVBQVUsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBQztJQUM5QyxRQUFRLElBQUksVUFBVSxFQUFFO0lBQ3hCLFlBQVksVUFBVSxDQUFDLEtBQUssR0FBRTtJQUM5QixZQUFZLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLGtCQUFrQixFQUFDO0lBQ25GLFlBQVksT0FBTyxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsa0JBQWtCLEVBQUM7SUFDcEYsWUFBWSxPQUFPLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsRUFBQztJQUNyRixTQUFTO0lBQ1QsS0FBSztJQUNMLENBQUM7O0lDMU1NLE1BQU0sY0FBYyxDQUFDOztJQUU1QixJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUU7SUFDekIsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLFFBQU87SUFDOUIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksaUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUk7SUFDM0Qsd0NBQXdDLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLEVBQUM7SUFDckUsS0FBSzs7SUFFTCxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7SUFDbkIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLFVBQVUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtJQUNyQyxRQUFRLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUM7SUFDakUsUUFBUSxJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBQztJQUNsRCxRQUFRLElBQUksTUFBTSxFQUFFO0lBQ3BCLFlBQVksSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFDO0lBQ3hELFlBQVksSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFRO0lBQ25ELFlBQVksSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUN2RCxZQUFZLElBQUksTUFBTSxJQUFJLElBQUksRUFBRTtJQUNoQyxnQkFBZ0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLEVBQUM7SUFDckQsZ0JBQWdCLE9BQU8sSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUN0RCxhQUFhO0lBQ2IsU0FBUztJQUNULFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxXQUFXLENBQUM7O0lBRXpCLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRTtJQUM1QyxRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBSztJQUMxQixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTTtJQUM1QixRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBSztJQUMxQixLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRTtJQUNuQixRQUFRLE9BQU8sSUFBSTtJQUNuQixLQUFLOztJQUVMLElBQUksa0JBQWtCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtJQUNwQyxRQUFRLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUM7SUFDeEQsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUU7SUFDekMsWUFBWSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhO0lBQzFDLFlBQVksT0FBTyxFQUFFLElBQUk7SUFDekIsWUFBWSxVQUFVLEVBQUUsSUFBSTtJQUM1QixZQUFZLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4QixZQUFZLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDMUIsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUM7SUFDeEMsS0FBSzs7SUFFTCxJQUFJLGVBQWUsQ0FBQyxRQUFRLEVBQUU7SUFDOUIsUUFBUSxJQUFJLE9BQU8sR0FBRyxHQUFFO0lBQ3hCLFFBQVEsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBUTtJQUNuRCxRQUFRLElBQUksSUFBSSxHQUFHLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFO0lBQ3hDLFlBQVksSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDekMsWUFBWSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFDO0lBQzVELFlBQVksSUFBSSxXQUFXLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUM1RCxZQUFZLElBQUksS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUUsR0FBRztJQUM3RCxxQ0FBcUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUN4RCxZQUFZLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDO0lBQy9CLFNBQVM7SUFDVCxPQUFPLE9BQU8sSUFBSSxTQUFTLENBQUMsR0FBRyxPQUFPLENBQUM7SUFDdkMsS0FBSzs7SUFFTCxJQUFJLHdCQUF3QixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0lBQ3BELFFBQVEsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBUTtJQUNuRCxRQUFRLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUM7SUFDeEQsUUFBUSxJQUFJLFdBQVcsR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQ3hELFFBQVEsTUFBTSxRQUFRLEdBQUcsSUFBSSxLQUFLLENBQUM7SUFDbkMsWUFBWSxVQUFVLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUNsQyxZQUFZLE1BQU0sRUFBRSxXQUFXO0lBQy9CLFlBQVksT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLFlBQVksT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLFlBQVksS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RCLFlBQVksS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RCLFlBQVksT0FBTyxFQUFFLEdBQUc7SUFDeEIsWUFBWSxPQUFPLEVBQUUsR0FBRztJQUN4QixZQUFZLGFBQWEsRUFBRSxFQUFFO0lBQzdCLFlBQVksS0FBSyxFQUFFLEdBQUc7SUFDdEIsU0FBUyxDQUFDLENBQUM7O0lBRVgsUUFBUSxNQUFNLFVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUU7SUFDaEQsWUFBWSxVQUFVLEVBQUUsSUFBSTtJQUM1QixZQUFZLE9BQU8sRUFBRSxJQUFJO0lBQ3pCLFlBQVksT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO0lBQy9CLFlBQVksYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDO0lBQ3JDLFlBQVksY0FBYyxFQUFFLENBQUMsUUFBUSxDQUFDO0lBQ3RDLFlBQVksUUFBUSxFQUFFLEtBQUs7SUFDM0IsU0FBUyxDQUFDLENBQUM7SUFDWCxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixFQUFFLFVBQVUsRUFBQztJQUMzRSxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlDLEtBQUs7O0lBRUwsSUFBSSx3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsZUFBZSxFQUFFO0lBQ25GLFFBQVEsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBQztJQUN4RCxRQUFRLElBQUksSUFBSSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYTtJQUNuRCxZQUFZLE9BQU8sRUFBRSxJQUFJO0lBQ3pCLFlBQVksVUFBVSxFQUFFLElBQUk7SUFDNUIsWUFBWSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEIsWUFBWSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUN6QixRQUFRLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBQztJQUM1RCxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUM7SUFDOUMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxVQUFVLEVBQUM7SUFDM0UsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUM7SUFDeEMsS0FBSzs7SUFFTCxJQUFJLGtCQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxlQUFlLEVBQUU7SUFDN0UsUUFBUSxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUU7SUFDbkMsWUFBWSxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFDO0lBQy9FLFNBQVM7SUFDVCxhQUFhO0lBQ2IsWUFBWSxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUM7SUFDaEUsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUU7SUFDNUIsUUFBUSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztJQUNqRixLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7SUFDaEMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUM7SUFDckUsUUFBUSxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUMvRCxZQUFZLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQzlDLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBQztJQUMzRCxhQUFhO0lBQ2IsaUJBQWlCO0lBQ2pCLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLEtBQUs7SUFDM0Qsb0JBQW9CLFdBQVcsQ0FBQyxPQUFPLEVBQUM7SUFDeEMsZ0JBQWdCLE1BQU07SUFDdEIsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7SUFDL0IsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUM7SUFDN0MsUUFBUSxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUMvRCxZQUFZLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQzlDLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBQztJQUMzRCxhQUFhO0lBQ2IsaUJBQWlCO0lBQ2pCLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLEtBQUs7SUFDMUQsb0JBQW9CLFdBQVcsQ0FBQyxPQUFPLEVBQUM7SUFDeEMsZ0JBQWdCLE1BQU07SUFDdEIsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7SUFDOUIsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUM7SUFDNUMsUUFBUSxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUMvRCxZQUFZLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQzlDLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBQztJQUMxRCxhQUFhO0lBQ2IsaUJBQWlCO0lBQ2pCLGdCQUFnQixJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLEtBQUs7SUFDekQsb0JBQW9CLFdBQVcsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUM7SUFDeEQsZ0JBQWdCLE1BQU07SUFDdEIsYUFBYTtJQUNiLFNBQVM7SUFDVCxLQUFLO0lBQ0wsQ0FBQzs7SUNwS00sTUFBTSxPQUFPLENBQUM7SUFDckI7O0lBRUEsSUFBSSxPQUFPLGdCQUFnQjtJQUMzQixJQUFJO0lBQ0osUUFBUSxJQUFJLE9BQU8sR0FBRyxHQUFFO0lBQ3hCLFFBQVEsSUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBQztJQUM3RCxRQUFRLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQ2pELFlBQVksT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDbkMsWUFBWSxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBQztJQUNwQyxTQUFTO0lBQ1QsUUFBUSxPQUFPLE9BQU87SUFDdEIsS0FBSztJQUNMLENBQUM7O0lDYkQ7SUFDQTs7SUFFQTtJQUNBO0lBQ0E7O0lBRUE7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBZSxNQUFNLE1BQU0sQ0FBQzs7SUFFNUI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLENBQUMsSUFBSSxHQUFHLEVBQUUsRUFBRTs7SUFFM0IsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFO0lBQ3RDLFlBQVksU0FBUyxFQUFFLENBQUM7SUFDeEIsWUFBWSxTQUFTLEVBQUUsTUFBTTtJQUM3QixZQUFZLEtBQUssRUFBRSxLQUFLO0lBQ3hCLFlBQVksZUFBZSxFQUFFLElBQUk7SUFDakMsU0FBUyxFQUFFLElBQUksRUFBQzs7SUFFaEI7SUFDQTtJQUNBLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRTtJQUMzRCxZQUFZLE1BQU0sRUFBRSxJQUFJO0lBQ3hCLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUM7SUFDdEIsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQzs7SUFFckQ7SUFDQTtJQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsS0FBSyxNQUFNLEVBQUU7SUFDNUMsWUFBWSxJQUFJLE1BQU0sQ0FBQyxZQUFZLEVBQUU7SUFDckMsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDL0MsYUFBYSxNQUFNLElBQUksY0FBYyxJQUFJLE1BQU0sRUFBRTtJQUNqRCxnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBTztJQUM3QyxhQUFhLE1BQU07SUFDbkIsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLFFBQU87SUFDN0MsYUFBYTtJQUNiLFNBQVM7O0lBRVQsUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFO0lBQzdCLFlBQVksT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUM7SUFDN0QsU0FBUzs7SUFFVCxRQUFRLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLENBQUMsRUFBQztJQUNyQyxRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBQzs7SUFFekI7SUFDQTtJQUNBLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRTtJQUNwQixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksS0FBSyxHQUFHO0lBQ1osUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxJQUFJLFFBQVEsR0FBRztJQUNuQixRQUFRLE9BQU8sSUFBSSxDQUFDLFNBQVM7SUFDN0IsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxLQUFLLEdBQUc7SUFDWixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFFO0lBQzdCLFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksSUFBSSxHQUFHO0lBQ1gsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRTtJQUM5QixRQUFRLE9BQU8sSUFBSTtJQUNuQixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLEtBQUssR0FBRztJQUNaLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUU7SUFDOUIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLEdBQUc7SUFDZCxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFFO0lBQ2hDLFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFO0lBQ3hEO0lBQ0E7SUFDQTtJQUNBLFFBQVEsQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBQztJQUM3RSxRQUFRLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUM7O0lBRXREO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxFQUFDOztJQUVuRztJQUNBO0lBQ0EsUUFBUSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUU7SUFDakMsWUFBWSxPQUFPLEVBQUUsSUFBSTtJQUN6QixZQUFZLFVBQVUsRUFBRSxJQUFJO0lBQzVCLFlBQVksVUFBVSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUQsWUFBWSxTQUFTLEVBQUUsSUFBSTtJQUMzQixZQUFZLE9BQU8sRUFBRSxNQUFNO0lBQzNCLFlBQVksT0FBTyxFQUFFLElBQUk7SUFDekIsWUFBWSxVQUFVLEVBQUUsSUFBSTtJQUM1QixTQUFTLEVBQUUsSUFBSSxFQUFDOztJQUVoQixRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtJQUM1QixZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVM7SUFDNUMsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBQzs7SUFFOUY7SUFDQTtJQUNBLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsUUFBUSxJQUFJOztJQUUvQztJQUNBO0lBQ0EsWUFBWSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFDOztJQUVuRTtJQUNBO0lBQ0EsWUFBWSxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7SUFDbkMsZ0JBQWdCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsR0FBRTtJQUN6RCxnQkFBZ0IsUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUM7SUFDNUQsYUFBYTs7SUFFYjtJQUNBO0lBQ0EsWUFBWSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBQztJQUN6RCxZQUFZLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsTUFBTSxFQUFDOztJQUVwRTtJQUNBO0lBQ0EsWUFBWSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUM5QyxnQkFBZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDO0lBQzdDLGFBQWE7O0lBRWI7SUFDQTtJQUNBLFlBQVksTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBQzs7SUFFbEYsWUFBWSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7O0lBRXBDO0lBQ0E7SUFDQSxnQkFBZ0IsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFDO0lBQzVGLGdCQUFnQixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxFQUFDO0lBQzlFLGdCQUFnQixJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBQzs7SUFFOUM7SUFDQTtJQUNBLGdCQUFnQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDbEMsb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUM7SUFDdkQsaUJBQWlCO0lBQ2pCLGFBQWE7O0lBRWI7SUFDQTtJQUNBLFlBQVksTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFDO0lBQzNGLFlBQVksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBQztJQUM3RSxZQUFZLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFDOztJQUU3QztJQUNBO0lBQ0EsWUFBWSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7SUFDakMsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUM7SUFDekQsYUFBYTtJQUNiO0lBQ0EsU0FBUyxFQUFFLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUM7O0lBRXhDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRTs7SUFFdkIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLElBQUksR0FBRyxFQUFFLEVBQUU7O0lBRXhEO0lBQ0E7SUFDQSxRQUFRLENBQUMsUUFBUSxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUM7SUFDN0UsUUFBUSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFDOztJQUV0RDtJQUNBO0lBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsRUFBQzs7SUFFbkc7SUFDQTtJQUNBLFFBQVEsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFO0lBQ2pDLFlBQVksT0FBTyxFQUFFLElBQUk7SUFDekIsWUFBWSxRQUFRLEVBQUUsSUFBSTtJQUMxQixZQUFZLFVBQVUsRUFBRSxJQUFJO0lBQzVCLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLFlBQVksUUFBUSxFQUFFLENBQUM7SUFDdkIsWUFBWSxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVE7SUFDakMsWUFBWSxVQUFVLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDbEUsWUFBWSxPQUFPLEVBQUUsTUFBTTtJQUMzQixZQUFZLE9BQU8sRUFBRSxJQUFJO0lBQ3pCLFlBQVksVUFBVSxFQUFFLElBQUk7SUFDNUIsU0FBUyxFQUFFLElBQUksRUFBQzs7SUFFaEI7SUFDQTtJQUNBLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsUUFBUSxJQUFJOztJQUUvQztJQUNBO0lBQ0EsWUFBWSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFDOztJQUVuRTtJQUNBO0lBQ0EsWUFBWSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBQzs7SUFFdkQ7SUFDQTtJQUNBLFlBQVksTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBQzs7SUFFbEYsWUFBWSxNQUFNLE1BQU0sR0FBRztJQUMzQixnQkFBZ0IsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO0lBQy9CLGdCQUFnQixPQUFPLEVBQUUsTUFBTTs7SUFFL0I7SUFDQTtJQUNBLG9CQUFvQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUM7SUFDekYsb0JBQW9CLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUM7SUFDN0Usb0JBQW9CLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDOztJQUU3QztJQUNBO0lBQ0Esb0JBQW9CLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUN0Qyx3QkFBd0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztJQUN0RCxxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGdCQUFnQixRQUFRLEVBQUUsTUFBTTs7SUFFaEM7SUFDQTtJQUNBLG9CQUFvQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUM7SUFDekYsb0JBQW9CLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUM7SUFDN0Usb0JBQW9CLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDOztJQUU3QztJQUNBO0lBQ0Esb0JBQW9CLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUN2Qyx3QkFBd0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztJQUN2RCxxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGdCQUFnQixVQUFVLEVBQUUsTUFBTTs7SUFFbEM7SUFDQTtJQUNBLG9CQUFvQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUM7SUFDekYsb0JBQW9CLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUM7SUFDN0Usb0JBQW9CLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDOztJQUU3QztJQUNBO0lBQ0Esb0JBQW9CLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtJQUN6Qyx3QkFBd0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztJQUN6RCxxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGNBQWE7O0lBRWI7SUFDQTtJQUNBLFlBQVksTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUM7SUFDL0MsWUFBWSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUM7O0lBRXpDO0lBQ0E7SUFDQSxZQUFZLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFDOztJQUVwRCxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBQztJQUN4QztJQUNBLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRTs7SUFFdkIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLElBQUksR0FBRyxFQUFFLEVBQUU7O0lBRTFEO0lBQ0E7SUFDQSxRQUFRLENBQUMsUUFBUSxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUM7SUFDN0UsUUFBUSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFDOztJQUV0RDtJQUNBO0lBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsRUFBQzs7SUFFbkc7SUFDQTtJQUNBLFFBQVEsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFO0lBQ2pDLFlBQVksT0FBTyxFQUFFLElBQUk7SUFDekIsWUFBWSxRQUFRLEVBQUUsSUFBSTtJQUMxQixZQUFZLFVBQVUsRUFBRSxJQUFJO0lBQzVCLFlBQVksZUFBZSxFQUFFLEtBQUs7SUFDbEMsWUFBWSxRQUFRLEVBQUUsQ0FBQztJQUN2QixZQUFZLFFBQVEsRUFBRSxHQUFHO0lBQ3pCLFlBQVksRUFBRSxFQUFFLElBQUk7SUFDcEIsWUFBWSxNQUFNLEVBQUUsSUFBSTtJQUN4QixZQUFZLElBQUksRUFBRSxNQUFNLENBQUMsUUFBUTtJQUNqQyxZQUFZLFVBQVUsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNsRSxZQUFZLE9BQU8sRUFBRSxNQUFNO0lBQzNCLFlBQVksT0FBTyxFQUFFLElBQUk7SUFDekIsWUFBWSxVQUFVLEVBQUUsSUFBSTtJQUM1QixTQUFTLEVBQUUsSUFBSSxFQUFDOztJQUVoQjtJQUNBO0lBQ0EsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxRQUFRLElBQUk7O0lBRS9DO0lBQ0E7SUFDQSxZQUFZLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUM7O0lBRW5FO0lBQ0E7SUFDQSxZQUFZLElBQUksS0FBSyxHQUFHLEtBQUk7SUFDNUIsWUFBWSxJQUFJLEtBQUssR0FBRyxLQUFJOztJQUU1QixZQUFZLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDeEUsZ0JBQWdCLEtBQUssR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUN6RCxnQkFBZ0IsS0FBSyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFDO0lBQ3pELGFBQWEsTUFBTTtJQUNuQixnQkFBZ0IsS0FBSyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFDO0lBQ3RELGdCQUFnQixLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBQztJQUNoRCxhQUFhOztJQUViO0lBQ0E7SUFDQSxZQUFZLElBQUksT0FBTyxHQUFHLEdBQUU7SUFDNUIsWUFBWSxJQUFJLE9BQU8sR0FBRyxHQUFFOztJQUU1QixZQUFZLElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0lBQ3hDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBQztJQUM5RCxhQUFhLE1BQU07SUFDbkIsZ0JBQWdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBRztJQUM1RSxnQkFBZ0IsT0FBTyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLFFBQVEsR0FBRyxFQUFDO0lBQ2xELGdCQUFnQixPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFDO0lBQ25DLGdCQUFnQixPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsUUFBUSxHQUFHLEVBQUM7SUFDbEQsZ0JBQWdCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUM7SUFDbkMsYUFBYTs7SUFFYjtJQUNBO0lBQ0EsWUFBWSxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUN0QyxZQUFZLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLEVBQUM7SUFDOUQsWUFBWSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxFQUFDOztJQUU5RDtJQUNBO0lBQ0EsWUFBWSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsS0FBSzs7SUFFN0M7SUFDQTtJQUNBLGdCQUFnQixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsUUFBTzs7SUFFMUM7SUFDQTtJQUNBLGdCQUFnQixNQUFNLFNBQVMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEdBQUcsS0FBSyxDQUFDLEVBQUM7O0lBRTVILGdCQUFnQixNQUFNLE1BQU0sR0FBRztJQUMvQixvQkFBb0IsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO0lBQ25DLG9CQUFvQixPQUFPLEVBQUUsTUFBTTs7SUFFbkM7SUFDQTtJQUNBLHdCQUF3QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUM7SUFDN0Ysd0JBQXdCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUM7SUFDakYsd0JBQXdCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDOztJQUVqRDtJQUNBO0lBQ0Esd0JBQXdCLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsZUFBZSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsRUFBRTtJQUNqRiw0QkFBNEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztJQUMxRCx5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLG9CQUFvQixRQUFRLEVBQUUsTUFBTTs7SUFFcEM7SUFDQTtJQUNBLHdCQUF3QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUM7SUFDN0Ysd0JBQXdCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUM7SUFDakYsd0JBQXdCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDOztJQUVqRDtJQUNBO0lBQ0Esd0JBQXdCLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsZUFBZSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsRUFBRTtJQUNsRiw0QkFBNEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztJQUMzRCx5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLG9CQUFvQixVQUFVLEVBQUUsTUFBTTs7SUFFdEM7SUFDQTtJQUNBLHdCQUF3QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUM7SUFDN0Ysd0JBQXdCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUM7SUFDakYsd0JBQXdCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFDOztJQUVqRDtJQUNBO0lBQ0Esd0JBQXdCLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsZUFBZSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsRUFBRTtJQUNwRiw0QkFBNEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztJQUM3RCx5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLGtCQUFpQjs7SUFFakI7SUFDQTtJQUNBLGdCQUFnQixNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFDOztJQUVuRDtJQUNBO0lBQ0EsZ0JBQWdCLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFDO0lBQ3hELGFBQWEsRUFBQzs7SUFFZCxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBQztJQUN4QztJQUNBLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRTs7SUFFdkIsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBOztJQUVBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7O0lBRUE7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTs7SUFFQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBOztJQUVBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7O0lBRTdCO0lBQ0E7SUFDQSxRQUFRLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUM7O0lBRWpDO0lBQ0E7SUFDQSxRQUFRLElBQUksUUFBUSxHQUFHLEtBQUk7SUFDM0IsUUFBUSxJQUFJLGdCQUFnQixHQUFHLEtBQUk7SUFDbkMsUUFBUSxJQUFJLElBQUksR0FBRyxLQUFJO0lBQ3ZCO0lBQ0E7SUFDQTtJQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQ3RDLFlBQVksZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBQztJQUN4QyxTQUFTLE1BQU0sSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUU7SUFDckksWUFBWSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBQztJQUM1QixTQUFTLE1BQU0sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFO0lBQ3RDLFlBQVksUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUM7SUFDaEMsU0FBUzs7SUFFVDtJQUNBO0lBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDdEMsWUFBWSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsQ0FBQyxFQUFDO0lBQ3hDLFNBQVMsTUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDN0MsWUFBWSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBQztJQUM1QixTQUFTOztJQUVUO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtJQUN0QyxZQUFZLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxFQUFDO0lBQzVCLFNBQVM7QUFDVCxBQU1BO0lBQ0EsUUFBUSxJQUFJLGdCQUFnQixLQUFLLElBQUksRUFBRTtJQUN2QyxZQUFZLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFO0lBQ3pFLGdCQUFnQixNQUFNLElBQUksS0FBSyxDQUFDLCtHQUErRyxDQUFDO0lBQ2hKLGFBQWE7SUFDYixZQUFZLGdCQUFnQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLEVBQUM7SUFDdEcsU0FBUzs7SUFFVCxRQUFRLElBQUksSUFBSSxLQUFLLElBQUksRUFBRTtJQUMzQixZQUFZLElBQUksR0FBRyxHQUFFO0lBQ3JCLFNBQVM7O0lBRVQsUUFBUSxPQUFPLENBQUMsUUFBUSxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQztJQUNqRCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksYUFBYSxDQUFDLE1BQU0sRUFBRTtJQUMxQjtJQUNBLFFBQVEsTUFBTSxJQUFJLEdBQUcsR0FBRTs7SUFFdkIsUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRTtJQUMvQyxZQUFZLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJO0lBQ2pDLGdCQUFnQixJQUFJLEVBQUUsS0FBSyxNQUFNLEVBQUU7SUFDbkMsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFDO0lBQzVDLGlCQUFpQixNQUFNLElBQUksRUFBRSxLQUFLLE1BQU0sRUFBRTtJQUMxQyxvQkFBb0IsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUM7SUFDNUMsaUJBQWlCLE1BQU0sSUFBSSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3hDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBQztJQUMxQyxpQkFBaUI7SUFDakIsYUFBYSxFQUFDO0lBQ2QsU0FBUyxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssT0FBTyxFQUFFO0lBQ3BELFlBQVksTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUk7SUFDakMsZ0JBQWdCLElBQUksRUFBRSxLQUFLLE1BQU0sRUFBRTtJQUNuQyxvQkFBb0IsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDM0MsaUJBQWlCLE1BQU0sSUFBSSxFQUFFLEtBQUssTUFBTSxFQUFFO0lBQzFDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBQztJQUMxQyxpQkFBaUIsTUFBTSxJQUFJLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDeEMsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFDO0lBQ3pDLGlCQUFpQjtJQUNqQixhQUFhLEVBQUM7SUFDZCxTQUFTLE1BQU07SUFDZixZQUFZLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJO0lBQ2pDLGdCQUFnQixJQUFJLEVBQUUsS0FBSyxNQUFNLEVBQUU7SUFDbkMsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFDO0lBQzFDLGlCQUFpQixNQUFNLElBQUksRUFBRSxLQUFLLE1BQU0sRUFBRTtJQUMxQyxvQkFBb0IsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUM7SUFDMUMsaUJBQWlCLE1BQU0sSUFBSSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3hDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQztJQUN4QyxpQkFBaUI7SUFDakIsYUFBYSxFQUFDO0lBQ2QsU0FBUzs7SUFFVCxRQUFRLE9BQU8sSUFBSTtJQUNuQixLQUFLO0lBQ0wsQ0FBQzs7SUFFRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsTUFBTSxJQUFJLENBQUM7O0lBRVg7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sY0FBYyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUU7O0lBRTVDLFFBQVEsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxPQUFPLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxTQUFRO0lBQ3ZGLFFBQVEsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxHQUFHLFFBQU87O0lBRW5GLFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sZUFBZSxDQUFDLE1BQU0sRUFBRTs7SUFFbkM7SUFDQTtJQUNBLFFBQVEsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUM7O0lBRXJDO0lBQ0E7SUFDQSxRQUFRLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDckIsWUFBWSxRQUFRLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDMUIsWUFBWSxRQUFRLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDMUIsU0FBUyxNQUFNLElBQUksT0FBTyxNQUFNLENBQUMsU0FBUyxLQUFLLFVBQVUsRUFBRTtJQUMzRCxZQUFZLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxTQUFTLEdBQUU7SUFDN0MsWUFBWSxRQUFRLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFDO0lBQ3BELFlBQVksUUFBUSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsRUFBQztJQUNyRCxTQUFTLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0lBQzFDLFlBQVksUUFBUSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxFQUFDO0lBQ2xDLFlBQVksUUFBUSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxFQUFDO0lBQ2xDLFNBQVMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFO0lBQ3pELFlBQVksUUFBUSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBQztJQUNqQyxZQUFZLFFBQVEsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUM7SUFDakMsU0FBUzs7SUFFVCxRQUFRLE9BQU8sUUFBUTtJQUN2QixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLFNBQVMsQ0FBQyxJQUFJLEVBQUU7O0lBRTNCLFFBQVEsTUFBTSxNQUFNLEdBQUcsR0FBRTs7SUFFekIsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7O0lBRXpCLFlBQVksSUFBSSxNQUFNLEdBQUcsS0FBSTs7SUFFN0IsWUFBWSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO0lBQzVDLGdCQUFnQixNQUFNLEdBQUc7SUFDekIsb0JBQW9CLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMzRSxvQkFBb0IsSUFBSSxFQUFFLE1BQU07SUFDaEMsa0JBQWlCO0lBQ2pCLGFBQWEsTUFBTTtJQUNuQixnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQzNGLGdCQUFnQixNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU07SUFDcEMsYUFBYTs7SUFFYixZQUFZLE1BQU0sQ0FBQyxNQUFNLEdBQUcsT0FBTTtJQUNsQyxTQUFTLE1BQU07SUFDZixZQUFZLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBQztJQUNwRCxZQUFZLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUM7SUFDM0IsWUFBWSxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFDO0lBQzNCLFNBQVM7O0lBRVQsUUFBUSxPQUFPLE1BQU07SUFDckIsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxjQUFjLENBQUMsSUFBSSxFQUFFOztJQUVoQyxRQUFRLE1BQU0sT0FBTyxHQUFHLEdBQUU7O0lBRTFCLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFOztJQUV6QixZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSTs7SUFFdEMsZ0JBQWdCLElBQUksTUFBTSxHQUFHLEtBQUk7O0lBRWpDLGdCQUFnQixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDdkMsb0JBQW9CLE1BQU0sR0FBRztJQUM3Qix3QkFBd0IsTUFBTSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdEUsd0JBQXdCLElBQUksRUFBRSxNQUFNO0lBQ3BDLHNCQUFxQjtJQUNyQixpQkFBaUIsTUFBTTtJQUN2QixvQkFBb0IsRUFBRSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUM3RSxvQkFBb0IsTUFBTSxHQUFHLEdBQUU7SUFDL0IsaUJBQWlCOztJQUVqQixnQkFBZ0IsT0FBTyxDQUFDLElBQUksQ0FBQztJQUM3QixvQkFBb0IsTUFBTTtJQUMxQixpQkFBaUIsRUFBQztJQUNsQixhQUFhLEVBQUM7O0lBRWQsU0FBUyxNQUFNOztJQUVmLFlBQVksSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJO0lBQ2xDLGdCQUFnQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBQztJQUNuRCxnQkFBZ0IsT0FBTyxDQUFDLElBQUksQ0FBQztJQUM3QixvQkFBb0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzNCLG9CQUFvQixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDM0IsaUJBQWlCLEVBQUM7SUFDbEIsYUFBYSxFQUFDO0lBQ2QsU0FBUzs7SUFFVCxRQUFRLE9BQU8sT0FBTztJQUN0QixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDNUIsUUFBUSxPQUFPLE9BQU8sTUFBTSxLQUFLLFFBQVE7SUFDekMsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxRQUFRLENBQUMsTUFBTSxFQUFFO0lBQzVCLFFBQVEsT0FBTyxPQUFPLE1BQU0sS0FBSyxRQUFRO0lBQ3pDLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLE9BQU8sUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUM1QixRQUFRLE9BQU8sT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDbkUsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUU7SUFDdkMsUUFBUSxPQUFPLE9BQU8sTUFBTSxDQUFDLFNBQVMsS0FBSyxVQUFVLElBQUksT0FBTyxNQUFNLENBQUMsV0FBVyxLQUFLLFVBQVUsSUFBSSxPQUFPLE1BQU0sQ0FBQyxZQUFZLEtBQUssVUFBVTtJQUM5SSxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLE9BQU8sQ0FBQyxNQUFNLEVBQUU7SUFDM0IsUUFBUSxPQUFPLE1BQU0sQ0FBQyxlQUFlLElBQUksSUFBSTtJQUM3QyxLQUFLO0lBQ0wsQ0FBQzs7SUFFRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsTUFBTSxLQUFLLENBQUM7O0lBRVo7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxHQUFHLFdBQVcsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFOztJQUVsRixRQUFRLE1BQU0sSUFBSSxHQUFHLE9BQU8sTUFBTSxDQUFDLHFCQUFxQixLQUFLLFVBQVUsR0FBRyxNQUFNLENBQUMscUJBQXFCLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQzs7SUFFdkg7SUFDQSxRQUFRLE1BQU0sU0FBUyxHQUFHO0lBQzFCLFlBQVksT0FBTyxFQUFFLElBQUk7SUFDekIsWUFBWSxVQUFVLEVBQUUsSUFBSTtJQUM1QixZQUFZLFFBQVEsRUFBRSxLQUFLO0lBQzNCLFVBQVM7O0lBRVQ7SUFDQSxRQUFRLE1BQU0sV0FBVyxHQUFHO0lBQzVCLFlBQVksTUFBTSxFQUFFLENBQUM7SUFDckIsWUFBWSxJQUFJLEVBQUUsTUFBTTtJQUN4QixVQUFTOztJQUVUO0lBQ0EsUUFBUSxNQUFNLGNBQWMsR0FBRztJQUMvQixZQUFZLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLENBQUM7SUFDcEUsWUFBWSxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxDQUFDO0lBQ25FLFlBQVksT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUM7SUFDeEMsWUFBWSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQztJQUN4QyxZQUFZLE9BQU8sRUFBRSxLQUFLO0lBQzFCLFlBQVksUUFBUSxFQUFFLEtBQUs7SUFDM0IsWUFBWSxNQUFNLEVBQUUsS0FBSztJQUN6QixZQUFZLE9BQU8sRUFBRSxLQUFLO0lBQzFCLFlBQVksTUFBTSxFQUFFLENBQUM7SUFDckIsWUFBWSxPQUFPLEVBQUUsQ0FBQztJQUN0QixZQUFZLGFBQWEsRUFBRSxJQUFJO0lBQy9CLFlBQVksTUFBTSxFQUFFLElBQUk7SUFDeEIsVUFBUzs7SUFFVDtJQUNBLFFBQVEsTUFBTSxjQUFjLEdBQUc7SUFDL0IsWUFBWSxPQUFPLEVBQUUsRUFBRTtJQUN2QixZQUFZLGFBQWEsRUFBRSxFQUFFO0lBQzdCLFlBQVksY0FBYyxFQUFFLEVBQUU7SUFDOUIsWUFBWSxPQUFPLEVBQUUsS0FBSztJQUMxQixZQUFZLFFBQVEsRUFBRSxLQUFLO0lBQzNCLFlBQVksTUFBTSxFQUFFLEtBQUs7SUFDekIsWUFBWSxPQUFPLEVBQUUsS0FBSztJQUMxQixVQUFTOztJQUVUO0lBQ0EsUUFBUSxNQUFNLGdCQUFnQixHQUFHO0lBQ2pDLFlBQVksU0FBUyxFQUFFLENBQUM7SUFDeEIsWUFBWSxLQUFLLEVBQUUsQ0FBQztJQUNwQixZQUFZLE1BQU0sRUFBRSxDQUFDO0lBQ3JCLFlBQVksUUFBUSxFQUFFLENBQUM7SUFDdkIsWUFBWSxrQkFBa0IsRUFBRSxDQUFDO0lBQ2pDLFlBQVksS0FBSyxFQUFFLENBQUM7SUFDcEIsWUFBWSxLQUFLLEVBQUUsQ0FBQztJQUNwQixZQUFZLEtBQUssRUFBRSxDQUFDO0lBQ3BCLFlBQVksV0FBVyxFQUFFLE9BQU87SUFDaEMsWUFBWSxTQUFTLEVBQUUsSUFBSTtJQUMzQixVQUFTOztJQUVULFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFO0lBQ3hDLFlBQVksT0FBTyxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUgsU0FBUyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUM3QyxZQUFZLE9BQU8sSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3hHLFNBQVMsTUFBTTtJQUNmLFlBQVksT0FBTyxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDeEcsU0FBUztJQUNULEtBQUs7SUFDTCxDQUFDOztJQ2g3QkQ7SUFDQTtJQUNBOztJQUVBLE1BQU0sQ0FBQyxlQUFlLEdBQUcsZ0JBQWU7SUFDeEMsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQ3BCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsSUFBRztJQUNoQixNQUFNLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDNUIsTUFBTSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ2xDLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRyxrQkFBaUI7SUFDNUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxPQUFNO0lBQ3RCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBSzs7SUFFcEIsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQ3hCLE1BQU0sQ0FBQyxZQUFZLEdBQUcsYUFBWTtJQUNsQyxNQUFNLENBQUMsVUFBVSxHQUFHLFdBQVU7SUFDOUIsTUFBTSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQzVCLE1BQU0sQ0FBQyxVQUFVLEdBQUcsV0FBVTtJQUM5QixNQUFNLENBQUMsV0FBVyxHQUFHLFlBQVc7SUFDaEMsTUFBTSxDQUFDLFdBQVcsR0FBRyxZQUFXOztJQUVoQyxNQUFNLENBQUMsVUFBVSxHQUFHLFdBQVU7SUFDOUIsTUFBTSxDQUFDLG1CQUFtQixHQUFHLG9CQUFtQjtJQUNoRCxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDcEIsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQ3hCLE1BQU0sQ0FBQyxRQUFRLEdBQUdBLFdBQVE7SUFDMUIsTUFBTSxDQUFDLE1BQU0sR0FBRyxPQUFNO0lBQ3RCLE1BQU0sQ0FBQyxhQUFhLEdBQUcsY0FBYTtJQUNwQyxNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDdEIsTUFBTSxDQUFDLGNBQWMsR0FBRyxlQUFjO0lBQ3RDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsWUFBVztJQUNoQyxNQUFNLENBQUMsSUFBSSxHQUFHLEtBQUk7SUFDbEIsTUFBTSxDQUFDLHdCQUF3QixHQUFHLHlCQUF3QjtJQUMxRCxNQUFNLENBQUMsa0JBQWtCLEdBQUcsbUJBQWtCO0lBQzlDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBSztJQUNwQixNQUFNLENBQUMsT0FBTyxHQUFHLFFBQU87SUFDeEIsTUFBTSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ2hDLE1BQU0sQ0FBQyxtQkFBbUIsR0FBRyxvQkFBbUI7SUFDaEQsTUFBTSxDQUFDLGdCQUFnQixHQUFHLGlCQUFnQjtJQUMxQyxNQUFNLENBQUMsaUJBQWlCLEdBQUdDLG9CQUFpQjtJQUM1QyxNQUFNLENBQUMsaUJBQWlCLEdBQUcsa0JBQWlCO0lBQzVDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsVUFBUztJQUM1QixNQUFNLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDMUIsTUFBTSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ2xCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsT0FBTTtJQUN0QixNQUFNLENBQUMsT0FBTyxHQUFHLFFBQU87SUFDeEIsTUFBTSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQzFCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBSztJQUNwQixNQUFNLENBQUMsU0FBUyxHQUFHQyxZQUFTO0lBQzVCLE1BQU0sQ0FBQyxXQUFXLEdBQUcsWUFBVztJQUNoQyxNQUFNLENBQUMsWUFBWSxHQUFHLGFBQVk7SUFDbEMsTUFBTSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ2xCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUN4QixNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU07SUFDdEIsTUFBTSxDQUFDLEtBQUssR0FBR0gsUUFBSztJQUNwQixNQUFNLENBQUMsT0FBTyxHQUFHLFFBQU87SUFDeEIsTUFBTSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ2xCLE1BQU0sQ0FBQyxRQUFRLEdBQUcsU0FBUTtJQUMxQixNQUFNLENBQUMsU0FBUyxHQUFHLFVBQVM7SUFDNUIsTUFBTSxDQUFDLFdBQVcsR0FBRyxXQUFXOzs7OyJ9
|