made with requirebin
Created
April 21, 2016 14:51
-
-
Save jtenner/ce0ae98f5f1cfeead9502808c5ae9f93 to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var e2d = require('e2d'); | |
var r = e2d.Renderer.create(400, 400); | |
var helloWorld = e2d.fillText('Hello World'); | |
r.ready(); | |
r.on('frame', | |
() => r.render( | |
e2d.clearRect(400, 400), | |
e2d.translate(200, 200, | |
helloWorld | |
) | |
) | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
setTimeout(function(){ | |
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
// Source: http://jsfiddle.net/vWx8V/ | |
// http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes | |
/** | |
* Conenience method returns corresponding value for given keyName or keyCode. | |
* | |
* @param {Mixed} keyCode {Number} or keyName {String} | |
* @return {Mixed} | |
* @api public | |
*/ | |
exports = module.exports = function(searchInput) { | |
// Keyboard Events | |
if (searchInput && 'object' === typeof searchInput) { | |
var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode | |
if (hasKeyCode) searchInput = hasKeyCode | |
} | |
// Numbers | |
if ('number' === typeof searchInput) return names[searchInput] | |
// Everything else (cast to string) | |
var search = String(searchInput) | |
// check codes | |
var foundNamedKey = codes[search.toLowerCase()] | |
if (foundNamedKey) return foundNamedKey | |
// check aliases | |
var foundNamedKey = aliases[search.toLowerCase()] | |
if (foundNamedKey) return foundNamedKey | |
// weird character? | |
if (search.length === 1) return search.charCodeAt(0) | |
return undefined | |
} | |
/** | |
* Get by name | |
* | |
* exports.code['enter'] // => 13 | |
*/ | |
var codes = exports.code = exports.codes = { | |
'backspace': 8, | |
'tab': 9, | |
'enter': 13, | |
'shift': 16, | |
'ctrl': 17, | |
'alt': 18, | |
'pause/break': 19, | |
'caps lock': 20, | |
'esc': 27, | |
'space': 32, | |
'page up': 33, | |
'page down': 34, | |
'end': 35, | |
'home': 36, | |
'left': 37, | |
'up': 38, | |
'right': 39, | |
'down': 40, | |
'insert': 45, | |
'delete': 46, | |
'command': 91, | |
'right click': 93, | |
'numpad *': 106, | |
'numpad +': 107, | |
'numpad -': 109, | |
'numpad .': 110, | |
'numpad /': 111, | |
'num lock': 144, | |
'scroll lock': 145, | |
'my computer': 182, | |
'my calculator': 183, | |
';': 186, | |
'=': 187, | |
',': 188, | |
'-': 189, | |
'.': 190, | |
'/': 191, | |
'`': 192, | |
'[': 219, | |
'\\': 220, | |
']': 221, | |
"'": 222, | |
} | |
// Helper aliases | |
var aliases = exports.aliases = { | |
'windows': 91, | |
'⇧': 16, | |
'⌥': 18, | |
'⌃': 17, | |
'⌘': 91, | |
'ctl': 17, | |
'control': 17, | |
'option': 18, | |
'pause': 19, | |
'break': 19, | |
'caps': 20, | |
'return': 13, | |
'escape': 27, | |
'spc': 32, | |
'pgup': 33, | |
'pgdn': 33, | |
'ins': 45, | |
'del': 46, | |
'cmd': 91 | |
} | |
/*! | |
* Programatically add the following | |
*/ | |
// lower case chars | |
for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32 | |
// numbers | |
for (var i = 48; i < 58; i++) codes[i - 48] = i | |
// function keys | |
for (i = 1; i < 13; i++) codes['f'+i] = i + 111 | |
// numpad keys | |
for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96 | |
/** | |
* Get by code | |
* | |
* exports.name[13] // => 'Enter' | |
*/ | |
var names = exports.names = exports.title = {} // title for backward compat | |
// Create reverse mapping | |
for (i in codes) names[codes[i]] = i | |
// Add aliases | |
for (var alias in aliases) { | |
codes[alias] = aliases[alias] | |
} | |
},{}],2:[function(require,module,exports){ | |
module.exports = function (point, vs) { | |
// ray-casting algorithm based on | |
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html | |
var x = point[0], y = point[1]; | |
var inside = false; | |
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) { | |
var xi = vs[i][0], yi = vs[i][1]; | |
var xj = vs[j][0], yj = vs[j][1]; | |
var intersect = ((yi > y) != (yj > y)) | |
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi); | |
if (intersect) inside = !inside; | |
} | |
return inside; | |
}; | |
},{}],3:[function(require,module,exports){ | |
//jshint worker: true, browser: true, node: true | |
'use strict'; | |
function Canvas(width, height) { | |
var Renderer = require('./Renderer'); | |
this.renderer = new Renderer(width, height, window.document.createElement('div')); | |
this.fillPattern = null; | |
this.skipPatternCreation = false; | |
return Object.seal(this); | |
} | |
Canvas.prototype.render = function render(children) { | |
var result = [], | |
i; | |
for (i = 0; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
this.renderer.render(result); | |
if (!this.skipPatternCreation) { | |
this.fillPattern = this.renderer.ctx.createPattern(this.renderer.canvas, 'no-repeat'); | |
} | |
return this; | |
}; | |
Canvas.prototype.style = function style() { | |
var defs = []; | |
for (var i = 0; i < arguments.length; i++) { | |
defs.push(arguments[i]); | |
} | |
this.renderer.style.apply(this.renderer, defs); | |
return this; | |
}; | |
Canvas.prototype.toImage = function toImage(imageID) { | |
return this.renderer.toImage(); | |
}; | |
Canvas.prototype.resize = function resize(width, height) { | |
this.renderer.resize(+width, +height); | |
return this; | |
}; | |
Object.defineProperty(Canvas.prototype, 'height', { | |
get: function() { | |
return this.renderer.canvas.width; | |
}, | |
enumerable: true, | |
configurable: false | |
}); | |
Object.defineProperty(Canvas.prototype, 'width', { | |
get: function() { | |
return this.renderer.canvas.width; | |
}, | |
enumerable: true, | |
configurable: false | |
}); | |
Canvas.create = function create(width, height, id) { | |
return new Canvas(width, height, id); | |
}; | |
Object.seal(Canvas); | |
Object.seal(Canvas.prototype); | |
module.exports = Canvas; | |
},{"./Renderer":6}],4:[function(require,module,exports){ | |
//jshint node: true, browser: true, worker: true | |
'use strict'; | |
var path = require('path'), | |
events = require('events'), | |
util = require('util'); | |
util.inherits(Img, events.EventEmitter); | |
function Img() { | |
events.EventEmitter.call(this); | |
this.imageElement = null; | |
this.imagePattern = null; | |
this.imagePatternRepeat = null; | |
Object.seal(this); | |
} | |
Object.defineProperty(Img.prototype, 'src', { | |
set: function(val) { | |
var element = new Image(); | |
this.imageElement = element; | |
element.src = val; | |
if (element.complete) { //firefox compatibility code | |
setTimeout(this.imageLoad.bind(this), 0); | |
} else { | |
element.onload = this.imageLoad.bind(this); | |
} | |
}, | |
get: function() { | |
return this.imageElement.src; | |
} | |
}); | |
Img.prototype.imageLoad = function imageLoad() { | |
var ctx = window.document.createElement('canvas').getContext('2d'); | |
this.imagePattern = ctx.createPattern(this.imageElement, 'no-repeat'); | |
this.imagePatternRepeat = ctx.createPattern(this.imageElement, 'repeat'); | |
return this.emit('load', this); | |
}; | |
Object.defineProperty(Img.prototype, 'width', { | |
enumerable: true, | |
get: function() { | |
return this.imageElement.width; | |
}, | |
set: function(value) { | |
this.imageElement.width = value; | |
} | |
}); | |
Object.defineProperty(Img.prototype, 'height', { | |
enumerable: true, | |
get: function() { | |
return this.imageElement.height; | |
}, | |
set: function(value) { | |
this.imageElement.height = value; | |
} | |
}); | |
Object.seal(Img); | |
Object.seal(Img.prototype); | |
module.exports = Img; | |
},{"events":59,"path":61,"util":64}],5:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
function Instruction(type, props) { | |
this.type = type; | |
this.props = props; | |
Object.seal(this); | |
} | |
Object.seal(Instruction); | |
Object.seal(Instruction.prototype); | |
module.exports = Instruction; | |
},{}],6:[function(require,module,exports){ | |
//jshint node: true, browser: true, worker: true | |
'use strict'; | |
var createLinearGradient = require('./createLinearGradient'), | |
createRadialGradient = require('./createRadialGradient'), | |
events = require('events'), | |
util = require('util'), | |
keycode = require('keycode'), | |
transformPoints = require('./transformPoints'), | |
pointInPolygon = require('point-in-polygon'), | |
identity = [1, 0, 0, 1, 0, 0], | |
Img = require('./Img'); | |
util.inherits(Renderer, events.EventEmitter); | |
function Renderer(width, height, parent, opts) { | |
events.EventEmitter.call(this); | |
opts = opts || {}; | |
//virtual stack | |
this.transformStack = new Float64Array( | |
((opts.transformStackCount || 500) + 1) * 6 //properties | |
); | |
this.transformStackIndex = 6; | |
this.transformStack.set(identity); | |
this.fillStyleStack = []; | |
this.strokeStyleStack = []; | |
this.lineStyleStack = []; | |
this.textStyleStack = []; | |
this.shadowStyleStack = []; | |
this.globalAlphaStack = []; | |
this.imageSmoothingEnabledStack = []; | |
this.globalCompositeOperationStack = []; | |
this.pi2 = Math.PI * 2; | |
this.isReady = false; | |
this.mouseState = 'up'; | |
this.mouseData = { | |
x: 0, | |
y: 0, | |
state: this.mouseState, | |
clicked: false, | |
activeRegions: [] | |
}; | |
this.lastMouseEvent = null; | |
this.ranMouseEvent = false; | |
this.mouseRegions = []; | |
this.activeRegions = []; | |
this.styleQueue = []; | |
//user input here | |
this.keyData = {}; | |
this.touchData = { | |
touches: [], | |
ids: [] | |
}; | |
this.lastTouchEvent = null; | |
this.ranTouchEvent = false; | |
this.touchRegions = []; | |
//set parent | |
if (parent && parent.nodeType === 1) { | |
this.parent = parent; | |
} else { | |
this.parent = window.document.createElement('div'); | |
this.parent.style.margin = '0 auto'; | |
this.parent.style.width = width + 'px'; | |
this.parent.style.height = height + 'px'; | |
window.document.body.appendChild(this.parent); | |
} | |
//set width and height automatically | |
if (!width || width <= 0) { | |
width = window.innerWidth; | |
} | |
if (!height || height <= 0) { | |
height = window.innerHeight; | |
} | |
this.canvas = window.document.createElement('canvas'); | |
//focusable canvas bugfix | |
this.canvas.tabIndex = 1; | |
this.ctx = this.canvas.getContext('2d'); | |
this.canvas.width = width; | |
this.canvas.height = height; | |
this.parent.appendChild(this.canvas); | |
//hook mouse, keyboard, and keyboard events right away | |
this.hookMouseEvents(); | |
this.hookKeyboardEvents(); | |
this.hookTouchEvents(); | |
this.boundHookRenderFunction = this.hookRender.bind(this); | |
Object.seal(this); | |
} | |
Renderer.prototype.render = function render(args) { | |
var i, | |
len, | |
child, | |
props, | |
type, | |
cache, | |
matrix = [1, 0, 0, 1, 0, 0], | |
sinr, | |
cosr, | |
ctx = this.ctx, | |
children = [], | |
concat = children.concat; | |
//flush the virtual stack | |
this.fillStyleStack.splice(0, this.fillStyleStack.length); | |
this.strokeStyleStack.splice(0, this.strokeStyleStack.length); | |
this.lineStyleStack.splice(0, this.lineStyleStack.length); | |
this.textStyleStack.splice(0, this.textStyleStack.length); | |
this.shadowStyleStack.splice(0, this.shadowStyleStack.length); | |
this.globalCompositeOperationStack.splice(0, this.globalCompositeOperationStack.length); | |
this.globalAlphaStack.splice(0, this.globalAlphaStack.length); | |
this.imageSmoothingEnabledStack.splice(0, this.imageSmoothingEnabledStack.length); | |
for (i = 0, len = arguments.length; i < len; i++) { | |
children.push(arguments[i]); | |
} | |
//loop over every child | |
for (i = 0, len = children.length; i < len; i++) { | |
child = children[i]; | |
//flattening algorithm | |
if (child && child.constructor === Array) { | |
children = concat.apply([], children); | |
child = children[i]; | |
while (child && child.constructor === Array) { | |
children = concat.apply([], children); | |
child = children[i]; | |
} | |
len = children.length; | |
} | |
//child must be truthy | |
if (!child) { | |
continue; | |
} | |
//set props and type object | |
props = child.props; | |
type = child.type; | |
if (type === 'transform') { | |
matrix[0] = this.transformStack[this.transformStackIndex - 6]; | |
matrix[1] = this.transformStack[this.transformStackIndex - 5]; | |
matrix[2] = this.transformStack[this.transformStackIndex - 4]; | |
matrix[3] = this.transformStack[this.transformStackIndex - 3]; | |
matrix[4] = this.transformStack[this.transformStackIndex - 2]; | |
matrix[5] = this.transformStack[this.transformStackIndex - 1]; | |
this.transformStackIndex += 6; | |
if (this.transformStackIndex > this.transformStack.length) { | |
this.increaseTransformStackSize(); | |
} | |
this.transformStack[this.transformStackIndex - 6] = //d | |
matrix[0] * props[0] + matrix[2] * props[1]; | |
this.transformStack[this.transformStackIndex - 5] = //b | |
matrix[1] * props[0] + matrix[3] * props[1]; | |
this.transformStack[this.transformStackIndex - 4] = //c | |
matrix[0] * props[2] + matrix[2] * props[3]; | |
this.transformStack[this.transformStackIndex - 3] = //d | |
matrix[1] * props[2] + matrix[3] * props[3]; | |
this.transformStack[this.transformStackIndex - 2] = //e | |
matrix[0] * props[4] + matrix[2] * props[5] + matrix[4]; | |
this.transformStack[this.transformStackIndex - 1] = //f | |
matrix[1] * props[4] + matrix[3] * props[5] + matrix[5]; | |
ctx.setTransform( | |
this.transformStack[this.transformStackIndex - 6], | |
this.transformStack[this.transformStackIndex - 5], | |
this.transformStack[this.transformStackIndex - 4], | |
this.transformStack[this.transformStackIndex - 3], | |
this.transformStack[this.transformStackIndex - 2], | |
this.transformStack[this.transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'setTransform') { | |
this.transformStackIndex += 6; | |
if (this.transformStackIndex > this.transformStack.length) { | |
this.increaseTransformStackSize(); | |
} | |
this.transformStack[this.transformStackIndex - 6] = props[0];//a | |
this.transformStack[this.transformStackIndex - 5] = props[1];//b | |
this.transformStack[this.transformStackIndex - 4] = props[2];//c | |
this.transformStack[this.transformStackIndex - 3] = props[3];//d | |
this.transformStack[this.transformStackIndex - 2] = props[4];//e | |
this.transformStack[this.transformStackIndex - 1] = props[5];//f | |
ctx.setTransform(props[0], props[1], props[2], props[3], props[4], props[5]); | |
continue; | |
} | |
if (type === 'scale') { | |
matrix[0] = this.transformStack[this.transformStackIndex - 6]; | |
matrix[1] = this.transformStack[this.transformStackIndex - 5]; | |
matrix[2] = this.transformStack[this.transformStackIndex - 4]; | |
matrix[3] = this.transformStack[this.transformStackIndex - 3]; | |
matrix[4] = this.transformStack[this.transformStackIndex - 2]; | |
matrix[5] = this.transformStack[this.transformStackIndex - 1]; | |
this.transformStackIndex += 6; | |
if (this.transformStackIndex > this.transformStack.length) { | |
this.increaseTransformStackSize(); | |
} | |
this.transformStack[this.transformStackIndex - 6] = matrix[0] * props.x; //a | |
this.transformStack[this.transformStackIndex - 5] = matrix[1] * props.x; //b | |
this.transformStack[this.transformStackIndex - 4] = matrix[2] * props.y; //c | |
this.transformStack[this.transformStackIndex - 3] = matrix[3] * props.y; //d | |
this.transformStack[this.transformStackIndex - 2] = matrix[4]; //e | |
this.transformStack[this.transformStackIndex - 1] = matrix[5]; //f | |
ctx.setTransform( | |
this.transformStack[this.transformStackIndex - 6], | |
this.transformStack[this.transformStackIndex - 5], | |
this.transformStack[this.transformStackIndex - 4], | |
this.transformStack[this.transformStackIndex - 3], | |
this.transformStack[this.transformStackIndex - 2], | |
this.transformStack[this.transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'translate') { | |
matrix[0] = this.transformStack[this.transformStackIndex - 6]; | |
matrix[1] = this.transformStack[this.transformStackIndex - 5]; | |
matrix[2] = this.transformStack[this.transformStackIndex - 4]; | |
matrix[3] = this.transformStack[this.transformStackIndex - 3]; | |
matrix[4] = this.transformStack[this.transformStackIndex - 2]; | |
matrix[5] = this.transformStack[this.transformStackIndex - 1]; | |
this.transformStackIndex += 6; | |
if (this.transformStackIndex > this.transformStack.length) { | |
this.increaseTransformStackSize(); | |
} | |
this.transformStack[this.transformStackIndex - 6] = matrix[0]; //a | |
this.transformStack[this.transformStackIndex - 5] = matrix[1]; //b | |
this.transformStack[this.transformStackIndex - 4] = matrix[2]; //c | |
this.transformStack[this.transformStackIndex - 3] = matrix[3]; //d | |
this.transformStack[this.transformStackIndex - 2] = matrix[4] + matrix[0] * props.x + matrix[2] * props.y; //e | |
this.transformStack[this.transformStackIndex - 1] = matrix[5] + matrix[1] * props.x + matrix[3] * props.y; //f | |
ctx.setTransform( | |
this.transformStack[this.transformStackIndex - 6], | |
this.transformStack[this.transformStackIndex - 5], | |
this.transformStack[this.transformStackIndex - 4], | |
this.transformStack[this.transformStackIndex - 3], | |
this.transformStack[this.transformStackIndex - 2], | |
this.transformStack[this.transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'rotate') { | |
matrix[0] = this.transformStack[this.transformStackIndex - 6]; | |
matrix[1] = this.transformStack[this.transformStackIndex - 5]; | |
matrix[2] = this.transformStack[this.transformStackIndex - 4]; | |
matrix[3] = this.transformStack[this.transformStackIndex - 3]; | |
matrix[4] = this.transformStack[this.transformStackIndex - 2]; | |
matrix[5] = this.transformStack[this.transformStackIndex - 1]; | |
cosr = Math.cos(props.r); | |
sinr = Math.sin(props.r); | |
this.transformStackIndex += 6; | |
if (this.transformStackIndex > this.transformStack.length) { | |
this.increaseTransformStackSize(); | |
} | |
this.transformStack[this.transformStackIndex - 6] = | |
matrix[0] * cosr + matrix[2] * sinr; //a | |
this.transformStack[this.transformStackIndex - 5] = | |
matrix[1] * cosr + matrix[3] * sinr; //b | |
this.transformStack[this.transformStackIndex - 4] = | |
matrix[0] * -sinr + matrix[2] * cosr; //c | |
this.transformStack[this.transformStackIndex - 3] = | |
matrix[1] * -sinr + matrix[3] * cosr; //d | |
this.transformStack[this.transformStackIndex - 2] = matrix[4]; //e | |
this.transformStack[this.transformStackIndex - 1] = matrix[5];//f | |
ctx.setTransform( | |
this.transformStack[this.transformStackIndex - 6], | |
this.transformStack[this.transformStackIndex - 5], | |
this.transformStack[this.transformStackIndex - 4], | |
this.transformStack[this.transformStackIndex - 3], | |
this.transformStack[this.transformStackIndex - 2], | |
this.transformStack[this.transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'restore') { | |
this.transformStackIndex -= 6; | |
matrix[0] = this.transformStack[this.transformStackIndex - 6]; | |
matrix[1] = this.transformStack[this.transformStackIndex - 5]; | |
matrix[2] = this.transformStack[this.transformStackIndex - 4]; | |
matrix[3] = this.transformStack[this.transformStackIndex - 3]; | |
matrix[4] = this.transformStack[this.transformStackIndex - 2]; | |
matrix[5] = this.transformStack[this.transformStackIndex - 1]; | |
ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); | |
continue; | |
} | |
if (type === 'fillRect') { | |
ctx.fillRect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'strokeRect') { | |
ctx.strokeRect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'clearRect') { | |
ctx.clearRect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'rect') { | |
ctx.rect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'fillStyle') { | |
this.fillStyleStack.push(ctx.fillStyle); | |
ctx.fillStyle = props.value; | |
continue; | |
} | |
if (type === 'strokeStyle') { | |
this.strokeStyleStack.push(ctx.strokeStyle); | |
ctx.strokeStyle = props.value; | |
continue; | |
} | |
if (type === 'endFillStyle') { | |
ctx.fillStyle = this.fillStyleStack.pop(); | |
continue; | |
} | |
if (type === 'endStrokeStyle') { | |
ctx.strokeStyle = this.strokeStyleStack.pop(); | |
continue; | |
} | |
if (type === 'lineStyle') { | |
this.lineStyleStack.push({ | |
lineWidth: ctx.lineWidth, | |
lineCap: ctx.lineCap, | |
lineJoin: ctx.lineJoin, | |
miterLimit: ctx.miterLimit, | |
lineDash: ctx.getLineDash(), | |
lineDashOffset: ctx.lineDashOffset | |
}); | |
if (props.lineWidth !== null) { | |
ctx.lineWidth = props.lineWidth; | |
} | |
if (props.lineCap !== null) { | |
ctx.lineCap = props.lineCap; | |
} | |
if (props.lineJoin !== null) { | |
ctx.lineJoin = props.lineJoin; | |
} | |
if (props.miterLimit !== null) { | |
ctx.miterLimit = props.miterLimit; | |
} | |
if (props.lineDash.length > 0) { | |
ctx.setLineDash(props.lineDash); | |
} | |
if (props.lineDashOffset !== null) { | |
ctx.lineDashOffset = props.lineDashOffset; | |
} | |
continue; | |
} | |
if (type === 'endLineStyle') { | |
cache = this.lineStyleStack.pop(); | |
ctx.lineWidth = cache.lineWidth; | |
ctx.lineCap = cache.lineCap; | |
ctx.lineJoin = cache.lineJoin; | |
ctx.miterLimit = cache.miterLimit; | |
ctx.setLineDash(cache.lineDash); | |
ctx.lineDashOffset = cache.lineDashOffset; | |
continue; | |
} | |
if (type === 'textStyle') { | |
this.textStyleStack.push({ | |
font: ctx.font, | |
textAlign: ctx.textAlign, | |
textBaseline: ctx.textBaseline, | |
direction: ctx.direction | |
}); | |
if (props.font !== null) { | |
ctx.font = props.font; | |
} | |
if (props.textAlign !== null) { | |
ctx.textAlign = props.textAlign; | |
} | |
if (props.textBaseline !== null) { | |
ctx.textBaseline = props.textBaseline; | |
} | |
if (props.lineJoin !== null) { | |
ctx.direction = props.direction; | |
} | |
continue; | |
} | |
if (type === 'endTextStyle') { | |
cache = this.textStyleStack.pop(); | |
ctx.font = cache.font; | |
ctx.textAlign = cache.textAlign; | |
ctx.textBaseline = cache.textBaseline; | |
ctx.direction = cache.direction; | |
continue; | |
} | |
if (type === 'shadowStyle') { | |
this.shadowStyleStack.push({ | |
shadowBlur: ctx.shadowBlur, | |
shadowColor: ctx.shadowColor, | |
shadowOffsetX: ctx.shadowOffsetX, | |
shadowOffsetY: ctx.shadowOffsetY | |
}); | |
if (props.shadowBlur !== null) { | |
ctx.shadowBlur = props.shadowBlur; | |
} | |
if (props.shadowColor !== null) { | |
ctx.shadowColor = props.shadowColor; | |
} | |
if (props.shadowOffsetX !== null) { | |
ctx.shadowOffsetX = props.shadowOffsetX; | |
} | |
if (props.shadowOffsetY !== null) { | |
ctx.shadowOffsetY = props.shadowOffsetY; | |
} | |
continue; | |
} | |
if (type === 'endShadowStyle') { | |
cache = this.shadowStyleStack.pop(); | |
ctx.shadowBlur = cache.shadowBlur; | |
ctx.shadowColor = cache.shadowColor; | |
ctx.shadowOffsetX = cache.shadowOffsetX; | |
ctx.shadowOffsetY = cache.shadowOffsetY; | |
continue; | |
} | |
if (type === 'strokeText') { | |
if (props.maxWidth) { | |
ctx.strokeText(props.text, props.x, props.y, props.maxWidth); | |
continue; | |
} | |
ctx.strokeText(props.text, props.x, props.y); | |
continue; | |
} | |
if (type === 'fillText') { | |
if (props.maxWidth) { | |
ctx.fillText(props.text, props.x, props.y, props.maxWidth); | |
continue; | |
} | |
ctx.fillText(props.text, props.x, props.y); | |
continue; | |
} | |
if (type === 'text') { | |
if (props.maxWidth !== 0) { | |
if (props.fill) { | |
ctx.fillText(props.text, props.x, props.y, props.maxWidth); | |
} | |
if (props.stroke) { | |
ctx.strokeText(props.text, props.x, props.y, props.maxWidth); | |
} | |
continue; | |
} | |
if (props.fill) { | |
ctx.fillText(props.text, props.x, props.y); | |
} | |
if (props.stroke) { | |
ctx.strokeText(props.text, props.x, props.y); | |
} | |
continue; | |
} | |
if (type === 'drawImage') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img.constructor === Img ? props.img.imageElement || new Image() : props.img; | |
ctx.drawImage(cache || new Image(), props.dx, props.dy); | |
continue; | |
} | |
if (type === 'drawImageSize') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img.constructor === Img ? props.img.imageElement || new Image() : props.img; | |
ctx.drawImage(cache, props.dx, props.dy, props.dWidth, props.dHeight); | |
continue; | |
} | |
if (type === 'drawImageSource') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img.constructor === Img ? props.img.imageElement || new Image() : props.img; | |
ctx.drawImage(cache, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight); | |
continue; | |
} | |
if (type === 'fillImagePattern') { | |
if (!props.img) { | |
continue; | |
} | |
ctx.fillStyle = props.img.imagePatternRepeat; | |
ctx.translate(props.dx, props.dy); | |
ctx.fillRect(0, 0, props.dWidth, props.dHeight); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'fillImage') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img.imageElement; | |
ctx.save(); | |
ctx.fillStyle = props.img.imagePattern; | |
ctx.translate(props.dx, props.dy); | |
ctx.fillRect(0, 0, cache.width, cache.height); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'fillImageSize') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img.imageElement; | |
ctx.save(); | |
ctx.fillStyle = props.img.imagePattern; | |
ctx.translate(props.dx, props.dy); | |
ctx.scale(props.dWidth / cache.width, props.dHeight / cache.height); | |
ctx.fillRect(0, 0, cache.width, cache.height); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'fillImageSource') { | |
if (!props.img) { | |
continue; | |
} | |
ctx.save(); | |
ctx.fillStyle = props.img.imagePattern; | |
ctx.translate(props.dx, props.dy); | |
ctx.scale(props.dWidth / props.sWidth, props.dHeight / props.sHeight); | |
ctx.translate(-props.sx, -props.sy); | |
ctx.fillRect(props.sx, props.sy, props.sWidth, props.sHeight); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'fillCanvas') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img; | |
ctx.save(); | |
ctx.fillStyle = cache.fillPattern; | |
ctx.translate(props.dx, props.dy); | |
ctx.fillRect(0, 0, cache.width, cache.height); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'fillCanvasSize') { | |
if (!props.img) { | |
continue; | |
} | |
cache = props.img; | |
ctx.save(); | |
ctx.fillStyle = cache.fillPattern; | |
ctx.translate(props.dx, props.dy); | |
ctx.scale(props.dWidth / cache.width, props.dHeight / cache.height); | |
ctx.fillRect(0, 0, cache.width, cache.height); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'fillCanvasSource') { | |
if (!props.img) { | |
continue; | |
} | |
ctx.save(); | |
ctx.fillStyle = props.img.fillPattern; | |
ctx.translate(props.dx, props.dy); | |
ctx.scale(props.dWidth / props.sWidth, props.dHeight / props.sHeight); | |
ctx.translate(-props.sx, -props.sy); | |
ctx.fillRect(props.sx, props.sy, props.sWidth, props.sHeight); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'drawCanvas') { | |
if (!props.img) { | |
continue; | |
} | |
ctx.drawImage(props.img.renderer.canvas, props.dx, props.dy); | |
continue; | |
} | |
if (type === 'drawCanvasSize') { | |
if (!props.img) { | |
continue; | |
} | |
ctx.drawImage(props.img.renderer.canvas, props.dx, props.dy, props.dWidth, props.dHeight); | |
continue; | |
} | |
if (type === 'drawCanvasSource') { | |
if (!props.img) { | |
continue; | |
} | |
ctx.drawImage(props.img.renderer.canvas, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight); | |
continue; | |
} | |
if (type === 'strokeArc') { | |
ctx.beginPath(); | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle); | |
ctx.closePath(); | |
ctx.stroke(); | |
continue; | |
} | |
if (type === 'strokeArc-counterclockwise') { | |
ctx.beginPath(); | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, true); | |
ctx.closePath(); | |
ctx.stroke(); | |
continue; | |
} | |
if (type === 'fillArc') { | |
ctx.beginPath(); | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle); | |
ctx.closePath(); | |
ctx.fill(); | |
continue; | |
} | |
if (type === 'fillArc-counterclockwise') { | |
ctx.beginPath(); | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, true); | |
ctx.closePath(); | |
ctx.fill(); | |
continue; | |
} | |
if (type === 'moveTo') { | |
ctx.moveTo(props.x, props.y); | |
continue; | |
} | |
if (type === 'lineTo') { | |
ctx.lineTo(props.x, props.y); | |
continue; | |
} | |
if (type === 'bezierCurveTo') { | |
ctx.bezierCurveTo(props.cp1x, props.cp1y, props.cp2x, props.cp2y, props.x, props.y); | |
continue; | |
} | |
if (type === 'quadraticCurveTo') { | |
ctx.quadraticCurveTo(props.cpx, props.cpy, props.x, props.y); | |
continue; | |
} | |
if (type === 'anticlockwise-arc') { | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, true); | |
continue; | |
} | |
if (type === 'arc') { | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle); | |
continue; | |
} | |
if (type === 'full-arc') { | |
ctx.arc(props.x, props.y, props.r, 0, this.pi2); | |
continue; | |
} | |
if (type === 'quick-arc') { | |
ctx.arc(0, 0, props.r, 0, this.pi2); | |
continue; | |
} | |
if (type === 'arcTo') { | |
ctx.arcTo(props.x1, props.y1, props.x2, props.y2, props.r); | |
continue; | |
} | |
if (type === 'anticlockwise-ellipse') { | |
this.save(); | |
this.translate(props.x, props.y); | |
this.rotate(props.rotation); | |
this.scale(props.radiusX, props.radiusY); | |
this.arc(0, 0, 1, props.startAngle, props.endAngle, true); | |
this.restore(); | |
continue; | |
} | |
if (type === 'ellipse') { | |
this.save(); | |
this.translate(props.x, props.y); | |
this.rotate(props.rotation); | |
this.scale(props.radiusX, props.radiusY); | |
this.arc(0, 0, 1, props.startAngle, props.endAngle); | |
this.restore(); | |
continue; | |
} | |
if (type === 'full-ellipse') { | |
this.save(); | |
this.translate(props.x, props.y); | |
this.rotate(props.rotation); | |
this.scale(props.radiusX, props.radiusY); | |
this.arc(0, 0, 1, 0, this.pi2); | |
this.restore(); | |
continue; | |
} | |
if (type === 'quick-ellipse') { | |
this.save(); | |
this.translate(props.x, props.y); | |
this.scale(props.radiusX, props.radiusY); | |
this.arc(0, 0, 1, 0, this.pi2); | |
this.restore(); | |
continue; | |
} | |
if (type === 'globalCompositeOperation') { | |
this.globalCompositeOperationStack.push(ctx.globalCompositeOperation); | |
ctx.globalCompositeOperation = props.value; | |
continue; | |
} | |
if (type === 'endGlobalCompositeOperation') { | |
ctx.globalCompositeOperation = this.globalCompositeOperationStack.pop(); | |
continue; | |
} | |
if (type === 'fill') { | |
ctx.fill(); | |
continue; | |
} | |
if (type === 'stroke') { | |
ctx.stroke(); | |
continue; | |
} | |
if (type === 'beginClip') { | |
ctx.save(); | |
ctx.beginPath(); | |
continue; | |
} | |
if (type === 'clip') { | |
ctx.clip(); | |
continue; | |
} | |
if (type === 'endClip') { | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'beginPath') { | |
ctx.beginPath(); | |
continue; | |
} | |
if (type === 'closePath') { | |
ctx.closePath(); | |
continue; | |
} | |
if (type === 'globalAlpha') { | |
this.globalAlphaStack.push(ctx.globalAlpha); | |
ctx.globalAlpha *= props.value; | |
continue; | |
} | |
if (type === 'endGlobalAlpha') { | |
ctx.globalAlpha = this.globalAlphaStack.pop(); | |
continue; | |
} | |
if (type === 'hitRegion') { | |
matrix[0] = this.transformStack[this.transformStackIndex - 6]; | |
matrix[1] = this.transformStack[this.transformStackIndex - 5]; | |
matrix[2] = this.transformStack[this.transformStackIndex - 4]; | |
matrix[3] = this.transformStack[this.transformStackIndex - 3]; | |
matrix[4] = this.transformStack[this.transformStackIndex - 2]; | |
matrix[5] = this.transformStack[this.transformStackIndex - 1]; | |
cache = { | |
id: props.id, | |
points: transformPoints(props.points, matrix) | |
}; | |
this.mouseRegions.push(cache); | |
this.touchRegions.push(cache); | |
continue; | |
} | |
if (type === 'imageSmoothingEnabled') { | |
this.imageSmoothingEnabledStack.push(ctx.imageSmoothingEnabled); | |
ctx.imageSmoothingEnabled = props.value; | |
continue; | |
} | |
if (type === 'endImageSmoothingEnabled') { | |
ctx.imageSmoothingEnabled = this.imageSmoothingEnabledStack.pop(); | |
continue; | |
} | |
} | |
return this.applyStyles(); | |
}; | |
Renderer.create = function create(width, height, parent, worker) { | |
if (arguments.length > 2) { | |
return new Renderer(width, height, parent, worker); | |
} | |
if (arguments.length === 2) { | |
return new Renderer(width, height); | |
} | |
return new Renderer(); | |
}; | |
Renderer.prototype.resize = function(width, height) { | |
//only resize if the sizes are different, because it clears the canvas | |
if (this.canvas.width.toString() !== width.toString()) { | |
this.canvas.width = width; | |
if (this.parent !== document.body) { | |
this.parent.style.width = width + "px"; | |
} | |
} | |
if (this.canvas.height.toString() !== height.toString()) { | |
this.canvas.height = height; | |
if (this.parent !== document.body) { | |
this.parent.style.height = height + "px"; | |
} | |
} | |
}; | |
Renderer.prototype.toImage = function toImage() { | |
var Img = require('./Img'); | |
var img = new Img(); | |
img.src = this.canvas.toDataURL('image/png'); | |
return img; | |
}; | |
Renderer.prototype.hookRender = function hookRender() { | |
//If the client has sent a 'ready' command and a tree exists | |
if (this.isReady) { | |
//fire the mouse event again if it wasn't run | |
if (this.lastMouseEvent && !this.ranMouseEvent) { | |
this.mouseMove(this.lastMouseEvent); | |
} | |
if (this.lastTouchEvent && !this.ranTouchEvent) { | |
this.touchEvent(this.lastMouseEvent); | |
} | |
this.fireFrame(); | |
} | |
return window.requestAnimationFrame(this.boundHookRenderFunction); | |
}; | |
Renderer.prototype.hookMouseEvents = function hookMouseEvents() { | |
//whenever the mouse moves, report the position | |
window.document.addEventListener('mousemove', this.mouseMove.bind(this)); | |
//only report mousedown on canvas | |
this.canvas.addEventListener('mousedown', this.mouseDown.bind(this)); | |
//mouse up can happen anywhere | |
return window.document.addEventListener('mouseup', this.mouseUp.bind(this)); | |
}; | |
Renderer.prototype.hookTouchEvents = function hookTouchEvents() { | |
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].forEach(function(evt) { | |
return window.document.addEventListener(evt, this.touchEvent.bind(this)); | |
}, this); | |
}; | |
Renderer.prototype.touchEvent = function touchEvent(evt) { | |
var rect = this.canvas.getBoundingClientRect(), | |
touchRegions = this.touchRegions.slice(), | |
mousePoint = [0,0], | |
region; | |
var previousIds = this.touchData.ids.splice(0, this.touchData.ids.length), | |
previousTouches = this.touchData.touches.splice(0, this.touchData.touches.length), | |
touchPoint; | |
for(var i = 0; i < evt.touches.length; i++) { | |
var touch = evt.touches.item(i); | |
var index = previousIds.indexOf(touch.identifier); | |
touchPoint = index === -1 ? { x: 0, y: 0, activeRegions: [], id: touch.identifier, touched: true, held: false } : previousTouches[index]; | |
touchPoint.touched = index === -1; | |
touchPoint.held = !touchPoint.touched; | |
touchPoint.x = touch.clientX - rect.left; | |
touchPoint.y = touch.clientY - rect.top; | |
this.touchData.touches.push(touchPoint); | |
this.touchData.ids.push(touchPoint.identifier); | |
mousePoint[0] = touchPoint.x; | |
mousePoint[1] = touchPoint.y; | |
touchPoint.activeRegions.splice(0, touchPoint.activeRegions.length); | |
for(var j = 0; j < this.mouseRegions.length; i++) { | |
region = touchRegions[j]; | |
if (pointInPolygon(mousePoint, region.points)) { | |
touchPoint.activeRegions.push(region.id); | |
touchRegions.splice(touchRegions.indexOf(region), 1); | |
j -= 1; | |
} | |
} | |
} | |
this.lastTouchEvent = evt; | |
this.ranTouchEvent = true; | |
evt.preventDefault(); | |
this.emit('touch', this.touchData); | |
return false; | |
}; | |
Renderer.prototype.mouseMove = function mouseMove(evt) { | |
//get bounding rectangle | |
var rect = this.canvas.getBoundingClientRect(), | |
mousePoint = [0,0], | |
region; | |
this.lastMouseEvent = evt; | |
this.ranMouseEvent = true; | |
mousePoint[0] = evt.clientX - rect.left; | |
mousePoint[1] = evt.clientY - rect.top; | |
for(var i = 0; i < this.mouseRegions.length; i++) { | |
region = this.mouseRegions[i]; | |
if (pointInPolygon(mousePoint, region.points)) { | |
this.activeRegions.push(region.id); | |
this.mouseRegions.splice(this.mouseRegions.indexOf(region), 1); | |
i -= 1; | |
} | |
} | |
this.mouseData.x = mousePoint[0]; | |
this.mouseData.y = mousePoint[1]; | |
//new state is down, last state is up | |
this.mouseData.clicked = this.mouseState === 'down' && this.mouseData.state === 'up'; | |
this.mouseData.state = this.mouseState; | |
this.mouseData.activeRegions = this.activeRegions; | |
this.emit('mouse', this.mouseData); | |
//default event stuff | |
evt.preventDefault(); | |
return false; | |
}; | |
Renderer.prototype.mouseDown = function mouseMove(evt) { | |
//set the mouseState down | |
this.mouseState = 'down'; | |
this.canvas.focus(); | |
//defer to mouseMove | |
return this.mouseMove(evt); | |
}; | |
Renderer.prototype.mouseUp = function mouseMove(evt) { | |
//set the mouse state | |
this.mouseState = 'up'; | |
//defer to mouse move | |
return this.mouseMove(evt); | |
}; | |
Renderer.prototype.hookKeyboardEvents = function hookKeyboardEvents() { | |
//every code in keycode.code needs to be on keyData | |
for (var name in keycode.code) { | |
if (keycode.code.hasOwnProperty(name)) { | |
this.keyData[name] = "up"; | |
} | |
} | |
//keydown should only happen ON the canvas | |
this.canvas.addEventListener('keydown', this.keyDown.bind(this)); | |
//but keyup should be captured everywhere | |
return window.document.addEventListener('keyup', this.keyUp.bind(this)); | |
}; | |
Renderer.prototype.keyChange = function keyChange(evt) { | |
this.emit('key', this.keyData); | |
evt.preventDefault(); | |
return false; | |
}; | |
Renderer.prototype.keyDown = function keyDown(evt) { | |
this.keyData[keycode(evt.keyCode)] = "down"; | |
return this.keyChange(evt); | |
}; | |
Renderer.prototype.keyUp = function keyUp(evt) { | |
this.keyData[keycode(evt.keyCode)] = "up"; | |
return this.keyChange(evt); | |
}; | |
Renderer.prototype.fireFrame = function() { | |
this.mouseRegions.splice(0, this.mouseRegions.length); | |
this.touchRegions.splice(0, this.touchRegions.length); | |
this.emit('frame', {}); | |
this.activeRegions.splice(0, this.activeRegions.length); | |
this.ranMouseEvent = false; | |
return this; | |
}; | |
Renderer.prototype.style = function style() { | |
var children = [], | |
styles = [], | |
concat = children.concat, | |
len, | |
i, | |
child, | |
name; | |
for(i = 0, len = arguments.length; i < len; i++) { | |
children.push(arguments[i]); | |
} | |
for (i = 0, len = children.length; i < len; i++) { | |
child = children[i]; | |
if (child && child.constructor === Array) { | |
children = concat.apply([], children); | |
child = children[i]; | |
while(child && child.constructor === Array) { | |
children = concat.apply([], children); | |
child = children[i]; | |
} | |
len = children.length; | |
} | |
if (child) { | |
styles.push(child); | |
} | |
} | |
for (i = 0; i < styles.length; i++) { | |
this.styleQueue.push(styles[i]); | |
} | |
return this; | |
}; | |
Renderer.prototype.applyStyles = function applyStyles() { | |
var styleVal, value; | |
for(var i = 0; i < this.styleQueue.length; i++) { | |
styleVal = this.styleQueue[i]; | |
for(var name in styleVal) { | |
if (styleVal.hasOwnProperty(name)) { | |
this.canvas.style[name] = styleVal[name]; | |
} | |
} | |
} | |
this.styleQueue.splice(0, this.styleQueue.length); | |
return this; | |
}; | |
Renderer.prototype.ready = function ready() { | |
this.isReady = true; | |
this.fireFrame(); | |
return window.requestAnimationFrame(this.hookRender.bind(this)); | |
}; | |
Renderer.prototype.measureText = function measureText(font, text) { | |
var oldFont = this.ctx.font, | |
result; | |
this.ctx.font = font; | |
result = this.ctx.measureText(text); | |
this.ctx.font = oldFont; | |
return result; | |
}; | |
Renderer.prototype.increaseTransformStackSize = function increaseTransformStackSize() { | |
var cache = this.transformStack; | |
this.transformStack = new Float64Array(this.transformStack.length + 600); //add 100 more | |
this.transformStack.set(cache); | |
return this; | |
}; | |
Object.defineProperty(Renderer.prototype, 'height', { | |
get: function() { | |
return this.canvas.width; | |
}, | |
enumerable: true, | |
configurable: false | |
}); | |
Object.defineProperty(Renderer.prototype, 'width', { | |
get: function() { | |
return this.canvas.width; | |
}, | |
enumerable: true, | |
configurable: false | |
}); | |
Object.seal(Renderer); | |
Object.seal(Renderer.prototype); | |
module.exports = Renderer; | |
},{"./Img":4,"./createLinearGradient":17,"./createRadialGradient":18,"./transformPoints":57,"events":59,"keycode":1,"point-in-polygon":2,"util":64}],7:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function addColorStop(offset, color) { | |
return new Instruction('addColorStop', { offset: offset, color: color }); | |
} | |
module.exports = addColorStop; | |
},{"./Instruction":5}],8:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function arc(x, y, r, startAngle, endAngle, anticlockwise) { | |
if (arguments.length > 5) { | |
return new Instruction(anticlockwise ? 'anticlockwise-arc' : 'arc', { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length === 5) { | |
return new Instruction('arc', { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length >= 3) { | |
return new Instruction('full-arc', { x: x, y: y, r: r}); | |
} | |
if (arguments.length >= 1) { | |
return new Instruction('quick-arc', { r: x }); | |
} | |
return new Instruction('quick-arc', { r: 1 }); | |
} | |
module.exports = arc; | |
},{"./Instruction":5}],9:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function arcTo(x1, y1, x2, y2, r) { | |
return new Instruction('arcTo', { x1: x1, y1: y1, x2: x2, y2: y2, r: r }); | |
} | |
module.exports = arcTo; | |
},{"./Instruction":5}],10:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function beginPath() { | |
return new Instruction('beginPath'); | |
} | |
module.exports = beginPath; | |
},{"./Instruction":5}],11:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { | |
return new Instruction('bezierCurveTo', { | |
cp1x: cp1x, | |
cp1y: cp1y, | |
cp2x: cp2x, | |
cp2y: cp2y, | |
x: x, | |
y: y | |
}); | |
} | |
module.exports = bezierCurveTo; | |
},{"./Instruction":5}],12:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillRect(x, y, width, height) { | |
if (arguments.length > 2) { | |
return new Instruction("clearRect", { x: x, y: y, width: width, height: height }); | |
} else { | |
return new Instruction("clearRect", { x: 0, y: 0, width: x, height: y }); | |
} | |
} | |
module.exports = fillRect; | |
},{"./Instruction":5}],13:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function clip(path, children) { | |
var result = [new Instruction('beginClip'), path, new Instruction('clip')]; | |
for(var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('endClip')); | |
return result; | |
} | |
module.exports = clip; | |
},{"./Instruction":5}],14:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function clipPath() { | |
return new Instruction('clipPath'); | |
} | |
module.exports = clipPath; | |
},{"./Instruction":5}],15:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function closePath() { | |
return new Instruction('closePath'); | |
} | |
module.exports = closePath; | |
},{"./Instruction":5}],16:[function(require,module,exports){ | |
'use strict'; | |
var concat = [].concat; | |
function createClass() { | |
var args = [], i; | |
for(i = 0; i < arguments.length; i++) { | |
args.push(arguments[i]); | |
} | |
for(i = 0; i < args.length; i++) { | |
while (args[i] && args[i].constructor === Array) { | |
args = concat.apply([], args); | |
} | |
if (args[i] && args[i].type === 'placeholder') { | |
// remove the placeholder | |
break; | |
} | |
} | |
return (function() { | |
var start = args, end = start.splice(i + 1, args.length); | |
start.pop(); | |
return function createdClass() { | |
var children = [], i; | |
for(i = 0; i < arguments.length; i++) { | |
children.push(arguments[i]); | |
} | |
return [ | |
start, children, end | |
]; | |
}; | |
}()); | |
} | |
module.exports = createClass; | |
},{}],17:[function(require,module,exports){ | |
//jshint node: true, browser: true, worker: true | |
'use strict'; | |
function createLinearGradient(x0, y0, x1, y1, children) { | |
var ctx = window.document.createElement('canvas').getContext('2d'), | |
grd = ctx.createLinearGradient(x0, y0, x1, y1); | |
for(var i = 0; i < children.length; i++) { | |
var colorStop = children[i]; | |
grd.addColorStop(colorStop.props.offset, colorStop.props.color); | |
} | |
return grd; | |
} | |
module.exports = createLinearGradient; | |
},{}],18:[function(require,module,exports){ | |
//jshint node: true, browser: true, worker: true | |
'use strict'; | |
function createRadialGradient(x0, y0, r0, x1, y1, r1, children) { | |
var ctx = window.document.createElement('canvas').getContext('2d'), | |
grd = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1); | |
for(var i = 0; i < children.length; i++) { | |
var colorStop = children[i]; | |
grd.addColorStop(colorStop.props.offset, colorStop.props.color); | |
} | |
return grd; | |
} | |
module.exports = createRadialGradient; | |
},{}],19:[function(require,module,exports){ | |
'use strict'; | |
function createRegularPolygon(radius, position, sides) { | |
radius = +radius || 1; | |
position[0] = +position[0] || 0; | |
position[1] = +position[1] || 0; | |
sides = +sides || 3; | |
var polygon = []; | |
for(var i = 0; i < sides; i++) { | |
polygon.push([ | |
position[0] + radius * Math.cos(Math.PI * 2 * i / sides), | |
position[1] + radius * Math.sin(Math.PI * 2 * i / sides) | |
]); | |
} | |
return polygon; | |
} | |
module.exports = createRegularPolygon; | |
},{}],20:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function drawCanvas(canvas, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) { | |
if (arguments.length === 9) { | |
return new Instruction('drawCanvasSource', { | |
img: canvas, | |
sx: sx, | |
sy: sy, | |
sWidth: sWidth, | |
sHeight: sHeight, | |
dx: dx, | |
dy: dy, | |
dWidth: dWidth, | |
dHeight: dHeight | |
}); | |
} | |
if (arguments.length >= 5) { | |
return new Instruction('drawCanvasSize', { | |
img: canvas, | |
dx: sx, | |
dy: sy, | |
dWidth: sWidth, | |
dHeight: sHeight | |
}); | |
} | |
if (arguments.length >= 3) { | |
return new Instruction('drawCanvas', { | |
img: canvas, | |
dx: sx, | |
dy: sy | |
}); | |
} | |
return new Instruction('drawCanvas', { | |
img: canvas, | |
dx: 0, | |
dy: 0 | |
}); | |
} | |
module.exports = drawCanvas; | |
},{"./Instruction":5}],21:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) { | |
if (arguments.length === 9) { | |
return new Instruction('drawImageSource', { | |
img: img, | |
sx: sx, | |
sy: sy, | |
sWidth: sWidth, | |
sHeight: sHeight, | |
dx: dx, | |
dy: dy, | |
dWidth: dWidth, | |
dHeight: dHeight | |
}); | |
} | |
if (arguments.length >= 5) { | |
return new Instruction('drawImageSize', { | |
img: img, | |
dx: sx, | |
dy: sy, | |
dWidth: sWidth, | |
dHeight: sHeight | |
}); | |
} | |
if (arguments.length >= 3) { | |
return new Instruction('drawImage', { | |
img: img, | |
dx: sx, | |
dy: sy | |
}); | |
} | |
return new Instruction('drawImage', { | |
img: img, | |
dx: 0, | |
dy: 0 | |
}); | |
} | |
module.exports = drawImage; | |
},{"./Instruction":5}],22:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) { | |
if (arguments.length > 7) { | |
return new Instruction(anticlockwise ? 'anticlockwise-ellipse' : 'ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length === 7) { | |
return new Instruction('ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY, rotation: rotation, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length >= 5) { | |
return new Instruction('full-ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY, rotation: rotation }); | |
} | |
if (arguments.length === 4) { | |
return new Instruction('quick-ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY }); | |
} | |
return new Instruction('quick-ellipse', { x: 0, y: 0, radiusX: x, radiusY: y }); | |
} | |
module.exports = ellipse; | |
},{"./Instruction":5}],23:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fill() { | |
return new Instruction('fill'); | |
} | |
module.exports = fill; | |
},{"./Instruction":5}],24:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'), | |
pi2 = Math.PI * 2; | |
function fillArc(x, y, r, startAngle, endAngle, counterclockwise) { | |
if (arguments.length >= 6 && counterclockwise) { | |
return new Instruction("fillArc-counterclockwise", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length > 3) { | |
return new Instruction("fillArc", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length > 1){ | |
return new Instruction("fillArc", { x: x, y: y, r: r, startAngle: 0, endAngle: pi2 }); | |
} | |
return new Instruction("fillArc", { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2 }); | |
} | |
module.exports = fillArc; | |
},{"./Instruction":5}],25:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) { | |
if (arguments.length === 9) { | |
return new Instruction('fillCanvasSource', { | |
img: img, | |
sx: sx, | |
sy: sy, | |
sWidth: sWidth, | |
sHeight: sHeight, | |
dx: dx, | |
dy: dy, | |
dWidth: dWidth, | |
dHeight: dHeight | |
}); | |
} | |
if (arguments.length >= 5) { | |
return new Instruction('fillCanvasSize', { | |
img: img, | |
dx: sx, | |
dy: sy, | |
dWidth: sWidth, | |
dHeight: sHeight | |
}); | |
} | |
if (arguments.length >= 3) { | |
return new Instruction('fillCanvas', { | |
img: img, | |
dx: sx, | |
dy: sy | |
}); | |
} | |
return new Instruction('fillCanvas', { | |
img: img, | |
dx: 0, | |
dy: 0 | |
}); | |
} | |
module.exports = fillImage; | |
},{"./Instruction":5}],26:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) { | |
if (arguments.length === 9) { | |
return new Instruction('fillImageSource', { | |
img: img, | |
sx: sx, | |
sy: sy, | |
sWidth: sWidth, | |
sHeight: sHeight, | |
dx: dx, | |
dy: dy, | |
dWidth: dWidth, | |
dHeight: dHeight | |
}); | |
} | |
if (arguments.length >= 5) { | |
return new Instruction('fillImageSize', { | |
img: img, | |
dx: sx, | |
dy: sy, | |
dWidth: sWidth, | |
dHeight: sHeight | |
}); | |
} | |
if (arguments.length >= 3) { | |
return new Instruction('fillImage', { | |
img: img, | |
dx: sx, | |
dy: sy | |
}); | |
} | |
return new Instruction('fillImage', { | |
img: img, | |
dx: 0, | |
dy: 0 | |
}); | |
} | |
module.exports = fillImage; | |
},{"./Instruction":5}],27:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillImagePattern(img, dx, dy, dWidth, dHeight) { | |
if (arguments.length >= 5) { | |
return new Instruction('fillImagePattern', { | |
img: img, | |
dx: dx, | |
dy: dy, | |
dWidth: dWidth, | |
dHeight: dHeight | |
}); | |
} | |
if (arguments.length >= 3) { | |
return new Instruction('fillImagePattern', { | |
img: img, | |
dx: 0, | |
dy: 0, | |
dWidth: dx, | |
dHeight: dy | |
}); | |
} | |
return new Instruction('fillImagePattern', { | |
img: img, | |
dx: 0, | |
dy: 0, | |
dWidth: 0, | |
dHeight: 0 | |
}); | |
} | |
module.exports = fillImagePattern; | |
},{"./Instruction":5}],28:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillRect(x, y, width, height) { | |
if (arguments.length >= 4) { | |
return new Instruction("fillRect", { x: x, y: y, width: width, height: height }); | |
} else { | |
return new Instruction("fillRect", { x: 0, y: 0, width: x, height: y }); | |
} | |
} | |
module.exports = fillRect; | |
},{"./Instruction":5}],29:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillStyle(value, children) { | |
var result = [new Instruction('fillStyle', { value: value })]; | |
for(var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('endFillStyle')); | |
return result; | |
} | |
module.exports = fillStyle; | |
},{"./Instruction":5}],30:[function(require,module,exports){ | |
var Instruction = require('./Instruction'); | |
module.exports = function fillText(text, x, y, maxWidth) { | |
if (arguments.length < 4) { | |
maxWidth = null; | |
} | |
if (arguments.length < 3) { | |
x = 0; | |
y = 0; | |
} | |
return new Instruction('fillText', { | |
text: text, | |
x: x, | |
y: y, | |
maxWidth: maxWidth | |
}); | |
}; | |
},{"./Instruction":5}],31:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function globalAlpha(alpha, children) { | |
var result = [new Instruction('globalAlpha', { value: alpha })]; | |
for(var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('endGlobalAlpha')); | |
return result; | |
} | |
module.exports = globalAlpha; | |
},{"./Instruction":5}],32:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function globalCompositeOperation(operationType, children) { | |
var result = [new Instruction('globalCompositeOperation', { value: operationType })]; | |
if (arguments.length === 0) { | |
return []; | |
} | |
for (var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('endGlobalCompositeOperation')); | |
return result; | |
} | |
module.exports = globalCompositeOperation; | |
},{"./Instruction":5}],33:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'), | |
hitRegion = require('./hitRegion'); | |
function hitRect(id, x, y, width, height) { | |
if (arguments.length <= 3) { | |
width = x; | |
height = y; | |
x = 0; | |
y = 0; | |
} | |
var points = [ | |
[x, y], | |
[x, y + height], | |
[x + width, y + height], | |
[x + width, y] | |
]; | |
return hitRegion(id, points); | |
} | |
module.exports = hitRect; | |
},{"./Instruction":5,"./hitRegion":34}],34:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function hitRegion(id, points) { | |
return new Instruction('hitRegion', { | |
id: id, | |
points: points | |
}); | |
} | |
module.exports = hitRegion; | |
},{"./Instruction":5}],35:[function(require,module,exports){ | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
module.exports = function imageSmoothingEnabled(val, children) { | |
children = []; | |
for(var i = 1; i < arguments.length; i++) { | |
children.push(arguments[i]); | |
} | |
return [new Instruction('imageSmoothingEnabled', { value: Boolean(val) })].concat(children).concat(new Instruction('endImageSmoothingEnabled')); | |
}; | |
},{"./Instruction":5}],36:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function lineStyle(value, children) { | |
value = value || {}; | |
var result = { | |
lineWidth: null, | |
lineCap: null, | |
lineJoin: null, | |
miterLimit: null, | |
lineDash: [], | |
lineDashOffset: null | |
}; | |
if (typeof value.lineWidth !== 'undefined') { | |
result.lineWidth = value.lineWidth; | |
} | |
if (typeof value.lineCap !== 'undefined') { | |
result.lineCap = value.lineCap; | |
} | |
if (typeof value.lineJoin !== 'undefined') { | |
result.lineJoin = value.lineJoin; | |
} | |
if (typeof value.miterLimit !== 'undefined') { | |
result.miterLimit = value.miterLimit; | |
} | |
if (typeof value.lineDash !== 'undefined') { | |
result.lineDash = value.lineDash; | |
} | |
if (typeof value.lineDashOffset !== 'undefined') { | |
result.lineDashOffset = value.lineDashOffset; | |
} | |
var tree = [new Instruction('lineStyle', result)]; | |
for(var i = 1; i < arguments.length; i++) { | |
tree.push(arguments[i]); | |
} | |
tree.push(new Instruction('endLineStyle')); | |
return tree; | |
} | |
module.exports = lineStyle; | |
},{"./Instruction":5}],37:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function lineTo(x, y) { | |
if (arguments.length === 0) { | |
return new Instruction('lineTo', { x: 0, y: 0}); | |
} | |
return new Instruction('lineTo', { x: x, y: y }); | |
} | |
module.exports = lineTo; | |
},{"./Instruction":5}],38:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function moveTo(x, y) { | |
if (arguments.length === 0) { | |
return new Instruction('moveTo', { x: 0, y: 0}); | |
} | |
return new Instruction('moveTo', { x: x, y: y }); | |
} | |
module.exports = moveTo; | |
},{"./Instruction":5}],39:[function(require,module,exports){ | |
'use strict'; | |
var moveTo = require('./moveTo'), lineTo = require('./lineTo'); | |
function moveToLineTo(point, index) { | |
return index === 0 ? moveTo(point[0], point[1]) : lineTo(point[0], point[1]); | |
} | |
module.exports = moveToLineTo; | |
},{"./lineTo":37,"./moveTo":38}],40:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var beginPath = require('./beginPath'), | |
closePath = require('./closePath'); | |
function path(children) { | |
var result = [beginPath()]; | |
for(var i = 0; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(closePath()); | |
return result; | |
} | |
module.exports = path; | |
},{"./beginPath":10,"./closePath":15}],41:[function(require,module,exports){ | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
module.exports = function placeHolder() { | |
return new Instruction('placeholder'); | |
}; | |
},{"./Instruction":5}],42:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function quadraticCurveTo(cpx, cpy, x, y) { | |
return new Instruction('quadraticCurveTo', { | |
cpx: cpx, | |
cpy: cpy, | |
x: x, | |
y: y | |
}); | |
} | |
module.exports = quadraticCurveTo; | |
},{"./Instruction":5}],43:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function rect(x, y, width, height) { | |
if (arguments.length > 2) { | |
return new Instruction("rect", { x: x, y: y, width: width, height: height }); | |
} else { | |
return new Instruction("rect", { x: 0, y: 0, width: x, height: y }); | |
} | |
} | |
module.exports = rect; | |
},{"./Instruction":5}],44:[function(require,module,exports){ | |
'use strict'; | |
var setTransform = require('./setTransform'); | |
module.exports = function resetTransform() { | |
var args = []; | |
for(var i = 0; i < arguments.length; i++) { | |
args.push(arguments[i]); | |
} | |
return setTransform([1, 0, 0, 1, 0, 0], args); | |
}; | |
},{"./setTransform":47}],45:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function rotate(r, children) { | |
r = +r; | |
var result = [new Instruction('rotate', { r: r })]; | |
for(var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('restore')); | |
return result; | |
} | |
module.exports = rotate; | |
},{"./Instruction":5}],46:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function scale(x, y, children) { | |
var i = 2; | |
if (typeof y !== 'number') { | |
y = x; | |
i = 1; | |
} | |
children = children || []; | |
var result = [new Instruction('scale', { x: x, y: y })], | |
child; | |
for (; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('restore')); | |
return result; | |
} | |
module.exports = scale; | |
},{"./Instruction":5}],47:[function(require,module,exports){ | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
module.exports = function(matrix, children) { | |
var result = [new Instruction('setTransform', [ | |
matrix[0], | |
matrix[1], | |
matrix[2], | |
matrix[3], | |
matrix[4], | |
matrix[5] | |
])]; | |
for(var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('restore')); | |
return result; | |
}; | |
},{"./Instruction":5}],48:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function shadowStyle(value, children) { | |
value = value || {}; | |
var result = { | |
shadowBlur: null, | |
shadowColor: null, | |
shadowOffsetX: null, | |
shadowOffsetY: null | |
}; | |
if (typeof value.shadowBlur !== 'undefined') { | |
result.shadowBlur = value.shadowBlur; | |
} | |
if (typeof value.shadowColor !== 'undefined') { | |
result.shadowColor = value.shadowColor; | |
} | |
if (typeof value.shadowOffsetX !== 'undefined') { | |
result.shadowOffsetX = value.shadowOffsetX; | |
} | |
if (typeof value.direction !== 'undefined') { | |
result.shadowOffsetY = value.shadowOffsetY; | |
} | |
var tree = [new Instruction('shadowStyle', value)]; | |
for (var i = 1; i < arguments.length; i++) { | |
tree.push(arguments[i]); | |
} | |
tree.push(new Instruction('endShadowStyle')); | |
return tree; | |
} | |
module.exports = shadowStyle; | |
},{"./Instruction":5}],49:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function stroke() { | |
return new Instruction('stroke'); | |
} | |
module.exports = stroke; | |
},{"./Instruction":5}],50:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'), | |
pi2 = Math.PI * 2; | |
function strokeArc(x, y, r, startAngle, endAngle, counterclockwise) { | |
if (arguments.length >= 6 && counterclockwise) { | |
return new Instruction("strokeArc-counterclockwise", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length > 3) { | |
return new Instruction("strokeArc", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle }); | |
} | |
if (arguments.length > 1){ | |
return new Instruction("strokeArc", { x: x, y: y, r: r, startAngle: 0, endAngle: pi2 }); | |
} | |
return new Instruction("strokeArc", { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2 }); | |
} | |
module.exports = strokeArc; | |
},{"./Instruction":5}],51:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function strokeRect(x, y, width, height) { | |
if (arguments.length > 2) { | |
return new Instruction("strokeRect", { x: x, y: y, width: width, height: height }); | |
} else { | |
return new Instruction("strokeRect", { x: 0, y: 0, width: x, height: y }); | |
} | |
} | |
module.exports = strokeRect; | |
},{"./Instruction":5}],52:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function fillStyle(value, children) { | |
var result = [ new Instruction('strokeStyle', { value: value }) ]; | |
for(var i = 1; i < arguments.length; i++) { | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('endStrokeStyle')); | |
return result; | |
} | |
module.exports = fillStyle; | |
},{"./Instruction":5}],53:[function(require,module,exports){ | |
var Instruction = require('./Instruction'); | |
module.exports = function strokeText(text, x, y, maxWidth) { | |
if (arguments.length < 4) { | |
maxWidth = null; | |
} | |
if (arguments.length < 3) { | |
x = 0; | |
y = 0; | |
} | |
return new Instruction('strokeText', { | |
text: text, | |
x: x, | |
y: y, | |
maxWidth: maxWidth | |
}); | |
}; | |
},{"./Instruction":5}],54:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function text(str, x, y, fill, stroke, maxWidth) { | |
if (arguments.length === 6) { | |
return new Instruction('text', { | |
x: x, | |
y: y, | |
fill: fill, | |
stroke: stroke, | |
text: str, | |
maxWidth: maxWidth | |
}); | |
} | |
if (arguments.length === 5) { | |
return new Instruction('text', { | |
x: x, | |
y: y, | |
fill: fill, | |
stroke: stroke, | |
text: str, | |
maxWidth: 0 | |
}); | |
} | |
if (arguments.length === 4) { | |
return new Instruction('text', { | |
x: x, | |
y: y, | |
fill: fill, | |
stroke: false, | |
text: str, | |
maxWidth: 0 | |
}); | |
} | |
if (arguments.length === 3) { | |
return new Instruction('text', { | |
x: x, | |
y: y, | |
fill: true, | |
stroke: false, | |
text: str, | |
maxWidth: 0 | |
}); | |
} | |
return new Instruction('text', { | |
x: 0, | |
y: 0, | |
fill: true, | |
stroke: false, | |
text: str, | |
maxWidth: 0 | |
}); | |
} | |
module.exports = text; | |
},{"./Instruction":5}],55:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function textStyle(value, children) { | |
value = value || {}; | |
var result = { | |
font: null, | |
textAlign: null, | |
textBaseline: null, | |
direction: null | |
}; | |
if (typeof value.font !== 'undefined') { | |
result.font = value.font; | |
} | |
if (typeof value.textAlign !== 'undefined') { | |
result.textAlign = value.textAlign; | |
} | |
if (typeof value.textBaseline !== 'undefined') { | |
result.textBaseline = value.textBaseline; | |
} | |
if (typeof value.direction !== 'undefined') { | |
result.direction = value.direction; | |
} | |
var tree = [new Instruction('textStyle', value)]; | |
for(var i = 1; i < arguments.length; i++) { | |
tree.push(arguments[i]); | |
} | |
tree.push(new Instruction('endTextStyle')); | |
return tree; | |
} | |
module.exports = textStyle; | |
},{"./Instruction":5}],56:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function transform(values, children) { | |
var transformResult = [ | |
new Instruction('transform',[ | |
values[0], | |
values[1], | |
values[2], | |
values[3], | |
values[4], | |
values[5] | |
]) | |
]; | |
for(var i = 1, len = arguments.length; i < len; i++) { | |
transformResult.push(arguments[i]); | |
} | |
transformResult.push(new Instruction('restore')); | |
return transformResult; | |
} | |
module.exports = transform; | |
},{"./Instruction":5}],57:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
function transformPoints(points, matrix) { | |
var result = [], | |
len = points.length, | |
point; | |
for(var i = 0; i < len; i++) { | |
point = points[i]; | |
result.push([ | |
matrix[0] * point[0] + matrix[2] * point[1] + matrix[4], | |
matrix[1] * point[0] + matrix[3] * point[1] + matrix[5] | |
]); | |
} | |
return result; | |
} | |
module.exports = transformPoints; | |
},{}],58:[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
var Instruction = require('./Instruction'); | |
function translate(x, y, children) { | |
var result = [new Instruction('translate', { x: x, y: y })]; | |
var val; | |
for (var i = 2; i < arguments.length; i++) { | |
val = arguments[i]; | |
if (Array.isArray(val)) { | |
result = result.concat(val); | |
continue; | |
} | |
result.push(arguments[i]); | |
} | |
result.push(new Instruction('restore')); | |
return result; | |
} | |
module.exports = translate; | |
},{"./Instruction":5}],59:[function(require,module,exports){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
function EventEmitter() { | |
this._events = this._events || {}; | |
this._maxListeners = this._maxListeners || undefined; | |
} | |
module.exports = EventEmitter; | |
// Backwards-compat with node 0.10.x | |
EventEmitter.EventEmitter = EventEmitter; | |
EventEmitter.prototype._events = undefined; | |
EventEmitter.prototype._maxListeners = undefined; | |
// By default EventEmitters will print a warning if more than 10 listeners are | |
// added to it. This is a useful default which helps finding memory leaks. | |
EventEmitter.defaultMaxListeners = 10; | |
// Obviously not all Emitters should be limited to 10. This function allows | |
// that to be increased. Set to zero for unlimited. | |
EventEmitter.prototype.setMaxListeners = function(n) { | |
if (!isNumber(n) || n < 0 || isNaN(n)) | |
throw TypeError('n must be a positive number'); | |
this._maxListeners = n; | |
return this; | |
}; | |
EventEmitter.prototype.emit = function(type) { | |
var er, handler, len, args, i, listeners; | |
if (!this._events) | |
this._events = {}; | |
// If there is no 'error' event listener then throw. | |
if (type === 'error') { | |
if (!this._events.error || | |
(isObject(this._events.error) && !this._events.error.length)) { | |
er = arguments[1]; | |
if (er instanceof Error) { | |
throw er; // Unhandled 'error' event | |
} else { | |
throw TypeError('Uncaught, unspecified "error" event.'); | |
} | |
return false; | |
} | |
} | |
handler = this._events[type]; | |
if (isUndefined(handler)) | |
return false; | |
if (isFunction(handler)) { | |
switch (arguments.length) { | |
// fast cases | |
case 1: | |
handler.call(this); | |
break; | |
case 2: | |
handler.call(this, arguments[1]); | |
break; | |
case 3: | |
handler.call(this, arguments[1], arguments[2]); | |
break; | |
// slower | |
default: | |
len = arguments.length; | |
args = new Array(len - 1); | |
for (i = 1; i < len; i++) | |
args[i - 1] = arguments[i]; | |
handler.apply(this, args); | |
} | |
} else if (isObject(handler)) { | |
len = arguments.length; | |
args = new Array(len - 1); | |
for (i = 1; i < len; i++) | |
args[i - 1] = arguments[i]; | |
listeners = handler.slice(); | |
len = listeners.length; | |
for (i = 0; i < len; i++) | |
listeners[i].apply(this, args); | |
} | |
return true; | |
}; | |
EventEmitter.prototype.addListener = function(type, listener) { | |
var m; | |
if (!isFunction(listener)) | |
throw TypeError('listener must be a function'); | |
if (!this._events) | |
this._events = {}; | |
// To avoid recursion in the case that type === "newListener"! Before | |
// adding it to the listeners, first emit "newListener". | |
if (this._events.newListener) | |
this.emit('newListener', type, | |
isFunction(listener.listener) ? | |
listener.listener : listener); | |
if (!this._events[type]) | |
// Optimize the case of one listener. Don't need the extra array object. | |
this._events[type] = listener; | |
else if (isObject(this._events[type])) | |
// If we've already got an array, just append. | |
this._events[type].push(listener); | |
else | |
// Adding the second element, need to change to array. | |
this._events[type] = [this._events[type], listener]; | |
// Check for listener leak | |
if (isObject(this._events[type]) && !this._events[type].warned) { | |
var m; | |
if (!isUndefined(this._maxListeners)) { | |
m = this._maxListeners; | |
} else { | |
m = EventEmitter.defaultMaxListeners; | |
} | |
if (m && m > 0 && this._events[type].length > m) { | |
this._events[type].warned = true; | |
console.error('(node) warning: possible EventEmitter memory ' + | |
'leak detected. %d listeners added. ' + | |
'Use emitter.setMaxListeners() to increase limit.', | |
this._events[type].length); | |
if (typeof console.trace === 'function') { | |
// not supported in IE 10 | |
console.trace(); | |
} | |
} | |
} | |
return this; | |
}; | |
EventEmitter.prototype.on = EventEmitter.prototype.addListener; | |
EventEmitter.prototype.once = function(type, listener) { | |
if (!isFunction(listener)) | |
throw TypeError('listener must be a function'); | |
var fired = false; | |
function g() { | |
this.removeListener(type, g); | |
if (!fired) { | |
fired = true; | |
listener.apply(this, arguments); | |
} | |
} | |
g.listener = listener; | |
this.on(type, g); | |
return this; | |
}; | |
// emits a 'removeListener' event iff the listener was removed | |
EventEmitter.prototype.removeListener = function(type, listener) { | |
var list, position, length, i; | |
if (!isFunction(listener)) | |
throw TypeError('listener must be a function'); | |
if (!this._events || !this._events[type]) | |
return this; | |
list = this._events[type]; | |
length = list.length; | |
position = -1; | |
if (list === listener || | |
(isFunction(list.listener) && list.listener === listener)) { | |
delete this._events[type]; | |
if (this._events.removeListener) | |
this.emit('removeListener', type, listener); | |
} else if (isObject(list)) { | |
for (i = length; i-- > 0;) { | |
if (list[i] === listener || | |
(list[i].listener && list[i].listener === listener)) { | |
position = i; | |
break; | |
} | |
} | |
if (position < 0) | |
return this; | |
if (list.length === 1) { | |
list.length = 0; | |
delete this._events[type]; | |
} else { | |
list.splice(position, 1); | |
} | |
if (this._events.removeListener) | |
this.emit('removeListener', type, listener); | |
} | |
return this; | |
}; | |
EventEmitter.prototype.removeAllListeners = function(type) { | |
var key, listeners; | |
if (!this._events) | |
return this; | |
// not listening for removeListener, no need to emit | |
if (!this._events.removeListener) { | |
if (arguments.length === 0) | |
this._events = {}; | |
else if (this._events[type]) | |
delete this._events[type]; | |
return this; | |
} | |
// emit removeListener for all listeners on all events | |
if (arguments.length === 0) { | |
for (key in this._events) { | |
if (key === 'removeListener') continue; | |
this.removeAllListeners(key); | |
} | |
this.removeAllListeners('removeListener'); | |
this._events = {}; | |
return this; | |
} | |
listeners = this._events[type]; | |
if (isFunction(listeners)) { | |
this.removeListener(type, listeners); | |
} else { | |
// LIFO order | |
while (listeners.length) | |
this.removeListener(type, listeners[listeners.length - 1]); | |
} | |
delete this._events[type]; | |
return this; | |
}; | |
EventEmitter.prototype.listeners = function(type) { | |
var ret; | |
if (!this._events || !this._events[type]) | |
ret = []; | |
else if (isFunction(this._events[type])) | |
ret = [this._events[type]]; | |
else | |
ret = this._events[type].slice(); | |
return ret; | |
}; | |
EventEmitter.listenerCount = function(emitter, type) { | |
var ret; | |
if (!emitter._events || !emitter._events[type]) | |
ret = 0; | |
else if (isFunction(emitter._events[type])) | |
ret = 1; | |
else | |
ret = emitter._events[type].length; | |
return ret; | |
}; | |
function isFunction(arg) { | |
return typeof arg === 'function'; | |
} | |
function isNumber(arg) { | |
return typeof arg === 'number'; | |
} | |
function isObject(arg) { | |
return typeof arg === 'object' && arg !== null; | |
} | |
function isUndefined(arg) { | |
return arg === void 0; | |
} | |
},{}],60:[function(require,module,exports){ | |
if (typeof Object.create === 'function') { | |
// implementation from standard node.js 'util' module | |
module.exports = function inherits(ctor, superCtor) { | |
ctor.super_ = superCtor | |
ctor.prototype = Object.create(superCtor.prototype, { | |
constructor: { | |
value: ctor, | |
enumerable: false, | |
writable: true, | |
configurable: true | |
} | |
}); | |
}; | |
} else { | |
// old school shim for old browsers | |
module.exports = function inherits(ctor, superCtor) { | |
ctor.super_ = superCtor | |
var TempCtor = function () {} | |
TempCtor.prototype = superCtor.prototype | |
ctor.prototype = new TempCtor() | |
ctor.prototype.constructor = ctor | |
} | |
} | |
},{}],61:[function(require,module,exports){ | |
(function (process){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
// resolves . and .. elements in a path array with directory names there | |
// must be no slashes, empty elements, or device names (c:\) in the array | |
// (so also no leading and trailing slashes - it does not distinguish | |
// relative and absolute paths) | |
function normalizeArray(parts, allowAboveRoot) { | |
// if the path tries to go above the root, `up` ends up > 0 | |
var up = 0; | |
for (var i = parts.length - 1; i >= 0; i--) { | |
var last = parts[i]; | |
if (last === '.') { | |
parts.splice(i, 1); | |
} else if (last === '..') { | |
parts.splice(i, 1); | |
up++; | |
} else if (up) { | |
parts.splice(i, 1); | |
up--; | |
} | |
} | |
// if the path is allowed to go above the root, restore leading ..s | |
if (allowAboveRoot) { | |
for (; up--; up) { | |
parts.unshift('..'); | |
} | |
} | |
return parts; | |
} | |
// Split a filename into [root, dir, basename, ext], unix version | |
// 'root' is just a slash, or nothing. | |
var splitPathRe = | |
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; | |
var splitPath = function(filename) { | |
return splitPathRe.exec(filename).slice(1); | |
}; | |
// path.resolve([from ...], to) | |
// posix version | |
exports.resolve = function() { | |
var resolvedPath = '', | |
resolvedAbsolute = false; | |
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | |
var path = (i >= 0) ? arguments[i] : process.cwd(); | |
// Skip empty and invalid entries | |
if (typeof path !== 'string') { | |
throw new TypeError('Arguments to path.resolve must be strings'); | |
} else if (!path) { | |
continue; | |
} | |
resolvedPath = path + '/' + resolvedPath; | |
resolvedAbsolute = path.charAt(0) === '/'; | |
} | |
// At this point the path should be resolved to a full absolute path, but | |
// handle relative paths to be safe (might happen when process.cwd() fails) | |
// Normalize the path | |
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { | |
return !!p; | |
}), !resolvedAbsolute).join('/'); | |
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | |
}; | |
// path.normalize(path) | |
// posix version | |
exports.normalize = function(path) { | |
var isAbsolute = exports.isAbsolute(path), | |
trailingSlash = substr(path, -1) === '/'; | |
// Normalize the path | |
path = normalizeArray(filter(path.split('/'), function(p) { | |
return !!p; | |
}), !isAbsolute).join('/'); | |
if (!path && !isAbsolute) { | |
path = '.'; | |
} | |
if (path && trailingSlash) { | |
path += '/'; | |
} | |
return (isAbsolute ? '/' : '') + path; | |
}; | |
// posix version | |
exports.isAbsolute = function(path) { | |
return path.charAt(0) === '/'; | |
}; | |
// posix version | |
exports.join = function() { | |
var paths = Array.prototype.slice.call(arguments, 0); | |
return exports.normalize(filter(paths, function(p, index) { | |
if (typeof p !== 'string') { | |
throw new TypeError('Arguments to path.join must be strings'); | |
} | |
return p; | |
}).join('/')); | |
}; | |
// path.relative(from, to) | |
// posix version | |
exports.relative = function(from, to) { | |
from = exports.resolve(from).substr(1); | |
to = exports.resolve(to).substr(1); | |
function trim(arr) { | |
var start = 0; | |
for (; start < arr.length; start++) { | |
if (arr[start] !== '') break; | |
} | |
var end = arr.length - 1; | |
for (; end >= 0; end--) { | |
if (arr[end] !== '') break; | |
} | |
if (start > end) return []; | |
return arr.slice(start, end - start + 1); | |
} | |
var fromParts = trim(from.split('/')); | |
var toParts = trim(to.split('/')); | |
var length = Math.min(fromParts.length, toParts.length); | |
var samePartsLength = length; | |
for (var i = 0; i < length; i++) { | |
if (fromParts[i] !== toParts[i]) { | |
samePartsLength = i; | |
break; | |
} | |
} | |
var outputParts = []; | |
for (var i = samePartsLength; i < fromParts.length; i++) { | |
outputParts.push('..'); | |
} | |
outputParts = outputParts.concat(toParts.slice(samePartsLength)); | |
return outputParts.join('/'); | |
}; | |
exports.sep = '/'; | |
exports.delimiter = ':'; | |
exports.dirname = function(path) { | |
var result = splitPath(path), | |
root = result[0], | |
dir = result[1]; | |
if (!root && !dir) { | |
// No dirname whatsoever | |
return '.'; | |
} | |
if (dir) { | |
// It has a dirname, strip trailing slash | |
dir = dir.substr(0, dir.length - 1); | |
} | |
return root + dir; | |
}; | |
exports.basename = function(path, ext) { | |
var f = splitPath(path)[2]; | |
// TODO: make this comparison case-insensitive on windows? | |
if (ext && f.substr(-1 * ext.length) === ext) { | |
f = f.substr(0, f.length - ext.length); | |
} | |
return f; | |
}; | |
exports.extname = function(path) { | |
return splitPath(path)[3]; | |
}; | |
function filter (xs, f) { | |
if (xs.filter) return xs.filter(f); | |
var res = []; | |
for (var i = 0; i < xs.length; i++) { | |
if (f(xs[i], i, xs)) res.push(xs[i]); | |
} | |
return res; | |
} | |
// String.prototype.substr - negative index don't work in IE8 | |
var substr = 'ab'.substr(-1) === 'b' | |
? function (str, start, len) { return str.substr(start, len) } | |
: function (str, start, len) { | |
if (start < 0) start = str.length + start; | |
return str.substr(start, len); | |
} | |
; | |
}).call(this,require('_process')) | |
},{"_process":62}],62:[function(require,module,exports){ | |
// shim for using process in browser | |
var process = module.exports = {}; | |
process.nextTick = (function () { | |
var canSetImmediate = typeof window !== 'undefined' | |
&& window.setImmediate; | |
var canPost = typeof window !== 'undefined' | |
&& window.postMessage && window.addEventListener | |
; | |
if (canSetImmediate) { | |
return function (f) { return window.setImmediate(f) }; | |
} | |
if (canPost) { | |
var queue = []; | |
window.addEventListener('message', function (ev) { | |
var source = ev.source; | |
if ((source === window || source === null) && ev.data === 'process-tick') { | |
ev.stopPropagation(); | |
if (queue.length > 0) { | |
var fn = queue.shift(); | |
fn(); | |
} | |
} | |
}, true); | |
return function nextTick(fn) { | |
queue.push(fn); | |
window.postMessage('process-tick', '*'); | |
}; | |
} | |
return function nextTick(fn) { | |
setTimeout(fn, 0); | |
}; | |
})(); | |
process.title = 'browser'; | |
process.browser = true; | |
process.env = {}; | |
process.argv = []; | |
function noop() {} | |
process.on = noop; | |
process.addListener = noop; | |
process.once = noop; | |
process.off = noop; | |
process.removeListener = noop; | |
process.removeAllListeners = noop; | |
process.emit = noop; | |
process.binding = function (name) { | |
throw new Error('process.binding is not supported'); | |
} | |
// TODO(shtylman) | |
process.cwd = function () { return '/' }; | |
process.chdir = function (dir) { | |
throw new Error('process.chdir is not supported'); | |
}; | |
},{}],63:[function(require,module,exports){ | |
module.exports = function isBuffer(arg) { | |
return arg && typeof arg === 'object' | |
&& typeof arg.copy === 'function' | |
&& typeof arg.fill === 'function' | |
&& typeof arg.readUInt8 === 'function'; | |
} | |
},{}],64:[function(require,module,exports){ | |
(function (process,global){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
var formatRegExp = /%[sdj%]/g; | |
exports.format = function(f) { | |
if (!isString(f)) { | |
var objects = []; | |
for (var i = 0; i < arguments.length; i++) { | |
objects.push(inspect(arguments[i])); | |
} | |
return objects.join(' '); | |
} | |
var i = 1; | |
var args = arguments; | |
var len = args.length; | |
var str = String(f).replace(formatRegExp, function(x) { | |
if (x === '%%') return '%'; | |
if (i >= len) return x; | |
switch (x) { | |
case '%s': return String(args[i++]); | |
case '%d': return Number(args[i++]); | |
case '%j': | |
try { | |
return JSON.stringify(args[i++]); | |
} catch (_) { | |
return '[Circular]'; | |
} | |
default: | |
return x; | |
} | |
}); | |
for (var x = args[i]; i < len; x = args[++i]) { | |
if (isNull(x) || !isObject(x)) { | |
str += ' ' + x; | |
} else { | |
str += ' ' + inspect(x); | |
} | |
} | |
return str; | |
}; | |
// Mark that a method should not be used. | |
// Returns a modified function which warns once by default. | |
// If --no-deprecation is set, then it is a no-op. | |
exports.deprecate = function(fn, msg) { | |
// Allow for deprecating things in the process of starting up. | |
if (isUndefined(global.process)) { | |
return function() { | |
return exports.deprecate(fn, msg).apply(this, arguments); | |
}; | |
} | |
if (process.noDeprecation === true) { | |
return fn; | |
} | |
var warned = false; | |
function deprecated() { | |
if (!warned) { | |
if (process.throwDeprecation) { | |
throw new Error(msg); | |
} else if (process.traceDeprecation) { | |
console.trace(msg); | |
} else { | |
console.error(msg); | |
} | |
warned = true; | |
} | |
return fn.apply(this, arguments); | |
} | |
return deprecated; | |
}; | |
var debugs = {}; | |
var debugEnviron; | |
exports.debuglog = function(set) { | |
if (isUndefined(debugEnviron)) | |
debugEnviron = process.env.NODE_DEBUG || ''; | |
set = set.toUpperCase(); | |
if (!debugs[set]) { | |
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { | |
var pid = process.pid; | |
debugs[set] = function() { | |
var msg = exports.format.apply(exports, arguments); | |
console.error('%s %d: %s', set, pid, msg); | |
}; | |
} else { | |
debugs[set] = function() {}; | |
} | |
} | |
return debugs[set]; | |
}; | |
/** | |
* Echos the value of a value. Trys to print the value out | |
* in the best way possible given the different types. | |
* | |
* @param {Object} obj The object to print out. | |
* @param {Object} opts Optional options object that alters the output. | |
*/ | |
/* legacy: obj, showHidden, depth, colors*/ | |
function inspect(obj, opts) { | |
// default options | |
var ctx = { | |
seen: [], | |
stylize: stylizeNoColor | |
}; | |
// legacy... | |
if (arguments.length >= 3) ctx.depth = arguments[2]; | |
if (arguments.length >= 4) ctx.colors = arguments[3]; | |
if (isBoolean(opts)) { | |
// legacy... | |
ctx.showHidden = opts; | |
} else if (opts) { | |
// got an "options" object | |
exports._extend(ctx, opts); | |
} | |
// set default options | |
if (isUndefined(ctx.showHidden)) ctx.showHidden = false; | |
if (isUndefined(ctx.depth)) ctx.depth = 2; | |
if (isUndefined(ctx.colors)) ctx.colors = false; | |
if (isUndefined(ctx.customInspect)) ctx.customInspect = true; | |
if (ctx.colors) ctx.stylize = stylizeWithColor; | |
return formatValue(ctx, obj, ctx.depth); | |
} | |
exports.inspect = inspect; | |
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics | |
inspect.colors = { | |
'bold' : [1, 22], | |
'italic' : [3, 23], | |
'underline' : [4, 24], | |
'inverse' : [7, 27], | |
'white' : [37, 39], | |
'grey' : [90, 39], | |
'black' : [30, 39], | |
'blue' : [34, 39], | |
'cyan' : [36, 39], | |
'green' : [32, 39], | |
'magenta' : [35, 39], | |
'red' : [31, 39], | |
'yellow' : [33, 39] | |
}; | |
// Don't use 'blue' not visible on cmd.exe | |
inspect.styles = { | |
'special': 'cyan', | |
'number': 'yellow', | |
'boolean': 'yellow', | |
'undefined': 'grey', | |
'null': 'bold', | |
'string': 'green', | |
'date': 'magenta', | |
// "name": intentionally not styling | |
'regexp': 'red' | |
}; | |
function stylizeWithColor(str, styleType) { | |
var style = inspect.styles[styleType]; | |
if (style) { | |
return '\u001b[' + inspect.colors[style][0] + 'm' + str + | |
'\u001b[' + inspect.colors[style][1] + 'm'; | |
} else { | |
return str; | |
} | |
} | |
function stylizeNoColor(str, styleType) { | |
return str; | |
} | |
function arrayToHash(array) { | |
var hash = {}; | |
array.forEach(function(val, idx) { | |
hash[val] = true; | |
}); | |
return hash; | |
} | |
function formatValue(ctx, value, recurseTimes) { | |
// Provide a hook for user-specified inspect functions. | |
// Check that value is an object with an inspect function on it | |
if (ctx.customInspect && | |
value && | |
isFunction(value.inspect) && | |
// Filter out the util module, it's inspect function is special | |
value.inspect !== exports.inspect && | |
// Also filter out any prototype objects using the circular check. | |
!(value.constructor && value.constructor.prototype === value)) { | |
var ret = value.inspect(recurseTimes, ctx); | |
if (!isString(ret)) { | |
ret = formatValue(ctx, ret, recurseTimes); | |
} | |
return ret; | |
} | |
// Primitive types cannot have properties | |
var primitive = formatPrimitive(ctx, value); | |
if (primitive) { | |
return primitive; | |
} | |
// Look up the keys of the object. | |
var keys = Object.keys(value); | |
var visibleKeys = arrayToHash(keys); | |
if (ctx.showHidden) { | |
keys = Object.getOwnPropertyNames(value); | |
} | |
// IE doesn't make error fields non-enumerable | |
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx | |
if (isError(value) | |
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { | |
return formatError(value); | |
} | |
// Some type of object without properties can be shortcutted. | |
if (keys.length === 0) { | |
if (isFunction(value)) { | |
var name = value.name ? ': ' + value.name : ''; | |
return ctx.stylize('[Function' + name + ']', 'special'); | |
} | |
if (isRegExp(value)) { | |
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); | |
} | |
if (isDate(value)) { | |
return ctx.stylize(Date.prototype.toString.call(value), 'date'); | |
} | |
if (isError(value)) { | |
return formatError(value); | |
} | |
} | |
var base = '', array = false, braces = ['{', '}']; | |
// Make Array say that they are Array | |
if (isArray(value)) { | |
array = true; | |
braces = ['[', ']']; | |
} | |
// Make functions say that they are functions | |
if (isFunction(value)) { | |
var n = value.name ? ': ' + value.name : ''; | |
base = ' [Function' + n + ']'; | |
} | |
// Make RegExps say that they are RegExps | |
if (isRegExp(value)) { | |
base = ' ' + RegExp.prototype.toString.call(value); | |
} | |
// Make dates with properties first say the date | |
if (isDate(value)) { | |
base = ' ' + Date.prototype.toUTCString.call(value); | |
} | |
// Make error with message first say the error | |
if (isError(value)) { | |
base = ' ' + formatError(value); | |
} | |
if (keys.length === 0 && (!array || value.length == 0)) { | |
return braces[0] + base + braces[1]; | |
} | |
if (recurseTimes < 0) { | |
if (isRegExp(value)) { | |
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); | |
} else { | |
return ctx.stylize('[Object]', 'special'); | |
} | |
} | |
ctx.seen.push(value); | |
var output; | |
if (array) { | |
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); | |
} else { | |
output = keys.map(function(key) { | |
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); | |
}); | |
} | |
ctx.seen.pop(); | |
return reduceToSingleString(output, base, braces); | |
} | |
function formatPrimitive(ctx, value) { | |
if (isUndefined(value)) | |
return ctx.stylize('undefined', 'undefined'); | |
if (isString(value)) { | |
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') | |
.replace(/'/g, "\\'") | |
.replace(/\\"/g, '"') + '\''; | |
return ctx.stylize(simple, 'string'); | |
} | |
if (isNumber(value)) | |
return ctx.stylize('' + value, 'number'); | |
if (isBoolean(value)) | |
return ctx.stylize('' + value, 'boolean'); | |
// For some reason typeof null is "object", so special case here. | |
if (isNull(value)) | |
return ctx.stylize('null', 'null'); | |
} | |
function formatError(value) { | |
return '[' + Error.prototype.toString.call(value) + ']'; | |
} | |
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { | |
var output = []; | |
for (var i = 0, l = value.length; i < l; ++i) { | |
if (hasOwnProperty(value, String(i))) { | |
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, | |
String(i), true)); | |
} else { | |
output.push(''); | |
} | |
} | |
keys.forEach(function(key) { | |
if (!key.match(/^\d+$/)) { | |
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, | |
key, true)); | |
} | |
}); | |
return output; | |
} | |
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { | |
var name, str, desc; | |
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; | |
if (desc.get) { | |
if (desc.set) { | |
str = ctx.stylize('[Getter/Setter]', 'special'); | |
} else { | |
str = ctx.stylize('[Getter]', 'special'); | |
} | |
} else { | |
if (desc.set) { | |
str = ctx.stylize('[Setter]', 'special'); | |
} | |
} | |
if (!hasOwnProperty(visibleKeys, key)) { | |
name = '[' + key + ']'; | |
} | |
if (!str) { | |
if (ctx.seen.indexOf(desc.value) < 0) { | |
if (isNull(recurseTimes)) { | |
str = formatValue(ctx, desc.value, null); | |
} else { | |
str = formatValue(ctx, desc.value, recurseTimes - 1); | |
} | |
if (str.indexOf('\n') > -1) { | |
if (array) { | |
str = str.split('\n').map(function(line) { | |
return ' ' + line; | |
}).join('\n').substr(2); | |
} else { | |
str = '\n' + str.split('\n').map(function(line) { | |
return ' ' + line; | |
}).join('\n'); | |
} | |
} | |
} else { | |
str = ctx.stylize('[Circular]', 'special'); | |
} | |
} | |
if (isUndefined(name)) { | |
if (array && key.match(/^\d+$/)) { | |
return str; | |
} | |
name = JSON.stringify('' + key); | |
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { | |
name = name.substr(1, name.length - 2); | |
name = ctx.stylize(name, 'name'); | |
} else { | |
name = name.replace(/'/g, "\\'") | |
.replace(/\\"/g, '"') | |
.replace(/(^"|"$)/g, "'"); | |
name = ctx.stylize(name, 'string'); | |
} | |
} | |
return name + ': ' + str; | |
} | |
function reduceToSingleString(output, base, braces) { | |
var numLinesEst = 0; | |
var length = output.reduce(function(prev, cur) { | |
numLinesEst++; | |
if (cur.indexOf('\n') >= 0) numLinesEst++; | |
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; | |
}, 0); | |
if (length > 60) { | |
return braces[0] + | |
(base === '' ? '' : base + '\n ') + | |
' ' + | |
output.join(',\n ') + | |
' ' + | |
braces[1]; | |
} | |
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; | |
} | |
// NOTE: These type checking functions intentionally don't use `instanceof` | |
// because it is fragile and can be easily faked with `Object.create()`. | |
function isArray(ar) { | |
return Array.isArray(ar); | |
} | |
exports.isArray = isArray; | |
function isBoolean(arg) { | |
return typeof arg === 'boolean'; | |
} | |
exports.isBoolean = isBoolean; | |
function isNull(arg) { | |
return arg === null; | |
} | |
exports.isNull = isNull; | |
function isNullOrUndefined(arg) { | |
return arg == null; | |
} | |
exports.isNullOrUndefined = isNullOrUndefined; | |
function isNumber(arg) { | |
return typeof arg === 'number'; | |
} | |
exports.isNumber = isNumber; | |
function isString(arg) { | |
return typeof arg === 'string'; | |
} | |
exports.isString = isString; | |
function isSymbol(arg) { | |
return typeof arg === 'symbol'; | |
} | |
exports.isSymbol = isSymbol; | |
function isUndefined(arg) { | |
return arg === void 0; | |
} | |
exports.isUndefined = isUndefined; | |
function isRegExp(re) { | |
return isObject(re) && objectToString(re) === '[object RegExp]'; | |
} | |
exports.isRegExp = isRegExp; | |
function isObject(arg) { | |
return typeof arg === 'object' && arg !== null; | |
} | |
exports.isObject = isObject; | |
function isDate(d) { | |
return isObject(d) && objectToString(d) === '[object Date]'; | |
} | |
exports.isDate = isDate; | |
function isError(e) { | |
return isObject(e) && | |
(objectToString(e) === '[object Error]' || e instanceof Error); | |
} | |
exports.isError = isError; | |
function isFunction(arg) { | |
return typeof arg === 'function'; | |
} | |
exports.isFunction = isFunction; | |
function isPrimitive(arg) { | |
return arg === null || | |
typeof arg === 'boolean' || | |
typeof arg === 'number' || | |
typeof arg === 'string' || | |
typeof arg === 'symbol' || // ES6 symbol | |
typeof arg === 'undefined'; | |
} | |
exports.isPrimitive = isPrimitive; | |
exports.isBuffer = require('./support/isBuffer'); | |
function objectToString(o) { | |
return Object.prototype.toString.call(o); | |
} | |
function pad(n) { | |
return n < 10 ? '0' + n.toString(10) : n.toString(10); | |
} | |
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', | |
'Oct', 'Nov', 'Dec']; | |
// 26 Feb 16:19:34 | |
function timestamp() { | |
var d = new Date(); | |
var time = [pad(d.getHours()), | |
pad(d.getMinutes()), | |
pad(d.getSeconds())].join(':'); | |
return [d.getDate(), months[d.getMonth()], time].join(' '); | |
} | |
// log is just a thin wrapper to console.log that prepends a timestamp | |
exports.log = function() { | |
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); | |
}; | |
/** | |
* Inherit the prototype methods from one constructor into another. | |
* | |
* The Function.prototype.inherits from lang.js rewritten as a standalone | |
* function (not on Function.prototype). NOTE: If this file is to be loaded | |
* during bootstrapping this function needs to be rewritten using some native | |
* functions as prototype setup using normal JavaScript does not work as | |
* expected during bootstrapping (see mirror.js in r114903). | |
* | |
* @param {function} ctor Constructor function which needs to inherit the | |
* prototype. | |
* @param {function} superCtor Constructor function to inherit prototype from. | |
*/ | |
exports.inherits = require('inherits'); | |
exports._extend = function(origin, add) { | |
// Don't do anything if add isn't an object | |
if (!add || !isObject(add)) return origin; | |
var keys = Object.keys(add); | |
var i = keys.length; | |
while (i--) { | |
origin[keys[i]] = add[keys[i]]; | |
} | |
return origin; | |
}; | |
function hasOwnProperty(obj, prop) { | |
return Object.prototype.hasOwnProperty.call(obj, prop); | |
} | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{"./support/isBuffer":63,"_process":62,"inherits":60}],"e2d":[function(require,module,exports){ | |
//jshint node: true | |
'use strict'; | |
module.exports = { | |
addColorStop: require('./src/addColorStop'), | |
arc: require('./src/arc'), | |
arcTo: require('./src/arcTo'), | |
beginPath: require('./src/beginPath'), | |
bezierCurveTo: require('./src/bezierCurveTo'), | |
Canvas: require('./src/Canvas'), | |
clearRect: require('./src/clearRect'), | |
clip: require('./src/clip'), | |
clipPath: require('./src/clipPath'), | |
closePath: require('./src/closePath'), | |
createClass: require('./src/createClass'), | |
createLinearGradient: require('./src/createLinearGradient'), | |
createRadialGradient: require('./src/createRadialGradient'), | |
createRegularPolygon : require('./src/createRegularPolygon'), | |
drawCanvas: require('./src/drawCanvas'), | |
drawImage: require('./src/drawImage'), | |
ellipse: require('./src/ellipse'), | |
fill: require('./src/fill'), | |
fillArc: require('./src/fillArc'), | |
fillCanvas: require('./src/fillCanvas'), | |
fillImage: require('./src/fillImage'), | |
fillImagePattern: require('./src/fillImagePattern'), | |
fillRect: require('./src/fillRect'), | |
fillStyle: require('./src/fillStyle'), | |
fillText: require('./src/fillText'), | |
globalAlpha: require('./src/globalAlpha'), | |
globalCompositeOperation: require('./src/globalCompositeOperation'), | |
hitRect: require('./src/hitRect'), | |
hitRegion: require('./src/hitRegion'), | |
imageSmoothingEnabled: require('./src/imageSmoothingEnabled'), | |
Img: require('./src/Img'), | |
Instruction: require('./src/Instruction'), | |
lineStyle: require('./src/lineStyle'), | |
lineTo: require('./src/lineTo'), | |
moveTo: require('./src/moveTo'), | |
moveToLineTo: require('./src/moveToLineTo'), | |
path: require('./src/path'), | |
placeHolder: require('./src/placeHolder'), | |
quadraticCurveTo: require('./src/quadraticCurveTo'), | |
rect: require('./src/rect'), | |
Renderer: require('./src/Renderer'), | |
resetTransform: require('./src/resetTransform'), | |
rotate: require('./src/rotate'), | |
scale: require('./src/scale'), | |
setTransform: require('./src/setTransform'), | |
shadowStyle: require('./src/shadowStyle'), | |
stroke: require('./src/stroke'), | |
strokeArc: require('./src/strokeArc'), | |
strokeRect: require('./src/strokeRect'), | |
strokeStyle: require('./src/strokeStyle'), | |
strokeText: require('./src/strokeText'), | |
text: require('./src/text'), | |
textStyle: require('./src/textStyle'), | |
transform: require('./src/transform'), | |
transformPoints: require('./src/transformPoints'), | |
translate: require('./src/translate') | |
}; | |
},{"./src/Canvas":3,"./src/Img":4,"./src/Instruction":5,"./src/Renderer":6,"./src/addColorStop":7,"./src/arc":8,"./src/arcTo":9,"./src/beginPath":10,"./src/bezierCurveTo":11,"./src/clearRect":12,"./src/clip":13,"./src/clipPath":14,"./src/closePath":15,"./src/createClass":16,"./src/createLinearGradient":17,"./src/createRadialGradient":18,"./src/createRegularPolygon":19,"./src/drawCanvas":20,"./src/drawImage":21,"./src/ellipse":22,"./src/fill":23,"./src/fillArc":24,"./src/fillCanvas":25,"./src/fillImage":26,"./src/fillImagePattern":27,"./src/fillRect":28,"./src/fillStyle":29,"./src/fillText":30,"./src/globalAlpha":31,"./src/globalCompositeOperation":32,"./src/hitRect":33,"./src/hitRegion":34,"./src/imageSmoothingEnabled":35,"./src/lineStyle":36,"./src/lineTo":37,"./src/moveTo":38,"./src/moveToLineTo":39,"./src/path":40,"./src/placeHolder":41,"./src/quadraticCurveTo":42,"./src/rect":43,"./src/resetTransform":44,"./src/rotate":45,"./src/scale":46,"./src/setTransform":47,"./src/shadowStyle":48,"./src/stroke":49,"./src/strokeArc":50,"./src/strokeRect":51,"./src/strokeStyle":52,"./src/strokeText":53,"./src/text":54,"./src/textStyle":55,"./src/transform":56,"./src/transformPoints":57,"./src/translate":58}]},{},[]) | |
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi91c3IvbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL25vZGVfbW9kdWxlcy9rZXljb2RlL2luZGV4LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9ub2RlX21vZHVsZXMvcG9pbnQtaW4tcG9seWdvbi9pbmRleC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL0NhbnZhcy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL0ltZy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL0luc3RydWN0aW9uLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvUmVuZGVyZXIuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9hZGRDb2xvclN0b3AuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9hcmMuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9hcmNUby5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2JlZ2luUGF0aC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2JlemllckN1cnZlVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jbGVhclJlY3QuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jbGlwLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvY2xpcFBhdGguanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jbG9zZVBhdGguanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jcmVhdGVDbGFzcy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2NyZWF0ZUxpbmVhckdyYWRpZW50LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvY3JlYXRlUmFkaWFsR3JhZGllbnQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jcmVhdGVSZWd1bGFyUG9seWdvbi5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2RyYXdDYW52YXMuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9kcmF3SW1hZ2UuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9lbGxpcHNlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2ZpbGxBcmMuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9maWxsQ2FudmFzLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbEltYWdlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbEltYWdlUGF0dGVybi5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2ZpbGxSZWN0LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbFN0eWxlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbFRleHQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9nbG9iYWxBbHBoYS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbi5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2hpdFJlY3QuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9oaXRSZWdpb24uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9pbWFnZVNtb290aGluZ0VuYWJsZWQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9saW5lU3R5bGUuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9saW5lVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9tb3ZlVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9tb3ZlVG9MaW5lVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9wYXRoLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvcGxhY2VIb2xkZXIuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9xdWFkcmF0aWNDdXJ2ZVRvLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvcmVjdC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3Jlc2V0VHJhbnNmb3JtLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvcm90YXRlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvc2NhbGUuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9zZXRUcmFuc2Zvcm0uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9zaGFkb3dTdHlsZS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZUFyYy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZVJlY3QuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9zdHJva2VTdHlsZS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZVRleHQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy90ZXh0LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdGV4dFN0eWxlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdHJhbnNmb3JtLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdHJhbnNmb3JtUG9pbnRzLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdHJhbnNsYXRlLmpzIiwiL3Vzci9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCIvdXNyL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIi91c3IvbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYXRoLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvdXNyL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL3Vzci9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanMiLCIvdXNyL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdXRpbC91dGlsLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBTb3VyY2U6IGh0dHA6Ly9qc2ZpZGRsZS5uZXQvdld4OFYvXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU2MDMxOTUvZnVsbC1saXN0LW9mLWphdmFzY3JpcHQta2V5Y29kZXNcblxuXG5cbi8qKlxuICogQ29uZW5pZW5jZSBtZXRob2QgcmV0dXJucyBjb3JyZXNwb25kaW5nIHZhbHVlIGZvciBnaXZlbiBrZXlOYW1lIG9yIGtleUNvZGUuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0ga2V5Q29kZSB7TnVtYmVyfSBvciBrZXlOYW1lIHtTdHJpbmd9XG4gKiBAcmV0dXJuIHtNaXhlZH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2VhcmNoSW5wdXQpIHtcbiAgLy8gS2V5Ym9hcmQgRXZlbnRzXG4gIGlmIChzZWFyY2hJbnB1dCAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIHNlYXJjaElucHV0KSB7XG4gICAgdmFyIGhhc0tleUNvZGUgPSBzZWFyY2hJbnB1dC53aGljaCB8fCBzZWFyY2hJbnB1dC5rZXlDb2RlIHx8IHNlYXJjaElucHV0LmNoYXJDb2RlXG4gICAgaWYgKGhhc0tleUNvZGUpIHNlYXJjaElucHV0ID0gaGFzS2V5Q29kZVxuICB9XG5cbiAgLy8gTnVtYmVyc1xuICBpZiAoJ251bWJlcicgPT09IHR5cGVvZiBzZWFyY2hJbnB1dCkgcmV0dXJuIG5hbWVzW3NlYXJjaElucHV0XVxuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSAoY2FzdCB0byBzdHJpbmcpXG4gIHZhciBzZWFyY2ggPSBTdHJpbmcoc2VhcmNoSW5wdXQpXG5cbiAgLy8gY2hlY2sgY29kZXNcbiAgdmFyIGZvdW5kTmFtZWRLZXkgPSBjb2Rlc1tzZWFyY2gudG9Mb3dlckNhc2UoKV1cbiAgaWYgKGZvdW5kTmFtZWRLZXkpIHJldHVybiBmb3VuZE5hbWVkS2V5XG5cbiAgLy8gY2hlY2sgYWxpYXNlc1xuICB2YXIgZm91bmROYW1lZEtleSA9IGFsaWFzZXNbc2VhcmNoLnRvTG93ZXJDYXNlKCldXG4gIGlmIChmb3VuZE5hbWVkS2V5KSByZXR1cm4gZm91bmROYW1lZEtleVxuXG4gIC8vIHdlaXJkIGNoYXJhY3Rlcj9cbiAgaWYgKHNlYXJjaC5sZW5ndGggPT09IDEpIHJldHVybiBzZWFyY2guY2hhckNvZGVBdCgwKVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBHZXQgYnkgbmFtZVxuICpcbiAqICAgZXhwb3J0cy5jb2RlWydlbnRlciddIC8vID0+IDEzXG4gKi9cblxudmFyIGNvZGVzID0gZXhwb3J0cy5jb2RlID0gZXhwb3J0cy5jb2RlcyA9IHtcbiAgJ2JhY2tzcGFjZSc6IDgsXG4gICd0YWInOiA5LFxuICAnZW50ZXInOiAxMyxcbiAgJ3NoaWZ0JzogMTYsXG4gICdjdHJsJzogMTcsXG4gICdhbHQnOiAxOCxcbiAgJ3BhdXNlL2JyZWFrJzogMTksXG4gICdjYXBzIGxvY2snOiAyMCxcbiAgJ2VzYyc6IDI3LFxuICAnc3BhY2UnOiAzMixcbiAgJ3BhZ2UgdXAnOiAzMyxcbiAgJ3BhZ2UgZG93bic6IDM0LFxuICAnZW5kJzogMzUsXG4gICdob21lJzogMzYsXG4gICdsZWZ0JzogMzcsXG4gICd1cCc6IDM4LFxuICAncmlnaHQnOiAzOSxcbiAgJ2Rvd24nOiA0MCxcbiAgJ2luc2VydCc6IDQ1LFxuICAnZGVsZXRlJzogNDYsXG4gICdjb21tYW5kJzogOTEsXG4gICdyaWdodCBjbGljayc6IDkzLFxuICAnbnVtcGFkIConOiAxMDYsXG4gICdudW1wYWQgKyc6IDEwNyxcbiAgJ251bXBhZCAtJzogMTA5LFxuICAnbnVtcGFkIC4nOiAxMTAsXG4gICdudW1wYWQgLyc6IDExMSxcbiAgJ251bSBsb2NrJzogMTQ0LFxuICAnc2Nyb2xsIGxvY2snOiAxNDUsXG4gICdteSBjb21wdXRlcic6IDE4MixcbiAgJ215IGNhbGN1bGF0b3InOiAxODMsXG4gICc7JzogMTg2LFxuICAnPSc6IDE4NyxcbiAgJywnOiAxODgsXG4gICctJzogMTg5LFxuICAnLic6IDE5MCxcbiAgJy8nOiAxOTEsXG4gICdgJzogMTkyLFxuICAnWyc6IDIxOSxcbiAgJ1xcXFwnOiAyMjAsXG4gICddJzogMjIxLFxuICBcIidcIjogMjIyLFxufVxuXG4vLyBIZWxwZXIgYWxpYXNlc1xuXG52YXIgYWxpYXNlcyA9IGV4cG9ydHMuYWxpYXNlcyA9IHtcbiAgJ3dpbmRvd3MnOiA5MSxcbiAgJ+KHpyc6IDE2LFxuICAn4oylJzogMTgsXG4gICfijIMnOiAxNyxcbiAgJ+KMmCc6IDkxLFxuICAnY3RsJzogMTcsXG4gICdjb250cm9sJzogMTcsXG4gICdvcHRpb24nOiAxOCxcbiAgJ3BhdXNlJzogMTksXG4gICdicmVhayc6IDE5LFxuICAnY2Fwcyc6IDIwLFxuICAncmV0dXJuJzogMTMsXG4gICdlc2NhcGUnOiAyNyxcbiAgJ3NwYyc6IDMyLFxuICAncGd1cCc6IDMzLFxuICAncGdkbic6IDMzLFxuICAnaW5zJzogNDUsXG4gICdkZWwnOiA0NixcbiAgJ2NtZCc6IDkxXG59XG5cblxuLyohXG4gKiBQcm9ncmFtYXRpY2FsbHkgYWRkIHRoZSBmb2xsb3dpbmdcbiAqL1xuXG4vLyBsb3dlciBjYXNlIGNoYXJzXG5mb3IgKGkgPSA5NzsgaSA8IDEyMzsgaSsrKSBjb2Rlc1tTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGkgLSAzMlxuXG4vLyBudW1iZXJzXG5mb3IgKHZhciBpID0gNDg7IGkgPCA1ODsgaSsrKSBjb2Rlc1tpIC0gNDhdID0gaVxuXG4vLyBmdW5jdGlvbiBrZXlzXG5mb3IgKGkgPSAxOyBpIDwgMTM7IGkrKykgY29kZXNbJ2YnK2ldID0gaSArIDExMVxuXG4vLyBudW1wYWQga2V5c1xuZm9yIChpID0gMDsgaSA8IDEwOyBpKyspIGNvZGVzWydudW1wYWQgJytpXSA9IGkgKyA5NlxuXG4vKipcbiAqIEdldCBieSBjb2RlXG4gKlxuICogICBleHBvcnRzLm5hbWVbMTNdIC8vID0+ICdFbnRlcidcbiAqL1xuXG52YXIgbmFtZXMgPSBleHBvcnRzLm5hbWVzID0gZXhwb3J0cy50aXRsZSA9IHt9IC8vIHRpdGxlIGZvciBiYWNrd2FyZCBjb21wYXRcblxuLy8gQ3JlYXRlIHJldmVyc2UgbWFwcGluZ1xuZm9yIChpIGluIGNvZGVzKSBuYW1lc1tjb2Rlc1tpXV0gPSBpXG5cbi8vIEFkZCBhbGlhc2VzXG5mb3IgKHZhciBhbGlhcyBpbiBhbGlhc2VzKSB7XG4gIGNvZGVzW2FsaWFzXSA9IGFsaWFzZXNbYWxpYXNdXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwb2ludCwgdnMpIHtcbiAgICAvLyByYXktY2FzdGluZyBhbGdvcml0aG0gYmFzZWQgb25cbiAgICAvLyBodHRwOi8vd3d3LmVjc2UucnBpLmVkdS9Ib21lcGFnZXMvd3JmL1Jlc2VhcmNoL1Nob3J0X05vdGVzL3BucG9seS5odG1sXG4gICAgXG4gICAgdmFyIHggPSBwb2ludFswXSwgeSA9IHBvaW50WzFdO1xuICAgIFxuICAgIHZhciBpbnNpZGUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IHZzLmxlbmd0aCAtIDE7IGkgPCB2cy5sZW5ndGg7IGogPSBpKyspIHtcbiAgICAgICAgdmFyIHhpID0gdnNbaV1bMF0sIHlpID0gdnNbaV1bMV07XG4gICAgICAgIHZhciB4aiA9IHZzW2pdWzBdLCB5aiA9IHZzW2pdWzFdO1xuICAgICAgICBcbiAgICAgICAgdmFyIGludGVyc2VjdCA9ICgoeWkgPiB5KSAhPSAoeWogPiB5KSlcbiAgICAgICAgICAgICYmICh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBpbnNpZGU7XG59O1xuIiwiLy9qc2hpbnQgd29ya2VyOiB0cnVlLCBicm93c2VyOiB0cnVlLCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIENhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XHJcblxyXG4gIHZhciBSZW5kZXJlciA9IHJlcXVpcmUoJy4vUmVuZGVyZXInKTtcclxuICB0aGlzLnJlbmRlcmVyID0gbmV3IFJlbmRlcmVyKHdpZHRoLCBoZWlnaHQsIHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSk7XHJcbiAgdGhpcy5maWxsUGF0dGVybiA9IG51bGw7XHJcbiAgdGhpcy5za2lwUGF0dGVybkNyZWF0aW9uID0gZmFsc2U7XHJcblxyXG4gIHJldHVybiBPYmplY3Quc2VhbCh0aGlzKTtcclxufVxyXG5cclxuQ2FudmFzLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoY2hpbGRyZW4pIHtcclxuICB2YXIgcmVzdWx0ID0gW10sXHJcbiAgICAgIGk7XHJcbiAgZm9yIChpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcblxyXG4gIHRoaXMucmVuZGVyZXIucmVuZGVyKHJlc3VsdCk7XHJcbiAgaWYgKCF0aGlzLnNraXBQYXR0ZXJuQ3JlYXRpb24pIHtcclxuICAgIHRoaXMuZmlsbFBhdHRlcm4gPSB0aGlzLnJlbmRlcmVyLmN0eC5jcmVhdGVQYXR0ZXJuKHRoaXMucmVuZGVyZXIuY2FudmFzLCAnbm8tcmVwZWF0Jyk7XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuQ2FudmFzLnByb3RvdHlwZS5zdHlsZSA9IGZ1bmN0aW9uIHN0eWxlKCkge1xyXG4gIHZhciBkZWZzID0gW107XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIGRlZnMucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICB0aGlzLnJlbmRlcmVyLnN0eWxlLmFwcGx5KHRoaXMucmVuZGVyZXIsIGRlZnMpO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuQ2FudmFzLnByb3RvdHlwZS50b0ltYWdlID0gZnVuY3Rpb24gdG9JbWFnZShpbWFnZUlEKSB7XHJcbiAgcmV0dXJuIHRoaXMucmVuZGVyZXIudG9JbWFnZSgpO1xyXG59O1xyXG5cclxuQ2FudmFzLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbiByZXNpemUod2lkdGgsIGhlaWdodCkge1xyXG4gIHRoaXMucmVuZGVyZXIucmVzaXplKCt3aWR0aCwgK2hlaWdodCk7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQ2FudmFzLnByb3RvdHlwZSwgJ2hlaWdodCcsIHtcclxuICBnZXQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXIuY2FudmFzLndpZHRoO1xyXG4gIH0sXHJcbiAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICBjb25maWd1cmFibGU6IGZhbHNlXHJcbn0pO1xyXG5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KENhbnZhcy5wcm90b3R5cGUsICd3aWR0aCcsIHtcclxuICBnZXQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXIuY2FudmFzLndpZHRoO1xyXG4gIH0sXHJcbiAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICBjb25maWd1cmFibGU6IGZhbHNlXHJcbn0pO1xyXG5cclxuXHJcbkNhbnZhcy5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUod2lkdGgsIGhlaWdodCwgaWQpIHtcclxuICByZXR1cm4gbmV3IENhbnZhcyh3aWR0aCwgaGVpZ2h0LCBpZCk7XHJcbn07XHJcblxyXG5cclxuT2JqZWN0LnNlYWwoQ2FudmFzKTtcclxuT2JqZWN0LnNlYWwoQ2FudmFzLnByb3RvdHlwZSk7XHJcbm1vZHVsZS5leHBvcnRzID0gQ2FudmFzO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlLCBicm93c2VyOiB0cnVlLCB3b3JrZXI6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyksXHJcbiAgICBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKSxcclxuICAgIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XHJcblxyXG51dGlsLmluaGVyaXRzKEltZywgZXZlbnRzLkV2ZW50RW1pdHRlcik7XHJcblxyXG5mdW5jdGlvbiBJbWcoKSB7XHJcbiAgZXZlbnRzLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xyXG4gIHRoaXMuaW1hZ2VFbGVtZW50ID0gbnVsbDtcclxuICB0aGlzLmltYWdlUGF0dGVybiA9IG51bGw7XHJcbiAgdGhpcy5pbWFnZVBhdHRlcm5SZXBlYXQgPSBudWxsO1xyXG4gIE9iamVjdC5zZWFsKHRoaXMpO1xyXG59XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW1nLnByb3RvdHlwZSwgJ3NyYycsIHtcclxuICBzZXQ6IGZ1bmN0aW9uKHZhbCkge1xyXG5cclxuICAgIHZhciBlbGVtZW50ID0gbmV3IEltYWdlKCk7XHJcbiAgICB0aGlzLmltYWdlRWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICBlbGVtZW50LnNyYyA9IHZhbDtcclxuXHJcbiAgICBpZiAoZWxlbWVudC5jb21wbGV0ZSkgeyAvL2ZpcmVmb3ggY29tcGF0aWJpbGl0eSBjb2RlXHJcbiAgICAgIHNldFRpbWVvdXQodGhpcy5pbWFnZUxvYWQuYmluZCh0aGlzKSwgMCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBlbGVtZW50Lm9ubG9hZCA9IHRoaXMuaW1hZ2VMb2FkLmJpbmQodGhpcyk7XHJcbiAgICB9XHJcbiAgfSxcclxuICBnZXQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VFbGVtZW50LnNyYztcclxuICB9XHJcbn0pO1xyXG5cclxuSW1nLnByb3RvdHlwZS5pbWFnZUxvYWQgPSBmdW5jdGlvbiBpbWFnZUxvYWQoKSB7XHJcblxyXG4gIHZhciBjdHggPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcclxuICB0aGlzLmltYWdlUGF0dGVybiA9IGN0eC5jcmVhdGVQYXR0ZXJuKHRoaXMuaW1hZ2VFbGVtZW50LCAnbm8tcmVwZWF0Jyk7XHJcbiAgdGhpcy5pbWFnZVBhdHRlcm5SZXBlYXQgPSBjdHguY3JlYXRlUGF0dGVybih0aGlzLmltYWdlRWxlbWVudCwgJ3JlcGVhdCcpO1xyXG5cclxuICByZXR1cm4gdGhpcy5lbWl0KCdsb2FkJywgdGhpcyk7XHJcbn07XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW1nLnByb3RvdHlwZSwgJ3dpZHRoJywge1xyXG4gIGVudW1lcmFibGU6IHRydWUsXHJcbiAgZ2V0OiBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLmltYWdlRWxlbWVudC53aWR0aDtcclxuICB9LFxyXG4gIHNldDogZnVuY3Rpb24odmFsdWUpIHtcclxuICAgIHRoaXMuaW1hZ2VFbGVtZW50LndpZHRoID0gdmFsdWU7XHJcbiAgfVxyXG59KTtcclxuXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbWcucHJvdG90eXBlLCAnaGVpZ2h0Jywge1xyXG4gIGVudW1lcmFibGU6IHRydWUsXHJcbiAgZ2V0OiBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLmltYWdlRWxlbWVudC5oZWlnaHQ7XHJcbiAgfSxcclxuICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICB0aGlzLmltYWdlRWxlbWVudC5oZWlnaHQgPSB2YWx1ZTtcclxuICB9XHJcbn0pO1xyXG5cclxuT2JqZWN0LnNlYWwoSW1nKTtcclxuT2JqZWN0LnNlYWwoSW1nLnByb3RvdHlwZSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEltZztcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbmZ1bmN0aW9uIEluc3RydWN0aW9uKHR5cGUsIHByb3BzKSB7XHJcbiAgdGhpcy50eXBlID0gdHlwZTtcclxuICB0aGlzLnByb3BzID0gcHJvcHM7XHJcbiAgT2JqZWN0LnNlYWwodGhpcyk7XHJcbn1cclxuXHJcbk9iamVjdC5zZWFsKEluc3RydWN0aW9uKTtcclxuT2JqZWN0LnNlYWwoSW5zdHJ1Y3Rpb24ucHJvdG90eXBlKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gSW5zdHJ1Y3Rpb247IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZSwgYnJvd3NlcjogdHJ1ZSwgd29ya2VyOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBjcmVhdGVMaW5lYXJHcmFkaWVudCA9IHJlcXVpcmUoJy4vY3JlYXRlTGluZWFyR3JhZGllbnQnKSxcclxuICAgIGNyZWF0ZVJhZGlhbEdyYWRpZW50ID0gcmVxdWlyZSgnLi9jcmVhdGVSYWRpYWxHcmFkaWVudCcpLFxyXG4gICAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXHJcbiAgICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxyXG4gICAga2V5Y29kZSA9IHJlcXVpcmUoJ2tleWNvZGUnKSxcclxuICAgIHRyYW5zZm9ybVBvaW50cyA9IHJlcXVpcmUoJy4vdHJhbnNmb3JtUG9pbnRzJyksXHJcbiAgICBwb2ludEluUG9seWdvbiA9IHJlcXVpcmUoJ3BvaW50LWluLXBvbHlnb24nKSxcclxuICAgIGlkZW50aXR5ID0gWzEsIDAsIDAsIDEsIDAsIDBdLFxyXG4gICAgSW1nID0gcmVxdWlyZSgnLi9JbWcnKTtcclxuXHJcbnV0aWwuaW5oZXJpdHMoUmVuZGVyZXIsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xyXG5cclxuZnVuY3Rpb24gUmVuZGVyZXIod2lkdGgsIGhlaWdodCwgcGFyZW50LCBvcHRzKSB7XHJcbiAgZXZlbnRzLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xyXG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xyXG5cclxuICAvL3ZpcnR1YWwgc3RhY2tcclxuICB0aGlzLnRyYW5zZm9ybVN0YWNrID0gbmV3IEZsb2F0NjRBcnJheShcclxuICAgICgob3B0cy50cmFuc2Zvcm1TdGFja0NvdW50IHx8IDUwMCkgKyAxKSAqIDYgLy9wcm9wZXJ0aWVzXHJcbiAgKTtcclxuICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggPSA2O1xyXG4gIHRoaXMudHJhbnNmb3JtU3RhY2suc2V0KGlkZW50aXR5KTtcclxuXHJcbiAgdGhpcy5maWxsU3R5bGVTdGFjayA9IFtdO1xyXG4gIHRoaXMuc3Ryb2tlU3R5bGVTdGFjayA9IFtdO1xyXG4gIHRoaXMubGluZVN0eWxlU3RhY2sgPSBbXTtcclxuICB0aGlzLnRleHRTdHlsZVN0YWNrID0gW107XHJcbiAgdGhpcy5zaGFkb3dTdHlsZVN0YWNrID0gW107XHJcbiAgdGhpcy5nbG9iYWxBbHBoYVN0YWNrID0gW107XHJcbiAgdGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjayA9IFtdO1xyXG4gIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2sgPSBbXTtcclxuXHJcbiAgdGhpcy5waTIgPSBNYXRoLlBJICogMjtcclxuXHJcbiAgdGhpcy5pc1JlYWR5ID0gZmFsc2U7XHJcbiAgdGhpcy5tb3VzZVN0YXRlID0gJ3VwJztcclxuICB0aGlzLm1vdXNlRGF0YSA9IHtcclxuICAgIHg6IDAsXHJcbiAgICB5OiAwLFxyXG4gICAgc3RhdGU6IHRoaXMubW91c2VTdGF0ZSxcclxuICAgIGNsaWNrZWQ6IGZhbHNlLFxyXG4gICAgYWN0aXZlUmVnaW9uczogW11cclxuICB9O1xyXG4gIHRoaXMubGFzdE1vdXNlRXZlbnQgPSBudWxsO1xyXG4gIHRoaXMucmFuTW91c2VFdmVudCA9IGZhbHNlO1xyXG4gIHRoaXMubW91c2VSZWdpb25zID0gW107XHJcbiAgdGhpcy5hY3RpdmVSZWdpb25zID0gW107XHJcbiAgdGhpcy5zdHlsZVF1ZXVlID0gW107XHJcblxyXG4gIC8vdXNlciBpbnB1dCBoZXJlXHJcbiAgdGhpcy5rZXlEYXRhID0ge307XHJcblxyXG4gIHRoaXMudG91Y2hEYXRhID0ge1xyXG4gICAgdG91Y2hlczogW10sXHJcbiAgICBpZHM6IFtdXHJcbiAgfTtcclxuICB0aGlzLmxhc3RUb3VjaEV2ZW50ID0gbnVsbDtcclxuICB0aGlzLnJhblRvdWNoRXZlbnQgPSBmYWxzZTtcclxuICB0aGlzLnRvdWNoUmVnaW9ucyA9IFtdO1xyXG5cclxuICAvL3NldCBwYXJlbnRcclxuICBpZiAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgfSBlbHNlIHtcclxuICAgIHRoaXMucGFyZW50ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgdGhpcy5wYXJlbnQuc3R5bGUubWFyZ2luID0gJzAgYXV0byc7XHJcbiAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgJ3B4JztcclxuICAgIHRoaXMucGFyZW50LnN0eWxlLmhlaWdodCA9IGhlaWdodCArICdweCc7XHJcbiAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0aGlzLnBhcmVudCk7XHJcbiAgfVxyXG5cclxuICAvL3NldCB3aWR0aCBhbmQgaGVpZ2h0IGF1dG9tYXRpY2FsbHlcclxuICBpZiAoIXdpZHRoIHx8IHdpZHRoIDw9IDApIHtcclxuICAgIHdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgfVxyXG5cclxuICBpZiAoIWhlaWdodCB8fCBoZWlnaHQgPD0gMCkge1xyXG4gICAgaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xyXG4gIH1cclxuXHJcbiAgdGhpcy5jYW52YXMgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XHJcblxyXG4gIC8vZm9jdXNhYmxlIGNhbnZhcyBidWdmaXhcclxuICB0aGlzLmNhbnZhcy50YWJJbmRleCA9IDE7XHJcblxyXG4gIHRoaXMuY3R4ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuXHJcbiAgdGhpcy5jYW52YXMud2lkdGggPSB3aWR0aDtcclxuICB0aGlzLmNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XHJcbiAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMpO1xyXG5cclxuICAvL2hvb2sgbW91c2UsIGtleWJvYXJkLCBhbmQga2V5Ym9hcmQgZXZlbnRzIHJpZ2h0IGF3YXlcclxuICB0aGlzLmhvb2tNb3VzZUV2ZW50cygpO1xyXG4gIHRoaXMuaG9va0tleWJvYXJkRXZlbnRzKCk7XHJcbiAgdGhpcy5ob29rVG91Y2hFdmVudHMoKTtcclxuXHJcbiAgdGhpcy5ib3VuZEhvb2tSZW5kZXJGdW5jdGlvbiA9IHRoaXMuaG9va1JlbmRlci5iaW5kKHRoaXMpO1xyXG4gIE9iamVjdC5zZWFsKHRoaXMpO1xyXG59XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKGFyZ3MpIHtcclxuICB2YXIgaSxcclxuICAgICAgbGVuLFxyXG4gICAgICBjaGlsZCxcclxuICAgICAgcHJvcHMsXHJcbiAgICAgIHR5cGUsXHJcbiAgICAgIGNhY2hlLFxyXG4gICAgICBtYXRyaXggPSBbMSwgMCwgMCwgMSwgMCwgMF0sXHJcbiAgICAgIHNpbnIsXHJcbiAgICAgIGNvc3IsXHJcbiAgICAgIGN0eCA9IHRoaXMuY3R4LFxyXG4gICAgICBjaGlsZHJlbiA9IFtdLFxyXG4gICAgICBjb25jYXQgPSBjaGlsZHJlbi5jb25jYXQ7XHJcblxyXG4gIC8vZmx1c2ggdGhlIHZpcnR1YWwgc3RhY2tcclxuXHJcbiAgdGhpcy5maWxsU3R5bGVTdGFjay5zcGxpY2UoMCwgdGhpcy5maWxsU3R5bGVTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMuc3Ryb2tlU3R5bGVTdGFjay5zcGxpY2UoMCwgdGhpcy5zdHJva2VTdHlsZVN0YWNrLmxlbmd0aCk7XHJcbiAgdGhpcy5saW5lU3R5bGVTdGFjay5zcGxpY2UoMCwgdGhpcy5saW5lU3R5bGVTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMudGV4dFN0eWxlU3RhY2suc3BsaWNlKDAsIHRoaXMudGV4dFN0eWxlU3RhY2subGVuZ3RoKTtcclxuICB0aGlzLnNoYWRvd1N0eWxlU3RhY2suc3BsaWNlKDAsIHRoaXMuc2hhZG93U3R5bGVTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2suc3BsaWNlKDAsIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2subGVuZ3RoKTtcclxuICB0aGlzLmdsb2JhbEFscGhhU3RhY2suc3BsaWNlKDAsIHRoaXMuZ2xvYmFsQWxwaGFTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkU3RhY2suc3BsaWNlKDAsIHRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkU3RhY2subGVuZ3RoKTtcclxuXHJcbiAgZm9yIChpID0gMCwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjaGlsZHJlbi5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG5cclxuICAvL2xvb3Agb3ZlciBldmVyeSBjaGlsZFxyXG4gIGZvciAoaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjaGlsZCA9IGNoaWxkcmVuW2ldO1xyXG5cclxuICAgIC8vZmxhdHRlbmluZyBhbGdvcml0aG1cclxuICAgIGlmIChjaGlsZCAmJiBjaGlsZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXkpIHtcclxuICAgICAgY2hpbGRyZW4gPSBjb25jYXQuYXBwbHkoW10sIGNoaWxkcmVuKTtcclxuICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG4gICAgICBsZW4gPSBjaGlsZHJlbi5sZW5ndGg7XHJcbiAgICB9XHJcblxyXG4gICAgLy9jaGlsZCBtdXN0IGJlIHRydXRoeVxyXG4gICAgaWYgKCFjaGlsZCkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICAvL3NldCBwcm9wcyBhbmQgdHlwZSBvYmplY3RcclxuICAgIHByb3BzID0gY2hpbGQucHJvcHM7XHJcbiAgICB0eXBlID0gY2hpbGQudHlwZTtcclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3RyYW5zZm9ybScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XTtcclxuICAgICAgbWF0cml4WzFdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXTtcclxuICAgICAgbWF0cml4WzRdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCA+IHRoaXMudHJhbnNmb3JtU3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdID0gLy9kXHJcbiAgICAgICAgbWF0cml4WzBdICogcHJvcHNbMF0gKyBtYXRyaXhbMl0gKiBwcm9wc1sxXTtcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IC8vYlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzBdICsgbWF0cml4WzNdICogcHJvcHNbMV07XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0gPSAvL2NcclxuICAgICAgICBtYXRyaXhbMF0gKiBwcm9wc1syXSArIG1hdHJpeFsyXSAqIHByb3BzWzNdO1xyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gLy9kXHJcbiAgICAgICAgbWF0cml4WzFdICogcHJvcHNbMl0gKyBtYXRyaXhbM10gKiBwcm9wc1szXTtcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IC8vZVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzRdICsgbWF0cml4WzJdICogcHJvcHNbNV0gKyBtYXRyaXhbNF07XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV0gPSAvL2ZcclxuICAgICAgICBtYXRyaXhbMV0gKiBwcm9wc1s0XSArIG1hdHJpeFszXSAqIHByb3BzWzVdICsgbWF0cml4WzVdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzZXRUcmFuc2Zvcm0nKSB7XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodGhpcy50cmFuc2Zvcm1TdGFja0luZGV4ID4gdGhpcy50cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICB0aGlzLmluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBwcm9wc1swXTsvL2FcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IHByb3BzWzFdOy8vYlxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gcHJvcHNbMl07Ly9jXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBwcm9wc1szXTsvL2RcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IHByb3BzWzRdOy8vZVxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gcHJvcHNbNV07Ly9mXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0ocHJvcHNbMF0sIHByb3BzWzFdLCBwcm9wc1syXSwgcHJvcHNbM10sIHByb3BzWzRdLCBwcm9wc1s1XSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc2NhbGUnKSB7XHJcbiAgICAgIG1hdHJpeFswXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNF07XHJcbiAgICAgIG1hdHJpeFszXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV07XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCA+IHRoaXMudHJhbnNmb3JtU3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdID0gbWF0cml4WzBdICogcHJvcHMueDsgLy9hXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPSBtYXRyaXhbMV0gKiBwcm9wcy54OyAvL2JcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vY1xyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gbWF0cml4WzNdICogcHJvcHMueTsgLy9kXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0gPSBtYXRyaXhbNF07IC8vZVxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOyAvL2ZcclxuXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNsYXRlJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdO1xyXG4gICAgICBtYXRyaXhbMl0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdO1xyXG4gICAgICBtYXRyaXhbNV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4ICs9IDY7XHJcbiAgICAgIGlmICh0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggPiB0aGlzLnRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMuaW5jcmVhc2VUcmFuc2Zvcm1TdGFja1NpemUoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPSBtYXRyaXhbMV07IC8vYlxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gbWF0cml4WzJdOyAvL2NcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IG1hdHJpeFszXTsgLy9kXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0gPSBtYXRyaXhbNF0gKyBtYXRyaXhbMF0gKiBwcm9wcy54ICsgbWF0cml4WzJdICogcHJvcHMueTsgLy9lXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV0gPSBtYXRyaXhbNV0gKyBtYXRyaXhbMV0gKiBwcm9wcy54ICsgbWF0cml4WzNdICogcHJvcHMueTsgLy9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3JvdGF0ZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XTtcclxuICAgICAgbWF0cml4WzFdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXTtcclxuICAgICAgbWF0cml4WzRdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuICAgICAgY29zciA9IE1hdGguY29zKHByb3BzLnIpO1xyXG4gICAgICBzaW5yID0gTWF0aC5zaW4ocHJvcHMucik7XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCA+IHRoaXMudHJhbnNmb3JtU3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdID1cclxuICAgICAgICBtYXRyaXhbMF0gKiBjb3NyICsgbWF0cml4WzJdICogc2lucjsgLy9hXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPVxyXG4gICAgICAgIG1hdHJpeFsxXSAqIGNvc3IgKyBtYXRyaXhbM10gKiBzaW5yOyAvL2JcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9XHJcbiAgICAgICAgbWF0cml4WzBdICogLXNpbnIgKyBtYXRyaXhbMl0gKiBjb3NyOyAvL2NcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9XHJcbiAgICAgICAgbWF0cml4WzFdICogLXNpbnIgKyBtYXRyaXhbM10gKiBjb3NyOyAvL2RcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV0gPSBtYXRyaXhbNV07Ly9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3Jlc3RvcmUnKSB7XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtPSA2O1xyXG4gICAgICBtYXRyaXhbMF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdO1xyXG4gICAgICBtYXRyaXhbMl0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdO1xyXG4gICAgICBtYXRyaXhbNV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbFJlY3QnKSB7XHJcbiAgICAgIGN0eC5maWxsUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlUmVjdCcpIHtcclxuICAgICAgY3R4LnN0cm9rZVJlY3QocHJvcHMueCwgcHJvcHMueSwgcHJvcHMud2lkdGgsIHByb3BzLmhlaWdodCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsZWFyUmVjdCcpIHtcclxuICAgICAgY3R4LmNsZWFyUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncmVjdCcpIHtcclxuICAgICAgY3R4LnJlY3QocHJvcHMueCwgcHJvcHMueSwgcHJvcHMud2lkdGgsIHByb3BzLmhlaWdodCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxTdHlsZScpIHtcclxuICAgICAgdGhpcy5maWxsU3R5bGVTdGFjay5wdXNoKGN0eC5maWxsU3R5bGUpO1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gcHJvcHMudmFsdWU7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVN0eWxlJykge1xyXG4gICAgICB0aGlzLnN0cm9rZVN0eWxlU3RhY2sucHVzaChjdHguc3Ryb2tlU3R5bGUpO1xyXG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBwcm9wcy52YWx1ZTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kRmlsbFN0eWxlJykge1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gdGhpcy5maWxsU3R5bGVTdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kU3Ryb2tlU3R5bGUnKSB7XHJcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHRoaXMuc3Ryb2tlU3R5bGVTdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGUgPT09ICdsaW5lU3R5bGUnKSB7XHJcbiAgICAgIHRoaXMubGluZVN0eWxlU3RhY2sucHVzaCh7XHJcbiAgICAgICAgbGluZVdpZHRoOiBjdHgubGluZVdpZHRoLFxyXG4gICAgICAgIGxpbmVDYXA6IGN0eC5saW5lQ2FwLFxyXG4gICAgICAgIGxpbmVKb2luOiBjdHgubGluZUpvaW4sXHJcbiAgICAgICAgbWl0ZXJMaW1pdDogY3R4Lm1pdGVyTGltaXQsXHJcbiAgICAgICAgbGluZURhc2g6IGN0eC5nZXRMaW5lRGFzaCgpLFxyXG4gICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBjdHgubGluZURhc2hPZmZzZXRcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZVdpZHRoICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHByb3BzLmxpbmVXaWR0aDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUNhcCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5saW5lQ2FwID0gcHJvcHMubGluZUNhcDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUpvaW4gIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZUpvaW4gPSBwcm9wcy5saW5lSm9pbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubWl0ZXJMaW1pdCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5taXRlckxpbWl0ID0gcHJvcHMubWl0ZXJMaW1pdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2gubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGN0eC5zZXRMaW5lRGFzaChwcm9wcy5saW5lRGFzaCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLmxpbmVEYXNoT2Zmc2V0ICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gcHJvcHMubGluZURhc2hPZmZzZXQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kTGluZVN0eWxlJykge1xyXG4gICAgICBjYWNoZSA9IHRoaXMubGluZVN0eWxlU3RhY2sucG9wKCk7XHJcbiAgICAgIGN0eC5saW5lV2lkdGggPSBjYWNoZS5saW5lV2lkdGg7XHJcbiAgICAgIGN0eC5saW5lQ2FwID0gY2FjaGUubGluZUNhcDtcclxuICAgICAgY3R4LmxpbmVKb2luID0gY2FjaGUubGluZUpvaW47XHJcbiAgICAgIGN0eC5taXRlckxpbWl0ID0gY2FjaGUubWl0ZXJMaW1pdDtcclxuICAgICAgY3R4LnNldExpbmVEYXNoKGNhY2hlLmxpbmVEYXNoKTtcclxuICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gY2FjaGUubGluZURhc2hPZmZzZXQ7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3RleHRTdHlsZScpIHtcclxuICAgICAgdGhpcy50ZXh0U3R5bGVTdGFjay5wdXNoKHtcclxuICAgICAgICBmb250OiBjdHguZm9udCxcclxuICAgICAgICB0ZXh0QWxpZ246IGN0eC50ZXh0QWxpZ24sXHJcbiAgICAgICAgdGV4dEJhc2VsaW5lOiBjdHgudGV4dEJhc2VsaW5lLFxyXG4gICAgICAgIGRpcmVjdGlvbjogY3R4LmRpcmVjdGlvblxyXG4gICAgICB9KTtcclxuICAgICAgaWYgKHByb3BzLmZvbnQgIT09IG51bGwpIHtcclxuICAgICAgICBjdHguZm9udCA9IHByb3BzLmZvbnQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLnRleHRBbGlnbiAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC50ZXh0QWxpZ24gPSBwcm9wcy50ZXh0QWxpZ247XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLnRleHRCYXNlbGluZSAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSBwcm9wcy50ZXh0QmFzZWxpbmU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLmxpbmVKb2luICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmRpcmVjdGlvbiA9IHByb3BzLmRpcmVjdGlvbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRUZXh0U3R5bGUnKSB7XHJcbiAgICAgIGNhY2hlID0gdGhpcy50ZXh0U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmZvbnQgPSBjYWNoZS5mb250O1xyXG4gICAgICBjdHgudGV4dEFsaWduID0gY2FjaGUudGV4dEFsaWduO1xyXG4gICAgICBjdHgudGV4dEJhc2VsaW5lID0gY2FjaGUudGV4dEJhc2VsaW5lO1xyXG4gICAgICBjdHguZGlyZWN0aW9uID0gY2FjaGUuZGlyZWN0aW9uO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzaGFkb3dTdHlsZScpIHtcclxuICAgICAgdGhpcy5zaGFkb3dTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIHNoYWRvd0JsdXI6IGN0eC5zaGFkb3dCbHVyLFxyXG4gICAgICAgIHNoYWRvd0NvbG9yOiBjdHguc2hhZG93Q29sb3IsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WDogY3R4LnNoYWRvd09mZnNldFgsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WTogY3R4LnNoYWRvd09mZnNldFlcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dCbHVyICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBwcm9wcy5zaGFkb3dCbHVyO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dDb2xvciAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5zaGFkb3dDb2xvciA9IHByb3BzLnNoYWRvd0NvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRYICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBwcm9wcy5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRZICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFkgPSBwcm9wcy5zaGFkb3dPZmZzZXRZO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZFNoYWRvd1N0eWxlJykge1xyXG4gICAgICBjYWNoZSA9IHRoaXMuc2hhZG93U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LnNoYWRvd0JsdXIgPSBjYWNoZS5zaGFkb3dCbHVyO1xyXG4gICAgICBjdHguc2hhZG93Q29sb3IgPSBjYWNoZS5zaGFkb3dDb2xvcjtcclxuICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjYWNoZS5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WSA9IGNhY2hlLnNoYWRvd09mZnNldFk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVRleHQnKSB7XHJcbiAgICAgIGlmIChwcm9wcy5tYXhXaWR0aCkge1xyXG4gICAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnksIHByb3BzLm1heFdpZHRoKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc3Ryb2tlVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsVGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoKSB7XHJcbiAgICAgICAgY3R4LmZpbGxUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnksIHByb3BzLm1heFdpZHRoKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguZmlsbFRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoICE9PSAwKSB7XHJcbiAgICAgICAgaWYgKHByb3BzLmZpbGwpIHtcclxuICAgICAgICAgIGN0eC5maWxsVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5tYXhXaWR0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwcm9wcy5zdHJva2UpIHtcclxuICAgICAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnksIHByb3BzLm1heFdpZHRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5maWxsKSB7XHJcbiAgICAgICAgY3R4LmZpbGxUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zdHJva2UpIHtcclxuICAgICAgICBjdHguc3Ryb2tlVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdJbWFnZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZy5jb25zdHJ1Y3RvciA9PT0gSW1nID8gcHJvcHMuaW1nLmltYWdlRWxlbWVudCB8fCBuZXcgSW1hZ2UoKSA6IHByb3BzLmltZztcclxuICAgICAgY3R4LmRyYXdJbWFnZShjYWNoZSB8fCBuZXcgSW1hZ2UoKSwgcHJvcHMuZHgsIHByb3BzLmR5KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3SW1hZ2VTaXplJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNhY2hlID0gcHJvcHMuaW1nLmNvbnN0cnVjdG9yID09PSBJbWcgPyBwcm9wcy5pbWcuaW1hZ2VFbGVtZW50IHx8IG5ldyBJbWFnZSgpIDogcHJvcHMuaW1nO1xyXG4gICAgICBjdHguZHJhd0ltYWdlKGNhY2hlLCBwcm9wcy5keCwgcHJvcHMuZHksIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZHJhd0ltYWdlU291cmNlJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNhY2hlID0gcHJvcHMuaW1nLmNvbnN0cnVjdG9yID09PSBJbWcgPyBwcm9wcy5pbWcuaW1hZ2VFbGVtZW50IHx8IG5ldyBJbWFnZSgpIDogcHJvcHMuaW1nO1xyXG4gICAgICBjdHguZHJhd0ltYWdlKGNhY2hlLCBwcm9wcy5zeCwgcHJvcHMuc3ksIHByb3BzLnNXaWR0aCwgcHJvcHMuc0hlaWdodCwgcHJvcHMuZHgsIHByb3BzLmR5LCBwcm9wcy5kV2lkdGgsIHByb3BzLmRIZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxJbWFnZVBhdHRlcm4nKSB7XHJcbiAgICAgIGlmICghcHJvcHMuaW1nKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IHByb3BzLmltZy5pbWFnZVBhdHRlcm5SZXBlYXQ7XHJcbiAgICAgIGN0eC50cmFuc2xhdGUocHJvcHMuZHgsIHByb3BzLmR5KTtcclxuICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxJbWFnZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZy5pbWFnZUVsZW1lbnQ7XHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy5pbWcuaW1hZ2VQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYWNoZS53aWR0aCwgY2FjaGUuaGVpZ2h0KTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbEltYWdlU2l6ZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZy5pbWFnZUVsZW1lbnQ7XHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy5pbWcuaW1hZ2VQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBjYWNoZS53aWR0aCwgcHJvcHMuZEhlaWdodCAvIGNhY2hlLmhlaWdodCk7XHJcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYWNoZS53aWR0aCwgY2FjaGUuaGVpZ2h0KTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbEltYWdlU291cmNlJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy5pbWcuaW1hZ2VQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBwcm9wcy5zV2lkdGgsIHByb3BzLmRIZWlnaHQgLyBwcm9wcy5zSGVpZ2h0KTtcclxuICAgICAgY3R4LnRyYW5zbGF0ZSgtcHJvcHMuc3gsIC1wcm9wcy5zeSk7XHJcbiAgICAgIGN0eC5maWxsUmVjdChwcm9wcy5zeCwgcHJvcHMuc3ksIHByb3BzLnNXaWR0aCwgcHJvcHMuc0hlaWdodCk7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsQ2FudmFzJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNhY2hlID0gcHJvcHMuaW1nO1xyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gY2FjaGUuZmlsbFBhdHRlcm47XHJcbiAgICAgIGN0eC50cmFuc2xhdGUocHJvcHMuZHgsIHByb3BzLmR5KTtcclxuICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIGNhY2hlLndpZHRoLCBjYWNoZS5oZWlnaHQpO1xyXG4gICAgICBjdHgucmVzdG9yZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsQ2FudmFzU2l6ZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZztcclxuICAgICAgY3R4LnNhdmUoKTtcclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IGNhY2hlLmZpbGxQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBjYWNoZS53aWR0aCwgcHJvcHMuZEhlaWdodCAvIGNhY2hlLmhlaWdodCk7XHJcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYWNoZS53aWR0aCwgY2FjaGUuaGVpZ2h0KTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbENhbnZhc1NvdXJjZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gcHJvcHMuaW1nLmZpbGxQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBwcm9wcy5zV2lkdGgsIHByb3BzLmRIZWlnaHQgLyBwcm9wcy5zSGVpZ2h0KTtcclxuICAgICAgY3R4LnRyYW5zbGF0ZSgtcHJvcHMuc3gsIC1wcm9wcy5zeSk7XHJcbiAgICAgIGN0eC5maWxsUmVjdChwcm9wcy5zeCwgcHJvcHMuc3ksIHByb3BzLnNXaWR0aCwgcHJvcHMuc0hlaWdodCk7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdDYW52YXMnKSB7XHJcbiAgICAgIGlmICghcHJvcHMuaW1nKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgY3R4LmRyYXdJbWFnZShwcm9wcy5pbWcucmVuZGVyZXIuY2FudmFzLCBwcm9wcy5keCwgcHJvcHMuZHkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdDYW52YXNTaXplJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLnJlbmRlcmVyLmNhbnZhcywgcHJvcHMuZHgsIHByb3BzLmR5LCBwcm9wcy5kV2lkdGgsIHByb3BzLmRIZWlnaHQpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3Q2FudmFzU291cmNlJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLnJlbmRlcmVyLmNhbnZhcywgcHJvcHMuc3gsIHByb3BzLnN5LCBwcm9wcy5zV2lkdGgsIHByb3BzLnNIZWlnaHQsIHByb3BzLmR4LCBwcm9wcy5keSwgcHJvcHMuZFdpZHRoLCBwcm9wcy5kSGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlQXJjJykge1xyXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgIGN0eC5hcmMocHJvcHMueCwgcHJvcHMueSwgcHJvcHMuciwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUpO1xyXG4gICAgICBjdHguY2xvc2VQYXRoKCk7XHJcbiAgICAgIGN0eC5zdHJva2UoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlQXJjLWNvdW50ZXJjbG9ja3dpc2UnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgdHJ1ZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbEFyYycpIHtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICBjdHguYXJjKHByb3BzLngsIHByb3BzLnksIHByb3BzLnIsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlKTtcclxuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsQXJjLWNvdW50ZXJjbG9ja3dpc2UnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgdHJ1ZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LmZpbGwoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnbW92ZVRvJykge1xyXG4gICAgICBjdHgubW92ZVRvKHByb3BzLngsIHByb3BzLnkpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdsaW5lVG8nKSB7XHJcbiAgICAgIGN0eC5saW5lVG8ocHJvcHMueCwgcHJvcHMueSk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlemllckN1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHByb3BzLmNwMXgsIHByb3BzLmNwMXksIHByb3BzLmNwMngsIHByb3BzLmNwMnksIHByb3BzLngsIHByb3BzLnkpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdxdWFkcmF0aWNDdXJ2ZVRvJykge1xyXG4gICAgICBjdHgucXVhZHJhdGljQ3VydmVUbyhwcm9wcy5jcHgsIHByb3BzLmNweSwgcHJvcHMueCwgcHJvcHMueSk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FudGljbG9ja3dpc2UtYXJjJykge1xyXG4gICAgICBjdHguYXJjKHByb3BzLngsIHByb3BzLnksIHByb3BzLnIsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlLCB0cnVlKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnYXJjJykge1xyXG4gICAgICBjdHguYXJjKHByb3BzLngsIHByb3BzLnksIHByb3BzLnIsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmdWxsLWFyYycpIHtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCAwLCB0aGlzLnBpMik7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3F1aWNrLWFyYycpIHtcclxuICAgICAgY3R4LmFyYygwLCAwLCBwcm9wcy5yLCAwLCB0aGlzLnBpMik7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FyY1RvJykge1xyXG4gICAgICBjdHguYXJjVG8ocHJvcHMueDEsIHByb3BzLnkxLCBwcm9wcy54MiwgcHJvcHMueTIsIHByb3BzLnIpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdhbnRpY2xvY2t3aXNlLWVsbGlwc2UnKSB7XHJcbiAgICAgIHRoaXMuc2F2ZSgpO1xyXG4gICAgICB0aGlzLnRyYW5zbGF0ZShwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgdGhpcy5yb3RhdGUocHJvcHMucm90YXRpb24pO1xyXG4gICAgICB0aGlzLnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICB0aGlzLmFyYygwLCAwLCAxLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgdHJ1ZSk7XHJcbiAgICAgIHRoaXMucmVzdG9yZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbGxpcHNlJykge1xyXG4gICAgICB0aGlzLnNhdmUoKTtcclxuICAgICAgdGhpcy50cmFuc2xhdGUocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIHRoaXMucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgdGhpcy5zY2FsZShwcm9wcy5yYWRpdXNYLCBwcm9wcy5yYWRpdXNZKTtcclxuICAgICAgdGhpcy5hcmMoMCwgMCwgMSwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUpO1xyXG4gICAgICB0aGlzLnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZnVsbC1lbGxpcHNlJykge1xyXG4gICAgICB0aGlzLnNhdmUoKTtcclxuICAgICAgdGhpcy50cmFuc2xhdGUocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIHRoaXMucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgdGhpcy5zY2FsZShwcm9wcy5yYWRpdXNYLCBwcm9wcy5yYWRpdXNZKTtcclxuICAgICAgdGhpcy5hcmMoMCwgMCwgMSwgMCwgdGhpcy5waTIpO1xyXG4gICAgICB0aGlzLnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncXVpY2stZWxsaXBzZScpIHtcclxuICAgICAgdGhpcy5zYXZlKCk7XHJcbiAgICAgIHRoaXMudHJhbnNsYXRlKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICB0aGlzLnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICB0aGlzLmFyYygwLCAwLCAxLCAwLCB0aGlzLnBpMik7XHJcbiAgICAgIHRoaXMucmVzdG9yZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2sucHVzaChjdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uKTtcclxuICAgICAgY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9IHByb3BzLnZhbHVlO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSB0aGlzLmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsJykge1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2UnKSB7XHJcbiAgICAgIGN0eC5zdHJva2UoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnYmVnaW5DbGlwJykge1xyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsaXAnKSB7XHJcbiAgICAgIGN0eC5jbGlwKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZENsaXAnKSB7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlZ2luUGF0aCcpIHtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdjbG9zZVBhdGgnKSB7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZ2xvYmFsQWxwaGEnKSB7XHJcbiAgICAgIHRoaXMuZ2xvYmFsQWxwaGFTdGFjay5wdXNoKGN0eC5nbG9iYWxBbHBoYSk7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSAqPSBwcm9wcy52YWx1ZTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kR2xvYmFsQWxwaGEnKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IHRoaXMuZ2xvYmFsQWxwaGFTdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaGl0UmVnaW9uJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdO1xyXG4gICAgICBtYXRyaXhbMl0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdO1xyXG4gICAgICBtYXRyaXhbNV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG4gICAgICBjYWNoZSA9IHtcclxuICAgICAgICBpZDogcHJvcHMuaWQsXHJcbiAgICAgICAgcG9pbnRzOiB0cmFuc2Zvcm1Qb2ludHMocHJvcHMucG9pbnRzLCBtYXRyaXgpXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMubW91c2VSZWdpb25zLnB1c2goY2FjaGUpO1xyXG4gICAgICB0aGlzLnRvdWNoUmVnaW9ucy5wdXNoKGNhY2hlKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICB0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrLnB1c2goY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCk7XHJcbiAgICAgIGN0eC5pbWFnZVNtb290aGluZ0VuYWJsZWQgPSBwcm9wcy52YWx1ZTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kSW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gdGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5hcHBseVN0eWxlcygpO1xyXG59O1xyXG5cclxuUmVuZGVyZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHdpZHRoLCBoZWlnaHQsIHBhcmVudCwgd29ya2VyKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XHJcbiAgICByZXR1cm4gbmV3IFJlbmRlcmVyKHdpZHRoLCBoZWlnaHQsIHBhcmVudCwgd29ya2VyKTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcclxuICAgIHJldHVybiBuZXcgUmVuZGVyZXIod2lkdGgsIGhlaWdodCk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgUmVuZGVyZXIoKTtcclxufTtcclxuXHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCkge1xyXG4gIC8vb25seSByZXNpemUgaWYgdGhlIHNpemVzIGFyZSBkaWZmZXJlbnQsIGJlY2F1c2UgaXQgY2xlYXJzIHRoZSBjYW52YXNcclxuICBpZiAodGhpcy5jYW52YXMud2lkdGgudG9TdHJpbmcoKSAhPT0gd2lkdGgudG9TdHJpbmcoKSkge1xyXG4gICAgdGhpcy5jYW52YXMud2lkdGggPSB3aWR0aDtcclxuICAgIGlmICh0aGlzLnBhcmVudCAhPT0gZG9jdW1lbnQuYm9keSkge1xyXG4gICAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgXCJweFwiO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAodGhpcy5jYW52YXMuaGVpZ2h0LnRvU3RyaW5nKCkgIT09IGhlaWdodC50b1N0cmluZygpKSB7XHJcbiAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XHJcbiAgICBpZiAodGhpcy5wYXJlbnQgIT09IGRvY3VtZW50LmJvZHkpIHtcclxuICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS50b0ltYWdlID0gZnVuY3Rpb24gdG9JbWFnZSgpIHtcclxuICB2YXIgSW1nID0gcmVxdWlyZSgnLi9JbWcnKTtcclxuICB2YXIgaW1nID0gbmV3IEltZygpO1xyXG4gIGltZy5zcmMgPSB0aGlzLmNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xyXG4gIHJldHVybiBpbWc7XHJcbn07XHJcblxyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLmhvb2tSZW5kZXIgPSBmdW5jdGlvbiBob29rUmVuZGVyKCkge1xyXG5cclxuICAvL0lmIHRoZSBjbGllbnQgaGFzIHNlbnQgYSAncmVhZHknIGNvbW1hbmQgYW5kIGEgdHJlZSBleGlzdHNcclxuICBpZiAodGhpcy5pc1JlYWR5KSB7XHJcbiAgICAvL2ZpcmUgdGhlIG1vdXNlIGV2ZW50IGFnYWluIGlmIGl0IHdhc24ndCBydW5cclxuICAgIGlmICh0aGlzLmxhc3RNb3VzZUV2ZW50ICYmICF0aGlzLnJhbk1vdXNlRXZlbnQpIHtcclxuICAgICAgdGhpcy5tb3VzZU1vdmUodGhpcy5sYXN0TW91c2VFdmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMubGFzdFRvdWNoRXZlbnQgJiYgIXRoaXMucmFuVG91Y2hFdmVudCkge1xyXG4gICAgICB0aGlzLnRvdWNoRXZlbnQodGhpcy5sYXN0TW91c2VFdmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maXJlRnJhbWUoKTtcclxuXHJcbiAgfVxyXG5cclxuICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmJvdW5kSG9va1JlbmRlckZ1bmN0aW9uKTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5ob29rTW91c2VFdmVudHMgPSBmdW5jdGlvbiBob29rTW91c2VFdmVudHMoKSB7XHJcbiAgLy93aGVuZXZlciB0aGUgbW91c2UgbW92ZXMsIHJlcG9ydCB0aGUgcG9zaXRpb25cclxuICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5tb3VzZU1vdmUuYmluZCh0aGlzKSk7XHJcblxyXG4gIC8vb25seSByZXBvcnQgbW91c2Vkb3duIG9uIGNhbnZhc1xyXG4gIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMubW91c2VEb3duLmJpbmQodGhpcykpO1xyXG5cclxuICAvL21vdXNlIHVwIGNhbiBoYXBwZW4gYW55d2hlcmVcclxuICByZXR1cm4gd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm1vdXNlVXAuYmluZCh0aGlzKSk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUuaG9va1RvdWNoRXZlbnRzID0gZnVuY3Rpb24gaG9va1RvdWNoRXZlbnRzKCkge1xyXG5cclxuICByZXR1cm4gWyd0b3VjaHN0YXJ0JywgJ3RvdWNobW92ZScsICd0b3VjaGVuZCcsICd0b3VjaGNhbmNlbCddLmZvckVhY2goZnVuY3Rpb24oZXZ0KSB7XHJcbiAgICByZXR1cm4gd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZ0LCB0aGlzLnRvdWNoRXZlbnQuYmluZCh0aGlzKSk7XHJcbiAgfSwgdGhpcyk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUudG91Y2hFdmVudCA9IGZ1bmN0aW9uIHRvdWNoRXZlbnQoZXZ0KSB7XHJcbiAgdmFyIHJlY3QgPSB0aGlzLmNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcclxuICAgICAgdG91Y2hSZWdpb25zID0gdGhpcy50b3VjaFJlZ2lvbnMuc2xpY2UoKSxcclxuICAgICAgbW91c2VQb2ludCA9IFswLDBdLFxyXG4gICAgICByZWdpb247XHJcblxyXG4gIHZhciBwcmV2aW91c0lkcyA9IHRoaXMudG91Y2hEYXRhLmlkcy5zcGxpY2UoMCwgdGhpcy50b3VjaERhdGEuaWRzLmxlbmd0aCksXHJcbiAgICBwcmV2aW91c1RvdWNoZXMgPSB0aGlzLnRvdWNoRGF0YS50b3VjaGVzLnNwbGljZSgwLCB0aGlzLnRvdWNoRGF0YS50b3VjaGVzLmxlbmd0aCksXHJcbiAgICB0b3VjaFBvaW50O1xyXG5cclxuICBmb3IodmFyIGkgPSAwOyBpIDwgZXZ0LnRvdWNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgIHZhciB0b3VjaCA9IGV2dC50b3VjaGVzLml0ZW0oaSk7XHJcbiAgICB2YXIgaW5kZXggPSBwcmV2aW91c0lkcy5pbmRleE9mKHRvdWNoLmlkZW50aWZpZXIpO1xyXG5cclxuICAgIHRvdWNoUG9pbnQgPSBpbmRleCA9PT0gLTEgPyB7IHg6IDAsIHk6IDAsIGFjdGl2ZVJlZ2lvbnM6IFtdLCBpZDogdG91Y2guaWRlbnRpZmllciwgdG91Y2hlZDogdHJ1ZSwgaGVsZDogZmFsc2UgfSA6IHByZXZpb3VzVG91Y2hlc1tpbmRleF07XHJcbiAgICB0b3VjaFBvaW50LnRvdWNoZWQgPSBpbmRleCA9PT0gLTE7XHJcbiAgICB0b3VjaFBvaW50LmhlbGQgPSAhdG91Y2hQb2ludC50b3VjaGVkO1xyXG5cclxuICAgIHRvdWNoUG9pbnQueCA9IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQ7XHJcbiAgICB0b3VjaFBvaW50LnkgPSB0b3VjaC5jbGllbnRZIC0gcmVjdC50b3A7XHJcbiAgICB0aGlzLnRvdWNoRGF0YS50b3VjaGVzLnB1c2godG91Y2hQb2ludCk7XHJcbiAgICB0aGlzLnRvdWNoRGF0YS5pZHMucHVzaCh0b3VjaFBvaW50LmlkZW50aWZpZXIpO1xyXG5cclxuICAgIG1vdXNlUG9pbnRbMF0gPSB0b3VjaFBvaW50Lng7XHJcbiAgICBtb3VzZVBvaW50WzFdID0gdG91Y2hQb2ludC55O1xyXG5cclxuICAgIHRvdWNoUG9pbnQuYWN0aXZlUmVnaW9ucy5zcGxpY2UoMCwgdG91Y2hQb2ludC5hY3RpdmVSZWdpb25zLmxlbmd0aCk7XHJcblxyXG4gICAgZm9yKHZhciBqID0gMDsgaiA8IHRoaXMubW91c2VSZWdpb25zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHJlZ2lvbiA9IHRvdWNoUmVnaW9uc1tqXTtcclxuICAgICAgaWYgKHBvaW50SW5Qb2x5Z29uKG1vdXNlUG9pbnQsIHJlZ2lvbi5wb2ludHMpKSB7XHJcbiAgICAgICAgdG91Y2hQb2ludC5hY3RpdmVSZWdpb25zLnB1c2gocmVnaW9uLmlkKTtcclxuICAgICAgICB0b3VjaFJlZ2lvbnMuc3BsaWNlKHRvdWNoUmVnaW9ucy5pbmRleE9mKHJlZ2lvbiksIDEpO1xyXG4gICAgICAgIGogLT0gMTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIHRoaXMubGFzdFRvdWNoRXZlbnQgPSBldnQ7XHJcbiAgdGhpcy5yYW5Ub3VjaEV2ZW50ID0gdHJ1ZTtcclxuXHJcblxyXG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIHRoaXMuZW1pdCgndG91Y2gnLCB0aGlzLnRvdWNoRGF0YSk7XHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLm1vdXNlTW92ZSA9IGZ1bmN0aW9uIG1vdXNlTW92ZShldnQpIHtcclxuICAvL2dldCBib3VuZGluZyByZWN0YW5nbGVcclxuICB2YXIgcmVjdCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxyXG4gICAgICBtb3VzZVBvaW50ID0gWzAsMF0sXHJcbiAgICAgIHJlZ2lvbjtcclxuICB0aGlzLmxhc3RNb3VzZUV2ZW50ID0gZXZ0O1xyXG4gIHRoaXMucmFuTW91c2VFdmVudCA9IHRydWU7XHJcblxyXG4gIG1vdXNlUG9pbnRbMF0gPSBldnQuY2xpZW50WCAtIHJlY3QubGVmdDtcclxuICBtb3VzZVBvaW50WzFdID0gZXZ0LmNsaWVudFkgLSByZWN0LnRvcDtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMubW91c2VSZWdpb25zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZWdpb24gPSB0aGlzLm1vdXNlUmVnaW9uc1tpXTtcclxuICAgIGlmIChwb2ludEluUG9seWdvbihtb3VzZVBvaW50LCByZWdpb24ucG9pbnRzKSkge1xyXG4gICAgICB0aGlzLmFjdGl2ZVJlZ2lvbnMucHVzaChyZWdpb24uaWQpO1xyXG4gICAgICB0aGlzLm1vdXNlUmVnaW9ucy5zcGxpY2UodGhpcy5tb3VzZVJlZ2lvbnMuaW5kZXhPZihyZWdpb24pLCAxKTtcclxuICAgICAgaSAtPSAxO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdGhpcy5tb3VzZURhdGEueCA9IG1vdXNlUG9pbnRbMF07XHJcbiAgdGhpcy5tb3VzZURhdGEueSA9IG1vdXNlUG9pbnRbMV07XHJcblxyXG4gIC8vbmV3IHN0YXRlIGlzIGRvd24sIGxhc3Qgc3RhdGUgaXMgdXBcclxuXHJcbiAgdGhpcy5tb3VzZURhdGEuY2xpY2tlZCA9IHRoaXMubW91c2VTdGF0ZSA9PT0gJ2Rvd24nICYmIHRoaXMubW91c2VEYXRhLnN0YXRlID09PSAndXAnO1xyXG5cclxuICB0aGlzLm1vdXNlRGF0YS5zdGF0ZSA9IHRoaXMubW91c2VTdGF0ZTtcclxuICB0aGlzLm1vdXNlRGF0YS5hY3RpdmVSZWdpb25zID0gdGhpcy5hY3RpdmVSZWdpb25zO1xyXG5cclxuICB0aGlzLmVtaXQoJ21vdXNlJywgdGhpcy5tb3VzZURhdGEpO1xyXG4gIC8vZGVmYXVsdCBldmVudCBzdHVmZlxyXG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIHJldHVybiBmYWxzZTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5tb3VzZURvd24gPSBmdW5jdGlvbiBtb3VzZU1vdmUoZXZ0KSB7XHJcbiAgLy9zZXQgdGhlIG1vdXNlU3RhdGUgZG93blxyXG4gIHRoaXMubW91c2VTdGF0ZSA9ICdkb3duJztcclxuICB0aGlzLmNhbnZhcy5mb2N1cygpO1xyXG4gIC8vZGVmZXIgdG8gbW91c2VNb3ZlXHJcbiAgcmV0dXJuIHRoaXMubW91c2VNb3ZlKGV2dCk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUubW91c2VVcCA9IGZ1bmN0aW9uIG1vdXNlTW92ZShldnQpIHtcclxuICAvL3NldCB0aGUgbW91c2Ugc3RhdGVcclxuICB0aGlzLm1vdXNlU3RhdGUgPSAndXAnO1xyXG4gIC8vZGVmZXIgdG8gbW91c2UgbW92ZVxyXG4gIHJldHVybiB0aGlzLm1vdXNlTW92ZShldnQpO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLmhvb2tLZXlib2FyZEV2ZW50cyA9IGZ1bmN0aW9uIGhvb2tLZXlib2FyZEV2ZW50cygpIHtcclxuXHJcbiAgLy9ldmVyeSBjb2RlIGluIGtleWNvZGUuY29kZSBuZWVkcyB0byBiZSBvbiBrZXlEYXRhXHJcbiAgZm9yICh2YXIgbmFtZSBpbiBrZXljb2RlLmNvZGUpIHtcclxuICAgIGlmIChrZXljb2RlLmNvZGUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcclxuICAgICAgdGhpcy5rZXlEYXRhW25hbWVdID0gXCJ1cFwiO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy9rZXlkb3duIHNob3VsZCBvbmx5IGhhcHBlbiBPTiB0aGUgY2FudmFzXHJcbiAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMua2V5RG93bi5iaW5kKHRoaXMpKTtcclxuXHJcbiAgLy9idXQga2V5dXAgc2hvdWxkIGJlIGNhcHR1cmVkIGV2ZXJ5d2hlcmVcclxuICByZXR1cm4gd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5rZXlVcC5iaW5kKHRoaXMpKTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5rZXlDaGFuZ2UgPSBmdW5jdGlvbiBrZXlDaGFuZ2UoZXZ0KSB7XHJcbiAgdGhpcy5lbWl0KCdrZXknLCB0aGlzLmtleURhdGEpO1xyXG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIHJldHVybiBmYWxzZTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5rZXlEb3duID0gZnVuY3Rpb24ga2V5RG93bihldnQpIHtcclxuICB0aGlzLmtleURhdGFba2V5Y29kZShldnQua2V5Q29kZSldID0gXCJkb3duXCI7XHJcbiAgcmV0dXJuIHRoaXMua2V5Q2hhbmdlKGV2dCk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUua2V5VXAgPSBmdW5jdGlvbiBrZXlVcChldnQpIHtcclxuICB0aGlzLmtleURhdGFba2V5Y29kZShldnQua2V5Q29kZSldID0gXCJ1cFwiO1xyXG4gIHJldHVybiB0aGlzLmtleUNoYW5nZShldnQpO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLmZpcmVGcmFtZSA9IGZ1bmN0aW9uKCkge1xyXG4gIHRoaXMubW91c2VSZWdpb25zLnNwbGljZSgwLCB0aGlzLm1vdXNlUmVnaW9ucy5sZW5ndGgpO1xyXG4gIHRoaXMudG91Y2hSZWdpb25zLnNwbGljZSgwLCB0aGlzLnRvdWNoUmVnaW9ucy5sZW5ndGgpO1xyXG5cclxuICB0aGlzLmVtaXQoJ2ZyYW1lJywge30pO1xyXG4gIHRoaXMuYWN0aXZlUmVnaW9ucy5zcGxpY2UoMCwgdGhpcy5hY3RpdmVSZWdpb25zLmxlbmd0aCk7XHJcbiAgdGhpcy5yYW5Nb3VzZUV2ZW50ID0gZmFsc2U7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUuc3R5bGUgPSBmdW5jdGlvbiBzdHlsZSgpIHtcclxuICB2YXIgY2hpbGRyZW4gPSBbXSxcclxuICAgICAgc3R5bGVzID0gW10sXHJcbiAgICAgIGNvbmNhdCA9IGNoaWxkcmVuLmNvbmNhdCxcclxuICAgICAgbGVuLFxyXG4gICAgICBpLFxyXG4gICAgICBjaGlsZCxcclxuICAgICAgbmFtZTtcclxuICBmb3IoaSA9IDAsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY2hpbGRyZW4ucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuXHJcbiAgZm9yIChpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcbiAgICBpZiAoY2hpbGQgJiYgY2hpbGQuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XHJcbiAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcbiAgICAgIHdoaWxlKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG4gICAgICBsZW4gPSBjaGlsZHJlbi5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICBpZiAoY2hpbGQpIHtcclxuICAgICAgc3R5bGVzLnB1c2goY2hpbGQpO1xyXG4gICAgfVxyXG4gIH1cclxuICBmb3IgKGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB0aGlzLnN0eWxlUXVldWUucHVzaChzdHlsZXNbaV0pO1xyXG4gIH1cclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5hcHBseVN0eWxlcyA9IGZ1bmN0aW9uIGFwcGx5U3R5bGVzKCkge1xyXG4gIHZhciBzdHlsZVZhbCwgdmFsdWU7XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuc3R5bGVRdWV1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgc3R5bGVWYWwgPSB0aGlzLnN0eWxlUXVldWVbaV07XHJcbiAgICBmb3IodmFyIG5hbWUgaW4gc3R5bGVWYWwpIHtcclxuICAgICAgaWYgKHN0eWxlVmFsLmhhc093blByb3BlcnR5KG5hbWUpKSB7XHJcbiAgICAgICAgdGhpcy5jYW52YXMuc3R5bGVbbmFtZV0gPSBzdHlsZVZhbFtuYW1lXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICB0aGlzLnN0eWxlUXVldWUuc3BsaWNlKDAsIHRoaXMuc3R5bGVRdWV1ZS5sZW5ndGgpO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLnJlYWR5ID0gZnVuY3Rpb24gcmVhZHkoKSB7XHJcbiAgdGhpcy5pc1JlYWR5ID0gdHJ1ZTtcclxuICB0aGlzLmZpcmVGcmFtZSgpO1xyXG4gIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuaG9va1JlbmRlci5iaW5kKHRoaXMpKTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5tZWFzdXJlVGV4dCA9IGZ1bmN0aW9uIG1lYXN1cmVUZXh0KGZvbnQsIHRleHQpIHtcclxuICB2YXIgb2xkRm9udCA9IHRoaXMuY3R4LmZvbnQsXHJcbiAgICAgIHJlc3VsdDtcclxuXHJcbiAgdGhpcy5jdHguZm9udCA9IGZvbnQ7XHJcbiAgcmVzdWx0ID0gdGhpcy5jdHgubWVhc3VyZVRleHQodGV4dCk7XHJcbiAgdGhpcy5jdHguZm9udCA9IG9sZEZvbnQ7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSA9IGZ1bmN0aW9uIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCkge1xyXG4gIHZhciBjYWNoZSA9IHRoaXMudHJhbnNmb3JtU3RhY2s7XHJcbiAgdGhpcy50cmFuc2Zvcm1TdGFjayA9IG5ldyBGbG9hdDY0QXJyYXkodGhpcy50cmFuc2Zvcm1TdGFjay5sZW5ndGggKyA2MDApOyAvL2FkZCAxMDAgbW9yZVxyXG4gIHRoaXMudHJhbnNmb3JtU3RhY2suc2V0KGNhY2hlKTtcclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZW5kZXJlci5wcm90b3R5cGUsICdoZWlnaHQnLCB7XHJcbiAgZ2V0OiBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLmNhbnZhcy53aWR0aDtcclxuICB9LFxyXG4gIGVudW1lcmFibGU6IHRydWUsXHJcbiAgY29uZmlndXJhYmxlOiBmYWxzZVxyXG59KTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlbmRlcmVyLnByb3RvdHlwZSwgJ3dpZHRoJywge1xyXG4gIGdldDogZnVuY3Rpb24oKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jYW52YXMud2lkdGg7XHJcbiAgfSxcclxuICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gIGNvbmZpZ3VyYWJsZTogZmFsc2VcclxufSk7XHJcbk9iamVjdC5zZWFsKFJlbmRlcmVyKTtcclxuT2JqZWN0LnNlYWwoUmVuZGVyZXIucHJvdG90eXBlKTtcclxubW9kdWxlLmV4cG9ydHMgPSBSZW5kZXJlcjtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG5cclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBhZGRDb2xvclN0b3Aob2Zmc2V0LCBjb2xvcikge1xyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2FkZENvbG9yU3RvcCcsIHsgb2Zmc2V0OiBvZmZzZXQsIGNvbG9yOiBjb2xvciB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhZGRDb2xvclN0b3A7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGFyYyh4LCB5LCByLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW50aWNsb2Nrd2lzZSkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihhbnRpY2xvY2t3aXNlID8gJ2FudGljbG9ja3dpc2UtYXJjJyA6ICdhcmMnLCB7IHg6IHgsIHk6IHksIHI6IHIsIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlOiBlbmRBbmdsZSB9KTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2FyYycsIHsgeDogeCwgeTogeSwgcjogciwgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH0pO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmdWxsLWFyYycsIHsgeDogeCwgeTogeSwgcjogcn0pO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAxKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdxdWljay1hcmMnLCB7IHI6IHggfSk7XHJcbiAgfVxyXG4gIFxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1aWNrLWFyYycsIHsgcjogMSB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmM7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGFyY1RvKHgxLCB5MSwgeDIsIHkyLCByKSB7XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignYXJjVG8nLCB7IHgxOiB4MSwgeTE6IHkxLCB4MjogeDIsIHkyOiB5MiwgcjogciB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmNUbztcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGJlZ2luUGF0aCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdiZWdpblBhdGgnKTtcclxufVxyXG5tb2R1bGUuZXhwb3J0cyA9IGJlZ2luUGF0aDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gYmV6aWVyQ3VydmVUbyhjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KSB7XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignYmV6aWVyQ3VydmVUbycsIHtcclxuICAgIGNwMXg6IGNwMXgsIFxyXG4gICAgY3AxeTogY3AxeSwgXHJcbiAgICBjcDJ4OiBjcDJ4LCBcclxuICAgIGNwMnk6IGNwMnksIFxyXG4gICAgeDogeCwgXHJcbiAgICB5OiB5XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYmV6aWVyQ3VydmVUbzsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbFJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImNsZWFyUmVjdFwiLCB7IHg6IHgsIHk6IHksIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJjbGVhclJlY3RcIiwgeyB4OiAwLCB5OiAwLCB3aWR0aDogeCwgaGVpZ2h0OiB5IH0pO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGNsaXAocGF0aCwgY2hpbGRyZW4pIHtcclxuICB2YXIgcmVzdWx0ID0gW25ldyBJbnN0cnVjdGlvbignYmVnaW5DbGlwJyksIHBhdGgsIG5ldyBJbnN0cnVjdGlvbignY2xpcCcpXTtcclxuXHJcbiAgZm9yKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcblxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kQ2xpcCcpKTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsaXA7XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBjbGlwUGF0aCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdjbGlwUGF0aCcpO1xyXG59XHJcbm1vZHVsZS5leHBvcnRzID0gY2xpcFBhdGg7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGNsb3NlUGF0aCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdjbG9zZVBhdGgnKTtcclxufVxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsb3NlUGF0aDsiLCIndXNlIHN0cmljdCc7XHJcbnZhciBjb25jYXQgPSBbXS5jb25jYXQ7XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVDbGFzcygpIHtcclxuICB2YXIgYXJncyA9IFtdLCBpO1xyXG4gIGZvcihpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG5cclxuICBmb3IoaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB3aGlsZSAoYXJnc1tpXSAmJiBhcmdzW2ldLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICBhcmdzID0gY29uY2F0LmFwcGx5KFtdLCBhcmdzKTtcclxuICAgIH1cclxuICAgIGlmIChhcmdzW2ldICYmIGFyZ3NbaV0udHlwZSA9PT0gJ3BsYWNlaG9sZGVyJykge1xyXG4gICAgICAgLy8gcmVtb3ZlIHRoZSBwbGFjZWhvbGRlclxyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIChmdW5jdGlvbigpIHtcclxuICAgIHZhciBzdGFydCA9IGFyZ3MsIGVuZCA9IHN0YXJ0LnNwbGljZShpICsgMSwgYXJncy5sZW5ndGgpO1xyXG4gICAgc3RhcnQucG9wKCk7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlZENsYXNzKCkge1xyXG4gICAgICB2YXIgY2hpbGRyZW4gPSBbXSwgaTtcclxuICAgICAgZm9yKGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY2hpbGRyZW4ucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBbXHJcbiAgICAgICAgc3RhcnQsIGNoaWxkcmVuLCBlbmRcclxuICAgICAgXTtcclxuICAgIH07XHJcbiAgfSgpKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVDbGFzcztcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZSwgYnJvd3NlcjogdHJ1ZSwgd29ya2VyOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUxpbmVhckdyYWRpZW50KHgwLCB5MCwgeDEsIHkxLCBjaGlsZHJlbikge1xyXG4gIHZhciBjdHggPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKSxcclxuICAgIGdyZCA9IGN0eC5jcmVhdGVMaW5lYXJHcmFkaWVudCh4MCwgeTAsIHgxLCB5MSk7XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgY29sb3JTdG9wID0gY2hpbGRyZW5baV07XHJcbiAgICBncmQuYWRkQ29sb3JTdG9wKGNvbG9yU3RvcC5wcm9wcy5vZmZzZXQsIGNvbG9yU3RvcC5wcm9wcy5jb2xvcik7XHJcbiAgfVxyXG4gIHJldHVybiBncmQ7XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUxpbmVhckdyYWRpZW50O1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlLCBicm93c2VyOiB0cnVlLCB3b3JrZXI6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gY3JlYXRlUmFkaWFsR3JhZGllbnQoeDAsIHkwLCByMCwgeDEsIHkxLCByMSwgY2hpbGRyZW4pIHtcclxuICB2YXIgY3R4ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyksXHJcbiAgICBncmQgPSBjdHguY3JlYXRlUmFkaWFsR3JhZGllbnQoeDAsIHkwLCByMCwgeDEsIHkxLCByMSk7XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgY29sb3JTdG9wID0gY2hpbGRyZW5baV07XHJcbiAgICBncmQuYWRkQ29sb3JTdG9wKGNvbG9yU3RvcC5wcm9wcy5vZmZzZXQsIGNvbG9yU3RvcC5wcm9wcy5jb2xvcik7XHJcbiAgfVxyXG4gIHJldHVybiBncmQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUmFkaWFsR3JhZGllbnQ7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVJlZ3VsYXJQb2x5Z29uKHJhZGl1cywgcG9zaXRpb24sIHNpZGVzKSB7XHJcbiAgcmFkaXVzID0gK3JhZGl1cyB8fCAxO1xyXG4gIHBvc2l0aW9uWzBdID0gK3Bvc2l0aW9uWzBdIHx8IDA7XHJcbiAgcG9zaXRpb25bMV0gPSArcG9zaXRpb25bMV0gfHwgMDtcclxuICBzaWRlcyA9ICtzaWRlcyB8fCAzO1xyXG4gIHZhciBwb2x5Z29uID0gW107XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHNpZGVzOyBpKyspIHtcclxuICAgIHBvbHlnb24ucHVzaChbXHJcbiAgICAgIHBvc2l0aW9uWzBdICsgcmFkaXVzICogTWF0aC5jb3MoTWF0aC5QSSAqIDIgKiBpIC8gc2lkZXMpLFxyXG4gICAgICBwb3NpdGlvblsxXSArIHJhZGl1cyAqIE1hdGguc2luKE1hdGguUEkgKiAyICogaSAvIHNpZGVzKVxyXG4gICAgXSk7XHJcbiAgfVxyXG4gIHJldHVybiBwb2x5Z29uO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlZ3VsYXJQb2x5Z29uO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZHJhd0NhbnZhcyhjYW52YXMsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA5KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdkcmF3Q2FudmFzU291cmNlJywge1xyXG4gICAgICBpbWc6IGNhbnZhcyxcclxuICAgICAgc3g6IHN4LFxyXG4gICAgICBzeTogc3ksXHJcbiAgICAgIHNXaWR0aDogc1dpZHRoLFxyXG4gICAgICBzSGVpZ2h0OiBzSGVpZ2h0LFxyXG4gICAgICBkeDogZHgsXHJcbiAgICAgIGR5OiBkeSxcclxuICAgICAgZFdpZHRoOiBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0NhbnZhc1NpemUnLCB7XHJcbiAgICAgIGltZzogY2FudmFzLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeSxcclxuICAgICAgZFdpZHRoOiBzV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IHNIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0NhbnZhcycsIHtcclxuICAgICAgaW1nOiBjYW52YXMsXHJcbiAgICAgIGR4OiBzeCxcclxuICAgICAgZHk6IHN5XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdDYW52YXMnLCB7XHJcbiAgICBpbWc6IGNhbnZhcyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmF3Q2FudmFzO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZHJhd0ltYWdlKGltZywgc3gsIHN5LCBzV2lkdGgsIHNIZWlnaHQsIGR4LCBkeSwgZFdpZHRoLCBkSGVpZ2h0KSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDkpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNvdXJjZScsIHtcclxuICAgICAgaW1nOiBpbWcsXHJcbiAgICAgIHN4OiBzeCxcclxuICAgICAgc3k6IHN5LFxyXG4gICAgICBzV2lkdGg6IHNXaWR0aCxcclxuICAgICAgc0hlaWdodDogc0hlaWdodCxcclxuICAgICAgZHg6IGR4LFxyXG4gICAgICBkeTogZHksXHJcbiAgICAgIGRXaWR0aDogZFdpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBkSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNpemUnLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeSxcclxuICAgICAgZFdpZHRoOiBzV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IHNIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3lcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgaW1nOiBpbWcsXHJcbiAgICBkeDogMCxcclxuICAgIGR5OiAwXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZHJhd0ltYWdlO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZWxsaXBzZSh4LCB5LCByYWRpdXNYLCByYWRpdXNZLCByb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFudGljbG9ja3dpc2UpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDcpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oYW50aWNsb2Nrd2lzZSA/ICdhbnRpY2xvY2t3aXNlLWVsbGlwc2UnIDogJ2VsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1ksIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlOiBlbmRBbmdsZSB9KTtcclxuICB9XHJcbiAgXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDcpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2VsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1ksIHJvdGF0aW9uOiByb3RhdGlvbiwgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH0pO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA1KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmdWxsLWVsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1ksIHJvdGF0aW9uOiByb3RhdGlvbiB9KTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1aWNrLWVsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1kgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1aWNrLWVsbGlwc2UnLCB7IHg6IDAsIHk6IDAsIHJhZGl1c1g6IHgsIHJhZGl1c1k6IHkgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZWxsaXBzZTsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsJyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5mdW5jdGlvbiBmaWxsQXJjKHgsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNiAmJiBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbEFyYy1jb3VudGVyY2xvY2t3aXNlXCIsIHsgeDogeCwgeTogeSwgcjogciwgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH0pO1xyXG4gICAgXHJcbiAgfVxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImZpbGxBcmNcIiwgeyB4OiB4LCB5OiB5LCByOiByLCBzdGFydEFuZ2xlOiBzdGFydEFuZ2xlLCBlbmRBbmdsZTogZW5kQW5nbGUgfSk7XHJcbiAgfSBcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpe1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImZpbGxBcmNcIiwgeyB4OiB4LCB5OiB5LCByOiByLCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyIH0pO1xyXG4gIH1cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbEFyY1wiLCAgeyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxBcmM7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGZpbGxJbWFnZShpbWcsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA5KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsQ2FudmFzU291cmNlJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgc3g6IHN4LFxyXG4gICAgICBzeTogc3ksXHJcbiAgICAgIHNXaWR0aDogc1dpZHRoLFxyXG4gICAgICBzSGVpZ2h0OiBzSGVpZ2h0LFxyXG4gICAgICBkeDogZHgsXHJcbiAgICAgIGR5OiBkeSxcclxuICAgICAgZFdpZHRoOiBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbENhbnZhc1NpemUnLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeSxcclxuICAgICAgZFdpZHRoOiBzV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IHNIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbENhbnZhcycsIHtcclxuICAgICAgaW1nOiBpbWcsXHJcbiAgICAgIGR4OiBzeCxcclxuICAgICAgZHk6IHN5XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxDYW52YXMnLCB7XHJcbiAgICBpbWc6IGltZyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsSW1hZ2U7XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBmaWxsSW1hZ2UoaW1nLCBzeCwgc3ksIHNXaWR0aCwgc0hlaWdodCwgZHgsIGR5LCBkV2lkdGgsIGRIZWlnaHQpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gOSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbEltYWdlU291cmNlJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgc3g6IHN4LFxyXG4gICAgICBzeTogc3ksXHJcbiAgICAgIHNXaWR0aDogc1dpZHRoLFxyXG4gICAgICBzSGVpZ2h0OiBzSGVpZ2h0LFxyXG4gICAgICBkeDogZHgsXHJcbiAgICAgIGR5OiBkeSxcclxuICAgICAgZFdpZHRoOiBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbEltYWdlU2l6ZScsIHtcclxuICAgICAgaW1nOiBpbWcsXHJcbiAgICAgIGR4OiBzeCxcclxuICAgICAgZHk6IHN5LFxyXG4gICAgICBkV2lkdGg6IHNXaWR0aCxcclxuICAgICAgZEhlaWdodDogc0hlaWdodFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsSW1hZ2UnLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsSW1hZ2UnLCB7XHJcbiAgICBpbWc6IGltZyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsSW1hZ2U7XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBmaWxsSW1hZ2VQYXR0ZXJuKGltZywgZHgsIGR5LCBkV2lkdGgsIGRIZWlnaHQpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA1KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsSW1hZ2VQYXR0ZXJuJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgZHg6IGR4LFxyXG4gICAgICBkeTogZHksXHJcbiAgICAgIGRXaWR0aDogZFdpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBkSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxJbWFnZVBhdHRlcm4nLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogMCxcclxuICAgICAgZHk6IDAsXHJcbiAgICAgIGRXaWR0aDogZHgsXHJcbiAgICAgIGRIZWlnaHQ6IGR5XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxJbWFnZVBhdHRlcm4nLCB7XHJcbiAgICBpbWc6IGltZyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDAsXHJcbiAgICBkV2lkdGg6IDAsXHJcbiAgICBkSGVpZ2h0OiAwXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbEltYWdlUGF0dGVybjtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGZpbGxSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbFJlY3RcIiwgeyB4OiB4LCB5OiB5LCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0IH0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbFJlY3RcIiwgeyB4OiAwLCB5OiAwLCB3aWR0aDogeCwgaGVpZ2h0OiB5IH0pO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbFN0eWxlKHZhbHVlLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdmaWxsU3R5bGUnLCB7IHZhbHVlOiB2YWx1ZSB9KV07XHJcblxyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHJlc3VsdC5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kRmlsbFN0eWxlJykpO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbFN0eWxlO1xyXG4iLCJ2YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZpbGxUZXh0KHRleHQsIHgsIHksIG1heFdpZHRoKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCA0KSB7XHJcbiAgICBtYXhXaWR0aCA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbFRleHQnLCB7XHJcbiAgICB0ZXh0OiB0ZXh0LFxyXG4gICAgeDogeCxcclxuICAgIHk6IHksXHJcbiAgICBtYXhXaWR0aDogbWF4V2lkdGhcclxuICB9KTtcclxufTtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGdsb2JhbEFscGhhKGFscGhhLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdnbG9iYWxBbHBoYScsIHsgdmFsdWU6IGFscGhhIH0pXTtcclxuICBmb3IodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICByZXN1bHQucHVzaChuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEdsb2JhbEFscGhhJykpO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZ2xvYmFsQWxwaGE7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbihvcGVyYXRpb25UeXBlLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nLCB7IHZhbHVlOiBvcGVyYXRpb25UeXBlIH0pXTtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuICBcclxuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmVzdWx0LnB1c2gobmV3IEluc3RydWN0aW9uKCdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnbG9iYWxDb21wb3NpdGVPcGVyYXRpb247IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKSxcclxuICAgIGhpdFJlZ2lvbiA9IHJlcXVpcmUoJy4vaGl0UmVnaW9uJyk7XHJcblxyXG5cclxuZnVuY3Rpb24gaGl0UmVjdChpZCwgeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDw9IDMpIHtcclxuICAgIHdpZHRoID0geDtcclxuICAgIGhlaWdodCA9IHk7XHJcbiAgICB4ID0gMDtcclxuICAgIHkgPSAwO1xyXG4gIH1cclxuICBcclxuICB2YXIgcG9pbnRzID0gW1xyXG4gICAgW3gsIHldLFxyXG4gICAgW3gsIHkgKyBoZWlnaHRdLFxyXG4gICAgW3ggKyB3aWR0aCwgeSArIGhlaWdodF0sXHJcbiAgICBbeCArIHdpZHRoLCB5XVxyXG4gIF07XHJcbiAgXHJcbiAgcmV0dXJuIGhpdFJlZ2lvbihpZCwgcG9pbnRzKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBoaXRSZWN0OyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5cclxuZnVuY3Rpb24gaGl0UmVnaW9uKGlkLCBwb2ludHMpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdoaXRSZWdpb24nLCB7XHJcbiAgICBpZDogaWQsXHJcbiAgICBwb2ludHM6IHBvaW50c1xyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGhpdFJlZ2lvbjsiLCIndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW1hZ2VTbW9vdGhpbmdFbmFibGVkKHZhbCwgY2hpbGRyZW4pIHtcclxuICBjaGlsZHJlbiA9IFtdO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIGNoaWxkcmVuLnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmV0dXJuIFtuZXcgSW5zdHJ1Y3Rpb24oJ2ltYWdlU21vb3RoaW5nRW5hYmxlZCcsIHsgdmFsdWU6IEJvb2xlYW4odmFsKSB9KV0uY29uY2F0KGNoaWxkcmVuKS5jb25jYXQobmV3IEluc3RydWN0aW9uKCdlbmRJbWFnZVNtb290aGluZ0VuYWJsZWQnKSk7XHJcbn07XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBsaW5lU3R5bGUodmFsdWUsIGNoaWxkcmVuKSB7XHJcbiAgXHJcbiAgdmFsdWUgPSB2YWx1ZSB8fCB7fTtcclxuICB2YXIgcmVzdWx0ID0ge1xyXG4gICAgbGluZVdpZHRoOiBudWxsLFxyXG4gICAgbGluZUNhcDogbnVsbCxcclxuICAgIGxpbmVKb2luOiBudWxsLFxyXG4gICAgbWl0ZXJMaW1pdDogbnVsbCxcclxuICAgIGxpbmVEYXNoOiBbXSxcclxuICAgIGxpbmVEYXNoT2Zmc2V0OiBudWxsXHJcbiAgfTtcclxuICBcclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVXaWR0aCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lV2lkdGggPSB2YWx1ZS5saW5lV2lkdGg7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZUNhcCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lQ2FwID0gdmFsdWUubGluZUNhcDtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lSm9pbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lSm9pbiA9IHZhbHVlLmxpbmVKb2luO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLm1pdGVyTGltaXQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubWl0ZXJMaW1pdCA9IHZhbHVlLm1pdGVyTGltaXQ7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZURhc2ggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZURhc2ggPSB2YWx1ZS5saW5lRGFzaDtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lRGFzaE9mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lRGFzaE9mZnNldCA9IHZhbHVlLmxpbmVEYXNoT2Zmc2V0O1xyXG4gIH1cclxuICB2YXIgdHJlZSA9IFtuZXcgSW5zdHJ1Y3Rpb24oJ2xpbmVTdHlsZScsIHJlc3VsdCldO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHRyZWUucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICB0cmVlLnB1c2gobmV3IEluc3RydWN0aW9uKCdlbmRMaW5lU3R5bGUnKSk7XHJcbiAgcmV0dXJuIHRyZWU7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZVN0eWxlOyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBsaW5lVG8oeCwgeSkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdsaW5lVG8nLCB7IHg6IDAsIHk6IDB9KTtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignbGluZVRvJywgeyB4OiB4LCB5OiB5IH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxpbmVUbzsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gbW92ZVRvKHgsIHkpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignbW92ZVRvJywgeyB4OiAwLCB5OiAwfSk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ21vdmVUbycsIHsgeDogeCwgeTogeSB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBtb3ZlVG87IiwiJ3VzZSBzdHJpY3QnO1xyXG52YXIgbW92ZVRvID0gcmVxdWlyZSgnLi9tb3ZlVG8nKSwgbGluZVRvID0gcmVxdWlyZSgnLi9saW5lVG8nKTtcclxuZnVuY3Rpb24gbW92ZVRvTGluZVRvKHBvaW50LCBpbmRleCkge1xyXG4gIHJldHVybiBpbmRleCA9PT0gMCA/IG1vdmVUbyhwb2ludFswXSwgcG9pbnRbMV0pIDogbGluZVRvKHBvaW50WzBdLCBwb2ludFsxXSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbW92ZVRvTGluZVRvO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBiZWdpblBhdGggPSByZXF1aXJlKCcuL2JlZ2luUGF0aCcpLFxyXG4gICAgY2xvc2VQYXRoID0gcmVxdWlyZSgnLi9jbG9zZVBhdGgnKTtcclxuXHJcbmZ1bmN0aW9uIHBhdGgoY2hpbGRyZW4pIHtcclxuICB2YXIgcmVzdWx0ID0gW2JlZ2luUGF0aCgpXTtcclxuICBmb3IodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICByZXN1bHQucHVzaChjbG9zZVBhdGgoKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwYXRoOyIsIid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBsYWNlSG9sZGVyKCkge1xyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3BsYWNlaG9sZGVyJyk7XHJcbn07XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBxdWFkcmF0aWNDdXJ2ZVRvKGNweCwgY3B5LCB4LCB5KSB7XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbigncXVhZHJhdGljQ3VydmVUbycsIHtcclxuICAgIGNweDogY3B4LCBcclxuICAgIGNweTogY3B5LCBcclxuICAgIHg6IHgsIFxyXG4gICAgeTogeVxyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHF1YWRyYXRpY0N1cnZlVG87IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIHJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInJlY3RcIiwgeyB4OiB4LCB5OiB5LCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0IH0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwicmVjdFwiLCB7IHg6IDAsIHk6IDAsIHdpZHRoOiB4LCBoZWlnaHQ6IHkgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHJlY3Q7IiwiJ3VzZSBzdHJpY3QnO1xyXG52YXIgc2V0VHJhbnNmb3JtID0gcmVxdWlyZSgnLi9zZXRUcmFuc2Zvcm0nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmVzZXRUcmFuc2Zvcm0oKSB7XHJcbiAgdmFyIGFyZ3MgPSBbXTtcclxuICBmb3IodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmV0dXJuIHNldFRyYW5zZm9ybShbMSwgMCwgMCwgMSwgMCwgMF0sIGFyZ3MpO1xyXG59O1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gcm90YXRlKHIsIGNoaWxkcmVuKSB7XHJcbiAgciA9ICtyO1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdyb3RhdGUnLCB7IHI6IHIgfSldO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHJlc3VsdC5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpKTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHJvdGF0ZTsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gc2NhbGUoeCwgeSwgY2hpbGRyZW4pIHtcclxuICB2YXIgaSA9IDI7XHJcbiAgaWYgKHR5cGVvZiB5ICE9PSAnbnVtYmVyJykge1xyXG4gICAgeSA9IHg7XHJcbiAgICBpID0gMTtcclxuICB9XHJcbiAgY2hpbGRyZW4gPSBjaGlsZHJlbiB8fCBbXTtcclxuICBcclxuICB2YXIgcmVzdWx0ID0gW25ldyBJbnN0cnVjdGlvbignc2NhbGUnLCB7IHg6IHgsIHk6IHkgfSldLFxyXG4gICAgICBjaGlsZDtcclxuICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmVzdWx0LnB1c2gobmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJykpO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2NhbGU7IiwiJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG1hdHJpeCwgY2hpbGRyZW4pIHtcclxuXHJcbiAgdmFyIHJlc3VsdCA9IFtuZXcgSW5zdHJ1Y3Rpb24oJ3NldFRyYW5zZm9ybScsIFtcclxuICAgIG1hdHJpeFswXSxcclxuICAgIG1hdHJpeFsxXSxcclxuICAgIG1hdHJpeFsyXSxcclxuICAgIG1hdHJpeFszXSxcclxuICAgIG1hdHJpeFs0XSxcclxuICAgIG1hdHJpeFs1XVxyXG4gIF0pXTtcclxuICBmb3IodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICByZXN1bHQucHVzaChuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIHNoYWRvd1N0eWxlKHZhbHVlLCBjaGlsZHJlbikge1xyXG4gIHZhbHVlID0gdmFsdWUgfHwge307XHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIHNoYWRvd0JsdXI6IG51bGwsXHJcbiAgICBzaGFkb3dDb2xvcjogbnVsbCxcclxuICAgIHNoYWRvd09mZnNldFg6IG51bGwsXHJcbiAgICBzaGFkb3dPZmZzZXRZOiBudWxsXHJcbiAgfTtcclxuICBcclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd0JsdXIgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93Qmx1ciA9IHZhbHVlLnNoYWRvd0JsdXI7IFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd0NvbG9yICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnNoYWRvd0NvbG9yID0gdmFsdWUuc2hhZG93Q29sb3I7IFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd09mZnNldFggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93T2Zmc2V0WCA9IHZhbHVlLnNoYWRvd09mZnNldFg7IFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmRpcmVjdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dPZmZzZXRZID0gdmFsdWUuc2hhZG93T2Zmc2V0WTsgXHJcbiAgfVxyXG4gIFxyXG4gIHZhciB0cmVlID0gW25ldyBJbnN0cnVjdGlvbignc2hhZG93U3R5bGUnLCB2YWx1ZSldO1xyXG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB0cmVlLnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgdHJlZS5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kU2hhZG93U3R5bGUnKSk7XHJcbiAgXHJcbiAgcmV0dXJuIHRyZWU7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2hhZG93U3R5bGU7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIHN0cm9rZSgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdzdHJva2UnKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2U7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxuZnVuY3Rpb24gc3Ryb2tlQXJjKHgsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNiAmJiBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwic3Ryb2tlQXJjLWNvdW50ZXJjbG9ja3dpc2VcIiwgeyB4OiB4LCB5OiB5LCByOiByLCBzdGFydEFuZ2xlOiBzdGFydEFuZ2xlLCBlbmRBbmdsZTogZW5kQW5nbGUgfSk7XHJcbiAgfVxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCB7IHg6IHgsIHk6IHksIHI6IHIsIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlOiBlbmRBbmdsZSB9KTtcclxuICB9IFxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSl7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwic3Ryb2tlQXJjXCIsIHsgeDogeCwgeTogeSwgcjogciwgc3RhcnRBbmdsZTogMCwgZW5kQW5nbGU6IHBpMiB9KTtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCAgeyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZUFyYzsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gc3Ryb2tlUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwic3Ryb2tlUmVjdFwiLCB7IHg6IHgsIHk6IHksIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJzdHJva2VSZWN0XCIsIHsgeDogMCwgeTogMCwgd2lkdGg6IHgsIGhlaWdodDogeSB9KTtcclxuICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3Ryb2tlUmVjdDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbFN0eWxlKHZhbHVlLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbIG5ldyBJbnN0cnVjdGlvbignc3Ryb2tlU3R5bGUnLCB7IHZhbHVlOiB2YWx1ZSB9KSBdO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHJlc3VsdC5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kU3Ryb2tlU3R5bGUnKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsU3R5bGU7XHJcbiIsInZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc3Ryb2tlVGV4dCh0ZXh0LCB4LCB5LCBtYXhXaWR0aCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xyXG4gICAgbWF4V2lkdGggPSBudWxsO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcclxuICAgIHggPSAwO1xyXG4gICAgeSA9IDA7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3N0cm9rZVRleHQnLCB7XHJcbiAgICB0ZXh0OiB0ZXh0LFxyXG4gICAgeDogeCxcclxuICAgIHk6IHksXHJcbiAgICBtYXhXaWR0aDogbWF4V2lkdGhcclxuICB9KTtcclxufTtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuZnVuY3Rpb24gdGV4dChzdHIsIHgsIHksIGZpbGwsIHN0cm9rZSwgbWF4V2lkdGgpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNikge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbigndGV4dCcsIHtcclxuICAgICAgeDogeCxcclxuICAgICAgeTogeSxcclxuICAgICAgZmlsbDogZmlsbCxcclxuICAgICAgc3Ryb2tlOiBzdHJva2UsXHJcbiAgICAgIHRleHQ6IHN0cixcclxuICAgICAgbWF4V2lkdGg6IG1heFdpZHRoXHJcbiAgICB9KTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3RleHQnLCB7XHJcbiAgICAgIHg6IHgsXHJcbiAgICAgIHk6IHksXHJcbiAgICAgIGZpbGw6IGZpbGwsXHJcbiAgICAgIHN0cm9rZTogc3Ryb2tlLFxyXG4gICAgICB0ZXh0OiBzdHIsXHJcbiAgICAgIG1heFdpZHRoOiAwXHJcbiAgICB9KTtcclxuICB9XHJcbiAgXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3RleHQnLCB7XHJcbiAgICAgIHg6IHgsXHJcbiAgICAgIHk6IHksXHJcbiAgICAgIGZpbGw6IGZpbGwsXHJcbiAgICAgIHN0cm9rZTogZmFsc2UsXHJcbiAgICAgIHRleHQ6IHN0cixcclxuICAgICAgbWF4V2lkdGg6IDBcclxuICAgIH0pO1xyXG4gIH1cclxuICBcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbigndGV4dCcsIHtcclxuICAgICAgeDogeCxcclxuICAgICAgeTogeSxcclxuICAgICAgZmlsbDogdHJ1ZSxcclxuICAgICAgc3Ryb2tlOiBmYWxzZSxcclxuICAgICAgdGV4dDogc3RyLFxyXG4gICAgICBtYXhXaWR0aDogMFxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIFxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3RleHQnLCB7XHJcbiAgICB4OiAwLFxyXG4gICAgeTogMCxcclxuICAgIGZpbGw6IHRydWUsXHJcbiAgICBzdHJva2U6IGZhbHNlLFxyXG4gICAgdGV4dDogc3RyLFxyXG4gICAgbWF4V2lkdGg6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0ZXh0OyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiB0ZXh0U3R5bGUodmFsdWUsIGNoaWxkcmVuKSB7XHJcbiAgdmFsdWUgPSB2YWx1ZSB8fCB7fTtcclxuICB2YXIgcmVzdWx0ID0ge1xyXG4gICAgZm9udDogbnVsbCxcclxuICAgIHRleHRBbGlnbjogbnVsbCxcclxuICAgIHRleHRCYXNlbGluZTogbnVsbCxcclxuICAgIGRpcmVjdGlvbjogbnVsbFxyXG4gIH07XHJcbiAgXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5mb250ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmZvbnQgPSB2YWx1ZS5mb250OyBcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS50ZXh0QWxpZ24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQudGV4dEFsaWduID0gdmFsdWUudGV4dEFsaWduOyBcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS50ZXh0QmFzZWxpbmUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQudGV4dEJhc2VsaW5lID0gdmFsdWUudGV4dEJhc2VsaW5lOyBcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5kaXJlY3Rpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuZGlyZWN0aW9uID0gdmFsdWUuZGlyZWN0aW9uOyBcclxuICB9XHJcbiAgdmFyIHRyZWUgPSBbbmV3IEluc3RydWN0aW9uKCd0ZXh0U3R5bGUnLCB2YWx1ZSldO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHRyZWUucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICB0cmVlLnB1c2gobmV3IEluc3RydWN0aW9uKCdlbmRUZXh0U3R5bGUnKSk7XHJcbiAgcmV0dXJuIHRyZWU7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dFN0eWxlOyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiB0cmFuc2Zvcm0odmFsdWVzLCBjaGlsZHJlbikge1xyXG5cclxuICB2YXIgdHJhbnNmb3JtUmVzdWx0ID0gW1xyXG4gICAgbmV3IEluc3RydWN0aW9uKCd0cmFuc2Zvcm0nLFtcclxuICAgICAgdmFsdWVzWzBdLFxyXG4gICAgICB2YWx1ZXNbMV0sXHJcbiAgICAgIHZhbHVlc1syXSxcclxuICAgICAgdmFsdWVzWzNdLFxyXG4gICAgICB2YWx1ZXNbNF0sXHJcbiAgICAgIHZhbHVlc1s1XVxyXG4gICAgXSlcclxuICBdO1xyXG4gIGZvcih2YXIgaSA9IDEsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgdHJhbnNmb3JtUmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgdHJhbnNmb3JtUmVzdWx0LnB1c2gobmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJykpO1xyXG5cclxuICByZXR1cm4gdHJhbnNmb3JtUmVzdWx0O1xyXG59XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2Zvcm07XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gdHJhbnNmb3JtUG9pbnRzKHBvaW50cywgbWF0cml4KSB7XHJcbiAgdmFyIHJlc3VsdCA9IFtdLFxyXG4gICAgICBsZW4gPSBwb2ludHMubGVuZ3RoLFxyXG4gICAgICBwb2ludDtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBwb2ludCA9IHBvaW50c1tpXTtcclxuICAgIHJlc3VsdC5wdXNoKFtcclxuICAgICAgbWF0cml4WzBdICogcG9pbnRbMF0gKyBtYXRyaXhbMl0gKiBwb2ludFsxXSArIG1hdHJpeFs0XSxcclxuICAgICAgbWF0cml4WzFdICogcG9pbnRbMF0gKyBtYXRyaXhbM10gKiBwb2ludFsxXSArIG1hdHJpeFs1XVxyXG4gICAgXSk7XHJcbiAgfVxyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtUG9pbnRzOyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiB0cmFuc2xhdGUoeCwgeSwgY2hpbGRyZW4pIHtcclxuICBcclxuICB2YXIgcmVzdWx0ID0gW25ldyBJbnN0cnVjdGlvbigndHJhbnNsYXRlJywgeyB4OiB4LCB5OiB5IH0pXTtcclxuICB2YXIgdmFsO1xyXG4gIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YWwgPSBhcmd1bWVudHNbaV07XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XHJcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodmFsKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICBcclxuICByZXN1bHQucHVzaChuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2xhdGU7IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IFR5cGVFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIHZhciBtO1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gMDtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbihlbWl0dGVyLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IDE7XG4gIGVsc2VcbiAgICByZXQgPSBlbWl0dGVyLl9ldmVudHNbdHlwZV0ubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCBhcnJheSB3aXRoIGRpcmVjdG9yeSBuYW1lcyB0aGVyZVxuLy8gbXVzdCBiZSBubyBzbGFzaGVzLCBlbXB0eSBlbGVtZW50cywgb3IgZGV2aWNlIG5hbWVzIChjOlxcKSBpbiB0aGUgYXJyYXlcbi8vIChzbyBhbHNvIG5vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgLSBpdCBkb2VzIG5vdCBkaXN0aW5ndWlzaFxuLy8gcmVsYXRpdmUgYW5kIGFic29sdXRlIHBhdGhzKVxuZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkocGFydHMsIGFsbG93QWJvdmVSb290KSB7XG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBsYXN0ID0gcGFydHNbaV07XG4gICAgaWYgKGxhc3QgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKGFsbG93QWJvdmVSb290KSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBwYXJ0cy51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuLy8gU3BsaXQgYSBmaWxlbmFtZSBpbnRvIFtyb290LCBkaXIsIGJhc2VuYW1lLCBleHRdLCB1bml4IHZlcnNpb25cbi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuXG52YXIgc3BsaXRQYXRoUmUgPVxuICAgIC9eKFxcLz98KShbXFxzXFxTXSo/KSgoPzpcXC57MSwyfXxbXlxcL10rP3wpKFxcLlteLlxcL10qfCkpKD86W1xcL10qKSQvO1xudmFyIHNwbGl0UGF0aCA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7XG4gIHJldHVybiBzcGxpdFBhdGhSZS5leGVjKGZpbGVuYW1lKS5zbGljZSgxKTtcbn07XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzb2x2ZWRQYXRoID0gJycsXG4gICAgICByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpID49IC0xICYmICFyZXNvbHZlZEFic29sdXRlOyBpLS0pIHtcbiAgICB2YXIgcGF0aCA9IChpID49IDApID8gYXJndW1lbnRzW2ldIDogcHJvY2Vzcy5jd2QoKTtcblxuICAgIC8vIFNraXAgZW1wdHkgYW5kIGludmFsaWQgZW50cmllc1xuICAgIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLnJlc29sdmUgbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfSBlbHNlIGlmICghcGF0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzb2x2ZWRQYXRoID0gcGF0aCArICcvJyArIHJlc29sdmVkUGF0aDtcbiAgICByZXNvbHZlZEFic29sdXRlID0gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZUFycmF5KGZpbHRlcihyZXNvbHZlZFBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhcmVzb2x2ZWRBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIHJldHVybiAoKHJlc29sdmVkQWJzb2x1dGUgPyAnLycgOiAnJykgKyByZXNvbHZlZFBhdGgpIHx8ICcuJztcbn07XG5cbi8vIHBhdGgubm9ybWFsaXplKHBhdGgpXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIGlzQWJzb2x1dGUgPSBleHBvcnRzLmlzQWJzb2x1dGUocGF0aCksXG4gICAgICB0cmFpbGluZ1NsYXNoID0gc3Vic3RyKHBhdGgsIC0xKSA9PT0gJy8nO1xuXG4gIC8vIE5vcm1hbGl6ZSB0aGUgcGF0aFxuICBwYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhaXNBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIGlmICghcGF0aCAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHBhdGggPSAnLic7XG4gIH1cbiAgaWYgKHBhdGggJiYgdHJhaWxpbmdTbGFzaCkge1xuICAgIHBhdGggKz0gJy8nO1xuICB9XG5cbiAgcmV0dXJuIChpc0Fic29sdXRlID8gJy8nIDogJycpICsgcGF0aDtcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGguY2hhckF0KDApID09PSAnLyc7XG59O1xuXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLmpvaW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGhzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgcmV0dXJuIGV4cG9ydHMubm9ybWFsaXplKGZpbHRlcihwYXRocywgZnVuY3Rpb24ocCwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgdG8gcGF0aC5qb2luIG11c3QgYmUgc3RyaW5ncycpO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfSkuam9pbignLycpKTtcbn07XG5cblxuLy8gcGF0aC5yZWxhdGl2ZShmcm9tLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVsYXRpdmUgPSBmdW5jdGlvbihmcm9tLCB0bykge1xuICBmcm9tID0gZXhwb3J0cy5yZXNvbHZlKGZyb20pLnN1YnN0cigxKTtcbiAgdG8gPSBleHBvcnRzLnJlc29sdmUodG8pLnN1YnN0cigxKTtcblxuICBmdW5jdGlvbiB0cmltKGFycikge1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgZm9yICg7IHN0YXJ0IDwgYXJyLmxlbmd0aDsgc3RhcnQrKykge1xuICAgICAgaWYgKGFycltzdGFydF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gYXJyLmxlbmd0aCAtIDE7XG4gICAgZm9yICg7IGVuZCA+PSAwOyBlbmQtLSkge1xuICAgICAgaWYgKGFycltlbmRdICE9PSAnJykgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID4gZW5kKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGFyci5zbGljZShzdGFydCwgZW5kIC0gc3RhcnQgKyAxKTtcbiAgfVxuXG4gIHZhciBmcm9tUGFydHMgPSB0cmltKGZyb20uc3BsaXQoJy8nKSk7XG4gIHZhciB0b1BhcnRzID0gdHJpbSh0by5zcGxpdCgnLycpKTtcblxuICB2YXIgbGVuZ3RoID0gTWF0aC5taW4oZnJvbVBhcnRzLmxlbmd0aCwgdG9QYXJ0cy5sZW5ndGgpO1xuICB2YXIgc2FtZVBhcnRzTGVuZ3RoID0gbGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZyb21QYXJ0c1tpXSAhPT0gdG9QYXJ0c1tpXSkge1xuICAgICAgc2FtZVBhcnRzTGVuZ3RoID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBvdXRwdXRQYXJ0cyA9IFtdO1xuICBmb3IgKHZhciBpID0gc2FtZVBhcnRzTGVuZ3RoOyBpIDwgZnJvbVBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0UGFydHMucHVzaCgnLi4nKTtcbiAgfVxuXG4gIG91dHB1dFBhcnRzID0gb3V0cHV0UGFydHMuY29uY2F0KHRvUGFydHMuc2xpY2Uoc2FtZVBhcnRzTGVuZ3RoKSk7XG5cbiAgcmV0dXJuIG91dHB1dFBhcnRzLmpvaW4oJy8nKTtcbn07XG5cbmV4cG9ydHMuc2VwID0gJy8nO1xuZXhwb3J0cy5kZWxpbWl0ZXIgPSAnOic7XG5cbmV4cG9ydHMuZGlybmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKSxcbiAgICAgIHJvb3QgPSByZXN1bHRbMF0sXG4gICAgICBkaXIgPSByZXN1bHRbMV07XG5cbiAgaWYgKCFyb290ICYmICFkaXIpIHtcbiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXJcbiAgICByZXR1cm4gJy4nO1xuICB9XG5cbiAgaWYgKGRpcikge1xuICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoXG4gICAgZGlyID0gZGlyLnN1YnN0cigwLCBkaXIubGVuZ3RoIC0gMSk7XG4gIH1cblxuICByZXR1cm4gcm9vdCArIGRpcjtcbn07XG5cblxuZXhwb3J0cy5iYXNlbmFtZSA9IGZ1bmN0aW9uKHBhdGgsIGV4dCkge1xuICB2YXIgZiA9IHNwbGl0UGF0aChwYXRoKVsyXTtcbiAgLy8gVE9ETzogbWFrZSB0aGlzIGNvbXBhcmlzb24gY2FzZS1pbnNlbnNpdGl2ZSBvbiB3aW5kb3dzP1xuICBpZiAoZXh0ICYmIGYuc3Vic3RyKC0xICogZXh0Lmxlbmd0aCkgPT09IGV4dCkge1xuICAgIGYgPSBmLnN1YnN0cigwLCBmLmxlbmd0aCAtIGV4dC5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBmO1xufTtcblxuXG5leHBvcnRzLmV4dG5hbWUgPSBmdW5jdGlvbihwYXRoKSB7XG4gIHJldHVybiBzcGxpdFBhdGgocGF0aClbM107XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXIgKHhzLCBmKSB7XG4gICAgaWYgKHhzLmZpbHRlcikgcmV0dXJuIHhzLmZpbHRlcihmKTtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZih4c1tpXSwgaSwgeHMpKSByZXMucHVzaCh4c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUuc3Vic3RyIC0gbmVnYXRpdmUgaW5kZXggZG9uJ3Qgd29yayBpbiBJRThcbnZhciBzdWJzdHIgPSAnYWInLnN1YnN0cigtMSkgPT09ICdiJ1xuICAgID8gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbikgeyByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKSB9XG4gICAgOiBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gc3RyLmxlbmd0aCArIHN0YXJ0O1xuICAgICAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKTtcbiAgICB9XG47XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKSIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG5cbi8vIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4vLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuLy8gSWYgLS1uby1kZXByZWNhdGlvbiBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24oZm4sIG1zZykge1xuICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzLm5vRGVwcmVjYXRpb24gPT09IHRydWUpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbikge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufTtcblxuXG52YXIgZGVidWdzID0ge307XG52YXIgZGVidWdFbnZpcm9uO1xuZXhwb3J0cy5kZWJ1Z2xvZyA9IGZ1bmN0aW9uKHNldCkge1xuICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSlcbiAgICBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcbiAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuICAgICAgdmFyIHBpZCA9IHByb2Nlc3MucGlkO1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG1zZyA9IGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyVzICVkOiAlcycsIHNldCwgcGlkLCBtc2cpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHt9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVidWdzW3NldF07XG59O1xuXG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIElFIGRvZXNuJ3QgbWFrZSBlcnJvciBmaWVsZHMgbm9uLWVudW1lcmFibGVcbiAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcbiAgaWYgKGlzRXJyb3IodmFsdWUpXG4gICAgICAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gcmVxdWlyZSgnLi9zdXBwb3J0L2lzQnVmZmVyJyk7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZSgnX3Byb2Nlc3MnKSx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KSIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICBhZGRDb2xvclN0b3A6IHJlcXVpcmUoJy4vc3JjL2FkZENvbG9yU3RvcCcpLFxyXG4gICAgYXJjOiByZXF1aXJlKCcuL3NyYy9hcmMnKSxcclxuICAgIGFyY1RvOiByZXF1aXJlKCcuL3NyYy9hcmNUbycpLFxyXG4gICAgYmVnaW5QYXRoOiByZXF1aXJlKCcuL3NyYy9iZWdpblBhdGgnKSxcclxuICAgIGJlemllckN1cnZlVG86IHJlcXVpcmUoJy4vc3JjL2JlemllckN1cnZlVG8nKSxcclxuICAgIENhbnZhczogcmVxdWlyZSgnLi9zcmMvQ2FudmFzJyksXHJcbiAgICBjbGVhclJlY3Q6IHJlcXVpcmUoJy4vc3JjL2NsZWFyUmVjdCcpLFxyXG4gICAgY2xpcDogcmVxdWlyZSgnLi9zcmMvY2xpcCcpLFxyXG4gICAgY2xpcFBhdGg6IHJlcXVpcmUoJy4vc3JjL2NsaXBQYXRoJyksXHJcbiAgICBjbG9zZVBhdGg6IHJlcXVpcmUoJy4vc3JjL2Nsb3NlUGF0aCcpLFxyXG4gICAgY3JlYXRlQ2xhc3M6IHJlcXVpcmUoJy4vc3JjL2NyZWF0ZUNsYXNzJyksXHJcbiAgICBjcmVhdGVMaW5lYXJHcmFkaWVudDogcmVxdWlyZSgnLi9zcmMvY3JlYXRlTGluZWFyR3JhZGllbnQnKSxcclxuICAgIGNyZWF0ZVJhZGlhbEdyYWRpZW50OiByZXF1aXJlKCcuL3NyYy9jcmVhdGVSYWRpYWxHcmFkaWVudCcpLFxyXG4gICAgY3JlYXRlUmVndWxhclBvbHlnb24gOiByZXF1aXJlKCcuL3NyYy9jcmVhdGVSZWd1bGFyUG9seWdvbicpLFxyXG4gICAgZHJhd0NhbnZhczogcmVxdWlyZSgnLi9zcmMvZHJhd0NhbnZhcycpLFxyXG4gICAgZHJhd0ltYWdlOiByZXF1aXJlKCcuL3NyYy9kcmF3SW1hZ2UnKSxcclxuICAgIGVsbGlwc2U6IHJlcXVpcmUoJy4vc3JjL2VsbGlwc2UnKSxcclxuICAgIGZpbGw6IHJlcXVpcmUoJy4vc3JjL2ZpbGwnKSxcclxuICAgIGZpbGxBcmM6IHJlcXVpcmUoJy4vc3JjL2ZpbGxBcmMnKSxcclxuICAgIGZpbGxDYW52YXM6IHJlcXVpcmUoJy4vc3JjL2ZpbGxDYW52YXMnKSxcclxuICAgIGZpbGxJbWFnZTogcmVxdWlyZSgnLi9zcmMvZmlsbEltYWdlJyksXHJcbiAgICBmaWxsSW1hZ2VQYXR0ZXJuOiByZXF1aXJlKCcuL3NyYy9maWxsSW1hZ2VQYXR0ZXJuJyksXHJcbiAgICBmaWxsUmVjdDogcmVxdWlyZSgnLi9zcmMvZmlsbFJlY3QnKSxcclxuICAgIGZpbGxTdHlsZTogcmVxdWlyZSgnLi9zcmMvZmlsbFN0eWxlJyksXHJcbiAgICBmaWxsVGV4dDogcmVxdWlyZSgnLi9zcmMvZmlsbFRleHQnKSxcclxuICAgIGdsb2JhbEFscGhhOiByZXF1aXJlKCcuL3NyYy9nbG9iYWxBbHBoYScpLFxyXG4gICAgZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uOiByZXF1aXJlKCcuL3NyYy9nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSxcclxuICAgIGhpdFJlY3Q6IHJlcXVpcmUoJy4vc3JjL2hpdFJlY3QnKSxcclxuICAgIGhpdFJlZ2lvbjogcmVxdWlyZSgnLi9zcmMvaGl0UmVnaW9uJyksXHJcbiAgICBpbWFnZVNtb290aGluZ0VuYWJsZWQ6IHJlcXVpcmUoJy4vc3JjL2ltYWdlU21vb3RoaW5nRW5hYmxlZCcpLFxyXG4gICAgSW1nOiByZXF1aXJlKCcuL3NyYy9JbWcnKSxcclxuICAgIEluc3RydWN0aW9uOiByZXF1aXJlKCcuL3NyYy9JbnN0cnVjdGlvbicpLFxyXG4gICAgbGluZVN0eWxlOiByZXF1aXJlKCcuL3NyYy9saW5lU3R5bGUnKSxcclxuICAgIGxpbmVUbzogcmVxdWlyZSgnLi9zcmMvbGluZVRvJyksXHJcbiAgICBtb3ZlVG86IHJlcXVpcmUoJy4vc3JjL21vdmVUbycpLFxyXG4gICAgbW92ZVRvTGluZVRvOiByZXF1aXJlKCcuL3NyYy9tb3ZlVG9MaW5lVG8nKSxcclxuICAgIHBhdGg6IHJlcXVpcmUoJy4vc3JjL3BhdGgnKSxcclxuICAgIHBsYWNlSG9sZGVyOiByZXF1aXJlKCcuL3NyYy9wbGFjZUhvbGRlcicpLFxyXG4gICAgcXVhZHJhdGljQ3VydmVUbzogcmVxdWlyZSgnLi9zcmMvcXVhZHJhdGljQ3VydmVUbycpLFxyXG4gICAgcmVjdDogcmVxdWlyZSgnLi9zcmMvcmVjdCcpLFxyXG4gICAgUmVuZGVyZXI6IHJlcXVpcmUoJy4vc3JjL1JlbmRlcmVyJyksXHJcbiAgICByZXNldFRyYW5zZm9ybTogcmVxdWlyZSgnLi9zcmMvcmVzZXRUcmFuc2Zvcm0nKSxcclxuICAgIHJvdGF0ZTogcmVxdWlyZSgnLi9zcmMvcm90YXRlJyksXHJcbiAgICBzY2FsZTogcmVxdWlyZSgnLi9zcmMvc2NhbGUnKSxcclxuICAgIHNldFRyYW5zZm9ybTogcmVxdWlyZSgnLi9zcmMvc2V0VHJhbnNmb3JtJyksXHJcbiAgICBzaGFkb3dTdHlsZTogcmVxdWlyZSgnLi9zcmMvc2hhZG93U3R5bGUnKSxcclxuICAgIHN0cm9rZTogcmVxdWlyZSgnLi9zcmMvc3Ryb2tlJyksXHJcbiAgICBzdHJva2VBcmM6IHJlcXVpcmUoJy4vc3JjL3N0cm9rZUFyYycpLFxyXG4gICAgc3Ryb2tlUmVjdDogcmVxdWlyZSgnLi9zcmMvc3Ryb2tlUmVjdCcpLFxyXG4gICAgc3Ryb2tlU3R5bGU6IHJlcXVpcmUoJy4vc3JjL3N0cm9rZVN0eWxlJyksXHJcbiAgICBzdHJva2VUZXh0OiByZXF1aXJlKCcuL3NyYy9zdHJva2VUZXh0JyksXHJcbiAgICB0ZXh0OiByZXF1aXJlKCcuL3NyYy90ZXh0JyksXHJcbiAgICB0ZXh0U3R5bGU6IHJlcXVpcmUoJy4vc3JjL3RleHRTdHlsZScpLFxyXG4gICAgdHJhbnNmb3JtOiByZXF1aXJlKCcuL3NyYy90cmFuc2Zvcm0nKSxcclxuICAgIHRyYW5zZm9ybVBvaW50czogcmVxdWlyZSgnLi9zcmMvdHJhbnNmb3JtUG9pbnRzJyksXHJcbiAgICB0cmFuc2xhdGU6IHJlcXVpcmUoJy4vc3JjL3RyYW5zbGF0ZScpXHJcbn07XHJcbiJdfQ== | |
var e2d = require('e2d'); | |
var r = e2d.Renderer.create(400, 400); | |
var helloWorld = e2d.fillText('Hello World'); | |
r.ready(); | |
r.on('frame', | |
() => r.render( | |
e2d.clearRect(400, 400), | |
e2d.translate(200, 200, | |
helloWorld | |
) | |
) | |
); | |
;}, 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "requirebin-sketch", | |
"version": "1.0.0", | |
"dependencies": { | |
"e2d": "3.2.1" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- contents of this file will be placed inside the <body> --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- contents of this file will be placed inside the <head> --> | |
<link rel = "stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css"> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment