You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
12964 lines
1.1 MiB
12964 lines
1.1 MiB
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory(factory.toString());
|
|
else if(typeof exports === 'object')
|
|
exports["Quagga"] = factory(factory.toString());
|
|
else
|
|
root["Quagga"] = factory(factory.toString());
|
|
})(this, function(__factorySource__) {
|
|
return /******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId])
|
|
/******/ return installedModules[moduleId].exports;
|
|
/******/
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ exports: {},
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = true;
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
/******/
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
/******/
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "/";
|
|
/******/
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = __webpack_require__(1);
|
|
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _typedefs = __webpack_require__(2);
|
|
|
|
var _typedefs2 = _interopRequireDefault(_typedefs);
|
|
|
|
// eslint-disable-line no-unused-vars
|
|
|
|
var _image_wrapper = __webpack_require__(3);
|
|
|
|
var _image_wrapper2 = _interopRequireDefault(_image_wrapper);
|
|
|
|
var _barcode_locator = __webpack_require__(18);
|
|
|
|
var _barcode_locator2 = _interopRequireDefault(_barcode_locator);
|
|
|
|
var _barcode_decoder = __webpack_require__(23);
|
|
|
|
var _barcode_decoder2 = _interopRequireDefault(_barcode_decoder);
|
|
|
|
var _config2 = __webpack_require__(68);
|
|
|
|
var _config3 = _interopRequireDefault(_config2);
|
|
|
|
var _events = __webpack_require__(69);
|
|
|
|
var _events2 = _interopRequireDefault(_events);
|
|
|
|
var _camera_access = __webpack_require__(70);
|
|
|
|
var _camera_access2 = _interopRequireDefault(_camera_access);
|
|
|
|
var _image_debug = __webpack_require__(22);
|
|
|
|
var _image_debug2 = _interopRequireDefault(_image_debug);
|
|
|
|
var _glMatrix = __webpack_require__(7);
|
|
|
|
var _result_collector = __webpack_require__(71);
|
|
|
|
var _result_collector2 = _interopRequireDefault(_result_collector);
|
|
|
|
var merge = __webpack_require__(35);
|
|
var InputStream = __webpack_require__(72);
|
|
var FrameGrabber = __webpack_require__(74);
|
|
|
|
var _inputStream,
|
|
_framegrabber,
|
|
_stopped,
|
|
_canvasContainer = {
|
|
ctx: {
|
|
image: null,
|
|
overlay: null
|
|
},
|
|
dom: {
|
|
image: null,
|
|
overlay: null
|
|
}
|
|
},
|
|
_inputImageWrapper,
|
|
_boxSize,
|
|
_decoder,
|
|
_workerPool = [],
|
|
_onUIThread = true,
|
|
_resultCollector,
|
|
_config = {};
|
|
|
|
function initializeData(imageWrapper) {
|
|
initBuffers(imageWrapper);
|
|
_decoder = _barcode_decoder2['default'].create(_config.decoder, _inputImageWrapper);
|
|
}
|
|
|
|
function initConfig() {
|
|
if (typeof document !== "undefined") {
|
|
var vis = [{
|
|
node: document.querySelector("div[data-controls]"),
|
|
prop: _config.controls
|
|
}, {
|
|
node: _canvasContainer.dom.overlay,
|
|
prop: _config.visual.show
|
|
}];
|
|
|
|
for (var i = 0; i < vis.length; i++) {
|
|
if (vis[i].node) {
|
|
if (vis[i].prop === true) {
|
|
vis[i].node.style.display = "block";
|
|
} else {
|
|
vis[i].node.style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function initInputStream(cb) {
|
|
var video;
|
|
if (_config.inputStream.type === "VideoStream") {
|
|
video = document.createElement("video");
|
|
_inputStream = InputStream.createVideoStream(video);
|
|
} else if (_config.inputStream.type === "ImageStream") {
|
|
_inputStream = InputStream.createImageStream();
|
|
} else if (_config.inputStream.type === "LiveStream") {
|
|
var $viewport = document.querySelector("#interactive.viewport");
|
|
if ($viewport) {
|
|
video = $viewport.querySelector("video");
|
|
if (!video) {
|
|
video = document.createElement("video");
|
|
$viewport.appendChild(video);
|
|
}
|
|
}
|
|
_inputStream = InputStream.createLiveStream(video);
|
|
_camera_access2['default'].request(video, _config.inputStream.constraints, function (err) {
|
|
if (!err) {
|
|
_inputStream.trigger("canrecord");
|
|
} else {
|
|
return cb(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
_inputStream.setAttribute("preload", "auto");
|
|
_inputStream.setAttribute("autoplay", true);
|
|
_inputStream.setInputStream(_config.inputStream);
|
|
_inputStream.addEventListener("canrecord", canRecord.bind(undefined, cb));
|
|
}
|
|
|
|
function canRecord(cb) {
|
|
_barcode_locator2['default'].checkImageConstraints(_inputStream, _config.locator);
|
|
initCanvas();
|
|
_framegrabber = FrameGrabber.create(_inputStream, _canvasContainer.dom.image);
|
|
initConfig();
|
|
|
|
if (_config.numOfWorkers > 0) {
|
|
initWorkers(function () {
|
|
console.log("Workers created");
|
|
ready(cb);
|
|
});
|
|
} else {
|
|
initializeData();
|
|
ready(cb);
|
|
}
|
|
}
|
|
|
|
function ready(cb) {
|
|
_inputStream.play();
|
|
cb();
|
|
}
|
|
|
|
function initCanvas() {
|
|
if (typeof document !== "undefined") {
|
|
var $viewport = document.querySelector("#interactive.viewport");
|
|
_canvasContainer.dom.image = document.querySelector("canvas.imgBuffer");
|
|
if (!_canvasContainer.dom.image) {
|
|
_canvasContainer.dom.image = document.createElement("canvas");
|
|
_canvasContainer.dom.image.className = "imgBuffer";
|
|
if ($viewport && _config.inputStream.type === "ImageStream") {
|
|
$viewport.appendChild(_canvasContainer.dom.image);
|
|
}
|
|
}
|
|
_canvasContainer.ctx.image = _canvasContainer.dom.image.getContext("2d");
|
|
_canvasContainer.dom.image.width = _inputStream.getCanvasSize().x;
|
|
_canvasContainer.dom.image.height = _inputStream.getCanvasSize().y;
|
|
|
|
_canvasContainer.dom.overlay = document.querySelector("canvas.drawingBuffer");
|
|
if (!_canvasContainer.dom.overlay) {
|
|
_canvasContainer.dom.overlay = document.createElement("canvas");
|
|
_canvasContainer.dom.overlay.className = "drawingBuffer";
|
|
if ($viewport) {
|
|
$viewport.appendChild(_canvasContainer.dom.overlay);
|
|
}
|
|
var clearFix = document.createElement("br");
|
|
clearFix.setAttribute("clear", "all");
|
|
if ($viewport) {
|
|
$viewport.appendChild(clearFix);
|
|
}
|
|
}
|
|
_canvasContainer.ctx.overlay = _canvasContainer.dom.overlay.getContext("2d");
|
|
_canvasContainer.dom.overlay.width = _inputStream.getCanvasSize().x;
|
|
_canvasContainer.dom.overlay.height = _inputStream.getCanvasSize().y;
|
|
}
|
|
}
|
|
|
|
function initBuffers(imageWrapper) {
|
|
if (imageWrapper) {
|
|
_inputImageWrapper = imageWrapper;
|
|
} else {
|
|
_inputImageWrapper = new _image_wrapper2['default']({
|
|
x: _inputStream.getWidth(),
|
|
y: _inputStream.getHeight()
|
|
});
|
|
}
|
|
|
|
console.log(_inputImageWrapper.size);
|
|
_boxSize = [_glMatrix.vec2.clone([0, 0]), _glMatrix.vec2.clone([0, _inputImageWrapper.size.y]), _glMatrix.vec2.clone([_inputImageWrapper.size.x, _inputImageWrapper.size.y]), _glMatrix.vec2.clone([_inputImageWrapper.size.x, 0])];
|
|
_barcode_locator2['default'].init(_inputImageWrapper, _config.locator);
|
|
}
|
|
|
|
function getBoundingBoxes() {
|
|
if (_config.locate) {
|
|
return _barcode_locator2['default'].locate();
|
|
} else {
|
|
return [[_glMatrix.vec2.clone(_boxSize[0]), _glMatrix.vec2.clone(_boxSize[1]), _glMatrix.vec2.clone(_boxSize[2]), _glMatrix.vec2.clone(_boxSize[3])]];
|
|
}
|
|
}
|
|
|
|
function transformResult(result) {
|
|
var topRight = _inputStream.getTopRight(),
|
|
xOffset = topRight.x,
|
|
yOffset = topRight.y,
|
|
i;
|
|
|
|
if (!result || xOffset === 0 && yOffset === 0) {
|
|
return;
|
|
}
|
|
|
|
if (result.line && result.line.length === 2) {
|
|
moveLine(result.line);
|
|
}
|
|
if (result.boxes && result.boxes.length > 0) {
|
|
for (i = 0; i < result.boxes.length; i++) {
|
|
moveBox(result.boxes[i]);
|
|
}
|
|
}
|
|
|
|
function moveBox(box) {
|
|
var corner = box.length;
|
|
|
|
while (corner--) {
|
|
box[corner][0] += xOffset;
|
|
box[corner][1] += yOffset;
|
|
}
|
|
}
|
|
|
|
function moveLine(line) {
|
|
line[0].x += xOffset;
|
|
line[0].y += yOffset;
|
|
line[1].x += xOffset;
|
|
line[1].y += yOffset;
|
|
}
|
|
}
|
|
|
|
function publishResult(result, imageData) {
|
|
if (_onUIThread) {
|
|
transformResult(result);
|
|
if (imageData && result && result.codeResult) {
|
|
if (_resultCollector) {
|
|
_resultCollector.addResult(imageData, _inputStream.getCanvasSize(), result.codeResult);
|
|
}
|
|
}
|
|
}
|
|
|
|
_events2['default'].publish("processed", result);
|
|
if (result && result.codeResult) {
|
|
_events2['default'].publish("detected", result);
|
|
}
|
|
}
|
|
|
|
function locateAndDecode() {
|
|
var result, boxes;
|
|
|
|
boxes = getBoundingBoxes();
|
|
if (boxes) {
|
|
result = _decoder.decodeFromBoundingBoxes(boxes);
|
|
result = result || {};
|
|
result.boxes = boxes;
|
|
publishResult(result, _inputImageWrapper.data);
|
|
} else {
|
|
publishResult();
|
|
}
|
|
}
|
|
|
|
function update() {
|
|
var availableWorker;
|
|
|
|
if (_onUIThread) {
|
|
if (_workerPool.length > 0) {
|
|
availableWorker = _workerPool.filter(function (workerThread) {
|
|
return !workerThread.busy;
|
|
})[0];
|
|
if (availableWorker) {
|
|
_framegrabber.attachData(availableWorker.imageData);
|
|
} else {
|
|
return; // all workers are busy
|
|
}
|
|
} else {
|
|
_framegrabber.attachData(_inputImageWrapper.data);
|
|
}
|
|
if (_framegrabber.grab()) {
|
|
if (availableWorker) {
|
|
availableWorker.busy = true;
|
|
availableWorker.worker.postMessage({
|
|
cmd: 'process',
|
|
imageData: availableWorker.imageData
|
|
}, [availableWorker.imageData.buffer]);
|
|
} else {
|
|
locateAndDecode();
|
|
}
|
|
}
|
|
} else {
|
|
locateAndDecode();
|
|
}
|
|
}
|
|
|
|
function _start() {
|
|
_stopped = false;
|
|
(function frame() {
|
|
if (!_stopped) {
|
|
update();
|
|
if (_onUIThread && _config.inputStream.type === "LiveStream") {
|
|
window.requestAnimFrame(frame);
|
|
}
|
|
}
|
|
})();
|
|
}
|
|
|
|
function initWorkers(cb) {
|
|
var i;
|
|
_workerPool = [];
|
|
|
|
for (i = 0; i < _config.numOfWorkers; i++) {
|
|
initWorker(workerInitialized);
|
|
}
|
|
|
|
function workerInitialized(workerThread) {
|
|
_workerPool.push(workerThread);
|
|
if (_workerPool.length >= _config.numOfWorkers) {
|
|
cb();
|
|
}
|
|
}
|
|
}
|
|
|
|
function initWorker(cb) {
|
|
var blobURL,
|
|
workerThread = {
|
|
worker: undefined,
|
|
imageData: new Uint8Array(_inputStream.getWidth() * _inputStream.getHeight()),
|
|
busy: true
|
|
};
|
|
|
|
blobURL = generateWorkerBlob();
|
|
workerThread.worker = new Worker(blobURL);
|
|
|
|
workerThread.worker.onmessage = function (e) {
|
|
if (e.data.event === 'initialized') {
|
|
URL.revokeObjectURL(blobURL);
|
|
workerThread.busy = false;
|
|
workerThread.imageData = new Uint8Array(e.data.imageData);
|
|
console.log("Worker initialized");
|
|
return cb(workerThread);
|
|
} else if (e.data.event === 'processed') {
|
|
workerThread.imageData = new Uint8Array(e.data.imageData);
|
|
workerThread.busy = false;
|
|
publishResult(e.data.result, workerThread.imageData);
|
|
} else if (e.data.event === 'error') {
|
|
console.log("Worker error: " + e.data.message);
|
|
}
|
|
};
|
|
|
|
workerThread.worker.postMessage({
|
|
cmd: 'init',
|
|
size: { x: _inputStream.getWidth(), y: _inputStream.getHeight() },
|
|
imageData: workerThread.imageData,
|
|
config: _config
|
|
}, [workerThread.imageData.buffer]);
|
|
}
|
|
|
|
function workerInterface(factory) {
|
|
/* eslint-disable no-undef*/
|
|
if (factory) {
|
|
var Quagga = factory();
|
|
if (!Quagga) {
|
|
self.postMessage({ 'event': 'error', message: 'Quagga could not be created' });
|
|
return;
|
|
}
|
|
}
|
|
var imageWrapper;
|
|
|
|
self.onmessage = function (e) {
|
|
if (e.data.cmd === 'init') {
|
|
var config = e.data.config;
|
|
config.numOfWorkers = 0;
|
|
imageWrapper = new Quagga.ImageWrapper({
|
|
x: e.data.size.x,
|
|
y: e.data.size.y
|
|
}, new Uint8Array(e.data.imageData));
|
|
Quagga.init(config, ready, imageWrapper);
|
|
Quagga.onProcessed(onProcessed);
|
|
} else if (e.data.cmd === 'process') {
|
|
imageWrapper.data = new Uint8Array(e.data.imageData);
|
|
Quagga.start();
|
|
} else if (e.data.cmd === 'setReaders') {
|
|
Quagga.setReaders(e.data.readers);
|
|
}
|
|
};
|
|
|
|
function onProcessed(result) {
|
|
self.postMessage({
|
|
'event': 'processed',
|
|
imageData: imageWrapper.data,
|
|
result: result
|
|
}, [imageWrapper.data.buffer]);
|
|
}
|
|
|
|
function ready() {
|
|
// eslint-disable-line
|
|
self.postMessage({ 'event': 'initialized', imageData: imageWrapper.data }, [imageWrapper.data.buffer]);
|
|
}
|
|
|
|
/* eslint-enable */
|
|
}
|
|
|
|
function generateWorkerBlob() {
|
|
var blob, factorySource;
|
|
|
|
/* jshint ignore:start */
|
|
if (typeof __factorySource__ !== 'undefined') {
|
|
factorySource = __factorySource__; // eslint-disable-line no-undef
|
|
}
|
|
/* jshint ignore:end */
|
|
|
|
blob = new Blob(['(' + workerInterface.toString() + ')(' + factorySource + ');'], { type: 'text/javascript' });
|
|
|
|
return window.URL.createObjectURL(blob);
|
|
}
|
|
|
|
function _setReaders(readers) {
|
|
if (_decoder) {
|
|
_decoder.setReaders(readers);
|
|
} else if (_onUIThread && _workerPool.length > 0) {
|
|
_workerPool.forEach(function (workerThread) {
|
|
workerThread.worker.postMessage({ cmd: 'setReaders', readers: readers });
|
|
});
|
|
}
|
|
}
|
|
|
|
exports['default'] = {
|
|
init: function init(config, cb, imageWrapper) {
|
|
_config = merge({}, _config3['default'], config);
|
|
if (imageWrapper) {
|
|
_onUIThread = false;
|
|
initializeData(imageWrapper);
|
|
return cb();
|
|
} else {
|
|
initInputStream(cb);
|
|
}
|
|
},
|
|
start: function start() {
|
|
_start();
|
|
},
|
|
stop: function stop() {
|
|
_stopped = true;
|
|
_workerPool.forEach(function (workerThread) {
|
|
workerThread.worker.terminate();
|
|
console.log("Worker terminated!");
|
|
});
|
|
_workerPool.length = 0;
|
|
if (_config.inputStream.type === "LiveStream") {
|
|
_camera_access2['default'].release();
|
|
_inputStream.clearEventHandlers();
|
|
}
|
|
},
|
|
pause: function pause() {
|
|
_stopped = true;
|
|
},
|
|
onDetected: function onDetected(callback) {
|
|
_events2['default'].subscribe("detected", callback);
|
|
},
|
|
offDetected: function offDetected(callback) {
|
|
_events2['default'].unsubscribe("detected", callback);
|
|
},
|
|
onProcessed: function onProcessed(callback) {
|
|
_events2['default'].subscribe("processed", callback);
|
|
},
|
|
offProcessed: function offProcessed(callback) {
|
|
_events2['default'].unsubscribe("processed", callback);
|
|
},
|
|
setReaders: function setReaders(readers) {
|
|
_setReaders(readers);
|
|
},
|
|
registerResultCollector: function registerResultCollector(resultCollector) {
|
|
if (resultCollector && typeof resultCollector.addResult === 'function') {
|
|
_resultCollector = resultCollector;
|
|
}
|
|
},
|
|
canvas: _canvasContainer,
|
|
decodeSingle: function decodeSingle(config, resultCallback) {
|
|
config = merge({
|
|
inputStream: {
|
|
type: "ImageStream",
|
|
sequence: false,
|
|
size: 800,
|
|
src: config.src
|
|
},
|
|
numOfWorkers: 1,
|
|
locator: {
|
|
halfSample: false
|
|
}
|
|
}, config);
|
|
this.init(config, function () {
|
|
_events2['default'].once("processed", function (result) {
|
|
_stopped = true;
|
|
resultCallback.call(null, result);
|
|
}, true);
|
|
_start();
|
|
});
|
|
},
|
|
ImageWrapper: _image_wrapper2['default'],
|
|
ImageDebug: _image_debug2['default'],
|
|
ResultCollector: _result_collector2['default']
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports) {
|
|
|
|
/*
|
|
* typedefs.js
|
|
* Normalizes browser-specific prefixes
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
if (typeof window !== 'undefined') {
|
|
window.requestAnimFrame = (function () {
|
|
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function ( /* function FrameRequestCallback */callback) {
|
|
window.setTimeout(callback, 1000 / 60);
|
|
};
|
|
})();
|
|
|
|
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
|
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
|
|
}
|
|
Math.imul = Math.imul || function (a, b) {
|
|
var ah = a >>> 16 & 0xffff,
|
|
al = a & 0xffff,
|
|
bh = b >>> 16 & 0xffff,
|
|
bl = b & 0xffff;
|
|
// the shift by 0 fixes the sign on the high part
|
|
// the final |0 converts the unsigned value into a signed value
|
|
return al * bl + (ah * bl + al * bh << 16 >>> 0) | 0;
|
|
};
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _subImage = __webpack_require__(4);
|
|
|
|
var _subImage2 = _interopRequireDefault(_subImage);
|
|
|
|
var _cv_utils = __webpack_require__(5);
|
|
|
|
var _cv_utils2 = _interopRequireDefault(_cv_utils);
|
|
|
|
var _array_helper = __webpack_require__(17);
|
|
|
|
var _array_helper2 = _interopRequireDefault(_array_helper);
|
|
|
|
var _glMatrix = __webpack_require__(7);
|
|
|
|
/**
|
|
* Represents a basic image combining the data and size.
|
|
* In addition, some methods for manipulation are contained.
|
|
* @param size {x,y} The size of the image in pixel
|
|
* @param data {Array} If given, a flat array containing the pixel data
|
|
* @param ArrayType {Type} If given, the desired DataType of the Array (may be typed/non-typed)
|
|
* @param initialize {Boolean} Indicating if the array should be initialized on creation.
|
|
* @returns {ImageWrapper}
|
|
*/
|
|
function ImageWrapper(size, data, ArrayType, initialize) {
|
|
if (!data) {
|
|
if (ArrayType) {
|
|
this.data = new ArrayType(size.x * size.y);
|
|
if (ArrayType === Array && initialize) {
|
|
_array_helper2['default'].init(this.data, 0);
|
|
}
|
|
} else {
|
|
this.data = new Uint8Array(size.x * size.y);
|
|
if (Uint8Array === Array && initialize) {
|
|
_array_helper2['default'].init(this.data, 0);
|
|
}
|
|
}
|
|
} else {
|
|
this.data = data;
|
|
}
|
|
this.size = size;
|
|
}
|
|
|
|
/**
|
|
* tests if a position is within the image with a given offset
|
|
* @param imgRef {x, y} The location to test
|
|
* @param border Number the padding value in pixel
|
|
* @returns {Boolean} true if location inside the image's border, false otherwise
|
|
* @see cvd/image.h
|
|
*/
|
|
ImageWrapper.prototype.inImageWithBorder = function (imgRef, border) {
|
|
return imgRef.x >= border && imgRef.y >= border && imgRef.x < this.size.x - border && imgRef.y < this.size.y - border;
|
|
};
|
|
|
|
/**
|
|
* Performs bilinear sampling
|
|
* @param inImg Image to extract sample from
|
|
* @param x the x-coordinate
|
|
* @param y the y-coordinate
|
|
* @returns the sampled value
|
|
* @see cvd/vision.h
|
|
*/
|
|
ImageWrapper.sample = function (inImg, x, y) {
|
|
var lx = Math.floor(x);
|
|
var ly = Math.floor(y);
|
|
var w = inImg.size.x;
|
|
var base = ly * inImg.size.x + lx;
|
|
var a = inImg.data[base + 0];
|
|
var b = inImg.data[base + 1];
|
|
var c = inImg.data[base + w];
|
|
var d = inImg.data[base + w + 1];
|
|
var e = a - b;
|
|
x -= lx;
|
|
y -= ly;
|
|
|
|
var result = Math.floor(x * (y * (e - c + d) - e) + y * (c - a) + a);
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Initializes a given array. Sets each element to zero.
|
|
* @param array {Array} The array to initialize
|
|
*/
|
|
ImageWrapper.clearArray = function (array) {
|
|
var l = array.length;
|
|
while (l--) {
|
|
array[l] = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Creates a {SubImage} from the current image ({this}).
|
|
* @param from {ImageRef} The position where to start the {SubImage} from. (top-left corner)
|
|
* @param size {ImageRef} The size of the resulting image
|
|
* @returns {SubImage} A shared part of the original image
|
|
*/
|
|
ImageWrapper.prototype.subImage = function (from, size) {
|
|
return new _subImage2['default'](from, size, this);
|
|
};
|
|
|
|
/**
|
|
* Creates an {ImageWrapper) and copies the needed underlying image-data area
|
|
* @param imageWrapper {ImageWrapper} The target {ImageWrapper} where the data should be copied
|
|
* @param from {ImageRef} The location where to copy from (top-left location)
|
|
*/
|
|
ImageWrapper.prototype.subImageAsCopy = function (imageWrapper, from) {
|
|
var sizeY = imageWrapper.size.y,
|
|
sizeX = imageWrapper.size.x;
|
|
var x, y;
|
|
for (x = 0; x < sizeX; x++) {
|
|
for (y = 0; y < sizeY; y++) {
|
|
imageWrapper.data[y * sizeX + x] = this.data[(from.y + y) * this.size.x + from.x + x];
|
|
}
|
|
}
|
|
};
|
|
|
|
ImageWrapper.prototype.copyTo = function (imageWrapper) {
|
|
var length = this.data.length,
|
|
srcData = this.data,
|
|
dstData = imageWrapper.data;
|
|
|
|
while (length--) {
|
|
dstData[length] = srcData[length];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Retrieves a given pixel position from the image
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @returns {Number} The grayscale value at the pixel-position
|
|
*/
|
|
ImageWrapper.prototype.get = function (x, y) {
|
|
return this.data[y * this.size.x + x];
|
|
};
|
|
|
|
/**
|
|
* Retrieves a given pixel position from the image
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @returns {Number} The grayscale value at the pixel-position
|
|
*/
|
|
ImageWrapper.prototype.getSafe = function (x, y) {
|
|
var i;
|
|
|
|
if (!this.indexMapping) {
|
|
this.indexMapping = {
|
|
x: [],
|
|
y: []
|
|
};
|
|
for (i = 0; i < this.size.x; i++) {
|
|
this.indexMapping.x[i] = i;
|
|
this.indexMapping.x[i + this.size.x] = i;
|
|
}
|
|
for (i = 0; i < this.size.y; i++) {
|
|
this.indexMapping.y[i] = i;
|
|
this.indexMapping.y[i + this.size.y] = i;
|
|
}
|
|
}
|
|
return this.data[this.indexMapping.y[y + this.size.y] * this.size.x + this.indexMapping.x[x + this.size.x]];
|
|
};
|
|
|
|
/**
|
|
* Sets a given pixel position in the image
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @param value {Number} The grayscale value to set
|
|
* @returns {ImageWrapper} The Image itself (for possible chaining)
|
|
*/
|
|
ImageWrapper.prototype.set = function (x, y, value) {
|
|
this.data[y * this.size.x + x] = value;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Sets the border of the image (1 pixel) to zero
|
|
*/
|
|
ImageWrapper.prototype.zeroBorder = function () {
|
|
var i,
|
|
width = this.size.x,
|
|
height = this.size.y,
|
|
data = this.data;
|
|
for (i = 0; i < width; i++) {
|
|
data[i] = data[(height - 1) * width + i] = 0;
|
|
}
|
|
for (i = 1; i < height - 1; i++) {
|
|
data[i * width] = data[i * width + (width - 1)] = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Inverts a binary image in place
|
|
*/
|
|
ImageWrapper.prototype.invert = function () {
|
|
var data = this.data,
|
|
length = data.length;
|
|
|
|
while (length--) {
|
|
data[length] = data[length] ? 0 : 1;
|
|
}
|
|
};
|
|
|
|
ImageWrapper.prototype.convolve = function (kernel) {
|
|
var x,
|
|
y,
|
|
kx,
|
|
ky,
|
|
kSize = kernel.length / 2 | 0,
|
|
accu = 0;
|
|
for (y = 0; y < this.size.y; y++) {
|
|
for (x = 0; x < this.size.x; x++) {
|
|
accu = 0;
|
|
for (ky = -kSize; ky <= kSize; ky++) {
|
|
for (kx = -kSize; kx <= kSize; kx++) {
|
|
accu += kernel[ky + kSize][kx + kSize] * this.getSafe(x + kx, y + ky);
|
|
}
|
|
}
|
|
this.data[y * this.size.x + x] = accu;
|
|
}
|
|
}
|
|
};
|
|
|
|
ImageWrapper.prototype.moments = function (labelcount) {
|
|
var data = this.data,
|
|
x,
|
|
y,
|
|
height = this.size.y,
|
|
width = this.size.x,
|
|
val,
|
|
ysq,
|
|
labelsum = [],
|
|
i,
|
|
label,
|
|
mu11,
|
|
mu02,
|
|
mu20,
|
|
x_,
|
|
y_,
|
|
tmp,
|
|
result = [],
|
|
PI = Math.PI,
|
|
PI_4 = PI / 4;
|
|
|
|
if (labelcount <= 0) {
|
|
return result;
|
|
}
|
|
|
|
for (i = 0; i < labelcount; i++) {
|
|
labelsum[i] = {
|
|
m00: 0,
|
|
m01: 0,
|
|
m10: 0,
|
|
m11: 0,
|
|
m02: 0,
|
|
m20: 0,
|
|
theta: 0,
|
|
rad: 0
|
|
};
|
|
}
|
|
|
|
for (y = 0; y < height; y++) {
|
|
ysq = y * y;
|
|
for (x = 0; x < width; x++) {
|
|
val = data[y * width + x];
|
|
if (val > 0) {
|
|
label = labelsum[val - 1];
|
|
label.m00 += 1;
|
|
label.m01 += y;
|
|
label.m10 += x;
|
|
label.m11 += x * y;
|
|
label.m02 += ysq;
|
|
label.m20 += x * x;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < labelcount; i++) {
|
|
label = labelsum[i];
|
|
if (!isNaN(label.m00) && label.m00 !== 0) {
|
|
x_ = label.m10 / label.m00;
|
|
y_ = label.m01 / label.m00;
|
|
mu11 = label.m11 / label.m00 - x_ * y_;
|
|
mu02 = label.m02 / label.m00 - y_ * y_;
|
|
mu20 = label.m20 / label.m00 - x_ * x_;
|
|
tmp = (mu02 - mu20) / (2 * mu11);
|
|
tmp = 0.5 * Math.atan(tmp) + (mu11 >= 0 ? PI_4 : -PI_4) + PI;
|
|
label.theta = (tmp * 180 / PI + 90) % 180 - 90;
|
|
if (label.theta < 0) {
|
|
label.theta += 180;
|
|
}
|
|
label.rad = tmp > PI ? tmp - PI : tmp;
|
|
label.vec = _glMatrix.vec2.clone([Math.cos(tmp), Math.sin(tmp)]);
|
|
result.push(label);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Displays the {ImageWrapper} in a given canvas
|
|
* @param canvas {Canvas} The canvas element to write to
|
|
* @param scale {Number} Scale which is applied to each pixel-value
|
|
*/
|
|
ImageWrapper.prototype.show = function (canvas, scale) {
|
|
var ctx, frame, data, current, pixel, x, y;
|
|
|
|
if (!scale) {
|
|
scale = 1.0;
|
|
}
|
|
ctx = canvas.getContext('2d');
|
|
canvas.width = this.size.x;
|
|
canvas.height = this.size.y;
|
|
frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
data = frame.data;
|
|
current = 0;
|
|
for (y = 0; y < this.size.y; y++) {
|
|
for (x = 0; x < this.size.x; x++) {
|
|
pixel = y * this.size.x + x;
|
|
current = this.get(x, y) * scale;
|
|
data[pixel * 4 + 0] = current;
|
|
data[pixel * 4 + 1] = current;
|
|
data[pixel * 4 + 2] = current;
|
|
data[pixel * 4 + 3] = 255;
|
|
}
|
|
}
|
|
//frame.data = data;
|
|
ctx.putImageData(frame, 0, 0);
|
|
};
|
|
|
|
/**
|
|
* Displays the {SubImage} in a given canvas
|
|
* @param canvas {Canvas} The canvas element to write to
|
|
* @param scale {Number} Scale which is applied to each pixel-value
|
|
*/
|
|
ImageWrapper.prototype.overlay = function (canvas, scale, from) {
|
|
if (!scale || scale < 0 || scale > 360) {
|
|
scale = 360;
|
|
}
|
|
var hsv = [0, 1, 1];
|
|
var rgb = [0, 0, 0];
|
|
var whiteRgb = [255, 255, 255];
|
|
var blackRgb = [0, 0, 0];
|
|
var result = [];
|
|
var ctx = canvas.getContext('2d');
|
|
var frame = ctx.getImageData(from.x, from.y, this.size.x, this.size.y);
|
|
var data = frame.data;
|
|
var length = this.data.length;
|
|
while (length--) {
|
|
hsv[0] = this.data[length] * scale;
|
|
result = hsv[0] <= 0 ? whiteRgb : hsv[0] >= 360 ? blackRgb : _cv_utils2['default'].hsv2rgb(hsv, rgb);
|
|
data[length * 4 + 0] = result[0];
|
|
data[length * 4 + 1] = result[1];
|
|
data[length * 4 + 2] = result[2];
|
|
data[length * 4 + 3] = 255;
|
|
}
|
|
ctx.putImageData(frame, from.x, from.y);
|
|
};
|
|
|
|
exports['default'] = ImageWrapper;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* Construct representing a part of another {ImageWrapper}. Shares data
|
|
* between the parent and the child.
|
|
* @param from {ImageRef} The position where to start the {SubImage} from. (top-left corner)
|
|
* @param size {ImageRef} The size of the resulting image
|
|
* @param I {ImageWrapper} The {ImageWrapper} to share from
|
|
* @returns {SubImage} A shared part of the original image
|
|
*/
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
function SubImage(from, size, I) {
|
|
if (!I) {
|
|
I = {
|
|
data: null,
|
|
size: size
|
|
};
|
|
}
|
|
this.data = I.data;
|
|
this.originalSize = I.size;
|
|
this.I = I;
|
|
|
|
this.from = from;
|
|
this.size = size;
|
|
}
|
|
|
|
/**
|
|
* Displays the {SubImage} in a given canvas
|
|
* @param canvas {Canvas} The canvas element to write to
|
|
* @param scale {Number} Scale which is applied to each pixel-value
|
|
*/
|
|
SubImage.prototype.show = function (canvas, scale) {
|
|
var ctx, frame, data, current, y, x, pixel;
|
|
|
|
if (!scale) {
|
|
scale = 1.0;
|
|
}
|
|
ctx = canvas.getContext('2d');
|
|
canvas.width = this.size.x;
|
|
canvas.height = this.size.y;
|
|
frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
data = frame.data;
|
|
current = 0;
|
|
for (y = 0; y < this.size.y; y++) {
|
|
for (x = 0; x < this.size.x; x++) {
|
|
pixel = y * this.size.x + x;
|
|
current = this.get(x, y) * scale;
|
|
data[pixel * 4 + 0] = current;
|
|
data[pixel * 4 + 1] = current;
|
|
data[pixel * 4 + 2] = current;
|
|
data[pixel * 4 + 3] = 255;
|
|
}
|
|
}
|
|
frame.data = data;
|
|
ctx.putImageData(frame, 0, 0);
|
|
};
|
|
|
|
/**
|
|
* Retrieves a given pixel position from the {SubImage}
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @returns {Number} The grayscale value at the pixel-position
|
|
*/
|
|
SubImage.prototype.get = function (x, y) {
|
|
return this.data[(this.from.y + y) * this.originalSize.x + this.from.x + x];
|
|
};
|
|
|
|
/**
|
|
* Updates the underlying data from a given {ImageWrapper}
|
|
* @param image {ImageWrapper} The updated image
|
|
*/
|
|
SubImage.prototype.updateData = function (image) {
|
|
this.originalSize = image.size;
|
|
this.data = image.data;
|
|
};
|
|
|
|
/**
|
|
* Updates the position of the shared area
|
|
* @param from {x,y} The new location
|
|
* @returns {SubImage} returns {this} for possible chaining
|
|
*/
|
|
SubImage.prototype.updateFrom = function (from) {
|
|
this.from = from;
|
|
return this;
|
|
};
|
|
|
|
exports['default'] = SubImage;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _cluster = __webpack_require__(6);
|
|
|
|
var _cluster2 = _interopRequireDefault(_cluster);
|
|
|
|
var _array_helper = __webpack_require__(17);
|
|
|
|
var _array_helper2 = _interopRequireDefault(_array_helper);
|
|
|
|
var _glMatrix = __webpack_require__(7);
|
|
|
|
var CVUtils = {};
|
|
|
|
/**
|
|
* @param x x-coordinate
|
|
* @param y y-coordinate
|
|
* @return ImageReference {x,y} Coordinate
|
|
*/
|
|
CVUtils.imageRef = function (x, y) {
|
|
var that = {
|
|
x: x,
|
|
y: y,
|
|
toVec2: function toVec2() {
|
|
return _glMatrix.vec2.clone([this.x, this.y]);
|
|
},
|
|
toVec3: function toVec3() {
|
|
return _glMatrix.vec3.clone([this.x, this.y, 1]);
|
|
},
|
|
round: function round() {
|
|
this.x = this.x > 0.0 ? Math.floor(this.x + 0.5) : Math.floor(this.x - 0.5);
|
|
this.y = this.y > 0.0 ? Math.floor(this.y + 0.5) : Math.floor(this.y - 0.5);
|
|
return this;
|
|
}
|
|
};
|
|
return that;
|
|
};
|
|
|
|
/**
|
|
* Computes an integral image of a given grayscale image.
|
|
* @param imageDataContainer {ImageDataContainer} the image to be integrated
|
|
*/
|
|
CVUtils.computeIntegralImage2 = function (imageWrapper, integralWrapper) {
|
|
var imageData = imageWrapper.data;
|
|
var width = imageWrapper.size.x;
|
|
var height = imageWrapper.size.y;
|
|
var integralImageData = integralWrapper.data;
|
|
var sum = 0,
|
|
posA = 0,
|
|
posB = 0,
|
|
posC = 0,
|
|
posD = 0,
|
|
x,
|
|
y;
|
|
|
|
// sum up first column
|
|
posB = width;
|
|
sum = 0;
|
|
for (y = 1; y < height; y++) {
|
|
sum += imageData[posA];
|
|
integralImageData[posB] += sum;
|
|
posA += width;
|
|
posB += width;
|
|
}
|
|
|
|
posA = 0;
|
|
posB = 1;
|
|
sum = 0;
|
|
for (x = 1; x < width; x++) {
|
|
sum += imageData[posA];
|
|
integralImageData[posB] += sum;
|
|
posA++;
|
|
posB++;
|
|
}
|
|
|
|
for (y = 1; y < height; y++) {
|
|
posA = y * width + 1;
|
|
posB = (y - 1) * width + 1;
|
|
posC = y * width;
|
|
posD = (y - 1) * width;
|
|
for (x = 1; x < width; x++) {
|
|
integralImageData[posA] += imageData[posA] + integralImageData[posB] + integralImageData[posC] - integralImageData[posD];
|
|
posA++;
|
|
posB++;
|
|
posC++;
|
|
posD++;
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.computeIntegralImage = function (imageWrapper, integralWrapper) {
|
|
var imageData = imageWrapper.data;
|
|
var width = imageWrapper.size.x;
|
|
var height = imageWrapper.size.y;
|
|
var integralImageData = integralWrapper.data;
|
|
var sum = 0;
|
|
|
|
// sum up first row
|
|
for (var i = 0; i < width; i++) {
|
|
sum += imageData[i];
|
|
integralImageData[i] = sum;
|
|
}
|
|
|
|
for (var v = 1; v < height; v++) {
|
|
sum = 0;
|
|
for (var u = 0; u < width; u++) {
|
|
sum += imageData[v * width + u];
|
|
integralImageData[v * width + u] = sum + integralImageData[(v - 1) * width + u];
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.thresholdImage = function (imageWrapper, threshold, targetWrapper) {
|
|
if (!targetWrapper) {
|
|
targetWrapper = imageWrapper;
|
|
}
|
|
var imageData = imageWrapper.data,
|
|
length = imageData.length,
|
|
targetData = targetWrapper.data;
|
|
|
|
while (length--) {
|
|
targetData[length] = imageData[length] < threshold ? 1 : 0;
|
|
}
|
|
};
|
|
|
|
CVUtils.computeHistogram = function (imageWrapper, bitsPerPixel) {
|
|
if (!bitsPerPixel) {
|
|
bitsPerPixel = 8;
|
|
}
|
|
var imageData = imageWrapper.data,
|
|
length = imageData.length,
|
|
bitShift = 8 - bitsPerPixel,
|
|
bucketCnt = 1 << bitsPerPixel,
|
|
hist = new Int32Array(bucketCnt);
|
|
|
|
while (length--) {
|
|
hist[imageData[length] >> bitShift]++;
|
|
}
|
|
return hist;
|
|
};
|
|
|
|
CVUtils.sharpenLine = function (line) {
|
|
var i,
|
|
length = line.length,
|
|
left = line[0],
|
|
center = line[1],
|
|
right;
|
|
|
|
for (i = 1; i < length - 1; i++) {
|
|
right = line[i + 1];
|
|
// -1 4 -1 kernel
|
|
line[i - 1] = center * 2 - left - right & 255;
|
|
left = center;
|
|
center = right;
|
|
}
|
|
return line;
|
|
};
|
|
|
|
CVUtils.determineOtsuThreshold = function (imageWrapper, bitsPerPixel) {
|
|
if (!bitsPerPixel) {
|
|
bitsPerPixel = 8;
|
|
}
|
|
var hist,
|
|
threshold,
|
|
bitShift = 8 - bitsPerPixel;
|
|
|
|
function px(init, end) {
|
|
var sum = 0,
|
|
i;
|
|
for (i = init; i <= end; i++) {
|
|
sum += hist[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
function mx(init, end) {
|
|
var i,
|
|
sum = 0;
|
|
|
|
for (i = init; i <= end; i++) {
|
|
sum += i * hist[i];
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
function determineThreshold() {
|
|
var vet = [0],
|
|
p1,
|
|
p2,
|
|
p12,
|
|
k,
|
|
m1,
|
|
m2,
|
|
m12,
|
|
max = (1 << bitsPerPixel) - 1;
|
|
|
|
hist = CVUtils.computeHistogram(imageWrapper, bitsPerPixel);
|
|
for (k = 1; k < max; k++) {
|
|
p1 = px(0, k);
|
|
p2 = px(k + 1, max);
|
|
p12 = p1 * p2;
|
|
if (p12 === 0) {
|
|
p12 = 1;
|
|
}
|
|
m1 = mx(0, k) * p2;
|
|
m2 = mx(k + 1, max) * p1;
|
|
m12 = m1 - m2;
|
|
vet[k] = m12 * m12 / p12;
|
|
}
|
|
return _array_helper2['default'].maxIndex(vet);
|
|
}
|
|
|
|
threshold = determineThreshold();
|
|
return threshold << bitShift;
|
|
};
|
|
|
|
CVUtils.otsuThreshold = function (imageWrapper, targetWrapper) {
|
|
var threshold = CVUtils.determineOtsuThreshold(imageWrapper);
|
|
|
|
CVUtils.thresholdImage(imageWrapper, threshold, targetWrapper);
|
|
return threshold;
|
|
};
|
|
|
|
// local thresholding
|
|
CVUtils.computeBinaryImage = function (imageWrapper, integralWrapper, targetWrapper) {
|
|
CVUtils.computeIntegralImage(imageWrapper, integralWrapper);
|
|
|
|
if (!targetWrapper) {
|
|
targetWrapper = imageWrapper;
|
|
}
|
|
var imageData = imageWrapper.data;
|
|
var targetData = targetWrapper.data;
|
|
var width = imageWrapper.size.x;
|
|
var height = imageWrapper.size.y;
|
|
var integralImageData = integralWrapper.data;
|
|
var sum = 0,
|
|
v,
|
|
u,
|
|
kernel = 3,
|
|
A,
|
|
B,
|
|
C,
|
|
D,
|
|
avg,
|
|
size = (kernel * 2 + 1) * (kernel * 2 + 1);
|
|
|
|
// clear out top & bottom-border
|
|
for (v = 0; v <= kernel; v++) {
|
|
for (u = 0; u < width; u++) {
|
|
targetData[v * width + u] = 0;
|
|
targetData[(height - 1 - v) * width + u] = 0;
|
|
}
|
|
}
|
|
|
|
// clear out left & right border
|
|
for (v = kernel; v < height - kernel; v++) {
|
|
for (u = 0; u <= kernel; u++) {
|
|
targetData[v * width + u] = 0;
|
|
targetData[v * width + (width - 1 - u)] = 0;
|
|
}
|
|
}
|
|
|
|
for (v = kernel + 1; v < height - kernel - 1; v++) {
|
|
for (u = kernel + 1; u < width - kernel; u++) {
|
|
A = integralImageData[(v - kernel - 1) * width + (u - kernel - 1)];
|
|
B = integralImageData[(v - kernel - 1) * width + (u + kernel)];
|
|
C = integralImageData[(v + kernel) * width + (u - kernel - 1)];
|
|
D = integralImageData[(v + kernel) * width + (u + kernel)];
|
|
sum = D - C - B + A;
|
|
avg = sum / size;
|
|
targetData[v * width + u] = imageData[v * width + u] > avg + 5 ? 0 : 1;
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.cluster = function (points, threshold, property) {
|
|
var i,
|
|
k,
|
|
cluster,
|
|
point,
|
|
clusters = [];
|
|
|
|
if (!property) {
|
|
property = "rad";
|
|
}
|
|
|
|
function addToCluster(newPoint) {
|
|
var found = false;
|
|
for (k = 0; k < clusters.length; k++) {
|
|
cluster = clusters[k];
|
|
if (cluster.fits(newPoint)) {
|
|
cluster.add(newPoint);
|
|
found = true;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
// iterate over each cloud
|
|
for (i = 0; i < points.length; i++) {
|
|
point = _cluster2['default'].createPoint(points[i], i, property);
|
|
if (!addToCluster(point)) {
|
|
clusters.push(_cluster2['default'].create(point, threshold));
|
|
}
|
|
}
|
|
return clusters;
|
|
};
|
|
|
|
CVUtils.Tracer = {
|
|
trace: function trace(points, vec) {
|
|
var iteration,
|
|
maxIterations = 10,
|
|
top = [],
|
|
result = [],
|
|
centerPos = 0,
|
|
currentPos = 0;
|
|
|
|
function trace(idx, forward) {
|
|
var from,
|
|
to,
|
|
toIdx,
|
|
predictedPos,
|
|
thresholdX = 1,
|
|
thresholdY = Math.abs(vec[1] / 10),
|
|
found = false;
|
|
|
|
function match(pos, predicted) {
|
|
if (pos.x > predicted.x - thresholdX && pos.x < predicted.x + thresholdX && pos.y > predicted.y - thresholdY && pos.y < predicted.y + thresholdY) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// check if the next index is within the vec specifications
|
|
// if not, check as long as the threshold is met
|
|
|
|
from = points[idx];
|
|
if (forward) {
|
|
predictedPos = {
|
|
x: from.x + vec[0],
|
|
y: from.y + vec[1]
|
|
};
|
|
} else {
|
|
predictedPos = {
|
|
x: from.x - vec[0],
|
|
y: from.y - vec[1]
|
|
};
|
|
}
|
|
|
|
toIdx = forward ? idx + 1 : idx - 1;
|
|
to = points[toIdx];
|
|
while (to && (found = match(to, predictedPos)) !== true && Math.abs(to.y - from.y) < vec[1]) {
|
|
toIdx = forward ? toIdx + 1 : toIdx - 1;
|
|
to = points[toIdx];
|
|
}
|
|
|
|
return found ? toIdx : null;
|
|
}
|
|
|
|
for (iteration = 0; iteration < maxIterations; iteration++) {
|
|
// randomly select point to start with
|
|
centerPos = Math.floor(Math.random() * points.length);
|
|
|
|
// trace forward
|
|
top = [];
|
|
currentPos = centerPos;
|
|
top.push(points[currentPos]);
|
|
while ((currentPos = trace(currentPos, true)) !== null) {
|
|
top.push(points[currentPos]);
|
|
}
|
|
if (centerPos > 0) {
|
|
currentPos = centerPos;
|
|
while ((currentPos = trace(currentPos, false)) !== null) {
|
|
top.push(points[currentPos]);
|
|
}
|
|
}
|
|
|
|
if (top.length > result.length) {
|
|
result = top;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
|
|
CVUtils.DILATE = 1;
|
|
CVUtils.ERODE = 2;
|
|
|
|
CVUtils.dilate = function (inImageWrapper, outImageWrapper) {
|
|
var v,
|
|
u,
|
|
inImageData = inImageWrapper.data,
|
|
outImageData = outImageWrapper.data,
|
|
height = inImageWrapper.size.y,
|
|
width = inImageWrapper.size.x,
|
|
sum,
|
|
yStart1,
|
|
yStart2,
|
|
xStart1,
|
|
xStart2;
|
|
|
|
for (v = 1; v < height - 1; v++) {
|
|
for (u = 1; u < width - 1; u++) {
|
|
yStart1 = v - 1;
|
|
yStart2 = v + 1;
|
|
xStart1 = u - 1;
|
|
xStart2 = u + 1;
|
|
sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] + inImageData[v * width + u] + inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2];
|
|
outImageData[v * width + u] = sum > 0 ? 1 : 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.erode = function (inImageWrapper, outImageWrapper) {
|
|
var v,
|
|
u,
|
|
inImageData = inImageWrapper.data,
|
|
outImageData = outImageWrapper.data,
|
|
height = inImageWrapper.size.y,
|
|
width = inImageWrapper.size.x,
|
|
sum,
|
|
yStart1,
|
|
yStart2,
|
|
xStart1,
|
|
xStart2;
|
|
|
|
for (v = 1; v < height - 1; v++) {
|
|
for (u = 1; u < width - 1; u++) {
|
|
yStart1 = v - 1;
|
|
yStart2 = v + 1;
|
|
xStart1 = u - 1;
|
|
xStart2 = u + 1;
|
|
sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] + inImageData[v * width + u] + inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2];
|
|
outImageData[v * width + u] = sum === 5 ? 1 : 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.subtract = function (aImageWrapper, bImageWrapper, resultImageWrapper) {
|
|
if (!resultImageWrapper) {
|
|
resultImageWrapper = aImageWrapper;
|
|
}
|
|
var length = aImageWrapper.data.length,
|
|
aImageData = aImageWrapper.data,
|
|
bImageData = bImageWrapper.data,
|
|
cImageData = resultImageWrapper.data;
|
|
|
|
while (length--) {
|
|
cImageData[length] = aImageData[length] - bImageData[length];
|
|
}
|
|
};
|
|
|
|
CVUtils.bitwiseOr = function (aImageWrapper, bImageWrapper, resultImageWrapper) {
|
|
if (!resultImageWrapper) {
|
|
resultImageWrapper = aImageWrapper;
|
|
}
|
|
var length = aImageWrapper.data.length,
|
|
aImageData = aImageWrapper.data,
|
|
bImageData = bImageWrapper.data,
|
|
cImageData = resultImageWrapper.data;
|
|
|
|
while (length--) {
|
|
cImageData[length] = aImageData[length] || bImageData[length];
|
|
}
|
|
};
|
|
|
|
CVUtils.countNonZero = function (imageWrapper) {
|
|
var length = imageWrapper.data.length,
|
|
data = imageWrapper.data,
|
|
sum = 0;
|
|
|
|
while (length--) {
|
|
sum += data[length];
|
|
}
|
|
return sum;
|
|
};
|
|
|
|
CVUtils.topGeneric = function (list, top, scoreFunc) {
|
|
var i,
|
|
minIdx = 0,
|
|
min = 0,
|
|
queue = [],
|
|
score,
|
|
hit,
|
|
pos;
|
|
|
|
for (i = 0; i < top; i++) {
|
|
queue[i] = {
|
|
score: 0,
|
|
item: null
|
|
};
|
|
}
|
|
|
|
for (i = 0; i < list.length; i++) {
|
|
score = scoreFunc.apply(this, [list[i]]);
|
|
if (score > min) {
|
|
hit = queue[minIdx];
|
|
hit.score = score;
|
|
hit.item = list[i];
|
|
min = Number.MAX_VALUE;
|
|
for (pos = 0; pos < top; pos++) {
|
|
if (queue[pos].score < min) {
|
|
min = queue[pos].score;
|
|
minIdx = pos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return queue;
|
|
};
|
|
|
|
CVUtils.grayArrayFromImage = function (htmlImage, offsetX, ctx, array) {
|
|
ctx.drawImage(htmlImage, offsetX, 0, htmlImage.width, htmlImage.height);
|
|
var ctxData = ctx.getImageData(offsetX, 0, htmlImage.width, htmlImage.height).data;
|
|
CVUtils.computeGray(ctxData, array);
|
|
};
|
|
|
|
CVUtils.grayArrayFromContext = function (ctx, size, offset, array) {
|
|
var ctxData = ctx.getImageData(offset.x, offset.y, size.x, size.y).data;
|
|
CVUtils.computeGray(ctxData, array);
|
|
};
|
|
|
|
CVUtils.grayAndHalfSampleFromCanvasData = function (canvasData, size, outArray) {
|
|
var topRowIdx = 0;
|
|
var bottomRowIdx = size.x;
|
|
var endIdx = Math.floor(canvasData.length / 4);
|
|
var outWidth = size.x / 2;
|
|
var outImgIdx = 0;
|
|
var inWidth = size.x;
|
|
var i;
|
|
|
|
while (bottomRowIdx < endIdx) {
|
|
for (i = 0; i < outWidth; i++) {
|
|
outArray[outImgIdx] = Math.floor((0.299 * canvasData[topRowIdx * 4 + 0] + 0.587 * canvasData[topRowIdx * 4 + 1] + 0.114 * canvasData[topRowIdx * 4 + 2] + (0.299 * canvasData[(topRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(topRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(topRowIdx + 1) * 4 + 2]) + (0.299 * canvasData[bottomRowIdx * 4 + 0] + 0.587 * canvasData[bottomRowIdx * 4 + 1] + 0.114 * canvasData[bottomRowIdx * 4 + 2]) + (0.299 * canvasData[(bottomRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(bottomRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(bottomRowIdx + 1) * 4 + 2])) / 4);
|
|
outImgIdx++;
|
|
topRowIdx = topRowIdx + 2;
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
}
|
|
topRowIdx = topRowIdx + inWidth;
|
|
bottomRowIdx = bottomRowIdx + inWidth;
|
|
}
|
|
};
|
|
|
|
CVUtils.computeGray = function (imageData, outArray, config) {
|
|
var l = imageData.length / 4 | 0,
|
|
i,
|
|
singleChannel = config && config.singleChannel === true;
|
|
|
|
if (singleChannel) {
|
|
for (i = 0; i < l; i++) {
|
|
outArray[i] = imageData[i * 4 + 0];
|
|
}
|
|
} else {
|
|
for (i = 0; i < l; i++) {
|
|
outArray[i] = Math.floor(0.299 * imageData[i * 4 + 0] + 0.587 * imageData[i * 4 + 1] + 0.114 * imageData[i * 4 + 2]);
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.loadImageArray = function (src, callback, canvas) {
|
|
if (!canvas) {
|
|
canvas = document.createElement('canvas');
|
|
}
|
|
var img = new Image();
|
|
img.callback = callback;
|
|
img.onload = function () {
|
|
canvas.width = this.width;
|
|
canvas.height = this.height;
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.drawImage(this, 0, 0);
|
|
var array = new Uint8Array(this.width * this.height);
|
|
ctx.drawImage(this, 0, 0);
|
|
var data = ctx.getImageData(0, 0, this.width, this.height).data;
|
|
CVUtils.computeGray(data, array);
|
|
this.callback(array, {
|
|
x: this.width,
|
|
y: this.height
|
|
}, this);
|
|
};
|
|
img.src = src;
|
|
};
|
|
|
|
/**
|
|
* @param inImg {ImageWrapper} input image to be sampled
|
|
* @param outImg {ImageWrapper} to be stored in
|
|
*/
|
|
CVUtils.halfSample = function (inImgWrapper, outImgWrapper) {
|
|
var inImg = inImgWrapper.data;
|
|
var inWidth = inImgWrapper.size.x;
|
|
var outImg = outImgWrapper.data;
|
|
var topRowIdx = 0;
|
|
var bottomRowIdx = inWidth;
|
|
var endIdx = inImg.length;
|
|
var outWidth = inWidth / 2;
|
|
var outImgIdx = 0;
|
|
while (bottomRowIdx < endIdx) {
|
|
for (var i = 0; i < outWidth; i++) {
|
|
outImg[outImgIdx] = Math.floor((inImg[topRowIdx] + inImg[topRowIdx + 1] + inImg[bottomRowIdx] + inImg[bottomRowIdx + 1]) / 4);
|
|
outImgIdx++;
|
|
topRowIdx = topRowIdx + 2;
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
}
|
|
topRowIdx = topRowIdx + inWidth;
|
|
bottomRowIdx = bottomRowIdx + inWidth;
|
|
}
|
|
};
|
|
|
|
CVUtils.hsv2rgb = function (hsv, rgb) {
|
|
var h = hsv[0],
|
|
s = hsv[1],
|
|
v = hsv[2],
|
|
c = v * s,
|
|
x = c * (1 - Math.abs(h / 60 % 2 - 1)),
|
|
m = v - c,
|
|
r = 0,
|
|
g = 0,
|
|
b = 0;
|
|
|
|
rgb = rgb || [0, 0, 0];
|
|
|
|
if (h < 60) {
|
|
r = c;
|
|
g = x;
|
|
} else if (h < 120) {
|
|
r = x;
|
|
g = c;
|
|
} else if (h < 180) {
|
|
g = c;
|
|
b = x;
|
|
} else if (h < 240) {
|
|
g = x;
|
|
b = c;
|
|
} else if (h < 300) {
|
|
r = x;
|
|
b = c;
|
|
} else if (h < 360) {
|
|
r = c;
|
|
b = x;
|
|
}
|
|
rgb[0] = (r + m) * 255 | 0;
|
|
rgb[1] = (g + m) * 255 | 0;
|
|
rgb[2] = (b + m) * 255 | 0;
|
|
return rgb;
|
|
};
|
|
|
|
CVUtils._computeDivisors = function (n) {
|
|
var largeDivisors = [],
|
|
divisors = [],
|
|
i;
|
|
|
|
for (i = 1; i < Math.sqrt(n) + 1; i++) {
|
|
if (n % i === 0) {
|
|
divisors.push(i);
|
|
if (i !== n / i) {
|
|
largeDivisors.unshift(Math.floor(n / i));
|
|
}
|
|
}
|
|
}
|
|
return divisors.concat(largeDivisors);
|
|
};
|
|
|
|
CVUtils._computeIntersection = function (arr1, arr2) {
|
|
var i = 0,
|
|
j = 0,
|
|
result = [];
|
|
|
|
while (i < arr1.length && j < arr2.length) {
|
|
if (arr1[i] === arr2[j]) {
|
|
result.push(arr1[i]);
|
|
i++;
|
|
j++;
|
|
} else if (arr1[i] > arr2[j]) {
|
|
j++;
|
|
} else {
|
|
i++;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
CVUtils.calculatePatchSize = function (patchSize, imgSize) {
|
|
var divisorsX = this._computeDivisors(imgSize.x),
|
|
divisorsY = this._computeDivisors(imgSize.y),
|
|
wideSide = Math.max(imgSize.x, imgSize.y),
|
|
common = this._computeIntersection(divisorsX, divisorsY),
|
|
nrOfPatchesList = [8, 10, 15, 20, 32, 60, 80],
|
|
nrOfPatchesMap = {
|
|
"x-small": 5,
|
|
"small": 4,
|
|
"medium": 3,
|
|
"large": 2,
|
|
"x-large": 1
|
|
},
|
|
nrOfPatchesIdx = nrOfPatchesMap[patchSize] || nrOfPatchesMap.medium,
|
|
nrOfPatches = nrOfPatchesList[nrOfPatchesIdx],
|
|
desiredPatchSize = Math.floor(wideSide / nrOfPatches),
|
|
optimalPatchSize;
|
|
|
|
function findPatchSizeForDivisors(divisors) {
|
|
var i = 0,
|
|
found = divisors[Math.floor(divisors.length / 2)];
|
|
|
|
while (i < divisors.length - 1 && divisors[i] < desiredPatchSize) {
|
|
i++;
|
|
}
|
|
if (i > 0) {
|
|
if (Math.abs(divisors[i] - desiredPatchSize) > Math.abs(divisors[i - 1] - desiredPatchSize)) {
|
|
found = divisors[i - 1];
|
|
} else {
|
|
found = divisors[i];
|
|
}
|
|
}
|
|
if (desiredPatchSize / found < nrOfPatchesList[nrOfPatchesIdx + 1] / nrOfPatchesList[nrOfPatchesIdx] && desiredPatchSize / found > nrOfPatchesList[nrOfPatchesIdx - 1] / nrOfPatchesList[nrOfPatchesIdx]) {
|
|
return { x: found, y: found };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
optimalPatchSize = findPatchSizeForDivisors(common);
|
|
if (!optimalPatchSize) {
|
|
optimalPatchSize = findPatchSizeForDivisors(this._computeDivisors(wideSide));
|
|
if (!optimalPatchSize) {
|
|
optimalPatchSize = findPatchSizeForDivisors(this._computeDivisors(desiredPatchSize * nrOfPatches));
|
|
}
|
|
}
|
|
return optimalPatchSize;
|
|
};
|
|
|
|
CVUtils._parseCSSDimensionValues = function (value) {
|
|
var dimension = {
|
|
value: parseFloat(value),
|
|
unit: value.indexOf("%") === value.length - 1 ? "%" : "%"
|
|
};
|
|
|
|
return dimension;
|
|
};
|
|
|
|
CVUtils._dimensionsConverters = {
|
|
top: function top(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.height * (dimension.value / 100));
|
|
}
|
|
},
|
|
right: function right(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.width - context.width * (dimension.value / 100));
|
|
}
|
|
},
|
|
bottom: function bottom(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.height - context.height * (dimension.value / 100));
|
|
}
|
|
},
|
|
left: function left(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.width * (dimension.value / 100));
|
|
}
|
|
}
|
|
};
|
|
|
|
CVUtils.computeImageArea = function (inputWidth, inputHeight, area) {
|
|
var context = { width: inputWidth, height: inputHeight };
|
|
|
|
var parsedArea = Object.keys(area).reduce(function (result, key) {
|
|
var value = area[key],
|
|
parsed = CVUtils._parseCSSDimensionValues(value),
|
|
calculated = CVUtils._dimensionsConverters[key](parsed, context);
|
|
|
|
result[key] = calculated;
|
|
return result;
|
|
}, {});
|
|
|
|
return {
|
|
sx: parsedArea.left,
|
|
sy: parsedArea.top,
|
|
sw: parsedArea.right - parsedArea.left,
|
|
sh: parsedArea.bottom - parsedArea.top
|
|
};
|
|
};
|
|
|
|
exports['default'] = CVUtils;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _glMatrix = __webpack_require__(7);
|
|
|
|
/**
|
|
* Creates a cluster for grouping similar orientations of datapoints
|
|
*/
|
|
exports['default'] = {
|
|
create: function create(point, threshold) {
|
|
var points = [],
|
|
center = {
|
|
rad: 0,
|
|
vec: _glMatrix.vec2.clone([0, 0])
|
|
},
|
|
pointMap = {};
|
|
|
|
function init() {
|
|
_add(point);
|
|
updateCenter();
|
|
}
|
|
|
|
function _add(pointToAdd) {
|
|
pointMap[pointToAdd.id] = pointToAdd;
|
|
points.push(pointToAdd);
|
|
}
|
|
|
|
function updateCenter() {
|
|
var i,
|
|
sum = 0;
|
|
for (i = 0; i < points.length; i++) {
|
|
sum += points[i].rad;
|
|
}
|
|
center.rad = sum / points.length;
|
|
center.vec = _glMatrix.vec2.clone([Math.cos(center.rad), Math.sin(center.rad)]);
|
|
}
|
|
|
|
init();
|
|
|
|
return {
|
|
add: function add(pointToAdd) {
|
|
if (!pointMap[pointToAdd.id]) {
|
|
_add(pointToAdd);
|
|
updateCenter();
|
|
}
|
|
},
|
|
fits: function fits(otherPoint) {
|
|
// check cosine similarity to center-angle
|
|
var similarity = Math.abs(_glMatrix.vec2.dot(otherPoint.point.vec, center.vec));
|
|
if (similarity > threshold) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
getPoints: function getPoints() {
|
|
return points;
|
|
},
|
|
getCenter: function getCenter() {
|
|
return center;
|
|
}
|
|
};
|
|
},
|
|
createPoint: function createPoint(newPoint, id, property) {
|
|
return {
|
|
rad: newPoint[property],
|
|
point: newPoint,
|
|
id: id
|
|
};
|
|
}
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 7 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @fileoverview gl-matrix - High performance matrix and vector operations
|
|
* @author Brandon Jones
|
|
* @author Colin MacKenzie IV
|
|
* @version 2.3.0
|
|
*/
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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. */
|
|
// END HEADER
|
|
|
|
exports.glMatrix = __webpack_require__(8);
|
|
exports.mat2 = __webpack_require__(9);
|
|
exports.mat2d = __webpack_require__(10);
|
|
exports.mat3 = __webpack_require__(11);
|
|
exports.mat4 = __webpack_require__(12);
|
|
exports.quat = __webpack_require__(13);
|
|
exports.vec2 = __webpack_require__(16);
|
|
exports.vec3 = __webpack_require__(14);
|
|
exports.vec4 = __webpack_require__(15);
|
|
|
|
/***/ },
|
|
/* 8 */
|
|
/***/ function(module, exports) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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. */
|
|
|
|
/**
|
|
* @class Common utilities
|
|
* @name glMatrix
|
|
*/
|
|
var glMatrix = {};
|
|
|
|
// Constants
|
|
glMatrix.EPSILON = 0.000001;
|
|
glMatrix.ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
|
|
glMatrix.RANDOM = Math.random;
|
|
|
|
/**
|
|
* Sets the type of array used when creating new vectors and matrices
|
|
*
|
|
* @param {Type} type Array type, such as Float32Array or Array
|
|
*/
|
|
glMatrix.setMatrixArrayType = function(type) {
|
|
GLMAT_ARRAY_TYPE = type;
|
|
}
|
|
|
|
var degree = Math.PI / 180;
|
|
|
|
/**
|
|
* Convert Degree To Radian
|
|
*
|
|
* @param {Number} Angle in Degrees
|
|
*/
|
|
glMatrix.toRadian = function(a){
|
|
return a * degree;
|
|
}
|
|
|
|
module.exports = glMatrix;
|
|
|
|
|
|
/***/ },
|
|
/* 9 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 2x2 Matrix
|
|
* @name mat2
|
|
*/
|
|
var mat2 = {};
|
|
|
|
/**
|
|
* Creates a new identity mat2
|
|
*
|
|
* @returns {mat2} a new 2x2 matrix
|
|
*/
|
|
mat2.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(4);
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new mat2 initialized with values from an existing matrix
|
|
*
|
|
* @param {mat2} a matrix to clone
|
|
* @returns {mat2} a new 2x2 matrix
|
|
*/
|
|
mat2.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(4);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one mat2 to another
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the source matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set a mat2 to the identity matrix
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.identity = function(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transpose the values of a mat2
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the source matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.transpose = function(out, a) {
|
|
// If we are transposing ourselves we can skip a few steps but have to cache some values
|
|
if (out === a) {
|
|
var a1 = a[1];
|
|
out[1] = a[2];
|
|
out[2] = a1;
|
|
} else {
|
|
out[0] = a[0];
|
|
out[1] = a[2];
|
|
out[2] = a[1];
|
|
out[3] = a[3];
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Inverts a mat2
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the source matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.invert = function(out, a) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
|
|
|
|
// Calculate the determinant
|
|
det = a0 * a3 - a2 * a1;
|
|
|
|
if (!det) {
|
|
return null;
|
|
}
|
|
det = 1.0 / det;
|
|
|
|
out[0] = a3 * det;
|
|
out[1] = -a1 * det;
|
|
out[2] = -a2 * det;
|
|
out[3] = a0 * det;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the adjugate of a mat2
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the source matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.adjoint = function(out, a) {
|
|
// Caching this value is nessecary if out == a
|
|
var a0 = a[0];
|
|
out[0] = a[3];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = a0;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the determinant of a mat2
|
|
*
|
|
* @param {mat2} a the source matrix
|
|
* @returns {Number} determinant of a
|
|
*/
|
|
mat2.determinant = function (a) {
|
|
return a[0] * a[3] - a[2] * a[1];
|
|
};
|
|
|
|
/**
|
|
* Multiplies two mat2's
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the first operand
|
|
* @param {mat2} b the second operand
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.multiply = function (out, a, b) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
|
|
var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
|
|
out[0] = a0 * b0 + a2 * b1;
|
|
out[1] = a1 * b0 + a3 * b1;
|
|
out[2] = a0 * b2 + a2 * b3;
|
|
out[3] = a1 * b2 + a3 * b3;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link mat2.multiply}
|
|
* @function
|
|
*/
|
|
mat2.mul = mat2.multiply;
|
|
|
|
/**
|
|
* Rotates a mat2 by the given angle
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.rotate = function (out, a, rad) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
|
|
s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
out[0] = a0 * c + a2 * s;
|
|
out[1] = a1 * c + a3 * s;
|
|
out[2] = a0 * -s + a2 * c;
|
|
out[3] = a1 * -s + a3 * c;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales the mat2 by the dimensions in the given vec2
|
|
*
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the matrix to rotate
|
|
* @param {vec2} v the vec2 to scale the matrix by
|
|
* @returns {mat2} out
|
|
**/
|
|
mat2.scale = function(out, a, v) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
|
|
v0 = v[0], v1 = v[1];
|
|
out[0] = a0 * v0;
|
|
out[1] = a1 * v0;
|
|
out[2] = a2 * v1;
|
|
out[3] = a3 * v1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a matrix from a given angle
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat2.identity(dest);
|
|
* mat2.rotate(dest, dest, rad);
|
|
*
|
|
* @param {mat2} out mat2 receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.fromRotation = function(out, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = -s;
|
|
out[3] = c;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a vector scaling
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat2.identity(dest);
|
|
* mat2.scale(dest, dest, vec);
|
|
*
|
|
* @param {mat2} out mat2 receiving operation result
|
|
* @param {vec2} v Scaling vector
|
|
* @returns {mat2} out
|
|
*/
|
|
mat2.fromScaling = function(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = v[1];
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of a mat2
|
|
*
|
|
* @param {mat2} mat matrix to represent as a string
|
|
* @returns {String} string representation of the matrix
|
|
*/
|
|
mat2.str = function (a) {
|
|
return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
|
|
};
|
|
|
|
/**
|
|
* Returns Frobenius norm of a mat2
|
|
*
|
|
* @param {mat2} a the matrix to calculate Frobenius norm of
|
|
* @returns {Number} Frobenius norm
|
|
*/
|
|
mat2.frob = function (a) {
|
|
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2)))
|
|
};
|
|
|
|
/**
|
|
* Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix
|
|
* @param {mat2} L the lower triangular matrix
|
|
* @param {mat2} D the diagonal matrix
|
|
* @param {mat2} U the upper triangular matrix
|
|
* @param {mat2} a the input matrix to factorize
|
|
*/
|
|
|
|
mat2.LDU = function (L, D, U, a) {
|
|
L[2] = a[2]/a[0];
|
|
U[0] = a[0];
|
|
U[1] = a[1];
|
|
U[3] = a[3] - L[2] * U[1];
|
|
return [L, D, U];
|
|
};
|
|
|
|
|
|
module.exports = mat2;
|
|
|
|
|
|
/***/ },
|
|
/* 10 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 2x3 Matrix
|
|
* @name mat2d
|
|
*
|
|
* @description
|
|
* A mat2d contains six elements defined as:
|
|
* <pre>
|
|
* [a, c, tx,
|
|
* b, d, ty]
|
|
* </pre>
|
|
* This is a short form for the 3x3 matrix:
|
|
* <pre>
|
|
* [a, c, tx,
|
|
* b, d, ty,
|
|
* 0, 0, 1]
|
|
* </pre>
|
|
* The last row is ignored so the array is shorter and operations are faster.
|
|
*/
|
|
var mat2d = {};
|
|
|
|
/**
|
|
* Creates a new identity mat2d
|
|
*
|
|
* @returns {mat2d} a new 2x3 matrix
|
|
*/
|
|
mat2d.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(6);
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new mat2d initialized with values from an existing matrix
|
|
*
|
|
* @param {mat2d} a matrix to clone
|
|
* @returns {mat2d} a new 2x3 matrix
|
|
*/
|
|
mat2d.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(6);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one mat2d to another
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @param {mat2d} a the source matrix
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set a mat2d to the identity matrix
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.identity = function(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Inverts a mat2d
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @param {mat2d} a the source matrix
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.invert = function(out, a) {
|
|
var aa = a[0], ab = a[1], ac = a[2], ad = a[3],
|
|
atx = a[4], aty = a[5];
|
|
|
|
var det = aa * ad - ab * ac;
|
|
if(!det){
|
|
return null;
|
|
}
|
|
det = 1.0 / det;
|
|
|
|
out[0] = ad * det;
|
|
out[1] = -ab * det;
|
|
out[2] = -ac * det;
|
|
out[3] = aa * det;
|
|
out[4] = (ac * aty - ad * atx) * det;
|
|
out[5] = (ab * atx - aa * aty) * det;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the determinant of a mat2d
|
|
*
|
|
* @param {mat2d} a the source matrix
|
|
* @returns {Number} determinant of a
|
|
*/
|
|
mat2d.determinant = function (a) {
|
|
return a[0] * a[3] - a[1] * a[2];
|
|
};
|
|
|
|
/**
|
|
* Multiplies two mat2d's
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @param {mat2d} a the first operand
|
|
* @param {mat2d} b the second operand
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.multiply = function (out, a, b) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
|
|
b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
|
|
out[0] = a0 * b0 + a2 * b1;
|
|
out[1] = a1 * b0 + a3 * b1;
|
|
out[2] = a0 * b2 + a2 * b3;
|
|
out[3] = a1 * b2 + a3 * b3;
|
|
out[4] = a0 * b4 + a2 * b5 + a4;
|
|
out[5] = a1 * b4 + a3 * b5 + a5;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link mat2d.multiply}
|
|
* @function
|
|
*/
|
|
mat2d.mul = mat2d.multiply;
|
|
|
|
/**
|
|
* Rotates a mat2d by the given angle
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @param {mat2d} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.rotate = function (out, a, rad) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
|
|
s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
out[0] = a0 * c + a2 * s;
|
|
out[1] = a1 * c + a3 * s;
|
|
out[2] = a0 * -s + a2 * c;
|
|
out[3] = a1 * -s + a3 * c;
|
|
out[4] = a4;
|
|
out[5] = a5;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales the mat2d by the dimensions in the given vec2
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @param {mat2d} a the matrix to translate
|
|
* @param {vec2} v the vec2 to scale the matrix by
|
|
* @returns {mat2d} out
|
|
**/
|
|
mat2d.scale = function(out, a, v) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
|
|
v0 = v[0], v1 = v[1];
|
|
out[0] = a0 * v0;
|
|
out[1] = a1 * v0;
|
|
out[2] = a2 * v1;
|
|
out[3] = a3 * v1;
|
|
out[4] = a4;
|
|
out[5] = a5;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Translates the mat2d by the dimensions in the given vec2
|
|
*
|
|
* @param {mat2d} out the receiving matrix
|
|
* @param {mat2d} a the matrix to translate
|
|
* @param {vec2} v the vec2 to translate the matrix by
|
|
* @returns {mat2d} out
|
|
**/
|
|
mat2d.translate = function(out, a, v) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
|
|
v0 = v[0], v1 = v[1];
|
|
out[0] = a0;
|
|
out[1] = a1;
|
|
out[2] = a2;
|
|
out[3] = a3;
|
|
out[4] = a0 * v0 + a2 * v1 + a4;
|
|
out[5] = a1 * v0 + a3 * v1 + a5;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a matrix from a given angle
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat2d.identity(dest);
|
|
* mat2d.rotate(dest, dest, rad);
|
|
*
|
|
* @param {mat2d} out mat2d receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.fromRotation = function(out, rad) {
|
|
var s = Math.sin(rad), c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = -s;
|
|
out[3] = c;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a vector scaling
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat2d.identity(dest);
|
|
* mat2d.scale(dest, dest, vec);
|
|
*
|
|
* @param {mat2d} out mat2d receiving operation result
|
|
* @param {vec2} v Scaling vector
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.fromScaling = function(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = v[1];
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a vector translation
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat2d.identity(dest);
|
|
* mat2d.translate(dest, dest, vec);
|
|
*
|
|
* @param {mat2d} out mat2d receiving operation result
|
|
* @param {vec2} v Translation vector
|
|
* @returns {mat2d} out
|
|
*/
|
|
mat2d.fromTranslation = function(out, v) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = v[0];
|
|
out[5] = v[1];
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of a mat2d
|
|
*
|
|
* @param {mat2d} a matrix to represent as a string
|
|
* @returns {String} string representation of the matrix
|
|
*/
|
|
mat2d.str = function (a) {
|
|
return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
|
|
a[3] + ', ' + a[4] + ', ' + a[5] + ')';
|
|
};
|
|
|
|
/**
|
|
* Returns Frobenius norm of a mat2d
|
|
*
|
|
* @param {mat2d} a the matrix to calculate Frobenius norm of
|
|
* @returns {Number} Frobenius norm
|
|
*/
|
|
mat2d.frob = function (a) {
|
|
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1))
|
|
};
|
|
|
|
module.exports = mat2d;
|
|
|
|
|
|
/***/ },
|
|
/* 11 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 3x3 Matrix
|
|
* @name mat3
|
|
*/
|
|
var mat3 = {};
|
|
|
|
/**
|
|
* Creates a new identity mat3
|
|
*
|
|
* @returns {mat3} a new 3x3 matrix
|
|
*/
|
|
mat3.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(9);
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 1;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copies the upper-left 3x3 values into the given mat3.
|
|
*
|
|
* @param {mat3} out the receiving 3x3 matrix
|
|
* @param {mat4} a the source 4x4 matrix
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.fromMat4 = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[4];
|
|
out[4] = a[5];
|
|
out[5] = a[6];
|
|
out[6] = a[8];
|
|
out[7] = a[9];
|
|
out[8] = a[10];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new mat3 initialized with values from an existing matrix
|
|
*
|
|
* @param {mat3} a matrix to clone
|
|
* @returns {mat3} a new 3x3 matrix
|
|
*/
|
|
mat3.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(9);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one mat3 to another
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the source matrix
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set a mat3 to the identity matrix
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.identity = function(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 1;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transpose the values of a mat3
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the source matrix
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.transpose = function(out, a) {
|
|
// If we are transposing ourselves we can skip a few steps but have to cache some values
|
|
if (out === a) {
|
|
var a01 = a[1], a02 = a[2], a12 = a[5];
|
|
out[1] = a[3];
|
|
out[2] = a[6];
|
|
out[3] = a01;
|
|
out[5] = a[7];
|
|
out[6] = a02;
|
|
out[7] = a12;
|
|
} else {
|
|
out[0] = a[0];
|
|
out[1] = a[3];
|
|
out[2] = a[6];
|
|
out[3] = a[1];
|
|
out[4] = a[4];
|
|
out[5] = a[7];
|
|
out[6] = a[2];
|
|
out[7] = a[5];
|
|
out[8] = a[8];
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Inverts a mat3
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the source matrix
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.invert = function(out, a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2],
|
|
a10 = a[3], a11 = a[4], a12 = a[5],
|
|
a20 = a[6], a21 = a[7], a22 = a[8],
|
|
|
|
b01 = a22 * a11 - a12 * a21,
|
|
b11 = -a22 * a10 + a12 * a20,
|
|
b21 = a21 * a10 - a11 * a20,
|
|
|
|
// Calculate the determinant
|
|
det = a00 * b01 + a01 * b11 + a02 * b21;
|
|
|
|
if (!det) {
|
|
return null;
|
|
}
|
|
det = 1.0 / det;
|
|
|
|
out[0] = b01 * det;
|
|
out[1] = (-a22 * a01 + a02 * a21) * det;
|
|
out[2] = (a12 * a01 - a02 * a11) * det;
|
|
out[3] = b11 * det;
|
|
out[4] = (a22 * a00 - a02 * a20) * det;
|
|
out[5] = (-a12 * a00 + a02 * a10) * det;
|
|
out[6] = b21 * det;
|
|
out[7] = (-a21 * a00 + a01 * a20) * det;
|
|
out[8] = (a11 * a00 - a01 * a10) * det;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the adjugate of a mat3
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the source matrix
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.adjoint = function(out, a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2],
|
|
a10 = a[3], a11 = a[4], a12 = a[5],
|
|
a20 = a[6], a21 = a[7], a22 = a[8];
|
|
|
|
out[0] = (a11 * a22 - a12 * a21);
|
|
out[1] = (a02 * a21 - a01 * a22);
|
|
out[2] = (a01 * a12 - a02 * a11);
|
|
out[3] = (a12 * a20 - a10 * a22);
|
|
out[4] = (a00 * a22 - a02 * a20);
|
|
out[5] = (a02 * a10 - a00 * a12);
|
|
out[6] = (a10 * a21 - a11 * a20);
|
|
out[7] = (a01 * a20 - a00 * a21);
|
|
out[8] = (a00 * a11 - a01 * a10);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the determinant of a mat3
|
|
*
|
|
* @param {mat3} a the source matrix
|
|
* @returns {Number} determinant of a
|
|
*/
|
|
mat3.determinant = function (a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2],
|
|
a10 = a[3], a11 = a[4], a12 = a[5],
|
|
a20 = a[6], a21 = a[7], a22 = a[8];
|
|
|
|
return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
|
|
};
|
|
|
|
/**
|
|
* Multiplies two mat3's
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the first operand
|
|
* @param {mat3} b the second operand
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.multiply = function (out, a, b) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2],
|
|
a10 = a[3], a11 = a[4], a12 = a[5],
|
|
a20 = a[6], a21 = a[7], a22 = a[8],
|
|
|
|
b00 = b[0], b01 = b[1], b02 = b[2],
|
|
b10 = b[3], b11 = b[4], b12 = b[5],
|
|
b20 = b[6], b21 = b[7], b22 = b[8];
|
|
|
|
out[0] = b00 * a00 + b01 * a10 + b02 * a20;
|
|
out[1] = b00 * a01 + b01 * a11 + b02 * a21;
|
|
out[2] = b00 * a02 + b01 * a12 + b02 * a22;
|
|
|
|
out[3] = b10 * a00 + b11 * a10 + b12 * a20;
|
|
out[4] = b10 * a01 + b11 * a11 + b12 * a21;
|
|
out[5] = b10 * a02 + b11 * a12 + b12 * a22;
|
|
|
|
out[6] = b20 * a00 + b21 * a10 + b22 * a20;
|
|
out[7] = b20 * a01 + b21 * a11 + b22 * a21;
|
|
out[8] = b20 * a02 + b21 * a12 + b22 * a22;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link mat3.multiply}
|
|
* @function
|
|
*/
|
|
mat3.mul = mat3.multiply;
|
|
|
|
/**
|
|
* Translate a mat3 by the given vector
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the matrix to translate
|
|
* @param {vec2} v vector to translate by
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.translate = function(out, a, v) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2],
|
|
a10 = a[3], a11 = a[4], a12 = a[5],
|
|
a20 = a[6], a21 = a[7], a22 = a[8],
|
|
x = v[0], y = v[1];
|
|
|
|
out[0] = a00;
|
|
out[1] = a01;
|
|
out[2] = a02;
|
|
|
|
out[3] = a10;
|
|
out[4] = a11;
|
|
out[5] = a12;
|
|
|
|
out[6] = x * a00 + y * a10 + a20;
|
|
out[7] = x * a01 + y * a11 + a21;
|
|
out[8] = x * a02 + y * a12 + a22;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a mat3 by the given angle
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.rotate = function (out, a, rad) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2],
|
|
a10 = a[3], a11 = a[4], a12 = a[5],
|
|
a20 = a[6], a21 = a[7], a22 = a[8],
|
|
|
|
s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
|
|
out[0] = c * a00 + s * a10;
|
|
out[1] = c * a01 + s * a11;
|
|
out[2] = c * a02 + s * a12;
|
|
|
|
out[3] = c * a10 - s * a00;
|
|
out[4] = c * a11 - s * a01;
|
|
out[5] = c * a12 - s * a02;
|
|
|
|
out[6] = a20;
|
|
out[7] = a21;
|
|
out[8] = a22;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales the mat3 by the dimensions in the given vec2
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat3} a the matrix to rotate
|
|
* @param {vec2} v the vec2 to scale the matrix by
|
|
* @returns {mat3} out
|
|
**/
|
|
mat3.scale = function(out, a, v) {
|
|
var x = v[0], y = v[1];
|
|
|
|
out[0] = x * a[0];
|
|
out[1] = x * a[1];
|
|
out[2] = x * a[2];
|
|
|
|
out[3] = y * a[3];
|
|
out[4] = y * a[4];
|
|
out[5] = y * a[5];
|
|
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a matrix from a vector translation
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat3.identity(dest);
|
|
* mat3.translate(dest, dest, vec);
|
|
*
|
|
* @param {mat3} out mat3 receiving operation result
|
|
* @param {vec2} v Translation vector
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.fromTranslation = function(out, v) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 1;
|
|
out[5] = 0;
|
|
out[6] = v[0];
|
|
out[7] = v[1];
|
|
out[8] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a given angle
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat3.identity(dest);
|
|
* mat3.rotate(dest, dest, rad);
|
|
*
|
|
* @param {mat3} out mat3 receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.fromRotation = function(out, rad) {
|
|
var s = Math.sin(rad), c = Math.cos(rad);
|
|
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = 0;
|
|
|
|
out[3] = -s;
|
|
out[4] = c;
|
|
out[5] = 0;
|
|
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a vector scaling
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat3.identity(dest);
|
|
* mat3.scale(dest, dest, vec);
|
|
*
|
|
* @param {mat3} out mat3 receiving operation result
|
|
* @param {vec2} v Scaling vector
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.fromScaling = function(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
|
|
out[3] = 0;
|
|
out[4] = v[1];
|
|
out[5] = 0;
|
|
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Copies the values from a mat2d into a mat3
|
|
*
|
|
* @param {mat3} out the receiving matrix
|
|
* @param {mat2d} a the matrix to copy
|
|
* @returns {mat3} out
|
|
**/
|
|
mat3.fromMat2d = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = 0;
|
|
|
|
out[3] = a[2];
|
|
out[4] = a[3];
|
|
out[5] = 0;
|
|
|
|
out[6] = a[4];
|
|
out[7] = a[5];
|
|
out[8] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates a 3x3 matrix from the given quaternion
|
|
*
|
|
* @param {mat3} out mat3 receiving operation result
|
|
* @param {quat} q Quaternion to create matrix from
|
|
*
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.fromQuat = function (out, q) {
|
|
var x = q[0], y = q[1], z = q[2], w = q[3],
|
|
x2 = x + x,
|
|
y2 = y + y,
|
|
z2 = z + z,
|
|
|
|
xx = x * x2,
|
|
yx = y * x2,
|
|
yy = y * y2,
|
|
zx = z * x2,
|
|
zy = z * y2,
|
|
zz = z * z2,
|
|
wx = w * x2,
|
|
wy = w * y2,
|
|
wz = w * z2;
|
|
|
|
out[0] = 1 - yy - zz;
|
|
out[3] = yx - wz;
|
|
out[6] = zx + wy;
|
|
|
|
out[1] = yx + wz;
|
|
out[4] = 1 - xx - zz;
|
|
out[7] = zy - wx;
|
|
|
|
out[2] = zx - wy;
|
|
out[5] = zy + wx;
|
|
out[8] = 1 - xx - yy;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
|
|
*
|
|
* @param {mat3} out mat3 receiving operation result
|
|
* @param {mat4} a Mat4 to derive the normal matrix from
|
|
*
|
|
* @returns {mat3} out
|
|
*/
|
|
mat3.normalFromMat4 = function (out, a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
|
|
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
|
|
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
|
|
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
|
|
|
|
b00 = a00 * a11 - a01 * a10,
|
|
b01 = a00 * a12 - a02 * a10,
|
|
b02 = a00 * a13 - a03 * a10,
|
|
b03 = a01 * a12 - a02 * a11,
|
|
b04 = a01 * a13 - a03 * a11,
|
|
b05 = a02 * a13 - a03 * a12,
|
|
b06 = a20 * a31 - a21 * a30,
|
|
b07 = a20 * a32 - a22 * a30,
|
|
b08 = a20 * a33 - a23 * a30,
|
|
b09 = a21 * a32 - a22 * a31,
|
|
b10 = a21 * a33 - a23 * a31,
|
|
b11 = a22 * a33 - a23 * a32,
|
|
|
|
// Calculate the determinant
|
|
det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
|
|
if (!det) {
|
|
return null;
|
|
}
|
|
det = 1.0 / det;
|
|
|
|
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
|
|
out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
|
|
|
|
out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
|
|
out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
|
|
|
|
out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
|
|
out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
|
|
out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns a string representation of a mat3
|
|
*
|
|
* @param {mat3} mat matrix to represent as a string
|
|
* @returns {String} string representation of the matrix
|
|
*/
|
|
mat3.str = function (a) {
|
|
return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
|
|
a[3] + ', ' + a[4] + ', ' + a[5] + ', ' +
|
|
a[6] + ', ' + a[7] + ', ' + a[8] + ')';
|
|
};
|
|
|
|
/**
|
|
* Returns Frobenius norm of a mat3
|
|
*
|
|
* @param {mat3} a the matrix to calculate Frobenius norm of
|
|
* @returns {Number} Frobenius norm
|
|
*/
|
|
mat3.frob = function (a) {
|
|
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)))
|
|
};
|
|
|
|
|
|
module.exports = mat3;
|
|
|
|
|
|
/***/ },
|
|
/* 12 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 4x4 Matrix
|
|
* @name mat4
|
|
*/
|
|
var mat4 = {};
|
|
|
|
/**
|
|
* Creates a new identity mat4
|
|
*
|
|
* @returns {mat4} a new 4x4 matrix
|
|
*/
|
|
mat4.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(16);
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new mat4 initialized with values from an existing matrix
|
|
*
|
|
* @param {mat4} a matrix to clone
|
|
* @returns {mat4} a new 4x4 matrix
|
|
*/
|
|
mat4.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(16);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one mat4 to another
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the source matrix
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set a mat4 to the identity matrix
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.identity = function(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transpose the values of a mat4
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the source matrix
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.transpose = function(out, a) {
|
|
// If we are transposing ourselves we can skip a few steps but have to cache some values
|
|
if (out === a) {
|
|
var a01 = a[1], a02 = a[2], a03 = a[3],
|
|
a12 = a[6], a13 = a[7],
|
|
a23 = a[11];
|
|
|
|
out[1] = a[4];
|
|
out[2] = a[8];
|
|
out[3] = a[12];
|
|
out[4] = a01;
|
|
out[6] = a[9];
|
|
out[7] = a[13];
|
|
out[8] = a02;
|
|
out[9] = a12;
|
|
out[11] = a[14];
|
|
out[12] = a03;
|
|
out[13] = a13;
|
|
out[14] = a23;
|
|
} else {
|
|
out[0] = a[0];
|
|
out[1] = a[4];
|
|
out[2] = a[8];
|
|
out[3] = a[12];
|
|
out[4] = a[1];
|
|
out[5] = a[5];
|
|
out[6] = a[9];
|
|
out[7] = a[13];
|
|
out[8] = a[2];
|
|
out[9] = a[6];
|
|
out[10] = a[10];
|
|
out[11] = a[14];
|
|
out[12] = a[3];
|
|
out[13] = a[7];
|
|
out[14] = a[11];
|
|
out[15] = a[15];
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Inverts a mat4
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the source matrix
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.invert = function(out, a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
|
|
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
|
|
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
|
|
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
|
|
|
|
b00 = a00 * a11 - a01 * a10,
|
|
b01 = a00 * a12 - a02 * a10,
|
|
b02 = a00 * a13 - a03 * a10,
|
|
b03 = a01 * a12 - a02 * a11,
|
|
b04 = a01 * a13 - a03 * a11,
|
|
b05 = a02 * a13 - a03 * a12,
|
|
b06 = a20 * a31 - a21 * a30,
|
|
b07 = a20 * a32 - a22 * a30,
|
|
b08 = a20 * a33 - a23 * a30,
|
|
b09 = a21 * a32 - a22 * a31,
|
|
b10 = a21 * a33 - a23 * a31,
|
|
b11 = a22 * a33 - a23 * a32,
|
|
|
|
// Calculate the determinant
|
|
det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
|
|
if (!det) {
|
|
return null;
|
|
}
|
|
det = 1.0 / det;
|
|
|
|
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
|
|
out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
|
|
out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
|
|
out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
|
|
out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
|
|
out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
|
|
out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
|
|
out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
|
|
out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
|
|
out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
|
|
out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
|
|
out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
|
|
out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
|
|
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the adjugate of a mat4
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the source matrix
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.adjoint = function(out, a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
|
|
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
|
|
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
|
|
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
|
|
|
|
out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
|
|
out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
|
|
out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
|
|
out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
|
|
out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
|
|
out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
|
|
out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
|
|
out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
|
|
out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
|
|
out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
|
|
out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
|
|
out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
|
|
out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
|
|
out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
|
|
out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
|
|
out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the determinant of a mat4
|
|
*
|
|
* @param {mat4} a the source matrix
|
|
* @returns {Number} determinant of a
|
|
*/
|
|
mat4.determinant = function (a) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
|
|
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
|
|
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
|
|
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
|
|
|
|
b00 = a00 * a11 - a01 * a10,
|
|
b01 = a00 * a12 - a02 * a10,
|
|
b02 = a00 * a13 - a03 * a10,
|
|
b03 = a01 * a12 - a02 * a11,
|
|
b04 = a01 * a13 - a03 * a11,
|
|
b05 = a02 * a13 - a03 * a12,
|
|
b06 = a20 * a31 - a21 * a30,
|
|
b07 = a20 * a32 - a22 * a30,
|
|
b08 = a20 * a33 - a23 * a30,
|
|
b09 = a21 * a32 - a22 * a31,
|
|
b10 = a21 * a33 - a23 * a31,
|
|
b11 = a22 * a33 - a23 * a32;
|
|
|
|
// Calculate the determinant
|
|
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
};
|
|
|
|
/**
|
|
* Multiplies two mat4's
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the first operand
|
|
* @param {mat4} b the second operand
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.multiply = function (out, a, b) {
|
|
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
|
|
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
|
|
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
|
|
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
|
|
|
|
// Cache only the current line of the second matrix
|
|
var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
|
|
out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
|
out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
|
out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
|
out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
|
|
|
b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
|
|
out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
|
out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
|
out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
|
out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
|
|
|
b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
|
|
out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
|
out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
|
out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
|
out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
|
|
|
b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
|
|
out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
|
out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
|
out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
|
out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link mat4.multiply}
|
|
* @function
|
|
*/
|
|
mat4.mul = mat4.multiply;
|
|
|
|
/**
|
|
* Translate a mat4 by the given vector
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the matrix to translate
|
|
* @param {vec3} v vector to translate by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.translate = function (out, a, v) {
|
|
var x = v[0], y = v[1], z = v[2],
|
|
a00, a01, a02, a03,
|
|
a10, a11, a12, a13,
|
|
a20, a21, a22, a23;
|
|
|
|
if (a === out) {
|
|
out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
|
|
out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
|
|
out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
|
|
out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
|
|
} else {
|
|
a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
|
|
a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
|
|
a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
|
|
|
|
out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
|
|
out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
|
|
out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
|
|
|
|
out[12] = a00 * x + a10 * y + a20 * z + a[12];
|
|
out[13] = a01 * x + a11 * y + a21 * z + a[13];
|
|
out[14] = a02 * x + a12 * y + a22 * z + a[14];
|
|
out[15] = a03 * x + a13 * y + a23 * z + a[15];
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales the mat4 by the dimensions in the given vec3
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the matrix to scale
|
|
* @param {vec3} v the vec3 to scale the matrix by
|
|
* @returns {mat4} out
|
|
**/
|
|
mat4.scale = function(out, a, v) {
|
|
var x = v[0], y = v[1], z = v[2];
|
|
|
|
out[0] = a[0] * x;
|
|
out[1] = a[1] * x;
|
|
out[2] = a[2] * x;
|
|
out[3] = a[3] * x;
|
|
out[4] = a[4] * y;
|
|
out[5] = a[5] * y;
|
|
out[6] = a[6] * y;
|
|
out[7] = a[7] * y;
|
|
out[8] = a[8] * z;
|
|
out[9] = a[9] * z;
|
|
out[10] = a[10] * z;
|
|
out[11] = a[11] * z;
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a mat4 by the given angle around the given axis
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @param {vec3} axis the axis to rotate around
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.rotate = function (out, a, rad, axis) {
|
|
var x = axis[0], y = axis[1], z = axis[2],
|
|
len = Math.sqrt(x * x + y * y + z * z),
|
|
s, c, t,
|
|
a00, a01, a02, a03,
|
|
a10, a11, a12, a13,
|
|
a20, a21, a22, a23,
|
|
b00, b01, b02,
|
|
b10, b11, b12,
|
|
b20, b21, b22;
|
|
|
|
if (Math.abs(len) < glMatrix.EPSILON) { return null; }
|
|
|
|
len = 1 / len;
|
|
x *= len;
|
|
y *= len;
|
|
z *= len;
|
|
|
|
s = Math.sin(rad);
|
|
c = Math.cos(rad);
|
|
t = 1 - c;
|
|
|
|
a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
|
|
a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
|
|
a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
|
|
|
|
// Construct the elements of the rotation matrix
|
|
b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
|
|
b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
|
|
b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
|
|
|
|
// Perform rotation-specific matrix multiplication
|
|
out[0] = a00 * b00 + a10 * b01 + a20 * b02;
|
|
out[1] = a01 * b00 + a11 * b01 + a21 * b02;
|
|
out[2] = a02 * b00 + a12 * b01 + a22 * b02;
|
|
out[3] = a03 * b00 + a13 * b01 + a23 * b02;
|
|
out[4] = a00 * b10 + a10 * b11 + a20 * b12;
|
|
out[5] = a01 * b10 + a11 * b11 + a21 * b12;
|
|
out[6] = a02 * b10 + a12 * b11 + a22 * b12;
|
|
out[7] = a03 * b10 + a13 * b11 + a23 * b12;
|
|
out[8] = a00 * b20 + a10 * b21 + a20 * b22;
|
|
out[9] = a01 * b20 + a11 * b21 + a21 * b22;
|
|
out[10] = a02 * b20 + a12 * b21 + a22 * b22;
|
|
out[11] = a03 * b20 + a13 * b21 + a23 * b22;
|
|
|
|
if (a !== out) { // If the source and destination differ, copy the unchanged last row
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
}
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a matrix by the given angle around the X axis
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.rotateX = function (out, a, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad),
|
|
a10 = a[4],
|
|
a11 = a[5],
|
|
a12 = a[6],
|
|
a13 = a[7],
|
|
a20 = a[8],
|
|
a21 = a[9],
|
|
a22 = a[10],
|
|
a23 = a[11];
|
|
|
|
if (a !== out) { // If the source and destination differ, copy the unchanged rows
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
}
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
out[4] = a10 * c + a20 * s;
|
|
out[5] = a11 * c + a21 * s;
|
|
out[6] = a12 * c + a22 * s;
|
|
out[7] = a13 * c + a23 * s;
|
|
out[8] = a20 * c - a10 * s;
|
|
out[9] = a21 * c - a11 * s;
|
|
out[10] = a22 * c - a12 * s;
|
|
out[11] = a23 * c - a13 * s;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a matrix by the given angle around the Y axis
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.rotateY = function (out, a, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad),
|
|
a00 = a[0],
|
|
a01 = a[1],
|
|
a02 = a[2],
|
|
a03 = a[3],
|
|
a20 = a[8],
|
|
a21 = a[9],
|
|
a22 = a[10],
|
|
a23 = a[11];
|
|
|
|
if (a !== out) { // If the source and destination differ, copy the unchanged rows
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
}
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
out[0] = a00 * c - a20 * s;
|
|
out[1] = a01 * c - a21 * s;
|
|
out[2] = a02 * c - a22 * s;
|
|
out[3] = a03 * c - a23 * s;
|
|
out[8] = a00 * s + a20 * c;
|
|
out[9] = a01 * s + a21 * c;
|
|
out[10] = a02 * s + a22 * c;
|
|
out[11] = a03 * s + a23 * c;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a matrix by the given angle around the Z axis
|
|
*
|
|
* @param {mat4} out the receiving matrix
|
|
* @param {mat4} a the matrix to rotate
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.rotateZ = function (out, a, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad),
|
|
a00 = a[0],
|
|
a01 = a[1],
|
|
a02 = a[2],
|
|
a03 = a[3],
|
|
a10 = a[4],
|
|
a11 = a[5],
|
|
a12 = a[6],
|
|
a13 = a[7];
|
|
|
|
if (a !== out) { // If the source and destination differ, copy the unchanged last row
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
}
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
out[0] = a00 * c + a10 * s;
|
|
out[1] = a01 * c + a11 * s;
|
|
out[2] = a02 * c + a12 * s;
|
|
out[3] = a03 * c + a13 * s;
|
|
out[4] = a10 * c - a00 * s;
|
|
out[5] = a11 * c - a01 * s;
|
|
out[6] = a12 * c - a02 * s;
|
|
out[7] = a13 * c - a03 * s;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a matrix from a vector translation
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.translate(dest, dest, vec);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {vec3} v Translation vector
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromTranslation = function(out, v) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = v[0];
|
|
out[13] = v[1];
|
|
out[14] = v[2];
|
|
out[15] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a vector scaling
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.scale(dest, dest, vec);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {vec3} v Scaling vector
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromScaling = function(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = v[1];
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = v[2];
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a given angle around a given axis
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.rotate(dest, dest, rad, axis);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @param {vec3} axis the axis to rotate around
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromRotation = function(out, rad, axis) {
|
|
var x = axis[0], y = axis[1], z = axis[2],
|
|
len = Math.sqrt(x * x + y * y + z * z),
|
|
s, c, t;
|
|
|
|
if (Math.abs(len) < glMatrix.EPSILON) { return null; }
|
|
|
|
len = 1 / len;
|
|
x *= len;
|
|
y *= len;
|
|
z *= len;
|
|
|
|
s = Math.sin(rad);
|
|
c = Math.cos(rad);
|
|
t = 1 - c;
|
|
|
|
// Perform rotation-specific matrix multiplication
|
|
out[0] = x * x * t + c;
|
|
out[1] = y * x * t + z * s;
|
|
out[2] = z * x * t - y * s;
|
|
out[3] = 0;
|
|
out[4] = x * y * t - z * s;
|
|
out[5] = y * y * t + c;
|
|
out[6] = z * y * t + x * s;
|
|
out[7] = 0;
|
|
out[8] = x * z * t + y * s;
|
|
out[9] = y * z * t - x * s;
|
|
out[10] = z * z * t + c;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from the given angle around the X axis
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.rotateX(dest, dest, rad);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromXRotation = function(out, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = c;
|
|
out[6] = s;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = -s;
|
|
out[10] = c;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from the given angle around the Y axis
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.rotateY(dest, dest, rad);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromYRotation = function(out, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
out[0] = c;
|
|
out[1] = 0;
|
|
out[2] = -s;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = s;
|
|
out[9] = 0;
|
|
out[10] = c;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from the given angle around the Z axis
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.rotateZ(dest, dest, rad);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {Number} rad the angle to rotate the matrix by
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromZRotation = function(out, rad) {
|
|
var s = Math.sin(rad),
|
|
c = Math.cos(rad);
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = -s;
|
|
out[5] = c;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Creates a matrix from a quaternion rotation and vector translation
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.translate(dest, vec);
|
|
* var quatMat = mat4.create();
|
|
* quat4.toMat4(quat, quatMat);
|
|
* mat4.multiply(dest, quatMat);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {quat4} q Rotation quaternion
|
|
* @param {vec3} v Translation vector
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromRotationTranslation = function (out, q, v) {
|
|
// Quaternion math
|
|
var x = q[0], y = q[1], z = q[2], w = q[3],
|
|
x2 = x + x,
|
|
y2 = y + y,
|
|
z2 = z + z,
|
|
|
|
xx = x * x2,
|
|
xy = x * y2,
|
|
xz = x * z2,
|
|
yy = y * y2,
|
|
yz = y * z2,
|
|
zz = z * z2,
|
|
wx = w * x2,
|
|
wy = w * y2,
|
|
wz = w * z2;
|
|
|
|
out[0] = 1 - (yy + zz);
|
|
out[1] = xy + wz;
|
|
out[2] = xz - wy;
|
|
out[3] = 0;
|
|
out[4] = xy - wz;
|
|
out[5] = 1 - (xx + zz);
|
|
out[6] = yz + wx;
|
|
out[7] = 0;
|
|
out[8] = xz + wy;
|
|
out[9] = yz - wx;
|
|
out[10] = 1 - (xx + yy);
|
|
out[11] = 0;
|
|
out[12] = v[0];
|
|
out[13] = v[1];
|
|
out[14] = v[2];
|
|
out[15] = 1;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a matrix from a quaternion rotation, vector translation and vector scale
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.translate(dest, vec);
|
|
* var quatMat = mat4.create();
|
|
* quat4.toMat4(quat, quatMat);
|
|
* mat4.multiply(dest, quatMat);
|
|
* mat4.scale(dest, scale)
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {quat4} q Rotation quaternion
|
|
* @param {vec3} v Translation vector
|
|
* @param {vec3} s Scaling vector
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromRotationTranslationScale = function (out, q, v, s) {
|
|
// Quaternion math
|
|
var x = q[0], y = q[1], z = q[2], w = q[3],
|
|
x2 = x + x,
|
|
y2 = y + y,
|
|
z2 = z + z,
|
|
|
|
xx = x * x2,
|
|
xy = x * y2,
|
|
xz = x * z2,
|
|
yy = y * y2,
|
|
yz = y * z2,
|
|
zz = z * z2,
|
|
wx = w * x2,
|
|
wy = w * y2,
|
|
wz = w * z2,
|
|
sx = s[0],
|
|
sy = s[1],
|
|
sz = s[2];
|
|
|
|
out[0] = (1 - (yy + zz)) * sx;
|
|
out[1] = (xy + wz) * sx;
|
|
out[2] = (xz - wy) * sx;
|
|
out[3] = 0;
|
|
out[4] = (xy - wz) * sy;
|
|
out[5] = (1 - (xx + zz)) * sy;
|
|
out[6] = (yz + wx) * sy;
|
|
out[7] = 0;
|
|
out[8] = (xz + wy) * sz;
|
|
out[9] = (yz - wx) * sz;
|
|
out[10] = (1 - (xx + yy)) * sz;
|
|
out[11] = 0;
|
|
out[12] = v[0];
|
|
out[13] = v[1];
|
|
out[14] = v[2];
|
|
out[15] = 1;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
|
|
* This is equivalent to (but much faster than):
|
|
*
|
|
* mat4.identity(dest);
|
|
* mat4.translate(dest, vec);
|
|
* mat4.translate(dest, origin);
|
|
* var quatMat = mat4.create();
|
|
* quat4.toMat4(quat, quatMat);
|
|
* mat4.multiply(dest, quatMat);
|
|
* mat4.scale(dest, scale)
|
|
* mat4.translate(dest, negativeOrigin);
|
|
*
|
|
* @param {mat4} out mat4 receiving operation result
|
|
* @param {quat4} q Rotation quaternion
|
|
* @param {vec3} v Translation vector
|
|
* @param {vec3} s Scaling vector
|
|
* @param {vec3} o The origin vector around which to scale and rotate
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.fromRotationTranslationScaleOrigin = function (out, q, v, s, o) {
|
|
// Quaternion math
|
|
var x = q[0], y = q[1], z = q[2], w = q[3],
|
|
x2 = x + x,
|
|
y2 = y + y,
|
|
z2 = z + z,
|
|
|
|
xx = x * x2,
|
|
xy = x * y2,
|
|
xz = x * z2,
|
|
yy = y * y2,
|
|
yz = y * z2,
|
|
zz = z * z2,
|
|
wx = w * x2,
|
|
wy = w * y2,
|
|
wz = w * z2,
|
|
|
|
sx = s[0],
|
|
sy = s[1],
|
|
sz = s[2],
|
|
|
|
ox = o[0],
|
|
oy = o[1],
|
|
oz = o[2];
|
|
|
|
out[0] = (1 - (yy + zz)) * sx;
|
|
out[1] = (xy + wz) * sx;
|
|
out[2] = (xz - wy) * sx;
|
|
out[3] = 0;
|
|
out[4] = (xy - wz) * sy;
|
|
out[5] = (1 - (xx + zz)) * sy;
|
|
out[6] = (yz + wx) * sy;
|
|
out[7] = 0;
|
|
out[8] = (xz + wy) * sz;
|
|
out[9] = (yz - wx) * sz;
|
|
out[10] = (1 - (xx + yy)) * sz;
|
|
out[11] = 0;
|
|
out[12] = v[0] + ox - (out[0] * ox + out[4] * oy + out[8] * oz);
|
|
out[13] = v[1] + oy - (out[1] * ox + out[5] * oy + out[9] * oz);
|
|
out[14] = v[2] + oz - (out[2] * ox + out[6] * oy + out[10] * oz);
|
|
out[15] = 1;
|
|
|
|
return out;
|
|
};
|
|
|
|
mat4.fromQuat = function (out, q) {
|
|
var x = q[0], y = q[1], z = q[2], w = q[3],
|
|
x2 = x + x,
|
|
y2 = y + y,
|
|
z2 = z + z,
|
|
|
|
xx = x * x2,
|
|
yx = y * x2,
|
|
yy = y * y2,
|
|
zx = z * x2,
|
|
zy = z * y2,
|
|
zz = z * z2,
|
|
wx = w * x2,
|
|
wy = w * y2,
|
|
wz = w * z2;
|
|
|
|
out[0] = 1 - yy - zz;
|
|
out[1] = yx + wz;
|
|
out[2] = zx - wy;
|
|
out[3] = 0;
|
|
|
|
out[4] = yx - wz;
|
|
out[5] = 1 - xx - zz;
|
|
out[6] = zy + wx;
|
|
out[7] = 0;
|
|
|
|
out[8] = zx + wy;
|
|
out[9] = zy - wx;
|
|
out[10] = 1 - xx - yy;
|
|
out[11] = 0;
|
|
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a frustum matrix with the given bounds
|
|
*
|
|
* @param {mat4} out mat4 frustum matrix will be written into
|
|
* @param {Number} left Left bound of the frustum
|
|
* @param {Number} right Right bound of the frustum
|
|
* @param {Number} bottom Bottom bound of the frustum
|
|
* @param {Number} top Top bound of the frustum
|
|
* @param {Number} near Near bound of the frustum
|
|
* @param {Number} far Far bound of the frustum
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.frustum = function (out, left, right, bottom, top, near, far) {
|
|
var rl = 1 / (right - left),
|
|
tb = 1 / (top - bottom),
|
|
nf = 1 / (near - far);
|
|
out[0] = (near * 2) * rl;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = (near * 2) * tb;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = (right + left) * rl;
|
|
out[9] = (top + bottom) * tb;
|
|
out[10] = (far + near) * nf;
|
|
out[11] = -1;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = (far * near * 2) * nf;
|
|
out[15] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a perspective projection matrix with the given bounds
|
|
*
|
|
* @param {mat4} out mat4 frustum matrix will be written into
|
|
* @param {number} fovy Vertical field of view in radians
|
|
* @param {number} aspect Aspect ratio. typically viewport width/height
|
|
* @param {number} near Near bound of the frustum
|
|
* @param {number} far Far bound of the frustum
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.perspective = function (out, fovy, aspect, near, far) {
|
|
var f = 1.0 / Math.tan(fovy / 2),
|
|
nf = 1 / (near - far);
|
|
out[0] = f / aspect;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = f;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = (far + near) * nf;
|
|
out[11] = -1;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = (2 * far * near) * nf;
|
|
out[15] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a perspective projection matrix with the given field of view.
|
|
* This is primarily useful for generating projection matrices to be used
|
|
* with the still experiemental WebVR API.
|
|
*
|
|
* @param {mat4} out mat4 frustum matrix will be written into
|
|
* @param {number} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
|
|
* @param {number} near Near bound of the frustum
|
|
* @param {number} far Far bound of the frustum
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.perspectiveFromFieldOfView = function (out, fov, near, far) {
|
|
var upTan = Math.tan(fov.upDegrees * Math.PI/180.0),
|
|
downTan = Math.tan(fov.downDegrees * Math.PI/180.0),
|
|
leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0),
|
|
rightTan = Math.tan(fov.rightDegrees * Math.PI/180.0),
|
|
xScale = 2.0 / (leftTan + rightTan),
|
|
yScale = 2.0 / (upTan + downTan);
|
|
|
|
out[0] = xScale;
|
|
out[1] = 0.0;
|
|
out[2] = 0.0;
|
|
out[3] = 0.0;
|
|
out[4] = 0.0;
|
|
out[5] = yScale;
|
|
out[6] = 0.0;
|
|
out[7] = 0.0;
|
|
out[8] = -((leftTan - rightTan) * xScale * 0.5);
|
|
out[9] = ((upTan - downTan) * yScale * 0.5);
|
|
out[10] = far / (near - far);
|
|
out[11] = -1.0;
|
|
out[12] = 0.0;
|
|
out[13] = 0.0;
|
|
out[14] = (far * near) / (near - far);
|
|
out[15] = 0.0;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Generates a orthogonal projection matrix with the given bounds
|
|
*
|
|
* @param {mat4} out mat4 frustum matrix will be written into
|
|
* @param {number} left Left bound of the frustum
|
|
* @param {number} right Right bound of the frustum
|
|
* @param {number} bottom Bottom bound of the frustum
|
|
* @param {number} top Top bound of the frustum
|
|
* @param {number} near Near bound of the frustum
|
|
* @param {number} far Far bound of the frustum
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.ortho = function (out, left, right, bottom, top, near, far) {
|
|
var lr = 1 / (left - right),
|
|
bt = 1 / (bottom - top),
|
|
nf = 1 / (near - far);
|
|
out[0] = -2 * lr;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = -2 * bt;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 2 * nf;
|
|
out[11] = 0;
|
|
out[12] = (left + right) * lr;
|
|
out[13] = (top + bottom) * bt;
|
|
out[14] = (far + near) * nf;
|
|
out[15] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a look-at matrix with the given eye position, focal point, and up axis
|
|
*
|
|
* @param {mat4} out mat4 frustum matrix will be written into
|
|
* @param {vec3} eye Position of the viewer
|
|
* @param {vec3} center Point the viewer is looking at
|
|
* @param {vec3} up vec3 pointing up
|
|
* @returns {mat4} out
|
|
*/
|
|
mat4.lookAt = function (out, eye, center, up) {
|
|
var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
|
|
eyex = eye[0],
|
|
eyey = eye[1],
|
|
eyez = eye[2],
|
|
upx = up[0],
|
|
upy = up[1],
|
|
upz = up[2],
|
|
centerx = center[0],
|
|
centery = center[1],
|
|
centerz = center[2];
|
|
|
|
if (Math.abs(eyex - centerx) < glMatrix.EPSILON &&
|
|
Math.abs(eyey - centery) < glMatrix.EPSILON &&
|
|
Math.abs(eyez - centerz) < glMatrix.EPSILON) {
|
|
return mat4.identity(out);
|
|
}
|
|
|
|
z0 = eyex - centerx;
|
|
z1 = eyey - centery;
|
|
z2 = eyez - centerz;
|
|
|
|
len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
|
|
z0 *= len;
|
|
z1 *= len;
|
|
z2 *= len;
|
|
|
|
x0 = upy * z2 - upz * z1;
|
|
x1 = upz * z0 - upx * z2;
|
|
x2 = upx * z1 - upy * z0;
|
|
len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
|
|
if (!len) {
|
|
x0 = 0;
|
|
x1 = 0;
|
|
x2 = 0;
|
|
} else {
|
|
len = 1 / len;
|
|
x0 *= len;
|
|
x1 *= len;
|
|
x2 *= len;
|
|
}
|
|
|
|
y0 = z1 * x2 - z2 * x1;
|
|
y1 = z2 * x0 - z0 * x2;
|
|
y2 = z0 * x1 - z1 * x0;
|
|
|
|
len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
|
|
if (!len) {
|
|
y0 = 0;
|
|
y1 = 0;
|
|
y2 = 0;
|
|
} else {
|
|
len = 1 / len;
|
|
y0 *= len;
|
|
y1 *= len;
|
|
y2 *= len;
|
|
}
|
|
|
|
out[0] = x0;
|
|
out[1] = y0;
|
|
out[2] = z0;
|
|
out[3] = 0;
|
|
out[4] = x1;
|
|
out[5] = y1;
|
|
out[6] = z1;
|
|
out[7] = 0;
|
|
out[8] = x2;
|
|
out[9] = y2;
|
|
out[10] = z2;
|
|
out[11] = 0;
|
|
out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
|
|
out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
|
|
out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
|
|
out[15] = 1;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns a string representation of a mat4
|
|
*
|
|
* @param {mat4} mat matrix to represent as a string
|
|
* @returns {String} string representation of the matrix
|
|
*/
|
|
mat4.str = function (a) {
|
|
return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
|
|
a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
|
|
a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' +
|
|
a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
|
|
};
|
|
|
|
/**
|
|
* Returns Frobenius norm of a mat4
|
|
*
|
|
* @param {mat4} a the matrix to calculate Frobenius norm of
|
|
* @returns {Number} Frobenius norm
|
|
*/
|
|
mat4.frob = function (a) {
|
|
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) ))
|
|
};
|
|
|
|
|
|
module.exports = mat4;
|
|
|
|
|
|
/***/ },
|
|
/* 13 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
var mat3 = __webpack_require__(11);
|
|
var vec3 = __webpack_require__(14);
|
|
var vec4 = __webpack_require__(15);
|
|
|
|
/**
|
|
* @class Quaternion
|
|
* @name quat
|
|
*/
|
|
var quat = {};
|
|
|
|
/**
|
|
* Creates a new identity quat
|
|
*
|
|
* @returns {quat} a new quaternion
|
|
*/
|
|
quat.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(4);
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Sets a quaternion to represent the shortest rotation from one
|
|
* vector to another.
|
|
*
|
|
* Both vectors are assumed to be unit length.
|
|
*
|
|
* @param {quat} out the receiving quaternion.
|
|
* @param {vec3} a the initial vector
|
|
* @param {vec3} b the destination vector
|
|
* @returns {quat} out
|
|
*/
|
|
quat.rotationTo = (function() {
|
|
var tmpvec3 = vec3.create();
|
|
var xUnitVec3 = vec3.fromValues(1,0,0);
|
|
var yUnitVec3 = vec3.fromValues(0,1,0);
|
|
|
|
return function(out, a, b) {
|
|
var dot = vec3.dot(a, b);
|
|
if (dot < -0.999999) {
|
|
vec3.cross(tmpvec3, xUnitVec3, a);
|
|
if (vec3.length(tmpvec3) < 0.000001)
|
|
vec3.cross(tmpvec3, yUnitVec3, a);
|
|
vec3.normalize(tmpvec3, tmpvec3);
|
|
quat.setAxisAngle(out, tmpvec3, Math.PI);
|
|
return out;
|
|
} else if (dot > 0.999999) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out;
|
|
} else {
|
|
vec3.cross(tmpvec3, a, b);
|
|
out[0] = tmpvec3[0];
|
|
out[1] = tmpvec3[1];
|
|
out[2] = tmpvec3[2];
|
|
out[3] = 1 + dot;
|
|
return quat.normalize(out, out);
|
|
}
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Sets the specified quaternion with values corresponding to the given
|
|
* axes. Each axis is a vec3 and is expected to be unit length and
|
|
* perpendicular to all other specified axes.
|
|
*
|
|
* @param {vec3} view the vector representing the viewing direction
|
|
* @param {vec3} right the vector representing the local "right" direction
|
|
* @param {vec3} up the vector representing the local "up" direction
|
|
* @returns {quat} out
|
|
*/
|
|
quat.setAxes = (function() {
|
|
var matr = mat3.create();
|
|
|
|
return function(out, view, right, up) {
|
|
matr[0] = right[0];
|
|
matr[3] = right[1];
|
|
matr[6] = right[2];
|
|
|
|
matr[1] = up[0];
|
|
matr[4] = up[1];
|
|
matr[7] = up[2];
|
|
|
|
matr[2] = -view[0];
|
|
matr[5] = -view[1];
|
|
matr[8] = -view[2];
|
|
|
|
return quat.normalize(out, quat.fromMat3(out, matr));
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Creates a new quat initialized with values from an existing quaternion
|
|
*
|
|
* @param {quat} a quaternion to clone
|
|
* @returns {quat} a new quaternion
|
|
* @function
|
|
*/
|
|
quat.clone = vec4.clone;
|
|
|
|
/**
|
|
* Creates a new quat initialized with the given values
|
|
*
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @param {Number} z Z component
|
|
* @param {Number} w W component
|
|
* @returns {quat} a new quaternion
|
|
* @function
|
|
*/
|
|
quat.fromValues = vec4.fromValues;
|
|
|
|
/**
|
|
* Copy the values from one quat to another
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a the source quaternion
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.copy = vec4.copy;
|
|
|
|
/**
|
|
* Set the components of a quat to the given values
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @param {Number} z Z component
|
|
* @param {Number} w W component
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.set = vec4.set;
|
|
|
|
/**
|
|
* Set a quat to the identity quaternion
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @returns {quat} out
|
|
*/
|
|
quat.identity = function(out) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Sets a quat from the given angle and rotation axis,
|
|
* then returns it.
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {vec3} axis the axis around which to rotate
|
|
* @param {Number} rad the angle in radians
|
|
* @returns {quat} out
|
|
**/
|
|
quat.setAxisAngle = function(out, axis, rad) {
|
|
rad = rad * 0.5;
|
|
var s = Math.sin(rad);
|
|
out[0] = s * axis[0];
|
|
out[1] = s * axis[1];
|
|
out[2] = s * axis[2];
|
|
out[3] = Math.cos(rad);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two quat's
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a the first operand
|
|
* @param {quat} b the second operand
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.add = vec4.add;
|
|
|
|
/**
|
|
* Multiplies two quat's
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a the first operand
|
|
* @param {quat} b the second operand
|
|
* @returns {quat} out
|
|
*/
|
|
quat.multiply = function(out, a, b) {
|
|
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
|
|
bx = b[0], by = b[1], bz = b[2], bw = b[3];
|
|
|
|
out[0] = ax * bw + aw * bx + ay * bz - az * by;
|
|
out[1] = ay * bw + aw * by + az * bx - ax * bz;
|
|
out[2] = az * bw + aw * bz + ax * by - ay * bx;
|
|
out[3] = aw * bw - ax * bx - ay * by - az * bz;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link quat.multiply}
|
|
* @function
|
|
*/
|
|
quat.mul = quat.multiply;
|
|
|
|
/**
|
|
* Scales a quat by a scalar number
|
|
*
|
|
* @param {quat} out the receiving vector
|
|
* @param {quat} a the vector to scale
|
|
* @param {Number} b amount to scale the vector by
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.scale = vec4.scale;
|
|
|
|
/**
|
|
* Rotates a quaternion by the given angle about the X axis
|
|
*
|
|
* @param {quat} out quat receiving operation result
|
|
* @param {quat} a quat to rotate
|
|
* @param {number} rad angle (in radians) to rotate
|
|
* @returns {quat} out
|
|
*/
|
|
quat.rotateX = function (out, a, rad) {
|
|
rad *= 0.5;
|
|
|
|
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
|
|
bx = Math.sin(rad), bw = Math.cos(rad);
|
|
|
|
out[0] = ax * bw + aw * bx;
|
|
out[1] = ay * bw + az * bx;
|
|
out[2] = az * bw - ay * bx;
|
|
out[3] = aw * bw - ax * bx;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a quaternion by the given angle about the Y axis
|
|
*
|
|
* @param {quat} out quat receiving operation result
|
|
* @param {quat} a quat to rotate
|
|
* @param {number} rad angle (in radians) to rotate
|
|
* @returns {quat} out
|
|
*/
|
|
quat.rotateY = function (out, a, rad) {
|
|
rad *= 0.5;
|
|
|
|
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
|
|
by = Math.sin(rad), bw = Math.cos(rad);
|
|
|
|
out[0] = ax * bw - az * by;
|
|
out[1] = ay * bw + aw * by;
|
|
out[2] = az * bw + ax * by;
|
|
out[3] = aw * bw - ay * by;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotates a quaternion by the given angle about the Z axis
|
|
*
|
|
* @param {quat} out quat receiving operation result
|
|
* @param {quat} a quat to rotate
|
|
* @param {number} rad angle (in radians) to rotate
|
|
* @returns {quat} out
|
|
*/
|
|
quat.rotateZ = function (out, a, rad) {
|
|
rad *= 0.5;
|
|
|
|
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
|
|
bz = Math.sin(rad), bw = Math.cos(rad);
|
|
|
|
out[0] = ax * bw + ay * bz;
|
|
out[1] = ay * bw - ax * bz;
|
|
out[2] = az * bw + aw * bz;
|
|
out[3] = aw * bw - az * bz;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the W component of a quat from the X, Y, and Z components.
|
|
* Assumes that quaternion is 1 unit in length.
|
|
* Any existing W component will be ignored.
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a quat to calculate W component of
|
|
* @returns {quat} out
|
|
*/
|
|
quat.calculateW = function (out, a) {
|
|
var x = a[0], y = a[1], z = a[2];
|
|
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the dot product of two quat's
|
|
*
|
|
* @param {quat} a the first operand
|
|
* @param {quat} b the second operand
|
|
* @returns {Number} dot product of a and b
|
|
* @function
|
|
*/
|
|
quat.dot = vec4.dot;
|
|
|
|
/**
|
|
* Performs a linear interpolation between two quat's
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a the first operand
|
|
* @param {quat} b the second operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.lerp = vec4.lerp;
|
|
|
|
/**
|
|
* Performs a spherical linear interpolation between two quat
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a the first operand
|
|
* @param {quat} b the second operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {quat} out
|
|
*/
|
|
quat.slerp = function (out, a, b, t) {
|
|
// benchmarks:
|
|
// http://jsperf.com/quaternion-slerp-implementations
|
|
|
|
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
|
|
bx = b[0], by = b[1], bz = b[2], bw = b[3];
|
|
|
|
var omega, cosom, sinom, scale0, scale1;
|
|
|
|
// calc cosine
|
|
cosom = ax * bx + ay * by + az * bz + aw * bw;
|
|
// adjust signs (if necessary)
|
|
if ( cosom < 0.0 ) {
|
|
cosom = -cosom;
|
|
bx = - bx;
|
|
by = - by;
|
|
bz = - bz;
|
|
bw = - bw;
|
|
}
|
|
// calculate coefficients
|
|
if ( (1.0 - cosom) > 0.000001 ) {
|
|
// standard case (slerp)
|
|
omega = Math.acos(cosom);
|
|
sinom = Math.sin(omega);
|
|
scale0 = Math.sin((1.0 - t) * omega) / sinom;
|
|
scale1 = Math.sin(t * omega) / sinom;
|
|
} else {
|
|
// "from" and "to" quaternions are very close
|
|
// ... so we can do a linear interpolation
|
|
scale0 = 1.0 - t;
|
|
scale1 = t;
|
|
}
|
|
// calculate final values
|
|
out[0] = scale0 * ax + scale1 * bx;
|
|
out[1] = scale0 * ay + scale1 * by;
|
|
out[2] = scale0 * az + scale1 * bz;
|
|
out[3] = scale0 * aw + scale1 * bw;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Performs a spherical linear interpolation with two control points
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a the first operand
|
|
* @param {quat} b the second operand
|
|
* @param {quat} c the third operand
|
|
* @param {quat} d the fourth operand
|
|
* @param {Number} t interpolation amount
|
|
* @returns {quat} out
|
|
*/
|
|
quat.sqlerp = (function () {
|
|
var temp1 = quat.create();
|
|
var temp2 = quat.create();
|
|
|
|
return function (out, a, b, c, d, t) {
|
|
quat.slerp(temp1, a, d, t);
|
|
quat.slerp(temp2, b, c, t);
|
|
quat.slerp(out, temp1, temp2, 2 * t * (1 - t));
|
|
|
|
return out;
|
|
};
|
|
}());
|
|
|
|
/**
|
|
* Calculates the inverse of a quat
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a quat to calculate inverse of
|
|
* @returns {quat} out
|
|
*/
|
|
quat.invert = function(out, a) {
|
|
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
|
|
dot = a0*a0 + a1*a1 + a2*a2 + a3*a3,
|
|
invDot = dot ? 1.0/dot : 0;
|
|
|
|
// TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
|
|
|
|
out[0] = -a0*invDot;
|
|
out[1] = -a1*invDot;
|
|
out[2] = -a2*invDot;
|
|
out[3] = a3*invDot;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the conjugate of a quat
|
|
* If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a quat to calculate conjugate of
|
|
* @returns {quat} out
|
|
*/
|
|
quat.conjugate = function (out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the length of a quat
|
|
*
|
|
* @param {quat} a vector to calculate length of
|
|
* @returns {Number} length of a
|
|
* @function
|
|
*/
|
|
quat.length = vec4.length;
|
|
|
|
/**
|
|
* Alias for {@link quat.length}
|
|
* @function
|
|
*/
|
|
quat.len = quat.length;
|
|
|
|
/**
|
|
* Calculates the squared length of a quat
|
|
*
|
|
* @param {quat} a vector to calculate squared length of
|
|
* @returns {Number} squared length of a
|
|
* @function
|
|
*/
|
|
quat.squaredLength = vec4.squaredLength;
|
|
|
|
/**
|
|
* Alias for {@link quat.squaredLength}
|
|
* @function
|
|
*/
|
|
quat.sqrLen = quat.squaredLength;
|
|
|
|
/**
|
|
* Normalize a quat
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {quat} a quaternion to normalize
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.normalize = vec4.normalize;
|
|
|
|
/**
|
|
* Creates a quaternion from the given 3x3 rotation matrix.
|
|
*
|
|
* NOTE: The resultant quaternion is not normalized, so you should be sure
|
|
* to renormalize the quaternion yourself where necessary.
|
|
*
|
|
* @param {quat} out the receiving quaternion
|
|
* @param {mat3} m rotation matrix
|
|
* @returns {quat} out
|
|
* @function
|
|
*/
|
|
quat.fromMat3 = function(out, m) {
|
|
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
|
|
// article "Quaternion Calculus and Fast Animation".
|
|
var fTrace = m[0] + m[4] + m[8];
|
|
var fRoot;
|
|
|
|
if ( fTrace > 0.0 ) {
|
|
// |w| > 1/2, may as well choose w > 1/2
|
|
fRoot = Math.sqrt(fTrace + 1.0); // 2w
|
|
out[3] = 0.5 * fRoot;
|
|
fRoot = 0.5/fRoot; // 1/(4w)
|
|
out[0] = (m[5]-m[7])*fRoot;
|
|
out[1] = (m[6]-m[2])*fRoot;
|
|
out[2] = (m[1]-m[3])*fRoot;
|
|
} else {
|
|
// |w| <= 1/2
|
|
var i = 0;
|
|
if ( m[4] > m[0] )
|
|
i = 1;
|
|
if ( m[8] > m[i*3+i] )
|
|
i = 2;
|
|
var j = (i+1)%3;
|
|
var k = (i+2)%3;
|
|
|
|
fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0);
|
|
out[i] = 0.5 * fRoot;
|
|
fRoot = 0.5 / fRoot;
|
|
out[3] = (m[j*3+k] - m[k*3+j]) * fRoot;
|
|
out[j] = (m[j*3+i] + m[i*3+j]) * fRoot;
|
|
out[k] = (m[k*3+i] + m[i*3+k]) * fRoot;
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns a string representation of a quatenion
|
|
*
|
|
* @param {quat} vec vector to represent as a string
|
|
* @returns {String} string representation of the vector
|
|
*/
|
|
quat.str = function (a) {
|
|
return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
|
|
};
|
|
|
|
module.exports = quat;
|
|
|
|
|
|
/***/ },
|
|
/* 14 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 3 Dimensional Vector
|
|
* @name vec3
|
|
*/
|
|
var vec3 = {};
|
|
|
|
/**
|
|
* Creates a new, empty vec3
|
|
*
|
|
* @returns {vec3} a new 3D vector
|
|
*/
|
|
vec3.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(3);
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new vec3 initialized with values from an existing vector
|
|
*
|
|
* @param {vec3} a vector to clone
|
|
* @returns {vec3} a new 3D vector
|
|
*/
|
|
vec3.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(3);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new vec3 initialized with the given values
|
|
*
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @param {Number} z Z component
|
|
* @returns {vec3} a new 3D vector
|
|
*/
|
|
vec3.fromValues = function(x, y, z) {
|
|
var out = new glMatrix.ARRAY_TYPE(3);
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one vec3 to another
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the source vector
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set the components of a vec3 to the given values
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @param {Number} z Z component
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.set = function(out, x, y, z) {
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.add = function(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Subtracts vector b from vector a
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.subtract = function(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.subtract}
|
|
* @function
|
|
*/
|
|
vec3.sub = vec3.subtract;
|
|
|
|
/**
|
|
* Multiplies two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.multiply = function(out, a, b) {
|
|
out[0] = a[0] * b[0];
|
|
out[1] = a[1] * b[1];
|
|
out[2] = a[2] * b[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.multiply}
|
|
* @function
|
|
*/
|
|
vec3.mul = vec3.multiply;
|
|
|
|
/**
|
|
* Divides two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.divide = function(out, a, b) {
|
|
out[0] = a[0] / b[0];
|
|
out[1] = a[1] / b[1];
|
|
out[2] = a[2] / b[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.divide}
|
|
* @function
|
|
*/
|
|
vec3.div = vec3.divide;
|
|
|
|
/**
|
|
* Returns the minimum of two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.min = function(out, a, b) {
|
|
out[0] = Math.min(a[0], b[0]);
|
|
out[1] = Math.min(a[1], b[1]);
|
|
out[2] = Math.min(a[2], b[2]);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns the maximum of two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.max = function(out, a, b) {
|
|
out[0] = Math.max(a[0], b[0]);
|
|
out[1] = Math.max(a[1], b[1]);
|
|
out[2] = Math.max(a[2], b[2]);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales a vec3 by a scalar number
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the vector to scale
|
|
* @param {Number} b amount to scale the vector by
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.scale = function(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two vec3's after scaling the second operand by a scalar value
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @param {Number} scale the amount to scale b by before adding
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.scaleAndAdd = function(out, a, b, scale) {
|
|
out[0] = a[0] + (b[0] * scale);
|
|
out[1] = a[1] + (b[1] * scale);
|
|
out[2] = a[2] + (b[2] * scale);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the euclidian distance between two vec3's
|
|
*
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {Number} distance between a and b
|
|
*/
|
|
vec3.distance = function(a, b) {
|
|
var x = b[0] - a[0],
|
|
y = b[1] - a[1],
|
|
z = b[2] - a[2];
|
|
return Math.sqrt(x*x + y*y + z*z);
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.distance}
|
|
* @function
|
|
*/
|
|
vec3.dist = vec3.distance;
|
|
|
|
/**
|
|
* Calculates the squared euclidian distance between two vec3's
|
|
*
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {Number} squared distance between a and b
|
|
*/
|
|
vec3.squaredDistance = function(a, b) {
|
|
var x = b[0] - a[0],
|
|
y = b[1] - a[1],
|
|
z = b[2] - a[2];
|
|
return x*x + y*y + z*z;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.squaredDistance}
|
|
* @function
|
|
*/
|
|
vec3.sqrDist = vec3.squaredDistance;
|
|
|
|
/**
|
|
* Calculates the length of a vec3
|
|
*
|
|
* @param {vec3} a vector to calculate length of
|
|
* @returns {Number} length of a
|
|
*/
|
|
vec3.length = function (a) {
|
|
var x = a[0],
|
|
y = a[1],
|
|
z = a[2];
|
|
return Math.sqrt(x*x + y*y + z*z);
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.length}
|
|
* @function
|
|
*/
|
|
vec3.len = vec3.length;
|
|
|
|
/**
|
|
* Calculates the squared length of a vec3
|
|
*
|
|
* @param {vec3} a vector to calculate squared length of
|
|
* @returns {Number} squared length of a
|
|
*/
|
|
vec3.squaredLength = function (a) {
|
|
var x = a[0],
|
|
y = a[1],
|
|
z = a[2];
|
|
return x*x + y*y + z*z;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec3.squaredLength}
|
|
* @function
|
|
*/
|
|
vec3.sqrLen = vec3.squaredLength;
|
|
|
|
/**
|
|
* Negates the components of a vec3
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a vector to negate
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.negate = function(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns the inverse of the components of a vec3
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a vector to invert
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.inverse = function(out, a) {
|
|
out[0] = 1.0 / a[0];
|
|
out[1] = 1.0 / a[1];
|
|
out[2] = 1.0 / a[2];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Normalize a vec3
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a vector to normalize
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.normalize = function(out, a) {
|
|
var x = a[0],
|
|
y = a[1],
|
|
z = a[2];
|
|
var len = x*x + y*y + z*z;
|
|
if (len > 0) {
|
|
//TODO: evaluate use of glm_invsqrt here?
|
|
len = 1 / Math.sqrt(len);
|
|
out[0] = a[0] * len;
|
|
out[1] = a[1] * len;
|
|
out[2] = a[2] * len;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the dot product of two vec3's
|
|
*
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {Number} dot product of a and b
|
|
*/
|
|
vec3.dot = function (a, b) {
|
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
};
|
|
|
|
/**
|
|
* Computes the cross product of two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.cross = function(out, a, b) {
|
|
var ax = a[0], ay = a[1], az = a[2],
|
|
bx = b[0], by = b[1], bz = b[2];
|
|
|
|
out[0] = ay * bz - az * by;
|
|
out[1] = az * bx - ax * bz;
|
|
out[2] = ax * by - ay * bx;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Performs a linear interpolation between two vec3's
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.lerp = function (out, a, b, t) {
|
|
var ax = a[0],
|
|
ay = a[1],
|
|
az = a[2];
|
|
out[0] = ax + t * (b[0] - ax);
|
|
out[1] = ay + t * (b[1] - ay);
|
|
out[2] = az + t * (b[2] - az);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Performs a hermite interpolation with two control points
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @param {vec3} c the third operand
|
|
* @param {vec3} d the fourth operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.hermite = function (out, a, b, c, d, t) {
|
|
var factorTimes2 = t * t,
|
|
factor1 = factorTimes2 * (2 * t - 3) + 1,
|
|
factor2 = factorTimes2 * (t - 2) + t,
|
|
factor3 = factorTimes2 * (t - 1),
|
|
factor4 = factorTimes2 * (3 - 2 * t);
|
|
|
|
out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
|
|
out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
|
|
out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Performs a bezier interpolation with two control points
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the first operand
|
|
* @param {vec3} b the second operand
|
|
* @param {vec3} c the third operand
|
|
* @param {vec3} d the fourth operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.bezier = function (out, a, b, c, d, t) {
|
|
var inverseFactor = 1 - t,
|
|
inverseFactorTimesTwo = inverseFactor * inverseFactor,
|
|
factorTimes2 = t * t,
|
|
factor1 = inverseFactorTimesTwo * inverseFactor,
|
|
factor2 = 3 * t * inverseFactorTimesTwo,
|
|
factor3 = 3 * factorTimes2 * inverseFactor,
|
|
factor4 = factorTimes2 * t;
|
|
|
|
out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
|
|
out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
|
|
out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a random vector with the given scale
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.random = function (out, scale) {
|
|
scale = scale || 1.0;
|
|
|
|
var r = glMatrix.RANDOM() * 2.0 * Math.PI;
|
|
var z = (glMatrix.RANDOM() * 2.0) - 1.0;
|
|
var zScale = Math.sqrt(1.0-z*z) * scale;
|
|
|
|
out[0] = Math.cos(r) * zScale;
|
|
out[1] = Math.sin(r) * zScale;
|
|
out[2] = z * scale;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec3 with a mat4.
|
|
* 4th vector component is implicitly '1'
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the vector to transform
|
|
* @param {mat4} m matrix to transform with
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.transformMat4 = function(out, a, m) {
|
|
var x = a[0], y = a[1], z = a[2],
|
|
w = m[3] * x + m[7] * y + m[11] * z + m[15];
|
|
w = w || 1.0;
|
|
out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
|
|
out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
|
|
out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec3 with a mat3.
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the vector to transform
|
|
* @param {mat4} m the 3x3 matrix to transform with
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.transformMat3 = function(out, a, m) {
|
|
var x = a[0], y = a[1], z = a[2];
|
|
out[0] = x * m[0] + y * m[3] + z * m[6];
|
|
out[1] = x * m[1] + y * m[4] + z * m[7];
|
|
out[2] = x * m[2] + y * m[5] + z * m[8];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec3 with a quat
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec3} a the vector to transform
|
|
* @param {quat} q quaternion to transform with
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.transformQuat = function(out, a, q) {
|
|
// benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
|
|
|
|
var x = a[0], y = a[1], z = a[2],
|
|
qx = q[0], qy = q[1], qz = q[2], qw = q[3],
|
|
|
|
// calculate quat * vec
|
|
ix = qw * x + qy * z - qz * y,
|
|
iy = qw * y + qz * x - qx * z,
|
|
iz = qw * z + qx * y - qy * x,
|
|
iw = -qx * x - qy * y - qz * z;
|
|
|
|
// calculate result * inverse quat
|
|
out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
|
out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
|
out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotate a 3D vector around the x-axis
|
|
* @param {vec3} out The receiving vec3
|
|
* @param {vec3} a The vec3 point to rotate
|
|
* @param {vec3} b The origin of the rotation
|
|
* @param {Number} c The angle of rotation
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.rotateX = function(out, a, b, c){
|
|
var p = [], r=[];
|
|
//Translate point to the origin
|
|
p[0] = a[0] - b[0];
|
|
p[1] = a[1] - b[1];
|
|
p[2] = a[2] - b[2];
|
|
|
|
//perform rotation
|
|
r[0] = p[0];
|
|
r[1] = p[1]*Math.cos(c) - p[2]*Math.sin(c);
|
|
r[2] = p[1]*Math.sin(c) + p[2]*Math.cos(c);
|
|
|
|
//translate to correct position
|
|
out[0] = r[0] + b[0];
|
|
out[1] = r[1] + b[1];
|
|
out[2] = r[2] + b[2];
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotate a 3D vector around the y-axis
|
|
* @param {vec3} out The receiving vec3
|
|
* @param {vec3} a The vec3 point to rotate
|
|
* @param {vec3} b The origin of the rotation
|
|
* @param {Number} c The angle of rotation
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.rotateY = function(out, a, b, c){
|
|
var p = [], r=[];
|
|
//Translate point to the origin
|
|
p[0] = a[0] - b[0];
|
|
p[1] = a[1] - b[1];
|
|
p[2] = a[2] - b[2];
|
|
|
|
//perform rotation
|
|
r[0] = p[2]*Math.sin(c) + p[0]*Math.cos(c);
|
|
r[1] = p[1];
|
|
r[2] = p[2]*Math.cos(c) - p[0]*Math.sin(c);
|
|
|
|
//translate to correct position
|
|
out[0] = r[0] + b[0];
|
|
out[1] = r[1] + b[1];
|
|
out[2] = r[2] + b[2];
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Rotate a 3D vector around the z-axis
|
|
* @param {vec3} out The receiving vec3
|
|
* @param {vec3} a The vec3 point to rotate
|
|
* @param {vec3} b The origin of the rotation
|
|
* @param {Number} c The angle of rotation
|
|
* @returns {vec3} out
|
|
*/
|
|
vec3.rotateZ = function(out, a, b, c){
|
|
var p = [], r=[];
|
|
//Translate point to the origin
|
|
p[0] = a[0] - b[0];
|
|
p[1] = a[1] - b[1];
|
|
p[2] = a[2] - b[2];
|
|
|
|
//perform rotation
|
|
r[0] = p[0]*Math.cos(c) - p[1]*Math.sin(c);
|
|
r[1] = p[0]*Math.sin(c) + p[1]*Math.cos(c);
|
|
r[2] = p[2];
|
|
|
|
//translate to correct position
|
|
out[0] = r[0] + b[0];
|
|
out[1] = r[1] + b[1];
|
|
out[2] = r[2] + b[2];
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Perform some operation over an array of vec3s.
|
|
*
|
|
* @param {Array} a the array of vectors to iterate over
|
|
* @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
|
|
* @param {Number} offset Number of elements to skip at the beginning of the array
|
|
* @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
|
|
* @param {Function} fn Function to call for each vector in the array
|
|
* @param {Object} [arg] additional argument to pass to fn
|
|
* @returns {Array} a
|
|
* @function
|
|
*/
|
|
vec3.forEach = (function() {
|
|
var vec = vec3.create();
|
|
|
|
return function(a, stride, offset, count, fn, arg) {
|
|
var i, l;
|
|
if(!stride) {
|
|
stride = 3;
|
|
}
|
|
|
|
if(!offset) {
|
|
offset = 0;
|
|
}
|
|
|
|
if(count) {
|
|
l = Math.min((count * stride) + offset, a.length);
|
|
} else {
|
|
l = a.length;
|
|
}
|
|
|
|
for(i = offset; i < l; i += stride) {
|
|
vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2];
|
|
fn(vec, vec, arg);
|
|
a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2];
|
|
}
|
|
|
|
return a;
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Get the angle between two 3D vectors
|
|
* @param {vec3} a The first operand
|
|
* @param {vec3} b The second operand
|
|
* @returns {Number} The angle in radians
|
|
*/
|
|
vec3.angle = function(a, b) {
|
|
|
|
var tempA = vec3.fromValues(a[0], a[1], a[2]);
|
|
var tempB = vec3.fromValues(b[0], b[1], b[2]);
|
|
|
|
vec3.normalize(tempA, tempA);
|
|
vec3.normalize(tempB, tempB);
|
|
|
|
var cosine = vec3.dot(tempA, tempB);
|
|
|
|
if(cosine > 1.0){
|
|
return 0;
|
|
} else {
|
|
return Math.acos(cosine);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns a string representation of a vector
|
|
*
|
|
* @param {vec3} vec vector to represent as a string
|
|
* @returns {String} string representation of the vector
|
|
*/
|
|
vec3.str = function (a) {
|
|
return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
|
|
};
|
|
|
|
module.exports = vec3;
|
|
|
|
|
|
/***/ },
|
|
/* 15 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 4 Dimensional Vector
|
|
* @name vec4
|
|
*/
|
|
var vec4 = {};
|
|
|
|
/**
|
|
* Creates a new, empty vec4
|
|
*
|
|
* @returns {vec4} a new 4D vector
|
|
*/
|
|
vec4.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(4);
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new vec4 initialized with values from an existing vector
|
|
*
|
|
* @param {vec4} a vector to clone
|
|
* @returns {vec4} a new 4D vector
|
|
*/
|
|
vec4.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(4);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new vec4 initialized with the given values
|
|
*
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @param {Number} z Z component
|
|
* @param {Number} w W component
|
|
* @returns {vec4} a new 4D vector
|
|
*/
|
|
vec4.fromValues = function(x, y, z, w) {
|
|
var out = new glMatrix.ARRAY_TYPE(4);
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
out[3] = w;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one vec4 to another
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the source vector
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set the components of a vec4 to the given values
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @param {Number} z Z component
|
|
* @param {Number} w W component
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.set = function(out, x, y, z, w) {
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
out[3] = w;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two vec4's
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.add = function(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Subtracts vector b from vector a
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.subtract = function(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
out[3] = a[3] - b[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.subtract}
|
|
* @function
|
|
*/
|
|
vec4.sub = vec4.subtract;
|
|
|
|
/**
|
|
* Multiplies two vec4's
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.multiply = function(out, a, b) {
|
|
out[0] = a[0] * b[0];
|
|
out[1] = a[1] * b[1];
|
|
out[2] = a[2] * b[2];
|
|
out[3] = a[3] * b[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.multiply}
|
|
* @function
|
|
*/
|
|
vec4.mul = vec4.multiply;
|
|
|
|
/**
|
|
* Divides two vec4's
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.divide = function(out, a, b) {
|
|
out[0] = a[0] / b[0];
|
|
out[1] = a[1] / b[1];
|
|
out[2] = a[2] / b[2];
|
|
out[3] = a[3] / b[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.divide}
|
|
* @function
|
|
*/
|
|
vec4.div = vec4.divide;
|
|
|
|
/**
|
|
* Returns the minimum of two vec4's
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.min = function(out, a, b) {
|
|
out[0] = Math.min(a[0], b[0]);
|
|
out[1] = Math.min(a[1], b[1]);
|
|
out[2] = Math.min(a[2], b[2]);
|
|
out[3] = Math.min(a[3], b[3]);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns the maximum of two vec4's
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.max = function(out, a, b) {
|
|
out[0] = Math.max(a[0], b[0]);
|
|
out[1] = Math.max(a[1], b[1]);
|
|
out[2] = Math.max(a[2], b[2]);
|
|
out[3] = Math.max(a[3], b[3]);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales a vec4 by a scalar number
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the vector to scale
|
|
* @param {Number} b amount to scale the vector by
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.scale = function(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two vec4's after scaling the second operand by a scalar value
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @param {Number} scale the amount to scale b by before adding
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.scaleAndAdd = function(out, a, b, scale) {
|
|
out[0] = a[0] + (b[0] * scale);
|
|
out[1] = a[1] + (b[1] * scale);
|
|
out[2] = a[2] + (b[2] * scale);
|
|
out[3] = a[3] + (b[3] * scale);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the euclidian distance between two vec4's
|
|
*
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {Number} distance between a and b
|
|
*/
|
|
vec4.distance = function(a, b) {
|
|
var x = b[0] - a[0],
|
|
y = b[1] - a[1],
|
|
z = b[2] - a[2],
|
|
w = b[3] - a[3];
|
|
return Math.sqrt(x*x + y*y + z*z + w*w);
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.distance}
|
|
* @function
|
|
*/
|
|
vec4.dist = vec4.distance;
|
|
|
|
/**
|
|
* Calculates the squared euclidian distance between two vec4's
|
|
*
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {Number} squared distance between a and b
|
|
*/
|
|
vec4.squaredDistance = function(a, b) {
|
|
var x = b[0] - a[0],
|
|
y = b[1] - a[1],
|
|
z = b[2] - a[2],
|
|
w = b[3] - a[3];
|
|
return x*x + y*y + z*z + w*w;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.squaredDistance}
|
|
* @function
|
|
*/
|
|
vec4.sqrDist = vec4.squaredDistance;
|
|
|
|
/**
|
|
* Calculates the length of a vec4
|
|
*
|
|
* @param {vec4} a vector to calculate length of
|
|
* @returns {Number} length of a
|
|
*/
|
|
vec4.length = function (a) {
|
|
var x = a[0],
|
|
y = a[1],
|
|
z = a[2],
|
|
w = a[3];
|
|
return Math.sqrt(x*x + y*y + z*z + w*w);
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.length}
|
|
* @function
|
|
*/
|
|
vec4.len = vec4.length;
|
|
|
|
/**
|
|
* Calculates the squared length of a vec4
|
|
*
|
|
* @param {vec4} a vector to calculate squared length of
|
|
* @returns {Number} squared length of a
|
|
*/
|
|
vec4.squaredLength = function (a) {
|
|
var x = a[0],
|
|
y = a[1],
|
|
z = a[2],
|
|
w = a[3];
|
|
return x*x + y*y + z*z + w*w;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec4.squaredLength}
|
|
* @function
|
|
*/
|
|
vec4.sqrLen = vec4.squaredLength;
|
|
|
|
/**
|
|
* Negates the components of a vec4
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a vector to negate
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.negate = function(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = -a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns the inverse of the components of a vec4
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a vector to invert
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.inverse = function(out, a) {
|
|
out[0] = 1.0 / a[0];
|
|
out[1] = 1.0 / a[1];
|
|
out[2] = 1.0 / a[2];
|
|
out[3] = 1.0 / a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Normalize a vec4
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a vector to normalize
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.normalize = function(out, a) {
|
|
var x = a[0],
|
|
y = a[1],
|
|
z = a[2],
|
|
w = a[3];
|
|
var len = x*x + y*y + z*z + w*w;
|
|
if (len > 0) {
|
|
len = 1 / Math.sqrt(len);
|
|
out[0] = x * len;
|
|
out[1] = y * len;
|
|
out[2] = z * len;
|
|
out[3] = w * len;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the dot product of two vec4's
|
|
*
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @returns {Number} dot product of a and b
|
|
*/
|
|
vec4.dot = function (a, b) {
|
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
|
|
};
|
|
|
|
/**
|
|
* Performs a linear interpolation between two vec4's
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the first operand
|
|
* @param {vec4} b the second operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.lerp = function (out, a, b, t) {
|
|
var ax = a[0],
|
|
ay = a[1],
|
|
az = a[2],
|
|
aw = a[3];
|
|
out[0] = ax + t * (b[0] - ax);
|
|
out[1] = ay + t * (b[1] - ay);
|
|
out[2] = az + t * (b[2] - az);
|
|
out[3] = aw + t * (b[3] - aw);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a random vector with the given scale
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.random = function (out, scale) {
|
|
scale = scale || 1.0;
|
|
|
|
//TODO: This is a pretty awful way of doing this. Find something better.
|
|
out[0] = glMatrix.RANDOM();
|
|
out[1] = glMatrix.RANDOM();
|
|
out[2] = glMatrix.RANDOM();
|
|
out[3] = glMatrix.RANDOM();
|
|
vec4.normalize(out, out);
|
|
vec4.scale(out, out, scale);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec4 with a mat4.
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the vector to transform
|
|
* @param {mat4} m matrix to transform with
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.transformMat4 = function(out, a, m) {
|
|
var x = a[0], y = a[1], z = a[2], w = a[3];
|
|
out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
|
|
out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
|
|
out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
|
out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec4 with a quat
|
|
*
|
|
* @param {vec4} out the receiving vector
|
|
* @param {vec4} a the vector to transform
|
|
* @param {quat} q quaternion to transform with
|
|
* @returns {vec4} out
|
|
*/
|
|
vec4.transformQuat = function(out, a, q) {
|
|
var x = a[0], y = a[1], z = a[2],
|
|
qx = q[0], qy = q[1], qz = q[2], qw = q[3],
|
|
|
|
// calculate quat * vec
|
|
ix = qw * x + qy * z - qz * y,
|
|
iy = qw * y + qz * x - qx * z,
|
|
iz = qw * z + qx * y - qy * x,
|
|
iw = -qx * x - qy * y - qz * z;
|
|
|
|
// calculate result * inverse quat
|
|
out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
|
out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
|
out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
|
out[3] = a[3];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Perform some operation over an array of vec4s.
|
|
*
|
|
* @param {Array} a the array of vectors to iterate over
|
|
* @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
|
|
* @param {Number} offset Number of elements to skip at the beginning of the array
|
|
* @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
|
|
* @param {Function} fn Function to call for each vector in the array
|
|
* @param {Object} [arg] additional argument to pass to fn
|
|
* @returns {Array} a
|
|
* @function
|
|
*/
|
|
vec4.forEach = (function() {
|
|
var vec = vec4.create();
|
|
|
|
return function(a, stride, offset, count, fn, arg) {
|
|
var i, l;
|
|
if(!stride) {
|
|
stride = 4;
|
|
}
|
|
|
|
if(!offset) {
|
|
offset = 0;
|
|
}
|
|
|
|
if(count) {
|
|
l = Math.min((count * stride) + offset, a.length);
|
|
} else {
|
|
l = a.length;
|
|
}
|
|
|
|
for(i = offset; i < l; i += stride) {
|
|
vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3];
|
|
fn(vec, vec, arg);
|
|
a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3];
|
|
}
|
|
|
|
return a;
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Returns a string representation of a vector
|
|
*
|
|
* @param {vec4} vec vector to represent as a string
|
|
* @returns {String} string representation of the vector
|
|
*/
|
|
vec4.str = function (a) {
|
|
return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
|
|
};
|
|
|
|
module.exports = vec4;
|
|
|
|
|
|
/***/ },
|
|
/* 16 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
|
|
|
|
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 glMatrix = __webpack_require__(8);
|
|
|
|
/**
|
|
* @class 2 Dimensional Vector
|
|
* @name vec2
|
|
*/
|
|
var vec2 = {};
|
|
|
|
/**
|
|
* Creates a new, empty vec2
|
|
*
|
|
* @returns {vec2} a new 2D vector
|
|
*/
|
|
vec2.create = function() {
|
|
var out = new glMatrix.ARRAY_TYPE(2);
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new vec2 initialized with values from an existing vector
|
|
*
|
|
* @param {vec2} a vector to clone
|
|
* @returns {vec2} a new 2D vector
|
|
*/
|
|
vec2.clone = function(a) {
|
|
var out = new glMatrix.ARRAY_TYPE(2);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates a new vec2 initialized with the given values
|
|
*
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @returns {vec2} a new 2D vector
|
|
*/
|
|
vec2.fromValues = function(x, y) {
|
|
var out = new glMatrix.ARRAY_TYPE(2);
|
|
out[0] = x;
|
|
out[1] = y;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Copy the values from one vec2 to another
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the source vector
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.copy = function(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Set the components of a vec2 to the given values
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {Number} x X component
|
|
* @param {Number} y Y component
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.set = function(out, x, y) {
|
|
out[0] = x;
|
|
out[1] = y;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two vec2's
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.add = function(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Subtracts vector b from vector a
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.subtract = function(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.subtract}
|
|
* @function
|
|
*/
|
|
vec2.sub = vec2.subtract;
|
|
|
|
/**
|
|
* Multiplies two vec2's
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.multiply = function(out, a, b) {
|
|
out[0] = a[0] * b[0];
|
|
out[1] = a[1] * b[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.multiply}
|
|
* @function
|
|
*/
|
|
vec2.mul = vec2.multiply;
|
|
|
|
/**
|
|
* Divides two vec2's
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.divide = function(out, a, b) {
|
|
out[0] = a[0] / b[0];
|
|
out[1] = a[1] / b[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.divide}
|
|
* @function
|
|
*/
|
|
vec2.div = vec2.divide;
|
|
|
|
/**
|
|
* Returns the minimum of two vec2's
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.min = function(out, a, b) {
|
|
out[0] = Math.min(a[0], b[0]);
|
|
out[1] = Math.min(a[1], b[1]);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns the maximum of two vec2's
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.max = function(out, a, b) {
|
|
out[0] = Math.max(a[0], b[0]);
|
|
out[1] = Math.max(a[1], b[1]);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Scales a vec2 by a scalar number
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to scale
|
|
* @param {Number} b amount to scale the vector by
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.scale = function(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Adds two vec2's after scaling the second operand by a scalar value
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @param {Number} scale the amount to scale b by before adding
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.scaleAndAdd = function(out, a, b, scale) {
|
|
out[0] = a[0] + (b[0] * scale);
|
|
out[1] = a[1] + (b[1] * scale);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the euclidian distance between two vec2's
|
|
*
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {Number} distance between a and b
|
|
*/
|
|
vec2.distance = function(a, b) {
|
|
var x = b[0] - a[0],
|
|
y = b[1] - a[1];
|
|
return Math.sqrt(x*x + y*y);
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.distance}
|
|
* @function
|
|
*/
|
|
vec2.dist = vec2.distance;
|
|
|
|
/**
|
|
* Calculates the squared euclidian distance between two vec2's
|
|
*
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {Number} squared distance between a and b
|
|
*/
|
|
vec2.squaredDistance = function(a, b) {
|
|
var x = b[0] - a[0],
|
|
y = b[1] - a[1];
|
|
return x*x + y*y;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.squaredDistance}
|
|
* @function
|
|
*/
|
|
vec2.sqrDist = vec2.squaredDistance;
|
|
|
|
/**
|
|
* Calculates the length of a vec2
|
|
*
|
|
* @param {vec2} a vector to calculate length of
|
|
* @returns {Number} length of a
|
|
*/
|
|
vec2.length = function (a) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
return Math.sqrt(x*x + y*y);
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.length}
|
|
* @function
|
|
*/
|
|
vec2.len = vec2.length;
|
|
|
|
/**
|
|
* Calculates the squared length of a vec2
|
|
*
|
|
* @param {vec2} a vector to calculate squared length of
|
|
* @returns {Number} squared length of a
|
|
*/
|
|
vec2.squaredLength = function (a) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
return x*x + y*y;
|
|
};
|
|
|
|
/**
|
|
* Alias for {@link vec2.squaredLength}
|
|
* @function
|
|
*/
|
|
vec2.sqrLen = vec2.squaredLength;
|
|
|
|
/**
|
|
* Negates the components of a vec2
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a vector to negate
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.negate = function(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Returns the inverse of the components of a vec2
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a vector to invert
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.inverse = function(out, a) {
|
|
out[0] = 1.0 / a[0];
|
|
out[1] = 1.0 / a[1];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Normalize a vec2
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a vector to normalize
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.normalize = function(out, a) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
var len = x*x + y*y;
|
|
if (len > 0) {
|
|
//TODO: evaluate use of glm_invsqrt here?
|
|
len = 1 / Math.sqrt(len);
|
|
out[0] = a[0] * len;
|
|
out[1] = a[1] * len;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Calculates the dot product of two vec2's
|
|
*
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {Number} dot product of a and b
|
|
*/
|
|
vec2.dot = function (a, b) {
|
|
return a[0] * b[0] + a[1] * b[1];
|
|
};
|
|
|
|
/**
|
|
* Computes the cross product of two vec2's
|
|
* Note that the cross product must by definition produce a 3D vector
|
|
*
|
|
* @param {vec3} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {vec3} out
|
|
*/
|
|
vec2.cross = function(out, a, b) {
|
|
var z = a[0] * b[1] - a[1] * b[0];
|
|
out[0] = out[1] = 0;
|
|
out[2] = z;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Performs a linear interpolation between two vec2's
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @param {Number} t interpolation amount between the two inputs
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.lerp = function (out, a, b, t) {
|
|
var ax = a[0],
|
|
ay = a[1];
|
|
out[0] = ax + t * (b[0] - ax);
|
|
out[1] = ay + t * (b[1] - ay);
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Generates a random vector with the given scale
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.random = function (out, scale) {
|
|
scale = scale || 1.0;
|
|
var r = glMatrix.RANDOM() * 2.0 * Math.PI;
|
|
out[0] = Math.cos(r) * scale;
|
|
out[1] = Math.sin(r) * scale;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec2 with a mat2
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to transform
|
|
* @param {mat2} m matrix to transform with
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.transformMat2 = function(out, a, m) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
out[0] = m[0] * x + m[2] * y;
|
|
out[1] = m[1] * x + m[3] * y;
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec2 with a mat2d
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to transform
|
|
* @param {mat2d} m matrix to transform with
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.transformMat2d = function(out, a, m) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
out[0] = m[0] * x + m[2] * y + m[4];
|
|
out[1] = m[1] * x + m[3] * y + m[5];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec2 with a mat3
|
|
* 3rd vector component is implicitly '1'
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to transform
|
|
* @param {mat3} m matrix to transform with
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.transformMat3 = function(out, a, m) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
out[0] = m[0] * x + m[3] * y + m[6];
|
|
out[1] = m[1] * x + m[4] * y + m[7];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Transforms the vec2 with a mat4
|
|
* 3rd vector component is implicitly '0'
|
|
* 4th vector component is implicitly '1'
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to transform
|
|
* @param {mat4} m matrix to transform with
|
|
* @returns {vec2} out
|
|
*/
|
|
vec2.transformMat4 = function(out, a, m) {
|
|
var x = a[0],
|
|
y = a[1];
|
|
out[0] = m[0] * x + m[4] * y + m[12];
|
|
out[1] = m[1] * x + m[5] * y + m[13];
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Perform some operation over an array of vec2s.
|
|
*
|
|
* @param {Array} a the array of vectors to iterate over
|
|
* @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
|
|
* @param {Number} offset Number of elements to skip at the beginning of the array
|
|
* @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
|
|
* @param {Function} fn Function to call for each vector in the array
|
|
* @param {Object} [arg] additional argument to pass to fn
|
|
* @returns {Array} a
|
|
* @function
|
|
*/
|
|
vec2.forEach = (function() {
|
|
var vec = vec2.create();
|
|
|
|
return function(a, stride, offset, count, fn, arg) {
|
|
var i, l;
|
|
if(!stride) {
|
|
stride = 2;
|
|
}
|
|
|
|
if(!offset) {
|
|
offset = 0;
|
|
}
|
|
|
|
if(count) {
|
|
l = Math.min((count * stride) + offset, a.length);
|
|
} else {
|
|
l = a.length;
|
|
}
|
|
|
|
for(i = offset; i < l; i += stride) {
|
|
vec[0] = a[i]; vec[1] = a[i+1];
|
|
fn(vec, vec, arg);
|
|
a[i] = vec[0]; a[i+1] = vec[1];
|
|
}
|
|
|
|
return a;
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Returns a string representation of a vector
|
|
*
|
|
* @param {vec2} vec vector to represent as a string
|
|
* @returns {String} string representation of the vector
|
|
*/
|
|
vec2.str = function (a) {
|
|
return 'vec2(' + a[0] + ', ' + a[1] + ')';
|
|
};
|
|
|
|
module.exports = vec2;
|
|
|
|
|
|
/***/ },
|
|
/* 17 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports["default"] = {
|
|
init: function init(arr, val) {
|
|
var l = arr.length;
|
|
while (l--) {
|
|
arr[l] = val;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Shuffles the content of an array
|
|
* @return {Array} the array itself shuffled
|
|
*/
|
|
shuffle: function shuffle(arr) {
|
|
var i = arr.length - 1,
|
|
j,
|
|
x;
|
|
for (i; i >= 0; i--) {
|
|
j = Math.floor(Math.random() * i);
|
|
x = arr[i];
|
|
arr[i] = arr[j];
|
|
arr[j] = x;
|
|
}
|
|
return arr;
|
|
},
|
|
|
|
toPointList: function toPointList(arr) {
|
|
var i,
|
|
j,
|
|
row = [],
|
|
rows = [];
|
|
for (i = 0; i < arr.length; i++) {
|
|
row = [];
|
|
for (j = 0; j < arr[i].length; j++) {
|
|
row[j] = arr[i][j];
|
|
}
|
|
rows[i] = "[" + row.join(",") + "]";
|
|
}
|
|
return "[" + rows.join(",\r\n") + "]";
|
|
},
|
|
|
|
/**
|
|
* returns the elements which's score is bigger than the threshold
|
|
* @return {Array} the reduced array
|
|
*/
|
|
threshold: function threshold(arr, _threshold, scoreFunc) {
|
|
var i,
|
|
queue = [];
|
|
for (i = 0; i < arr.length; i++) {
|
|
if (scoreFunc.apply(arr, [arr[i]]) >= _threshold) {
|
|
queue.push(arr[i]);
|
|
}
|
|
}
|
|
return queue;
|
|
},
|
|
|
|
maxIndex: function maxIndex(arr) {
|
|
var i,
|
|
max = 0;
|
|
for (i = 0; i < arr.length; i++) {
|
|
if (arr[i] > arr[max]) {
|
|
max = i;
|
|
}
|
|
}
|
|
return max;
|
|
},
|
|
|
|
max: function max(arr) {
|
|
var i,
|
|
max = 0;
|
|
for (i = 0; i < arr.length; i++) {
|
|
if (arr[i] > max) {
|
|
max = arr[i];
|
|
}
|
|
}
|
|
return max;
|
|
},
|
|
|
|
sum: function sum(arr) {
|
|
var length = arr.length,
|
|
sum = 0;
|
|
|
|
while (length--) {
|
|
sum += arr[length];
|
|
}
|
|
return sum;
|
|
}
|
|
};
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 18 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _image_wrapper = __webpack_require__(3);
|
|
|
|
var _image_wrapper2 = _interopRequireDefault(_image_wrapper);
|
|
|
|
var _cv_utils = __webpack_require__(5);
|
|
|
|
var _cv_utils2 = _interopRequireDefault(_cv_utils);
|
|
|
|
var _rasterizer = __webpack_require__(19);
|
|
|
|
var _rasterizer2 = _interopRequireDefault(_rasterizer);
|
|
|
|
var _tracer = __webpack_require__(20);
|
|
|
|
var _tracer2 = _interopRequireDefault(_tracer);
|
|
|
|
var _skeletonizer2 = __webpack_require__(21);
|
|
|
|
var _skeletonizer3 = _interopRequireDefault(_skeletonizer2);
|
|
|
|
var _array_helper = __webpack_require__(17);
|
|
|
|
var _array_helper2 = _interopRequireDefault(_array_helper);
|
|
|
|
var _image_debug = __webpack_require__(22);
|
|
|
|
var _image_debug2 = _interopRequireDefault(_image_debug);
|
|
|
|
var _glMatrix = __webpack_require__(7);
|
|
|
|
var _glMatrix2 = _interopRequireDefault(_glMatrix);
|
|
|
|
var _config,
|
|
_currentImageWrapper,
|
|
_skelImageWrapper,
|
|
_subImageWrapper,
|
|
_labelImageWrapper,
|
|
_patchGrid,
|
|
_patchLabelGrid,
|
|
_imageToPatchGrid,
|
|
_binaryImageWrapper,
|
|
_patchSize,
|
|
_canvasContainer = {
|
|
ctx: {
|
|
binary: null
|
|
},
|
|
dom: {
|
|
binary: null
|
|
}
|
|
},
|
|
_numPatches = { x: 0, y: 0 },
|
|
_inputImageWrapper,
|
|
_skeletonizer,
|
|
vec2 = _glMatrix2['default'].vec2,
|
|
mat2 = _glMatrix2['default'].mat2;
|
|
|
|
function initBuffers() {
|
|
var skeletonImageData;
|
|
|
|
if (_config.halfSample) {
|
|
_currentImageWrapper = new _image_wrapper2['default']({
|
|
x: _inputImageWrapper.size.x / 2 | 0,
|
|
y: _inputImageWrapper.size.y / 2 | 0
|
|
});
|
|
} else {
|
|
_currentImageWrapper = _inputImageWrapper;
|
|
}
|
|
|
|
_patchSize = _cv_utils2['default'].calculatePatchSize(_config.patchSize, _currentImageWrapper.size);
|
|
|
|
_numPatches.x = _currentImageWrapper.size.x / _patchSize.x | 0;
|
|
_numPatches.y = _currentImageWrapper.size.y / _patchSize.y | 0;
|
|
|
|
_binaryImageWrapper = new _image_wrapper2['default'](_currentImageWrapper.size, undefined, Uint8Array, false);
|
|
|
|
_labelImageWrapper = new _image_wrapper2['default'](_patchSize, undefined, Array, true);
|
|
|
|
skeletonImageData = new ArrayBuffer(64 * 1024);
|
|
_subImageWrapper = new _image_wrapper2['default'](_patchSize, new Uint8Array(skeletonImageData, 0, _patchSize.x * _patchSize.y));
|
|
_skelImageWrapper = new _image_wrapper2['default'](_patchSize, new Uint8Array(skeletonImageData, _patchSize.x * _patchSize.y * 3, _patchSize.x * _patchSize.y), undefined, true);
|
|
_skeletonizer = (0, _skeletonizer3['default'])(typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : global, {
|
|
size: _patchSize.x
|
|
}, skeletonImageData);
|
|
|
|
_imageToPatchGrid = new _image_wrapper2['default']({
|
|
x: _currentImageWrapper.size.x / _subImageWrapper.size.x | 0,
|
|
y: _currentImageWrapper.size.y / _subImageWrapper.size.y | 0
|
|
}, undefined, Array, true);
|
|
_patchGrid = new _image_wrapper2['default'](_imageToPatchGrid.size, undefined, undefined, true);
|
|
_patchLabelGrid = new _image_wrapper2['default'](_imageToPatchGrid.size, undefined, Int32Array, true);
|
|
}
|
|
|
|
function initCanvas() {
|
|
if (_config.useWorker || typeof document === 'undefined') {
|
|
return;
|
|
}
|
|
_canvasContainer.dom.binary = document.createElement("canvas");
|
|
_canvasContainer.dom.binary.className = "binaryBuffer";
|
|
if (_config.showCanvas === true) {
|
|
document.querySelector("#debug").appendChild(_canvasContainer.dom.binary);
|
|
}
|
|
_canvasContainer.ctx.binary = _canvasContainer.dom.binary.getContext("2d");
|
|
_canvasContainer.dom.binary.width = _binaryImageWrapper.size.x;
|
|
_canvasContainer.dom.binary.height = _binaryImageWrapper.size.y;
|
|
}
|
|
|
|
/**
|
|
* Creates a bounding box which encloses all the given patches
|
|
* @returns {Array} The minimal bounding box
|
|
*/
|
|
function boxFromPatches(patches) {
|
|
var overAvg,
|
|
i,
|
|
j,
|
|
patch,
|
|
transMat,
|
|
minx = _binaryImageWrapper.size.x,
|
|
miny = _binaryImageWrapper.size.y,
|
|
maxx = -_binaryImageWrapper.size.x,
|
|
maxy = -_binaryImageWrapper.size.y,
|
|
box,
|
|
scale;
|
|
|
|
// draw all patches which are to be taken into consideration
|
|
overAvg = 0;
|
|
for (i = 0; i < patches.length; i++) {
|
|
patch = patches[i];
|
|
overAvg += patch.rad;
|
|
if (_config.showPatches) {
|
|
_image_debug2['default'].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "red" });
|
|
}
|
|
}
|
|
|
|
overAvg /= patches.length;
|
|
overAvg = (overAvg * 180 / Math.PI + 90) % 180 - 90;
|
|
if (overAvg < 0) {
|
|
overAvg += 180;
|
|
}
|
|
|
|
overAvg = (180 - overAvg) * Math.PI / 180;
|
|
transMat = mat2.clone([Math.cos(overAvg), Math.sin(overAvg), -Math.sin(overAvg), Math.cos(overAvg)]);
|
|
|
|
// iterate over patches and rotate by angle
|
|
for (i = 0; i < patches.length; i++) {
|
|
patch = patches[i];
|
|
for (j = 0; j < 4; j++) {
|
|
vec2.transformMat2(patch.box[j], patch.box[j], transMat);
|
|
}
|
|
|
|
if (_config.boxFromPatches.showTransformed) {
|
|
_image_debug2['default'].drawPath(patch.box, { x: 0, y: 1 }, _canvasContainer.ctx.binary, { color: '#99ff00', lineWidth: 2 });
|
|
}
|
|
}
|
|
|
|
// find bounding box
|
|
for (i = 0; i < patches.length; i++) {
|
|
patch = patches[i];
|
|
for (j = 0; j < 4; j++) {
|
|
if (patch.box[j][0] < minx) {
|
|
minx = patch.box[j][0];
|
|
}
|
|
if (patch.box[j][0] > maxx) {
|
|
maxx = patch.box[j][0];
|
|
}
|
|
if (patch.box[j][1] < miny) {
|
|
miny = patch.box[j][1];
|
|
}
|
|
if (patch.box[j][1] > maxy) {
|
|
maxy = patch.box[j][1];
|
|
}
|
|
}
|
|
}
|
|
|
|
box = [[minx, miny], [maxx, miny], [maxx, maxy], [minx, maxy]];
|
|
|
|
if (_config.boxFromPatches.showTransformedBox) {
|
|
_image_debug2['default'].drawPath(box, { x: 0, y: 1 }, _canvasContainer.ctx.binary, { color: '#ff0000', lineWidth: 2 });
|
|
}
|
|
|
|
scale = _config.halfSample ? 2 : 1;
|
|
// reverse rotation;
|
|
transMat = mat2.invert(transMat, transMat);
|
|
for (j = 0; j < 4; j++) {
|
|
vec2.transformMat2(box[j], box[j], transMat);
|
|
}
|
|
|
|
if (_config.boxFromPatches.showBB) {
|
|
_image_debug2['default'].drawPath(box, { x: 0, y: 1 }, _canvasContainer.ctx.binary, { color: '#ff0000', lineWidth: 2 });
|
|
}
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
vec2.scale(box[j], box[j], scale);
|
|
}
|
|
|
|
return box;
|
|
}
|
|
|
|
/**
|
|
* Creates a binary image of the current image
|
|
*/
|
|
function binarizeImage() {
|
|
_cv_utils2['default'].otsuThreshold(_currentImageWrapper, _binaryImageWrapper);
|
|
_binaryImageWrapper.zeroBorder();
|
|
if (_config.showCanvas) {
|
|
_binaryImageWrapper.show(_canvasContainer.dom.binary, 255);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Iterate over the entire image
|
|
* extract patches
|
|
*/
|
|
function findPatches() {
|
|
var i,
|
|
j,
|
|
x,
|
|
y,
|
|
moments,
|
|
patchesFound = [],
|
|
rasterizer,
|
|
rasterResult,
|
|
patch;
|
|
for (i = 0; i < _numPatches.x; i++) {
|
|
for (j = 0; j < _numPatches.y; j++) {
|
|
x = _subImageWrapper.size.x * i;
|
|
y = _subImageWrapper.size.y * j;
|
|
|
|
// seperate parts
|
|
skeletonize(x, y);
|
|
|
|
// Rasterize, find individual bars
|
|
_skelImageWrapper.zeroBorder();
|
|
_array_helper2['default'].init(_labelImageWrapper.data, 0);
|
|
rasterizer = _rasterizer2['default'].create(_skelImageWrapper, _labelImageWrapper);
|
|
rasterResult = rasterizer.rasterize(0);
|
|
|
|
if (_config.showLabels) {
|
|
_labelImageWrapper.overlay(_canvasContainer.dom.binary, Math.floor(360 / rasterResult.count), { x: x, y: y });
|
|
}
|
|
|
|
// calculate moments from the skeletonized patch
|
|
moments = _labelImageWrapper.moments(rasterResult.count);
|
|
|
|
// extract eligible patches
|
|
patchesFound = patchesFound.concat(describePatch(moments, [i, j], x, y));
|
|
}
|
|
}
|
|
|
|
if (_config.showFoundPatches) {
|
|
for (i = 0; i < patchesFound.length; i++) {
|
|
patch = patchesFound[i];
|
|
_image_debug2['default'].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "#99ff00", lineWidth: 2 });
|
|
}
|
|
}
|
|
|
|
return patchesFound;
|
|
}
|
|
|
|
/**
|
|
* Finds those connected areas which contain at least 6 patches
|
|
* and returns them ordered DESC by the number of contained patches
|
|
* @param {Number} maxLabel
|
|
*/
|
|
function findBiggestConnectedAreas(maxLabel) {
|
|
var i,
|
|
sum,
|
|
labelHist = [],
|
|
topLabels = [];
|
|
|
|
for (i = 0; i < maxLabel; i++) {
|
|
labelHist.push(0);
|
|
}
|
|
sum = _patchLabelGrid.data.length;
|
|
while (sum--) {
|
|
if (_patchLabelGrid.data[sum] > 0) {
|
|
labelHist[_patchLabelGrid.data[sum] - 1]++;
|
|
}
|
|
}
|
|
|
|
labelHist = labelHist.map(function (val, idx) {
|
|
return {
|
|
val: val,
|
|
label: idx + 1
|
|
};
|
|
});
|
|
|
|
labelHist.sort(function (a, b) {
|
|
return b.val - a.val;
|
|
});
|
|
|
|
// extract top areas with at least 6 patches present
|
|
topLabels = labelHist.filter(function (el) {
|
|
return el.val >= 5;
|
|
});
|
|
|
|
return topLabels;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function findBoxes(topLabels, maxLabel) {
|
|
var i,
|
|
j,
|
|
sum,
|
|
patches = [],
|
|
patch,
|
|
box,
|
|
boxes = [],
|
|
hsv = [0, 1, 1],
|
|
rgb = [0, 0, 0];
|
|
|
|
for (i = 0; i < topLabels.length; i++) {
|
|
sum = _patchLabelGrid.data.length;
|
|
patches.length = 0;
|
|
while (sum--) {
|
|
if (_patchLabelGrid.data[sum] === topLabels[i].label) {
|
|
patch = _imageToPatchGrid.data[sum];
|
|
patches.push(patch);
|
|
}
|
|
}
|
|
box = boxFromPatches(patches);
|
|
if (box) {
|
|
boxes.push(box);
|
|
|
|
// draw patch-labels if requested
|
|
if (_config.showRemainingPatchLabels) {
|
|
for (j = 0; j < patches.length; j++) {
|
|
patch = patches[j];
|
|
hsv[0] = topLabels[i].label / (maxLabel + 1) * 360;
|
|
_cv_utils2['default'].hsv2rgb(hsv, rgb);
|
|
_image_debug2['default'].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "rgb(" + rgb.join(",") + ")", lineWidth: 2 });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return boxes;
|
|
}
|
|
|
|
/**
|
|
* Find similar moments (via cluster)
|
|
* @param {Object} moments
|
|
*/
|
|
function similarMoments(moments) {
|
|
var clusters = _cv_utils2['default'].cluster(moments, 0.90);
|
|
var topCluster = _cv_utils2['default'].topGeneric(clusters, 1, function (e) {
|
|
return e.getPoints().length;
|
|
});
|
|
var points = [],
|
|
result = [];
|
|
if (topCluster.length === 1) {
|
|
points = topCluster[0].item.getPoints();
|
|
for (var i = 0; i < points.length; i++) {
|
|
result.push(points[i].point);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function skeletonize(x, y) {
|
|
_binaryImageWrapper.subImageAsCopy(_subImageWrapper, _cv_utils2['default'].imageRef(x, y));
|
|
_skeletonizer.skeletonize();
|
|
|
|
// Show skeleton if requested
|
|
if (_config.showSkeleton) {
|
|
_skelImageWrapper.overlay(_canvasContainer.dom.binary, 360, _cv_utils2['default'].imageRef(x, y));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extracts and describes those patches which seem to contain a barcode pattern
|
|
* @param {Array} moments
|
|
* @param {Object} patchPos,
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @returns {Array} list of patches
|
|
*/
|
|
function describePatch(moments, patchPos, x, y) {
|
|
var k,
|
|
avg,
|
|
eligibleMoments = [],
|
|
matchingMoments,
|
|
patch,
|
|
patchesFound = [],
|
|
minComponentWeight = Math.ceil(_patchSize.x / 3);
|
|
|
|
if (moments.length >= 2) {
|
|
// only collect moments which's area covers at least minComponentWeight pixels.
|
|
for (k = 0; k < moments.length; k++) {
|
|
if (moments[k].m00 > minComponentWeight) {
|
|
eligibleMoments.push(moments[k]);
|
|
}
|
|
}
|
|
|
|
// if at least 2 moments are found which have at least minComponentWeights covered
|
|
if (eligibleMoments.length >= 2) {
|
|
matchingMoments = similarMoments(eligibleMoments);
|
|
avg = 0;
|
|
// determine the similarity of the moments
|
|
for (k = 0; k < matchingMoments.length; k++) {
|
|
avg += matchingMoments[k].rad;
|
|
}
|
|
|
|
// Only two of the moments are allowed not to fit into the equation
|
|
// add the patch to the set
|
|
if (matchingMoments.length > 1 && matchingMoments.length >= eligibleMoments.length / 4 * 3 && matchingMoments.length > moments.length / 4) {
|
|
avg /= matchingMoments.length;
|
|
patch = {
|
|
index: patchPos[1] * _numPatches.x + patchPos[0],
|
|
pos: {
|
|
x: x,
|
|
y: y
|
|
},
|
|
box: [vec2.clone([x, y]), vec2.clone([x + _subImageWrapper.size.x, y]), vec2.clone([x + _subImageWrapper.size.x, y + _subImageWrapper.size.y]), vec2.clone([x, y + _subImageWrapper.size.y])],
|
|
moments: matchingMoments,
|
|
rad: avg,
|
|
vec: vec2.clone([Math.cos(avg), Math.sin(avg)])
|
|
};
|
|
patchesFound.push(patch);
|
|
}
|
|
}
|
|
}
|
|
return patchesFound;
|
|
}
|
|
|
|
/**
|
|
* finds patches which are connected and share the same orientation
|
|
* @param {Object} patchesFound
|
|
*/
|
|
function rasterizeAngularSimilarity(patchesFound) {
|
|
var label = 0,
|
|
threshold = 0.95,
|
|
currIdx = 0,
|
|
j,
|
|
patch,
|
|
hsv = [0, 1, 1],
|
|
rgb = [0, 0, 0];
|
|
|
|
function notYetProcessed() {
|
|
var i;
|
|
for (i = 0; i < _patchLabelGrid.data.length; i++) {
|
|
if (_patchLabelGrid.data[i] === 0 && _patchGrid.data[i] === 1) {
|
|
return i;
|
|
}
|
|
}
|
|
return _patchLabelGrid.length;
|
|
}
|
|
|
|
function trace(currentIdx) {
|
|
var x,
|
|
y,
|
|
currentPatch,
|
|
idx,
|
|
dir,
|
|
current = {
|
|
x: currentIdx % _patchLabelGrid.size.x,
|
|
y: currentIdx / _patchLabelGrid.size.x | 0
|
|
},
|
|
similarity;
|
|
|
|
if (currentIdx < _patchLabelGrid.data.length) {
|
|
currentPatch = _imageToPatchGrid.data[currentIdx];
|
|
// assign label
|
|
_patchLabelGrid.data[currentIdx] = label;
|
|
for (dir = 0; dir < _tracer2['default'].searchDirections.length; dir++) {
|
|
y = current.y + _tracer2['default'].searchDirections[dir][0];
|
|
x = current.x + _tracer2['default'].searchDirections[dir][1];
|
|
idx = y * _patchLabelGrid.size.x + x;
|
|
|
|
// continue if patch empty
|
|
if (_patchGrid.data[idx] === 0) {
|
|
_patchLabelGrid.data[idx] = Number.MAX_VALUE;
|
|
continue;
|
|
}
|
|
|
|
if (_patchLabelGrid.data[idx] === 0) {
|
|
similarity = Math.abs(vec2.dot(_imageToPatchGrid.data[idx].vec, currentPatch.vec));
|
|
if (similarity > threshold) {
|
|
trace(idx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// prepare for finding the right patches
|
|
_array_helper2['default'].init(_patchGrid.data, 0);
|
|
_array_helper2['default'].init(_patchLabelGrid.data, 0);
|
|
_array_helper2['default'].init(_imageToPatchGrid.data, null);
|
|
|
|
for (j = 0; j < patchesFound.length; j++) {
|
|
patch = patchesFound[j];
|
|
_imageToPatchGrid.data[patch.index] = patch;
|
|
_patchGrid.data[patch.index] = 1;
|
|
}
|
|
|
|
// rasterize the patches found to determine area
|
|
_patchGrid.zeroBorder();
|
|
|
|
while ((currIdx = notYetProcessed()) < _patchLabelGrid.data.length) {
|
|
label++;
|
|
trace(currIdx);
|
|
}
|
|
|
|
// draw patch-labels if requested
|
|
if (_config.showPatchLabels) {
|
|
for (j = 0; j < _patchLabelGrid.data.length; j++) {
|
|
if (_patchLabelGrid.data[j] > 0 && _patchLabelGrid.data[j] <= label) {
|
|
patch = _imageToPatchGrid.data[j];
|
|
hsv[0] = _patchLabelGrid.data[j] / (label + 1) * 360;
|
|
_cv_utils2['default'].hsv2rgb(hsv, rgb);
|
|
_image_debug2['default'].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "rgb(" + rgb.join(",") + ")", lineWidth: 2 });
|
|
}
|
|
}
|
|
}
|
|
|
|
return label;
|
|
}
|
|
|
|
exports['default'] = {
|
|
init: function init(inputImageWrapper, config) {
|
|
_config = config;
|
|
_inputImageWrapper = inputImageWrapper;
|
|
|
|
initBuffers();
|
|
initCanvas();
|
|
},
|
|
|
|
locate: function locate() {
|
|
var patchesFound, topLabels, boxes;
|
|
|
|
if (_config.halfSample) {
|
|
_cv_utils2['default'].halfSample(_inputImageWrapper, _currentImageWrapper);
|
|
}
|
|
|
|
binarizeImage();
|
|
patchesFound = findPatches();
|
|
// return unless 5% or more patches are found
|
|
if (patchesFound.length < _numPatches.x * _numPatches.y * 0.05) {
|
|
return null;
|
|
}
|
|
|
|
// rasterrize area by comparing angular similarity;
|
|
var maxLabel = rasterizeAngularSimilarity(patchesFound);
|
|
if (maxLabel < 1) {
|
|
return null;
|
|
}
|
|
|
|
// search for area with the most patches (biggest connected area)
|
|
topLabels = findBiggestConnectedAreas(maxLabel);
|
|
if (topLabels.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
boxes = findBoxes(topLabels, maxLabel);
|
|
return boxes;
|
|
},
|
|
|
|
checkImageConstraints: function checkImageConstraints(inputStream, config) {
|
|
var patchSize,
|
|
width = inputStream.getWidth(),
|
|
height = inputStream.getHeight(),
|
|
halfSample = config.halfSample ? 0.5 : 1,
|
|
size,
|
|
area;
|
|
|
|
// calculate width and height based on area
|
|
if (inputStream.getConfig().area) {
|
|
area = _cv_utils2['default'].computeImageArea(width, height, inputStream.getConfig().area);
|
|
inputStream.setTopRight({ x: area.sx, y: area.sy });
|
|
inputStream.setCanvasSize({ x: width, y: height });
|
|
width = area.sw;
|
|
height = area.sh;
|
|
}
|
|
|
|
size = {
|
|
x: Math.floor(width * halfSample),
|
|
y: Math.floor(height * halfSample)
|
|
};
|
|
|
|
patchSize = _cv_utils2['default'].calculatePatchSize(config.patchSize, size);
|
|
console.log("Patch-Size: " + JSON.stringify(patchSize));
|
|
|
|
inputStream.setWidth(Math.floor(Math.floor(size.x / patchSize.x) * (1 / halfSample) * patchSize.x));
|
|
inputStream.setHeight(Math.floor(Math.floor(size.y / patchSize.y) * (1 / halfSample) * patchSize.y));
|
|
|
|
if (inputStream.getWidth() % patchSize.x === 0 && inputStream.getHeight() % patchSize.y === 0) {
|
|
return true;
|
|
}
|
|
|
|
throw new Error("Image dimensions do not comply with the current settings: Width (" + width + " )and height (" + height + ") must a multiple of " + patchSize.x);
|
|
}
|
|
};
|
|
module.exports = exports['default'];
|
|
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
|
|
|
/***/ },
|
|
/* 19 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _tracer = __webpack_require__(20);
|
|
|
|
var _tracer2 = _interopRequireDefault(_tracer);
|
|
|
|
/**
|
|
* http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization
|
|
*/
|
|
var Rasterizer = {
|
|
createContour2D: function createContour2D() {
|
|
return {
|
|
dir: null,
|
|
index: null,
|
|
firstVertex: null,
|
|
insideContours: null,
|
|
nextpeer: null,
|
|
prevpeer: null
|
|
};
|
|
},
|
|
CONTOUR_DIR: {
|
|
CW_DIR: 0,
|
|
CCW_DIR: 1,
|
|
UNKNOWN_DIR: 2
|
|
},
|
|
DIR: {
|
|
OUTSIDE_EDGE: -32767,
|
|
INSIDE_EDGE: -32766
|
|
},
|
|
create: function create(imageWrapper, labelWrapper) {
|
|
var imageData = imageWrapper.data,
|
|
labelData = labelWrapper.data,
|
|
width = imageWrapper.size.x,
|
|
height = imageWrapper.size.y,
|
|
tracer = _tracer2["default"].create(imageWrapper, labelWrapper);
|
|
|
|
return {
|
|
rasterize: function rasterize(depthlabel) {
|
|
var color,
|
|
bc,
|
|
lc,
|
|
labelindex,
|
|
cx,
|
|
cy,
|
|
colorMap = [],
|
|
vertex,
|
|
p,
|
|
cc,
|
|
sc,
|
|
pos,
|
|
connectedCount = 0,
|
|
i;
|
|
|
|
for (i = 0; i < 400; i++) {
|
|
colorMap[i] = 0;
|
|
}
|
|
|
|
colorMap[0] = imageData[0];
|
|
cc = null;
|
|
for (cy = 1; cy < height - 1; cy++) {
|
|
labelindex = 0;
|
|
bc = colorMap[0];
|
|
for (cx = 1; cx < width - 1; cx++) {
|
|
pos = cy * width + cx;
|
|
if (labelData[pos] === 0) {
|
|
color = imageData[pos];
|
|
if (color !== bc) {
|
|
if (labelindex === 0) {
|
|
lc = connectedCount + 1;
|
|
colorMap[lc] = color;
|
|
bc = color;
|
|
vertex = tracer.contourTracing(cy, cx, lc, color, Rasterizer.DIR.OUTSIDE_EDGE);
|
|
if (vertex !== null) {
|
|
connectedCount++;
|
|
labelindex = lc;
|
|
p = Rasterizer.createContour2D();
|
|
p.dir = Rasterizer.CONTOUR_DIR.CW_DIR;
|
|
p.index = labelindex;
|
|
p.firstVertex = vertex;
|
|
p.nextpeer = cc;
|
|
p.insideContours = null;
|
|
if (cc !== null) {
|
|
cc.prevpeer = p;
|
|
}
|
|
cc = p;
|
|
}
|
|
} else {
|
|
vertex = tracer.contourTracing(cy, cx, Rasterizer.DIR.INSIDE_EDGE, color, labelindex);
|
|
if (vertex !== null) {
|
|
p = Rasterizer.createContour2D();
|
|
p.firstVertex = vertex;
|
|
p.insideContours = null;
|
|
if (depthlabel === 0) {
|
|
p.dir = Rasterizer.CONTOUR_DIR.CCW_DIR;
|
|
} else {
|
|
p.dir = Rasterizer.CONTOUR_DIR.CW_DIR;
|
|
}
|
|
p.index = depthlabel;
|
|
sc = cc;
|
|
while (sc !== null && sc.index !== labelindex) {
|
|
sc = sc.nextpeer;
|
|
}
|
|
if (sc !== null) {
|
|
p.nextpeer = sc.insideContours;
|
|
if (sc.insideContours !== null) {
|
|
sc.insideContours.prevpeer = p;
|
|
}
|
|
sc.insideContours = p;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
labelData[pos] = labelindex;
|
|
}
|
|
} else if (labelData[pos] === Rasterizer.DIR.OUTSIDE_EDGE || labelData[pos] === Rasterizer.DIR.INSIDE_EDGE) {
|
|
labelindex = 0;
|
|
if (labelData[pos] === Rasterizer.DIR.INSIDE_EDGE) {
|
|
bc = imageData[pos];
|
|
} else {
|
|
bc = colorMap[0];
|
|
}
|
|
} else {
|
|
labelindex = labelData[pos];
|
|
bc = colorMap[labelindex];
|
|
}
|
|
}
|
|
}
|
|
sc = cc;
|
|
while (sc !== null) {
|
|
sc.index = depthlabel;
|
|
sc = sc.nextpeer;
|
|
}
|
|
return {
|
|
cc: cc,
|
|
count: connectedCount
|
|
};
|
|
},
|
|
debug: {
|
|
drawContour: function drawContour(canvas, firstContour) {
|
|
var ctx = canvas.getContext("2d"),
|
|
pq = firstContour,
|
|
iq,
|
|
q,
|
|
p;
|
|
|
|
ctx.strokeStyle = "red";
|
|
ctx.fillStyle = "red";
|
|
ctx.lineWidth = 1;
|
|
|
|
if (pq !== null) {
|
|
iq = pq.insideContours;
|
|
} else {
|
|
iq = null;
|
|
}
|
|
|
|
while (pq !== null) {
|
|
if (iq !== null) {
|
|
q = iq;
|
|
iq = iq.nextpeer;
|
|
} else {
|
|
q = pq;
|
|
pq = pq.nextpeer;
|
|
if (pq !== null) {
|
|
iq = pq.insideContours;
|
|
} else {
|
|
iq = null;
|
|
}
|
|
}
|
|
|
|
switch (q.dir) {
|
|
case Rasterizer.CONTOUR_DIR.CW_DIR:
|
|
ctx.strokeStyle = "red";
|
|
break;
|
|
case Rasterizer.CONTOUR_DIR.CCW_DIR:
|
|
ctx.strokeStyle = "blue";
|
|
break;
|
|
case Rasterizer.CONTOUR_DIR.UNKNOWN_DIR:
|
|
ctx.strokeStyle = "green";
|
|
break;
|
|
}
|
|
|
|
p = q.firstVertex;
|
|
ctx.beginPath();
|
|
ctx.moveTo(p.x, p.y);
|
|
do {
|
|
p = p.next;
|
|
ctx.lineTo(p.x, p.y);
|
|
} while (p !== q.firstVertex);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
exports["default"] = Rasterizer;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 20 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization
|
|
*/
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var Tracer = {
|
|
searchDirections: [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]],
|
|
create: function create(imageWrapper, labelWrapper) {
|
|
var imageData = imageWrapper.data,
|
|
labelData = labelWrapper.data,
|
|
searchDirections = this.searchDirections,
|
|
width = imageWrapper.size.x,
|
|
pos;
|
|
|
|
function _trace(current, color, label, edgelabel) {
|
|
var i, y, x;
|
|
|
|
for (i = 0; i < 7; i++) {
|
|
y = current.cy + searchDirections[current.dir][0];
|
|
x = current.cx + searchDirections[current.dir][1];
|
|
pos = y * width + x;
|
|
if (imageData[pos] === color && (labelData[pos] === 0 || labelData[pos] === label)) {
|
|
labelData[pos] = label;
|
|
current.cy = y;
|
|
current.cx = x;
|
|
return true;
|
|
} else {
|
|
if (labelData[pos] === 0) {
|
|
labelData[pos] = edgelabel;
|
|
}
|
|
current.dir = (current.dir + 1) % 8;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function vertex2D(x, y, dir) {
|
|
return {
|
|
dir: dir,
|
|
x: x,
|
|
y: y,
|
|
next: null,
|
|
prev: null
|
|
};
|
|
}
|
|
|
|
function _contourTracing(sy, sx, label, color, edgelabel) {
|
|
var Fv = null,
|
|
Cv,
|
|
P,
|
|
ldir,
|
|
current = {
|
|
cx: sx,
|
|
cy: sy,
|
|
dir: 0
|
|
};
|
|
|
|
if (_trace(current, color, label, edgelabel)) {
|
|
Fv = vertex2D(sx, sy, current.dir);
|
|
Cv = Fv;
|
|
ldir = current.dir;
|
|
P = vertex2D(current.cx, current.cy, 0);
|
|
P.prev = Cv;
|
|
Cv.next = P;
|
|
P.next = null;
|
|
Cv = P;
|
|
do {
|
|
current.dir = (current.dir + 6) % 8;
|
|
_trace(current, color, label, edgelabel);
|
|
if (ldir !== current.dir) {
|
|
Cv.dir = current.dir;
|
|
P = vertex2D(current.cx, current.cy, 0);
|
|
P.prev = Cv;
|
|
Cv.next = P;
|
|
P.next = null;
|
|
Cv = P;
|
|
} else {
|
|
Cv.dir = ldir;
|
|
Cv.x = current.cx;
|
|
Cv.y = current.cy;
|
|
}
|
|
ldir = current.dir;
|
|
} while (current.cx !== sx || current.cy !== sy);
|
|
Fv.prev = Cv.prev;
|
|
Cv.prev.next = Fv;
|
|
}
|
|
return Fv;
|
|
}
|
|
|
|
return {
|
|
trace: function trace(current, color, label, edgelabel) {
|
|
return _trace(current, color, label, edgelabel);
|
|
},
|
|
contourTracing: function contourTracing(sy, sx, label, color, edgelabel) {
|
|
return _contourTracing(sy, sx, label, color, edgelabel);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
exports["default"] = Tracer;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 21 */
|
|
/***/ function(module, exports) {
|
|
|
|
/* @preserve ASM BEGIN */
|
|
/* eslint-disable eqeqeq*/
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
function Skeletonizer(stdlib, foreign, buffer) {
|
|
"use asm";
|
|
|
|
var images = new stdlib.Uint8Array(buffer),
|
|
size = foreign.size | 0,
|
|
imul = stdlib.Math.imul;
|
|
|
|
function erode(inImagePtr, outImagePtr) {
|
|
inImagePtr = inImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var v = 0,
|
|
u = 0,
|
|
sum = 0,
|
|
yStart1 = 0,
|
|
yStart2 = 0,
|
|
xStart1 = 0,
|
|
xStart2 = 0,
|
|
offset = 0;
|
|
|
|
for (v = 1; (v | 0) < (size - 1 | 0); v = v + 1 | 0) {
|
|
offset = offset + size | 0;
|
|
for (u = 1; (u | 0) < (size - 1 | 0); u = u + 1 | 0) {
|
|
yStart1 = offset - size | 0;
|
|
yStart2 = offset + size | 0;
|
|
xStart1 = u - 1 | 0;
|
|
xStart2 = u + 1 | 0;
|
|
sum = (images[inImagePtr + yStart1 + xStart1 | 0] | 0) + (images[inImagePtr + yStart1 + xStart2 | 0] | 0) + (images[inImagePtr + offset + u | 0] | 0) + (images[inImagePtr + yStart2 + xStart1 | 0] | 0) + (images[inImagePtr + yStart2 + xStart2 | 0] | 0) | 0;
|
|
if ((sum | 0) == (5 | 0)) {
|
|
images[outImagePtr + offset + u | 0] = 1;
|
|
} else {
|
|
images[outImagePtr + offset + u | 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
function subtract(aImagePtr, bImagePtr, outImagePtr) {
|
|
aImagePtr = aImagePtr | 0;
|
|
bImagePtr = bImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[outImagePtr + length | 0] = (images[aImagePtr + length | 0] | 0) - (images[bImagePtr + length | 0] | 0) | 0;
|
|
}
|
|
}
|
|
|
|
function bitwiseOr(aImagePtr, bImagePtr, outImagePtr) {
|
|
aImagePtr = aImagePtr | 0;
|
|
bImagePtr = bImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[outImagePtr + length | 0] = images[aImagePtr + length | 0] | 0 | (images[bImagePtr + length | 0] | 0) | 0;
|
|
}
|
|
}
|
|
|
|
function countNonZero(imagePtr) {
|
|
imagePtr = imagePtr | 0;
|
|
|
|
var sum = 0,
|
|
length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
sum = (sum | 0) + (images[imagePtr + length | 0] | 0) | 0;
|
|
}
|
|
|
|
return sum | 0;
|
|
}
|
|
|
|
function init(imagePtr, value) {
|
|
imagePtr = imagePtr | 0;
|
|
value = value | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[imagePtr + length | 0] = value;
|
|
}
|
|
}
|
|
|
|
function dilate(inImagePtr, outImagePtr) {
|
|
inImagePtr = inImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var v = 0,
|
|
u = 0,
|
|
sum = 0,
|
|
yStart1 = 0,
|
|
yStart2 = 0,
|
|
xStart1 = 0,
|
|
xStart2 = 0,
|
|
offset = 0;
|
|
|
|
for (v = 1; (v | 0) < (size - 1 | 0); v = v + 1 | 0) {
|
|
offset = offset + size | 0;
|
|
for (u = 1; (u | 0) < (size - 1 | 0); u = u + 1 | 0) {
|
|
yStart1 = offset - size | 0;
|
|
yStart2 = offset + size | 0;
|
|
xStart1 = u - 1 | 0;
|
|
xStart2 = u + 1 | 0;
|
|
sum = (images[inImagePtr + yStart1 + xStart1 | 0] | 0) + (images[inImagePtr + yStart1 + xStart2 | 0] | 0) + (images[inImagePtr + offset + u | 0] | 0) + (images[inImagePtr + yStart2 + xStart1 | 0] | 0) + (images[inImagePtr + yStart2 + xStart2 | 0] | 0) | 0;
|
|
if ((sum | 0) > (0 | 0)) {
|
|
images[outImagePtr + offset + u | 0] = 1;
|
|
} else {
|
|
images[outImagePtr + offset + u | 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
function memcpy(srcImagePtr, dstImagePtr) {
|
|
srcImagePtr = srcImagePtr | 0;
|
|
dstImagePtr = dstImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[dstImagePtr + length | 0] = images[srcImagePtr + length | 0] | 0;
|
|
}
|
|
}
|
|
|
|
function zeroBorder(imagePtr) {
|
|
imagePtr = imagePtr | 0;
|
|
|
|
var x = 0,
|
|
y = 0;
|
|
|
|
for (x = 0; (x | 0) < (size - 1 | 0); x = x + 1 | 0) {
|
|
images[imagePtr + x | 0] = 0;
|
|
images[imagePtr + y | 0] = 0;
|
|
y = y + size - 1 | 0;
|
|
images[imagePtr + y | 0] = 0;
|
|
y = y + 1 | 0;
|
|
}
|
|
for (x = 0; (x | 0) < (size | 0); x = x + 1 | 0) {
|
|
images[imagePtr + y | 0] = 0;
|
|
y = y + 1 | 0;
|
|
}
|
|
}
|
|
|
|
function skeletonize() {
|
|
var subImagePtr = 0,
|
|
erodedImagePtr = 0,
|
|
tempImagePtr = 0,
|
|
skelImagePtr = 0,
|
|
sum = 0,
|
|
done = 0;
|
|
|
|
erodedImagePtr = imul(size, size) | 0;
|
|
tempImagePtr = erodedImagePtr + erodedImagePtr | 0;
|
|
skelImagePtr = tempImagePtr + erodedImagePtr | 0;
|
|
|
|
// init skel-image
|
|
init(skelImagePtr, 0);
|
|
zeroBorder(subImagePtr);
|
|
|
|
do {
|
|
erode(subImagePtr, erodedImagePtr);
|
|
dilate(erodedImagePtr, tempImagePtr);
|
|
subtract(subImagePtr, tempImagePtr, tempImagePtr);
|
|
bitwiseOr(skelImagePtr, tempImagePtr, skelImagePtr);
|
|
memcpy(erodedImagePtr, subImagePtr);
|
|
sum = countNonZero(subImagePtr) | 0;
|
|
done = (sum | 0) == 0 | 0;
|
|
} while (!done);
|
|
}
|
|
|
|
return {
|
|
skeletonize: skeletonize
|
|
};
|
|
}
|
|
|
|
exports["default"] = Skeletonizer;
|
|
|
|
/* eslint-enable eqeqeq*/
|
|
/* @preserve ASM END */
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 22 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports["default"] = {
|
|
drawRect: function drawRect(pos, size, ctx, style) {
|
|
ctx.strokeStyle = style.color;
|
|
ctx.fillStyle = style.color;
|
|
ctx.lineWidth = 1;
|
|
ctx.beginPath();
|
|
ctx.strokeRect(pos.x, pos.y, size.x, size.y);
|
|
},
|
|
drawPath: function drawPath(path, def, ctx, style) {
|
|
ctx.strokeStyle = style.color;
|
|
ctx.fillStyle = style.color;
|
|
ctx.lineWidth = style.lineWidth;
|
|
ctx.beginPath();
|
|
ctx.moveTo(path[0][def.x], path[0][def.y]);
|
|
for (var j = 1; j < path.length; j++) {
|
|
ctx.lineTo(path[j][def.x], path[j][def.y]);
|
|
}
|
|
ctx.closePath();
|
|
ctx.stroke();
|
|
},
|
|
drawImage: function drawImage(imageData, size, ctx) {
|
|
var canvasData = ctx.getImageData(0, 0, size.x, size.y),
|
|
data = canvasData.data,
|
|
imageDataPos = imageData.length,
|
|
canvasDataPos = data.length,
|
|
value;
|
|
|
|
if (canvasDataPos / imageDataPos !== 4) {
|
|
return false;
|
|
}
|
|
while (imageDataPos--) {
|
|
value = imageData[imageDataPos];
|
|
data[--canvasDataPos] = 255;
|
|
data[--canvasDataPos] = value;
|
|
data[--canvasDataPos] = value;
|
|
data[--canvasDataPos] = value;
|
|
}
|
|
ctx.putImageData(canvasData, 0, 0);
|
|
return true;
|
|
}
|
|
};
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 23 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _bresenham = __webpack_require__(24);
|
|
|
|
var _bresenham2 = _interopRequireDefault(_bresenham);
|
|
|
|
var _image_debug = __webpack_require__(22);
|
|
|
|
var _image_debug2 = _interopRequireDefault(_image_debug);
|
|
|
|
var _code_128_reader = __webpack_require__(25);
|
|
|
|
var _code_128_reader2 = _interopRequireDefault(_code_128_reader);
|
|
|
|
var _ean_reader = __webpack_require__(27);
|
|
|
|
var _ean_reader2 = _interopRequireDefault(_ean_reader);
|
|
|
|
var _code_39_reader = __webpack_require__(28);
|
|
|
|
var _code_39_reader2 = _interopRequireDefault(_code_39_reader);
|
|
|
|
var _code_39_vin_reader = __webpack_require__(29);
|
|
|
|
var _code_39_vin_reader2 = _interopRequireDefault(_code_39_vin_reader);
|
|
|
|
var _codabar_reader = __webpack_require__(30);
|
|
|
|
var _codabar_reader2 = _interopRequireDefault(_codabar_reader);
|
|
|
|
var _upc_reader = __webpack_require__(31);
|
|
|
|
var _upc_reader2 = _interopRequireDefault(_upc_reader);
|
|
|
|
var _ean_8_reader = __webpack_require__(32);
|
|
|
|
var _ean_8_reader2 = _interopRequireDefault(_ean_8_reader);
|
|
|
|
var _upc_e_reader = __webpack_require__(33);
|
|
|
|
var _upc_e_reader2 = _interopRequireDefault(_upc_e_reader);
|
|
|
|
var _i2of5_reader = __webpack_require__(34);
|
|
|
|
var _i2of5_reader2 = _interopRequireDefault(_i2of5_reader);
|
|
|
|
var READERS = {
|
|
code_128_reader: _code_128_reader2['default'],
|
|
ean_reader: _ean_reader2['default'],
|
|
ean_8_reader: _ean_8_reader2['default'],
|
|
code_39_reader: _code_39_reader2['default'],
|
|
code_39_vin_reader: _code_39_vin_reader2['default'],
|
|
codabar_reader: _codabar_reader2['default'],
|
|
upc_reader: _upc_reader2['default'],
|
|
upc_e_reader: _upc_e_reader2['default'],
|
|
i2of5_reader: _i2of5_reader2['default']
|
|
};
|
|
exports['default'] = {
|
|
create: function create(config, inputImageWrapper) {
|
|
var _canvas = {
|
|
ctx: {
|
|
frequency: null,
|
|
pattern: null,
|
|
overlay: null
|
|
},
|
|
dom: {
|
|
frequency: null,
|
|
pattern: null,
|
|
overlay: null
|
|
}
|
|
},
|
|
_barcodeReaders = [];
|
|
|
|
initCanvas();
|
|
initReaders();
|
|
initConfig();
|
|
|
|
function initCanvas() {
|
|
if (typeof document !== 'undefined') {
|
|
var $debug = document.querySelector("#debug.detection");
|
|
_canvas.dom.frequency = document.querySelector("canvas.frequency");
|
|
if (!_canvas.dom.frequency) {
|
|
_canvas.dom.frequency = document.createElement("canvas");
|
|
_canvas.dom.frequency.className = "frequency";
|
|
if ($debug) {
|
|
$debug.appendChild(_canvas.dom.frequency);
|
|
}
|
|
}
|
|
_canvas.ctx.frequency = _canvas.dom.frequency.getContext("2d");
|
|
|
|
_canvas.dom.pattern = document.querySelector("canvas.patternBuffer");
|
|
if (!_canvas.dom.pattern) {
|
|
_canvas.dom.pattern = document.createElement("canvas");
|
|
_canvas.dom.pattern.className = "patternBuffer";
|
|
if ($debug) {
|
|
$debug.appendChild(_canvas.dom.pattern);
|
|
}
|
|
}
|
|
_canvas.ctx.pattern = _canvas.dom.pattern.getContext("2d");
|
|
|
|
_canvas.dom.overlay = document.querySelector("canvas.drawingBuffer");
|
|
if (_canvas.dom.overlay) {
|
|
_canvas.ctx.overlay = _canvas.dom.overlay.getContext("2d");
|
|
}
|
|
}
|
|
}
|
|
|
|
function initReaders() {
|
|
config.readers.forEach(function (readerConfig) {
|
|
var reader,
|
|
configuration = {};
|
|
|
|
if (typeof readerConfig === 'object') {
|
|
reader = readerConfig.format;
|
|
configuration = readerConfig.config;
|
|
} else if (typeof readerConfig === 'string') {
|
|
reader = readerConfig;
|
|
}
|
|
console.log("Before registering reader: ", reader);
|
|
_barcodeReaders.push(new READERS[reader](configuration));
|
|
});
|
|
console.log("Registered Readers: " + _barcodeReaders.map(function (reader) {
|
|
return JSON.stringify({ format: reader.FORMAT, config: reader.config });
|
|
}).join(', '));
|
|
}
|
|
|
|
function initConfig() {
|
|
if (typeof document !== 'undefined') {
|
|
var i,
|
|
vis = [{
|
|
node: _canvas.dom.frequency,
|
|
prop: config.showFrequency
|
|
}, {
|
|
node: _canvas.dom.pattern,
|
|
prop: config.showPattern
|
|
}];
|
|
|
|
for (i = 0; i < vis.length; i++) {
|
|
if (vis[i].prop === true) {
|
|
vis[i].node.style.display = "block";
|
|
} else {
|
|
vis[i].node.style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* extend the line on both ends
|
|
* @param {Array} line
|
|
* @param {Number} angle
|
|
*/
|
|
function getExtendedLine(line, angle, ext) {
|
|
function extendLine(amount) {
|
|
var extension = {
|
|
y: amount * Math.sin(angle),
|
|
x: amount * Math.cos(angle)
|
|
};
|
|
|
|
line[0].y -= extension.y;
|
|
line[0].x -= extension.x;
|
|
line[1].y += extension.y;
|
|
line[1].x += extension.x;
|
|
}
|
|
|
|
// check if inside image
|
|
extendLine(ext);
|
|
while (ext > 1 && (!inputImageWrapper.inImageWithBorder(line[0], 0) || !inputImageWrapper.inImageWithBorder(line[1], 0))) {
|
|
ext -= Math.ceil(ext / 2);
|
|
extendLine(-ext);
|
|
}
|
|
return line;
|
|
}
|
|
|
|
function getLine(box) {
|
|
return [{
|
|
x: (box[1][0] - box[0][0]) / 2 + box[0][0],
|
|
y: (box[1][1] - box[0][1]) / 2 + box[0][1]
|
|
}, {
|
|
x: (box[3][0] - box[2][0]) / 2 + box[2][0],
|
|
y: (box[3][1] - box[2][1]) / 2 + box[2][1]
|
|
}];
|
|
}
|
|
|
|
function tryDecode(line) {
|
|
var result = null,
|
|
i,
|
|
barcodeLine = _bresenham2['default'].getBarcodeLine(inputImageWrapper, line[0], line[1]);
|
|
|
|
if (config.showFrequency) {
|
|
_image_debug2['default'].drawPath(line, { x: 'x', y: 'y' }, _canvas.ctx.overlay, { color: 'red', lineWidth: 3 });
|
|
_bresenham2['default'].debug.printFrequency(barcodeLine.line, _canvas.dom.frequency);
|
|
}
|
|
_bresenham2['default'].toBinaryLine(barcodeLine);
|
|
if (config.showPattern) {
|
|
_bresenham2['default'].debug.printPattern(barcodeLine.line, _canvas.dom.pattern);
|
|
}
|
|
|
|
for (i = 0; i < _barcodeReaders.length && result === null; i++) {
|
|
result = _barcodeReaders[i].decodePattern(barcodeLine.line);
|
|
}
|
|
if (result === null) {
|
|
return null;
|
|
}
|
|
return {
|
|
codeResult: result,
|
|
barcodeLine: barcodeLine
|
|
};
|
|
}
|
|
|
|
/**
|
|
* This method slices the given area apart and tries to detect a barcode-pattern
|
|
* for each slice. It returns the decoded barcode, or null if nothing was found
|
|
* @param {Array} box
|
|
* @param {Array} line
|
|
* @param {Number} lineAngle
|
|
*/
|
|
function tryDecodeBruteForce(box, line, lineAngle) {
|
|
var sideLength = Math.sqrt(Math.pow(box[1][0] - box[0][0], 2) + Math.pow(box[1][1] - box[0][1], 2)),
|
|
i,
|
|
slices = 16,
|
|
result = null,
|
|
dir,
|
|
extension,
|
|
xdir = Math.sin(lineAngle),
|
|
ydir = Math.cos(lineAngle);
|
|
|
|
for (i = 1; i < slices && result === null; i++) {
|
|
// move line perpendicular to angle
|
|
dir = sideLength / slices * i * (i % 2 === 0 ? -1 : 1);
|
|
extension = {
|
|
y: dir * xdir,
|
|
x: dir * ydir
|
|
};
|
|
line[0].y += extension.x;
|
|
line[0].x -= extension.y;
|
|
line[1].y += extension.x;
|
|
line[1].x -= extension.y;
|
|
|
|
result = tryDecode(line);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function getLineLength(line) {
|
|
return Math.sqrt(Math.pow(Math.abs(line[1].y - line[0].y), 2) + Math.pow(Math.abs(line[1].x - line[0].x), 2));
|
|
}
|
|
|
|
/**
|
|
* With the help of the configured readers (Code128 or EAN) this function tries to detect a
|
|
* valid barcode pattern within the given area.
|
|
* @param {Object} box The area to search in
|
|
* @returns {Object} the result {codeResult, line, angle, pattern, threshold}
|
|
*/
|
|
function _decodeFromBoundingBox(box) {
|
|
var line,
|
|
lineAngle,
|
|
ctx = _canvas.ctx.overlay,
|
|
result,
|
|
lineLength;
|
|
|
|
if (config.drawBoundingBox && ctx) {
|
|
_image_debug2['default'].drawPath(box, { x: 0, y: 1 }, ctx, { color: "blue", lineWidth: 2 });
|
|
}
|
|
|
|
line = getLine(box);
|
|
lineLength = getLineLength(line);
|
|
lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
|
|
line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.1));
|
|
if (line === null) {
|
|
return null;
|
|
}
|
|
|
|
result = tryDecode(line);
|
|
if (result === null) {
|
|
result = tryDecodeBruteForce(box, line, lineAngle);
|
|
}
|
|
|
|
if (result === null) {
|
|
return null;
|
|
}
|
|
|
|
if (result && config.drawScanline && ctx) {
|
|
_image_debug2['default'].drawPath(line, { x: 'x', y: 'y' }, ctx, { color: 'red', lineWidth: 3 });
|
|
}
|
|
|
|
return {
|
|
codeResult: result.codeResult,
|
|
line: line,
|
|
angle: lineAngle,
|
|
pattern: result.barcodeLine.line,
|
|
threshold: result.barcodeLine.threshold
|
|
};
|
|
}
|
|
|
|
return {
|
|
decodeFromBoundingBox: function decodeFromBoundingBox(box) {
|
|
return _decodeFromBoundingBox(box);
|
|
},
|
|
decodeFromBoundingBoxes: function decodeFromBoundingBoxes(boxes) {
|
|
var i, result;
|
|
for (i = 0; i < boxes.length; i++) {
|
|
result = _decodeFromBoundingBox(boxes[i]);
|
|
if (result && result.codeResult) {
|
|
result.box = boxes[i];
|
|
return result;
|
|
}
|
|
}
|
|
},
|
|
setReaders: function setReaders(readers) {
|
|
config.readers = readers;
|
|
_barcodeReaders.length = 0;
|
|
initReaders();
|
|
}
|
|
};
|
|
}
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 24 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _cv_utils = __webpack_require__(5);
|
|
|
|
var _cv_utils2 = _interopRequireDefault(_cv_utils);
|
|
|
|
var _image_wrapper = __webpack_require__(3);
|
|
|
|
var _image_wrapper2 = _interopRequireDefault(_image_wrapper);
|
|
|
|
var Bresenham = {};
|
|
|
|
var Slope = {
|
|
DIR: {
|
|
UP: 1,
|
|
DOWN: -1
|
|
}
|
|
};
|
|
/**
|
|
* Scans a line of the given image from point p1 to p2 and returns a result object containing
|
|
* gray-scale values (0-255) of the underlying pixels in addition to the min
|
|
* and max values.
|
|
* @param {Object} imageWrapper
|
|
* @param {Object} p1 The start point {x,y}
|
|
* @param {Object} p2 The end point {x,y}
|
|
* @returns {line, min, max}
|
|
*/
|
|
Bresenham.getBarcodeLine = function (imageWrapper, p1, p2) {
|
|
var x0 = p1.x | 0,
|
|
y0 = p1.y | 0,
|
|
x1 = p2.x | 0,
|
|
y1 = p2.y | 0,
|
|
steep = Math.abs(y1 - y0) > Math.abs(x1 - x0),
|
|
deltax,
|
|
deltay,
|
|
error,
|
|
ystep,
|
|
y,
|
|
tmp,
|
|
x,
|
|
line = [],
|
|
imageData = imageWrapper.data,
|
|
width = imageWrapper.size.x,
|
|
sum = 0,
|
|
val,
|
|
min = 255,
|
|
max = 0;
|
|
|
|
function read(a, b) {
|
|
val = imageData[b * width + a];
|
|
sum += val;
|
|
min = val < min ? val : min;
|
|
max = val > max ? val : max;
|
|
line.push(val);
|
|
}
|
|
|
|
if (steep) {
|
|
tmp = x0;
|
|
x0 = y0;
|
|
y0 = tmp;
|
|
|
|
tmp = x1;
|
|
x1 = y1;
|
|
y1 = tmp;
|
|
}
|
|
if (x0 > x1) {
|
|
tmp = x0;
|
|
x0 = x1;
|
|
x1 = tmp;
|
|
|
|
tmp = y0;
|
|
y0 = y1;
|
|
y1 = tmp;
|
|
}
|
|
deltax = x1 - x0;
|
|
deltay = Math.abs(y1 - y0);
|
|
error = deltax / 2 | 0;
|
|
y = y0;
|
|
ystep = y0 < y1 ? 1 : -1;
|
|
for (x = x0; x < x1; x++) {
|
|
if (steep) {
|
|
read(y, x);
|
|
} else {
|
|
read(x, y);
|
|
}
|
|
error = error - deltay;
|
|
if (error < 0) {
|
|
y = y + ystep;
|
|
error = error + deltax;
|
|
}
|
|
}
|
|
|
|
return {
|
|
line: line,
|
|
min: min,
|
|
max: max
|
|
};
|
|
};
|
|
|
|
Bresenham.toOtsuBinaryLine = function (result) {
|
|
var line = result.line,
|
|
image = new _image_wrapper2['default']({ x: line.length - 1, y: 1 }, line),
|
|
threshold = _cv_utils2['default'].determineOtsuThreshold(image, 5);
|
|
|
|
line = _cv_utils2['default'].sharpenLine(line);
|
|
_cv_utils2['default'].thresholdImage(image, threshold);
|
|
|
|
return {
|
|
line: line,
|
|
threshold: threshold
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Converts the result from getBarcodeLine into a binary representation
|
|
* also considering the frequency and slope of the signal for more robust results
|
|
* @param {Object} result {line, min, max}
|
|
*/
|
|
Bresenham.toBinaryLine = function (result) {
|
|
var min = result.min,
|
|
max = result.max,
|
|
line = result.line,
|
|
slope,
|
|
slope2,
|
|
center = min + (max - min) / 2,
|
|
extrema = [],
|
|
currentDir,
|
|
dir,
|
|
threshold = (max - min) / 12,
|
|
rThreshold = -threshold,
|
|
i,
|
|
j;
|
|
|
|
// 1. find extrema
|
|
currentDir = line[0] > center ? Slope.DIR.UP : Slope.DIR.DOWN;
|
|
extrema.push({
|
|
pos: 0,
|
|
val: line[0]
|
|
});
|
|
for (i = 0; i < line.length - 2; i++) {
|
|
slope = line[i + 1] - line[i];
|
|
slope2 = line[i + 2] - line[i + 1];
|
|
if (slope + slope2 < rThreshold && line[i + 1] < center * 1.5) {
|
|
dir = Slope.DIR.DOWN;
|
|
} else if (slope + slope2 > threshold && line[i + 1] > center * 0.5) {
|
|
dir = Slope.DIR.UP;
|
|
} else {
|
|
dir = currentDir;
|
|
}
|
|
|
|
if (currentDir !== dir) {
|
|
extrema.push({
|
|
pos: i,
|
|
val: line[i]
|
|
});
|
|
currentDir = dir;
|
|
}
|
|
}
|
|
extrema.push({
|
|
pos: line.length,
|
|
val: line[line.length - 1]
|
|
});
|
|
|
|
for (j = extrema[0].pos; j < extrema[1].pos; j++) {
|
|
line[j] = line[j] > center ? 0 : 1;
|
|
}
|
|
|
|
// iterate over extrema and convert to binary based on avg between minmax
|
|
for (i = 1; i < extrema.length - 1; i++) {
|
|
if (extrema[i + 1].val > extrema[i].val) {
|
|
threshold = extrema[i].val + (extrema[i + 1].val - extrema[i].val) / 3 * 2 | 0;
|
|
} else {
|
|
threshold = extrema[i + 1].val + (extrema[i].val - extrema[i + 1].val) / 3 | 0;
|
|
}
|
|
|
|
for (j = extrema[i].pos; j < extrema[i + 1].pos; j++) {
|
|
line[j] = line[j] > threshold ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
return {
|
|
line: line,
|
|
threshold: threshold
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Used for development only
|
|
*/
|
|
Bresenham.debug = {
|
|
printFrequency: function printFrequency(line, canvas) {
|
|
var i,
|
|
ctx = canvas.getContext("2d");
|
|
canvas.width = line.length;
|
|
canvas.height = 256;
|
|
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = "blue";
|
|
for (i = 0; i < line.length; i++) {
|
|
ctx.moveTo(i, 255);
|
|
ctx.lineTo(i, 255 - line[i]);
|
|
}
|
|
ctx.stroke();
|
|
ctx.closePath();
|
|
},
|
|
|
|
printPattern: function printPattern(line, canvas) {
|
|
var ctx = canvas.getContext("2d"),
|
|
i;
|
|
|
|
canvas.width = line.length;
|
|
ctx.fillColor = "black";
|
|
for (i = 0; i < line.length; i++) {
|
|
if (line[i] === 1) {
|
|
ctx.fillRect(i, 0, 1, 100);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
exports['default'] = Bresenham;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 25 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _barcode_reader = __webpack_require__(26);
|
|
|
|
var _barcode_reader2 = _interopRequireDefault(_barcode_reader);
|
|
|
|
function Code128Reader() {
|
|
_barcode_reader2["default"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
CODE_SHIFT: { value: 98 },
|
|
CODE_C: { value: 99 },
|
|
CODE_B: { value: 100 },
|
|
CODE_A: { value: 101 },
|
|
START_CODE_A: { value: 103 },
|
|
START_CODE_B: { value: 104 },
|
|
START_CODE_C: { value: 105 },
|
|
STOP_CODE: { value: 106 },
|
|
MODULO: { value: 11 },
|
|
CODE_PATTERN: { value: [[2, 1, 2, 2, 2, 2], [2, 2, 2, 1, 2, 2], [2, 2, 2, 2, 2, 1], [1, 2, 1, 2, 2, 3], [1, 2, 1, 3, 2, 2], [1, 3, 1, 2, 2, 2], [1, 2, 2, 2, 1, 3], [1, 2, 2, 3, 1, 2], [1, 3, 2, 2, 1, 2], [2, 2, 1, 2, 1, 3], [2, 2, 1, 3, 1, 2], [2, 3, 1, 2, 1, 2], [1, 1, 2, 2, 3, 2], [1, 2, 2, 1, 3, 2], [1, 2, 2, 2, 3, 1], [1, 1, 3, 2, 2, 2], [1, 2, 3, 1, 2, 2], [1, 2, 3, 2, 2, 1], [2, 2, 3, 2, 1, 1], [2, 2, 1, 1, 3, 2], [2, 2, 1, 2, 3, 1], [2, 1, 3, 2, 1, 2], [2, 2, 3, 1, 1, 2], [3, 1, 2, 1, 3, 1], [3, 1, 1, 2, 2, 2], [3, 2, 1, 1, 2, 2], [3, 2, 1, 2, 2, 1], [3, 1, 2, 2, 1, 2], [3, 2, 2, 1, 1, 2], [3, 2, 2, 2, 1, 1], [2, 1, 2, 1, 2, 3], [2, 1, 2, 3, 2, 1], [2, 3, 2, 1, 2, 1], [1, 1, 1, 3, 2, 3], [1, 3, 1, 1, 2, 3], [1, 3, 1, 3, 2, 1], [1, 1, 2, 3, 1, 3], [1, 3, 2, 1, 1, 3], [1, 3, 2, 3, 1, 1], [2, 1, 1, 3, 1, 3], [2, 3, 1, 1, 1, 3], [2, 3, 1, 3, 1, 1], [1, 1, 2, 1, 3, 3], [1, 1, 2, 3, 3, 1], [1, 3, 2, 1, 3, 1], [1, 1, 3, 1, 2, 3], [1, 1, 3, 3, 2, 1], [1, 3, 3, 1, 2, 1], [3, 1, 3, 1, 2, 1], [2, 1, 1, 3, 3, 1], [2, 3, 1, 1, 3, 1], [2, 1, 3, 1, 1, 3], [2, 1, 3, 3, 1, 1], [2, 1, 3, 1, 3, 1], [3, 1, 1, 1, 2, 3], [3, 1, 1, 3, 2, 1], [3, 3, 1, 1, 2, 1], [3, 1, 2, 1, 1, 3], [3, 1, 2, 3, 1, 1], [3, 3, 2, 1, 1, 1], [3, 1, 4, 1, 1, 1], [2, 2, 1, 4, 1, 1], [4, 3, 1, 1, 1, 1], [1, 1, 1, 2, 2, 4], [1, 1, 1, 4, 2, 2], [1, 2, 1, 1, 2, 4], [1, 2, 1, 4, 2, 1], [1, 4, 1, 1, 2, 2], [1, 4, 1, 2, 2, 1], [1, 1, 2, 2, 1, 4], [1, 1, 2, 4, 1, 2], [1, 2, 2, 1, 1, 4], [1, 2, 2, 4, 1, 1], [1, 4, 2, 1, 1, 2], [1, 4, 2, 2, 1, 1], [2, 4, 1, 2, 1, 1], [2, 2, 1, 1, 1, 4], [4, 1, 3, 1, 1, 1], [2, 4, 1, 1, 1, 2], [1, 3, 4, 1, 1, 1], [1, 1, 1, 2, 4, 2], [1, 2, 1, 1, 4, 2], [1, 2, 1, 2, 4, 1], [1, 1, 4, 2, 1, 2], [1, 2, 4, 1, 1, 2], [1, 2, 4, 2, 1, 1], [4, 1, 1, 2, 1, 2], [4, 2, 1, 1, 1, 2], [4, 2, 1, 2, 1, 1], [2, 1, 2, 1, 4, 1], [2, 1, 4, 1, 2, 1], [4, 1, 2, 1, 2, 1], [1, 1, 1, 1, 4, 3], [1, 1, 1, 3, 4, 1], [1, 3, 1, 1, 4, 1], [1, 1, 4, 1, 1, 3], [1, 1, 4, 3, 1, 1], [4, 1, 1, 1, 1, 3], [4, 1, 1, 3, 1, 1], [1, 1, 3, 1, 4, 1], [1, 1, 4, 1, 3, 1], [3, 1, 1, 1, 4, 1], [4, 1, 1, 1, 3, 1], [2, 1, 1, 4, 1, 2], [2, 1, 1, 2, 1, 4], [2, 1, 1, 2, 3, 2], [2, 3, 3, 1, 1, 1, 2]] },
|
|
SINGLE_CODE_ERROR: { value: 1 },
|
|
AVG_CODE_ERROR: { value: 0.5 },
|
|
FORMAT: { value: "code_128", writeable: false }
|
|
};
|
|
|
|
Code128Reader.prototype = Object.create(_barcode_reader2["default"].prototype, properties);
|
|
Code128Reader.prototype.constructor = Code128Reader;
|
|
|
|
Code128Reader.prototype._decodeCode = function (start) {
|
|
var counter = [0, 0, 0, 0, 0, 0],
|
|
i,
|
|
self = this,
|
|
offset = start,
|
|
isWhite = !self._row[offset],
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: start,
|
|
end: start
|
|
},
|
|
code,
|
|
error,
|
|
normalized;
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = 0; code < self.CODE_PATTERN.length; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
bestMatch.end = i;
|
|
return bestMatch;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
Code128Reader.prototype._findStart = function () {
|
|
var counter = [0, 0, 0, 0, 0, 0],
|
|
i,
|
|
self = this,
|
|
offset = self._nextSet(self._row),
|
|
isWhite = false,
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
},
|
|
code,
|
|
error,
|
|
j,
|
|
sum,
|
|
normalized;
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
sum = 0;
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = self.START_CODE_A; code <= self.START_CODE_C; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
if (bestMatch.error < self.AVG_CODE_ERROR) {
|
|
bestMatch.start = i - sum;
|
|
bestMatch.end = i;
|
|
return bestMatch;
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[4] = 0;
|
|
counter[5] = 0;
|
|
counterPos--;
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
Code128Reader.prototype._decode = function () {
|
|
var self = this,
|
|
startInfo = self._findStart(),
|
|
code = null,
|
|
done = false,
|
|
result = [],
|
|
multiplier = 0,
|
|
checksum = 0,
|
|
codeset,
|
|
rawResult = [],
|
|
decodedCodes = [],
|
|
shiftNext = false,
|
|
unshift,
|
|
removeLastCharacter = true;
|
|
|
|
if (startInfo === null) {
|
|
return null;
|
|
}
|
|
code = {
|
|
code: startInfo.code,
|
|
start: startInfo.start,
|
|
end: startInfo.end
|
|
};
|
|
decodedCodes.push(code);
|
|
checksum = code.code;
|
|
switch (code.code) {
|
|
case self.START_CODE_A:
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.START_CODE_B:
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.START_CODE_C:
|
|
codeset = self.CODE_C;
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
|
|
while (!done) {
|
|
unshift = shiftNext;
|
|
shiftNext = false;
|
|
code = self._decodeCode(code.end);
|
|
if (code !== null) {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = true;
|
|
}
|
|
|
|
if (code.code !== self.STOP_CODE) {
|
|
rawResult.push(code.code);
|
|
multiplier++;
|
|
checksum += multiplier * code.code;
|
|
}
|
|
decodedCodes.push(code);
|
|
|
|
switch (codeset) {
|
|
case self.CODE_A:
|
|
if (code.code < 64) {
|
|
result.push(String.fromCharCode(32 + code.code));
|
|
} else if (code.code < 96) {
|
|
result.push(String.fromCharCode(code.code - 64));
|
|
} else {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = false;
|
|
}
|
|
switch (code.code) {
|
|
case self.CODE_SHIFT:
|
|
shiftNext = true;
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.CODE_B:
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.CODE_C:
|
|
codeset = self.CODE_C;
|
|
break;
|
|
case self.STOP_CODE:
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case self.CODE_B:
|
|
if (code.code < 96) {
|
|
result.push(String.fromCharCode(32 + code.code));
|
|
} else {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = false;
|
|
}
|
|
switch (code.code) {
|
|
case self.CODE_SHIFT:
|
|
shiftNext = true;
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.CODE_A:
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.CODE_C:
|
|
codeset = self.CODE_C;
|
|
break;
|
|
case self.STOP_CODE:
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case self.CODE_C:
|
|
if (code.code < 100) {
|
|
result.push(code.code < 10 ? "0" + code.code : code.code);
|
|
} else {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = false;
|
|
}
|
|
switch (code.code) {
|
|
case self.CODE_A:
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.CODE_B:
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.STOP_CODE:
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
done = true;
|
|
}
|
|
if (unshift) {
|
|
codeset = codeset === self.CODE_A ? self.CODE_B : self.CODE_A;
|
|
}
|
|
}
|
|
|
|
if (code === null) {
|
|
return null;
|
|
}
|
|
|
|
code.end = self._nextUnset(self._row, code.end);
|
|
if (!self._verifyTrailingWhitespace(code)) {
|
|
return null;
|
|
}
|
|
|
|
checksum -= multiplier * rawResult[rawResult.length - 1];
|
|
if (checksum % 103 !== rawResult[rawResult.length - 1]) {
|
|
return null;
|
|
}
|
|
|
|
if (!result.length) {
|
|
return null;
|
|
}
|
|
|
|
// remove last code from result (checksum)
|
|
if (removeLastCharacter) {
|
|
result.splice(result.length - 1, 1);
|
|
}
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: startInfo.start,
|
|
end: code.end,
|
|
codeset: codeset,
|
|
startInfo: startInfo,
|
|
decodedCodes: decodedCodes,
|
|
endInfo: code
|
|
};
|
|
};
|
|
|
|
_barcode_reader2["default"].prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start) / 2;
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
exports["default"] = Code128Reader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 26 */
|
|
/***/ function(module, exports) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
function BarcodeReader(config) {
|
|
this._row = [];
|
|
this.config = config || {};
|
|
return this;
|
|
}
|
|
|
|
BarcodeReader.prototype._nextUnset = function (line, start) {
|
|
var i;
|
|
|
|
if (start === undefined) {
|
|
start = 0;
|
|
}
|
|
for (i = start; i < line.length; i++) {
|
|
if (!line[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return line.length;
|
|
};
|
|
|
|
BarcodeReader.prototype._matchPattern = function (counter, code) {
|
|
var i,
|
|
error = 0,
|
|
singleError = 0,
|
|
modulo = this.MODULO,
|
|
maxSingleError = this.SINGLE_CODE_ERROR || 1;
|
|
|
|
for (i = 0; i < counter.length; i++) {
|
|
singleError = Math.abs(code[i] - counter[i]);
|
|
if (singleError > maxSingleError) {
|
|
return Number.MAX_VALUE;
|
|
}
|
|
error += singleError;
|
|
}
|
|
return error / modulo;
|
|
};
|
|
|
|
BarcodeReader.prototype._nextSet = function (line, offset) {
|
|
var i;
|
|
|
|
offset = offset || 0;
|
|
for (i = offset; i < line.length; i++) {
|
|
if (line[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return line.length;
|
|
};
|
|
|
|
BarcodeReader.prototype._normalize = function (counter, modulo) {
|
|
var i,
|
|
self = this,
|
|
sum = 0,
|
|
ratio,
|
|
numOnes = 0,
|
|
normalized = [],
|
|
norm = 0;
|
|
|
|
if (!modulo) {
|
|
modulo = self.MODULO;
|
|
}
|
|
for (i = 0; i < counter.length; i++) {
|
|
if (counter[i] === 1) {
|
|
numOnes++;
|
|
} else {
|
|
sum += counter[i];
|
|
}
|
|
}
|
|
ratio = sum / (modulo - numOnes);
|
|
if (ratio > 1.0) {
|
|
for (i = 0; i < counter.length; i++) {
|
|
norm = counter[i] === 1 ? counter[i] : counter[i] / ratio;
|
|
normalized.push(norm);
|
|
}
|
|
} else {
|
|
ratio = (sum + numOnes) / modulo;
|
|
for (i = 0; i < counter.length; i++) {
|
|
norm = counter[i] / ratio;
|
|
normalized.push(norm);
|
|
}
|
|
}
|
|
return normalized;
|
|
};
|
|
|
|
BarcodeReader.prototype._matchTrace = function (cmpCounter, epsilon) {
|
|
var counter = [],
|
|
i,
|
|
self = this,
|
|
offset = self._nextSet(self._row),
|
|
isWhite = !self._row[offset],
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0
|
|
},
|
|
error;
|
|
|
|
if (cmpCounter) {
|
|
for (i = 0; i < cmpCounter.length; i++) {
|
|
counter.push(0);
|
|
}
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
error = self._matchPattern(counter, cmpCounter);
|
|
|
|
if (error < epsilon) {
|
|
bestMatch.start = i - offset;
|
|
bestMatch.end = i;
|
|
bestMatch.counter = counter;
|
|
return bestMatch;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
} else {
|
|
counter.push(0);
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
counterPos++;
|
|
counter.push(0);
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if cmpCounter was not given
|
|
bestMatch.start = offset;
|
|
bestMatch.end = self._row.length - 1;
|
|
bestMatch.counter = counter;
|
|
return bestMatch;
|
|
};
|
|
|
|
BarcodeReader.prototype.decodePattern = function (pattern) {
|
|
var self = this,
|
|
result;
|
|
|
|
self._row = pattern;
|
|
result = self._decode();
|
|
if (result === null) {
|
|
self._row.reverse();
|
|
result = self._decode();
|
|
if (result) {
|
|
result.direction = BarcodeReader.DIRECTION.REVERSE;
|
|
result.start = self._row.length - result.start;
|
|
result.end = self._row.length - result.end;
|
|
}
|
|
} else {
|
|
result.direction = BarcodeReader.DIRECTION.FORWARD;
|
|
}
|
|
if (result) {
|
|
result.format = self.FORMAT;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
BarcodeReader.prototype._matchRange = function (start, end, value) {
|
|
var i;
|
|
|
|
start = start < 0 ? 0 : start;
|
|
for (i = start; i < end; i++) {
|
|
if (this._row[i] !== value) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
BarcodeReader.prototype._fillCounters = function (offset, end, isWhite) {
|
|
var self = this,
|
|
counterPos = 0,
|
|
i,
|
|
counters = [];
|
|
|
|
isWhite = typeof isWhite !== 'undefined' ? isWhite : true;
|
|
offset = typeof offset !== 'undefined' ? offset : self._nextUnset(self._row);
|
|
end = end || self._row.length;
|
|
|
|
counters[counterPos] = 0;
|
|
for (i = offset; i < end; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counters[counterPos]++;
|
|
} else {
|
|
counterPos++;
|
|
counters[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return counters;
|
|
};
|
|
|
|
Object.defineProperty(BarcodeReader.prototype, "FORMAT", {
|
|
value: 'unknown',
|
|
writeable: false
|
|
});
|
|
|
|
BarcodeReader.DIRECTION = {
|
|
FORWARD: 1,
|
|
REVERSE: -1
|
|
};
|
|
|
|
BarcodeReader.Exception = {
|
|
StartNotFoundException: "Start-Info was not found!",
|
|
CodeNotFoundException: "Code could not be found!",
|
|
PatternNotFoundException: "Pattern could not be found!"
|
|
};
|
|
|
|
BarcodeReader.CONFIG_KEYS = {};
|
|
|
|
exports['default'] = BarcodeReader;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 27 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _barcode_reader = __webpack_require__(26);
|
|
|
|
var _barcode_reader2 = _interopRequireDefault(_barcode_reader);
|
|
|
|
function EANReader(opts) {
|
|
_barcode_reader2["default"].call(this, opts);
|
|
}
|
|
|
|
var properties = {
|
|
CODE_L_START: { value: 0 },
|
|
MODULO: { value: 7 },
|
|
CODE_G_START: { value: 10 },
|
|
START_PATTERN: { value: [1 / 3 * 7, 1 / 3 * 7, 1 / 3 * 7] },
|
|
STOP_PATTERN: { value: [1 / 3 * 7, 1 / 3 * 7, 1 / 3 * 7] },
|
|
MIDDLE_PATTERN: { value: [1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7] },
|
|
CODE_PATTERN: { value: [[3, 2, 1, 1], [2, 2, 2, 1], [2, 1, 2, 2], [1, 4, 1, 1], [1, 1, 3, 2], [1, 2, 3, 1], [1, 1, 1, 4], [1, 3, 1, 2], [1, 2, 1, 3], [3, 1, 1, 2], [1, 1, 2, 3], [1, 2, 2, 2], [2, 2, 1, 2], [1, 1, 4, 1], [2, 3, 1, 1], [1, 3, 2, 1], [4, 1, 1, 1], [2, 1, 3, 1], [3, 1, 2, 1], [2, 1, 1, 3]] },
|
|
CODE_FREQUENCY: { value: [0, 11, 13, 14, 19, 25, 28, 21, 22, 26] },
|
|
SINGLE_CODE_ERROR: { value: 0.67 },
|
|
AVG_CODE_ERROR: { value: 0.27 },
|
|
FORMAT: { value: "ean_13", writeable: false }
|
|
};
|
|
|
|
EANReader.prototype = Object.create(_barcode_reader2["default"].prototype, properties);
|
|
EANReader.prototype.constructor = EANReader;
|
|
|
|
EANReader.prototype._decodeCode = function (start, coderange) {
|
|
var counter = [0, 0, 0, 0],
|
|
i,
|
|
self = this,
|
|
offset = start,
|
|
isWhite = !self._row[offset],
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: start,
|
|
end: start
|
|
},
|
|
code,
|
|
error,
|
|
normalized;
|
|
|
|
if (!coderange) {
|
|
coderange = self.CODE_PATTERN.length;
|
|
}
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = 0; code < coderange; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
bestMatch.end = i;
|
|
if (bestMatch.error > self.AVG_CODE_ERROR) {
|
|
return null;
|
|
}
|
|
return bestMatch;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._findPattern = function (pattern, offset, isWhite, tryHarder, epsilon) {
|
|
var counter = [],
|
|
self = this,
|
|
i,
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
},
|
|
error,
|
|
j,
|
|
sum,
|
|
normalized;
|
|
|
|
if (!offset) {
|
|
offset = self._nextSet(self._row);
|
|
}
|
|
|
|
if (isWhite === undefined) {
|
|
isWhite = false;
|
|
}
|
|
|
|
if (tryHarder === undefined) {
|
|
tryHarder = true;
|
|
}
|
|
|
|
if (epsilon === undefined) {
|
|
epsilon = self.AVG_CODE_ERROR;
|
|
}
|
|
|
|
for (i = 0; i < pattern.length; i++) {
|
|
counter[i] = 0;
|
|
}
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
sum = 0;
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
error = self._matchPattern(normalized, pattern);
|
|
|
|
if (error < epsilon) {
|
|
bestMatch.error = error;
|
|
bestMatch.start = i - sum;
|
|
bestMatch.end = i;
|
|
return bestMatch;
|
|
}
|
|
}
|
|
if (tryHarder) {
|
|
for (j = 0; j < counter.length - 2; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[counter.length - 2] = 0;
|
|
counter[counter.length - 1] = 0;
|
|
counterPos--;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._findStart = function () {
|
|
var self = this,
|
|
leadingWhitespaceStart,
|
|
offset = self._nextSet(self._row),
|
|
startInfo;
|
|
|
|
while (!startInfo) {
|
|
startInfo = self._findPattern(self.START_PATTERN, offset);
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
leadingWhitespaceStart = startInfo.start - (startInfo.end - startInfo.start);
|
|
if (leadingWhitespaceStart >= 0) {
|
|
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
|
|
return startInfo;
|
|
}
|
|
}
|
|
offset = startInfo.end;
|
|
startInfo = null;
|
|
}
|
|
};
|
|
|
|
EANReader.prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start);
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._findEnd = function (offset, isWhite) {
|
|
var self = this,
|
|
endInfo = self._findPattern(self.STOP_PATTERN, offset, isWhite, false);
|
|
|
|
return endInfo !== null ? self._verifyTrailingWhitespace(endInfo) : null;
|
|
};
|
|
|
|
EANReader.prototype._calculateFirstDigit = function (codeFrequency) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < self.CODE_FREQUENCY.length; i++) {
|
|
if (codeFrequency === self.CODE_FREQUENCY[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._decodePayload = function (code, result, decodedCodes) {
|
|
var i,
|
|
self = this,
|
|
codeFrequency = 0x0,
|
|
firstDigit;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
code = self._decodeCode(code.end);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
if (code.code >= self.CODE_G_START) {
|
|
code.code = code.code - self.CODE_G_START;
|
|
codeFrequency |= 1 << 5 - i;
|
|
} else {
|
|
codeFrequency |= 0 << 5 - i;
|
|
}
|
|
result.push(code.code);
|
|
decodedCodes.push(code);
|
|
}
|
|
|
|
firstDigit = self._calculateFirstDigit(codeFrequency);
|
|
if (firstDigit === null) {
|
|
return null;
|
|
}
|
|
result.unshift(firstDigit);
|
|
|
|
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
|
|
if (code === null) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
code = self._decodeCode(code.end, self.CODE_G_START);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
result.push(code.code);
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
EANReader.prototype._decode = function () {
|
|
var startInfo,
|
|
self = this,
|
|
code,
|
|
result = [],
|
|
decodedCodes = [];
|
|
|
|
startInfo = self._findStart();
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
code = {
|
|
code: startInfo.code,
|
|
start: startInfo.start,
|
|
end: startInfo.end
|
|
};
|
|
decodedCodes.push(code);
|
|
code = self._decodePayload(code, result, decodedCodes);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
code = self._findEnd(code.end, false);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
|
|
decodedCodes.push(code);
|
|
|
|
// Checksum
|
|
if (!self._checksum(result)) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: startInfo.start,
|
|
end: code.end,
|
|
codeset: "",
|
|
startInfo: startInfo,
|
|
decodedCodes: decodedCodes
|
|
};
|
|
};
|
|
|
|
EANReader.prototype._checksum = function (result) {
|
|
var sum = 0,
|
|
i;
|
|
|
|
for (i = result.length - 2; i >= 0; i -= 2) {
|
|
sum += result[i];
|
|
}
|
|
sum *= 3;
|
|
for (i = result.length - 1; i >= 0; i -= 2) {
|
|
sum += result[i];
|
|
}
|
|
return sum % 10 === 0;
|
|
};
|
|
|
|
exports["default"] = EANReader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 28 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _barcode_reader = __webpack_require__(26);
|
|
|
|
var _barcode_reader2 = _interopRequireDefault(_barcode_reader);
|
|
|
|
var _array_helper = __webpack_require__(17);
|
|
|
|
var _array_helper2 = _interopRequireDefault(_array_helper);
|
|
|
|
function Code39Reader() {
|
|
_barcode_reader2['default'].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
ALPHABETH_STRING: { value: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%" },
|
|
ALPHABET: { value: [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 45, 46, 32, 42, 36, 47, 43, 37] },
|
|
CHARACTER_ENCODINGS: { value: [0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094, 0x0A8, 0x0A2, 0x08A, 0x02A] },
|
|
ASTERISK: { value: 0x094 },
|
|
FORMAT: { value: "code_39", writeable: false }
|
|
};
|
|
|
|
Code39Reader.prototype = Object.create(_barcode_reader2['default'].prototype, properties);
|
|
Code39Reader.prototype.constructor = Code39Reader;
|
|
|
|
Code39Reader.prototype._toCounters = function (start, counter) {
|
|
var self = this,
|
|
numCounters = counter.length,
|
|
end = self._row.length,
|
|
isWhite = !self._row[start],
|
|
i,
|
|
counterPos = 0;
|
|
|
|
_array_helper2['default'].init(counter, 0);
|
|
|
|
for (i = start; i < end; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
counterPos++;
|
|
if (counterPos === numCounters) {
|
|
break;
|
|
} else {
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
}
|
|
|
|
return counter;
|
|
};
|
|
|
|
Code39Reader.prototype._decode = function () {
|
|
var self = this,
|
|
counters = [0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
result = [],
|
|
start = self._findStart(),
|
|
decodedChar,
|
|
lastStart,
|
|
pattern,
|
|
nextStart;
|
|
|
|
if (!start) {
|
|
return null;
|
|
}
|
|
nextStart = self._nextSet(self._row, start.end);
|
|
|
|
do {
|
|
counters = self._toCounters(nextStart, counters);
|
|
pattern = self._toPattern(counters);
|
|
if (pattern < 0) {
|
|
return null;
|
|
}
|
|
decodedChar = self._patternToChar(pattern);
|
|
if (decodedChar < 0) {
|
|
return null;
|
|
}
|
|
result.push(decodedChar);
|
|
lastStart = nextStart;
|
|
nextStart += _array_helper2['default'].sum(counters);
|
|
nextStart = self._nextSet(self._row, nextStart);
|
|
} while (decodedChar !== '*');
|
|
result.pop();
|
|
|
|
if (!result.length) {
|
|
return null;
|
|
}
|
|
|
|
if (!self._verifyTrailingWhitespace(lastStart, nextStart, counters)) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: start.start,
|
|
end: nextStart,
|
|
startInfo: start,
|
|
decodedCodes: result
|
|
};
|
|
};
|
|
|
|
Code39Reader.prototype._verifyTrailingWhitespace = function (lastStart, nextStart, counters) {
|
|
var trailingWhitespaceEnd,
|
|
patternSize = _array_helper2['default'].sum(counters);
|
|
|
|
trailingWhitespaceEnd = nextStart - lastStart - patternSize;
|
|
if (trailingWhitespaceEnd * 3 >= patternSize) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
Code39Reader.prototype._patternToChar = function (pattern) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < self.CHARACTER_ENCODINGS.length; i++) {
|
|
if (self.CHARACTER_ENCODINGS[i] === pattern) {
|
|
return String.fromCharCode(self.ALPHABET[i]);
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Code39Reader.prototype._findNextWidth = function (counters, current) {
|
|
var i,
|
|
minWidth = Number.MAX_VALUE;
|
|
|
|
for (i = 0; i < counters.length; i++) {
|
|
if (counters[i] < minWidth && counters[i] > current) {
|
|
minWidth = counters[i];
|
|
}
|
|
}
|
|
|
|
return minWidth;
|
|
};
|
|
|
|
Code39Reader.prototype._toPattern = function (counters) {
|
|
var numCounters = counters.length,
|
|
maxNarrowWidth = 0,
|
|
numWideBars = numCounters,
|
|
wideBarWidth = 0,
|
|
self = this,
|
|
pattern,
|
|
i;
|
|
|
|
while (numWideBars > 3) {
|
|
maxNarrowWidth = self._findNextWidth(counters, maxNarrowWidth);
|
|
numWideBars = 0;
|
|
pattern = 0;
|
|
for (i = 0; i < numCounters; i++) {
|
|
if (counters[i] > maxNarrowWidth) {
|
|
pattern |= 1 << numCounters - 1 - i;
|
|
numWideBars++;
|
|
wideBarWidth += counters[i];
|
|
}
|
|
}
|
|
|
|
if (numWideBars === 3) {
|
|
for (i = 0; i < numCounters && numWideBars > 0; i++) {
|
|
if (counters[i] > maxNarrowWidth) {
|
|
numWideBars--;
|
|
if (counters[i] * 2 >= wideBarWidth) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
return pattern;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Code39Reader.prototype._findStart = function () {
|
|
var self = this,
|
|
offset = self._nextSet(self._row),
|
|
patternStart = offset,
|
|
counter = [0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
counterPos = 0,
|
|
isWhite = false,
|
|
i,
|
|
j,
|
|
whiteSpaceMustStart;
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
// find start pattern
|
|
if (self._toPattern(counter) === self.ASTERISK) {
|
|
whiteSpaceMustStart = Math.floor(Math.max(0, patternStart - (i - patternStart) / 4));
|
|
if (self._matchRange(whiteSpaceMustStart, patternStart, 0)) {
|
|
return {
|
|
start: patternStart,
|
|
end: i
|
|
};
|
|
}
|
|
}
|
|
|
|
patternStart += counter[0] + counter[1];
|
|
for (j = 0; j < 7; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[7] = 0;
|
|
counter[8] = 0;
|
|
counterPos--;
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
exports['default'] = Code39Reader;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 29 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _code_39_reader = __webpack_require__(28);
|
|
|
|
var _code_39_reader2 = _interopRequireDefault(_code_39_reader);
|
|
|
|
function Code39VINReader() {
|
|
_code_39_reader2['default'].call(this);
|
|
}
|
|
|
|
var patterns = {
|
|
IOQ: /[IOQ]/g,
|
|
AZ09: /[A-Z0-9]{17}/
|
|
};
|
|
|
|
Code39VINReader.prototype = Object.create(_code_39_reader2['default'].prototype);
|
|
Code39VINReader.prototype.constructor = Code39VINReader;
|
|
|
|
// Cribbed from:
|
|
// https://github.com/zxing/zxing/blob/master/core/src/main/java/com/google/zxing/client/result/VINResultParser.java
|
|
Code39VINReader.prototype._decode = function () {
|
|
var result = _code_39_reader2['default'].prototype._decode.apply(this);
|
|
if (!result) {
|
|
return null;
|
|
}
|
|
|
|
var code = result.code;
|
|
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
|
|
code = code.replace(patterns.IOQ, '');
|
|
|
|
if (!code.match(patterns.AZ09)) {
|
|
console.log('Failed AZ09 pattern code:', code);
|
|
return null;
|
|
}
|
|
|
|
if (!this._checkChecksum(code)) {
|
|
return null;
|
|
}
|
|
|
|
result.code = code;
|
|
return result;
|
|
};
|
|
|
|
Code39VINReader.prototype._checkChecksum = function (code) {
|
|
// TODO
|
|
return !!code;
|
|
};
|
|
|
|
exports['default'] = Code39VINReader;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 30 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _barcode_reader = __webpack_require__(26);
|
|
|
|
var _barcode_reader2 = _interopRequireDefault(_barcode_reader);
|
|
|
|
function CodabarReader() {
|
|
_barcode_reader2["default"].call(this);
|
|
this._counters = [];
|
|
}
|
|
|
|
var properties = {
|
|
ALPHABETH_STRING: { value: "0123456789-$:/.+ABCD" },
|
|
ALPHABET: { value: [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 36, 58, 47, 46, 43, 65, 66, 67, 68] },
|
|
CHARACTER_ENCODINGS: { value: [0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, 0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E] },
|
|
START_END: { value: [0x01A, 0x029, 0x00B, 0x00E] },
|
|
MIN_ENCODED_CHARS: { value: 4 },
|
|
MAX_ACCEPTABLE: { value: 2.0 },
|
|
PADDING: { value: 1.5 },
|
|
FORMAT: { value: "codabar", writeable: false }
|
|
};
|
|
|
|
CodabarReader.prototype = Object.create(_barcode_reader2["default"].prototype, properties);
|
|
CodabarReader.prototype.constructor = CodabarReader;
|
|
|
|
CodabarReader.prototype._decode = function () {
|
|
var self = this,
|
|
result = [],
|
|
start,
|
|
decodedChar,
|
|
pattern,
|
|
nextStart,
|
|
end;
|
|
|
|
this._counters = self._fillCounters();
|
|
start = self._findStart();
|
|
if (!start) {
|
|
return null;
|
|
}
|
|
nextStart = start.startCounter;
|
|
|
|
do {
|
|
pattern = self._toPattern(nextStart);
|
|
if (pattern < 0) {
|
|
return null;
|
|
}
|
|
decodedChar = self._patternToChar(pattern);
|
|
if (decodedChar < 0) {
|
|
return null;
|
|
}
|
|
result.push(decodedChar);
|
|
nextStart += 8;
|
|
if (result.length > 1 && self._isStartEnd(pattern)) {
|
|
break;
|
|
}
|
|
} while (nextStart < self._counters.length);
|
|
|
|
// verify end
|
|
if (result.length - 2 < self.MIN_ENCODED_CHARS || !self._isStartEnd(pattern)) {
|
|
return null;
|
|
}
|
|
|
|
// verify end white space
|
|
if (!self._verifyWhitespace(start.startCounter, nextStart - 8)) {
|
|
return null;
|
|
}
|
|
|
|
if (!self._validateResult(result, start.startCounter)) {
|
|
return null;
|
|
}
|
|
|
|
nextStart = nextStart > self._counters.length ? self._counters.length : nextStart;
|
|
end = start.start + self._sumCounters(start.startCounter, nextStart - 8);
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: start.start,
|
|
end: end,
|
|
startInfo: start,
|
|
decodedCodes: result
|
|
};
|
|
};
|
|
|
|
CodabarReader.prototype._verifyWhitespace = function (startCounter, endCounter) {
|
|
if (startCounter - 1 <= 0 || this._counters[startCounter - 1] >= this._calculatePatternLength(startCounter) / 2.0) {
|
|
if (endCounter + 8 >= this._counters.length || this._counters[endCounter + 7] >= this._calculatePatternLength(endCounter) / 2.0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
CodabarReader.prototype._calculatePatternLength = function (offset) {
|
|
var i,
|
|
sum = 0;
|
|
|
|
for (i = offset; i < offset + 7; i++) {
|
|
sum += this._counters[i];
|
|
}
|
|
|
|
return sum;
|
|
};
|
|
|
|
CodabarReader.prototype._thresholdResultPattern = function (result, startCounter) {
|
|
var self = this,
|
|
categorization = {
|
|
space: {
|
|
narrow: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE },
|
|
wide: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE }
|
|
},
|
|
bar: {
|
|
narrow: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE },
|
|
wide: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE }
|
|
}
|
|
},
|
|
kind,
|
|
cat,
|
|
i,
|
|
j,
|
|
pos = startCounter,
|
|
pattern;
|
|
|
|
for (i = 0; i < result.length; i++) {
|
|
pattern = self._charToPattern(result[i]);
|
|
for (j = 6; j >= 0; j--) {
|
|
kind = (j & 1) === 2 ? categorization.bar : categorization.space;
|
|
cat = (pattern & 1) === 1 ? kind.wide : kind.narrow;
|
|
cat.size += self._counters[pos + j];
|
|
cat.counts++;
|
|
pattern >>= 1;
|
|
}
|
|
pos += 8;
|
|
}
|
|
|
|
["space", "bar"].forEach(function (key) {
|
|
var newkind = categorization[key];
|
|
newkind.wide.min = Math.floor((newkind.narrow.size / newkind.narrow.counts + newkind.wide.size / newkind.wide.counts) / 2);
|
|
newkind.narrow.max = Math.ceil(newkind.wide.min);
|
|
newkind.wide.max = Math.ceil((newkind.wide.size * self.MAX_ACCEPTABLE + self.PADDING) / newkind.wide.counts);
|
|
});
|
|
|
|
return categorization;
|
|
};
|
|
|
|
CodabarReader.prototype._charToPattern = function (char) {
|
|
var self = this,
|
|
charCode = char.charCodeAt(0),
|
|
i;
|
|
|
|
for (i = 0; i < self.ALPHABET.length; i++) {
|
|
if (self.ALPHABET[i] === charCode) {
|
|
return self.CHARACTER_ENCODINGS[i];
|
|
}
|
|
}
|
|
return 0x0;
|
|
};
|
|
|
|
CodabarReader.prototype._validateResult = function (result, startCounter) {
|
|
var self = this,
|
|
thresholds = self._thresholdResultPattern(result, startCounter),
|
|
i,
|
|
j,
|
|
kind,
|
|
cat,
|
|
size,
|
|
pos = startCounter,
|
|
pattern;
|
|
|
|
for (i = 0; i < result.length; i++) {
|
|
pattern = self._charToPattern(result[i]);
|
|
for (j = 6; j >= 0; j--) {
|
|
kind = (j & 1) === 0 ? thresholds.bar : thresholds.space;
|
|
cat = (pattern & 1) === 1 ? kind.wide : kind.narrow;
|
|
size = self._counters[pos + j];
|
|
if (size < cat.min || size > cat.max) {
|
|
return false;
|
|
}
|
|
pattern >>= 1;
|
|
}
|
|
pos += 8;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
CodabarReader.prototype._patternToChar = function (pattern) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < self.CHARACTER_ENCODINGS.length; i++) {
|
|
if (self.CHARACTER_ENCODINGS[i] === pattern) {
|
|
return String.fromCharCode(self.ALPHABET[i]);
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
CodabarReader.prototype._computeAlternatingThreshold = function (offset, end) {
|
|
var i,
|
|
min = Number.MAX_VALUE,
|
|
max = 0,
|
|
counter;
|
|
|
|
for (i = offset; i < end; i += 2) {
|
|
counter = this._counters[i];
|
|
if (counter > max) {
|
|
max = counter;
|
|
}
|
|
if (counter < min) {
|
|
min = counter;
|
|
}
|
|
}
|
|
|
|
return (min + max) / 2.0 | 0;
|
|
};
|
|
|
|
CodabarReader.prototype._toPattern = function (offset) {
|
|
var numCounters = 7,
|
|
end = offset + numCounters,
|
|
barThreshold,
|
|
spaceThreshold,
|
|
bitmask = 1 << numCounters - 1,
|
|
pattern = 0,
|
|
i,
|
|
threshold;
|
|
|
|
if (end > this._counters.length) {
|
|
return -1;
|
|
}
|
|
|
|
barThreshold = this._computeAlternatingThreshold(offset, end);
|
|
spaceThreshold = this._computeAlternatingThreshold(offset + 1, end);
|
|
|
|
for (i = 0; i < numCounters; i++) {
|
|
threshold = (i & 1) === 0 ? barThreshold : spaceThreshold;
|
|
if (this._counters[offset + i] > threshold) {
|
|
pattern |= bitmask;
|
|
}
|
|
bitmask >>= 1;
|
|
}
|
|
|
|
return pattern;
|
|
};
|
|
|
|
CodabarReader.prototype._isStartEnd = function (pattern) {
|
|
var i;
|
|
|
|
for (i = 0; i < this.START_END.length; i++) {
|
|
if (this.START_END[i] === pattern) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
CodabarReader.prototype._sumCounters = function (start, end) {
|
|
var i,
|
|
sum = 0;
|
|
|
|
for (i = start; i < end; i++) {
|
|
sum += this._counters[i];
|
|
}
|
|
return sum;
|
|
};
|
|
|
|
CodabarReader.prototype._findStart = function () {
|
|
var self = this,
|
|
i,
|
|
pattern,
|
|
start = self._nextUnset(self._row),
|
|
end;
|
|
|
|
for (i = 1; i < this._counters.length; i++) {
|
|
pattern = self._toPattern(i);
|
|
if (pattern !== -1 && self._isStartEnd(pattern)) {
|
|
// TODO: Look for whitespace ahead
|
|
start += self._sumCounters(0, i);
|
|
end = start + self._sumCounters(i, i + 8);
|
|
return {
|
|
start: start,
|
|
end: end,
|
|
startCounter: i,
|
|
endCounter: i + 8
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
exports["default"] = CodabarReader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 31 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _ean_reader = __webpack_require__(27);
|
|
|
|
var _ean_reader2 = _interopRequireDefault(_ean_reader);
|
|
|
|
function UPCReader() {
|
|
_ean_reader2["default"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
FORMAT: { value: "upc_a", writeable: false }
|
|
};
|
|
|
|
UPCReader.prototype = Object.create(_ean_reader2["default"].prototype, properties);
|
|
UPCReader.prototype.constructor = UPCReader;
|
|
|
|
UPCReader.prototype._decode = function () {
|
|
var result = _ean_reader2["default"].prototype._decode.call(this);
|
|
|
|
if (result && result.code && result.code.length === 13 && result.code.charAt(0) === "0") {
|
|
result.code = result.code.substring(1);
|
|
return result;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
exports["default"] = UPCReader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 32 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _ean_reader = __webpack_require__(27);
|
|
|
|
var _ean_reader2 = _interopRequireDefault(_ean_reader);
|
|
|
|
function EAN8Reader() {
|
|
_ean_reader2["default"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
FORMAT: { value: "ean_8", writeable: false }
|
|
};
|
|
|
|
EAN8Reader.prototype = Object.create(_ean_reader2["default"].prototype, properties);
|
|
EAN8Reader.prototype.constructor = EAN8Reader;
|
|
|
|
EAN8Reader.prototype._decodePayload = function (code, result, decodedCodes) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
code = self._decodeCode(code.end, self.CODE_G_START);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
result.push(code.code);
|
|
decodedCodes.push(code);
|
|
}
|
|
|
|
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
|
|
if (code === null) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
code = self._decodeCode(code.end, self.CODE_G_START);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
result.push(code.code);
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
exports["default"] = EAN8Reader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 33 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _ean_reader = __webpack_require__(27);
|
|
|
|
var _ean_reader2 = _interopRequireDefault(_ean_reader);
|
|
|
|
function UPCEReader() {
|
|
_ean_reader2["default"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
CODE_FREQUENCY: { value: [[56, 52, 50, 49, 44, 38, 35, 42, 41, 37], [7, 11, 13, 14, 19, 25, 28, 21, 22, 26]] },
|
|
STOP_PATTERN: { value: [1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7] },
|
|
FORMAT: { value: "upc_e", writeable: false }
|
|
};
|
|
|
|
UPCEReader.prototype = Object.create(_ean_reader2["default"].prototype, properties);
|
|
UPCEReader.prototype.constructor = UPCEReader;
|
|
|
|
UPCEReader.prototype._decodePayload = function (code, result, decodedCodes) {
|
|
var i,
|
|
self = this,
|
|
codeFrequency = 0x0;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
code = self._decodeCode(code.end);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
if (code.code >= self.CODE_G_START) {
|
|
code.code = code.code - self.CODE_G_START;
|
|
codeFrequency |= 1 << 5 - i;
|
|
}
|
|
result.push(code.code);
|
|
decodedCodes.push(code);
|
|
}
|
|
if (!self._determineParity(codeFrequency, result)) {
|
|
return null;
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
UPCEReader.prototype._determineParity = function (codeFrequency, result) {
|
|
var i, nrSystem;
|
|
|
|
for (nrSystem = 0; nrSystem < this.CODE_FREQUENCY.length; nrSystem++) {
|
|
for (i = 0; i < this.CODE_FREQUENCY[nrSystem].length; i++) {
|
|
if (codeFrequency === this.CODE_FREQUENCY[nrSystem][i]) {
|
|
result.unshift(nrSystem);
|
|
result.push(i);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
UPCEReader.prototype._convertToUPCA = function (result) {
|
|
var upca = [result[0]],
|
|
lastDigit = result[result.length - 2];
|
|
|
|
if (lastDigit <= 2) {
|
|
upca = upca.concat(result.slice(1, 3)).concat([lastDigit, 0, 0, 0, 0]).concat(result.slice(3, 6));
|
|
} else if (lastDigit === 3) {
|
|
upca = upca.concat(result.slice(1, 4)).concat([0, 0, 0, 0, 0]).concat(result.slice(4, 6));
|
|
} else if (lastDigit === 4) {
|
|
upca = upca.concat(result.slice(1, 5)).concat([0, 0, 0, 0, 0, result[5]]);
|
|
} else {
|
|
upca = upca.concat(result.slice(1, 6)).concat([0, 0, 0, 0, lastDigit]);
|
|
}
|
|
|
|
upca.push(result[result.length - 1]);
|
|
return upca;
|
|
};
|
|
|
|
UPCEReader.prototype._checksum = function (result) {
|
|
return _ean_reader2["default"].prototype._checksum.call(this, this._convertToUPCA(result));
|
|
};
|
|
|
|
UPCEReader.prototype._findEnd = function (offset, isWhite) {
|
|
isWhite = true;
|
|
return _ean_reader2["default"].prototype._findEnd.call(this, offset, isWhite);
|
|
};
|
|
|
|
UPCEReader.prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start) / 2;
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
};
|
|
|
|
exports["default"] = UPCEReader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 34 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _barcode_reader = __webpack_require__(26);
|
|
|
|
var _barcode_reader2 = _interopRequireDefault(_barcode_reader);
|
|
|
|
var merge = __webpack_require__(35);
|
|
|
|
function I2of5Reader(opts) {
|
|
opts = merge(getDefaulConfig(), opts);
|
|
_barcode_reader2['default'].call(this, opts);
|
|
this.barSpaceRatio = [1, 1];
|
|
if (opts.normalizeBarSpaceWidth) {
|
|
this.SINGLE_CODE_ERROR = 0.38;
|
|
this.AVG_CODE_ERROR = 0.09;
|
|
}
|
|
}
|
|
|
|
function getDefaulConfig() {
|
|
var config = {};
|
|
|
|
Object.keys(I2of5Reader.CONFIG_KEYS).forEach(function (key) {
|
|
config[key] = I2of5Reader.CONFIG_KEYS[key]['default'];
|
|
});
|
|
return config;
|
|
}
|
|
|
|
var N = 1,
|
|
W = 3,
|
|
properties = {
|
|
MODULO: { value: 10 },
|
|
START_PATTERN: { value: [N * 2.5, N * 2.5, N * 2.5, N * 2.5] },
|
|
STOP_PATTERN: { value: [N * 2, N * 2, W * 2] },
|
|
CODE_PATTERN: { value: [[N, N, W, W, N], [W, N, N, N, W], [N, W, N, N, W], [W, W, N, N, N], [N, N, W, N, W], [W, N, W, N, N], [N, W, W, N, N], [N, N, N, W, W], [W, N, N, W, N], [N, W, N, W, N]] },
|
|
SINGLE_CODE_ERROR: { value: 0.78, writable: true },
|
|
AVG_CODE_ERROR: { value: 0.38, writable: true },
|
|
MAX_CORRECTION_FACTOR: { value: 5 },
|
|
FORMAT: { value: "i2of5" }
|
|
};
|
|
|
|
I2of5Reader.prototype = Object.create(_barcode_reader2['default'].prototype, properties);
|
|
I2of5Reader.prototype.constructor = I2of5Reader;
|
|
|
|
I2of5Reader.prototype._matchPattern = function (counter, code) {
|
|
if (this.config.normalizeBarSpaceWidth) {
|
|
var i,
|
|
counterSum = [0, 0],
|
|
codeSum = [0, 0],
|
|
correction = [0, 0],
|
|
correctionRatio = this.MAX_CORRECTION_FACTOR,
|
|
correctionRatioInverse = 1 / correctionRatio;
|
|
|
|
for (i = 0; i < counter.length; i++) {
|
|
counterSum[i % 2] += counter[i];
|
|
codeSum[i % 2] += code[i];
|
|
}
|
|
correction[0] = codeSum[0] / counterSum[0];
|
|
correction[1] = codeSum[1] / counterSum[1];
|
|
|
|
correction[0] = Math.max(Math.min(correction[0], correctionRatio), correctionRatioInverse);
|
|
correction[1] = Math.max(Math.min(correction[1], correctionRatio), correctionRatioInverse);
|
|
this.barSpaceRatio = correction;
|
|
for (i = 0; i < counter.length; i++) {
|
|
counter[i] *= this.barSpaceRatio[i % 2];
|
|
}
|
|
}
|
|
return _barcode_reader2['default'].prototype._matchPattern.call(this, counter, code);
|
|
};
|
|
|
|
I2of5Reader.prototype._findPattern = function (pattern, offset, isWhite, tryHarder) {
|
|
var counter = [],
|
|
self = this,
|
|
i,
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
},
|
|
error,
|
|
j,
|
|
sum,
|
|
normalized,
|
|
epsilon = self.AVG_CODE_ERROR;
|
|
|
|
isWhite = isWhite || false;
|
|
tryHarder = tryHarder || false;
|
|
|
|
if (!offset) {
|
|
offset = self._nextSet(self._row);
|
|
}
|
|
|
|
for (i = 0; i < pattern.length; i++) {
|
|
counter[i] = 0;
|
|
}
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
sum = 0;
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
error = self._matchPattern(normalized, pattern);
|
|
|
|
if (error < epsilon) {
|
|
bestMatch.error = error;
|
|
bestMatch.start = i - sum;
|
|
bestMatch.end = i;
|
|
return bestMatch;
|
|
}
|
|
}
|
|
if (tryHarder) {
|
|
for (j = 0; j < counter.length - 2; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[counter.length - 2] = 0;
|
|
counter[counter.length - 1] = 0;
|
|
counterPos--;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
I2of5Reader.prototype._findStart = function () {
|
|
var self = this,
|
|
leadingWhitespaceStart,
|
|
offset = self._nextSet(self._row),
|
|
startInfo,
|
|
narrowBarWidth = 1;
|
|
|
|
while (!startInfo) {
|
|
startInfo = self._findPattern(self.START_PATTERN, offset, false, true);
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
narrowBarWidth = Math.floor((startInfo.end - startInfo.start) / 4);
|
|
leadingWhitespaceStart = startInfo.start - narrowBarWidth * 10;
|
|
if (leadingWhitespaceStart >= 0) {
|
|
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
|
|
return startInfo;
|
|
}
|
|
}
|
|
offset = startInfo.end;
|
|
startInfo = null;
|
|
}
|
|
};
|
|
|
|
I2of5Reader.prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start) / 2;
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
I2of5Reader.prototype._findEnd = function () {
|
|
var self = this,
|
|
endInfo,
|
|
tmp;
|
|
|
|
self._row.reverse();
|
|
endInfo = self._findPattern(self.STOP_PATTERN);
|
|
self._row.reverse();
|
|
|
|
if (endInfo === null) {
|
|
return null;
|
|
}
|
|
|
|
// reverse numbers
|
|
tmp = endInfo.start;
|
|
endInfo.start = self._row.length - endInfo.end;
|
|
endInfo.end = self._row.length - tmp;
|
|
|
|
return endInfo !== null ? self._verifyTrailingWhitespace(endInfo) : null;
|
|
};
|
|
|
|
I2of5Reader.prototype._decodePair = function (counterPair) {
|
|
var i,
|
|
code,
|
|
codes = [],
|
|
self = this;
|
|
|
|
for (i = 0; i < counterPair.length; i++) {
|
|
code = self._decodeCode(counterPair[i]);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
codes.push(code);
|
|
}
|
|
return codes;
|
|
};
|
|
|
|
I2of5Reader.prototype._decodeCode = function (counter) {
|
|
var j,
|
|
self = this,
|
|
sum = 0,
|
|
normalized,
|
|
error,
|
|
epsilon = self.AVG_CODE_ERROR,
|
|
code,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
};
|
|
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = 0; code < self.CODE_PATTERN.length; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
if (bestMatch.error < epsilon) {
|
|
return bestMatch;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
I2of5Reader.prototype._decodePayload = function (counters, result, decodedCodes) {
|
|
var i,
|
|
self = this,
|
|
pos = 0,
|
|
counterLength = counters.length,
|
|
counterPair = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]],
|
|
codes;
|
|
|
|
while (pos < counterLength) {
|
|
for (i = 0; i < 5; i++) {
|
|
counterPair[0][i] = counters[pos] * this.barSpaceRatio[0];
|
|
counterPair[1][i] = counters[pos + 1] * this.barSpaceRatio[1];
|
|
pos += 2;
|
|
}
|
|
codes = self._decodePair(counterPair);
|
|
if (!codes) {
|
|
return null;
|
|
}
|
|
for (i = 0; i < codes.length; i++) {
|
|
result.push(codes[i].code + "");
|
|
decodedCodes.push(codes[i]);
|
|
}
|
|
}
|
|
return codes;
|
|
};
|
|
|
|
I2of5Reader.prototype._verifyCounterLength = function (counters) {
|
|
return counters.length % 10 === 0;
|
|
};
|
|
|
|
I2of5Reader.prototype._decode = function () {
|
|
var startInfo,
|
|
endInfo,
|
|
self = this,
|
|
code,
|
|
result = [],
|
|
decodedCodes = [],
|
|
counters;
|
|
|
|
startInfo = self._findStart();
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(startInfo);
|
|
|
|
endInfo = self._findEnd();
|
|
if (!endInfo) {
|
|
return null;
|
|
}
|
|
|
|
counters = self._fillCounters(startInfo.end, endInfo.start, false);
|
|
if (!self._verifyCounterLength(counters)) {
|
|
return null;
|
|
}
|
|
code = self._decodePayload(counters, result, decodedCodes);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
if (result.length % 2 !== 0 || result.length < 6) {
|
|
return null;
|
|
}
|
|
|
|
decodedCodes.push(endInfo);
|
|
return {
|
|
code: result.join(""),
|
|
start: startInfo.start,
|
|
end: endInfo.end,
|
|
startInfo: startInfo,
|
|
decodedCodes: decodedCodes
|
|
};
|
|
};
|
|
|
|
I2of5Reader.CONFIG_KEYS = {
|
|
normalizeBarSpaceWidth: {
|
|
'type': 'boolean',
|
|
'default': false,
|
|
'description': 'If true, the reader tries to normalize the' + 'width-difference between bars and spaces'
|
|
}
|
|
};
|
|
|
|
exports['default'] = I2of5Reader;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 35 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseMerge = __webpack_require__(36),
|
|
createAssigner = __webpack_require__(63);
|
|
|
|
/**
|
|
* Recursively merges own enumerable properties of the source object(s), that
|
|
* don't resolve to `undefined` into the destination object. Subsequent sources
|
|
* overwrite property assignments of previous sources. If `customizer` is
|
|
* provided it's invoked to produce the merged values of the destination and
|
|
* source properties. If `customizer` returns `undefined` merging is handled
|
|
* by the method instead. The `customizer` is bound to `thisArg` and invoked
|
|
* with five arguments: (objectValue, sourceValue, key, object, source).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @param {*} [thisArg] The `this` binding of `customizer`.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
|
|
* };
|
|
*
|
|
* var ages = {
|
|
* 'data': [{ 'age': 36 }, { 'age': 40 }]
|
|
* };
|
|
*
|
|
* _.merge(users, ages);
|
|
* // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
|
|
*
|
|
* // using a customizer callback
|
|
* var object = {
|
|
* 'fruits': ['apple'],
|
|
* 'vegetables': ['beet']
|
|
* };
|
|
*
|
|
* var other = {
|
|
* 'fruits': ['banana'],
|
|
* 'vegetables': ['carrot']
|
|
* };
|
|
*
|
|
* _.merge(object, other, function(a, b) {
|
|
* if (_.isArray(a)) {
|
|
* return a.concat(b);
|
|
* }
|
|
* });
|
|
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
|
|
*/
|
|
var merge = createAssigner(baseMerge);
|
|
|
|
module.exports = merge;
|
|
|
|
|
|
/***/ },
|
|
/* 36 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var arrayEach = __webpack_require__(37),
|
|
baseMergeDeep = __webpack_require__(38),
|
|
isArray = __webpack_require__(46),
|
|
isArrayLike = __webpack_require__(41),
|
|
isObject = __webpack_require__(50),
|
|
isObjectLike = __webpack_require__(45),
|
|
isTypedArray = __webpack_require__(58),
|
|
keys = __webpack_require__(61);
|
|
|
|
/**
|
|
* The base implementation of `_.merge` without support for argument juggling,
|
|
* multiple sources, and `this` binding `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Array} [stackA=[]] Tracks traversed source objects.
|
|
* @param {Array} [stackB=[]] Associates values with source counterparts.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseMerge(object, source, customizer, stackA, stackB) {
|
|
if (!isObject(object)) {
|
|
return object;
|
|
}
|
|
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
|
|
props = isSrcArr ? undefined : keys(source);
|
|
|
|
arrayEach(props || source, function(srcValue, key) {
|
|
if (props) {
|
|
key = srcValue;
|
|
srcValue = source[key];
|
|
}
|
|
if (isObjectLike(srcValue)) {
|
|
stackA || (stackA = []);
|
|
stackB || (stackB = []);
|
|
baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
|
|
}
|
|
else {
|
|
var value = object[key],
|
|
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
|
isCommon = result === undefined;
|
|
|
|
if (isCommon) {
|
|
result = srcValue;
|
|
}
|
|
if ((result !== undefined || (isSrcArr && !(key in object))) &&
|
|
(isCommon || (result === result ? (result !== value) : (value === value)))) {
|
|
object[key] = result;
|
|
}
|
|
}
|
|
});
|
|
return object;
|
|
}
|
|
|
|
module.exports = baseMerge;
|
|
|
|
|
|
/***/ },
|
|
/* 37 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* A specialized version of `_.forEach` for arrays without support for callback
|
|
* shorthands and `this` binding.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEach(array, iteratee) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (iteratee(array[index], index, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
module.exports = arrayEach;
|
|
|
|
|
|
/***/ },
|
|
/* 38 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var arrayCopy = __webpack_require__(39),
|
|
isArguments = __webpack_require__(40),
|
|
isArray = __webpack_require__(46),
|
|
isArrayLike = __webpack_require__(41),
|
|
isPlainObject = __webpack_require__(51),
|
|
isTypedArray = __webpack_require__(58),
|
|
toPlainObject = __webpack_require__(59);
|
|
|
|
/**
|
|
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
* deep merges and tracks traversed objects enabling objects with circular
|
|
* references to be merged.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {string} key The key of the value to merge.
|
|
* @param {Function} mergeFunc The function to merge values.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Array} [stackA=[]] Tracks traversed source objects.
|
|
* @param {Array} [stackB=[]] Associates values with source counterparts.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
|
|
var length = stackA.length,
|
|
srcValue = source[key];
|
|
|
|
while (length--) {
|
|
if (stackA[length] == srcValue) {
|
|
object[key] = stackB[length];
|
|
return;
|
|
}
|
|
}
|
|
var value = object[key],
|
|
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
|
isCommon = result === undefined;
|
|
|
|
if (isCommon) {
|
|
result = srcValue;
|
|
if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
|
|
result = isArray(value)
|
|
? value
|
|
: (isArrayLike(value) ? arrayCopy(value) : []);
|
|
}
|
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
result = isArguments(value)
|
|
? toPlainObject(value)
|
|
: (isPlainObject(value) ? value : {});
|
|
}
|
|
else {
|
|
isCommon = false;
|
|
}
|
|
}
|
|
// Add the source value to the stack of traversed objects and associate
|
|
// it with its merged value.
|
|
stackA.push(srcValue);
|
|
stackB.push(result);
|
|
|
|
if (isCommon) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
|
|
} else if (result === result ? (result !== value) : (value === value)) {
|
|
object[key] = result;
|
|
}
|
|
}
|
|
|
|
module.exports = baseMergeDeep;
|
|
|
|
|
|
/***/ },
|
|
/* 39 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* Copies the values of `source` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} source The array to copy values from.
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayCopy(source, array) {
|
|
var index = -1,
|
|
length = source.length;
|
|
|
|
array || (array = Array(length));
|
|
while (++index < length) {
|
|
array[index] = source[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
module.exports = arrayCopy;
|
|
|
|
|
|
/***/ },
|
|
/* 40 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArrayLike = __webpack_require__(41),
|
|
isObjectLike = __webpack_require__(45);
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Native method references. */
|
|
var propertyIsEnumerable = objectProto.propertyIsEnumerable;
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `arguments` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArguments(function() { return arguments; }());
|
|
* // => true
|
|
*
|
|
* _.isArguments([1, 2, 3]);
|
|
* // => false
|
|
*/
|
|
function isArguments(value) {
|
|
return isObjectLike(value) && isArrayLike(value) &&
|
|
hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
|
|
}
|
|
|
|
module.exports = isArguments;
|
|
|
|
|
|
/***/ },
|
|
/* 41 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getLength = __webpack_require__(42),
|
|
isLength = __webpack_require__(44);
|
|
|
|
/**
|
|
* Checks if `value` is array-like.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
*/
|
|
function isArrayLike(value) {
|
|
return value != null && isLength(getLength(value));
|
|
}
|
|
|
|
module.exports = isArrayLike;
|
|
|
|
|
|
/***/ },
|
|
/* 42 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseProperty = __webpack_require__(43);
|
|
|
|
/**
|
|
* Gets the "length" property value of `object`.
|
|
*
|
|
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
|
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {*} Returns the "length" value.
|
|
*/
|
|
var getLength = baseProperty('length');
|
|
|
|
module.exports = getLength;
|
|
|
|
|
|
/***/ },
|
|
/* 43 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* The base implementation of `_.property` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseProperty(key) {
|
|
return function(object) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
module.exports = baseProperty;
|
|
|
|
|
|
/***/ },
|
|
/* 44 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
|
* of an array-like value.
|
|
*/
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like length.
|
|
*
|
|
* **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
*/
|
|
function isLength(value) {
|
|
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
module.exports = isLength;
|
|
|
|
|
|
/***/ },
|
|
/* 45 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* Checks if `value` is object-like.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
*/
|
|
function isObjectLike(value) {
|
|
return !!value && typeof value == 'object';
|
|
}
|
|
|
|
module.exports = isObjectLike;
|
|
|
|
|
|
/***/ },
|
|
/* 46 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getNative = __webpack_require__(47),
|
|
isLength = __webpack_require__(44),
|
|
isObjectLike = __webpack_require__(45);
|
|
|
|
/** `Object#toString` result references. */
|
|
var arrayTag = '[object Array]';
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objToString = objectProto.toString;
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeIsArray = getNative(Array, 'isArray');
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `Array` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArray([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArray(function() { return arguments; }());
|
|
* // => false
|
|
*/
|
|
var isArray = nativeIsArray || function(value) {
|
|
return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
|
|
};
|
|
|
|
module.exports = isArray;
|
|
|
|
|
|
/***/ },
|
|
/* 47 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isNative = __webpack_require__(48);
|
|
|
|
/**
|
|
* Gets the native function at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the method to get.
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
*/
|
|
function getNative(object, key) {
|
|
var value = object == null ? undefined : object[key];
|
|
return isNative(value) ? value : undefined;
|
|
}
|
|
|
|
module.exports = getNative;
|
|
|
|
|
|
/***/ },
|
|
/* 48 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isFunction = __webpack_require__(49),
|
|
isObjectLike = __webpack_require__(45);
|
|
|
|
/** Used to detect host constructors (Safari > 5). */
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var fnToString = Function.prototype.toString;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Used to detect if a method is native. */
|
|
var reIsNative = RegExp('^' +
|
|
fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
);
|
|
|
|
/**
|
|
* Checks if `value` is a native function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNative(Array.prototype.push);
|
|
* // => true
|
|
*
|
|
* _.isNative(_);
|
|
* // => false
|
|
*/
|
|
function isNative(value) {
|
|
if (value == null) {
|
|
return false;
|
|
}
|
|
if (isFunction(value)) {
|
|
return reIsNative.test(fnToString.call(value));
|
|
}
|
|
return isObjectLike(value) && reIsHostCtor.test(value);
|
|
}
|
|
|
|
module.exports = isNative;
|
|
|
|
|
|
/***/ },
|
|
/* 49 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(50);
|
|
|
|
/** `Object#toString` result references. */
|
|
var funcTag = '[object Function]';
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Function` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFunction(_);
|
|
* // => true
|
|
*
|
|
* _.isFunction(/abc/);
|
|
* // => false
|
|
*/
|
|
function isFunction(value) {
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
// in older versions of Chrome and Safari which return 'function' for regexes
|
|
// and Safari 8 which returns 'object' for typed array constructors.
|
|
return isObject(value) && objToString.call(value) == funcTag;
|
|
}
|
|
|
|
module.exports = isFunction;
|
|
|
|
|
|
/***/ },
|
|
/* 50 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
|
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObject({});
|
|
* // => true
|
|
*
|
|
* _.isObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObject(1);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
// Avoid a V8 JIT bug in Chrome 19-20.
|
|
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
|
|
var type = typeof value;
|
|
return !!value && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
module.exports = isObject;
|
|
|
|
|
|
/***/ },
|
|
/* 51 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseForIn = __webpack_require__(52),
|
|
isArguments = __webpack_require__(40),
|
|
isObjectLike = __webpack_require__(45);
|
|
|
|
/** `Object#toString` result references. */
|
|
var objectTag = '[object Object]';
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is a plain object, that is, an object created by the
|
|
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
*
|
|
* **Note:** This method assumes objects created by the `Object` constructor
|
|
* have no inherited enumerable properties.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* _.isPlainObject(new Foo);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject([1, 2, 3]);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
* // => true
|
|
*
|
|
* _.isPlainObject(Object.create(null));
|
|
* // => true
|
|
*/
|
|
function isPlainObject(value) {
|
|
var Ctor;
|
|
|
|
// Exit early for non `Object` objects.
|
|
if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
|
|
(!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
|
|
return false;
|
|
}
|
|
// IE < 9 iterates inherited properties before own properties. If the first
|
|
// iterated property is an object's own property then there are no inherited
|
|
// enumerable properties.
|
|
var result;
|
|
// In most environments an object's own properties are iterated before
|
|
// its inherited properties. If the last iterated property is an object's
|
|
// own property then there are no inherited enumerable properties.
|
|
baseForIn(value, function(subValue, key) {
|
|
result = key;
|
|
});
|
|
return result === undefined || hasOwnProperty.call(value, result);
|
|
}
|
|
|
|
module.exports = isPlainObject;
|
|
|
|
|
|
/***/ },
|
|
/* 52 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseFor = __webpack_require__(53),
|
|
keysIn = __webpack_require__(56);
|
|
|
|
/**
|
|
* The base implementation of `_.forIn` without support for callback
|
|
* shorthands and `this` binding.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForIn(object, iteratee) {
|
|
return baseFor(object, iteratee, keysIn);
|
|
}
|
|
|
|
module.exports = baseForIn;
|
|
|
|
|
|
/***/ },
|
|
/* 53 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var createBaseFor = __webpack_require__(54);
|
|
|
|
/**
|
|
* The base implementation of `baseForIn` and `baseForOwn` which iterates
|
|
* over `object` properties returned by `keysFunc` invoking `iteratee` for
|
|
* each property. Iteratee functions may exit iteration early by explicitly
|
|
* returning `false`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseFor = createBaseFor();
|
|
|
|
module.exports = baseFor;
|
|
|
|
|
|
/***/ },
|
|
/* 54 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var toObject = __webpack_require__(55);
|
|
|
|
/**
|
|
* Creates a base function for `_.forIn` or `_.forInRight`.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseFor(fromRight) {
|
|
return function(object, iteratee, keysFunc) {
|
|
var iterable = toObject(object),
|
|
props = keysFunc(object),
|
|
length = props.length,
|
|
index = fromRight ? length : -1;
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
var key = props[index];
|
|
if (iteratee(iterable[key], key, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return object;
|
|
};
|
|
}
|
|
|
|
module.exports = createBaseFor;
|
|
|
|
|
|
/***/ },
|
|
/* 55 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(50);
|
|
|
|
/**
|
|
* Converts `value` to an object if it's not one.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {Object} Returns the object.
|
|
*/
|
|
function toObject(value) {
|
|
return isObject(value) ? value : Object(value);
|
|
}
|
|
|
|
module.exports = toObject;
|
|
|
|
|
|
/***/ },
|
|
/* 56 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArguments = __webpack_require__(40),
|
|
isArray = __webpack_require__(46),
|
|
isIndex = __webpack_require__(57),
|
|
isLength = __webpack_require__(44),
|
|
isObject = __webpack_require__(50);
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keysIn(new Foo);
|
|
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
*/
|
|
function keysIn(object) {
|
|
if (object == null) {
|
|
return [];
|
|
}
|
|
if (!isObject(object)) {
|
|
object = Object(object);
|
|
}
|
|
var length = object.length;
|
|
length = (length && isLength(length) &&
|
|
(isArray(object) || isArguments(object)) && length) || 0;
|
|
|
|
var Ctor = object.constructor,
|
|
index = -1,
|
|
isProto = typeof Ctor == 'function' && Ctor.prototype === object,
|
|
result = Array(length),
|
|
skipIndexes = length > 0;
|
|
|
|
while (++index < length) {
|
|
result[index] = (index + '');
|
|
}
|
|
for (var key in object) {
|
|
if (!(skipIndexes && isIndex(key, length)) &&
|
|
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = keysIn;
|
|
|
|
|
|
/***/ },
|
|
/* 57 */
|
|
/***/ function(module, exports) {
|
|
|
|
/** Used to detect unsigned integer values. */
|
|
var reIsUint = /^\d+$/;
|
|
|
|
/**
|
|
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
|
* of an array-like value.
|
|
*/
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like index.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
*/
|
|
function isIndex(value, length) {
|
|
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|
return value > -1 && value % 1 == 0 && value < length;
|
|
}
|
|
|
|
module.exports = isIndex;
|
|
|
|
|
|
/***/ },
|
|
/* 58 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isLength = __webpack_require__(44),
|
|
isObjectLike = __webpack_require__(45);
|
|
|
|
/** `Object#toString` result references. */
|
|
var argsTag = '[object Arguments]',
|
|
arrayTag = '[object Array]',
|
|
boolTag = '[object Boolean]',
|
|
dateTag = '[object Date]',
|
|
errorTag = '[object Error]',
|
|
funcTag = '[object Function]',
|
|
mapTag = '[object Map]',
|
|
numberTag = '[object Number]',
|
|
objectTag = '[object Object]',
|
|
regexpTag = '[object RegExp]',
|
|
setTag = '[object Set]',
|
|
stringTag = '[object String]',
|
|
weakMapTag = '[object WeakMap]';
|
|
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|
float32Tag = '[object Float32Array]',
|
|
float64Tag = '[object Float64Array]',
|
|
int8Tag = '[object Int8Array]',
|
|
int16Tag = '[object Int16Array]',
|
|
int32Tag = '[object Int32Array]',
|
|
uint8Tag = '[object Uint8Array]',
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
uint16Tag = '[object Uint16Array]',
|
|
uint32Tag = '[object Uint32Array]';
|
|
|
|
/** Used to identify `toStringTag` values of typed arrays. */
|
|
var typedArrayTags = {};
|
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
typedArrayTags[uint32Tag] = true;
|
|
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
|
|
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
|
|
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
|
|
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
|
|
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a typed array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isTypedArray(new Uint8Array);
|
|
* // => true
|
|
*
|
|
* _.isTypedArray([]);
|
|
* // => false
|
|
*/
|
|
function isTypedArray(value) {
|
|
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
|
|
}
|
|
|
|
module.exports = isTypedArray;
|
|
|
|
|
|
/***/ },
|
|
/* 59 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseCopy = __webpack_require__(60),
|
|
keysIn = __webpack_require__(56);
|
|
|
|
/**
|
|
* Converts `value` to a plain object flattening inherited enumerable
|
|
* properties of `value` to own properties of the plain object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {Object} Returns the converted plain object.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.assign({ 'a': 1 }, new Foo);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*
|
|
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
|
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
|
*/
|
|
function toPlainObject(value) {
|
|
return baseCopy(value, keysIn(value));
|
|
}
|
|
|
|
module.exports = toPlainObject;
|
|
|
|
|
|
/***/ },
|
|
/* 60 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* Copies properties of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy properties from.
|
|
* @param {Array} props The property names to copy.
|
|
* @param {Object} [object={}] The object to copy properties to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseCopy(source, props, object) {
|
|
object || (object = {});
|
|
|
|
var index = -1,
|
|
length = props.length;
|
|
|
|
while (++index < length) {
|
|
var key = props[index];
|
|
object[key] = source[key];
|
|
}
|
|
return object;
|
|
}
|
|
|
|
module.exports = baseCopy;
|
|
|
|
|
|
/***/ },
|
|
/* 61 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getNative = __webpack_require__(47),
|
|
isArrayLike = __webpack_require__(41),
|
|
isObject = __webpack_require__(50),
|
|
shimKeys = __webpack_require__(62);
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeKeys = getNative(Object, 'keys');
|
|
|
|
/**
|
|
* Creates an array of the own enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|
* [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
|
|
* for more details.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keys(new Foo);
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|
*
|
|
* _.keys('hi');
|
|
* // => ['0', '1']
|
|
*/
|
|
var keys = !nativeKeys ? shimKeys : function(object) {
|
|
var Ctor = object == null ? undefined : object.constructor;
|
|
if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
|
|
(typeof object != 'function' && isArrayLike(object))) {
|
|
return shimKeys(object);
|
|
}
|
|
return isObject(object) ? nativeKeys(object) : [];
|
|
};
|
|
|
|
module.exports = keys;
|
|
|
|
|
|
/***/ },
|
|
/* 62 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArguments = __webpack_require__(40),
|
|
isArray = __webpack_require__(46),
|
|
isIndex = __webpack_require__(57),
|
|
isLength = __webpack_require__(44),
|
|
keysIn = __webpack_require__(56);
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* A fallback implementation of `Object.keys` which creates an array of the
|
|
* own enumerable property names of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function shimKeys(object) {
|
|
var props = keysIn(object),
|
|
propsLength = props.length,
|
|
length = propsLength && object.length;
|
|
|
|
var allowIndexes = !!length && isLength(length) &&
|
|
(isArray(object) || isArguments(object));
|
|
|
|
var index = -1,
|
|
result = [];
|
|
|
|
while (++index < propsLength) {
|
|
var key = props[index];
|
|
if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = shimKeys;
|
|
|
|
|
|
/***/ },
|
|
/* 63 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var bindCallback = __webpack_require__(64),
|
|
isIterateeCall = __webpack_require__(66),
|
|
restParam = __webpack_require__(67);
|
|
|
|
/**
|
|
* Creates a `_.assign`, `_.defaults`, or `_.merge` function.
|
|
*
|
|
* @private
|
|
* @param {Function} assigner The function to assign values.
|
|
* @returns {Function} Returns the new assigner function.
|
|
*/
|
|
function createAssigner(assigner) {
|
|
return restParam(function(object, sources) {
|
|
var index = -1,
|
|
length = object == null ? 0 : sources.length,
|
|
customizer = length > 2 ? sources[length - 2] : undefined,
|
|
guard = length > 2 ? sources[2] : undefined,
|
|
thisArg = length > 1 ? sources[length - 1] : undefined;
|
|
|
|
if (typeof customizer == 'function') {
|
|
customizer = bindCallback(customizer, thisArg, 5);
|
|
length -= 2;
|
|
} else {
|
|
customizer = typeof thisArg == 'function' ? thisArg : undefined;
|
|
length -= (customizer ? 1 : 0);
|
|
}
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
customizer = length < 3 ? undefined : customizer;
|
|
length = 1;
|
|
}
|
|
while (++index < length) {
|
|
var source = sources[index];
|
|
if (source) {
|
|
assigner(object, source, customizer);
|
|
}
|
|
}
|
|
return object;
|
|
});
|
|
}
|
|
|
|
module.exports = createAssigner;
|
|
|
|
|
|
/***/ },
|
|
/* 64 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var identity = __webpack_require__(65);
|
|
|
|
/**
|
|
* A specialized version of `baseCallback` which only supports `this` binding
|
|
* and specifying the number of arguments to provide to `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to bind.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {number} [argCount] The number of arguments to provide to `func`.
|
|
* @returns {Function} Returns the callback.
|
|
*/
|
|
function bindCallback(func, thisArg, argCount) {
|
|
if (typeof func != 'function') {
|
|
return identity;
|
|
}
|
|
if (thisArg === undefined) {
|
|
return func;
|
|
}
|
|
switch (argCount) {
|
|
case 1: return function(value) {
|
|
return func.call(thisArg, value);
|
|
};
|
|
case 3: return function(value, index, collection) {
|
|
return func.call(thisArg, value, index, collection);
|
|
};
|
|
case 4: return function(accumulator, value, index, collection) {
|
|
return func.call(thisArg, accumulator, value, index, collection);
|
|
};
|
|
case 5: return function(value, other, key, object, source) {
|
|
return func.call(thisArg, value, other, key, object, source);
|
|
};
|
|
}
|
|
return function() {
|
|
return func.apply(thisArg, arguments);
|
|
};
|
|
}
|
|
|
|
module.exports = bindCallback;
|
|
|
|
|
|
/***/ },
|
|
/* 65 */
|
|
/***/ function(module, exports) {
|
|
|
|
/**
|
|
* This method returns the first argument provided to it.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Utility
|
|
* @param {*} value Any value.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
*
|
|
* _.identity(object) === object;
|
|
* // => true
|
|
*/
|
|
function identity(value) {
|
|
return value;
|
|
}
|
|
|
|
module.exports = identity;
|
|
|
|
|
|
/***/ },
|
|
/* 66 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArrayLike = __webpack_require__(41),
|
|
isIndex = __webpack_require__(57),
|
|
isObject = __webpack_require__(50);
|
|
|
|
/**
|
|
* Checks if the provided arguments are from an iteratee call.
|
|
*
|
|
* @private
|
|
* @param {*} value The potential iteratee value argument.
|
|
* @param {*} index The potential iteratee index or key argument.
|
|
* @param {*} object The potential iteratee object argument.
|
|
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
|
|
*/
|
|
function isIterateeCall(value, index, object) {
|
|
if (!isObject(object)) {
|
|
return false;
|
|
}
|
|
var type = typeof index;
|
|
if (type == 'number'
|
|
? (isArrayLike(object) && isIndex(index, object.length))
|
|
: (type == 'string' && index in object)) {
|
|
var other = object[index];
|
|
return value === value ? (value === other) : (other !== other);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
module.exports = isIterateeCall;
|
|
|
|
|
|
/***/ },
|
|
/* 67 */
|
|
/***/ function(module, exports) {
|
|
|
|
/** Used as the `TypeError` message for "Functions" methods. */
|
|
var FUNC_ERROR_TEXT = 'Expected a function';
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeMax = Math.max;
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* created function and arguments from `start` and beyond provided as an array.
|
|
*
|
|
* **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Function
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.restParam(function(what, names) {
|
|
* return what + ' ' + _.initial(names).join(', ') +
|
|
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
|
* });
|
|
*
|
|
* say('hello', 'fred', 'barney', 'pebbles');
|
|
* // => 'hello fred, barney, & pebbles'
|
|
*/
|
|
function restParam(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
|
|
return function() {
|
|
var args = arguments,
|
|
index = -1,
|
|
length = nativeMax(args.length - start, 0),
|
|
rest = Array(length);
|
|
|
|
while (++index < length) {
|
|
rest[index] = args[start + index];
|
|
}
|
|
switch (start) {
|
|
case 0: return func.call(this, rest);
|
|
case 1: return func.call(this, args[0], rest);
|
|
case 2: return func.call(this, args[0], args[1], rest);
|
|
}
|
|
var otherArgs = Array(start + 1);
|
|
index = -1;
|
|
while (++index < start) {
|
|
otherArgs[index] = args[index];
|
|
}
|
|
otherArgs[start] = rest;
|
|
return func.apply(this, otherArgs);
|
|
};
|
|
}
|
|
|
|
module.exports = restParam;
|
|
|
|
|
|
/***/ },
|
|
/* 68 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports["default"] = {
|
|
inputStream: {
|
|
name: "Live",
|
|
type: "LiveStream",
|
|
constraints: {
|
|
width: 640,
|
|
height: 480,
|
|
minAspectRatio: 0,
|
|
maxAspectRatio: 100,
|
|
facing: "environment" // or user
|
|
},
|
|
area: {
|
|
top: "0%",
|
|
right: "0%",
|
|
left: "0%",
|
|
bottom: "0%"
|
|
},
|
|
singleChannel: false // true: only the red color-channel is read
|
|
},
|
|
tracking: false,
|
|
debug: false,
|
|
controls: false,
|
|
locate: true,
|
|
numOfWorkers: 4,
|
|
visual: {
|
|
show: true
|
|
},
|
|
decoder: {
|
|
drawBoundingBox: false,
|
|
showFrequency: false,
|
|
drawScanline: false,
|
|
showPattern: false,
|
|
readers: ['code_128_reader']
|
|
},
|
|
locator: {
|
|
halfSample: true,
|
|
patchSize: "medium", // x-small, small, medium, large, x-large
|
|
showCanvas: false,
|
|
showPatches: false,
|
|
showFoundPatches: false,
|
|
showSkeleton: false,
|
|
showLabels: false,
|
|
showPatchLabels: false,
|
|
showRemainingPatchLabels: false,
|
|
boxFromPatches: {
|
|
showTransformed: false,
|
|
showTransformedBox: false,
|
|
showBB: false
|
|
}
|
|
}
|
|
};
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 69 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
exports["default"] = (function () {
|
|
var events = {};
|
|
|
|
function getEvent(eventName) {
|
|
if (!events[eventName]) {
|
|
events[eventName] = {
|
|
subscribers: []
|
|
};
|
|
}
|
|
return events[eventName];
|
|
}
|
|
|
|
function clearEvents() {
|
|
events = {};
|
|
}
|
|
|
|
function publishSubscription(subscription, data) {
|
|
if (subscription.async) {
|
|
setTimeout(function () {
|
|
subscription.callback(data);
|
|
}, 4);
|
|
} else {
|
|
subscription.callback(data);
|
|
}
|
|
}
|
|
|
|
function _subscribe(event, callback, async) {
|
|
var subscription;
|
|
|
|
if (typeof callback === "function") {
|
|
subscription = {
|
|
callback: callback,
|
|
async: async
|
|
};
|
|
} else {
|
|
subscription = callback;
|
|
if (!subscription.callback) {
|
|
throw "Callback was not specified on options";
|
|
}
|
|
}
|
|
|
|
getEvent(event).subscribers.push(subscription);
|
|
}
|
|
|
|
return {
|
|
subscribe: function subscribe(event, callback, async) {
|
|
return _subscribe(event, callback, async);
|
|
},
|
|
publish: function publish(eventName, data) {
|
|
var event = getEvent(eventName),
|
|
subscribers = event.subscribers;
|
|
|
|
event.subscribers = subscribers.filter(function (subscriber) {
|
|
publishSubscription(subscriber, data);
|
|
return !subscriber.once;
|
|
});
|
|
},
|
|
once: function once(event, callback, async) {
|
|
_subscribe(event, {
|
|
callback: callback,
|
|
async: async,
|
|
once: true
|
|
});
|
|
},
|
|
unsubscribe: function unsubscribe(eventName, callback) {
|
|
var event;
|
|
|
|
if (eventName) {
|
|
event = getEvent(eventName);
|
|
if (event && callback) {
|
|
event.subscribers = event.subscribers.filter(function (subscriber) {
|
|
return subscriber.callback !== callback;
|
|
});
|
|
} else {
|
|
event.subscribers = [];
|
|
}
|
|
} else {
|
|
clearEvents();
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 70 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
var merge = __webpack_require__(35);
|
|
|
|
var streamRef, loadedDataHandler;
|
|
|
|
/**
|
|
* Wraps browser-specific getUserMedia
|
|
* @param {Object} constraints
|
|
* @param {Object} success Callback
|
|
* @param {Object} failure Callback
|
|
*/
|
|
function getUserMedia(constraints, success, failure) {
|
|
if (typeof navigator.getUserMedia !== 'undefined') {
|
|
navigator.getUserMedia(constraints, function (stream) {
|
|
streamRef = stream;
|
|
var videoSrc = window.URL && window.URL.createObjectURL(stream) || stream;
|
|
success.apply(null, [videoSrc]);
|
|
}, failure);
|
|
} else {
|
|
failure(new TypeError("getUserMedia not available"));
|
|
}
|
|
}
|
|
|
|
function loadedData(video, callback) {
|
|
var attempts = 10;
|
|
|
|
function checkVideo() {
|
|
if (attempts > 0) {
|
|
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
|
console.log(video.videoWidth + "px x " + video.videoHeight + "px");
|
|
callback();
|
|
} else {
|
|
window.setTimeout(checkVideo, 500);
|
|
}
|
|
} else {
|
|
callback('Unable to play video stream. Is webcam working?');
|
|
}
|
|
attempts--;
|
|
}
|
|
checkVideo();
|
|
}
|
|
|
|
/**
|
|
* Tries to attach the camera-stream to a given video-element
|
|
* and calls the callback function when the content is ready
|
|
* @param {Object} constraints
|
|
* @param {Object} video
|
|
* @param {Object} callback
|
|
*/
|
|
function initCamera(constraints, video, callback) {
|
|
getUserMedia(constraints, function (src) {
|
|
video.src = src;
|
|
if (loadedDataHandler) {
|
|
video.removeEventListener("loadeddata", loadedDataHandler, false);
|
|
}
|
|
loadedDataHandler = loadedData.bind(null, video, callback);
|
|
video.addEventListener('loadeddata', loadedDataHandler, false);
|
|
video.play();
|
|
}, function (e) {
|
|
callback(e);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Normalizes the incoming constraints to satisfy the current browser
|
|
* @param config
|
|
* @param cb Callback which is called whenever constraints are created
|
|
* @returns {*}
|
|
*/
|
|
function normalizeConstraints(config, cb) {
|
|
var constraints = {
|
|
audio: false,
|
|
video: true
|
|
},
|
|
videoConstraints = merge({
|
|
width: 640,
|
|
height: 480,
|
|
minAspectRatio: 0,
|
|
maxAspectRatio: 100,
|
|
facing: "environment"
|
|
}, config);
|
|
|
|
if (typeof MediaStreamTrack !== 'undefined' && typeof MediaStreamTrack.getSources !== 'undefined') {
|
|
MediaStreamTrack.getSources(function (sourceInfos) {
|
|
var videoSourceId;
|
|
for (var i = 0; i < sourceInfos.length; ++i) {
|
|
var sourceInfo = sourceInfos[i];
|
|
if (sourceInfo.kind === "video" && sourceInfo.facing === videoConstraints.facing) {
|
|
videoSourceId = sourceInfo.id;
|
|
}
|
|
}
|
|
constraints.video = {
|
|
mandatory: {
|
|
minWidth: videoConstraints.width,
|
|
minHeight: videoConstraints.height,
|
|
minAspectRatio: videoConstraints.minAspectRatio,
|
|
maxAspectRatio: videoConstraints.maxAspectRatio
|
|
},
|
|
optional: [{
|
|
sourceId: videoSourceId
|
|
}]
|
|
};
|
|
return cb(constraints);
|
|
});
|
|
} else {
|
|
constraints.video = {
|
|
mediaSource: "camera",
|
|
width: { min: videoConstraints.width, max: videoConstraints.width },
|
|
height: { min: videoConstraints.height, max: videoConstraints.height },
|
|
require: ["width", "height"]
|
|
};
|
|
return cb(constraints);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Requests the back-facing camera of the user. The callback is called
|
|
* whenever the stream is ready to be consumed, or if an error occures.
|
|
* @param {Object} video
|
|
* @param {Object} callback
|
|
*/
|
|
function _request(video, videoConstraints, callback) {
|
|
normalizeConstraints(videoConstraints, function (constraints) {
|
|
initCamera(constraints, video, callback);
|
|
});
|
|
}
|
|
|
|
exports['default'] = {
|
|
request: function request(video, constraints, callback) {
|
|
_request(video, constraints, callback);
|
|
},
|
|
release: function release() {
|
|
var tracks = streamRef && streamRef.getVideoTracks();
|
|
if (tracks.length) {
|
|
tracks[0].stop();
|
|
}
|
|
streamRef = null;
|
|
}
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 71 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _image_debug = __webpack_require__(22);
|
|
|
|
var _image_debug2 = _interopRequireDefault(_image_debug);
|
|
|
|
function contains(codeResult, list) {
|
|
if (list) {
|
|
return list.some(function (item) {
|
|
return Object.keys(item).every(function (key) {
|
|
return item[key] === codeResult[key];
|
|
});
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function passesFilter(codeResult, filter) {
|
|
if (typeof filter === 'function') {
|
|
return filter(codeResult);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
exports['default'] = {
|
|
create: function create(config) {
|
|
var canvas = document.createElement("canvas"),
|
|
ctx = canvas.getContext("2d"),
|
|
results = [],
|
|
capacity = config.capacity || 20,
|
|
capture = config.capture === true;
|
|
|
|
function matchesConstraints(codeResult) {
|
|
return capacity && codeResult && !contains(codeResult, config.blacklist) && passesFilter(codeResult, config.filter);
|
|
}
|
|
|
|
return {
|
|
addResult: function addResult(data, imageSize, codeResult) {
|
|
var result = {};
|
|
|
|
if (matchesConstraints(codeResult)) {
|
|
capacity--;
|
|
result.codeResult = codeResult;
|
|
if (capture) {
|
|
canvas.width = imageSize.x;
|
|
canvas.height = imageSize.y;
|
|
_image_debug2['default'].drawImage(data, imageSize, ctx);
|
|
result.frame = canvas.toDataURL();
|
|
}
|
|
results.push(result);
|
|
}
|
|
},
|
|
getResults: function getResults() {
|
|
return results;
|
|
}
|
|
};
|
|
}
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 72 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _image_loader = __webpack_require__(73);
|
|
|
|
var _image_loader2 = _interopRequireDefault(_image_loader);
|
|
|
|
var InputStream = {};
|
|
InputStream.createVideoStream = function (video) {
|
|
var that = {},
|
|
_config = null,
|
|
_eventNames = ['canrecord', 'ended'],
|
|
_eventHandlers = {},
|
|
_calculatedWidth,
|
|
_calculatedHeight,
|
|
_topRight = { x: 0, y: 0 },
|
|
_canvasSize = { x: 0, y: 0 };
|
|
|
|
function initSize() {
|
|
var width = video.videoWidth,
|
|
height = video.videoHeight;
|
|
|
|
_calculatedWidth = _config.size ? width / height > 1 ? _config.size : Math.floor(width / height * _config.size) : width;
|
|
_calculatedHeight = _config.size ? width / height > 1 ? Math.floor(height / width * _config.size) : _config.size : height;
|
|
|
|
_canvasSize.x = _calculatedWidth;
|
|
_canvasSize.y = _calculatedHeight;
|
|
}
|
|
|
|
that.getRealWidth = function () {
|
|
return video.videoWidth;
|
|
};
|
|
|
|
that.getRealHeight = function () {
|
|
return video.videoHeight;
|
|
};
|
|
|
|
that.getWidth = function () {
|
|
return _calculatedWidth;
|
|
};
|
|
|
|
that.getHeight = function () {
|
|
return _calculatedHeight;
|
|
};
|
|
|
|
that.setWidth = function (width) {
|
|
_calculatedWidth = width;
|
|
};
|
|
|
|
that.setHeight = function (height) {
|
|
_calculatedHeight = height;
|
|
};
|
|
|
|
that.setInputStream = function (config) {
|
|
_config = config;
|
|
video.src = typeof config.src !== 'undefined' ? config.src : '';
|
|
};
|
|
|
|
that.ended = function () {
|
|
return video.ended;
|
|
};
|
|
|
|
that.getConfig = function () {
|
|
return _config;
|
|
};
|
|
|
|
that.setAttribute = function (name, value) {
|
|
video.setAttribute(name, value);
|
|
};
|
|
|
|
that.pause = function () {
|
|
video.pause();
|
|
};
|
|
|
|
that.play = function () {
|
|
video.play();
|
|
};
|
|
|
|
that.setCurrentTime = function (time) {
|
|
if (_config.type !== "LiveStream") {
|
|
video.currentTime = time;
|
|
}
|
|
};
|
|
|
|
that.addEventListener = function (event, f, bool) {
|
|
if (_eventNames.indexOf(event) !== -1) {
|
|
if (!_eventHandlers[event]) {
|
|
_eventHandlers[event] = [];
|
|
}
|
|
_eventHandlers[event].push(f);
|
|
} else {
|
|
video.addEventListener(event, f, bool);
|
|
}
|
|
};
|
|
|
|
that.clearEventHandlers = function () {
|
|
_eventNames.forEach(function (eventName) {
|
|
var handlers = _eventHandlers[eventName];
|
|
if (handlers && handlers.length > 0) {
|
|
handlers.forEach(function (handler) {
|
|
video.removeEventListener(eventName, handler);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
that.trigger = function (eventName, args) {
|
|
var j,
|
|
handlers = _eventHandlers[eventName];
|
|
|
|
if (eventName === 'canrecord') {
|
|
initSize();
|
|
}
|
|
if (handlers && handlers.length > 0) {
|
|
for (j = 0; j < handlers.length; j++) {
|
|
handlers[j].apply(that, args);
|
|
}
|
|
}
|
|
};
|
|
|
|
that.setTopRight = function (topRight) {
|
|
_topRight.x = topRight.x;
|
|
_topRight.y = topRight.y;
|
|
};
|
|
|
|
that.getTopRight = function () {
|
|
return _topRight;
|
|
};
|
|
|
|
that.setCanvasSize = function (size) {
|
|
_canvasSize.x = size.x;
|
|
_canvasSize.y = size.y;
|
|
};
|
|
|
|
that.getCanvasSize = function () {
|
|
return _canvasSize;
|
|
};
|
|
|
|
that.getFrame = function () {
|
|
return video;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
InputStream.createLiveStream = function (video) {
|
|
video.setAttribute("autoplay", true);
|
|
var that = InputStream.createVideoStream(video);
|
|
|
|
that.ended = function () {
|
|
return false;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
InputStream.createImageStream = function () {
|
|
var that = {};
|
|
var _config = null;
|
|
|
|
var width = 0,
|
|
height = 0,
|
|
frameIdx = 0,
|
|
paused = true,
|
|
loaded = false,
|
|
imgArray = null,
|
|
size = 0,
|
|
offset = 1,
|
|
baseUrl = null,
|
|
ended = false,
|
|
calculatedWidth,
|
|
calculatedHeight,
|
|
_eventNames = ['canrecord', 'ended'],
|
|
_eventHandlers = {},
|
|
_topRight = { x: 0, y: 0 },
|
|
_canvasSize = { x: 0, y: 0 };
|
|
|
|
function loadImages() {
|
|
loaded = false;
|
|
_image_loader2['default'].load(baseUrl, function (imgs) {
|
|
imgArray = imgs;
|
|
width = imgs[0].width;
|
|
height = imgs[0].height;
|
|
calculatedWidth = _config.size ? width / height > 1 ? _config.size : Math.floor(width / height * _config.size) : width;
|
|
calculatedHeight = _config.size ? width / height > 1 ? Math.floor(height / width * _config.size) : _config.size : height;
|
|
_canvasSize.x = calculatedWidth;
|
|
_canvasSize.y = calculatedHeight;
|
|
loaded = true;
|
|
frameIdx = 0;
|
|
setTimeout(function () {
|
|
publishEvent("canrecord", []);
|
|
}, 0);
|
|
}, offset, size, _config.sequence);
|
|
}
|
|
|
|
function publishEvent(eventName, args) {
|
|
var j,
|
|
handlers = _eventHandlers[eventName];
|
|
|
|
if (handlers && handlers.length > 0) {
|
|
for (j = 0; j < handlers.length; j++) {
|
|
handlers[j].apply(that, args);
|
|
}
|
|
}
|
|
}
|
|
|
|
that.trigger = publishEvent;
|
|
|
|
that.getWidth = function () {
|
|
return calculatedWidth;
|
|
};
|
|
|
|
that.getHeight = function () {
|
|
return calculatedHeight;
|
|
};
|
|
|
|
that.setWidth = function (newWidth) {
|
|
calculatedWidth = newWidth;
|
|
};
|
|
|
|
that.setHeight = function (newHeight) {
|
|
calculatedHeight = newHeight;
|
|
};
|
|
|
|
that.getRealWidth = function () {
|
|
return width;
|
|
};
|
|
|
|
that.getRealHeight = function () {
|
|
return height;
|
|
};
|
|
|
|
that.setInputStream = function (stream) {
|
|
_config = stream;
|
|
if (stream.sequence === false) {
|
|
baseUrl = stream.src;
|
|
size = 1;
|
|
} else {
|
|
baseUrl = stream.src;
|
|
size = stream.length;
|
|
}
|
|
loadImages();
|
|
};
|
|
|
|
that.ended = function () {
|
|
return ended;
|
|
};
|
|
|
|
that.setAttribute = function () {};
|
|
|
|
that.getConfig = function () {
|
|
return _config;
|
|
};
|
|
|
|
that.pause = function () {
|
|
paused = true;
|
|
};
|
|
|
|
that.play = function () {
|
|
paused = false;
|
|
};
|
|
|
|
that.setCurrentTime = function (time) {
|
|
frameIdx = time;
|
|
};
|
|
|
|
that.addEventListener = function (event, f) {
|
|
if (_eventNames.indexOf(event) !== -1) {
|
|
if (!_eventHandlers[event]) {
|
|
_eventHandlers[event] = [];
|
|
}
|
|
_eventHandlers[event].push(f);
|
|
}
|
|
};
|
|
|
|
that.setTopRight = function (topRight) {
|
|
_topRight.x = topRight.x;
|
|
_topRight.y = topRight.y;
|
|
};
|
|
|
|
that.getTopRight = function () {
|
|
return _topRight;
|
|
};
|
|
|
|
that.setCanvasSize = function (canvasSize) {
|
|
_canvasSize.x = canvasSize.x;
|
|
_canvasSize.y = canvasSize.y;
|
|
};
|
|
|
|
that.getCanvasSize = function () {
|
|
return _canvasSize;
|
|
};
|
|
|
|
that.getFrame = function () {
|
|
var frame;
|
|
|
|
if (!loaded) {
|
|
return null;
|
|
}
|
|
if (!paused) {
|
|
frame = imgArray[frameIdx];
|
|
if (frameIdx < size - 1) {
|
|
frameIdx++;
|
|
} else {
|
|
setTimeout(function () {
|
|
ended = true;
|
|
publishEvent("ended", []);
|
|
}, 0);
|
|
}
|
|
}
|
|
return frame;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
exports['default'] = InputStream;
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 73 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var ImageLoader = {};
|
|
ImageLoader.load = function (directory, callback, offset, size, sequence) {
|
|
var htmlImagesSrcArray = new Array(size),
|
|
htmlImagesArray = new Array(htmlImagesSrcArray.length),
|
|
i,
|
|
img,
|
|
num;
|
|
|
|
if (sequence === false) {
|
|
htmlImagesSrcArray[0] = directory;
|
|
} else {
|
|
for (i = 0; i < htmlImagesSrcArray.length; i++) {
|
|
num = offset + i;
|
|
htmlImagesSrcArray[i] = directory + "image-" + ("00" + num).slice(-3) + ".jpg";
|
|
}
|
|
}
|
|
htmlImagesArray.notLoaded = [];
|
|
htmlImagesArray.addImage = function (image) {
|
|
htmlImagesArray.notLoaded.push(image);
|
|
};
|
|
htmlImagesArray.loaded = function (loadedImg) {
|
|
var notloadedImgs = htmlImagesArray.notLoaded;
|
|
for (var x = 0; x < notloadedImgs.length; x++) {
|
|
if (notloadedImgs[x] === loadedImg) {
|
|
notloadedImgs.splice(x, 1);
|
|
for (var y = 0; y < htmlImagesSrcArray.length; y++) {
|
|
var imgName = htmlImagesSrcArray[y].substr(htmlImagesSrcArray[y].lastIndexOf("/"));
|
|
if (loadedImg.src.lastIndexOf(imgName) !== -1) {
|
|
htmlImagesArray[y] = loadedImg;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (notloadedImgs.length === 0) {
|
|
console.log("Images loaded");
|
|
callback.apply(null, [htmlImagesArray]);
|
|
}
|
|
};
|
|
|
|
for (i = 0; i < htmlImagesSrcArray.length; i++) {
|
|
img = new Image();
|
|
htmlImagesArray.addImage(img);
|
|
addOnloadHandler(img, htmlImagesArray);
|
|
img.src = htmlImagesSrcArray[i];
|
|
}
|
|
};
|
|
|
|
function addOnloadHandler(img, htmlImagesArray) {
|
|
img.onload = function () {
|
|
htmlImagesArray.loaded(this);
|
|
};
|
|
}
|
|
|
|
exports["default"] = ImageLoader;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 74 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
|
|
var _cv_utils = __webpack_require__(5);
|
|
|
|
var _cv_utils2 = _interopRequireDefault(_cv_utils);
|
|
|
|
var FrameGrabber = {};
|
|
|
|
FrameGrabber.create = function (inputStream, canvas) {
|
|
var _that = {},
|
|
_streamConfig = inputStream.getConfig(),
|
|
_video_size = _cv_utils2["default"].imageRef(inputStream.getRealWidth(), inputStream.getRealHeight()),
|
|
_canvasSize = inputStream.getCanvasSize(),
|
|
_size = _cv_utils2["default"].imageRef(inputStream.getWidth(), inputStream.getHeight()),
|
|
topRight = inputStream.getTopRight(),
|
|
_sx = topRight.x,
|
|
_sy = topRight.y,
|
|
_canvas,
|
|
_ctx = null,
|
|
_data = null;
|
|
|
|
_canvas = canvas ? canvas : document.createElement("canvas");
|
|
_canvas.width = _canvasSize.x;
|
|
_canvas.height = _canvasSize.y;
|
|
_ctx = _canvas.getContext("2d");
|
|
_data = new Uint8Array(_size.x * _size.y);
|
|
console.log("FrameGrabber", JSON.stringify({
|
|
size: _size,
|
|
topRight: topRight,
|
|
videoSize: _video_size,
|
|
canvasSize: _canvasSize
|
|
}));
|
|
|
|
/**
|
|
* Uses the given array as frame-buffer
|
|
*/
|
|
_that.attachData = function (data) {
|
|
_data = data;
|
|
};
|
|
|
|
/**
|
|
* Returns the used frame-buffer
|
|
*/
|
|
_that.getData = function () {
|
|
return _data;
|
|
};
|
|
|
|
/**
|
|
* Fetches a frame from the input-stream and puts into the frame-buffer.
|
|
* The image-data is converted to gray-scale and then half-sampled if configured.
|
|
*/
|
|
_that.grab = function () {
|
|
var doHalfSample = _streamConfig.halfSample,
|
|
frame = inputStream.getFrame(),
|
|
ctxData;
|
|
if (frame) {
|
|
_ctx.drawImage(frame, 0, 0, _canvasSize.x, _canvasSize.y);
|
|
ctxData = _ctx.getImageData(_sx, _sy, _size.x, _size.y).data;
|
|
if (doHalfSample) {
|
|
_cv_utils2["default"].grayAndHalfSampleFromCanvasData(ctxData, _size, _data);
|
|
} else {
|
|
_cv_utils2["default"].computeGray(ctxData, _data, _streamConfig);
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
_that.getSize = function () {
|
|
return _size;
|
|
};
|
|
|
|
return _that;
|
|
};
|
|
|
|
exports["default"] = FrameGrabber;
|
|
module.exports = exports["default"];
|
|
|
|
/***/ }
|
|
/******/ ])
|
|
});
|
|
;
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9teU1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vL3dlYnBhY2svYm9vdHN0cmFwIGIxODdhNzYyNTRhNzBiMDkxN2MzIiwid2VicGFjazovLy8uL3NyYy9xdWFnZ2EuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3R5cGVkZWZzLmpzIiwid2VicGFjazovLy8uL3NyYy9pbWFnZV93cmFwcGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9zdWJJbWFnZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY3ZfdXRpbHMuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NsdXN0ZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC1tYXRyaXgvc3JjL2dsLW1hdHJpeC5qcyIsIndlYnBhY2s6Ly8vLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L2NvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L21hdDIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC1tYXRyaXgvc3JjL2dsLW1hdHJpeC9tYXQyZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L21hdDMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC1tYXRyaXgvc3JjL2dsLW1hdHJpeC9tYXQ0LmpzIiwid2VicGFjazovLy8uL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXgvcXVhdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L3ZlYzMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC1tYXRyaXgvc3JjL2dsLW1hdHJpeC92ZWM0LmpzIiwid2VicGFjazovLy8uL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXgvdmVjMi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXJyYXlfaGVscGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9iYXJjb2RlX2xvY2F0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3Jhc3Rlcml6ZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3RyYWNlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc2tlbGV0b25pemVyLmpzIiwid2VicGFjazovLy8uL3NyYy9pbWFnZV9kZWJ1Zy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYmFyY29kZV9kZWNvZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9icmVzZW5oYW0uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvZGVfMTI4X3JlYWRlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYmFyY29kZV9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Vhbl9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvZGVfMzlfcmVhZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9jb2RlXzM5X3Zpbl9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvZGFiYXJfcmVhZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy91cGNfcmVhZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9lYW5fOF9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3VwY19lX3JlYWRlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvaTJvZjVfcmVhZGVyLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL29iamVjdC9tZXJnZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pbnRlcm5hbC9iYXNlTWVyZ2UuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlFYWNoLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2ludGVybmFsL2Jhc2VNZXJnZURlZXAuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlDb3B5LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2xhbmcvaXNBcmd1bWVudHMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvZ2V0TGVuZ3RoLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2ludGVybmFsL2Jhc2VQcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pbnRlcm5hbC9pc09iamVjdExpa2UuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvbGFuZy9pc0FycmF5LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9sYW5nL2lzTmF0aXZlLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2xhbmcvaXNGdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9sYW5nL2lzT2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2xhbmcvaXNQbGFpbk9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvYmFzZUZvci5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2ludGVybmFsL3RvT2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL29iamVjdC9rZXlzSW4uanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvaXNJbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9sYW5nL2lzVHlwZWRBcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9sYW5nL3RvUGxhaW5PYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvYmFzZUNvcHkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvb2JqZWN0L2tleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvY3JlYXRlQXNzaWduZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvYmluZENhbGxiYWNrLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL3V0aWxpdHkvaWRlbnRpdHkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvZnVuY3Rpb24vcmVzdFBhcmFtLmpzIiwid2VicGFjazovLy8uL3NyYy9jb25maWcuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2V2ZW50cy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2FtZXJhX2FjY2Vzcy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcmVzdWx0X2NvbGxlY3Rvci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5wdXRfc3RyZWFtLmpzIiwid2VicGFjazovLy8uL3NyYy9pbWFnZV9sb2FkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2ZyYW1lX2dyYWJiZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsTztBQ1JBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVCQUFlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7cUNDdENxQixDQUFZOzs7Ozs7MENBQ1IsQ0FBaUI7Ozs7NENBQ2YsRUFBbUI7Ozs7NENBQ25CLEVBQW1COzs7O29DQUMzQixFQUFVOzs7O21DQUNWLEVBQVU7Ozs7MENBQ0osRUFBaUI7Ozs7d0NBQ25CLEVBQWU7Ozs7cUNBQ25CLENBQVc7OzZDQUNGLEVBQW9COzs7O0FBRWhELEtBQU0sS0FBSyxHQUFHLG1CQUFPLENBQUMs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LE1BQU0sQ0FBQyxDQUFDLElBQUksTUFBTSxJQUNsQixNQUFNLENBQUMsQ0FBQyxJQUFJLE1BQU8sSUFDbkIsTUFBTSxDQUFDLENBQUMsR0FBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxNQUFRLElBQ2xDLE1BQU0sQ0FBQyxDQUFDLEdBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBUSxDQUFDO0VBQzlDLENBQUM7Ozs7Ozs7Ozs7QUFVRixhQUFZLENBQUMsTUFBTSxHQUFHLFVBQVMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDeEMsU0FBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixTQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFNBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLFNBQUksSUFBSSxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsU0FBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0IsU0FBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0IsU0FBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0IsU0FBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLFNBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxNQUFDLElBQUksRUFBRSxDQUFDO0FBQ1IsTUFBQyxJQUFJLEVBQUUsQ0FBQzs7QUFFUixTQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxD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Q0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQzlCLGNBQUssR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsYUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUU7QUFDdEMsZUFBRSxHQUFHLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQztBQUMzQixlQUFFLEdBQUcsS0FBSyxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDO0FBQzNCLGlCQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkMsaUJBQUksR0FBRyxLQUFLLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUN2QyxpQkFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3ZDLGdCQUFHLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUNqQyxnQkFBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzlELGtCQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDL0MsaUJBQUksS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUU7QUFDakIsc0JBQUssQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDO2NBQ3RCO0FBQ0Qsa0JBQUssQ0FB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Ozs7QUNuREE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7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QUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0I7QUFDQSxxQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWM7QUFDZDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE1BQU07QUFDakIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVSxLQUFLO0FBQ2YsV0FBVSxLQUFLO0FBQ2Y7QUFDQSxhQUFZLEtBQUs7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVUsS0FBSztBQUNmLFdBQVUsS0FBSztBQUNmO0FBQ0EsYUFBWSxLQUFLO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxnQjtBQUNBLHFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOzs7Ozs7O0FDcGpCQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0I7QUFDQSxxQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBYyxXQUFXLFdBQVc7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBYyxXQUFXLFlBQVk7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWUsWUFBWSxZQUFZO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWM7QUFDZDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMLG9CQUFtQixZQUFZLFlBQVk7QUFDM0Msb0JBQW1CLFlBQVksWUFBWTtBQUMzQyxvQkFBbUIsWUFBWSxhQUFhOztBQUU1QyxzQkFBcUIsY0FBYyxjQUFjO0FBQ2pELHNCQUFxQixjQUFjLGNBQWM7QUFDakQsc0JBQXFCLGNBQWMsZUFBZTs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0Q0FBMkMsYUFBYTs7QUFFeEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGdCQUFlLFlBQVksWUFBWTtBQUN2QyxnQkFBZSxZQUFZLFlBQVk7QUFDdkMsZ0JBQWUsWUFBWSxhQUFhOztBQUV4QztBQUNBLHlCQUF3Qix5QkFBeUI7QUFDakQsNkJBQTRCLHFCQUFxQjtBQUNqRCw2QkFBNEIseUJBQXlCOztBQUVyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRDQUEyQyxhQUFhOztBQUV4RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxPQUFPO0FBQ2xCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsT0FBTztBQUNsQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxNQUFNO0FBQ2pCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE1BQU07QUFDakIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxNQUFNO0FBQ2pCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7Ozs7Ozs7QUNsd0NBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xC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QUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxPQUFPO0FBQ2xCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsT0FBTztBQUNsQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxPQUFPO0FBQ2xCLGNBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsS0FBSztBQUNoQixZQUFXLE9BQU87QUFDbEIsY0FBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFlBQVcsS0FBSztBQUNoQixZQUFXLEtBQUs7QUFDaEIsWUFBVyxLQUFLO0FBQ2hCLFlBQVcsT0FBTztBQUNsQixjQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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LFdBQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUM7QUFDcEIsV0FBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztBQUNwQixpQkFBWSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztBQUMxQixpQkFBWSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztBQUMxQixpQkFBWSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztBQUMxQixjQUFTLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDO0FBQ3ZCLFdBQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUM7QUFDbkIsaUJBQVksRUFBRSxFQUFDLEtBQUssRUFBRSxDQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNsQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQ3hCLEVBQUM7QUFDRixzQkFBaUIsRUFBRSxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUM7QUFDN0IsbUJBQWMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUM7QUFDNUIsV0FBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFDO0VBQ2hELENBQUM7O0FBRUYsY0FB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LG1CQUFjLEVBQUUsRUFBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFDO0FBQ2hGLGlCQUFZLEVBQUUsRUFBQyxLQUFLLEVBQUUsQ0FDbEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUs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R0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsV0FBUSxDQUFDO01BQ3RELENBQUMsQ0FBQztBQUNILFlBQU8sTUFBTSxDQUFDO0VBQ2pCOztBQUVELEtBQUksQ0FBQyxHQUFHLENBQUM7S0FDTCxDQUFDLEdBQUcsQ0FBQztLQUNMLFVBQVUsR0FBRztBQUNULFdBQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUM7QUFDbkIsa0JBQWEsRUFBRSxFQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBQztBQUM1RCxpQkFBWSxFQUFFLEVBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQztBQUM1QyxpQkFBWSxFQUFFLEVBQUMsS0FBSyxFQUFFLENBQ2xCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLENBQUMs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QUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUM3RCxpQkFBSSxZQUFZLEVBQUM7QUFDYix1Q0FBUSwrQkFBK0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2NBQ2xFLE1BQU07QUFDSCx1Q0FBUSxXQUFXLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztjQUN0RDtBQUNELG9CQUFPLElBQUksQ0FBQztVQUNmLE1BQU07QUFDSCxvQkFBTyxLQUFLLENBQUM7VUFDaEI7TUFDSixDQUFDOztBQUVGLFVBQUssQ0FBQyxPQUFPLEdBQUcsWUFBVztBQUN2QixnQkFBTyxLQUFLLENBQUM7TUFDaEIsQ0FBQzs7QUFFRixZQUFPLEtBQUssQ0FBQztFQUNoQixDQUFDOztzQkFFYSxZQUFZIiwiZmlsZSI6InF1YWdnYS5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoZmFjdG9yeS50b1N0cmluZygpKTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIlF1YWdnYVwiXSA9IGZhY3RvcnkoZmFjdG9yeS50b1N0cmluZygpKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJRdWFnZ2FcIl0gPSBmYWN0b3J5KGZhY3RvcnkudG9TdHJpbmcoKSk7XG59KSh0aGlzLCBmdW5jdGlvbihfX2ZhY3RvcnlTb3VyY2VfXykge1xucmV0dXJuIFxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIHdlYnBhY2svbXlNb2R1bGVEZWZpbml0aW9uXG4gKiovIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGV4cG9ydHM6IHt9LFxuIFx0XHRcdGlkOiBtb2R1bGVJZCxcbiBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiL1wiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogd2VicGFjay9ib290c3RyYXAgYjE4N2E3NjI1NGE3MGIwOTE3YzNcbiAqKi8iLCJpbXBvcnQgVHlwZURlZnMgZnJvbSAnLi90eXBlZGVmcyc7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbmltcG9ydCBJbWFnZVdyYXBwZXIgZnJvbSAnLi9pbWFnZV93cmFwcGVyJztcbmltcG9ydCBCYXJjb2RlTG9jYXRvciBmcm9tICcuL2JhcmNvZGVfbG9jYXRvcic7XG5pbXBvcnQgQmFyY29kZURlY29kZXIgZnJvbSAnLi9iYXJjb2RlX2RlY29kZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgRXZlbnRzIGZyb20gJy4vZXZlbnRzJztcbmltcG9ydCBDYW1lcmFBY2Nlc3MgZnJvbSAnLi9jYW1lcmFfYWNjZXNzJztcbmltcG9ydCBJbWFnZURlYnVnIGZyb20gJy4vaW1hZ2VfZGVidWcnO1xuaW1wb3J0IHt2ZWMyfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IFJlc3VsdENvbGxlY3RvciBmcm9tICcuL3Jlc3VsdF9jb2xsZWN0b3InO1xuXG5jb25zdCBtZXJnZSA9IHJlcXVpcmUoJ2xvZGFzaC9vYmplY3QvbWVyZ2UnKTtcbmNvbnN0IElucHV0U3RyZWFtID0gcmVxdWlyZSgnaW5wdXRfc3RyZWFtJyk7XG5jb25zdCBGcmFtZUdyYWJiZXIgPSByZXF1aXJlKCdmcmFtZV9ncmFiYmVyJyk7XG5cbnZhciBfaW5wdXRTdHJlYW0sXG4gICAgX2ZyYW1lZ3JhYmJlcixcbiAgICBfc3RvcHBlZCxcbiAgICBfY2FudmFzQ29udGFpbmVyID0ge1xuICAgICAgICBjdHg6IHtcbiAgICAgICAgICAgIGltYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheTogbnVsbFxuICAgICAgICB9LFxuICAgICAgICBkb206IHtcbiAgICAgICAgICAgIGltYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheTogbnVsbFxuICAgICAgICB9XG4gICAgfSxcbiAgICBfaW5wdXRJbWFnZVdyYXBwZXIsXG4gICAgX2JveFNpemUsXG4gICAgX2RlY29kZXIsXG4gICAgX3dvcmtlclBvb2wgPSBbXSxcbiAgICBfb25VSVRocmVhZCA9IHRydWUsXG4gICAgX3Jlc3VsdENvbGxlY3RvcixcbiAgICBfY29uZmlnID0ge307XG5cbmZ1bmN0aW9uIGluaXRpYWxpemVEYXRhKGltYWdlV3JhcHBlcikge1xuICAgIGluaXRCdWZmZXJzKGltYWdlV3JhcHBlcik7XG4gICAgX2RlY29kZXIgPSBCYXJjb2RlRGVjb2Rlci5jcmVhdGUoX2NvbmZpZy5kZWNvZGVyLCBfaW5wdXRJbWFnZVdyYXBwZXIpO1xufVxuXG5mdW5jdGlvbiBpbml0Q29uZmlnKCkge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgdmFyIHZpcyA9IFt7XG4gICAgICAgICAgICBub2RlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiZGl2W2RhdGEtY29udHJvbHNdXCIpLFxuICAgICAgICAgICAgcHJvcDogX2NvbmZpZy5jb250cm9sc1xuICAgICAgICB9LCB7XG4gICAgICAgICAgICBub2RlOiBfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5LFxuICAgICAgICAgICAgcHJvcDogX2NvbmZpZy52aXN1YWwuc2hvd1xuICAgICAgICB9XTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHZpc1tpXS5ub2RlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZpc1tpXS5wcm9wID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZpc1tpXS5ub2RlLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmlzW2ldLm5vZGUuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaW5pdElucHV0U3RyZWFtKGNiKSB7XG4gICAgdmFyIHZpZGVvO1xuICAgIGlmIChfY29uZmlnLmlucHV0U3RyZWFtLnR5cGUgPT09IFwiVmlkZW9TdHJlYW1cIikge1xuICAgICAgICB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ2aWRlb1wiKTtcbiAgICAgICAgX2lucHV0U3RyZWFtID0gSW5wdXRTdHJlYW0uY3JlYXRlVmlkZW9TdHJlYW0odmlkZW8pO1xuICAgIH0gZWxzZSBpZiAoX2NvbmZpZy5pbnB1dFN0cmVhbS50eXBlID09PSBcIkltYWdlU3RyZWFtXCIpIHtcbiAgICAgICAgX2lucHV0U3RyZWFtID0gSW5wdXRTdHJlYW0uY3JlYXRlSW1hZ2VTdHJlYW0oKTtcbiAgICB9IGVsc2UgaWYgKF9jb25maWcuaW5wdXRTdHJlYW0udHlwZSA9PT0gXCJMaXZlU3RyZWFtXCIpIHtcbiAgICAgICAgdmFyICR2aWV3cG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjaW50ZXJhY3RpdmUudmlld3BvcnRcIik7XG4gICAgICAgIGlmICgkdmlld3BvcnQpIHtcbiAgICAgICAgICAgIHZpZGVvID0gJHZpZXdwb3J0LnF1ZXJ5U2VsZWN0b3IoXCJ2aWRlb1wiKTtcbiAgICAgICAgICAgIGlmICghdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ2aWRlb1wiKTtcbiAgICAgICAgICAgICAgICAkdmlld3BvcnQuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIF9pbnB1dFN0cmVhbSA9IElucHV0U3RyZWFtLmNyZWF0ZUxpdmVTdHJlYW0odmlkZW8pO1xuICAgICAgICBDYW1lcmFBY2Nlc3MucmVxdWVzdCh2aWRlbywgX2NvbmZpZy5pbnB1dFN0cmVhbS5jb25zdHJhaW50cywgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICBpZiAoIWVycikge1xuICAgICAgICAgICAgICAgIF9pbnB1dFN0cmVhbS50cmlnZ2VyKFwiY2FucmVjb3JkXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2lucHV0U3RyZWFtLnNldEF0dHJpYnV0ZShcInByZWxvYWRcIiwgXCJhdXRvXCIpO1xuICAgIF9pbnB1dFN0cmVhbS5zZXRBdHRyaWJ1dGUoXCJhdXRvcGxheVwiLCB0cnVlKTtcbiAgICBfaW5wdXRTdHJlYW0uc2V0SW5wdXRTdHJlYW0oX2NvbmZpZy5pbnB1dFN0cmVhbSk7XG4gICAgX2lucHV0U3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXCJjYW5yZWNvcmRcIiwgY2FuUmVjb3JkLmJpbmQodW5kZWZpbmVkLCBjYikpO1xufVxuXG5mdW5jdGlvbiBjYW5SZWNvcmQoY2IpIHtcbiAgICBCYXJjb2RlTG9jYXRvci5jaGVja0ltYWdlQ29uc3RyYWludHMoX2lucHV0U3RyZWFtLCBfY29uZmlnLmxvY2F0b3IpO1xuICAgIGluaXRDYW52YXMoKTtcbiAgICBfZnJhbWVncmFiYmVyID0gRnJhbWVHcmFiYmVyLmNyZWF0ZShfaW5wdXRTdHJlYW0sIF9jYW52YXNDb250YWluZXIuZG9tLmltYWdlKTtcbiAgICBpbml0Q29uZmlnKCk7XG5cbiAgICBpZiAoX2NvbmZpZy5udW1PZldvcmtlcnMgPiAwKSB7XG4gICAgICAgIGluaXRXb3JrZXJzKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJXb3JrZXJzIGNyZWF0ZWRcIik7XG4gICAgICAgICAgICByZWFkeShjYik7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGluaXRpYWxpemVEYXRhKCk7XG4gICAgICAgIHJlYWR5KGNiKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlYWR5KGNiKXtcbiAgICBfaW5wdXRTdHJlYW0ucGxheSgpO1xuICAgIGNiKCk7XG59XG5cbmZ1bmN0aW9uIGluaXRDYW52YXMoKSB7XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB2YXIgJHZpZXdwb3J0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNpbnRlcmFjdGl2ZS52aWV3cG9ydFwiKTtcbiAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiY2FudmFzLmltZ0J1ZmZlclwiKTtcbiAgICAgICAgaWYgKCFfY2FudmFzQ29udGFpbmVyLmRvbS5pbWFnZSkge1xuICAgICAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UuY2xhc3NOYW1lID0gXCJpbWdCdWZmZXJcIjtcbiAgICAgICAgICAgIGlmICgkdmlld3BvcnQgJiYgX2NvbmZpZy5pbnB1dFN0cmVhbS50eXBlID09PSBcIkltYWdlU3RyZWFtXCIpIHtcbiAgICAgICAgICAgICAgICAkdmlld3BvcnQuYXBwZW5kQ2hpbGQoX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIF9jYW52YXNDb250YWluZXIuY3R4LmltYWdlID0gX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5pbWFnZS53aWR0aCA9IF9pbnB1dFN0cmVhbS5nZXRDYW52YXNTaXplKCkueDtcbiAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UuaGVpZ2h0ID0gX2lucHV0U3RyZWFtLmdldENhbnZhc1NpemUoKS55O1xuXG4gICAgICAgIF9jYW52YXNDb250YWluZXIuZG9tLm92ZXJsYXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiY2FudmFzLmRyYXdpbmdCdWZmZXJcIik7XG4gICAgICAgIGlmICghX2NhbnZhc0NvbnRhaW5lci5kb20ub3ZlcmxheSkge1xuICAgICAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20ub3ZlcmxheSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5LmNsYXNzTmFtZSA9IFwiZHJhd2luZ0J1ZmZlclwiO1xuICAgICAgICAgICAgaWYgKCR2aWV3cG9ydCkge1xuICAgICAgICAgICAgICAgICR2aWV3cG9ydC5hcHBlbmRDaGlsZChfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBjbGVhckZpeCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJiclwiKTtcbiAgICAgICAgICAgIGNsZWFyRml4LnNldEF0dHJpYnV0ZShcImNsZWFyXCIsIFwiYWxsXCIpO1xuICAgICAgICAgICAgaWYgKCR2aWV3cG9ydCkge1xuICAgICAgICAgICAgICAgICR2aWV3cG9ydC5hcHBlbmRDaGlsZChjbGVhckZpeCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5jdHgub3ZlcmxheSA9IF9jYW52YXNDb250YWluZXIuZG9tLm92ZXJsYXkuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5LndpZHRoID0gX2lucHV0U3RyZWFtLmdldENhbnZhc1NpemUoKS54O1xuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5LmhlaWdodCA9IF9pbnB1dFN0cmVhbS5nZXRDYW52YXNTaXplKCkueTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGluaXRCdWZmZXJzKGltYWdlV3JhcHBlcikge1xuICAgIGlmIChpbWFnZVdyYXBwZXIpIHtcbiAgICAgICAgX2lucHV0SW1hZ2VXcmFwcGVyID0gaW1hZ2VXcmFwcGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIF9pbnB1dEltYWdlV3JhcHBlciA9IG5ldyBJbWFnZVdyYXBwZXIoe1xuICAgICAgICAgICAgeDogX2lucHV0U3RyZWFtLmdldFdpZHRoKCksXG4gICAgICAgICAgICB5OiBfaW5wdXRTdHJlYW0uZ2V0SGVpZ2h0KClcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUpO1xuICAgIF9ib3hTaXplID0gW1xuICAgICAgICB2ZWMyLmNsb25lKFswLCAwXSksXG4gICAgICAgIHZlYzIuY2xvbmUoWzAsIF9pbnB1dEltYWdlV3JhcHBlci5zaXplLnldKSxcbiAgICAgICAgdmVjMi5jbG9uZShbX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUueCwgX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUueV0pLFxuICAgICAgICB2ZWMyLmNsb25lKFtfaW5wdXRJbWFnZVdyYXBwZXIuc2l6ZS54LCAwXSlcbiAgICBdO1xuICAgIEJhcmNvZGVMb2NhdG9yLmluaXQoX2lucHV0SW1hZ2VXcmFwcGVyLCBfY29uZmlnLmxvY2F0b3IpO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZGluZ0JveGVzKCkge1xuICAgIGlmIChfY29uZmlnLmxvY2F0ZSkge1xuICAgICAgICByZXR1cm4gQmFyY29kZUxvY2F0b3IubG9jYXRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtbXG4gICAgICAgICAgICB2ZWMyLmNsb25lKF9ib3hTaXplWzBdKSxcbiAgICAgICAgICAgIHZlYzIuY2xvbmUoX2JveFNpemVbMV0pLFxuICAgICAgICAgICAgdmVjMi5jbG9uZShfYm94U2l6ZVsyXSksXG4gICAgICAgICAgICB2ZWMyLmNsb25lKF9ib3hTaXplWzNdKV1dO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdHJhbnNmb3JtUmVzdWx0KHJlc3VsdCkge1xuICAgIHZhciB0b3BSaWdodCA9IF9pbnB1dFN0cmVhbS5nZXRUb3BSaWdodCgpLFxuICAgICAgICB4T2Zmc2V0ID0gdG9wUmlnaHQueCxcbiAgICAgICAgeU9mZnNldCA9IHRvcFJpZ2h0LnksXG4gICAgICAgIGk7XG5cbiAgICBpZiAoIXJlc3VsdCB8fCAoeE9mZnNldCA9PT0gMCAmJiB5T2Zmc2V0ID09PSAwKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICBpZiAocmVzdWx0LmxpbmUgJiYgcmVzdWx0LmxpbmUubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIG1vdmVMaW5lKHJlc3VsdC5saW5lKTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC5ib3hlcyAmJiByZXN1bHQuYm94ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdWx0LmJveGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBtb3ZlQm94KHJlc3VsdC5ib3hlc1tpXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3ZlQm94KGJveCkge1xuICAgICAgICB2YXIgY29ybmVyID0gYm94Lmxlbmd0aDtcblxuICAgICAgICB3aGlsZSAoY29ybmVyLS0pIHtcbiAgICAgICAgICAgIGJveFtjb3JuZXJdWzBdICs9IHhPZmZzZXQ7XG4gICAgICAgICAgICBib3hbY29ybmVyXVsxXSArPSB5T2Zmc2V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW92ZUxpbmUobGluZSkge1xuICAgICAgICBsaW5lWzBdLnggKz0geE9mZnNldDtcbiAgICAgICAgbGluZVswXS55ICs9IHlPZmZzZXQ7XG4gICAgICAgIGxpbmVbMV0ueCArPSB4T2Zmc2V0O1xuICAgICAgICBsaW5lWzFdLnkgKz0geU9mZnNldDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2hSZXN1bHQocmVzdWx0LCBpbWFnZURhdGEpIHtcbiAgICBpZiAoX29uVUlUaHJlYWQpIHtcbiAgICAgICAgdHJhbnNmb3JtUmVzdWx0KHJlc3VsdCk7XG4gICAgICAgIGlmIChpbWFnZURhdGEgJiYgcmVzdWx0ICYmIHJlc3VsdC5jb2RlUmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoX3Jlc3VsdENvbGxlY3Rvcikge1xuICAgICAgICAgICAgICAgIF9yZXN1bHRDb2xsZWN0b3IuYWRkUmVzdWx0KGltYWdlRGF0YSwgX2lucHV0U3RyZWFtLmdldENhbnZhc1NpemUoKSwgcmVzdWx0LmNvZGVSZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgRXZlbnRzLnB1Ymxpc2goXCJwcm9jZXNzZWRcIiwgcmVzdWx0KTtcbiAgICBpZiAocmVzdWx0ICYmIHJlc3VsdC5jb2RlUmVzdWx0KSB7XG4gICAgICAgIEV2ZW50cy5wdWJsaXNoKFwiZGV0ZWN0ZWRcIiwgcmVzdWx0KTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvY2F0ZUFuZERlY29kZSgpIHtcbiAgICB2YXIgcmVzdWx0LFxuICAgICAgICBib3hlcztcblxuICAgIGJveGVzID0gZ2V0Qm91bmRpbmdCb3hlcygpO1xuICAgIGlmIChib3hlcykge1xuICAgICAgICByZXN1bHQgPSBfZGVjb2Rlci5kZWNvZGVGcm9tQm91bmRpbmdCb3hlcyhib3hlcyk7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgICAgcmVzdWx0LmJveGVzID0gYm94ZXM7XG4gICAgICAgIHB1Ymxpc2hSZXN1bHQocmVzdWx0LCBfaW5wdXRJbWFnZVdyYXBwZXIuZGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcHVibGlzaFJlc3VsdCgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgIHZhciBhdmFpbGFibGVXb3JrZXI7XG5cbiAgICBpZiAoX29uVUlUaHJlYWQpIHtcbiAgICAgICAgaWYgKF93b3JrZXJQb29sLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGF2YWlsYWJsZVdvcmtlciA9IF93b3JrZXJQb29sLmZpbHRlcihmdW5jdGlvbih3b3JrZXJUaHJlYWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXdvcmtlclRocmVhZC5idXN5O1xuICAgICAgICAgICAgfSlbMF07XG4gICAgICAgICAgICBpZiAoYXZhaWxhYmxlV29ya2VyKSB7XG4gICAgICAgICAgICAgICAgX2ZyYW1lZ3JhYmJlci5hdHRhY2hEYXRhKGF2YWlsYWJsZVdvcmtlci5pbWFnZURhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIGFsbCB3b3JrZXJzIGFyZSBidXN5XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBfZnJhbWVncmFiYmVyLmF0dGFjaERhdGEoX2lucHV0SW1hZ2VXcmFwcGVyLmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChfZnJhbWVncmFiYmVyLmdyYWIoKSkge1xuICAgICAgICAgICAgaWYgKGF2YWlsYWJsZVdvcmtlcikge1xuICAgICAgICAgICAgICAgIGF2YWlsYWJsZVdvcmtlci5idXN5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBhdmFpbGFibGVXb3JrZXIud29ya2VyLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgICAgICAgICAgY21kOiAncHJvY2VzcycsXG4gICAgICAgICAgICAgICAgICAgIGltYWdlRGF0YTogYXZhaWxhYmxlV29ya2VyLmltYWdlRGF0YVxuICAgICAgICAgICAgICAgIH0sIFthdmFpbGFibGVXb3JrZXIuaW1hZ2VEYXRhLmJ1ZmZlcl0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2NhdGVBbmREZWNvZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGxvY2F0ZUFuZERlY29kZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgX3N0b3BwZWQgPSBmYWxzZTtcbiAgICAoIGZ1bmN0aW9uIGZyYW1lKCkge1xuICAgICAgICBpZiAoIV9zdG9wcGVkKSB7XG4gICAgICAgICAgICB1cGRhdGUoKTtcbiAgICAgICAgICAgIGlmIChfb25VSVRocmVhZCAmJiBfY29uZmlnLmlucHV0U3RyZWFtLnR5cGUgPT09IFwiTGl2ZVN0cmVhbVwiKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltRnJhbWUoZnJhbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSgpKTtcbn1cblxuZnVuY3Rpb24gaW5pdFdvcmtlcnMoY2IpIHtcbiAgICB2YXIgaTtcbiAgICBfd29ya2VyUG9vbCA9IFtdO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IF9jb25maWcubnVtT2ZXb3JrZXJzOyBpKyspIHtcbiAgICAgICAgaW5pdFdvcmtlcih3b3JrZXJJbml0aWFsaXplZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd29ya2VySW5pdGlhbGl6ZWQod29ya2VyVGhyZWFkKSB7XG4gICAgICAgIF93b3JrZXJQb29sLnB1c2god29ya2VyVGhyZWFkKTtcbiAgICAgICAgaWYgKF93b3JrZXJQb29sLmxlbmd0aCA+PSBfY29uZmlnLm51bU9mV29ya2Vycyl7XG4gICAgICAgICAgICBjYigpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpbml0V29ya2VyKGNiKSB7XG4gICAgdmFyIGJsb2JVUkwsXG4gICAgICAgIHdvcmtlclRocmVhZCA9IHtcbiAgICAgICAgICAgIHdvcmtlcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaW1hZ2VEYXRhOiBuZXcgVWludDhBcnJheShfaW5wdXRTdHJlYW0uZ2V0V2lkdGgoKSAqIF9pbnB1dFN0cmVhbS5nZXRIZWlnaHQoKSksXG4gICAgICAgICAgICBidXN5OiB0cnVlXG4gICAgICAgIH07XG5cbiAgICBibG9iVVJMID0gZ2VuZXJhdGVXb3JrZXJCbG9iKCk7XG4gICAgd29ya2VyVGhyZWFkLndvcmtlciA9IG5ldyBXb3JrZXIoYmxvYlVSTCk7XG5cbiAgICB3b3JrZXJUaHJlYWQud29ya2VyLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgaWYgKGUuZGF0YS5ldmVudCA9PT0gJ2luaXRpYWxpemVkJykge1xuICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChibG9iVVJMKTtcbiAgICAgICAgICAgIHdvcmtlclRocmVhZC5idXN5ID0gZmFsc2U7XG4gICAgICAgICAgICB3b3JrZXJUaHJlYWQuaW1hZ2VEYXRhID0gbmV3IFVpbnQ4QXJyYXkoZS5kYXRhLmltYWdlRGF0YSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIldvcmtlciBpbml0aWFsaXplZFwiKTtcbiAgICAgICAgICAgIHJldHVybiBjYih3b3JrZXJUaHJlYWQpO1xuICAgICAgICB9IGVsc2UgaWYgKGUuZGF0YS5ldmVudCA9PT0gJ3Byb2Nlc3NlZCcpIHtcbiAgICAgICAgICAgIHdvcmtlclRocmVhZC5pbWFnZURhdGEgPSBuZXcgVWludDhBcnJheShlLmRhdGEuaW1hZ2VEYXRhKTtcbiAgICAgICAgICAgIHdvcmtlclRocmVhZC5idXN5ID0gZmFsc2U7XG4gICAgICAgICAgICBwdWJsaXNoUmVzdWx0KGUuZGF0YS5yZXN1bHQsIHdvcmtlclRocmVhZC5pbWFnZURhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGUuZGF0YS5ldmVudCA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJXb3JrZXIgZXJyb3I6IFwiICsgZS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdvcmtlclRocmVhZC53b3JrZXIucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBjbWQ6ICdpbml0JyxcbiAgICAgICAgc2l6ZToge3g6IF9pbnB1dFN0cmVhbS5nZXRXaWR0aCgpLCB5OiBfaW5wdXRTdHJlYW0uZ2V0SGVpZ2h0KCl9LFxuICAgICAgICBpbWFnZURhdGE6IHdvcmtlclRocmVhZC5pbWFnZURhdGEsXG4gICAgICAgIGNvbmZpZzogX2NvbmZpZ1xuICAgIH0sIFt3b3JrZXJUaHJlYWQuaW1hZ2VEYXRhLmJ1ZmZlcl0pO1xufVxuXG5cbmZ1bmN0aW9uIHdvcmtlckludGVyZmFjZShmYWN0b3J5KSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYqL1xuICAgIGlmIChmYWN0b3J5KSB7XG4gICAgICAgIHZhciBRdWFnZ2EgPSBmYWN0b3J5KCk7XG4gICAgICAgIGlmICghUXVhZ2dhKSB7XG4gICAgICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKHsnZXZlbnQnOiAnZXJyb3InLCBtZXNzYWdlOiAnUXVhZ2dhIGNvdWxkIG5vdCBiZSBjcmVhdGVkJ30pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciBpbWFnZVdyYXBwZXI7XG5cbiAgICBzZWxmLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgaWYgKGUuZGF0YS5jbWQgPT09ICdpbml0Jykge1xuICAgICAgICAgICAgdmFyIGNvbmZpZyA9IGUuZGF0YS5jb25maWc7XG4gICAgICAgICAgICBjb25maWcubnVtT2ZXb3JrZXJzID0gMDtcbiAgICAgICAgICAgIGltYWdlV3JhcHBlciA9IG5ldyBRdWFnZ2EuSW1hZ2VXcmFwcGVyKHtcbiAgICAgICAgICAgICAgICB4OiBlLmRhdGEuc2l6ZS54LFxuICAgICAgICAgICAgICAgIHk6IGUuZGF0YS5zaXplLnlcbiAgICAgICAgICAgIH0sIG5ldyBVaW50OEFycmF5KGUuZGF0YS5pbWFnZURhdGEpKTtcbiAgICAgICAgICAgIFF1YWdnYS5pbml0KGNvbmZpZywgcmVhZHksIGltYWdlV3JhcHBlcik7XG4gICAgICAgICAgICBRdWFnZ2Eub25Qcm9jZXNzZWQob25Qcm9jZXNzZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKGUuZGF0YS5jbWQgPT09ICdwcm9jZXNzJykge1xuICAgICAgICAgICAgaW1hZ2VXcmFwcGVyLmRhdGEgPSBuZXcgVWludDhBcnJheShlLmRhdGEuaW1hZ2VEYXRhKTtcbiAgICAgICAgICAgIFF1YWdnYS5zdGFydCgpO1xuICAgICAgICB9IGVsc2UgaWYgKGUuZGF0YS5jbWQgPT09ICdzZXRSZWFkZXJzJykge1xuICAgICAgICAgICAgUXVhZ2dhLnNldFJlYWRlcnMoZS5kYXRhLnJlYWRlcnMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIG9uUHJvY2Vzc2VkKHJlc3VsdCkge1xuICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgICdldmVudCc6ICdwcm9jZXNzZWQnLFxuICAgICAgICAgICAgaW1hZ2VEYXRhOiBpbWFnZVdyYXBwZXIuZGF0YSxcbiAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgIH0sIFtpbWFnZVdyYXBwZXIuZGF0YS5idWZmZXJdKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZWFkeSgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKHsnZXZlbnQnOiAnaW5pdGlhbGl6ZWQnLCBpbWFnZURhdGE6IGltYWdlV3JhcHBlci5kYXRhfSwgW2ltYWdlV3JhcHBlci5kYXRhLmJ1ZmZlcl0pO1xuICAgIH1cblxuICAgIC8qIGVzbGludC1lbmFibGUgKi9cbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVXb3JrZXJCbG9iKCkge1xuICAgIHZhciBibG9iLFxuICAgICAgICBmYWN0b3J5U291cmNlO1xuXG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGlmICh0eXBlb2YgX19mYWN0b3J5U291cmNlX18gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGZhY3RvcnlTb3VyY2UgPSBfX2ZhY3RvcnlTb3VyY2VfXzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuICAgIH1cbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgYmxvYiA9IG5ldyBCbG9iKFsnKCcgKyB3b3JrZXJJbnRlcmZhY2UudG9TdHJpbmcoKSArICcpKCcgKyBmYWN0b3J5U291cmNlICsgJyk7J10sXG4gICAgICAgIHt0eXBlOiAndGV4dC9qYXZhc2NyaXB0J30pO1xuXG4gICAgcmV0dXJuIHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xufVxuXG5mdW5jdGlvbiBzZXRSZWFkZXJzKHJlYWRlcnMpIHtcbiAgICBpZiAoX2RlY29kZXIpIHtcbiAgICAgICAgX2RlY29kZXIuc2V0UmVhZGVycyhyZWFkZXJzKTtcbiAgICB9IGVsc2UgaWYgKF9vblVJVGhyZWFkICYmIF93b3JrZXJQb29sLmxlbmd0aCA+IDApIHtcbiAgICAgICAgX3dvcmtlclBvb2wuZm9yRWFjaChmdW5jdGlvbih3b3JrZXJUaHJlYWQpIHtcbiAgICAgICAgICAgIHdvcmtlclRocmVhZC53b3JrZXIucG9zdE1lc3NhZ2Uoe2NtZDogJ3NldFJlYWRlcnMnLCByZWFkZXJzOiByZWFkZXJzfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIGluaXQ6IGZ1bmN0aW9uKGNvbmZpZywgY2IsIGltYWdlV3JhcHBlcikge1xuICAgICAgICBfY29uZmlnID0gbWVyZ2Uoe30sIENvbmZpZywgY29uZmlnKTtcbiAgICAgICAgaWYgKGltYWdlV3JhcHBlcikge1xuICAgICAgICAgICAgX29uVUlUaHJlYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGluaXRpYWxpemVEYXRhKGltYWdlV3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm4gY2IoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluaXRJbnB1dFN0cmVhbShjYik7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgc3RhcnQoKTtcbiAgICB9LFxuICAgIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgICAgICBfc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIF93b3JrZXJQb29sLmZvckVhY2goZnVuY3Rpb24od29ya2VyVGhyZWFkKSB7XG4gICAgICAgICAgICB3b3JrZXJUaHJlYWQud29ya2VyLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJXb3JrZXIgdGVybWluYXRlZCFcIik7XG4gICAgICAgIH0pO1xuICAgICAgICBfd29ya2VyUG9vbC5sZW5ndGggPSAwO1xuICAgICAgICBpZiAoX2NvbmZpZy5pbnB1dFN0cmVhbS50eXBlID09PSBcIkxpdmVTdHJlYW1cIikge1xuICAgICAgICAgICAgQ2FtZXJhQWNjZXNzLnJlbGVhc2UoKTtcbiAgICAgICAgICAgIF9pbnB1dFN0cmVhbS5jbGVhckV2ZW50SGFuZGxlcnMoKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcGF1c2U6IGZ1bmN0aW9uKCkge1xuICAgICAgICBfc3RvcHBlZCA9IHRydWU7XG4gICAgfSxcbiAgICBvbkRldGVjdGVkOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgICBFdmVudHMuc3Vic2NyaWJlKFwiZGV0ZWN0ZWRcIiwgY2FsbGJhY2spO1xuICAgIH0sXG4gICAgb2ZmRGV0ZWN0ZWQ6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgIEV2ZW50cy51bnN1YnNjcmliZShcImRldGVjdGVkXCIsIGNhbGxiYWNrKTtcbiAgICB9LFxuICAgIG9uUHJvY2Vzc2VkOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgICBFdmVudHMuc3Vic2NyaWJlKFwicHJvY2Vzc2VkXCIsIGNhbGxiYWNrKTtcbiAgICB9LFxuICAgIG9mZlByb2Nlc3NlZDogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgICAgRXZlbnRzLnVuc3Vic2NyaWJlKFwicHJvY2Vzc2VkXCIsIGNhbGxiYWNrKTtcbiAgICB9LFxuICAgIHNldFJlYWRlcnM6IGZ1bmN0aW9uKHJlYWRlcnMpIHtcbiAgICAgICAgc2V0UmVhZGVycyhyZWFkZXJzKTtcbiAgICB9LFxuICAgIHJlZ2lzdGVyUmVzdWx0Q29sbGVjdG9yOiBmdW5jdGlvbihyZXN1bHRDb2xsZWN0b3IpIHtcbiAgICAgICAgaWYgKHJlc3VsdENvbGxlY3RvciAmJiB0eXBlb2YgcmVzdWx0Q29sbGVjdG9yLmFkZFJlc3VsdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgX3Jlc3VsdENvbGxlY3RvciA9IHJlc3VsdENvbGxlY3RvcjtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgY2FudmFzOiBfY2FudmFzQ29udGFpbmVyLFxuICAgIGRlY29kZVNpbmdsZTogZnVuY3Rpb24oY29uZmlnLCByZXN1bHRDYWxsYmFjaykge1xuICAgICAgICBjb25maWcgPSBtZXJnZSh7XG4gICAgICAgICAgICBpbnB1dFN0cmVhbToge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwiSW1hZ2VTdHJlYW1cIixcbiAgICAgICAgICAgICAgICBzZXF1ZW5jZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2l6ZTogODAwLFxuICAgICAgICAgICAgICAgIHNyYzogY29uZmlnLnNyY1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG51bU9mV29ya2VyczogMSxcbiAgICAgICAgICAgIGxvY2F0b3I6IHtcbiAgICAgICAgICAgICAgICBoYWxmU2FtcGxlOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9LCBjb25maWcpO1xuICAgICAgICB0aGlzLmluaXQoY29uZmlnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIEV2ZW50cy5vbmNlKFwicHJvY2Vzc2VkXCIsIGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIF9zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXN1bHRDYWxsYmFjay5jYWxsKG51bGwsIHJlc3VsdCk7XG4gICAgICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgICAgIHN0YXJ0KCk7XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgSW1hZ2VXcmFwcGVyOiBJbWFnZVdyYXBwZXIsXG4gICAgSW1hZ2VEZWJ1ZzogSW1hZ2VEZWJ1ZyxcbiAgICBSZXN1bHRDb2xsZWN0b3I6IFJlc3VsdENvbGxlY3RvclxufTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL3F1YWdnYS5qc1xuICoqLyIsIi8qXG4gKiB0eXBlZGVmcy5qc1xuICogTm9ybWFsaXplcyBicm93c2VyLXNwZWNpZmljIHByZWZpeGVzXG4gKi9cblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgd2luZG93LnJlcXVlc3RBbmltRnJhbWUgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAgICAgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAgICAgd2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAgICAgd2luZG93Lm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgICAgIHdpbmRvdy5tc1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAgICAgZnVuY3Rpb24gKC8qIGZ1bmN0aW9uIEZyYW1lUmVxdWVzdENhbGxiYWNrICovIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XG4gICAgICAgICAgICB9O1xuICAgIH0pKCk7XG5cbiAgICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLmdldFVzZXJNZWRpYSB8fFxuICAgICAgICBuYXZpZ2F0b3Iud2Via2l0R2V0VXNlck1lZGlhIHx8IG5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEgfHwgbmF2aWdhdG9yLm1zR2V0VXNlck1lZGlhO1xuICAgIHdpbmRvdy5VUkwgPSB3aW5kb3cuVVJMIHx8IHdpbmRvdy53ZWJraXRVUkwgfHwgd2luZG93Lm1velVSTCB8fCB3aW5kb3cubXNVUkw7XG59XG5NYXRoLmltdWwgPSBNYXRoLmltdWwgfHwgZnVuY3Rpb24oYSwgYikge1xuICAgIHZhciBhaCA9IChhID4+PiAxNikgJiAweGZmZmYsXG4gICAgICAgIGFsID0gYSAmIDB4ZmZmZixcbiAgICAgICAgYmggPSAoYiA+Pj4gMTYpICYgMHhmZmZmLFxuICAgICAgICBibCA9IGIgJiAweGZmZmY7XG4gICAgLy8gdGhlIHNoaWZ0IGJ5IDAgZml4ZXMgdGhlIHNpZ24gb24gdGhlIGhpZ2ggcGFydFxuICAgIC8vIHRoZSBmaW5hbCB8MCBjb252ZXJ0cyB0aGUgdW5zaWduZWQgdmFsdWUgaW50byBhIHNpZ25lZCB2YWx1ZVxuICAgIHJldHVybiAoKGFsICogYmwpICsgKCgoYWggKiBibCArIGFsICogYmgpIDw8IDE2KSA+Pj4gMCkgfCAwKTtcbn07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy90eXBlZGVmcy5qc1xuICoqLyIsImltcG9ydCBTdWJJbWFnZSBmcm9tICcuL3N1YkltYWdlJztcbmltcG9ydCBDVlV0aWxzIGZyb20gJy4vY3ZfdXRpbHMnO1xuaW1wb3J0IEFycmF5SGVscGVyIGZyb20gJy4vYXJyYXlfaGVscGVyJztcbmltcG9ydCB7dmVjMn0gZnJvbSAnZ2wtbWF0cml4JztcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgYmFzaWMgaW1hZ2UgY29tYmluaW5nIHRoZSBkYXRhIGFuZCBzaXplLlxuICogSW4gYWRkaXRpb24sIHNvbWUgbWV0aG9kcyBmb3IgbWFuaXB1bGF0aW9uIGFyZSBjb250YWluZWQuXG4gKiBAcGFyYW0gc2l6ZSB7eCx5fSBUaGUgc2l6ZSBvZiB0aGUgaW1hZ2UgaW4gcGl4ZWxcbiAqIEBwYXJhbSBkYXRhIHtBcnJheX0gSWYgZ2l2ZW4sIGEgZmxhdCBhcnJheSBjb250YWluaW5nIHRoZSBwaXhlbCBkYXRhXG4gKiBAcGFyYW0gQXJyYXlUeXBlIHtUeXBlfSBJZiBnaXZlbiwgdGhlIGRlc2lyZWQgRGF0YVR5cGUgb2YgdGhlIEFycmF5IChtYXkgYmUgdHlwZWQvbm9uLXR5cGVkKVxuICogQHBhcmFtIGluaXRpYWxpemUge0Jvb2xlYW59IEluZGljYXRpbmcgaWYgdGhlIGFycmF5IHNob3VsZCBiZSBpbml0aWFsaXplZCBvbiBjcmVhdGlvbi5cbiAqIEByZXR1cm5zIHtJbWFnZVdyYXBwZXJ9XG4gKi9cbmZ1bmN0aW9uIEltYWdlV3JhcHBlcihzaXplLCBkYXRhLCBBcnJheVR5cGUsIGluaXRpYWxpemUpIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgaWYgKEFycmF5VHlwZSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhID0gbmV3IEFycmF5VHlwZShzaXplLnggKiBzaXplLnkpO1xuICAgICAgICAgICAgaWYgKEFycmF5VHlwZSA9PT0gQXJyYXkgJiYgaW5pdGlhbGl6ZSkge1xuICAgICAgICAgICAgICAgIEFycmF5SGVscGVyLmluaXQodGhpcy5kYXRhLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KHNpemUueCAqIHNpemUueSk7XG4gICAgICAgICAgICBpZiAoVWludDhBcnJheSA9PT0gQXJyYXkgJiYgaW5pdGlhbGl6ZSkge1xuICAgICAgICAgICAgICAgIEFycmF5SGVscGVyLmluaXQodGhpcy5kYXRhLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuICAgIHRoaXMuc2l6ZSA9IHNpemU7XG59XG5cbi8qKlxuICogdGVzdHMgaWYgYSBwb3NpdGlvbiBpcyB3aXRoaW4gdGhlIGltYWdlIHdpdGggYSBnaXZlbiBvZmZzZXRcbiAqIEBwYXJhbSBpbWdSZWYge3gsIHl9IFRoZSBsb2NhdGlvbiB0byB0ZXN0XG4gKiBAcGFyYW0gYm9yZGVyIE51bWJlciB0aGUgcGFkZGluZyB2YWx1ZSBpbiBwaXhlbFxuICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgbG9jYXRpb24gaW5zaWRlIHRoZSBpbWFnZSdzIGJvcmRlciwgZmFsc2Ugb3RoZXJ3aXNlXG4gKiBAc2VlIGN2ZC9pbWFnZS5oXG4gKi9cbkltYWdlV3JhcHBlci5wcm90b3R5cGUuaW5JbWFnZVdpdGhCb3JkZXIgPSBmdW5jdGlvbihpbWdSZWYsIGJvcmRlcikge1xuICAgIHJldHVybiAoaW1nUmVmLnggPj0gYm9yZGVyKVxuICAgICAgICAmJiAoaW1nUmVmLnkgPj0gYm9yZGVyKVxuICAgICAgICAmJiAoaW1nUmVmLnggPCAodGhpcy5zaXplLnggLSBib3JkZXIpKVxuICAgICAgICAmJiAoaW1nUmVmLnkgPCAodGhpcy5zaXplLnkgLSBib3JkZXIpKTtcbn07XG5cbi8qKlxuICogUGVyZm9ybXMgYmlsaW5lYXIgc2FtcGxpbmdcbiAqIEBwYXJhbSBpbkltZyBJbWFnZSB0byBleHRyYWN0IHNhbXBsZSBmcm9tXG4gKiBAcGFyYW0geCB0aGUgeC1jb29yZGluYXRlXG4gKiBAcGFyYW0geSB0aGUgeS1jb29yZGluYXRlXG4gKiBAcmV0dXJucyB0aGUgc2FtcGxlZCB2YWx1ZVxuICogQHNlZSBjdmQvdmlzaW9uLmhcbiAqL1xuSW1hZ2VXcmFwcGVyLnNhbXBsZSA9IGZ1bmN0aW9uKGluSW1nLCB4LCB5KSB7XG4gICAgdmFyIGx4ID0gTWF0aC5mbG9vcih4KTtcbiAgICB2YXIgbHkgPSBNYXRoLmZsb29yKHkpO1xuICAgIHZhciB3ID0gaW5JbWcuc2l6ZS54O1xuICAgIHZhciBiYXNlID0gbHkgKiBpbkltZy5zaXplLnggKyBseDtcbiAgICB2YXIgYSA9IGluSW1nLmRhdGFbYmFzZSArIDBdO1xuICAgIHZhciBiID0gaW5JbWcuZGF0YVtiYXNlICsgMV07XG4gICAgdmFyIGMgPSBpbkltZy5kYXRhW2Jhc2UgKyB3XTtcbiAgICB2YXIgZCA9IGluSW1nLmRhdGFbYmFzZSArIHcgKyAxXTtcbiAgICB2YXIgZSA9IGEgLSBiO1xuICAgIHggLT0gbHg7XG4gICAgeSAtPSBseTtcblxuICAgIHZhciByZXN1bHQgPSBNYXRoLmZsb29yKHggKiAoeSAqIChlIC0gYyArIGQpIC0gZSkgKyB5ICogKGMgLSBhKSArIGEpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGEgZ2l2ZW4gYXJyYXkuIFNldHMgZWFjaCBlbGVtZW50IHRvIHplcm8uXG4gKiBAcGFyYW0gYXJyYXkge0FycmF5fSBUaGUgYXJyYXkgdG8gaW5pdGlhbGl6ZVxuICovXG5JbWFnZVdyYXBwZXIuY2xlYXJBcnJheSA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgdmFyIGwgPSBhcnJheS5sZW5ndGg7XG4gICAgd2hpbGUgKGwtLSkge1xuICAgICAgICBhcnJheVtsXSA9IDA7XG4gICAgfVxufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEge1N1YkltYWdlfSBmcm9tIHRoZSBjdXJyZW50IGltYWdlICh7dGhpc30pLlxuICogQHBhcmFtIGZyb20ge0ltYWdlUmVmfSBUaGUgcG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgdGhlIHtTdWJJbWFnZX0gZnJvbS4gKHRvcC1sZWZ0IGNvcm5lcilcbiAqIEBwYXJhbSBzaXplIHtJbWFnZVJlZn0gVGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBpbWFnZVxuICogQHJldHVybnMge1N1YkltYWdlfSBBIHNoYXJlZCBwYXJ0IG9mIHRoZSBvcmlnaW5hbCBpbWFnZVxuICovXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLnN1YkltYWdlID0gZnVuY3Rpb24oZnJvbSwgc2l6ZSkge1xuICAgIHJldHVybiBuZXcgU3ViSW1hZ2UoZnJvbSwgc2l6ZSwgdGhpcyk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4ge0ltYWdlV3JhcHBlcikgYW5kIGNvcGllcyB0aGUgbmVlZGVkIHVuZGVybHlpbmcgaW1hZ2UtZGF0YSBhcmVhXG4gKiBAcGFyYW0gaW1hZ2VXcmFwcGVyIHtJbWFnZVdyYXBwZXJ9IFRoZSB0YXJnZXQge0ltYWdlV3JhcHBlcn0gd2hlcmUgdGhlIGRhdGEgc2hvdWxkIGJlIGNvcGllZFxuICogQHBhcmFtIGZyb20ge0ltYWdlUmVmfSBUaGUgbG9jYXRpb24gd2hlcmUgdG8gY29weSBmcm9tICh0b3AtbGVmdCBsb2NhdGlvbilcbiAqL1xuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5zdWJJbWFnZUFzQ29weSA9IGZ1bmN0aW9uKGltYWdlV3JhcHBlciwgZnJvbSkge1xuICAgIHZhciBzaXplWSA9IGltYWdlV3JhcHBlci5zaXplLnksIHNpemVYID0gaW1hZ2VXcmFwcGVyLnNpemUueDtcbiAgICB2YXIgeCwgeTtcbiAgICBmb3IgKCB4ID0gMDsgeCA8IHNpemVYOyB4KyspIHtcbiAgICAgICAgZm9yICggeSA9IDA7IHkgPCBzaXplWTsgeSsrKSB7XG4gICAgICAgICAgICBpbWFnZVdyYXBwZXIuZGF0YVt5ICogc2l6ZVggKyB4XSA9IHRoaXMuZGF0YVsoZnJvbS55ICsgeSkgKiB0aGlzLnNpemUueCArIGZyb20ueCArIHhdO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5jb3B5VG8gPSBmdW5jdGlvbihpbWFnZVdyYXBwZXIpIHtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5kYXRhLmxlbmd0aCwgc3JjRGF0YSA9IHRoaXMuZGF0YSwgZHN0RGF0YSA9IGltYWdlV3JhcHBlci5kYXRhO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGRzdERhdGFbbGVuZ3RoXSA9IHNyY0RhdGFbbGVuZ3RoXTtcbiAgICB9XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyBhIGdpdmVuIHBpeGVsIHBvc2l0aW9uIGZyb20gdGhlIGltYWdlXG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxuICogQHBhcmFtIHkge051bWJlcn0gVGhlIHktcG9zaXRpb25cbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBncmF5c2NhbGUgdmFsdWUgYXQgdGhlIHBpeGVsLXBvc2l0aW9uXG4gKi9cbkltYWdlV3JhcHBlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgIHJldHVybiB0aGlzLmRhdGFbeSAqIHRoaXMuc2l6ZS54ICsgeF07XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyBhIGdpdmVuIHBpeGVsIHBvc2l0aW9uIGZyb20gdGhlIGltYWdlXG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxuICogQHBhcmFtIHkge051bWJlcn0gVGhlIHktcG9zaXRpb25cbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBncmF5c2NhbGUgdmFsdWUgYXQgdGhlIHBpeGVsLXBvc2l0aW9uXG4gKi9cbkltYWdlV3JhcHBlci5wcm90b3R5cGUuZ2V0U2FmZSA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB2YXIgaTtcblxuICAgIGlmICghdGhpcy5pbmRleE1hcHBpbmcpIHtcbiAgICAgICAgdGhpcy5pbmRleE1hcHBpbmcgPSB7XG4gICAgICAgICAgICB4OiBbXSxcbiAgICAgICAgICAgIHk6IFtdXG4gICAgICAgIH07XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLnNpemUueDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmluZGV4TWFwcGluZy54W2ldID0gaTtcbiAgICAgICAgICAgIHRoaXMuaW5kZXhNYXBwaW5nLnhbaSArIHRoaXMuc2l6ZS54XSA9IGk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2l6ZS55OyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXhNYXBwaW5nLnlbaV0gPSBpO1xuICAgICAgICAgICAgdGhpcy5pbmRleE1hcHBpbmcueVtpICsgdGhpcy5zaXplLnldID0gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5kYXRhWyh0aGlzLmluZGV4TWFwcGluZy55W3kgKyB0aGlzLnNpemUueV0pICogdGhpcy5zaXplLnggKyB0aGlzLmluZGV4TWFwcGluZy54W3ggKyB0aGlzLnNpemUueF1dO1xufTtcblxuLyoqXG4gKiBTZXRzIGEgZ2l2ZW4gcGl4ZWwgcG9zaXRpb24gaW4gdGhlIGltYWdlXG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxuICogQHBhcmFtIHkge051bWJlcn0gVGhlIHktcG9zaXRpb25cbiAqIEBwYXJhbSB2YWx1ZSB7TnVtYmVyfSBUaGUgZ3JheXNjYWxlIHZhbHVlIHRvIHNldFxuICogQHJldHVybnMge0ltYWdlV3JhcHBlcn0gVGhlIEltYWdlIGl0c2VsZiAoZm9yIHBvc3NpYmxlIGNoYWluaW5nKVxuICovXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKHgsIHksIHZhbHVlKSB7XG4gICAgdGhpcy5kYXRhW3kgKiB0aGlzLnNpemUueCArIHhdID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGJvcmRlciBvZiB0aGUgaW1hZ2UgKDEgcGl4ZWwpIHRvIHplcm9cbiAqL1xuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS56ZXJvQm9yZGVyID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGksIHdpZHRoID0gdGhpcy5zaXplLngsIGhlaWdodCA9IHRoaXMuc2l6ZS55LCBkYXRhID0gdGhpcy5kYXRhO1xuICAgIGZvciAoIGkgPSAwOyBpIDwgd2lkdGg7IGkrKykge1xuICAgICAgICBkYXRhW2ldID0gZGF0YVsoaGVpZ2h0IC0gMSkgKiB3aWR0aCArIGldID0gMDtcbiAgICB9XG4gICAgZm9yICggaSA9IDE7IGkgPCBoZWlnaHQgLSAxOyBpKyspIHtcbiAgICAgICAgZGF0YVtpICogd2lkdGhdID0gZGF0YVtpICogd2lkdGggKyAod2lkdGggLSAxKV0gPSAwO1xuICAgIH1cbn07XG5cbi8qKlxuICogSW52ZXJ0cyBhIGJpbmFyeSBpbWFnZSBpbiBwbGFjZVxuICovXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLmludmVydCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBkYXRhID0gdGhpcy5kYXRhLCBsZW5ndGggPSBkYXRhLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICBkYXRhW2xlbmd0aF0gPSBkYXRhW2xlbmd0aF0gPyAwIDogMTtcbiAgICB9XG59O1xuXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLmNvbnZvbHZlID0gZnVuY3Rpb24oa2VybmVsKSB7XG4gICAgdmFyIHgsIHksIGt4LCBreSwga1NpemUgPSAoa2VybmVsLmxlbmd0aCAvIDIpIHwgMCwgYWNjdSA9IDA7XG4gICAgZm9yICggeSA9IDA7IHkgPCB0aGlzLnNpemUueTsgeSsrKSB7XG4gICAgICAgIGZvciAoIHggPSAwOyB4IDwgdGhpcy5zaXplLng7IHgrKykge1xuICAgICAgICAgICAgYWNjdSA9IDA7XG4gICAgICAgICAgICBmb3IgKCBreSA9IC1rU2l6ZTsga3kgPD0ga1NpemU7IGt5KyspIHtcbiAgICAgICAgICAgICAgICBmb3IgKCBreCA9IC1rU2l6ZTsga3ggPD0ga1NpemU7IGt4KyspIHtcbiAgICAgICAgICAgICAgICAgICAgYWNjdSArPSBrZXJuZWxba3kgKyBrU2l6ZV1ba3ggKyBrU2l6ZV0gKiB0aGlzLmdldFNhZmUoeCArIGt4LCB5ICsga3kpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGF0YVt5ICogdGhpcy5zaXplLnggKyB4XSA9IGFjY3U7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLm1vbWVudHMgPSBmdW5jdGlvbihsYWJlbGNvdW50KSB7XG4gICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIGhlaWdodCA9IHRoaXMuc2l6ZS55LFxuICAgICAgICB3aWR0aCA9IHRoaXMuc2l6ZS54LFxuICAgICAgICB2YWwsXG4gICAgICAgIHlzcSxcbiAgICAgICAgbGFiZWxzdW0gPSBbXSxcbiAgICAgICAgaSxcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIG11MTEsXG4gICAgICAgIG11MDIsXG4gICAgICAgIG11MjAsXG4gICAgICAgIHhfLFxuICAgICAgICB5XyxcbiAgICAgICAgdG1wLFxuICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgUEkgPSBNYXRoLlBJLFxuICAgICAgICBQSV80ID0gUEkgLyA0O1xuXG4gICAgaWYgKGxhYmVsY291bnQgPD0gMCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGZvciAoIGkgPSAwOyBpIDwgbGFiZWxjb3VudDsgaSsrKSB7XG4gICAgICAgIGxhYmVsc3VtW2ldID0ge1xuICAgICAgICAgICAgbTAwOiAwLFxuICAgICAgICAgICAgbTAxOiAwLFxuICAgICAgICAgICAgbTEwOiAwLFxuICAgICAgICAgICAgbTExOiAwLFxuICAgICAgICAgICAgbTAyOiAwLFxuICAgICAgICAgICAgbTIwOiAwLFxuICAgICAgICAgICAgdGhldGE6IDAsXG4gICAgICAgICAgICByYWQ6IDBcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XG4gICAgICAgIHlzcSA9IHkgKiB5O1xuICAgICAgICBmb3IgKCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHtcbiAgICAgICAgICAgIHZhbCA9IGRhdGFbeSAqIHdpZHRoICsgeF07XG4gICAgICAgICAgICBpZiAodmFsID4gMCkge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gbGFiZWxzdW1bdmFsIC0gMV07XG4gICAgICAgICAgICAgICAgbGFiZWwubTAwICs9IDE7XG4gICAgICAgICAgICAgICAgbGFiZWwubTAxICs9IHk7XG4gICAgICAgICAgICAgICAgbGFiZWwubTEwICs9IHg7XG4gICAgICAgICAgICAgICAgbGFiZWwubTExICs9IHggKiB5O1xuICAgICAgICAgICAgICAgIGxhYmVsLm0wMiArPSB5c3E7XG4gICAgICAgICAgICAgICAgbGFiZWwubTIwICs9IHggKiB4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yICggaSA9IDA7IGkgPCBsYWJlbGNvdW50OyBpKyspIHtcbiAgICAgICAgbGFiZWwgPSBsYWJlbHN1bVtpXTtcbiAgICAgICAgaWYgKCFpc05hTihsYWJlbC5tMDApICYmIGxhYmVsLm0wMCAhPT0gMCkge1xuICAgICAgICAgICAgeF8gPSBsYWJlbC5tMTAgLyBsYWJlbC5tMDA7XG4gICAgICAgICAgICB5XyA9IGxhYmVsLm0wMSAvIGxhYmVsLm0wMDtcbiAgICAgICAgICAgIG11MTEgPSBsYWJlbC5tMTEgLyBsYWJlbC5tMDAgLSB4XyAqIHlfO1xuICAgICAgICAgICAgbXUwMiA9IGxhYmVsLm0wMiAvIGxhYmVsLm0wMCAtIHlfICogeV87XG4gICAgICAgICAgICBtdTIwID0gbGFiZWwubTIwIC8gbGFiZWwubTAwIC0geF8gKiB4XztcbiAgICAgICAgICAgIHRtcCA9IChtdTAyIC0gbXUyMCkgLyAoMiAqIG11MTEpO1xuICAgICAgICAgICAgdG1wID0gMC41ICogTWF0aC5hdGFuKHRtcCkgKyAobXUxMSA+PSAwID8gUElfNCA6IC1QSV80ICkgKyBQSTtcbiAgICAgICAgICAgIGxhYmVsLnRoZXRhID0gKHRtcCAqIDE4MCAvIFBJICsgOTApICUgMTgwIC0gOTA7XG4gICAgICAgICAgICBpZiAobGFiZWwudGhldGEgPCAwKSB7XG4gICAgICAgICAgICAgICAgbGFiZWwudGhldGEgKz0gMTgwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFiZWwucmFkID0gdG1wID4gUEkgPyB0bXAgLSBQSSA6IHRtcDtcbiAgICAgICAgICAgIGxhYmVsLnZlYyA9IHZlYzIuY2xvbmUoW01hdGguY29zKHRtcCksIE1hdGguc2luKHRtcCldKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGxhYmVsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIERpc3BsYXlzIHRoZSB7SW1hZ2VXcmFwcGVyfSBpbiBhIGdpdmVuIGNhbnZhc1xuICogQHBhcmFtIGNhbnZhcyB7Q2FudmFzfSBUaGUgY2FudmFzIGVsZW1lbnQgdG8gd3JpdGUgdG9cbiAqIEBwYXJhbSBzY2FsZSB7TnVtYmVyfSBTY2FsZSB3aGljaCBpcyBhcHBsaWVkIHRvIGVhY2ggcGl4ZWwtdmFsdWVcbiAqL1xuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24oY2FudmFzLCBzY2FsZSkge1xuICAgIHZhciBjdHgsXG4gICAgICAgIGZyYW1lLFxuICAgICAgICBkYXRhLFxuICAgICAgICBjdXJyZW50LFxuICAgICAgICBwaXhlbCxcbiAgICAgICAgeCxcbiAgICAgICAgeTtcblxuICAgIGlmICghc2NhbGUpIHtcbiAgICAgICAgc2NhbGUgPSAxLjA7XG4gICAgfVxuICAgIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIGNhbnZhcy53aWR0aCA9IHRoaXMuc2l6ZS54O1xuICAgIGNhbnZhcy5oZWlnaHQgPSB0aGlzLnNpemUueTtcbiAgICBmcmFtZSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICBkYXRhID0gZnJhbWUuZGF0YTtcbiAgICBjdXJyZW50ID0gMDtcbiAgICBmb3IgKHkgPSAwOyB5IDwgdGhpcy5zaXplLnk7IHkrKykge1xuICAgICAgICBmb3IgKHggPSAwOyB4IDwgdGhpcy5zaXplLng7IHgrKykge1xuICAgICAgICAgICAgcGl4ZWwgPSB5ICogdGhpcy5zaXplLnggKyB4O1xuICAgICAgICAgICAgY3VycmVudCA9IHRoaXMuZ2V0KHgsIHkpICogc2NhbGU7XG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDBdID0gY3VycmVudDtcbiAgICAgICAgICAgIGRhdGFbcGl4ZWwgKiA0ICsgMV0gPSBjdXJyZW50O1xuICAgICAgICAgICAgZGF0YVtwaXhlbCAqIDQgKyAyXSA9IGN1cnJlbnQ7XG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDNdID0gMjU1O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vZnJhbWUuZGF0YSA9IGRhdGE7XG4gICAgY3R4LnB1dEltYWdlRGF0YShmcmFtZSwgMCwgMCk7XG59O1xuXG4vKipcbiAqIERpc3BsYXlzIHRoZSB7U3ViSW1hZ2V9IGluIGEgZ2l2ZW4gY2FudmFzXG4gKiBAcGFyYW0gY2FudmFzIHtDYW52YXN9IFRoZSBjYW52YXMgZWxlbWVudCB0byB3cml0ZSB0b1xuICogQHBhcmFtIHNjYWxlIHtOdW1iZXJ9IFNjYWxlIHdoaWNoIGlzIGFwcGxpZWQgdG8gZWFjaCBwaXhlbC12YWx1ZVxuICovXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLm92ZXJsYXkgPSBmdW5jdGlvbihjYW52YXMsIHNjYWxlLCBmcm9tKSB7XG4gICAgaWYgKCFzY2FsZSB8fCBzY2FsZSA8IDAgfHwgc2NhbGUgPiAzNjApIHtcbiAgICAgICAgc2NhbGUgPSAzNjA7XG4gICAgfVxuICAgIHZhciBoc3YgPSBbMCwgMSwgMV07XG4gICAgdmFyIHJnYiA9IFswLCAwLCAwXTtcbiAgICB2YXIgd2hpdGVSZ2IgPSBbMjU1LCAyNTUsIDI1NV07XG4gICAgdmFyIGJsYWNrUmdiID0gWzAsIDAsIDBdO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgdmFyIGZyYW1lID0gY3R4LmdldEltYWdlRGF0YShmcm9tLngsIGZyb20ueSwgdGhpcy5zaXplLngsIHRoaXMuc2l6ZS55KTtcbiAgICB2YXIgZGF0YSA9IGZyYW1lLmRhdGE7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGhzdlswXSA9IHRoaXMuZGF0YVtsZW5ndGhdICogc2NhbGU7XG4gICAgICAgIHJlc3VsdCA9IGhzdlswXSA8PSAwID8gd2hpdGVSZ2IgOiBoc3ZbMF0gPj0gMzYwID8gYmxhY2tSZ2IgOiBDVlV0aWxzLmhzdjJyZ2IoaHN2LCByZ2IpO1xuICAgICAgICBkYXRhW2xlbmd0aCAqIDQgKyAwXSA9IHJlc3VsdFswXTtcbiAgICAgICAgZGF0YVtsZW5ndGggKiA0ICsgMV0gPSByZXN1bHRbMV07XG4gICAgICAgIGRhdGFbbGVuZ3RoICogNCArIDJdID0gcmVzdWx0WzJdO1xuICAgICAgICBkYXRhW2xlbmd0aCAqIDQgKyAzXSA9IDI1NTtcbiAgICB9XG4gICAgY3R4LnB1dEltYWdlRGF0YShmcmFtZSwgZnJvbS54LCBmcm9tLnkpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgSW1hZ2VXcmFwcGVyO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvaW1hZ2Vfd3JhcHBlci5qc1xuICoqLyIsIi8qKlxuICogQ29uc3RydWN0IHJlcHJlc2VudGluZyBhIHBhcnQgb2YgYW5vdGhlciB7SW1hZ2VXcmFwcGVyfS4gU2hhcmVzIGRhdGFcbiAqIGJldHdlZW4gdGhlIHBhcmVudCBhbmQgdGhlIGNoaWxkLlxuICogQHBhcmFtIGZyb20ge0ltYWdlUmVmfSBUaGUgcG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgdGhlIHtTdWJJbWFnZX0gZnJvbS4gKHRvcC1sZWZ0IGNvcm5lcilcbiAqIEBwYXJhbSBzaXplIHtJbWFnZVJlZn0gVGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBpbWFnZVxuICogQHBhcmFtIEkge0ltYWdlV3JhcHBlcn0gVGhlIHtJbWFnZVdyYXBwZXJ9IHRvIHNoYXJlIGZyb21cbiAqIEByZXR1cm5zIHtTdWJJbWFnZX0gQSBzaGFyZWQgcGFydCBvZiB0aGUgb3JpZ2luYWwgaW1hZ2VcbiAqL1xuZnVuY3Rpb24gU3ViSW1hZ2UoZnJvbSwgc2l6ZSwgSSkge1xuICAgIGlmICghSSkge1xuICAgICAgICBJID0ge1xuICAgICAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgICAgIHNpemU6IHNpemVcbiAgICAgICAgfTtcbiAgICB9XG4gICAgdGhpcy5kYXRhID0gSS5kYXRhO1xuICAgIHRoaXMub3JpZ2luYWxTaXplID0gSS5zaXplO1xuICAgIHRoaXMuSSA9IEk7XG5cbiAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgIHRoaXMuc2l6ZSA9IHNpemU7XG59XG5cbi8qKlxuICogRGlzcGxheXMgdGhlIHtTdWJJbWFnZX0gaW4gYSBnaXZlbiBjYW52YXNcbiAqIEBwYXJhbSBjYW52YXMge0NhbnZhc30gVGhlIGNhbnZhcyBlbGVtZW50IHRvIHdyaXRlIHRvXG4gKiBAcGFyYW0gc2NhbGUge051bWJlcn0gU2NhbGUgd2hpY2ggaXMgYXBwbGllZCB0byBlYWNoIHBpeGVsLXZhbHVlXG4gKi9cblN1YkltYWdlLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24oY2FudmFzLCBzY2FsZSkge1xuICAgIHZhciBjdHgsXG4gICAgICAgIGZyYW1lLFxuICAgICAgICBkYXRhLFxuICAgICAgICBjdXJyZW50LFxuICAgICAgICB5LFxuICAgICAgICB4LFxuICAgICAgICBwaXhlbDtcblxuICAgIGlmICghc2NhbGUpIHtcbiAgICAgICAgc2NhbGUgPSAxLjA7XG4gICAgfVxuICAgIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIGNhbnZhcy53aWR0aCA9IHRoaXMuc2l6ZS54O1xuICAgIGNhbnZhcy5oZWlnaHQgPSB0aGlzLnNpemUueTtcbiAgICBmcmFtZSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICBkYXRhID0gZnJhbWUuZGF0YTtcbiAgICBjdXJyZW50ID0gMDtcbiAgICBmb3IgKHkgPSAwOyB5IDwgdGhpcy5zaXplLnk7IHkrKykge1xuICAgICAgICBmb3IgKHggPSAwOyB4IDwgdGhpcy5zaXplLng7IHgrKykge1xuICAgICAgICAgICAgcGl4ZWwgPSB5ICogdGhpcy5zaXplLnggKyB4O1xuICAgICAgICAgICAgY3VycmVudCA9IHRoaXMuZ2V0KHgsIHkpICogc2NhbGU7XG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDBdID0gY3VycmVudDtcbiAgICAgICAgICAgIGRhdGFbcGl4ZWwgKiA0ICsgMV0gPSBjdXJyZW50O1xuICAgICAgICAgICAgZGF0YVtwaXhlbCAqIDQgKyAyXSA9IGN1cnJlbnQ7XG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDNdID0gMjU1O1xuICAgICAgICB9XG4gICAgfVxuICAgIGZyYW1lLmRhdGEgPSBkYXRhO1xuICAgIGN0eC5wdXRJbWFnZURhdGEoZnJhbWUsIDAsIDApO1xufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBnaXZlbiBwaXhlbCBwb3NpdGlvbiBmcm9tIHRoZSB7U3ViSW1hZ2V9XG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxuICogQHBhcmFtIHkge051bWJlcn0gVGhlIHktcG9zaXRpb25cbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBncmF5c2NhbGUgdmFsdWUgYXQgdGhlIHBpeGVsLXBvc2l0aW9uXG4gKi9cblN1YkltYWdlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVsodGhpcy5mcm9tLnkgKyB5KSAqIHRoaXMub3JpZ2luYWxTaXplLnggKyB0aGlzLmZyb20ueCArIHhdO1xufTtcblxuLyoqXG4gKiBVcGRhdGVzIHRoZSB1bmRlcmx5aW5nIGRhdGEgZnJvbSBhIGdpdmVuIHtJbWFnZVdyYXBwZXJ9XG4gKiBAcGFyYW0gaW1hZ2Uge0ltYWdlV3JhcHBlcn0gVGhlIHVwZGF0ZWQgaW1hZ2VcbiAqL1xuU3ViSW1hZ2UucHJvdG90eXBlLnVwZGF0ZURhdGEgPSBmdW5jdGlvbihpbWFnZSkge1xuICAgIHRoaXMub3JpZ2luYWxTaXplID0gaW1hZ2Uuc2l6ZTtcbiAgICB0aGlzLmRhdGEgPSBpbWFnZS5kYXRhO1xufTtcblxuLyoqXG4gKiBVcGRhdGVzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc2hhcmVkIGFyZWFcbiAqIEBwYXJhbSBmcm9tIHt4LHl9IFRoZSBuZXcgbG9jYXRpb25cbiAqIEByZXR1cm5zIHtTdWJJbWFnZX0gcmV0dXJucyB7dGhpc30gZm9yIHBvc3NpYmxlIGNoYWluaW5nXG4gKi9cblN1YkltYWdlLnByb3RvdHlwZS51cGRhdGVGcm9tID0gZnVuY3Rpb24oZnJvbSkge1xuICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5leHBvcnQgZGVmYXVsdCAoU3ViSW1hZ2UpO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvc3ViSW1hZ2UuanNcbiAqKi8iLCJpbXBvcnQgQ2x1c3RlcjIgZnJvbSAnLi9jbHVzdGVyJztcbmltcG9ydCBBcnJheUhlbHBlciBmcm9tICcuL2FycmF5X2hlbHBlcic7XG5pbXBvcnQge3ZlYzIsIHZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5cbnZhciBDVlV0aWxzID0ge307XG5cbi8qKlxuICogQHBhcmFtIHggeC1jb29yZGluYXRlXG4gKiBAcGFyYW0geSB5LWNvb3JkaW5hdGVcbiAqIEByZXR1cm4gSW1hZ2VSZWZlcmVuY2Uge3gseX0gQ29vcmRpbmF0ZVxuICovXG5DVlV0aWxzLmltYWdlUmVmID0gZnVuY3Rpb24oeCwgeSkge1xuICAgIHZhciB0aGF0ID0ge1xuICAgICAgICB4OiB4LFxuICAgICAgICB5OiB5LFxuICAgICAgICB0b1ZlYzI6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHZlYzIuY2xvbmUoW3RoaXMueCwgdGhpcy55XSk7XG4gICAgICAgIH0sXG4gICAgICAgIHRvVmVjMzogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdmVjMy5jbG9uZShbdGhpcy54LCB0aGlzLnksIDFdKTtcbiAgICAgICAgfSxcbiAgICAgICAgcm91bmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhpcy54ID0gdGhpcy54ID4gMC4wID8gTWF0aC5mbG9vcih0aGlzLnggKyAwLjUpIDogTWF0aC5mbG9vcih0aGlzLnggLSAwLjUpO1xuICAgICAgICAgICAgdGhpcy55ID0gdGhpcy55ID4gMC4wID8gTWF0aC5mbG9vcih0aGlzLnkgKyAwLjUpIDogTWF0aC5mbG9vcih0aGlzLnkgLSAwLjUpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiB0aGF0O1xufTtcblxuLyoqXG4gKiBDb21wdXRlcyBhbiBpbnRlZ3JhbCBpbWFnZSBvZiBhIGdpdmVuIGdyYXlzY2FsZSBpbWFnZS5cbiAqIEBwYXJhbSBpbWFnZURhdGFDb250YWluZXIge0ltYWdlRGF0YUNvbnRhaW5lcn0gdGhlIGltYWdlIHRvIGJlIGludGVncmF0ZWRcbiAqL1xuQ1ZVdGlscy5jb21wdXRlSW50ZWdyYWxJbWFnZTIgPSBmdW5jdGlvbihpbWFnZVdyYXBwZXIsIGludGVncmFsV3JhcHBlcikge1xuICAgIHZhciBpbWFnZURhdGEgPSBpbWFnZVdyYXBwZXIuZGF0YTtcbiAgICB2YXIgd2lkdGggPSBpbWFnZVdyYXBwZXIuc2l6ZS54O1xuICAgIHZhciBoZWlnaHQgPSBpbWFnZVdyYXBwZXIuc2l6ZS55O1xuICAgIHZhciBpbnRlZ3JhbEltYWdlRGF0YSA9IGludGVncmFsV3JhcHBlci5kYXRhO1xuICAgIHZhciBzdW0gPSAwLCBwb3NBID0gMCwgcG9zQiA9IDAsIHBvc0MgPSAwLCBwb3NEID0gMCwgeCwgeTtcblxuICAgIC8vIHN1bSB1cCBmaXJzdCBjb2x1bW5cbiAgICBwb3NCID0gd2lkdGg7XG4gICAgc3VtID0gMDtcbiAgICBmb3IgKCB5ID0gMTsgeSA8IGhlaWdodDsgeSsrKSB7XG4gICAgICAgIHN1bSArPSBpbWFnZURhdGFbcG9zQV07XG4gICAgICAgIGludGVncmFsSW1hZ2VEYXRhW3Bvc0JdICs9IHN1bTtcbiAgICAgICAgcG9zQSArPSB3aWR0aDtcbiAgICAgICAgcG9zQiArPSB3aWR0aDtcbiAgICB9XG5cbiAgICBwb3NBID0gMDtcbiAgICBwb3NCID0gMTtcbiAgICBzdW0gPSAwO1xuICAgIGZvciAoIHggPSAxOyB4IDwgd2lkdGg7IHgrKykge1xuICAgICAgICBzdW0gKz0gaW1hZ2VEYXRhW3Bvc0FdO1xuICAgICAgICBpbnRlZ3JhbEltYWdlRGF0YVtwb3NCXSArPSBzdW07XG4gICAgICAgIHBvc0ErKztcbiAgICAgICAgcG9zQisrO1xuICAgIH1cblxuICAgIGZvciAoIHkgPSAxOyB5IDwgaGVpZ2h0OyB5KyspIHtcbiAgICAgICAgcG9zQSA9IHkgKiB3aWR0aCArIDE7XG4gICAgICAgIHBvc0IgPSAoeSAtIDEpICogd2lkdGggKyAxO1xuICAgICAgICBwb3NDID0geSAqIHdpZHRoO1xuICAgICAgICBwb3NEID0gKHkgLSAxKSAqIHdpZHRoO1xuICAgICAgICBmb3IgKCB4ID0gMTsgeCA8IHdpZHRoOyB4KyspIHtcbiAgICAgICAgICAgIGludGVncmFsSW1hZ2VEYXRhW3Bvc0FdICs9XG4gICAgICAgICAgICAgICAgaW1hZ2VEYXRhW3Bvc0FdICsgaW50ZWdyYWxJbWFnZURhdGFbcG9zQl0gKyBpbnRlZ3JhbEltYWdlRGF0YVtwb3NDXSAtIGludGVncmFsSW1hZ2VEYXRhW3Bvc0RdO1xuICAgICAgICAgICAgcG9zQSsrO1xuICAgICAgICAgICAgcG9zQisrO1xuICAgICAgICAgICAgcG9zQysrO1xuICAgICAgICAgICAgcG9zRCsrO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuQ1ZVdGlscy5jb21wdXRlSW50ZWdyYWxJbWFnZSA9IGZ1bmN0aW9uKGltYWdlV3JhcHBlciwgaW50ZWdyYWxXcmFwcGVyKSB7XG4gICAgdmFyIGltYWdlRGF0YSA9IGltYWdlV3JhcHBlci5kYXRhO1xuICAgIHZhciB3aWR0aCA9IGltYWdlV3JhcHBlci5zaXplLng7XG4gICAgdmFyIGhlaWdodCA9IGltYWdlV3JhcHBlci5zaXplLnk7XG4gICAgdmFyIGludGVncmFsSW1hZ2VEYXRhID0gaW50ZWdyYWxXcmFwcGVyLmRhdGE7XG4gICAgdmFyIHN1bSA9IDA7XG5cbiAgICAvLyBzdW0gdXAgZmlyc3Qgcm93XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3aWR0aDsgaSsrKSB7XG4gICAgICAgIHN1bSArPSBpbWFnZURhdGFbaV07XG4gICAgICAgIGludGVncmFsSW1hZ2VEYXRhW2ldID0gc3VtO1xuICAgIH1cblxuICAgIGZvciAodmFyIHYgPSAxOyB2IDwgaGVpZ2h0OyB2KyspIHtcbiAgICAgICAgc3VtID0gMDtcbiAgICAgICAgZm9yICh2YXIgdSA9IDA7IHUgPCB3aWR0aDsgdSsrKSB7XG4gICAgICAgICAgICBzdW0gKz0gaW1hZ2VEYXRhW3YgKiB3aWR0aCArIHVdO1xuICAgICAgICAgICAgaW50ZWdyYWxJbWFnZURhdGFbKCh2KSAqIHdpZHRoKSArIHVdID0gc3VtICsgaW50ZWdyYWxJbWFnZURhdGFbKHYgLSAxKSAqIHdpZHRoICsgdV07XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5DVlV0aWxzLnRocmVzaG9sZEltYWdlID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCB0aHJlc2hvbGQsIHRhcmdldFdyYXBwZXIpIHtcbiAgICBpZiAoIXRhcmdldFdyYXBwZXIpIHtcbiAgICAgICAgdGFyZ2V0V3JhcHBlciA9IGltYWdlV3JhcHBlcjtcbiAgICB9XG4gICAgdmFyIGltYWdlRGF0YSA9IGltYWdlV3JhcHBlci5kYXRhLCBsZW5ndGggPSBpbWFnZURhdGEubGVuZ3RoLCB0YXJnZXREYXRhID0gdGFyZ2V0V3JhcHBlci5kYXRhO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHRhcmdldERhdGFbbGVuZ3RoXSA9IGltYWdlRGF0YVtsZW5ndGhdIDwgdGhyZXNob2xkID8gMSA6IDA7XG4gICAgfVxufTtcblxuQ1ZVdGlscy5jb21wdXRlSGlzdG9ncmFtID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBiaXRzUGVyUGl4ZWwpIHtcbiAgICBpZiAoIWJpdHNQZXJQaXhlbCkge1xuICAgICAgICBiaXRzUGVyUGl4ZWwgPSA4O1xuICAgIH1cbiAgICB2YXIgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGEsXG4gICAgICAgIGxlbmd0aCA9IGltYWdlRGF0YS5sZW5ndGgsXG4gICAgICAgIGJpdFNoaWZ0ID0gOCAtIGJpdHNQZXJQaXhlbCxcbiAgICAgICAgYnVja2V0Q250ID0gMSA8PCBiaXRzUGVyUGl4ZWwsXG4gICAgICAgIGhpc3QgPSBuZXcgSW50MzJBcnJheShidWNrZXRDbnQpO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGhpc3RbaW1hZ2VEYXRhW2xlbmd0aF0gPj4gYml0U2hpZnRdKys7XG4gICAgfVxuICAgIHJldHVybiBoaXN0O1xufTtcblxuQ1ZVdGlscy5zaGFycGVuTGluZSA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgbGVuZ3RoID0gbGluZS5sZW5ndGgsXG4gICAgICAgIGxlZnQgPSBsaW5lWzBdLFxuICAgICAgICBjZW50ZXIgPSBsaW5lWzFdLFxuICAgICAgICByaWdodDtcblxuICAgIGZvciAoaSA9IDE7IGkgPCBsZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgcmlnaHQgPSBsaW5lW2kgKyAxXTtcbiAgICAgICAgLy8gIC0xIDQgLTEga2VybmVsXG4gICAgICAgIGxpbmVbaSAtIDFdID0gKCgoY2VudGVyICogMikgLSBsZWZ0IC0gcmlnaHQpKSAmIDI1NTtcbiAgICAgICAgbGVmdCA9IGNlbnRlcjtcbiAgICAgICAgY2VudGVyID0gcmlnaHQ7XG4gICAgfVxuICAgIHJldHVybiBsaW5lO1xufTtcblxuQ1ZVdGlscy5kZXRlcm1pbmVPdHN1VGhyZXNob2xkID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBiaXRzUGVyUGl4ZWwpIHtcbiAgICBpZiAoIWJpdHNQZXJQaXhlbCkge1xuICAgICAgICBiaXRzUGVyUGl4ZWwgPSA4O1xuICAgIH1cbiAgICB2YXIgaGlzdCxcbiAgICAgICAgdGhyZXNob2xkLFxuICAgICAgICBiaXRTaGlmdCA9IDggLSBiaXRzUGVyUGl4ZWw7XG5cbiAgICBmdW5jdGlvbiBweChpbml0LCBlbmQpIHtcbiAgICAgICAgdmFyIHN1bSA9IDAsIGk7XG4gICAgICAgIGZvciAoIGkgPSBpbml0OyBpIDw9IGVuZDsgaSsrKSB7XG4gICAgICAgICAgICBzdW0gKz0gaGlzdFtpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VtO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG14KGluaXQsIGVuZCkge1xuICAgICAgICB2YXIgaSwgc3VtID0gMDtcblxuICAgICAgICBmb3IgKCBpID0gaW5pdDsgaSA8PSBlbmQ7IGkrKykge1xuICAgICAgICAgICAgc3VtICs9IGkgKiBoaXN0W2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHN1bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXRlcm1pbmVUaHJlc2hvbGQoKSB7XG4gICAgICAgIHZhciB2ZXQgPSBbMF0sIHAxLCBwMiwgcDEyLCBrLCBtMSwgbTIsIG0xMixcbiAgICAgICAgICAgIG1heCA9ICgxIDw8IGJpdHNQZXJQaXhlbCkgLSAxO1xuXG4gICAgICAgIGhpc3QgPSBDVlV0aWxzLmNvbXB1dGVIaXN0b2dyYW0oaW1hZ2VXcmFwcGVyLCBiaXRzUGVyUGl4ZWwpO1xuICAgICAgICBmb3IgKCBrID0gMTsgayA8IG1heDsgaysrKSB7XG4gICAgICAgICAgICBwMSA9IHB4KDAsIGspO1xuICAgICAgICAgICAgcDIgPSBweChrICsgMSwgbWF4KTtcbiAgICAgICAgICAgIHAxMiA9IHAxICogcDI7XG4gICAgICAgICAgICBpZiAocDEyID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcDEyID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG0xID0gbXgoMCwgaykgKiBwMjtcbiAgICAgICAgICAgIG0yID0gbXgoayArIDEsIG1heCkgKiBwMTtcbiAgICAgICAgICAgIG0xMiA9IG0xIC0gbTI7XG4gICAgICAgICAgICB2ZXRba10gPSBtMTIgKiBtMTIgLyBwMTI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIEFycmF5SGVscGVyLm1heEluZGV4KHZldCk7XG4gICAgfVxuXG4gICAgdGhyZXNob2xkID0gZGV0ZXJtaW5lVGhyZXNob2xkKCk7XG4gICAgcmV0dXJuIHRocmVzaG9sZCA8PCBiaXRTaGlmdDtcbn07XG5cbkNWVXRpbHMub3RzdVRocmVzaG9sZCA9IGZ1bmN0aW9uKGltYWdlV3JhcHBlciwgdGFyZ2V0V3JhcHBlcikge1xuICAgIHZhciB0aHJlc2hvbGQgPSBDVlV0aWxzLmRldGVybWluZU90c3VUaHJlc2hvbGQoaW1hZ2VXcmFwcGVyKTtcblxuICAgIENWVXRpbHMudGhyZXNob2xkSW1hZ2UoaW1hZ2VXcmFwcGVyLCB0aHJlc2hvbGQsIHRhcmdldFdyYXBwZXIpO1xuICAgIHJldHVybiB0aHJlc2hvbGQ7XG59O1xuXG4vLyBsb2NhbCB0aHJlc2hvbGRpbmdcbkNWVXRpbHMuY29tcHV0ZUJpbmFyeUltYWdlID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBpbnRlZ3JhbFdyYXBwZXIsIHRhcmdldFdyYXBwZXIpIHtcbiAgICBDVlV0aWxzLmNvbXB1dGVJbnRlZ3JhbEltYWdlKGltYWdlV3JhcHBlciwgaW50ZWdyYWxXcmFwcGVyKTtcblxuICAgIGlmICghdGFyZ2V0V3JhcHBlcikge1xuICAgICAgICB0YXJnZXRXcmFwcGVyID0gaW1hZ2VXcmFwcGVyO1xuICAgIH1cbiAgICB2YXIgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGE7XG4gICAgdmFyIHRhcmdldERhdGEgPSB0YXJnZXRXcmFwcGVyLmRhdGE7XG4gICAgdmFyIHdpZHRoID0gaW1hZ2VXcmFwcGVyLnNpemUueDtcbiAgICB2YXIgaGVpZ2h0ID0gaW1hZ2VXcmFwcGVyLnNpemUueTtcbiAgICB2YXIgaW50ZWdyYWxJbWFnZURhdGEgPSBpbnRlZ3JhbFdyYXBwZXIuZGF0YTtcbiAgICB2YXIgc3VtID0gMCwgdiwgdSwga2VybmVsID0gMywgQSwgQiwgQywgRCwgYXZnLCBzaXplID0gKGtlcm5lbCAqIDIgKyAxKSAqIChrZXJuZWwgKiAyICsgMSk7XG5cbiAgICAvLyBjbGVhciBvdXQgdG9wICYgYm90dG9tLWJvcmRlclxuICAgIGZvciAoIHYgPSAwOyB2IDw9IGtlcm5lbDsgdisrKSB7XG4gICAgICAgIGZvciAoIHUgPSAwOyB1IDwgd2lkdGg7IHUrKykge1xuICAgICAgICAgICAgdGFyZ2V0RGF0YVsoKHYpICogd2lkdGgpICsgdV0gPSAwO1xuICAgICAgICAgICAgdGFyZ2V0RGF0YVsoKChoZWlnaHQgLSAxKSAtIHYpICogd2lkdGgpICsgdV0gPSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2xlYXIgb3V0IGxlZnQgJiByaWdodCBib3JkZXJcbiAgICBmb3IgKCB2ID0ga2VybmVsOyB2IDwgaGVpZ2h0IC0ga2VybmVsOyB2KyspIHtcbiAgICAgICAgZm9yICggdSA9IDA7IHUgPD0ga2VybmVsOyB1KyspIHtcbiAgICAgICAgICAgIHRhcmdldERhdGFbKCh2KSAqIHdpZHRoKSArIHVdID0gMDtcbiAgICAgICAgICAgIHRhcmdldERhdGFbKCh2KSAqIHdpZHRoKSArICh3aWR0aCAtIDEgLSB1KV0gPSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yICggdiA9IGtlcm5lbCArIDE7IHYgPCBoZWlnaHQgLSBrZXJuZWwgLSAxOyB2KyspIHtcbiAgICAgICAgZm9yICggdSA9IGtlcm5lbCArIDE7IHUgPCB3aWR0aCAtIGtlcm5lbDsgdSsrKSB7XG4gICAgICAgICAgICBBID0gaW50ZWdyYWxJbWFnZURhdGFbKHYgLSBrZXJuZWwgLSAxKSAqIHdpZHRoICsgKHUgLSBrZXJuZWwgLSAxKV07XG4gICAgICAgICAgICBCID0gaW50ZWdyYWxJbWFnZURhdGFbKHYgLSBrZXJuZWwgLSAxKSAqIHdpZHRoICsgKHUgKyBrZXJuZWwpXTtcbiAgICAgICAgICAgIEMgPSBpbnRlZ3JhbEltYWdlRGF0YVsodiArIGtlcm5lbCkgKiB3aWR0aCArICh1IC0ga2VybmVsIC0gMSldO1xuICAgICAgICAgICAgRCA9IGludGVncmFsSW1hZ2VEYXRhWyh2ICsga2VybmVsKSAqIHdpZHRoICsgKHUgKyBrZXJuZWwpXTtcbiAgICAgICAgICAgIHN1bSA9IEQgLSBDIC0gQiArIEE7XG4gICAgICAgICAgICBhdmcgPSBzdW0gLyAoc2l6ZSk7XG4gICAgICAgICAgICB0YXJnZXREYXRhW3YgKiB3aWR0aCArIHVdID0gaW1hZ2VEYXRhW3YgKiB3aWR0aCArIHVdID4gKGF2ZyArIDUpID8gMCA6IDE7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5DVlV0aWxzLmNsdXN0ZXIgPSBmdW5jdGlvbihwb2ludHMsIHRocmVzaG9sZCwgcHJvcGVydHkpIHtcbiAgICB2YXIgaSwgaywgY2x1c3RlciwgcG9pbnQsIGNsdXN0ZXJzID0gW107XG5cbiAgICBpZiAoIXByb3BlcnR5KSB7XG4gICAgICAgIHByb3BlcnR5ID0gXCJyYWRcIjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRUb0NsdXN0ZXIobmV3UG9pbnQpIHtcbiAgICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGZvciAoIGsgPSAwOyBrIDwgY2x1c3RlcnMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgIGNsdXN0ZXIgPSBjbHVzdGVyc1trXTtcbiAgICAgICAgICAgIGlmIChjbHVzdGVyLmZpdHMobmV3UG9pbnQpKSB7XG4gICAgICAgICAgICAgICAgY2x1c3Rlci5hZGQobmV3UG9pbnQpO1xuICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgfVxuXG4gICAgLy8gaXRlcmF0ZSBvdmVyIGVhY2ggY2xvdWRcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBwb2ludCA9IENsdXN0ZXIyLmNyZWF0ZVBvaW50KHBvaW50c1tpXSwgaSwgcHJvcGVydHkpO1xuICAgICAgICBpZiAoIWFkZFRvQ2x1c3Rlcihwb2ludCkpIHtcbiAgICAgICAgICAgIGNsdXN0ZXJzLnB1c2goQ2x1c3RlcjIuY3JlYXRlKHBvaW50LCB0aHJlc2hvbGQpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY2x1c3RlcnM7XG59O1xuXG5DVlV0aWxzLlRyYWNlciA9IHtcbiAgICB0cmFjZTogZnVuY3Rpb24ocG9pbnRzLCB2ZWMpIHtcbiAgICAgICAgdmFyIGl0ZXJhdGlvbiwgbWF4SXRlcmF0aW9ucyA9IDEwLCB0b3AgPSBbXSwgcmVzdWx0ID0gW10sIGNlbnRlclBvcyA9IDAsIGN1cnJlbnRQb3MgPSAwO1xuXG4gICAgICAgIGZ1bmN0aW9uIHRyYWNlKGlkeCwgZm9yd2FyZCkge1xuICAgICAgICAgICAgdmFyIGZyb20sIHRvLCB0b0lkeCwgcHJlZGljdGVkUG9zLCB0aHJlc2hvbGRYID0gMSwgdGhyZXNob2xkWSA9IE1hdGguYWJzKHZlY1sxXSAvIDEwKSwgZm91bmQgPSBmYWxzZTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gbWF0Y2gocG9zLCBwcmVkaWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAocG9zLnggPiAocHJlZGljdGVkLnggLSB0aHJlc2hvbGRYKVxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgcG9zLnggPCAocHJlZGljdGVkLnggKyB0aHJlc2hvbGRYKVxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgcG9zLnkgPiAocHJlZGljdGVkLnkgLSB0aHJlc2hvbGRZKVxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgcG9zLnkgPCAocHJlZGljdGVkLnkgKyB0aHJlc2hvbGRZKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjaGVjayBpZiB0aGUgbmV4dCBpbmRleCBpcyB3aXRoaW4gdGhlIHZlYyBzcGVjaWZpY2F0aW9uc1xuICAgICAgICAgICAgLy8gaWYgbm90LCBjaGVjayBhcyBsb25nIGFzIHRoZSB0aHJlc2hvbGQgaXMgbWV0XG5cbiAgICAgICAgICAgIGZyb20gPSBwb2ludHNbaWR4XTtcbiAgICAgICAgICAgIGlmIChmb3J3YXJkKSB7XG4gICAgICAgICAgICAgICAgcHJlZGljdGVkUG9zID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiBmcm9tLnggKyB2ZWNbMF0sXG4gICAgICAgICAgICAgICAgICAgIHk6IGZyb20ueSArIHZlY1sxXVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZWRpY3RlZFBvcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogZnJvbS54IC0gdmVjWzBdLFxuICAgICAgICAgICAgICAgICAgICB5OiBmcm9tLnkgLSB2ZWNbMV1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0b0lkeCA9IGZvcndhcmQgPyBpZHggKyAxIDogaWR4IC0gMTtcbiAgICAgICAgICAgIHRvID0gcG9pbnRzW3RvSWR4XTtcbiAgICAgICAgICAgIHdoaWxlICh0byAmJiAoIGZvdW5kID0gbWF0Y2godG8sIHByZWRpY3RlZFBvcykpICE9PSB0cnVlICYmIChNYXRoLmFicyh0by55IC0gZnJvbS55KSA8IHZlY1sxXSkpIHtcbiAgICAgICAgICAgICAgICB0b0lkeCA9IGZvcndhcmQgPyB0b0lkeCArIDEgOiB0b0lkeCAtIDE7XG4gICAgICAgICAgICAgICAgdG8gPSBwb2ludHNbdG9JZHhdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZm91bmQgPyB0b0lkeCA6IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKCBpdGVyYXRpb24gPSAwOyBpdGVyYXRpb24gPCBtYXhJdGVyYXRpb25zOyBpdGVyYXRpb24rKykge1xuICAgICAgICAgICAgLy8gcmFuZG9tbHkgc2VsZWN0IHBvaW50IHRvIHN0YXJ0IHdpdGhcbiAgICAgICAgICAgIGNlbnRlclBvcyA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvaW50cy5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyB0cmFjZSBmb3J3YXJkXG4gICAgICAgICAgICB0b3AgPSBbXTtcbiAgICAgICAgICAgIGN1cnJlbnRQb3MgPSBjZW50ZXJQb3M7XG4gICAgICAgICAgICB0b3AucHVzaChwb2ludHNbY3VycmVudFBvc10pO1xuICAgICAgICAgICAgd2hpbGUgKCggY3VycmVudFBvcyA9IHRyYWNlKGN1cnJlbnRQb3MsIHRydWUpKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRvcC5wdXNoKHBvaW50c1tjdXJyZW50UG9zXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2VudGVyUG9zID4gMCkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRQb3MgPSBjZW50ZXJQb3M7XG4gICAgICAgICAgICAgICAgd2hpbGUgKCggY3VycmVudFBvcyA9IHRyYWNlKGN1cnJlbnRQb3MsIGZhbHNlKSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9wLnB1c2gocG9pbnRzW2N1cnJlbnRQb3NdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0b3AubGVuZ3RoID4gcmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRvcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn07XG5cbkNWVXRpbHMuRElMQVRFID0gMTtcbkNWVXRpbHMuRVJPREUgPSAyO1xuXG5DVlV0aWxzLmRpbGF0ZSA9IGZ1bmN0aW9uKGluSW1hZ2VXcmFwcGVyLCBvdXRJbWFnZVdyYXBwZXIpIHtcbiAgICB2YXIgdixcbiAgICAgICAgdSxcbiAgICAgICAgaW5JbWFnZURhdGEgPSBpbkltYWdlV3JhcHBlci5kYXRhLFxuICAgICAgICBvdXRJbWFnZURhdGEgPSBvdXRJbWFnZVdyYXBwZXIuZGF0YSxcbiAgICAgICAgaGVpZ2h0ID0gaW5JbWFnZVdyYXBwZXIuc2l6ZS55LFxuICAgICAgICB3aWR0aCA9IGluSW1hZ2VXcmFwcGVyLnNpemUueCxcbiAgICAgICAgc3VtLFxuICAgICAgICB5U3RhcnQxLFxuICAgICAgICB5U3RhcnQyLFxuICAgICAgICB4U3RhcnQxLFxuICAgICAgICB4U3RhcnQyO1xuXG4gICAgZm9yICggdiA9IDE7IHYgPCBoZWlnaHQgLSAxOyB2KyspIHtcbiAgICAgICAgZm9yICggdSA9IDE7IHUgPCB3aWR0aCAtIDE7IHUrKykge1xuICAgICAgICAgICAgeVN0YXJ0MSA9IHYgLSAxO1xuICAgICAgICAgICAgeVN0YXJ0MiA9IHYgKyAxO1xuICAgICAgICAgICAgeFN0YXJ0MSA9IHUgLSAxO1xuICAgICAgICAgICAgeFN0YXJ0MiA9IHUgKyAxO1xuICAgICAgICAgICAgc3VtID0gaW5JbWFnZURhdGFbeVN0YXJ0MSAqIHdpZHRoICsgeFN0YXJ0MV0gKyBpbkltYWdlRGF0YVt5U3RhcnQxICogd2lkdGggKyB4U3RhcnQyXSArXG4gICAgICAgICAgICBpbkltYWdlRGF0YVt2ICogd2lkdGggKyB1XSArXG4gICAgICAgICAgICBpbkltYWdlRGF0YVt5U3RhcnQyICogd2lkdGggKyB4U3RhcnQxXSArIGluSW1hZ2VEYXRhW3lTdGFydDIgKiB3aWR0aCArIHhTdGFydDJdO1xuICAgICAgICAgICAgb3V0SW1hZ2VEYXRhW3YgKiB3aWR0aCArIHVdID0gc3VtID4gMCA/IDEgOiAwO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuQ1ZVdGlscy5lcm9kZSA9IGZ1bmN0aW9uKGluSW1hZ2VXcmFwcGVyLCBvdXRJbWFnZVdyYXBwZXIpIHtcbiAgICB2YXIgdixcbiAgICAgICAgdSxcbiAgICAgICAgaW5JbWFnZURhdGEgPSBpbkltYWdlV3JhcHBlci5kYXRhLFxuICAgICAgICBvdXRJbWFnZURhdGEgPSBvdXRJbWFnZVdyYXBwZXIuZGF0YSxcbiAgICAgICAgaGVpZ2h0ID0gaW5JbWFnZVdyYXBwZXIuc2l6ZS55LFxuICAgICAgICB3aWR0aCA9IGluSW1hZ2VXcmFwcGVyLnNpemUueCxcbiAgICAgICAgc3VtLFxuICAgICAgICB5U3RhcnQxLFxuICAgICAgICB5U3RhcnQyLFxuICAgICAgICB4U3RhcnQxLFxuICAgICAgICB4U3RhcnQyO1xuXG4gICAgZm9yICggdiA9IDE7IHYgPCBoZWlnaHQgLSAxOyB2KyspIHtcbiAgICAgICAgZm9yICggdSA9IDE7IHUgPCB3aWR0aCAtIDE7IHUrKykge1xuICAgICAgICAgICAgeVN0YXJ0MSA9IHYgLSAxO1xuICAgICAgICAgICAgeVN0YXJ0MiA9IHYgKyAxO1xuICAgICAgICAgICAgeFN0YXJ0MSA9IHUgLSAxO1xuICAgICAgICAgICAgeFN0YXJ0MiA9IHUgKyAxO1xuICAgICAgICAgICAgc3VtID0gaW5JbWFnZURhdGFbeVN0YXJ0MSAqIHdpZHRoICsgeFN0YXJ0MV0gKyBpbkltYWdlRGF0YVt5U3RhcnQxICogd2lkdGggKyB4U3RhcnQyXSArXG4gICAgICAgICAgICBpbkltYWdlRGF0YVt2ICogd2lkdGggKyB1XSArXG4gICAgICAgICAgICBpbkltYWdlRGF0YVt5U3RhcnQyICogd2lkdGggKyB4U3RhcnQxXSArIGluSW1hZ2VEYXRhW3lTdGFydDIgKiB3aWR0aCArIHhTdGFydDJdO1xuICAgICAgICAgICAgb3V0SW1hZ2VEYXRhW3YgKiB3aWR0aCArIHVdID0gc3VtID09PSA1ID8gMSA6IDA7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5DVlV0aWxzLnN1YnRyYWN0ID0gZnVuY3Rpb24oYUltYWdlV3JhcHBlciwgYkltYWdlV3JhcHBlciwgcmVzdWx0SW1hZ2VXcmFwcGVyKSB7XG4gICAgaWYgKCFyZXN1bHRJbWFnZVdyYXBwZXIpIHtcbiAgICAgICAgcmVzdWx0SW1hZ2VXcmFwcGVyID0gYUltYWdlV3JhcHBlcjtcbiAgICB9XG4gICAgdmFyIGxlbmd0aCA9IGFJbWFnZVdyYXBwZXIuZGF0YS5sZW5ndGgsXG4gICAgICAgIGFJbWFnZURhdGEgPSBhSW1hZ2VXcmFwcGVyLmRhdGEsXG4gICAgICAgIGJJbWFnZURhdGEgPSBiSW1hZ2VXcmFwcGVyLmRhdGEsXG4gICAgICAgIGNJbWFnZURhdGEgPSByZXN1bHRJbWFnZVdyYXBwZXIuZGF0YTtcblxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICBjSW1hZ2VEYXRhW2xlbmd0aF0gPSBhSW1hZ2VEYXRhW2xlbmd0aF0gLSBiSW1hZ2VEYXRhW2xlbmd0aF07XG4gICAgfVxufTtcblxuQ1ZVdGlscy5iaXR3aXNlT3IgPSBmdW5jdGlvbihhSW1hZ2VXcmFwcGVyLCBiSW1hZ2VXcmFwcGVyLCByZXN1bHRJbWFnZVdyYXBwZXIpIHtcbiAgICBpZiAoIXJlc3VsdEltYWdlV3JhcHBlcikge1xuICAgICAgICByZXN1bHRJbWFnZVdyYXBwZXIgPSBhSW1hZ2VXcmFwcGVyO1xuICAgIH1cbiAgICB2YXIgbGVuZ3RoID0gYUltYWdlV3JhcHBlci5kYXRhLmxlbmd0aCxcbiAgICAgICAgYUltYWdlRGF0YSA9IGFJbWFnZVdyYXBwZXIuZGF0YSxcbiAgICAgICAgYkltYWdlRGF0YSA9IGJJbWFnZVdyYXBwZXIuZGF0YSxcbiAgICAgICAgY0ltYWdlRGF0YSA9IHJlc3VsdEltYWdlV3JhcHBlci5kYXRhO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGNJbWFnZURhdGFbbGVuZ3RoXSA9IGFJbWFnZURhdGFbbGVuZ3RoXSB8fCBiSW1hZ2VEYXRhW2xlbmd0aF07XG4gICAgfVxufTtcblxuQ1ZVdGlscy5jb3VudE5vblplcm8gPSBmdW5jdGlvbihpbWFnZVdyYXBwZXIpIHtcbiAgICB2YXIgbGVuZ3RoID0gaW1hZ2VXcmFwcGVyLmRhdGEubGVuZ3RoLCBkYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGEsIHN1bSA9IDA7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgc3VtICs9IGRhdGFbbGVuZ3RoXTtcbiAgICB9XG4gICAgcmV0dXJuIHN1bTtcbn07XG5cbkNWVXRpbHMudG9wR2VuZXJpYyA9IGZ1bmN0aW9uKGxpc3QsIHRvcCwgc2NvcmVGdW5jKSB7XG4gICAgdmFyIGksIG1pbklkeCA9IDAsIG1pbiA9IDAsIHF1ZXVlID0gW10sIHNjb3JlLCBoaXQsIHBvcztcblxuICAgIGZvciAoIGkgPSAwOyBpIDwgdG9wOyBpKyspIHtcbiAgICAgICAgcXVldWVbaV0gPSB7XG4gICAgICAgICAgICBzY29yZTogMCxcbiAgICAgICAgICAgIGl0ZW06IG51bGxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKCBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2NvcmUgPSBzY29yZUZ1bmMuYXBwbHkodGhpcywgW2xpc3RbaV1dKTtcbiAgICAgICAgaWYgKHNjb3JlID4gbWluKSB7XG4gICAgICAgICAgICBoaXQgPSBxdWV1ZVttaW5JZHhdO1xuICAgICAgICAgICAgaGl0LnNjb3JlID0gc2NvcmU7XG4gICAgICAgICAgICBoaXQuaXRlbSA9IGxpc3RbaV07XG4gICAgICAgICAgICBtaW4gPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICAgICAgICAgICAgZm9yICggcG9zID0gMDsgcG9zIDwgdG9wOyBwb3MrKykge1xuICAgICAgICAgICAgICAgIGlmIChxdWV1ZVtwb3NdLnNjb3JlIDwgbWluKSB7XG4gICAgICAgICAgICAgICAgICAgIG1pbiA9IHF1ZXVlW3Bvc10uc2NvcmU7XG4gICAgICAgICAgICAgICAgICAgIG1pbklkeCA9IHBvcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcXVldWU7XG59O1xuXG5DVlV0aWxzLmdyYXlBcnJheUZyb21JbWFnZSA9IGZ1bmN0aW9uKGh0bWxJbWFnZSwgb2Zmc2V0WCwgY3R4LCBhcnJheSkge1xuICAgIGN0eC5kcmF3SW1hZ2UoaHRtbEltYWdlLCBvZmZzZXRYLCAwLCBodG1sSW1hZ2Uud2lkdGgsIGh0bWxJbWFnZS5oZWlnaHQpO1xuICAgIHZhciBjdHhEYXRhID0gY3R4LmdldEltYWdlRGF0YShvZmZzZXRYLCAwLCBodG1sSW1hZ2Uud2lkdGgsIGh0bWxJbWFnZS5oZWlnaHQpLmRhdGE7XG4gICAgQ1ZVdGlscy5jb21wdXRlR3JheShjdHhEYXRhLCBhcnJheSk7XG59O1xuXG5DVlV0aWxzLmdyYXlBcnJheUZyb21Db250ZXh0ID0gZnVuY3Rpb24oY3R4LCBzaXplLCBvZmZzZXQsIGFycmF5KSB7XG4gICAgdmFyIGN0eERhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKG9mZnNldC54LCBvZmZzZXQueSwgc2l6ZS54LCBzaXplLnkpLmRhdGE7XG4gICAgQ1ZVdGlscy5jb21wdXRlR3JheShjdHhEYXRhLCBhcnJheSk7XG59O1xuXG5DVlV0aWxzLmdyYXlBbmRIYWxmU2FtcGxlRnJvbUNhbnZhc0RhdGEgPSBmdW5jdGlvbihjYW52YXNEYXRhLCBzaXplLCBvdXRBcnJheSkge1xuICAgIHZhciB0b3BSb3dJZHggPSAwO1xuICAgIHZhciBib3R0b21Sb3dJZHggPSBzaXplLng7XG4gICAgdmFyIGVuZElkeCA9IE1hdGguZmxvb3IoY2FudmFzRGF0YS5sZW5ndGggLyA0KTtcbiAgICB2YXIgb3V0V2lkdGggPSBzaXplLnggLyAyO1xuICAgIHZhciBvdXRJbWdJZHggPSAwO1xuICAgIHZhciBpbldpZHRoID0gc2l6ZS54O1xuICAgIHZhciBpO1xuXG4gICAgd2hpbGUgKGJvdHRvbVJvd0lkeCA8IGVuZElkeCkge1xuICAgICAgICBmb3IgKCBpID0gMDsgaSA8IG91dFdpZHRoOyBpKyspIHtcbiAgICAgICAgICAgIG91dEFycmF5W291dEltZ0lkeF0gPSBNYXRoLmZsb29yKChcbiAgICAgICAgICAgICAgICAoMC4yOTkgKiBjYW52YXNEYXRhW3RvcFJvd0lkeCAqIDQgKyAwXSArXG4gICAgICAgICAgICAgICAgIDAuNTg3ICogY2FudmFzRGF0YVt0b3BSb3dJZHggKiA0ICsgMV0gK1xuICAgICAgICAgICAgICAgICAwLjExNCAqIGNhbnZhc0RhdGFbdG9wUm93SWR4ICogNCArIDJdKSArXG4gICAgICAgICAgICAgICAgKDAuMjk5ICogY2FudmFzRGF0YVsodG9wUm93SWR4ICsgMSkgKiA0ICsgMF0gK1xuICAgICAgICAgICAgICAgICAwLjU4NyAqIGNhbnZhc0RhdGFbKHRvcFJvd0lkeCArIDEpICogNCArIDFdICtcbiAgICAgICAgICAgICAgICAgMC4xMTQgKiBjYW52YXNEYXRhWyh0b3BSb3dJZHggKyAxKSAqIDQgKyAyXSkgK1xuICAgICAgICAgICAgICAgICgwLjI5OSAqIGNhbnZhc0RhdGFbKGJvdHRvbVJvd0lkeCkgKiA0ICsgMF0gK1xuICAgICAgICAgICAgICAgICAwLjU4NyAqIGNhbnZhc0RhdGFbKGJvdHRvbVJvd0lkeCkgKiA0ICsgMV0gK1xuICAgICAgICAgICAgICAgICAwLjExNCAqIGNhbnZhc0RhdGFbKGJvdHRvbVJvd0lkeCkgKiA0ICsgMl0pICtcbiAgICAgICAgICAgICAgICAoMC4yOTkgKiBjYW52YXNEYXRhWyhib3R0b21Sb3dJZHggKyAxKSAqIDQgKyAwXSArXG4gICAgICAgICAgICAgICAgIDAuNTg3ICogY2FudmFzRGF0YVsoYm90dG9tUm93SWR4ICsgMSkgKiA0ICsgMV0gK1xuICAgICAgICAgICAgICAgICAwLjExNCAqIGNhbnZhc0RhdGFbKGJvdHRvbVJvd0lkeCArIDEpICogNCArIDJdKSkgLyA0KTtcbiAgICAgICAgICAgIG91dEltZ0lkeCsrO1xuICAgICAgICAgICAgdG9wUm93SWR4ID0gdG9wUm93SWR4ICsgMjtcbiAgICAgICAgICAgIGJvdHRvbVJvd0lkeCA9IGJvdHRvbVJvd0lkeCArIDI7XG4gICAgICAgIH1cbiAgICAgICAgdG9wUm93SWR4ID0gdG9wUm93SWR4ICsgaW5XaWR0aDtcbiAgICAgICAgYm90dG9tUm93SWR4ID0gYm90dG9tUm93SWR4ICsgaW5XaWR0aDtcbiAgICB9XG59O1xuXG5DVlV0aWxzLmNvbXB1dGVHcmF5ID0gZnVuY3Rpb24oaW1hZ2VEYXRhLCBvdXRBcnJheSwgY29uZmlnKSB7XG4gICAgdmFyIGwgPSAoaW1hZ2VEYXRhLmxlbmd0aCAvIDQpIHwgMCxcbiAgICAgICAgaSxcbiAgICAgICAgc2luZ2xlQ2hhbm5lbCA9IGNvbmZpZyAmJiBjb25maWcuc2luZ2xlQ2hhbm5lbCA9PT0gdHJ1ZTtcblxuICAgIGlmIChzaW5nbGVDaGFubmVsKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIG91dEFycmF5W2ldID0gaW1hZ2VEYXRhW2kgKiA0ICsgMF07XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBvdXRBcnJheVtpXSA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgICAgICAgMC4yOTkgKiBpbWFnZURhdGFbaSAqIDQgKyAwXSArIDAuNTg3ICogaW1hZ2VEYXRhW2kgKiA0ICsgMV0gKyAwLjExNCAqIGltYWdlRGF0YVtpICogNCArIDJdKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbkNWVXRpbHMubG9hZEltYWdlQXJyYXkgPSBmdW5jdGlvbihzcmMsIGNhbGxiYWNrLCBjYW52YXMpIHtcbiAgICBpZiAoIWNhbnZhcykge1xuICAgICAgICBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB9XG4gICAgdmFyIGltZyA9IG5ldyBJbWFnZSgpO1xuICAgIGltZy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIGltZy5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgY2FudmFzLndpZHRoID0gdGhpcy53aWR0aDtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcywgMCwgMCk7XG4gICAgICAgIHZhciBhcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMud2lkdGggKiB0aGlzLmhlaWdodCk7XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcywgMCwgMCk7XG4gICAgICAgIHZhciBkYXRhID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkuZGF0YTtcbiAgICAgICAgQ1ZVdGlscy5jb21wdXRlR3JheShkYXRhLCBhcnJheSk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2soYXJyYXksIHtcbiAgICAgICAgICAgIHg6IHRoaXMud2lkdGgsXG4gICAgICAgICAgICB5OiB0aGlzLmhlaWdodFxuICAgICAgICB9LCB0aGlzKTtcbiAgICB9O1xuICAgIGltZy5zcmMgPSBzcmM7XG59O1xuXG4vKipcbiAqIEBwYXJhbSBpbkltZyB7SW1hZ2VXcmFwcGVyfSBpbnB1dCBpbWFnZSB0byBiZSBzYW1wbGVkXG4gKiBAcGFyYW0gb3V0SW1nIHtJbWFnZVdyYXBwZXJ9IHRvIGJlIHN0b3JlZCBpblxuICovXG5DVlV0aWxzLmhhbGZTYW1wbGUgPSBmdW5jdGlvbihpbkltZ1dyYXBwZXIsIG91dEltZ1dyYXBwZXIpIHtcbiAgICB2YXIgaW5JbWcgPSBpbkltZ1dyYXBwZXIuZGF0YTtcbiAgICB2YXIgaW5XaWR0aCA9IGluSW1nV3JhcHBlci5zaXplLng7XG4gICAgdmFyIG91dEltZyA9IG91dEltZ1dyYXBwZXIuZGF0YTtcbiAgICB2YXIgdG9wUm93SWR4ID0gMDtcbiAgICB2YXIgYm90dG9tUm93SWR4ID0gaW5XaWR0aDtcbiAgICB2YXIgZW5kSWR4ID0gaW5JbWcubGVuZ3RoO1xuICAgIHZhciBvdXRXaWR0aCA9IGluV2lkdGggLyAyO1xuICAgIHZhciBvdXRJbWdJZHggPSAwO1xuICAgIHdoaWxlIChib3R0b21Sb3dJZHggPCBlbmRJZHgpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXRXaWR0aDsgaSsrKSB7XG4gICAgICAgICAgICBvdXRJbWdbb3V0SW1nSWR4XSA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgICAgICAgKGluSW1nW3RvcFJvd0lkeF0gKyBpbkltZ1t0b3BSb3dJZHggKyAxXSArIGluSW1nW2JvdHRvbVJvd0lkeF0gKyBpbkltZ1tib3R0b21Sb3dJZHggKyAxXSkgLyA0KTtcbiAgICAgICAgICAgIG91dEltZ0lkeCsrO1xuICAgICAgICAgICAgdG9wUm93SWR4ID0gdG9wUm93SWR4ICsgMjtcbiAgICAgICAgICAgIGJvdHRvbVJvd0lkeCA9IGJvdHRvbVJvd0lkeCArIDI7XG4gICAgICAgIH1cbiAgICAgICAgdG9wUm93SWR4ID0gdG9wUm93SWR4ICsgaW5XaWR0aDtcbiAgICAgICAgYm90dG9tUm93SWR4ID0gYm90dG9tUm93SWR4ICsgaW5XaWR0aDtcbiAgICB9XG59O1xuXG5DVlV0aWxzLmhzdjJyZ2IgPSBmdW5jdGlvbihoc3YsIHJnYikge1xuICAgIHZhciBoID0gaHN2WzBdLFxuICAgICAgICBzID0gaHN2WzFdLFxuICAgICAgICB2ID0gaHN2WzJdLFxuICAgICAgICBjID0gdiAqIHMsXG4gICAgICAgIHggPSBjICogKDEgLSBNYXRoLmFicygoaCAvIDYwKSAlIDIgLSAxKSksXG4gICAgICAgIG0gPSB2IC0gYyxcbiAgICAgICAgciA9IDAsXG4gICAgICAgIGcgPSAwLFxuICAgICAgICBiID0gMDtcblxuICAgIHJnYiA9IHJnYiB8fCBbMCwgMCwgMF07XG5cbiAgICBpZiAoaCA8IDYwKSB7XG4gICAgICAgIHIgPSBjO1xuICAgICAgICBnID0geDtcbiAgICB9IGVsc2UgaWYgKGggPCAxMjApIHtcbiAgICAgICAgciA9IHg7XG4gICAgICAgIGcgPSBjO1xuICAgIH0gZWxzZSBpZiAoaCA8IDE4MCkge1xuICAgICAgICBnID0gYztcbiAgICAgICAgYiA9IHg7XG4gICAgfSBlbHNlIGlmIChoIDwgMjQwKSB7XG4gICAgICAgIGcgPSB4O1xuICAgICAgICBiID0gYztcbiAgICB9IGVsc2UgaWYgKGggPCAzMDApIHtcbiAgICAgICAgciA9IHg7XG4gICAgICAgIGIgPSBjO1xuICAgIH0gZWxzZSBpZiAoaCA8IDM2MCkge1xuICAgICAgICByID0gYztcbiAgICAgICAgYiA9IHg7XG4gICAgfVxuICAgIHJnYlswXSA9ICgociArIG0pICogMjU1KSB8IDA7XG4gICAgcmdiWzFdID0gKChnICsgbSkgKiAyNTUpIHwgMDtcbiAgICByZ2JbMl0gPSAoKGIgKyBtKSAqIDI1NSkgfCAwO1xuICAgIHJldHVybiByZ2I7XG59O1xuXG5DVlV0aWxzLl9jb21wdXRlRGl2aXNvcnMgPSBmdW5jdGlvbihuKSB7XG4gICAgdmFyIGxhcmdlRGl2aXNvcnMgPSBbXSxcbiAgICAgICAgZGl2aXNvcnMgPSBbXSxcbiAgICAgICAgaTtcblxuICAgIGZvciAoaSA9IDE7IGkgPCBNYXRoLnNxcnQobikgKyAxOyBpKyspIHtcbiAgICAgICAgaWYgKG4gJSBpID09PSAwKSB7XG4gICAgICAgICAgICBkaXZpc29ycy5wdXNoKGkpO1xuICAgICAgICAgICAgaWYgKGkgIT09IG4gLyBpKSB7XG4gICAgICAgICAgICAgICAgbGFyZ2VEaXZpc29ycy51bnNoaWZ0KE1hdGguZmxvb3IobiAvIGkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGl2aXNvcnMuY29uY2F0KGxhcmdlRGl2aXNvcnMpO1xufTtcblxuQ1ZVdGlscy5fY29tcHV0ZUludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKGFycjEsIGFycjIpIHtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIGogPSAwLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlIChpIDwgYXJyMS5sZW5ndGggJiYgaiA8IGFycjIubGVuZ3RoKSB7XG4gICAgICAgIGlmIChhcnIxW2ldID09PSBhcnIyW2pdKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChhcnIxW2ldKTtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIGorKztcbiAgICAgICAgfSBlbHNlIGlmIChhcnIxW2ldID4gYXJyMltqXSkge1xuICAgICAgICAgICAgaisrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5DVlV0aWxzLmNhbGN1bGF0ZVBhdGNoU2l6ZSA9IGZ1bmN0aW9uKHBhdGNoU2l6ZSwgaW1nU2l6ZSkge1xuICAgIHZhciBkaXZpc29yc1ggPSB0aGlzLl9jb21wdXRlRGl2aXNvcnMoaW1nU2l6ZS54KSxcbiAgICAgICAgZGl2aXNvcnNZID0gdGhpcy5fY29tcHV0ZURpdmlzb3JzKGltZ1NpemUueSksXG4gICAgICAgIHdpZGVTaWRlID0gTWF0aC5tYXgoaW1nU2l6ZS54LCBpbWdTaXplLnkpLFxuICAgICAgICBjb21tb24gPSB0aGlzLl9jb21wdXRlSW50ZXJzZWN0aW9uKGRpdmlzb3JzWCwgZGl2aXNvcnNZKSxcbiAgICAgICAgbnJPZlBhdGNoZXNMaXN0ID0gWzgsIDEwLCAxNSwgMjAsIDMyLCA2MCwgODBdLFxuICAgICAgICBuck9mUGF0Y2hlc01hcCA9IHtcbiAgICAgICAgICAgIFwieC1zbWFsbFwiOiA1LFxuICAgICAgICAgICAgXCJzbWFsbFwiOiA0LFxuICAgICAgICAgICAgXCJtZWRpdW1cIjogMyxcbiAgICAgICAgICAgIFwibGFyZ2VcIjogMixcbiAgICAgICAgICAgIFwieC1sYXJnZVwiOiAxXG4gICAgICAgIH0sXG4gICAgICAgIG5yT2ZQYXRjaGVzSWR4ID0gbnJPZlBhdGNoZXNNYXBbcGF0Y2hTaXplXSB8fCBuck9mUGF0Y2hlc01hcC5tZWRpdW0sXG4gICAgICAgIG5yT2ZQYXRjaGVzID0gbnJPZlBhdGNoZXNMaXN0W25yT2ZQYXRjaGVzSWR4XSxcbiAgICAgICAgZGVzaXJlZFBhdGNoU2l6ZSA9IE1hdGguZmxvb3Iod2lkZVNpZGUgLyBuck9mUGF0Y2hlcyksXG4gICAgICAgIG9wdGltYWxQYXRjaFNpemU7XG5cbiAgICBmdW5jdGlvbiBmaW5kUGF0Y2hTaXplRm9yRGl2aXNvcnMoZGl2aXNvcnMpIHtcbiAgICAgICAgdmFyIGkgPSAwLFxuICAgICAgICAgICAgZm91bmQgPSBkaXZpc29yc1tNYXRoLmZsb29yKGRpdmlzb3JzLmxlbmd0aCAvIDIpXTtcblxuICAgICAgICB3aGlsZSAoaSA8IChkaXZpc29ycy5sZW5ndGggLSAxKSAmJiBkaXZpc29yc1tpXSA8IGRlc2lyZWRQYXRjaFNpemUpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkaXZpc29yc1tpXSAtIGRlc2lyZWRQYXRjaFNpemUpID4gTWF0aC5hYnMoZGl2aXNvcnNbaSAtIDFdIC0gZGVzaXJlZFBhdGNoU2l6ZSkpIHtcbiAgICAgICAgICAgICAgICBmb3VuZCA9IGRpdmlzb3JzW2kgLSAxXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm91bmQgPSBkaXZpc29yc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzaXJlZFBhdGNoU2l6ZSAvIGZvdW5kIDwgbnJPZlBhdGNoZXNMaXN0W25yT2ZQYXRjaGVzSWR4ICsgMV0gLyBuck9mUGF0Y2hlc0xpc3RbbnJPZlBhdGNoZXNJZHhdICYmXG4gICAgICAgICAgICBkZXNpcmVkUGF0Y2hTaXplIC8gZm91bmQgPiBuck9mUGF0Y2hlc0xpc3RbbnJPZlBhdGNoZXNJZHggLSAxXSAvIG5yT2ZQYXRjaGVzTGlzdFtuck9mUGF0Y2hlc0lkeF0gKSB7XG4gICAgICAgICAgICByZXR1cm4ge3g6IGZvdW5kLCB5OiBmb3VuZH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgb3B0aW1hbFBhdGNoU2l6ZSA9IGZpbmRQYXRjaFNpemVGb3JEaXZpc29ycyhjb21tb24pO1xuICAgIGlmICghb3B0aW1hbFBhdGNoU2l6ZSkge1xuICAgICAgICBvcHRpbWFsUGF0Y2hTaXplID0gZmluZFBhdGNoU2l6ZUZvckRpdmlzb3JzKHRoaXMuX2NvbXB1dGVEaXZpc29ycyh3aWRlU2lkZSkpO1xuICAgICAgICBpZiAoIW9wdGltYWxQYXRjaFNpemUpIHtcbiAgICAgICAgICAgIG9wdGltYWxQYXRjaFNpemUgPSBmaW5kUGF0Y2hTaXplRm9yRGl2aXNvcnMoKHRoaXMuX2NvbXB1dGVEaXZpc29ycyhkZXNpcmVkUGF0Y2hTaXplICogbnJPZlBhdGNoZXMpKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9wdGltYWxQYXRjaFNpemU7XG59O1xuXG5DVlV0aWxzLl9wYXJzZUNTU0RpbWVuc2lvblZhbHVlcyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIGRpbWVuc2lvbiA9IHtcbiAgICAgICAgdmFsdWU6IHBhcnNlRmxvYXQodmFsdWUpLFxuICAgICAgICB1bml0OiB2YWx1ZS5pbmRleE9mKFwiJVwiKSA9PT0gdmFsdWUubGVuZ3RoIC0gMSA/IFwiJVwiIDogXCIlXCJcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRpbWVuc2lvbjtcbn07XG5cbkNWVXRpbHMuX2RpbWVuc2lvbnNDb252ZXJ0ZXJzID0ge1xuICAgIHRvcDogZnVuY3Rpb24oZGltZW5zaW9uLCBjb250ZXh0KSB7XG4gICAgICAgIGlmIChkaW1lbnNpb24udW5pdCA9PT0gXCIlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKGNvbnRleHQuaGVpZ2h0ICogKGRpbWVuc2lvbi52YWx1ZSAvIDEwMCkpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICByaWdodDogZnVuY3Rpb24oZGltZW5zaW9uLCBjb250ZXh0KSB7XG4gICAgICAgIGlmIChkaW1lbnNpb24udW5pdCA9PT0gXCIlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKGNvbnRleHQud2lkdGggLSAoY29udGV4dC53aWR0aCAqIChkaW1lbnNpb24udmFsdWUgLyAxMDApKSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGJvdHRvbTogZnVuY3Rpb24oZGltZW5zaW9uLCBjb250ZXh0KSB7XG4gICAgICAgIGlmIChkaW1lbnNpb24udW5pdCA9PT0gXCIlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKGNvbnRleHQuaGVpZ2h0IC0gKGNvbnRleHQuaGVpZ2h0ICogKGRpbWVuc2lvbi52YWx1ZSAvIDEwMCkpKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgbGVmdDogZnVuY3Rpb24oZGltZW5zaW9uLCBjb250ZXh0KSB7XG4gICAgICAgIGlmIChkaW1lbnNpb24udW5pdCA9PT0gXCIlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKGNvbnRleHQud2lkdGggKiAoZGltZW5zaW9uLnZhbHVlIC8gMTAwKSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5DVlV0aWxzLmNvbXB1dGVJbWFnZUFyZWEgPSBmdW5jdGlvbihpbnB1dFdpZHRoLCBpbnB1dEhlaWdodCwgYXJlYSkge1xuICAgIHZhciBjb250ZXh0ID0ge3dpZHRoOiBpbnB1dFdpZHRoLCBoZWlnaHQ6IGlucHV0SGVpZ2h0fTtcblxuICAgIHZhciBwYXJzZWRBcmVhID0gT2JqZWN0LmtleXMoYXJlYSkucmVkdWNlKGZ1bmN0aW9uKHJlc3VsdCwga2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFyZWFba2V5XSxcbiAgICAgICAgICAgIHBhcnNlZCA9IENWVXRpbHMuX3BhcnNlQ1NTRGltZW5zaW9uVmFsdWVzKHZhbHVlKSxcbiAgICAgICAgICAgIGNhbGN1bGF0ZWQgPSBDVlV0aWxzLl9kaW1lbnNpb25zQ29udmVydGVyc1trZXldKHBhcnNlZCwgY29udGV4dCk7XG5cbiAgICAgICAgcmVzdWx0W2tleV0gPSBjYWxjdWxhdGVkO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sIHt9KTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIHN4OiBwYXJzZWRBcmVhLmxlZnQsXG4gICAgICAgIHN5OiBwYXJzZWRBcmVhLnRvcCxcbiAgICAgICAgc3c6IHBhcnNlZEFyZWEucmlnaHQgLSBwYXJzZWRBcmVhLmxlZnQsXG4gICAgICAgIHNoOiBwYXJzZWRBcmVhLmJvdHRvbSAtIHBhcnNlZEFyZWEudG9wXG4gICAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IENWVXRpbHM7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jdl91dGlscy5qc1xuICoqLyIsImltcG9ydCB7dmVjMn0gZnJvbSAnZ2wtbWF0cml4JztcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2x1c3RlciBmb3IgZ3JvdXBpbmcgc2ltaWxhciBvcmllbnRhdGlvbnMgb2YgZGF0YXBvaW50c1xuICAgICAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICAgIGNyZWF0ZTogZnVuY3Rpb24ocG9pbnQsIHRocmVzaG9sZCkge1xuICAgICAgICB2YXIgcG9pbnRzID0gW10sXG4gICAgICAgICAgICBjZW50ZXIgPSB7XG4gICAgICAgICAgICAgICAgcmFkOiAwLFxuICAgICAgICAgICAgICAgIHZlYzogdmVjMi5jbG9uZShbMCwgMF0pXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcG9pbnRNYXAgPSB7fTtcblxuICAgICAgICBmdW5jdGlvbiBpbml0KCkge1xuICAgICAgICAgICAgYWRkKHBvaW50KTtcbiAgICAgICAgICAgIHVwZGF0ZUNlbnRlcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYWRkKHBvaW50VG9BZGQpIHtcbiAgICAgICAgICAgIHBvaW50TWFwW3BvaW50VG9BZGQuaWRdID0gcG9pbnRUb0FkZDtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHBvaW50VG9BZGQpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gdXBkYXRlQ2VudGVyKCkge1xuICAgICAgICAgICAgdmFyIGksIHN1bSA9IDA7XG4gICAgICAgICAgICBmb3IgKCBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHN1bSArPSBwb2ludHNbaV0ucmFkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2VudGVyLnJhZCA9IHN1bSAvIHBvaW50cy5sZW5ndGg7XG4gICAgICAgICAgICBjZW50ZXIudmVjID0gdmVjMi5jbG9uZShbTWF0aC5jb3MoY2VudGVyLnJhZCksIE1hdGguc2luKGNlbnRlci5yYWQpXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpbml0KCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFkZDogZnVuY3Rpb24ocG9pbnRUb0FkZCkge1xuICAgICAgICAgICAgICAgIGlmICghcG9pbnRNYXBbcG9pbnRUb0FkZC5pZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkKHBvaW50VG9BZGQpO1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVDZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZml0czogZnVuY3Rpb24ob3RoZXJQb2ludCkge1xuICAgICAgICAgICAgICAgIC8vIGNoZWNrIGNvc2luZSBzaW1pbGFyaXR5IHRvIGNlbnRlci1hbmdsZVxuICAgICAgICAgICAgICAgIHZhciBzaW1pbGFyaXR5ID0gTWF0aC5hYnModmVjMi5kb3Qob3RoZXJQb2ludC5wb2ludC52ZWMsIGNlbnRlci52ZWMpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2ltaWxhcml0eSA+IHRocmVzaG9sZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldFBvaW50czogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvaW50cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRDZW50ZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjZW50ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSxcbiAgICBjcmVhdGVQb2ludDogZnVuY3Rpb24obmV3UG9pbnQsIGlkLCBwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmFkOiBuZXdQb2ludFtwcm9wZXJ0eV0sXG4gICAgICAgICAgICBwb2ludDogbmV3UG9pbnQsXG4gICAgICAgICAgICBpZDogaWRcbiAgICAgICAgfTtcbiAgICB9XG59O1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY2x1c3Rlci5qc1xuICoqLyIsIi8qKlxuICogQGZpbGVvdmVydmlldyBnbC1tYXRyaXggLSBIaWdoIHBlcmZvcm1hbmNlIG1hdHJpeCBhbmQgdmVjdG9yIG9wZXJhdGlvbnNcbiAqIEBhdXRob3IgQnJhbmRvbiBKb25lc1xuICogQGF1dGhvciBDb2xpbiBNYWNLZW56aWUgSVZcbiAqIEB2ZXJzaW9uIDIuMy4wXG4gKi9cblxuLyogQ29weXJpZ2h0IChjKSAyMDE1LCBCcmFuZG9uIEpvbmVzLCBDb2xpbiBNYWNLZW56aWUgSVYuXG5cblBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbm9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbmluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbnRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbmFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG5JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbkZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbk9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cblRIRSBTT0ZUV0FSRS4gKi9cbi8vIEVORCBIRUFERVJcblxuZXhwb3J0cy5nbE1hdHJpeCA9IHJlcXVpcmUoXCIuL2dsLW1hdHJpeC9jb21tb24uanNcIik7XG5leHBvcnRzLm1hdDIgPSByZXF1aXJlKFwiLi9nbC1tYXRyaXgvbWF0Mi5qc1wiKTtcbmV4cG9ydHMubWF0MmQgPSByZXF1aXJlKFwiLi9nbC1tYXRyaXgvbWF0MmQuanNcIik7XG5leHBvcnRzLm1hdDMgPSByZXF1aXJlKFwiLi9nbC1tYXRyaXgvbWF0My5qc1wiKTtcbmV4cG9ydHMubWF0NCA9IHJlcXVpcmUoXCIuL2dsLW1hdHJpeC9tYXQ0LmpzXCIpO1xuZXhwb3J0cy5xdWF0ID0gcmVxdWlyZShcIi4vZ2wtbWF0cml4L3F1YXQuanNcIik7XG5leHBvcnRzLnZlYzIgPSByZXF1aXJlKFwiLi9nbC1tYXRyaXgvdmVjMi5qc1wiKTtcbmV4cG9ydHMudmVjMyA9IHJlcXVpcmUoXCIuL2dsLW1hdHJpeC92ZWMzLmpzXCIpO1xuZXhwb3J0cy52ZWM0ID0gcmVxdWlyZShcIi4vZ2wtbWF0cml4L3ZlYzQuanNcIik7XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXguanNcbiAqKiBtb2R1bGUgaWQgPSA3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiBDb3B5cmlnaHQgKGMpIDIwMTUsIEJyYW5kb24gSm9uZXMsIENvbGluIE1hY0tlbnppZSBJVi5cblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxub2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xudG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG5mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuXG5UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG5BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG5MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuVEhFIFNPRlRXQVJFLiAqL1xuXG4vKipcbiAqIEBjbGFzcyBDb21tb24gdXRpbGl0aWVzXG4gKiBAbmFtZSBnbE1hdHJpeFxuICovXG52YXIgZ2xNYXRyaXggPSB7fTtcblxuLy8gQ29uc3RhbnRzXG5nbE1hdHJpeC5FUFNJTE9OID0gMC4wMDAwMDE7XG5nbE1hdHJpeC5BUlJBWV9UWVBFID0gKHR5cGVvZiBGbG9hdDMyQXJyYXkgIT09ICd1bmRlZmluZWQnKSA/IEZsb2F0MzJBcnJheSA6IEFycmF5O1xuZ2xNYXRyaXguUkFORE9NID0gTWF0aC5yYW5kb207XG5cbi8qKlxuICogU2V0cyB0aGUgdHlwZSBvZiBhcnJheSB1c2VkIHdoZW4gY3JlYXRpbmcgbmV3IHZlY3RvcnMgYW5kIG1hdHJpY2VzXG4gKlxuICogQHBhcmFtIHtUeXBlfSB0eXBlIEFycmF5IHR5cGUsIHN1Y2ggYXMgRmxvYXQzMkFycmF5IG9yIEFycmF5XG4gKi9cbmdsTWF0cml4LnNldE1hdHJpeEFycmF5VHlwZSA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgICBHTE1BVF9BUlJBWV9UWVBFID0gdHlwZTtcbn1cblxudmFyIGRlZ3JlZSA9IE1hdGguUEkgLyAxODA7XG5cbi8qKlxuKiBDb252ZXJ0IERlZ3JlZSBUbyBSYWRpYW5cbipcbiogQHBhcmFtIHtOdW1iZXJ9IEFuZ2xlIGluIERlZ3JlZXNcbiovXG5nbE1hdHJpeC50b1JhZGlhbiA9IGZ1bmN0aW9uKGEpe1xuICAgICByZXR1cm4gYSAqIGRlZ3JlZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnbE1hdHJpeDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L2NvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIENvcHlyaWdodCAoYykgMjAxNSwgQnJhbmRvbiBKb25lcywgQ29saW4gTWFjS2VuemllIElWLlxuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG5vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG5pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG50byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG5jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG5hbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG5USEUgU09GVFdBUkUuICovXG5cbnZhciBnbE1hdHJpeCA9IHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKTtcblxuLyoqXG4gKiBAY2xhc3MgMngyIE1hdHJpeFxuICogQG5hbWUgbWF0MlxuICovXG52YXIgbWF0MiA9IHt9O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0MlxuICpcbiAqIEByZXR1cm5zIHttYXQyfSBhIG5ldyAyeDIgbWF0cml4XG4gKi9cbm1hdDIuY3JlYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICAgIG91dFswXSA9IDE7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDE7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBtYXQyIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgbWF0cml4XG4gKlxuICogQHBhcmFtIHttYXQyfSBhIG1hdHJpeCB0byBjbG9uZVxuICogQHJldHVybnMge21hdDJ9IGEgbmV3IDJ4MiBtYXRyaXhcbiAqL1xubWF0Mi5jbG9uZSA9IGZ1bmN0aW9uKGEpIHtcbiAgICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzFdO1xuICAgIG91dFsyXSA9IGFbMl07XG4gICAgb3V0WzNdID0gYVszXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0MiB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0Mn0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5tYXQyLmNvcHkgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNldCBhIG1hdDIgdG8gdGhlIGlkZW50aXR5IG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cbm1hdDIuaWRlbnRpdHkgPSBmdW5jdGlvbihvdXQpIHtcbiAgICBvdXRbMF0gPSAxO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFRyYW5zcG9zZSB0aGUgdmFsdWVzIG9mIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xubWF0Mi50cmFuc3Bvc2UgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlIHNvbWUgdmFsdWVzXG4gICAgaWYgKG91dCA9PT0gYSkge1xuICAgICAgICB2YXIgYTEgPSBhWzFdO1xuICAgICAgICBvdXRbMV0gPSBhWzJdO1xuICAgICAgICBvdXRbMl0gPSBhMTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBvdXRbMF0gPSBhWzBdO1xuICAgICAgICBvdXRbMV0gPSBhWzJdO1xuICAgICAgICBvdXRbMl0gPSBhWzFdO1xuICAgICAgICBvdXRbM10gPSBhWzNdO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBJbnZlcnRzIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xubWF0Mi5pbnZlcnQgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICB2YXIgYTAgPSBhWzBdLCBhMSA9IGFbMV0sIGEyID0gYVsyXSwgYTMgPSBhWzNdLFxuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcbiAgICAgICAgZGV0ID0gYTAgKiBhMyAtIGEyICogYTE7XG5cbiAgICBpZiAoIWRldCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZGV0ID0gMS4wIC8gZGV0O1xuICAgIFxuICAgIG91dFswXSA9ICBhMyAqIGRldDtcbiAgICBvdXRbMV0gPSAtYTEgKiBkZXQ7XG4gICAgb3V0WzJdID0gLWEyICogZGV0O1xuICAgIG91dFszXSA9ICBhMCAqIGRldDtcblxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGFkanVnYXRlIG9mIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xubWF0Mi5hZGpvaW50ID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgLy8gQ2FjaGluZyB0aGlzIHZhbHVlIGlzIG5lc3NlY2FyeSBpZiBvdXQgPT0gYVxuICAgIHZhciBhMCA9IGFbMF07XG4gICAgb3V0WzBdID0gIGFbM107XG4gICAgb3V0WzFdID0gLWFbMV07XG4gICAgb3V0WzJdID0gLWFbMl07XG4gICAgb3V0WzNdID0gIGEwO1xuXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZGV0ZXJtaW5hbnQgb2YgYSBtYXQyXG4gKlxuICogQHBhcmFtIHttYXQyfSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkZXRlcm1pbmFudCBvZiBhXG4gKi9cbm1hdDIuZGV0ZXJtaW5hbnQgPSBmdW5jdGlvbiAoYSkge1xuICAgIHJldHVybiBhWzBdICogYVszXSAtIGFbMl0gKiBhWzFdO1xufTtcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQyJ3NcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge21hdDJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cbm1hdDIubXVsdGlwbHkgPSBmdW5jdGlvbiAob3V0LCBhLCBiKSB7XG4gICAgdmFyIGEwID0gYVswXSwgYTEgPSBhWzFdLCBhMiA9IGFbMl0sIGEzID0gYVszXTtcbiAgICB2YXIgYjAgPSBiWzBdLCBiMSA9IGJbMV0sIGIyID0gYlsyXSwgYjMgPSBiWzNdO1xuICAgIG91dFswXSA9IGEwICogYjAgKyBhMiAqIGIxO1xuICAgIG91dFsxXSA9IGExICogYjAgKyBhMyAqIGIxO1xuICAgIG91dFsyXSA9IGEwICogYjIgKyBhMiAqIGIzO1xuICAgIG91dFszXSA9IGExICogYjIgKyBhMyAqIGIzO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0Mi5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5tYXQyLm11bCA9IG1hdDIubXVsdGlwbHk7XG5cbi8qKlxuICogUm90YXRlcyBhIG1hdDIgYnkgdGhlIGdpdmVuIGFuZ2xlXG4gKlxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0Mn0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xubWF0Mi5yb3RhdGUgPSBmdW5jdGlvbiAob3V0LCBhLCByYWQpIHtcbiAgICB2YXIgYTAgPSBhWzBdLCBhMSA9IGFbMV0sIGEyID0gYVsyXSwgYTMgPSBhWzNdLFxuICAgICAgICBzID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgICAgYyA9IE1hdGguY29zKHJhZCk7XG4gICAgb3V0WzBdID0gYTAgKiAgYyArIGEyICogcztcbiAgICBvdXRbMV0gPSBhMSAqICBjICsgYTMgKiBzO1xuICAgIG91dFsyXSA9IGEwICogLXMgKyBhMiAqIGM7XG4gICAgb3V0WzNdID0gYTEgKiAtcyArIGEzICogYztcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDIgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQyfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge3ZlYzJ9IHYgdGhlIHZlYzIgdG8gc2NhbGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJ9IG91dFxuICoqL1xubWF0Mi5zY2FsZSA9IGZ1bmN0aW9uKG91dCwgYSwgdikge1xuICAgIHZhciBhMCA9IGFbMF0sIGExID0gYVsxXSwgYTIgPSBhWzJdLCBhMyA9IGFbM10sXG4gICAgICAgIHYwID0gdlswXSwgdjEgPSB2WzFdO1xuICAgIG91dFswXSA9IGEwICogdjA7XG4gICAgb3V0WzFdID0gYTEgKiB2MDtcbiAgICBvdXRbMl0gPSBhMiAqIHYxO1xuICAgIG91dFszXSA9IGEzICogdjE7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgZ2l2ZW4gYW5nbGVcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQyLmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDIucm90YXRlKGRlc3QsIGRlc3QsIHJhZCk7XG4gKlxuICogQHBhcmFtIHttYXQyfSBvdXQgbWF0MiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xubWF0Mi5mcm9tUm90YXRpb24gPSBmdW5jdGlvbihvdXQsIHJhZCkge1xuICAgIHZhciBzID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgICAgYyA9IE1hdGguY29zKHJhZCk7XG4gICAgb3V0WzBdID0gYztcbiAgICBvdXRbMV0gPSBzO1xuICAgIG91dFsyXSA9IC1zO1xuICAgIG91dFszXSA9IGM7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3Igc2NhbGluZ1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDIuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0Mi5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IG1hdDIgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7dmVjMn0gdiBTY2FsaW5nIHZlY3RvclxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5tYXQyLmZyb21TY2FsaW5nID0gZnVuY3Rpb24ob3V0LCB2KSB7XG4gICAgb3V0WzBdID0gdlswXTtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gdlsxXTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtYXQyXG4gKlxuICogQHBhcmFtIHttYXQyfSBtYXQgbWF0cml4IHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcbiAqL1xubWF0Mi5zdHIgPSBmdW5jdGlvbiAoYSkge1xuICAgIHJldHVybiAnbWF0MignICsgYVswXSArICcsICcgKyBhWzFdICsgJywgJyArIGFbMl0gKyAnLCAnICsgYVszXSArICcpJztcbn07XG5cbi8qKlxuICogUmV0dXJucyBGcm9iZW5pdXMgbm9ybSBvZiBhIG1hdDJcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IGEgdGhlIG1hdHJpeCB0byBjYWxjdWxhdGUgRnJvYmVuaXVzIG5vcm0gb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IEZyb2Jlbml1cyBub3JtXG4gKi9cbm1hdDIuZnJvYiA9IGZ1bmN0aW9uIChhKSB7XG4gICAgcmV0dXJuKE1hdGguc3FydChNYXRoLnBvdyhhWzBdLCAyKSArIE1hdGgucG93KGFbMV0sIDIpICsgTWF0aC5wb3coYVsyXSwgMikgKyBNYXRoLnBvdyhhWzNdLCAyKSkpXG59O1xuXG4vKipcbiAqIFJldHVybnMgTCwgRCBhbmQgVSBtYXRyaWNlcyAoTG93ZXIgdHJpYW5ndWxhciwgRGlhZ29uYWwgYW5kIFVwcGVyIHRyaWFuZ3VsYXIpIGJ5IGZhY3Rvcml6aW5nIHRoZSBpbnB1dCBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0Mn0gTCB0aGUgbG93ZXIgdHJpYW5ndWxhciBtYXRyaXggXG4gKiBAcGFyYW0ge21hdDJ9IEQgdGhlIGRpYWdvbmFsIG1hdHJpeCBcbiAqIEBwYXJhbSB7bWF0Mn0gVSB0aGUgdXBwZXIgdHJpYW5ndWxhciBtYXRyaXggXG4gKiBAcGFyYW0ge21hdDJ9IGEgdGhlIGlucHV0IG1hdHJpeCB0byBmYWN0b3JpemVcbiAqL1xuXG5tYXQyLkxEVSA9IGZ1bmN0aW9uIChMLCBELCBVLCBhKSB7IFxuICAgIExbMl0gPSBhWzJdL2FbMF07IFxuICAgIFVbMF0gPSBhWzBdOyBcbiAgICBVWzFdID0gYVsxXTsgXG4gICAgVVszXSA9IGFbM10gLSBMWzJdICogVVsxXTsgXG4gICAgcmV0dXJuIFtMLCBELCBVXTsgICAgICAgXG59OyBcblxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hdDI7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nbC1tYXRyaXgvc3JjL2dsLW1hdHJpeC9tYXQyLmpzXG4gKiogbW9kdWxlIGlkID0gOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyogQ29weXJpZ2h0IChjKSAyMDE1LCBCcmFuZG9uIEpvbmVzLCBDb2xpbiBNYWNLZW56aWUgSVYuXG5cblBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbm9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbmluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbnRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbmFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG5JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbkZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbk9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cblRIRSBTT0ZUV0FSRS4gKi9cblxudmFyIGdsTWF0cml4ID0gcmVxdWlyZShcIi4vY29tbW9uLmpzXCIpO1xuXG4vKipcbiAqIEBjbGFzcyAyeDMgTWF0cml4XG4gKiBAbmFtZSBtYXQyZFxuICogXG4gKiBAZGVzY3JpcHRpb24gXG4gKiBBIG1hdDJkIGNvbnRhaW5zIHNpeCBlbGVtZW50cyBkZWZpbmVkIGFzOlxuICogPHByZT5cbiAqIFthLCBjLCB0eCxcbiAqICBiLCBkLCB0eV1cbiAqIDwvcHJlPlxuICogVGhpcyBpcyBhIHNob3J0IGZvcm0gZm9yIHRoZSAzeDMgbWF0cml4OlxuICogPHByZT5cbiAqIFthLCBjLCB0eCxcbiAqICBiLCBkLCB0eSxcbiAqICAwLCAwLCAxXVxuICogPC9wcmU+XG4gKiBUaGUgbGFzdCByb3cgaXMgaWdub3JlZCBzbyB0aGUgYXJyYXkgaXMgc2hvcnRlciBhbmQgb3BlcmF0aW9ucyBhcmUgZmFzdGVyLlxuICovXG52YXIgbWF0MmQgPSB7fTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDJkXG4gKlxuICogQHJldHVybnMge21hdDJkfSBhIG5ldyAyeDMgbWF0cml4XG4gKi9cbm1hdDJkLmNyZWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg2KTtcbiAgICBvdXRbMF0gPSAxO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAxO1xuICAgIG91dFs0XSA9IDA7XG4gICAgb3V0WzVdID0gMDtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDJkIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgbWF0cml4XG4gKlxuICogQHBhcmFtIHttYXQyZH0gYSBtYXRyaXggdG8gY2xvbmVcbiAqIEByZXR1cm5zIHttYXQyZH0gYSBuZXcgMngzIG1hdHJpeFxuICovXG5tYXQyZC5jbG9uZSA9IGZ1bmN0aW9uKGEpIHtcbiAgICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNik7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzFdO1xuICAgIG91dFsyXSA9IGFbMl07XG4gICAgb3V0WzNdID0gYVszXTtcbiAgICBvdXRbNF0gPSBhWzRdO1xuICAgIG91dFs1XSA9IGFbNV07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIG1hdDJkIHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0MmR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cbm1hdDJkLmNvcHkgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTZXQgYSBtYXQyZCB0byB0aGUgaWRlbnRpdHkgbWF0cml4XG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxuICovXG5tYXQyZC5pZGVudGl0eSA9IGZ1bmN0aW9uKG91dCkge1xuICAgIG91dFswXSA9IDE7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDE7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNV0gPSAwO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEludmVydHMgYSBtYXQyZFxuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQyZH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xubWF0MmQuaW52ZXJ0ID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgdmFyIGFhID0gYVswXSwgYWIgPSBhWzFdLCBhYyA9IGFbMl0sIGFkID0gYVszXSxcbiAgICAgICAgYXR4ID0gYVs0XSwgYXR5ID0gYVs1XTtcblxuICAgIHZhciBkZXQgPSBhYSAqIGFkIC0gYWIgKiBhYztcbiAgICBpZighZGV0KXtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGRldCA9IDEuMCAvIGRldDtcblxuICAgIG91dFswXSA9IGFkICogZGV0O1xuICAgIG91dFsxXSA9IC1hYiAqIGRldDtcbiAgICBvdXRbMl0gPSAtYWMgKiBkZXQ7XG4gICAgb3V0WzNdID0gYWEgKiBkZXQ7XG4gICAgb3V0WzRdID0gKGFjICogYXR5IC0gYWQgKiBhdHgpICogZGV0O1xuICAgIG91dFs1XSA9IChhYiAqIGF0eCAtIGFhICogYXR5KSAqIGRldDtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBkZXRlcm1pbmFudCBvZiBhIG1hdDJkXG4gKlxuICogQHBhcmFtIHttYXQyZH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge051bWJlcn0gZGV0ZXJtaW5hbnQgb2YgYVxuICovXG5tYXQyZC5kZXRlcm1pbmFudCA9IGZ1bmN0aW9uIChhKSB7XG4gICAgcmV0dXJuIGFbMF0gKiBhWzNdIC0gYVsxXSAqIGFbMl07XG59O1xuXG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIG1hdDJkJ3NcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0MmR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7bWF0MmR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxuICovXG5tYXQyZC5tdWx0aXBseSA9IGZ1bmN0aW9uIChvdXQsIGEsIGIpIHtcbiAgICB2YXIgYTAgPSBhWzBdLCBhMSA9IGFbMV0sIGEyID0gYVsyXSwgYTMgPSBhWzNdLCBhNCA9IGFbNF0sIGE1ID0gYVs1XSxcbiAgICAgICAgYjAgPSBiWzBdLCBiMSA9IGJbMV0sIGIyID0gYlsyXSwgYjMgPSBiWzNdLCBiNCA9IGJbNF0sIGI1ID0gYls1XTtcbiAgICBvdXRbMF0gPSBhMCAqIGIwICsgYTIgKiBiMTtcbiAgICBvdXRbMV0gPSBhMSAqIGIwICsgYTMgKiBiMTtcbiAgICBvdXRbMl0gPSBhMCAqIGIyICsgYTIgKiBiMztcbiAgICBvdXRbM10gPSBhMSAqIGIyICsgYTMgKiBiMztcbiAgICBvdXRbNF0gPSBhMCAqIGI0ICsgYTIgKiBiNSArIGE0O1xuICAgIG91dFs1XSA9IGExICogYjQgKyBhMyAqIGI1ICsgYTU7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQyZC5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5tYXQyZC5tdWwgPSBtYXQyZC5tdWx0aXBseTtcblxuLyoqXG4gKiBSb3RhdGVzIGEgbWF0MmQgYnkgdGhlIGdpdmVuIGFuZ2xlXG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDJkfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xubWF0MmQucm90YXRlID0gZnVuY3Rpb24gKG91dCwgYSwgcmFkKSB7XG4gICAgdmFyIGEwID0gYVswXSwgYTEgPSBhWzFdLCBhMiA9IGFbMl0sIGEzID0gYVszXSwgYTQgPSBhWzRdLCBhNSA9IGFbNV0sXG4gICAgICAgIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgICBjID0gTWF0aC5jb3MocmFkKTtcbiAgICBvdXRbMF0gPSBhMCAqICBjICsgYTIgKiBzO1xuICAgIG91dFsxXSA9IGExICogIGMgKyBhMyAqIHM7XG4gICAgb3V0WzJdID0gYTAgKiAtcyArIGEyICogYztcbiAgICBvdXRbM10gPSBhMSAqIC1zICsgYTMgKiBjO1xuICAgIG91dFs0XSA9IGE0O1xuICAgIG91dFs1XSA9IGE1O1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNjYWxlcyB0aGUgbWF0MmQgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0MmR9IGEgdGhlIG1hdHJpeCB0byB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7dmVjMn0gdiB0aGUgdmVjMiB0byBzY2FsZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxuICoqL1xubWF0MmQuc2NhbGUgPSBmdW5jdGlvbihvdXQsIGEsIHYpIHtcbiAgICB2YXIgYTAgPSBhWzBdLCBhMSA9IGFbMV0sIGEyID0gYVsyXSwgYTMgPSBhWzNdLCBhNCA9IGFbNF0sIGE1ID0gYVs1XSxcbiAgICAgICAgdjAgPSB2WzBdLCB2MSA9IHZbMV07XG4gICAgb3V0WzBdID0gYTAgKiB2MDtcbiAgICBvdXRbMV0gPSBhMSAqIHYwO1xuICAgIG91dFsyXSA9IGEyICogdjE7XG4gICAgb3V0WzNdID0gYTMgKiB2MTtcbiAgICBvdXRbNF0gPSBhNDtcbiAgICBvdXRbNV0gPSBhNTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBUcmFuc2xhdGVzIHRoZSBtYXQyZCBieSB0aGUgZGltZW5zaW9ucyBpbiB0aGUgZ2l2ZW4gdmVjMlxuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQyZH0gYSB0aGUgbWF0cml4IHRvIHRyYW5zbGF0ZVxuICogQHBhcmFtIHt2ZWMyfSB2IHRoZSB2ZWMyIHRvIHRyYW5zbGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxuICoqL1xubWF0MmQudHJhbnNsYXRlID0gZnVuY3Rpb24ob3V0LCBhLCB2KSB7XG4gICAgdmFyIGEwID0gYVswXSwgYTEgPSBhWzFdLCBhMiA9IGFbMl0sIGEzID0gYVszXSwgYTQgPSBhWzRdLCBhNSA9IGFbNV0sXG4gICAgICAgIHYwID0gdlswXSwgdjEgPSB2WzFdO1xuICAgIG91dFswXSA9IGEwO1xuICAgIG91dFsxXSA9IGExO1xuICAgIG91dFsyXSA9IGEyO1xuICAgIG91dFszXSA9IGEzO1xuICAgIG91dFs0XSA9IGEwICogdjAgKyBhMiAqIHYxICsgYTQ7XG4gICAgb3V0WzVdID0gYTEgKiB2MCArIGEzICogdjEgKyBhNTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZVxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDJkLmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDJkLnJvdGF0ZShkZXN0LCBkZXN0LCByYWQpO1xuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCBtYXQyZCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cbm1hdDJkLmZyb21Sb3RhdGlvbiA9IGZ1bmN0aW9uKG91dCwgcmFkKSB7XG4gICAgdmFyIHMgPSBNYXRoLnNpbihyYWQpLCBjID0gTWF0aC5jb3MocmFkKTtcbiAgICBvdXRbMF0gPSBjO1xuICAgIG91dFsxXSA9IHM7XG4gICAgb3V0WzJdID0gLXM7XG4gICAgb3V0WzNdID0gYztcbiAgICBvdXRbNF0gPSAwO1xuICAgIG91dFs1XSA9IDA7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3Igc2NhbGluZ1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDJkLmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDJkLnNjYWxlKGRlc3QsIGRlc3QsIHZlYyk7XG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IG1hdDJkIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge3ZlYzJ9IHYgU2NhbGluZyB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cbm1hdDJkLmZyb21TY2FsaW5nID0gZnVuY3Rpb24ob3V0LCB2KSB7XG4gICAgb3V0WzBdID0gdlswXTtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gdlsxXTtcbiAgICBvdXRbNF0gPSAwO1xuICAgIG91dFs1XSA9IDA7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3IgdHJhbnNsYXRpb25cbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQyZC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQyZC50cmFuc2xhdGUoZGVzdCwgZGVzdCwgdmVjKTtcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgbWF0MmQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7dmVjMn0gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cbm1hdDJkLmZyb21UcmFuc2xhdGlvbiA9IGZ1bmN0aW9uKG91dCwgdikge1xuICAgIG91dFswXSA9IDE7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDE7XG4gICAgb3V0WzRdID0gdlswXTtcbiAgICBvdXRbNV0gPSB2WzFdO1xuICAgIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG1hdDJkXG4gKlxuICogQHBhcmFtIHttYXQyZH0gYSBtYXRyaXggdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1hdHJpeFxuICovXG5tYXQyZC5zdHIgPSBmdW5jdGlvbiAoYSkge1xuICAgIHJldHVybiAnbWF0MmQoJyArIGFbMF0gKyAnLCAnICsgYVsxXSArICcsICcgKyBhWzJdICsgJywgJyArIFxuICAgICAgICAgICAgICAgICAgICBhWzNdICsgJywgJyArIGFbNF0gKyAnLCAnICsgYVs1XSArICcpJztcbn07XG5cbi8qKlxuICogUmV0dXJucyBGcm9iZW5pdXMgbm9ybSBvZiBhIG1hdDJkXG4gKlxuICogQHBhcmFtIHttYXQyZH0gYSB0aGUgbWF0cml4IHRvIGNhbGN1bGF0ZSBGcm9iZW5pdXMgbm9ybSBvZlxuICogQHJldHVybnMge051bWJlcn0gRnJvYmVuaXVzIG5vcm1cbiAqL1xubWF0MmQuZnJvYiA9IGZ1bmN0aW9uIChhKSB7IFxuICAgIHJldHVybihNYXRoLnNxcnQoTWF0aC5wb3coYVswXSwgMikgKyBNYXRoLnBvdyhhWzFdLCAyKSArIE1hdGgucG93KGFbMl0sIDIpICsgTWF0aC5wb3coYVszXSwgMikgKyBNYXRoLnBvdyhhWzRdLCAyKSArIE1hdGgucG93KGFbNV0sIDIpICsgMSkpXG59OyBcblxubW9kdWxlLmV4cG9ydHMgPSBtYXQyZDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L21hdDJkLmpzXG4gKiogbW9kdWxlIGlkID0gMTBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIENvcHlyaWdodCAoYykgMjAxNSwgQnJhbmRvbiBKb25lcywgQ29saW4gTWFjS2VuemllIElWLlxuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG5vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG5pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG50byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG5jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG5hbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG5USEUgU09GVFdBUkUuICovXG5cbnZhciBnbE1hdHJpeCA9IHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKTtcblxuLyoqXG4gKiBAY2xhc3MgM3gzIE1hdHJpeFxuICogQG5hbWUgbWF0M1xuICovXG52YXIgbWF0MyA9IHt9O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0M1xuICpcbiAqIEByZXR1cm5zIHttYXQzfSBhIG5ldyAzeDMgbWF0cml4XG4gKi9cbm1hdDMuY3JlYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDkpO1xuICAgIG91dFswXSA9IDE7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gMTtcbiAgICBvdXRbNV0gPSAwO1xuICAgIG91dFs2XSA9IDA7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENvcGllcyB0aGUgdXBwZXItbGVmdCAzeDMgdmFsdWVzIGludG8gdGhlIGdpdmVuIG1hdDMuXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyAzeDMgbWF0cml4XG4gKiBAcGFyYW0ge21hdDR9IGEgICB0aGUgc291cmNlIDR4NCBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xubWF0My5mcm9tTWF0NCA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVsxXTtcbiAgICBvdXRbMl0gPSBhWzJdO1xuICAgIG91dFszXSA9IGFbNF07XG4gICAgb3V0WzRdID0gYVs1XTtcbiAgICBvdXRbNV0gPSBhWzZdO1xuICAgIG91dFs2XSA9IGFbOF07XG4gICAgb3V0WzddID0gYVs5XTtcbiAgICBvdXRbOF0gPSBhWzEwXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDMgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge21hdDN9IGEgbWF0cml4IHRvIGNsb25lXG4gKiBAcmV0dXJucyB7bWF0M30gYSBuZXcgM3gzIG1hdHJpeFxuICovXG5tYXQzLmNsb25lID0gZnVuY3Rpb24oYSkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg5KTtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICBvdXRbNl0gPSBhWzZdO1xuICAgIG91dFs3XSA9IGFbN107XG4gICAgb3V0WzhdID0gYVs4XTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0MyB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5tYXQzLmNvcHkgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICBvdXRbNl0gPSBhWzZdO1xuICAgIG91dFs3XSA9IGFbN107XG4gICAgb3V0WzhdID0gYVs4XTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTZXQgYSBtYXQzIHRvIHRoZSBpZGVudGl0eSBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5tYXQzLmlkZW50aXR5ID0gZnVuY3Rpb24ob3V0KSB7XG4gICAgb3V0WzBdID0gMTtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgICBvdXRbNF0gPSAxO1xuICAgIG91dFs1XSA9IDA7XG4gICAgb3V0WzZdID0gMDtcbiAgICBvdXRbN10gPSAwO1xuICAgIG91dFs4XSA9IDE7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogVHJhbnNwb3NlIHRoZSB2YWx1ZXMgb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5tYXQzLnRyYW5zcG9zZSA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIC8vIElmIHdlIGFyZSB0cmFuc3Bvc2luZyBvdXJzZWx2ZXMgd2UgY2FuIHNraXAgYSBmZXcgc3RlcHMgYnV0IGhhdmUgdG8gY2FjaGUgc29tZSB2YWx1ZXNcbiAgICBpZiAob3V0ID09PSBhKSB7XG4gICAgICAgIHZhciBhMDEgPSBhWzFdLCBhMDIgPSBhWzJdLCBhMTIgPSBhWzVdO1xuICAgICAgICBvdXRbMV0gPSBhWzNdO1xuICAgICAgICBvdXRbMl0gPSBhWzZdO1xuICAgICAgICBvdXRbM10gPSBhMDE7XG4gICAgICAgIG91dFs1XSA9IGFbN107XG4gICAgICAgIG91dFs2XSA9IGEwMjtcbiAgICAgICAgb3V0WzddID0gYTEyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG91dFswXSA9IGFbMF07XG4gICAgICAgIG91dFsxXSA9IGFbM107XG4gICAgICAgIG91dFsyXSA9IGFbNl07XG4gICAgICAgIG91dFszXSA9IGFbMV07XG4gICAgICAgIG91dFs0XSA9IGFbNF07XG4gICAgICAgIG91dFs1XSA9IGFbN107XG4gICAgICAgIG91dFs2XSA9IGFbMl07XG4gICAgICAgIG91dFs3XSA9IGFbNV07XG4gICAgICAgIG91dFs4XSA9IGFbOF07XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEludmVydHMgYSBtYXQzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5tYXQzLmludmVydCA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIHZhciBhMDAgPSBhWzBdLCBhMDEgPSBhWzFdLCBhMDIgPSBhWzJdLFxuICAgICAgICBhMTAgPSBhWzNdLCBhMTEgPSBhWzRdLCBhMTIgPSBhWzVdLFxuICAgICAgICBhMjAgPSBhWzZdLCBhMjEgPSBhWzddLCBhMjIgPSBhWzhdLFxuXG4gICAgICAgIGIwMSA9IGEyMiAqIGExMSAtIGExMiAqIGEyMSxcbiAgICAgICAgYjExID0gLWEyMiAqIGExMCArIGExMiAqIGEyMCxcbiAgICAgICAgYjIxID0gYTIxICogYTEwIC0gYTExICogYTIwLFxuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcbiAgICAgICAgZGV0ID0gYTAwICogYjAxICsgYTAxICogYjExICsgYTAyICogYjIxO1xuXG4gICAgaWYgKCFkZXQpIHsgXG4gICAgICAgIHJldHVybiBudWxsOyBcbiAgICB9XG4gICAgZGV0ID0gMS4wIC8gZGV0O1xuXG4gICAgb3V0WzBdID0gYjAxICogZGV0O1xuICAgIG91dFsxXSA9ICgtYTIyICogYTAxICsgYTAyICogYTIxKSAqIGRldDtcbiAgICBvdXRbMl0gPSAoYTEyICogYTAxIC0gYTAyICogYTExKSAqIGRldDtcbiAgICBvdXRbM10gPSBiMTEgKiBkZXQ7XG4gICAgb3V0WzRdID0gKGEyMiAqIGEwMCAtIGEwMiAqIGEyMCkgKiBkZXQ7XG4gICAgb3V0WzVdID0gKC1hMTIgKiBhMDAgKyBhMDIgKiBhMTApICogZGV0O1xuICAgIG91dFs2XSA9IGIyMSAqIGRldDtcbiAgICBvdXRbN10gPSAoLWEyMSAqIGEwMCArIGEwMSAqIGEyMCkgKiBkZXQ7XG4gICAgb3V0WzhdID0gKGExMSAqIGEwMCAtIGEwMSAqIGExMCkgKiBkZXQ7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgYWRqdWdhdGUgb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5tYXQzLmFkam9pbnQgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICB2YXIgYTAwID0gYVswXSwgYTAxID0gYVsxXSwgYTAyID0gYVsyXSxcbiAgICAgICAgYTEwID0gYVszXSwgYTExID0gYVs0XSwgYTEyID0gYVs1XSxcbiAgICAgICAgYTIwID0gYVs2XSwgYTIxID0gYVs3XSwgYTIyID0gYVs4XTtcblxuICAgIG91dFswXSA9IChhMTEgKiBhMjIgLSBhMTIgKiBhMjEpO1xuICAgIG91dFsxXSA9IChhMDIgKiBhMjEgLSBhMDEgKiBhMjIpO1xuICAgIG91dFsyXSA9IChhMDEgKiBhMTIgLSBhMDIgKiBhMTEpO1xuICAgIG91dFszXSA9IChhMTIgKiBhMjAgLSBhMTAgKiBhMjIpO1xuICAgIG91dFs0XSA9IChhMDAgKiBhMjIgLSBhMDIgKiBhMjApO1xuICAgIG91dFs1XSA9IChhMDIgKiBhMTAgLSBhMDAgKiBhMTIpO1xuICAgIG91dFs2XSA9IChhMTAgKiBhMjEgLSBhMTEgKiBhMjApO1xuICAgIG91dFs3XSA9IChhMDEgKiBhMjAgLSBhMDAgKiBhMjEpO1xuICAgIG91dFs4XSA9IChhMDAgKiBhMTEgLSBhMDEgKiBhMTApO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRldGVybWluYW50IG9mIGEgbWF0M1xuICpcbiAqIEBwYXJhbSB7bWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge051bWJlcn0gZGV0ZXJtaW5hbnQgb2YgYVxuICovXG5tYXQzLmRldGVybWluYW50ID0gZnVuY3Rpb24gKGEpIHtcbiAgICB2YXIgYTAwID0gYVswXSwgYTAxID0gYVsxXSwgYTAyID0gYVsyXSxcbiAgICAgICAgYTEwID0gYVszXSwgYTExID0gYVs0XSwgYTEyID0gYVs1XSxcbiAgICAgICAgYTIwID0gYVs2XSwgYTIxID0gYVs3XSwgYTIyID0gYVs4XTtcblxuICAgIHJldHVybiBhMDAgKiAoYTIyICogYTExIC0gYTEyICogYTIxKSArIGEwMSAqICgtYTIyICogYTEwICsgYTEyICogYTIwKSArIGEwMiAqIChhMjEgKiBhMTAgLSBhMTEgKiBhMjApO1xufTtcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQzJ3NcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge21hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cbm1hdDMubXVsdGlwbHkgPSBmdW5jdGlvbiAob3V0LCBhLCBiKSB7XG4gICAgdmFyIGEwMCA9IGFbMF0sIGEwMSA9IGFbMV0sIGEwMiA9IGFbMl0sXG4gICAgICAgIGExMCA9IGFbM10sIGExMSA9IGFbNF0sIGExMiA9IGFbNV0sXG4gICAgICAgIGEyMCA9IGFbNl0sIGEyMSA9IGFbN10sIGEyMiA9IGFbOF0sXG5cbiAgICAgICAgYjAwID0gYlswXSwgYjAxID0gYlsxXSwgYjAyID0gYlsyXSxcbiAgICAgICAgYjEwID0gYlszXSwgYjExID0gYls0XSwgYjEyID0gYls1XSxcbiAgICAgICAgYjIwID0gYls2XSwgYjIxID0gYls3XSwgYjIyID0gYls4XTtcblxuICAgIG91dFswXSA9IGIwMCAqIGEwMCArIGIwMSAqIGExMCArIGIwMiAqIGEyMDtcbiAgICBvdXRbMV0gPSBiMDAgKiBhMDEgKyBiMDEgKiBhMTEgKyBiMDIgKiBhMjE7XG4gICAgb3V0WzJdID0gYjAwICogYTAyICsgYjAxICogYTEyICsgYjAyICogYTIyO1xuXG4gICAgb3V0WzNdID0gYjEwICogYTAwICsgYjExICogYTEwICsgYjEyICogYTIwO1xuICAgIG91dFs0XSA9IGIxMCAqIGEwMSArIGIxMSAqIGExMSArIGIxMiAqIGEyMTtcbiAgICBvdXRbNV0gPSBiMTAgKiBhMDIgKyBiMTEgKiBhMTIgKyBiMTIgKiBhMjI7XG5cbiAgICBvdXRbNl0gPSBiMjAgKiBhMDAgKyBiMjEgKiBhMTAgKyBiMjIgKiBhMjA7XG4gICAgb3V0WzddID0gYjIwICogYTAxICsgYjIxICogYTExICsgYjIyICogYTIxO1xuICAgIG91dFs4XSA9IGIyMCAqIGEwMiArIGIyMSAqIGExMiArIGIyMiAqIGEyMjtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDMubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xubWF0My5tdWwgPSBtYXQzLm11bHRpcGx5O1xuXG4vKipcbiAqIFRyYW5zbGF0ZSBhIG1hdDMgYnkgdGhlIGdpdmVuIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDN9IGEgdGhlIG1hdHJpeCB0byB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7dmVjMn0gdiB2ZWN0b3IgdG8gdHJhbnNsYXRlIGJ5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cbm1hdDMudHJhbnNsYXRlID0gZnVuY3Rpb24ob3V0LCBhLCB2KSB7XG4gICAgdmFyIGEwMCA9IGFbMF0sIGEwMSA9IGFbMV0sIGEwMiA9IGFbMl0sXG4gICAgICAgIGExMCA9IGFbM10sIGExMSA9IGFbNF0sIGExMiA9IGFbNV0sXG4gICAgICAgIGEyMCA9IGFbNl0sIGEyMSA9IGFbN10sIGEyMiA9IGFbOF0sXG4gICAgICAgIHggPSB2WzBdLCB5ID0gdlsxXTtcblxuICAgIG91dFswXSA9IGEwMDtcbiAgICBvdXRbMV0gPSBhMDE7XG4gICAgb3V0WzJdID0gYTAyO1xuXG4gICAgb3V0WzNdID0gYTEwO1xuICAgIG91dFs0XSA9IGExMTtcbiAgICBvdXRbNV0gPSBhMTI7XG5cbiAgICBvdXRbNl0gPSB4ICogYTAwICsgeSAqIGExMCArIGEyMDtcbiAgICBvdXRbN10gPSB4ICogYTAxICsgeSAqIGExMSArIGEyMTtcbiAgICBvdXRbOF0gPSB4ICogYTAyICsgeSAqIGExMiArIGEyMjtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBSb3RhdGVzIGEgbWF0MyBieSB0aGUgZ2l2ZW4gYW5nbGVcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQzfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5tYXQzLnJvdGF0ZSA9IGZ1bmN0aW9uIChvdXQsIGEsIHJhZCkge1xuICAgIHZhciBhMDAgPSBhWzBdLCBhMDEgPSBhWzFdLCBhMDIgPSBhWzJdLFxuICAgICAgICBhMTAgPSBhWzNdLCBhMTEgPSBhWzRdLCBhMTIgPSBhWzVdLFxuICAgICAgICBhMjAgPSBhWzZdLCBhMjEgPSBhWzddLCBhMjIgPSBhWzhdLFxuXG4gICAgICAgIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgICBjID0gTWF0aC5jb3MocmFkKTtcblxuICAgIG91dFswXSA9IGMgKiBhMDAgKyBzICogYTEwO1xuICAgIG91dFsxXSA9IGMgKiBhMDEgKyBzICogYTExO1xuICAgIG91dFsyXSA9IGMgKiBhMDIgKyBzICogYTEyO1xuXG4gICAgb3V0WzNdID0gYyAqIGExMCAtIHMgKiBhMDA7XG4gICAgb3V0WzRdID0gYyAqIGExMSAtIHMgKiBhMDE7XG4gICAgb3V0WzVdID0gYyAqIGExMiAtIHMgKiBhMDI7XG5cbiAgICBvdXRbNl0gPSBhMjA7XG4gICAgb3V0WzddID0gYTIxO1xuICAgIG91dFs4XSA9IGEyMjtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDMgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQzfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge3ZlYzJ9IHYgdGhlIHZlYzIgdG8gc2NhbGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDN9IG91dFxuICoqL1xubWF0My5zY2FsZSA9IGZ1bmN0aW9uKG91dCwgYSwgdikge1xuICAgIHZhciB4ID0gdlswXSwgeSA9IHZbMV07XG5cbiAgICBvdXRbMF0gPSB4ICogYVswXTtcbiAgICBvdXRbMV0gPSB4ICogYVsxXTtcbiAgICBvdXRbMl0gPSB4ICogYVsyXTtcblxuICAgIG91dFszXSA9IHkgKiBhWzNdO1xuICAgIG91dFs0XSA9IHkgKiBhWzRdO1xuICAgIG91dFs1XSA9IHkgKiBhWzVdO1xuXG4gICAgb3V0WzZdID0gYVs2XTtcbiAgICBvdXRbN10gPSBhWzddO1xuICAgIG91dFs4XSA9IGFbOF07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHRyYW5zbGF0aW9uXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQzLnRyYW5zbGF0ZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7dmVjMn0gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xubWF0My5mcm9tVHJhbnNsYXRpb24gPSBmdW5jdGlvbihvdXQsIHYpIHtcbiAgICBvdXRbMF0gPSAxO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IDE7XG4gICAgb3V0WzVdID0gMDtcbiAgICBvdXRbNl0gPSB2WzBdO1xuICAgIG91dFs3XSA9IHZbMV07XG4gICAgb3V0WzhdID0gMTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIGdpdmVuIGFuZ2xlXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQzLnJvdGF0ZShkZXN0LCBkZXN0LCByYWQpO1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cbm1hdDMuZnJvbVJvdGF0aW9uID0gZnVuY3Rpb24ob3V0LCByYWQpIHtcbiAgICB2YXIgcyA9IE1hdGguc2luKHJhZCksIGMgPSBNYXRoLmNvcyhyYWQpO1xuXG4gICAgb3V0WzBdID0gYztcbiAgICBvdXRbMV0gPSBzO1xuICAgIG91dFsyXSA9IDA7XG5cbiAgICBvdXRbM10gPSAtcztcbiAgICBvdXRbNF0gPSBjO1xuICAgIG91dFs1XSA9IDA7XG5cbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gMTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciBzY2FsaW5nXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQzLnNjYWxlKGRlc3QsIGRlc3QsIHZlYyk7XG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgbWF0MyByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHt2ZWMyfSB2IFNjYWxpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cbm1hdDMuZnJvbVNjYWxpbmcgPSBmdW5jdGlvbihvdXQsIHYpIHtcbiAgICBvdXRbMF0gPSB2WzBdO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcblxuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gdlsxXTtcbiAgICBvdXRbNV0gPSAwO1xuXG4gICAgb3V0WzZdID0gMDtcbiAgICBvdXRbN10gPSAwO1xuICAgIG91dFs4XSA9IDE7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIHZhbHVlcyBmcm9tIGEgbWF0MmQgaW50byBhIG1hdDNcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQyZH0gYSB0aGUgbWF0cml4IHRvIGNvcHlcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqKi9cbm1hdDMuZnJvbU1hdDJkID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzFdO1xuICAgIG91dFsyXSA9IDA7XG5cbiAgICBvdXRbM10gPSBhWzJdO1xuICAgIG91dFs0XSA9IGFbM107XG4gICAgb3V0WzVdID0gMDtcblxuICAgIG91dFs2XSA9IGFbNF07XG4gICAgb3V0WzddID0gYVs1XTtcbiAgICBvdXRbOF0gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiogQ2FsY3VsYXRlcyBhIDN4MyBtYXRyaXggZnJvbSB0aGUgZ2l2ZW4gcXVhdGVybmlvblxuKlxuKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4qIEBwYXJhbSB7cXVhdH0gcSBRdWF0ZXJuaW9uIHRvIGNyZWF0ZSBtYXRyaXggZnJvbVxuKlxuKiBAcmV0dXJucyB7bWF0M30gb3V0XG4qL1xubWF0My5mcm9tUXVhdCA9IGZ1bmN0aW9uIChvdXQsIHEpIHtcbiAgICB2YXIgeCA9IHFbMF0sIHkgPSBxWzFdLCB6ID0gcVsyXSwgdyA9IHFbM10sXG4gICAgICAgIHgyID0geCArIHgsXG4gICAgICAgIHkyID0geSArIHksXG4gICAgICAgIHoyID0geiArIHosXG5cbiAgICAgICAgeHggPSB4ICogeDIsXG4gICAgICAgIHl4ID0geSAqIHgyLFxuICAgICAgICB5eSA9IHkgKiB5MixcbiAgICAgICAgenggPSB6ICogeDIsXG4gICAgICAgIHp5ID0geiAqIHkyLFxuICAgICAgICB6eiA9IHogKiB6MixcbiAgICAgICAgd3ggPSB3ICogeDIsXG4gICAgICAgIHd5ID0gdyAqIHkyLFxuICAgICAgICB3eiA9IHcgKiB6MjtcblxuICAgIG91dFswXSA9IDEgLSB5eSAtIHp6O1xuICAgIG91dFszXSA9IHl4IC0gd3o7XG4gICAgb3V0WzZdID0genggKyB3eTtcblxuICAgIG91dFsxXSA9IHl4ICsgd3o7XG4gICAgb3V0WzRdID0gMSAtIHh4IC0geno7XG4gICAgb3V0WzddID0genkgLSB3eDtcblxuICAgIG91dFsyXSA9IHp4IC0gd3k7XG4gICAgb3V0WzVdID0genkgKyB3eDtcbiAgICBvdXRbOF0gPSAxIC0geHggLSB5eTtcblxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiogQ2FsY3VsYXRlcyBhIDN4MyBub3JtYWwgbWF0cml4ICh0cmFuc3Bvc2UgaW52ZXJzZSkgZnJvbSB0aGUgNHg0IG1hdHJpeFxuKlxuKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4qIEBwYXJhbSB7bWF0NH0gYSBNYXQ0IHRvIGRlcml2ZSB0aGUgbm9ybWFsIG1hdHJpeCBmcm9tXG4qXG4qIEByZXR1cm5zIHttYXQzfSBvdXRcbiovXG5tYXQzLm5vcm1hbEZyb21NYXQ0ID0gZnVuY3Rpb24gKG91dCwgYSkge1xuICAgIHZhciBhMDAgPSBhWzBdLCBhMDEgPSBhWzFdLCBhMDIgPSBhWzJdLCBhMDMgPSBhWzNdLFxuICAgICAgICBhMTAgPSBhWzRdLCBhMTEgPSBhWzVdLCBhMTIgPSBhWzZdLCBhMTMgPSBhWzddLFxuICAgICAgICBhMjAgPSBhWzhdLCBhMjEgPSBhWzldLCBhMjIgPSBhWzEwXSwgYTIzID0gYVsxMV0sXG4gICAgICAgIGEzMCA9IGFbMTJdLCBhMzEgPSBhWzEzXSwgYTMyID0gYVsxNF0sIGEzMyA9IGFbMTVdLFxuXG4gICAgICAgIGIwMCA9IGEwMCAqIGExMSAtIGEwMSAqIGExMCxcbiAgICAgICAgYjAxID0gYTAwICogYTEyIC0gYTAyICogYTEwLFxuICAgICAgICBiMDIgPSBhMDAgKiBhMTMgLSBhMDMgKiBhMTAsXG4gICAgICAgIGIwMyA9IGEwMSAqIGExMiAtIGEwMiAqIGExMSxcbiAgICAgICAgYjA0ID0gYTAxICogYTEzIC0gYTAzICogYTExLFxuICAgICAgICBiMDUgPSBhMDIgKiBhMTMgLSBhMDMgKiBhMTIsXG4gICAgICAgIGIwNiA9IGEyMCAqIGEzMSAtIGEyMSAqIGEzMCxcbiAgICAgICAgYjA3ID0gYTIwICogYTMyIC0gYTIyICogYTMwLFxuICAgICAgICBiMDggPSBhMjAgKiBhMzMgLSBhMjMgKiBhMzAsXG4gICAgICAgIGIwOSA9IGEyMSAqIGEzMiAtIGEyMiAqIGEzMSxcbiAgICAgICAgYjEwID0gYTIxICogYTMzIC0gYTIzICogYTMxLFxuICAgICAgICBiMTEgPSBhMjIgKiBhMzMgLSBhMjMgKiBhMzIsXG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBkZXRlcm1pbmFudFxuICAgICAgICBkZXQgPSBiMDAgKiBiMTEgLSBiMDEgKiBiMTAgKyBiMDIgKiBiMDkgKyBiMDMgKiBiMDggLSBiMDQgKiBiMDcgKyBiMDUgKiBiMDY7XG5cbiAgICBpZiAoIWRldCkgeyBcbiAgICAgICAgcmV0dXJuIG51bGw7IFxuICAgIH1cbiAgICBkZXQgPSAxLjAgLyBkZXQ7XG5cbiAgICBvdXRbMF0gPSAoYTExICogYjExIC0gYTEyICogYjEwICsgYTEzICogYjA5KSAqIGRldDtcbiAgICBvdXRbMV0gPSAoYTEyICogYjA4IC0gYTEwICogYjExIC0gYTEzICogYjA3KSAqIGRldDtcbiAgICBvdXRbMl0gPSAoYTEwICogYjEwIC0gYTExICogYjA4ICsgYTEzICogYjA2KSAqIGRldDtcblxuICAgIG91dFszXSA9IChhMDIgKiBiMTAgLSBhMDEgKiBiMTEgLSBhMDMgKiBiMDkpICogZGV0O1xuICAgIG91dFs0XSA9IChhMDAgKiBiMTEgLSBhMDIgKiBiMDggKyBhMDMgKiBiMDcpICogZGV0O1xuICAgIG91dFs1XSA9IChhMDEgKiBiMDggLSBhMDAgKiBiMTAgLSBhMDMgKiBiMDYpICogZGV0O1xuXG4gICAgb3V0WzZdID0gKGEzMSAqIGIwNSAtIGEzMiAqIGIwNCArIGEzMyAqIGIwMykgKiBkZXQ7XG4gICAgb3V0WzddID0gKGEzMiAqIGIwMiAtIGEzMCAqIGIwNSAtIGEzMyAqIGIwMSkgKiBkZXQ7XG4gICAgb3V0WzhdID0gKGEzMCAqIGIwNCAtIGEzMSAqIGIwMiArIGEzMyAqIGIwMCkgKiBkZXQ7XG5cbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgbWF0M1xuICpcbiAqIEBwYXJhbSB7bWF0M30gbWF0IG1hdHJpeCB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWF0cml4XG4gKi9cbm1hdDMuc3RyID0gZnVuY3Rpb24gKGEpIHtcbiAgICByZXR1cm4gJ21hdDMoJyArIGFbMF0gKyAnLCAnICsgYVsxXSArICcsICcgKyBhWzJdICsgJywgJyArIFxuICAgICAgICAgICAgICAgICAgICBhWzNdICsgJywgJyArIGFbNF0gKyAnLCAnICsgYVs1XSArICcsICcgKyBcbiAgICAgICAgICAgICAgICAgICAgYVs2XSArICcsICcgKyBhWzddICsgJywgJyArIGFbOF0gKyAnKSc7XG59O1xuXG4vKipcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHttYXQzfSBhIHRoZSBtYXRyaXggdG8gY2FsY3VsYXRlIEZyb2Jlbml1cyBub3JtIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBGcm9iZW5pdXMgbm9ybVxuICovXG5tYXQzLmZyb2IgPSBmdW5jdGlvbiAoYSkge1xuICAgIHJldHVybihNYXRoLnNxcnQoTWF0aC5wb3coYVswXSwgMikgKyBNYXRoLnBvdyhhWzFdLCAyKSArIE1hdGgucG93KGFbMl0sIDIpICsgTWF0aC5wb3coYVszXSwgMikgKyBNYXRoLnBvdyhhWzRdLCAyKSArIE1hdGgucG93KGFbNV0sIDIpICsgTWF0aC5wb3coYVs2XSwgMikgKyBNYXRoLnBvdyhhWzddLCAyKSArIE1hdGgucG93KGFbOF0sIDIpKSlcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBtYXQzO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXgvbWF0My5qc1xuICoqIG1vZHVsZSBpZCA9IDExXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiBDb3B5cmlnaHQgKGMpIDIwMTUsIEJyYW5kb24gSm9uZXMsIENvbGluIE1hY0tlbnppZSBJVi5cblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxub2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xudG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG5mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuXG5UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG5BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG5MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuVEhFIFNPRlRXQVJFLiAqL1xuXG52YXIgZ2xNYXRyaXggPSByZXF1aXJlKFwiLi9jb21tb24uanNcIik7XG5cbi8qKlxuICogQGNsYXNzIDR4NCBNYXRyaXhcbiAqIEBuYW1lIG1hdDRcbiAqL1xudmFyIG1hdDQgPSB7fTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDRcbiAqXG4gKiBAcmV0dXJucyB7bWF0NH0gYSBuZXcgNHg0IG1hdHJpeFxuICovXG5tYXQ0LmNyZWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgxNik7XG4gICAgb3V0WzBdID0gMTtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgICBvdXRbNF0gPSAwO1xuICAgIG91dFs1XSA9IDE7XG4gICAgb3V0WzZdID0gMDtcbiAgICBvdXRbN10gPSAwO1xuICAgIG91dFs4XSA9IDA7XG4gICAgb3V0WzldID0gMDtcbiAgICBvdXRbMTBdID0gMTtcbiAgICBvdXRbMTFdID0gMDtcbiAgICBvdXRbMTJdID0gMDtcbiAgICBvdXRbMTNdID0gMDtcbiAgICBvdXRbMTRdID0gMDtcbiAgICBvdXRbMTVdID0gMTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge21hdDR9IGEgbWF0cml4IHRvIGNsb25lXG4gKiBAcmV0dXJucyB7bWF0NH0gYSBuZXcgNHg0IG1hdHJpeFxuICovXG5tYXQ0LmNsb25lID0gZnVuY3Rpb24oYSkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgxNik7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzFdO1xuICAgIG91dFsyXSA9IGFbMl07XG4gICAgb3V0WzNdID0gYVszXTtcbiAgICBvdXRbNF0gPSBhWzRdO1xuICAgIG91dFs1XSA9IGFbNV07XG4gICAgb3V0WzZdID0gYVs2XTtcbiAgICBvdXRbN10gPSBhWzddO1xuICAgIG91dFs4XSA9IGFbOF07XG4gICAgb3V0WzldID0gYVs5XTtcbiAgICBvdXRbMTBdID0gYVsxMF07XG4gICAgb3V0WzExXSA9IGFbMTFdO1xuICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0NCB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0NH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5tYXQ0LmNvcHkgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICBvdXRbNl0gPSBhWzZdO1xuICAgIG91dFs3XSA9IGFbN107XG4gICAgb3V0WzhdID0gYVs4XTtcbiAgICBvdXRbOV0gPSBhWzldO1xuICAgIG91dFsxMF0gPSBhWzEwXTtcbiAgICBvdXRbMTFdID0gYVsxMV07XG4gICAgb3V0WzEyXSA9IGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbMTVdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNldCBhIG1hdDQgdG8gdGhlIGlkZW50aXR5IG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQuaWRlbnRpdHkgPSBmdW5jdGlvbihvdXQpIHtcbiAgICBvdXRbMF0gPSAxO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IDA7XG4gICAgb3V0WzVdID0gMTtcbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gMDtcbiAgICBvdXRbOV0gPSAwO1xuICAgIG91dFsxMF0gPSAxO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSAwO1xuICAgIG91dFsxM10gPSAwO1xuICAgIG91dFsxNF0gPSAwO1xuICAgIG91dFsxNV0gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFRyYW5zcG9zZSB0aGUgdmFsdWVzIG9mIGEgbWF0NFxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC50cmFuc3Bvc2UgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlIHNvbWUgdmFsdWVzXG4gICAgaWYgKG91dCA9PT0gYSkge1xuICAgICAgICB2YXIgYTAxID0gYVsxXSwgYTAyID0gYVsyXSwgYTAzID0gYVszXSxcbiAgICAgICAgICAgIGExMiA9IGFbNl0sIGExMyA9IGFbN10sXG4gICAgICAgICAgICBhMjMgPSBhWzExXTtcblxuICAgICAgICBvdXRbMV0gPSBhWzRdO1xuICAgICAgICBvdXRbMl0gPSBhWzhdO1xuICAgICAgICBvdXRbM10gPSBhWzEyXTtcbiAgICAgICAgb3V0WzRdID0gYTAxO1xuICAgICAgICBvdXRbNl0gPSBhWzldO1xuICAgICAgICBvdXRbN10gPSBhWzEzXTtcbiAgICAgICAgb3V0WzhdID0gYTAyO1xuICAgICAgICBvdXRbOV0gPSBhMTI7XG4gICAgICAgIG91dFsxMV0gPSBhWzE0XTtcbiAgICAgICAgb3V0WzEyXSA9IGEwMztcbiAgICAgICAgb3V0WzEzXSA9IGExMztcbiAgICAgICAgb3V0WzE0XSA9IGEyMztcbiAgICB9IGVsc2Uge1xuICAgICAgICBvdXRbMF0gPSBhWzBdO1xuICAgICAgICBvdXRbMV0gPSBhWzRdO1xuICAgICAgICBvdXRbMl0gPSBhWzhdO1xuICAgICAgICBvdXRbM10gPSBhWzEyXTtcbiAgICAgICAgb3V0WzRdID0gYVsxXTtcbiAgICAgICAgb3V0WzVdID0gYVs1XTtcbiAgICAgICAgb3V0WzZdID0gYVs5XTtcbiAgICAgICAgb3V0WzddID0gYVsxM107XG4gICAgICAgIG91dFs4XSA9IGFbMl07XG4gICAgICAgIG91dFs5XSA9IGFbNl07XG4gICAgICAgIG91dFsxMF0gPSBhWzEwXTtcbiAgICAgICAgb3V0WzExXSA9IGFbMTRdO1xuICAgICAgICBvdXRbMTJdID0gYVszXTtcbiAgICAgICAgb3V0WzEzXSA9IGFbN107XG4gICAgICAgIG91dFsxNF0gPSBhWzExXTtcbiAgICAgICAgb3V0WzE1XSA9IGFbMTVdO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBJbnZlcnRzIGEgbWF0NFxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5pbnZlcnQgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICB2YXIgYTAwID0gYVswXSwgYTAxID0gYVsxXSwgYTAyID0gYVsyXSwgYTAzID0gYVszXSxcbiAgICAgICAgYTEwID0gYVs0XSwgYTExID0gYVs1XSwgYTEyID0gYVs2XSwgYTEzID0gYVs3XSxcbiAgICAgICAgYTIwID0gYVs4XSwgYTIxID0gYVs5XSwgYTIyID0gYVsxMF0sIGEyMyA9IGFbMTFdLFxuICAgICAgICBhMzAgPSBhWzEyXSwgYTMxID0gYVsxM10sIGEzMiA9IGFbMTRdLCBhMzMgPSBhWzE1XSxcblxuICAgICAgICBiMDAgPSBhMDAgKiBhMTEgLSBhMDEgKiBhMTAsXG4gICAgICAgIGIwMSA9IGEwMCAqIGExMiAtIGEwMiAqIGExMCxcbiAgICAgICAgYjAyID0gYTAwICogYTEzIC0gYTAzICogYTEwLFxuICAgICAgICBiMDMgPSBhMDEgKiBhMTIgLSBhMDIgKiBhMTEsXG4gICAgICAgIGIwNCA9IGEwMSAqIGExMyAtIGEwMyAqIGExMSxcbiAgICAgICAgYjA1ID0gYTAyICogYTEzIC0gYTAzICogYTEyLFxuICAgICAgICBiMDYgPSBhMjAgKiBhMzEgLSBhMjEgKiBhMzAsXG4gICAgICAgIGIwNyA9IGEyMCAqIGEzMiAtIGEyMiAqIGEzMCxcbiAgICAgICAgYjA4ID0gYTIwICogYTMzIC0gYTIzICogYTMwLFxuICAgICAgICBiMDkgPSBhMjEgKiBhMzIgLSBhMjIgKiBhMzEsXG4gICAgICAgIGIxMCA9IGEyMSAqIGEzMyAtIGEyMyAqIGEzMSxcbiAgICAgICAgYjExID0gYTIyICogYTMzIC0gYTIzICogYTMyLFxuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcbiAgICAgICAgZGV0ID0gYjAwICogYjExIC0gYjAxICogYjEwICsgYjAyICogYjA5ICsgYjAzICogYjA4IC0gYjA0ICogYjA3ICsgYjA1ICogYjA2O1xuXG4gICAgaWYgKCFkZXQpIHsgXG4gICAgICAgIHJldHVybiBudWxsOyBcbiAgICB9XG4gICAgZGV0ID0gMS4wIC8gZGV0O1xuXG4gICAgb3V0WzBdID0gKGExMSAqIGIxMSAtIGExMiAqIGIxMCArIGExMyAqIGIwOSkgKiBkZXQ7XG4gICAgb3V0WzFdID0gKGEwMiAqIGIxMCAtIGEwMSAqIGIxMSAtIGEwMyAqIGIwOSkgKiBkZXQ7XG4gICAgb3V0WzJdID0gKGEzMSAqIGIwNSAtIGEzMiAqIGIwNCArIGEzMyAqIGIwMykgKiBkZXQ7XG4gICAgb3V0WzNdID0gKGEyMiAqIGIwNCAtIGEyMSAqIGIwNSAtIGEyMyAqIGIwMykgKiBkZXQ7XG4gICAgb3V0WzRdID0gKGExMiAqIGIwOCAtIGExMCAqIGIxMSAtIGExMyAqIGIwNykgKiBkZXQ7XG4gICAgb3V0WzVdID0gKGEwMCAqIGIxMSAtIGEwMiAqIGIwOCArIGEwMyAqIGIwNykgKiBkZXQ7XG4gICAgb3V0WzZdID0gKGEzMiAqIGIwMiAtIGEzMCAqIGIwNSAtIGEzMyAqIGIwMSkgKiBkZXQ7XG4gICAgb3V0WzddID0gKGEyMCAqIGIwNSAtIGEyMiAqIGIwMiArIGEyMyAqIGIwMSkgKiBkZXQ7XG4gICAgb3V0WzhdID0gKGExMCAqIGIxMCAtIGExMSAqIGIwOCArIGExMyAqIGIwNikgKiBkZXQ7XG4gICAgb3V0WzldID0gKGEwMSAqIGIwOCAtIGEwMCAqIGIxMCAtIGEwMyAqIGIwNikgKiBkZXQ7XG4gICAgb3V0WzEwXSA9IChhMzAgKiBiMDQgLSBhMzEgKiBiMDIgKyBhMzMgKiBiMDApICogZGV0O1xuICAgIG91dFsxMV0gPSAoYTIxICogYjAyIC0gYTIwICogYjA0IC0gYTIzICogYjAwKSAqIGRldDtcbiAgICBvdXRbMTJdID0gKGExMSAqIGIwNyAtIGExMCAqIGIwOSAtIGExMiAqIGIwNikgKiBkZXQ7XG4gICAgb3V0WzEzXSA9IChhMDAgKiBiMDkgLSBhMDEgKiBiMDcgKyBhMDIgKiBiMDYpICogZGV0O1xuICAgIG91dFsxNF0gPSAoYTMxICogYjAxIC0gYTMwICogYjAzIC0gYTMyICogYjAwKSAqIGRldDtcbiAgICBvdXRbMTVdID0gKGEyMCAqIGIwMyAtIGEyMSAqIGIwMSArIGEyMiAqIGIwMCkgKiBkZXQ7XG5cbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBhZGp1Z2F0ZSBvZiBhIG1hdDRcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQuYWRqb2ludCA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIHZhciBhMDAgPSBhWzBdLCBhMDEgPSBhWzFdLCBhMDIgPSBhWzJdLCBhMDMgPSBhWzNdLFxuICAgICAgICBhMTAgPSBhWzRdLCBhMTEgPSBhWzVdLCBhMTIgPSBhWzZdLCBhMTMgPSBhWzddLFxuICAgICAgICBhMjAgPSBhWzhdLCBhMjEgPSBhWzldLCBhMjIgPSBhWzEwXSwgYTIzID0gYVsxMV0sXG4gICAgICAgIGEzMCA9IGFbMTJdLCBhMzEgPSBhWzEzXSwgYTMyID0gYVsxNF0sIGEzMyA9IGFbMTVdO1xuXG4gICAgb3V0WzBdICA9ICAoYTExICogKGEyMiAqIGEzMyAtIGEyMyAqIGEzMikgLSBhMjEgKiAoYTEyICogYTMzIC0gYTEzICogYTMyKSArIGEzMSAqIChhMTIgKiBhMjMgLSBhMTMgKiBhMjIpKTtcbiAgICBvdXRbMV0gID0gLShhMDEgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMSAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMxICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMikpO1xuICAgIG91dFsyXSAgPSAgKGEwMSAqIChhMTIgKiBhMzMgLSBhMTMgKiBhMzIpIC0gYTExICogKGEwMiAqIGEzMyAtIGEwMyAqIGEzMikgKyBhMzEgKiAoYTAyICogYTEzIC0gYTAzICogYTEyKSk7XG4gICAgb3V0WzNdICA9IC0oYTAxICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikgLSBhMTEgKiAoYTAyICogYTIzIC0gYTAzICogYTIyKSArIGEyMSAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpKTtcbiAgICBvdXRbNF0gID0gLShhMTAgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMCAqIChhMTIgKiBhMzMgLSBhMTMgKiBhMzIpICsgYTMwICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikpO1xuICAgIG91dFs1XSAgPSAgKGEwMCAqIChhMjIgKiBhMzMgLSBhMjMgKiBhMzIpIC0gYTIwICogKGEwMiAqIGEzMyAtIGEwMyAqIGEzMikgKyBhMzAgKiAoYTAyICogYTIzIC0gYTAzICogYTIyKSk7XG4gICAgb3V0WzZdICA9IC0oYTAwICogKGExMiAqIGEzMyAtIGExMyAqIGEzMikgLSBhMTAgKiAoYTAyICogYTMzIC0gYTAzICogYTMyKSArIGEzMCAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpKTtcbiAgICBvdXRbN10gID0gIChhMDAgKiAoYTEyICogYTIzIC0gYTEzICogYTIyKSAtIGExMCAqIChhMDIgKiBhMjMgLSBhMDMgKiBhMjIpICsgYTIwICogKGEwMiAqIGExMyAtIGEwMyAqIGExMikpO1xuICAgIG91dFs4XSAgPSAgKGExMCAqIChhMjEgKiBhMzMgLSBhMjMgKiBhMzEpIC0gYTIwICogKGExMSAqIGEzMyAtIGExMyAqIGEzMSkgKyBhMzAgKiAoYTExICogYTIzIC0gYTEzICogYTIxKSk7XG4gICAgb3V0WzldICA9IC0oYTAwICogKGEyMSAqIGEzMyAtIGEyMyAqIGEzMSkgLSBhMjAgKiAoYTAxICogYTMzIC0gYTAzICogYTMxKSArIGEzMCAqIChhMDEgKiBhMjMgLSBhMDMgKiBhMjEpKTtcbiAgICBvdXRbMTBdID0gIChhMDAgKiAoYTExICogYTMzIC0gYTEzICogYTMxKSAtIGExMCAqIChhMDEgKiBhMzMgLSBhMDMgKiBhMzEpICsgYTMwICogKGEwMSAqIGExMyAtIGEwMyAqIGExMSkpO1xuICAgIG91dFsxMV0gPSAtKGEwMCAqIChhMTEgKiBhMjMgLSBhMTMgKiBhMjEpIC0gYTEwICogKGEwMSAqIGEyMyAtIGEwMyAqIGEyMSkgKyBhMjAgKiAoYTAxICogYTEzIC0gYTAzICogYTExKSk7XG4gICAgb3V0WzEyXSA9IC0oYTEwICogKGEyMSAqIGEzMiAtIGEyMiAqIGEzMSkgLSBhMjAgKiAoYTExICogYTMyIC0gYTEyICogYTMxKSArIGEzMCAqIChhMTEgKiBhMjIgLSBhMTIgKiBhMjEpKTtcbiAgICBvdXRbMTNdID0gIChhMDAgKiAoYTIxICogYTMyIC0gYTIyICogYTMxKSAtIGEyMCAqIChhMDEgKiBhMzIgLSBhMDIgKiBhMzEpICsgYTMwICogKGEwMSAqIGEyMiAtIGEwMiAqIGEyMSkpO1xuICAgIG91dFsxNF0gPSAtKGEwMCAqIChhMTEgKiBhMzIgLSBhMTIgKiBhMzEpIC0gYTEwICogKGEwMSAqIGEzMiAtIGEwMiAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTEyIC0gYTAyICogYTExKSk7XG4gICAgb3V0WzE1XSA9ICAoYTAwICogKGExMSAqIGEyMiAtIGExMiAqIGEyMSkgLSBhMTAgKiAoYTAxICogYTIyIC0gYTAyICogYTIxKSArIGEyMCAqIChhMDEgKiBhMTIgLSBhMDIgKiBhMTEpKTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBkZXRlcm1pbmFudCBvZiBhIG1hdDRcbiAqXG4gKiBAcGFyYW0ge21hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRldGVybWluYW50IG9mIGFcbiAqL1xubWF0NC5kZXRlcm1pbmFudCA9IGZ1bmN0aW9uIChhKSB7XG4gICAgdmFyIGEwMCA9IGFbMF0sIGEwMSA9IGFbMV0sIGEwMiA9IGFbMl0sIGEwMyA9IGFbM10sXG4gICAgICAgIGExMCA9IGFbNF0sIGExMSA9IGFbNV0sIGExMiA9IGFbNl0sIGExMyA9IGFbN10sXG4gICAgICAgIGEyMCA9IGFbOF0sIGEyMSA9IGFbOV0sIGEyMiA9IGFbMTBdLCBhMjMgPSBhWzExXSxcbiAgICAgICAgYTMwID0gYVsxMl0sIGEzMSA9IGFbMTNdLCBhMzIgPSBhWzE0XSwgYTMzID0gYVsxNV0sXG5cbiAgICAgICAgYjAwID0gYTAwICogYTExIC0gYTAxICogYTEwLFxuICAgICAgICBiMDEgPSBhMDAgKiBhMTIgLSBhMDIgKiBhMTAsXG4gICAgICAgIGIwMiA9IGEwMCAqIGExMyAtIGEwMyAqIGExMCxcbiAgICAgICAgYjAzID0gYTAxICogYTEyIC0gYTAyICogYTExLFxuICAgICAgICBiMDQgPSBhMDEgKiBhMTMgLSBhMDMgKiBhMTEsXG4gICAgICAgIGIwNSA9IGEwMiAqIGExMyAtIGEwMyAqIGExMixcbiAgICAgICAgYjA2ID0gYTIwICogYTMxIC0gYTIxICogYTMwLFxuICAgICAgICBiMDcgPSBhMjAgKiBhMzIgLSBhMjIgKiBhMzAsXG4gICAgICAgIGIwOCA9IGEyMCAqIGEzMyAtIGEyMyAqIGEzMCxcbiAgICAgICAgYjA5ID0gYTIxICogYTMyIC0gYTIyICogYTMxLFxuICAgICAgICBiMTAgPSBhMjEgKiBhMzMgLSBhMjMgKiBhMzEsXG4gICAgICAgIGIxMSA9IGEyMiAqIGEzMyAtIGEyMyAqIGEzMjtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcbiAgICByZXR1cm4gYjAwICogYjExIC0gYjAxICogYjEwICsgYjAyICogYjA5ICsgYjAzICogYjA4IC0gYjA0ICogYjA3ICsgYjA1ICogYjA2O1xufTtcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQ0J3NcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQ0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge21hdDR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQubXVsdGlwbHkgPSBmdW5jdGlvbiAob3V0LCBhLCBiKSB7XG4gICAgdmFyIGEwMCA9IGFbMF0sIGEwMSA9IGFbMV0sIGEwMiA9IGFbMl0sIGEwMyA9IGFbM10sXG4gICAgICAgIGExMCA9IGFbNF0sIGExMSA9IGFbNV0sIGExMiA9IGFbNl0sIGExMyA9IGFbN10sXG4gICAgICAgIGEyMCA9IGFbOF0sIGEyMSA9IGFbOV0sIGEyMiA9IGFbMTBdLCBhMjMgPSBhWzExXSxcbiAgICAgICAgYTMwID0gYVsxMl0sIGEzMSA9IGFbMTNdLCBhMzIgPSBhWzE0XSwgYTMzID0gYVsxNV07XG5cbiAgICAvLyBDYWNoZSBvbmx5IHRoZSBjdXJyZW50IGxpbmUgb2YgdGhlIHNlY29uZCBtYXRyaXhcbiAgICB2YXIgYjAgID0gYlswXSwgYjEgPSBiWzFdLCBiMiA9IGJbMl0sIGIzID0gYlszXTsgIFxuICAgIG91dFswXSA9IGIwKmEwMCArIGIxKmExMCArIGIyKmEyMCArIGIzKmEzMDtcbiAgICBvdXRbMV0gPSBiMCphMDEgKyBiMSphMTEgKyBiMiphMjEgKyBiMyphMzE7XG4gICAgb3V0WzJdID0gYjAqYTAyICsgYjEqYTEyICsgYjIqYTIyICsgYjMqYTMyO1xuICAgIG91dFszXSA9IGIwKmEwMyArIGIxKmExMyArIGIyKmEyMyArIGIzKmEzMztcblxuICAgIGIwID0gYls0XTsgYjEgPSBiWzVdOyBiMiA9IGJbNl07IGIzID0gYls3XTtcbiAgICBvdXRbNF0gPSBiMCphMDAgKyBiMSphMTAgKyBiMiphMjAgKyBiMyphMzA7XG4gICAgb3V0WzVdID0gYjAqYTAxICsgYjEqYTExICsgYjIqYTIxICsgYjMqYTMxO1xuICAgIG91dFs2XSA9IGIwKmEwMiArIGIxKmExMiArIGIyKmEyMiArIGIzKmEzMjtcbiAgICBvdXRbN10gPSBiMCphMDMgKyBiMSphMTMgKyBiMiphMjMgKyBiMyphMzM7XG5cbiAgICBiMCA9IGJbOF07IGIxID0gYls5XTsgYjIgPSBiWzEwXTsgYjMgPSBiWzExXTtcbiAgICBvdXRbOF0gPSBiMCphMDAgKyBiMSphMTAgKyBiMiphMjAgKyBiMyphMzA7XG4gICAgb3V0WzldID0gYjAqYTAxICsgYjEqYTExICsgYjIqYTIxICsgYjMqYTMxO1xuICAgIG91dFsxMF0gPSBiMCphMDIgKyBiMSphMTIgKyBiMiphMjIgKyBiMyphMzI7XG4gICAgb3V0WzExXSA9IGIwKmEwMyArIGIxKmExMyArIGIyKmEyMyArIGIzKmEzMztcblxuICAgIGIwID0gYlsxMl07IGIxID0gYlsxM107IGIyID0gYlsxNF07IGIzID0gYlsxNV07XG4gICAgb3V0WzEyXSA9IGIwKmEwMCArIGIxKmExMCArIGIyKmEyMCArIGIzKmEzMDtcbiAgICBvdXRbMTNdID0gYjAqYTAxICsgYjEqYTExICsgYjIqYTIxICsgYjMqYTMxO1xuICAgIG91dFsxNF0gPSBiMCphMDIgKyBiMSphMTIgKyBiMiphMjIgKyBiMyphMzI7XG4gICAgb3V0WzE1XSA9IGIwKmEwMyArIGIxKmExMyArIGIyKmEyMyArIGIzKmEzMztcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDQubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xubWF0NC5tdWwgPSBtYXQ0Lm11bHRpcGx5O1xuXG4vKipcbiAqIFRyYW5zbGF0ZSBhIG1hdDQgYnkgdGhlIGdpdmVuIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDR9IGEgdGhlIG1hdHJpeCB0byB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7dmVjM30gdiB2ZWN0b3IgdG8gdHJhbnNsYXRlIGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQudHJhbnNsYXRlID0gZnVuY3Rpb24gKG91dCwgYSwgdikge1xuICAgIHZhciB4ID0gdlswXSwgeSA9IHZbMV0sIHogPSB2WzJdLFxuICAgICAgICBhMDAsIGEwMSwgYTAyLCBhMDMsXG4gICAgICAgIGExMCwgYTExLCBhMTIsIGExMyxcbiAgICAgICAgYTIwLCBhMjEsIGEyMiwgYTIzO1xuXG4gICAgaWYgKGEgPT09IG91dCkge1xuICAgICAgICBvdXRbMTJdID0gYVswXSAqIHggKyBhWzRdICogeSArIGFbOF0gKiB6ICsgYVsxMl07XG4gICAgICAgIG91dFsxM10gPSBhWzFdICogeCArIGFbNV0gKiB5ICsgYVs5XSAqIHogKyBhWzEzXTtcbiAgICAgICAgb3V0WzE0XSA9IGFbMl0gKiB4ICsgYVs2XSAqIHkgKyBhWzEwXSAqIHogKyBhWzE0XTtcbiAgICAgICAgb3V0WzE1XSA9IGFbM10gKiB4ICsgYVs3XSAqIHkgKyBhWzExXSAqIHogKyBhWzE1XTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBhMDAgPSBhWzBdOyBhMDEgPSBhWzFdOyBhMDIgPSBhWzJdOyBhMDMgPSBhWzNdO1xuICAgICAgICBhMTAgPSBhWzRdOyBhMTEgPSBhWzVdOyBhMTIgPSBhWzZdOyBhMTMgPSBhWzddO1xuICAgICAgICBhMjAgPSBhWzhdOyBhMjEgPSBhWzldOyBhMjIgPSBhWzEwXTsgYTIzID0gYVsxMV07XG5cbiAgICAgICAgb3V0WzBdID0gYTAwOyBvdXRbMV0gPSBhMDE7IG91dFsyXSA9IGEwMjsgb3V0WzNdID0gYTAzO1xuICAgICAgICBvdXRbNF0gPSBhMTA7IG91dFs1XSA9IGExMTsgb3V0WzZdID0gYTEyOyBvdXRbN10gPSBhMTM7XG4gICAgICAgIG91dFs4XSA9IGEyMDsgb3V0WzldID0gYTIxOyBvdXRbMTBdID0gYTIyOyBvdXRbMTFdID0gYTIzO1xuXG4gICAgICAgIG91dFsxMl0gPSBhMDAgKiB4ICsgYTEwICogeSArIGEyMCAqIHogKyBhWzEyXTtcbiAgICAgICAgb3V0WzEzXSA9IGEwMSAqIHggKyBhMTEgKiB5ICsgYTIxICogeiArIGFbMTNdO1xuICAgICAgICBvdXRbMTRdID0gYTAyICogeCArIGExMiAqIHkgKyBhMjIgKiB6ICsgYVsxNF07XG4gICAgICAgIG91dFsxNV0gPSBhMDMgKiB4ICsgYTEzICogeSArIGEyMyAqIHogKyBhWzE1XTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDQgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQ0fSBhIHRoZSBtYXRyaXggdG8gc2NhbGVcbiAqIEBwYXJhbSB7dmVjM30gdiB0aGUgdmVjMyB0byBzY2FsZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKiovXG5tYXQ0LnNjYWxlID0gZnVuY3Rpb24ob3V0LCBhLCB2KSB7XG4gICAgdmFyIHggPSB2WzBdLCB5ID0gdlsxXSwgeiA9IHZbMl07XG5cbiAgICBvdXRbMF0gPSBhWzBdICogeDtcbiAgICBvdXRbMV0gPSBhWzFdICogeDtcbiAgICBvdXRbMl0gPSBhWzJdICogeDtcbiAgICBvdXRbM10gPSBhWzNdICogeDtcbiAgICBvdXRbNF0gPSBhWzRdICogeTtcbiAgICBvdXRbNV0gPSBhWzVdICogeTtcbiAgICBvdXRbNl0gPSBhWzZdICogeTtcbiAgICBvdXRbN10gPSBhWzddICogeTtcbiAgICBvdXRbOF0gPSBhWzhdICogejtcbiAgICBvdXRbOV0gPSBhWzldICogejtcbiAgICBvdXRbMTBdID0gYVsxMF0gKiB6O1xuICAgIG91dFsxMV0gPSBhWzExXSAqIHo7XG4gICAgb3V0WzEyXSA9IGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbMTVdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJvdGF0ZXMgYSBtYXQ0IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIGdpdmVuIGF4aXNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQ0fSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHBhcmFtIHt2ZWMzfSBheGlzIHRoZSBheGlzIHRvIHJvdGF0ZSBhcm91bmRcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5yb3RhdGUgPSBmdW5jdGlvbiAob3V0LCBhLCByYWQsIGF4aXMpIHtcbiAgICB2YXIgeCA9IGF4aXNbMF0sIHkgPSBheGlzWzFdLCB6ID0gYXhpc1syXSxcbiAgICAgICAgbGVuID0gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkgKyB6ICogeiksXG4gICAgICAgIHMsIGMsIHQsXG4gICAgICAgIGEwMCwgYTAxLCBhMDIsIGEwMyxcbiAgICAgICAgYTEwLCBhMTEsIGExMiwgYTEzLFxuICAgICAgICBhMjAsIGEyMSwgYTIyLCBhMjMsXG4gICAgICAgIGIwMCwgYjAxLCBiMDIsXG4gICAgICAgIGIxMCwgYjExLCBiMTIsXG4gICAgICAgIGIyMCwgYjIxLCBiMjI7XG5cbiAgICBpZiAoTWF0aC5hYnMobGVuKSA8IGdsTWF0cml4LkVQU0lMT04pIHsgcmV0dXJuIG51bGw7IH1cbiAgICBcbiAgICBsZW4gPSAxIC8gbGVuO1xuICAgIHggKj0gbGVuO1xuICAgIHkgKj0gbGVuO1xuICAgIHogKj0gbGVuO1xuXG4gICAgcyA9IE1hdGguc2luKHJhZCk7XG4gICAgYyA9IE1hdGguY29zKHJhZCk7XG4gICAgdCA9IDEgLSBjO1xuXG4gICAgYTAwID0gYVswXTsgYTAxID0gYVsxXTsgYTAyID0gYVsyXTsgYTAzID0gYVszXTtcbiAgICBhMTAgPSBhWzRdOyBhMTEgPSBhWzVdOyBhMTIgPSBhWzZdOyBhMTMgPSBhWzddO1xuICAgIGEyMCA9IGFbOF07IGEyMSA9IGFbOV07IGEyMiA9IGFbMTBdOyBhMjMgPSBhWzExXTtcblxuICAgIC8vIENvbnN0cnVjdCB0aGUgZWxlbWVudHMgb2YgdGhlIHJvdGF0aW9uIG1hdHJpeFxuICAgIGIwMCA9IHggKiB4ICogdCArIGM7IGIwMSA9IHkgKiB4ICogdCArIHogKiBzOyBiMDIgPSB6ICogeCAqIHQgLSB5ICogcztcbiAgICBiMTAgPSB4ICogeSAqIHQgLSB6ICogczsgYjExID0geSAqIHkgKiB0ICsgYzsgYjEyID0geiAqIHkgKiB0ICsgeCAqIHM7XG4gICAgYjIwID0geCAqIHogKiB0ICsgeSAqIHM7IGIyMSA9IHkgKiB6ICogdCAtIHggKiBzOyBiMjIgPSB6ICogeiAqIHQgKyBjO1xuXG4gICAgLy8gUGVyZm9ybSByb3RhdGlvbi1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cbiAgICBvdXRbMF0gPSBhMDAgKiBiMDAgKyBhMTAgKiBiMDEgKyBhMjAgKiBiMDI7XG4gICAgb3V0WzFdID0gYTAxICogYjAwICsgYTExICogYjAxICsgYTIxICogYjAyO1xuICAgIG91dFsyXSA9IGEwMiAqIGIwMCArIGExMiAqIGIwMSArIGEyMiAqIGIwMjtcbiAgICBvdXRbM10gPSBhMDMgKiBiMDAgKyBhMTMgKiBiMDEgKyBhMjMgKiBiMDI7XG4gICAgb3V0WzRdID0gYTAwICogYjEwICsgYTEwICogYjExICsgYTIwICogYjEyO1xuICAgIG91dFs1XSA9IGEwMSAqIGIxMCArIGExMSAqIGIxMSArIGEyMSAqIGIxMjtcbiAgICBvdXRbNl0gPSBhMDIgKiBiMTAgKyBhMTIgKiBiMTEgKyBhMjIgKiBiMTI7XG4gICAgb3V0WzddID0gYTAzICogYjEwICsgYTEzICogYjExICsgYTIzICogYjEyO1xuICAgIG91dFs4XSA9IGEwMCAqIGIyMCArIGExMCAqIGIyMSArIGEyMCAqIGIyMjtcbiAgICBvdXRbOV0gPSBhMDEgKiBiMjAgKyBhMTEgKiBiMjEgKyBhMjEgKiBiMjI7XG4gICAgb3V0WzEwXSA9IGEwMiAqIGIyMCArIGExMiAqIGIyMSArIGEyMiAqIGIyMjtcbiAgICBvdXRbMTFdID0gYTAzICogYjIwICsgYTEzICogYjIxICsgYTIzICogYjIyO1xuXG4gICAgaWYgKGEgIT09IG91dCkgeyAvLyBJZiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkaWZmZXIsIGNvcHkgdGhlIHVuY2hhbmdlZCBsYXN0IHJvd1xuICAgICAgICBvdXRbMTJdID0gYVsxMl07XG4gICAgICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICAgICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgICAgICBvdXRbMTVdID0gYVsxNV07XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJvdGF0ZXMgYSBtYXRyaXggYnkgdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWCBheGlzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0NH0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5yb3RhdGVYID0gZnVuY3Rpb24gKG91dCwgYSwgcmFkKSB7XG4gICAgdmFyIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgICBjID0gTWF0aC5jb3MocmFkKSxcbiAgICAgICAgYTEwID0gYVs0XSxcbiAgICAgICAgYTExID0gYVs1XSxcbiAgICAgICAgYTEyID0gYVs2XSxcbiAgICAgICAgYTEzID0gYVs3XSxcbiAgICAgICAgYTIwID0gYVs4XSxcbiAgICAgICAgYTIxID0gYVs5XSxcbiAgICAgICAgYTIyID0gYVsxMF0sXG4gICAgICAgIGEyMyA9IGFbMTFdO1xuXG4gICAgaWYgKGEgIT09IG91dCkgeyAvLyBJZiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkaWZmZXIsIGNvcHkgdGhlIHVuY2hhbmdlZCByb3dzXG4gICAgICAgIG91dFswXSAgPSBhWzBdO1xuICAgICAgICBvdXRbMV0gID0gYVsxXTtcbiAgICAgICAgb3V0WzJdICA9IGFbMl07XG4gICAgICAgIG91dFszXSAgPSBhWzNdO1xuICAgICAgICBvdXRbMTJdID0gYVsxMl07XG4gICAgICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICAgICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgICAgICBvdXRbMTVdID0gYVsxNV07XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuICAgIG91dFs0XSA9IGExMCAqIGMgKyBhMjAgKiBzO1xuICAgIG91dFs1XSA9IGExMSAqIGMgKyBhMjEgKiBzO1xuICAgIG91dFs2XSA9IGExMiAqIGMgKyBhMjIgKiBzO1xuICAgIG91dFs3XSA9IGExMyAqIGMgKyBhMjMgKiBzO1xuICAgIG91dFs4XSA9IGEyMCAqIGMgLSBhMTAgKiBzO1xuICAgIG91dFs5XSA9IGEyMSAqIGMgLSBhMTEgKiBzO1xuICAgIG91dFsxMF0gPSBhMjIgKiBjIC0gYTEyICogcztcbiAgICBvdXRbMTFdID0gYTIzICogYyAtIGExMyAqIHM7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUm90YXRlcyBhIG1hdHJpeCBieSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBZIGF4aXNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHttYXQ0fSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5tYXQ0LnJvdGF0ZVkgPSBmdW5jdGlvbiAob3V0LCBhLCByYWQpIHtcbiAgICB2YXIgcyA9IE1hdGguc2luKHJhZCksXG4gICAgICAgIGMgPSBNYXRoLmNvcyhyYWQpLFxuICAgICAgICBhMDAgPSBhWzBdLFxuICAgICAgICBhMDEgPSBhWzFdLFxuICAgICAgICBhMDIgPSBhWzJdLFxuICAgICAgICBhMDMgPSBhWzNdLFxuICAgICAgICBhMjAgPSBhWzhdLFxuICAgICAgICBhMjEgPSBhWzldLFxuICAgICAgICBhMjIgPSBhWzEwXSxcbiAgICAgICAgYTIzID0gYVsxMV07XG5cbiAgICBpZiAoYSAhPT0gb3V0KSB7IC8vIElmIHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGRpZmZlciwgY29weSB0aGUgdW5jaGFuZ2VkIHJvd3NcbiAgICAgICAgb3V0WzRdICA9IGFbNF07XG4gICAgICAgIG91dFs1XSAgPSBhWzVdO1xuICAgICAgICBvdXRbNl0gID0gYVs2XTtcbiAgICAgICAgb3V0WzddICA9IGFbN107XG4gICAgICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICAgICAgb3V0WzEzXSA9IGFbMTNdO1xuICAgICAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgICB9XG5cbiAgICAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAgb3V0WzBdID0gYTAwICogYyAtIGEyMCAqIHM7XG4gICAgb3V0WzFdID0gYTAxICogYyAtIGEyMSAqIHM7XG4gICAgb3V0WzJdID0gYTAyICogYyAtIGEyMiAqIHM7XG4gICAgb3V0WzNdID0gYTAzICogYyAtIGEyMyAqIHM7XG4gICAgb3V0WzhdID0gYTAwICogcyArIGEyMCAqIGM7XG4gICAgb3V0WzldID0gYTAxICogcyArIGEyMSAqIGM7XG4gICAgb3V0WzEwXSA9IGEwMiAqIHMgKyBhMjIgKiBjO1xuICAgIG91dFsxMV0gPSBhMDMgKiBzICsgYTIzICogYztcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBSb3RhdGVzIGEgbWF0cml4IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFogYXhpc1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDR9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQucm90YXRlWiA9IGZ1bmN0aW9uIChvdXQsIGEsIHJhZCkge1xuICAgIHZhciBzID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgICAgYyA9IE1hdGguY29zKHJhZCksXG4gICAgICAgIGEwMCA9IGFbMF0sXG4gICAgICAgIGEwMSA9IGFbMV0sXG4gICAgICAgIGEwMiA9IGFbMl0sXG4gICAgICAgIGEwMyA9IGFbM10sXG4gICAgICAgIGExMCA9IGFbNF0sXG4gICAgICAgIGExMSA9IGFbNV0sXG4gICAgICAgIGExMiA9IGFbNl0sXG4gICAgICAgIGExMyA9IGFbN107XG5cbiAgICBpZiAoYSAhPT0gb3V0KSB7IC8vIElmIHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGRpZmZlciwgY29weSB0aGUgdW5jaGFuZ2VkIGxhc3Qgcm93XG4gICAgICAgIG91dFs4XSAgPSBhWzhdO1xuICAgICAgICBvdXRbOV0gID0gYVs5XTtcbiAgICAgICAgb3V0WzEwXSA9IGFbMTBdO1xuICAgICAgICBvdXRbMTFdID0gYVsxMV07XG4gICAgICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICAgICAgb3V0WzEzXSA9IGFbMTNdO1xuICAgICAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgICB9XG5cbiAgICAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAgb3V0WzBdID0gYTAwICogYyArIGExMCAqIHM7XG4gICAgb3V0WzFdID0gYTAxICogYyArIGExMSAqIHM7XG4gICAgb3V0WzJdID0gYTAyICogYyArIGExMiAqIHM7XG4gICAgb3V0WzNdID0gYTAzICogYyArIGExMyAqIHM7XG4gICAgb3V0WzRdID0gYTEwICogYyAtIGEwMCAqIHM7XG4gICAgb3V0WzVdID0gYTExICogYyAtIGEwMSAqIHM7XG4gICAgb3V0WzZdID0gYTEyICogYyAtIGEwMiAqIHM7XG4gICAgb3V0WzddID0gYTEzICogYyAtIGEwMyAqIHM7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHRyYW5zbGF0aW9uXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7dmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5mcm9tVHJhbnNsYXRpb24gPSBmdW5jdGlvbihvdXQsIHYpIHtcbiAgICBvdXRbMF0gPSAxO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IDA7XG4gICAgb3V0WzVdID0gMTtcbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gMDtcbiAgICBvdXRbOV0gPSAwO1xuICAgIG91dFsxMF0gPSAxO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSB2WzBdO1xuICAgIG91dFsxM10gPSB2WzFdO1xuICAgIG91dFsxNF0gPSB2WzJdO1xuICAgIG91dFsxNV0gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHNjYWxpbmdcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQuc2NhbGUoZGVzdCwgZGVzdCwgdmVjKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge3ZlYzN9IHYgU2NhbGluZyB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5mcm9tU2NhbGluZyA9IGZ1bmN0aW9uKG91dCwgdikge1xuICAgIG91dFswXSA9IHZbMF07XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNV0gPSB2WzFdO1xuICAgIG91dFs2XSA9IDA7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSAwO1xuICAgIG91dFs5XSA9IDA7XG4gICAgb3V0WzEwXSA9IHZbMl07XG4gICAgb3V0WzExXSA9IDA7XG4gICAgb3V0WzEyXSA9IDA7XG4gICAgb3V0WzEzXSA9IDA7XG4gICAgb3V0WzE0XSA9IDA7XG4gICAgb3V0WzE1XSA9IDE7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZSBhcm91bmQgYSBnaXZlbiBheGlzXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnJvdGF0ZShkZXN0LCBkZXN0LCByYWQsIGF4aXMpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcGFyYW0ge3ZlYzN9IGF4aXMgdGhlIGF4aXMgdG8gcm90YXRlIGFyb3VuZFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5tYXQ0LmZyb21Sb3RhdGlvbiA9IGZ1bmN0aW9uKG91dCwgcmFkLCBheGlzKSB7XG4gICAgdmFyIHggPSBheGlzWzBdLCB5ID0gYXhpc1sxXSwgeiA9IGF4aXNbMl0sXG4gICAgICAgIGxlbiA9IE1hdGguc3FydCh4ICogeCArIHkgKiB5ICsgeiAqIHopLFxuICAgICAgICBzLCBjLCB0O1xuICAgIFxuICAgIGlmIChNYXRoLmFicyhsZW4pIDwgZ2xNYXRyaXguRVBTSUxPTikgeyByZXR1cm4gbnVsbDsgfVxuICAgIFxuICAgIGxlbiA9IDEgLyBsZW47XG4gICAgeCAqPSBsZW47XG4gICAgeSAqPSBsZW47XG4gICAgeiAqPSBsZW47XG4gICAgXG4gICAgcyA9IE1hdGguc2luKHJhZCk7XG4gICAgYyA9IE1hdGguY29zKHJhZCk7XG4gICAgdCA9IDEgLSBjO1xuICAgIFxuICAgIC8vIFBlcmZvcm0gcm90YXRpb24tc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAgb3V0WzBdID0geCAqIHggKiB0ICsgYztcbiAgICBvdXRbMV0gPSB5ICogeCAqIHQgKyB6ICogcztcbiAgICBvdXRbMl0gPSB6ICogeCAqIHQgLSB5ICogcztcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IHggKiB5ICogdCAtIHogKiBzO1xuICAgIG91dFs1XSA9IHkgKiB5ICogdCArIGM7XG4gICAgb3V0WzZdID0geiAqIHkgKiB0ICsgeCAqIHM7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSB4ICogeiAqIHQgKyB5ICogcztcbiAgICBvdXRbOV0gPSB5ICogeiAqIHQgLSB4ICogcztcbiAgICBvdXRbMTBdID0geiAqIHogKiB0ICsgYztcbiAgICBvdXRbMTFdID0gMDtcbiAgICBvdXRbMTJdID0gMDtcbiAgICBvdXRbMTNdID0gMDtcbiAgICBvdXRbMTRdID0gMDtcbiAgICBvdXRbMTVdID0gMTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBYIGF4aXNcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQucm90YXRlWChkZXN0LCBkZXN0LCByYWQpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQuZnJvbVhSb3RhdGlvbiA9IGZ1bmN0aW9uKG91dCwgcmFkKSB7XG4gICAgdmFyIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgICBjID0gTWF0aC5jb3MocmFkKTtcbiAgICBcbiAgICAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAgb3V0WzBdICA9IDE7XG4gICAgb3V0WzFdICA9IDA7XG4gICAgb3V0WzJdICA9IDA7XG4gICAgb3V0WzNdICA9IDA7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNV0gPSBjO1xuICAgIG91dFs2XSA9IHM7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSAwO1xuICAgIG91dFs5XSA9IC1zO1xuICAgIG91dFsxMF0gPSBjO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSAwO1xuICAgIG91dFsxM10gPSAwO1xuICAgIG91dFsxNF0gPSAwO1xuICAgIG91dFsxNV0gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFkgYXhpc1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC5yb3RhdGVZKGRlc3QsIGRlc3QsIHJhZCk7XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5mcm9tWVJvdGF0aW9uID0gZnVuY3Rpb24ob3V0LCByYWQpIHtcbiAgICB2YXIgcyA9IE1hdGguc2luKHJhZCksXG4gICAgICAgIGMgPSBNYXRoLmNvcyhyYWQpO1xuICAgIFxuICAgIC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cbiAgICBvdXRbMF0gID0gYztcbiAgICBvdXRbMV0gID0gMDtcbiAgICBvdXRbMl0gID0gLXM7XG4gICAgb3V0WzNdICA9IDA7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNV0gPSAxO1xuICAgIG91dFs2XSA9IDA7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSBzO1xuICAgIG91dFs5XSA9IDA7XG4gICAgb3V0WzEwXSA9IGM7XG4gICAgb3V0WzExXSA9IDA7XG4gICAgb3V0WzEyXSA9IDA7XG4gICAgb3V0WzEzXSA9IDA7XG4gICAgb3V0WzE0XSA9IDA7XG4gICAgb3V0WzE1XSA9IDE7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWiBheGlzXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnJvdGF0ZVooZGVzdCwgZGVzdCwgcmFkKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5tYXQ0LmZyb21aUm90YXRpb24gPSBmdW5jdGlvbihvdXQsIHJhZCkge1xuICAgIHZhciBzID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgICAgYyA9IE1hdGguY29zKHJhZCk7XG4gICAgXG4gICAgLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuICAgIG91dFswXSAgPSBjO1xuICAgIG91dFsxXSAgPSBzO1xuICAgIG91dFsyXSAgPSAwO1xuICAgIG91dFszXSAgPSAwO1xuICAgIG91dFs0XSA9IC1zO1xuICAgIG91dFs1XSA9IGM7XG4gICAgb3V0WzZdID0gMDtcbiAgICBvdXRbN10gPSAwO1xuICAgIG91dFs4XSA9IDA7XG4gICAgb3V0WzldID0gMDtcbiAgICBvdXRbMTBdID0gMTtcbiAgICBvdXRbMTFdID0gMDtcbiAgICBvdXRbMTJdID0gMDtcbiAgICBvdXRbMTNdID0gMDtcbiAgICBvdXRbMTRdID0gMDtcbiAgICBvdXRbMTVdID0gMTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHF1YXRlcm5pb24gcm90YXRpb24gYW5kIHZlY3RvciB0cmFuc2xhdGlvblxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgdmVjKTtcbiAqICAgICB2YXIgcXVhdE1hdCA9IG1hdDQuY3JlYXRlKCk7XG4gKiAgICAgcXVhdDQudG9NYXQ0KHF1YXQsIHF1YXRNYXQpO1xuICogICAgIG1hdDQubXVsdGlwbHkoZGVzdCwgcXVhdE1hdCk7XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtxdWF0NH0gcSBSb3RhdGlvbiBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge3ZlYzN9IHYgVHJhbnNsYXRpb24gdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQuZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24gPSBmdW5jdGlvbiAob3V0LCBxLCB2KSB7XG4gICAgLy8gUXVhdGVybmlvbiBtYXRoXG4gICAgdmFyIHggPSBxWzBdLCB5ID0gcVsxXSwgeiA9IHFbMl0sIHcgPSBxWzNdLFxuICAgICAgICB4MiA9IHggKyB4LFxuICAgICAgICB5MiA9IHkgKyB5LFxuICAgICAgICB6MiA9IHogKyB6LFxuXG4gICAgICAgIHh4ID0geCAqIHgyLFxuICAgICAgICB4eSA9IHggKiB5MixcbiAgICAgICAgeHogPSB4ICogejIsXG4gICAgICAgIHl5ID0geSAqIHkyLFxuICAgICAgICB5eiA9IHkgKiB6MixcbiAgICAgICAgenogPSB6ICogejIsXG4gICAgICAgIHd4ID0gdyAqIHgyLFxuICAgICAgICB3eSA9IHcgKiB5MixcbiAgICAgICAgd3ogPSB3ICogejI7XG5cbiAgICBvdXRbMF0gPSAxIC0gKHl5ICsgenopO1xuICAgIG91dFsxXSA9IHh5ICsgd3o7XG4gICAgb3V0WzJdID0geHogLSB3eTtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IHh5IC0gd3o7XG4gICAgb3V0WzVdID0gMSAtICh4eCArIHp6KTtcbiAgICBvdXRbNl0gPSB5eiArIHd4O1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0geHogKyB3eTtcbiAgICBvdXRbOV0gPSB5eiAtIHd4O1xuICAgIG91dFsxMF0gPSAxIC0gKHh4ICsgeXkpO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSB2WzBdO1xuICAgIG91dFsxM10gPSB2WzFdO1xuICAgIG91dFsxNF0gPSB2WzJdO1xuICAgIG91dFsxNV0gPSAxO1xuICAgIFxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHF1YXRlcm5pb24gcm90YXRpb24sIHZlY3RvciB0cmFuc2xhdGlvbiBhbmQgdmVjdG9yIHNjYWxlXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCB2ZWMpO1xuICogICAgIHZhciBxdWF0TWF0ID0gbWF0NC5jcmVhdGUoKTtcbiAqICAgICBxdWF0NC50b01hdDQocXVhdCwgcXVhdE1hdCk7XG4gKiAgICAgbWF0NC5tdWx0aXBseShkZXN0LCBxdWF0TWF0KTtcbiAqICAgICBtYXQ0LnNjYWxlKGRlc3QsIHNjYWxlKVxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxuICogQHBhcmFtIHt2ZWMzfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBzIFNjYWxpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQuZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZSA9IGZ1bmN0aW9uIChvdXQsIHEsIHYsIHMpIHtcbiAgICAvLyBRdWF0ZXJuaW9uIG1hdGhcbiAgICB2YXIgeCA9IHFbMF0sIHkgPSBxWzFdLCB6ID0gcVsyXSwgdyA9IHFbM10sXG4gICAgICAgIHgyID0geCArIHgsXG4gICAgICAgIHkyID0geSArIHksXG4gICAgICAgIHoyID0geiArIHosXG5cbiAgICAgICAgeHggPSB4ICogeDIsXG4gICAgICAgIHh5ID0geCAqIHkyLFxuICAgICAgICB4eiA9IHggKiB6MixcbiAgICAgICAgeXkgPSB5ICogeTIsXG4gICAgICAgIHl6ID0geSAqIHoyLFxuICAgICAgICB6eiA9IHogKiB6MixcbiAgICAgICAgd3ggPSB3ICogeDIsXG4gICAgICAgIHd5ID0gdyAqIHkyLFxuICAgICAgICB3eiA9IHcgKiB6MixcbiAgICAgICAgc3ggPSBzWzBdLFxuICAgICAgICBzeSA9IHNbMV0sXG4gICAgICAgIHN6ID0gc1syXTtcblxuICAgIG91dFswXSA9ICgxIC0gKHl5ICsgenopKSAqIHN4O1xuICAgIG91dFsxXSA9ICh4eSArIHd6KSAqIHN4O1xuICAgIG91dFsyXSA9ICh4eiAtIHd5KSAqIHN4O1xuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gKHh5IC0gd3opICogc3k7XG4gICAgb3V0WzVdID0gKDEgLSAoeHggKyB6eikpICogc3k7XG4gICAgb3V0WzZdID0gKHl6ICsgd3gpICogc3k7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSAoeHogKyB3eSkgKiBzejtcbiAgICBvdXRbOV0gPSAoeXogLSB3eCkgKiBzejtcbiAgICBvdXRbMTBdID0gKDEgLSAoeHggKyB5eSkpICogc3o7XG4gICAgb3V0WzExXSA9IDA7XG4gICAgb3V0WzEyXSA9IHZbMF07XG4gICAgb3V0WzEzXSA9IHZbMV07XG4gICAgb3V0WzE0XSA9IHZbMl07XG4gICAgb3V0WzE1XSA9IDE7XG4gICAgXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgcXVhdGVybmlvbiByb3RhdGlvbiwgdmVjdG9yIHRyYW5zbGF0aW9uIGFuZCB2ZWN0b3Igc2NhbGUsIHJvdGF0aW5nIGFuZCBzY2FsaW5nIGFyb3VuZCB0aGUgZ2l2ZW4gb3JpZ2luXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCB2ZWMpO1xuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIG9yaWdpbik7XG4gKiAgICAgdmFyIHF1YXRNYXQgPSBtYXQ0LmNyZWF0ZSgpO1xuICogICAgIHF1YXQ0LnRvTWF0NChxdWF0LCBxdWF0TWF0KTtcbiAqICAgICBtYXQ0Lm11bHRpcGx5KGRlc3QsIHF1YXRNYXQpO1xuICogICAgIG1hdDQuc2NhbGUoZGVzdCwgc2NhbGUpXG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgbmVnYXRpdmVPcmlnaW4pO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxuICogQHBhcmFtIHt2ZWMzfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBzIFNjYWxpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IG8gVGhlIG9yaWdpbiB2ZWN0b3IgYXJvdW5kIHdoaWNoIHRvIHNjYWxlIGFuZCByb3RhdGVcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5mcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlT3JpZ2luID0gZnVuY3Rpb24gKG91dCwgcSwgdiwgcywgbykge1xuICAvLyBRdWF0ZXJuaW9uIG1hdGhcbiAgdmFyIHggPSBxWzBdLCB5ID0gcVsxXSwgeiA9IHFbMl0sIHcgPSBxWzNdLFxuICAgICAgeDIgPSB4ICsgeCxcbiAgICAgIHkyID0geSArIHksXG4gICAgICB6MiA9IHogKyB6LFxuXG4gICAgICB4eCA9IHggKiB4MixcbiAgICAgIHh5ID0geCAqIHkyLFxuICAgICAgeHogPSB4ICogejIsXG4gICAgICB5eSA9IHkgKiB5MixcbiAgICAgIHl6ID0geSAqIHoyLFxuICAgICAgenogPSB6ICogejIsXG4gICAgICB3eCA9IHcgKiB4MixcbiAgICAgIHd5ID0gdyAqIHkyLFxuICAgICAgd3ogPSB3ICogejIsXG4gICAgICBcbiAgICAgIHN4ID0gc1swXSxcbiAgICAgIHN5ID0gc1sxXSxcbiAgICAgIHN6ID0gc1syXSxcblxuICAgICAgb3ggPSBvWzBdLFxuICAgICAgb3kgPSBvWzFdLFxuICAgICAgb3ogPSBvWzJdO1xuICAgICAgXG4gIG91dFswXSA9ICgxIC0gKHl5ICsgenopKSAqIHN4O1xuICBvdXRbMV0gPSAoeHkgKyB3eikgKiBzeDtcbiAgb3V0WzJdID0gKHh6IC0gd3kpICogc3g7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9ICh4eSAtIHd6KSAqIHN5O1xuICBvdXRbNV0gPSAoMSAtICh4eCArIHp6KSkgKiBzeTtcbiAgb3V0WzZdID0gKHl6ICsgd3gpICogc3k7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9ICh4eiArIHd5KSAqIHN6O1xuICBvdXRbOV0gPSAoeXogLSB3eCkgKiBzejtcbiAgb3V0WzEwXSA9ICgxIC0gKHh4ICsgeXkpKSAqIHN6O1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IHZbMF0gKyBveCAtIChvdXRbMF0gKiBveCArIG91dFs0XSAqIG95ICsgb3V0WzhdICogb3opO1xuICBvdXRbMTNdID0gdlsxXSArIG95IC0gKG91dFsxXSAqIG94ICsgb3V0WzVdICogb3kgKyBvdXRbOV0gKiBveik7XG4gIG91dFsxNF0gPSB2WzJdICsgb3ogLSAob3V0WzJdICogb3ggKyBvdXRbNl0gKiBveSArIG91dFsxMF0gKiBveik7XG4gIG91dFsxNV0gPSAxO1xuICAgICAgICBcbiAgcmV0dXJuIG91dDtcbn07XG5cbm1hdDQuZnJvbVF1YXQgPSBmdW5jdGlvbiAob3V0LCBxKSB7XG4gICAgdmFyIHggPSBxWzBdLCB5ID0gcVsxXSwgeiA9IHFbMl0sIHcgPSBxWzNdLFxuICAgICAgICB4MiA9IHggKyB4LFxuICAgICAgICB5MiA9IHkgKyB5LFxuICAgICAgICB6MiA9IHogKyB6LFxuXG4gICAgICAgIHh4ID0geCAqIHgyLFxuICAgICAgICB5eCA9IHkgKiB4MixcbiAgICAgICAgeXkgPSB5ICogeTIsXG4gICAgICAgIHp4ID0geiAqIHgyLFxuICAgICAgICB6eSA9IHogKiB5MixcbiAgICAgICAgenogPSB6ICogejIsXG4gICAgICAgIHd4ID0gdyAqIHgyLFxuICAgICAgICB3eSA9IHcgKiB5MixcbiAgICAgICAgd3ogPSB3ICogejI7XG5cbiAgICBvdXRbMF0gPSAxIC0geXkgLSB6ejtcbiAgICBvdXRbMV0gPSB5eCArIHd6O1xuICAgIG91dFsyXSA9IHp4IC0gd3k7XG4gICAgb3V0WzNdID0gMDtcblxuICAgIG91dFs0XSA9IHl4IC0gd3o7XG4gICAgb3V0WzVdID0gMSAtIHh4IC0geno7XG4gICAgb3V0WzZdID0genkgKyB3eDtcbiAgICBvdXRbN10gPSAwO1xuXG4gICAgb3V0WzhdID0genggKyB3eTtcbiAgICBvdXRbOV0gPSB6eSAtIHd4O1xuICAgIG91dFsxMF0gPSAxIC0geHggLSB5eTtcbiAgICBvdXRbMTFdID0gMDtcblxuICAgIG91dFsxMl0gPSAwO1xuICAgIG91dFsxM10gPSAwO1xuICAgIG91dFsxNF0gPSAwO1xuICAgIG91dFsxNV0gPSAxO1xuXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgZnJ1c3R1bSBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtOdW1iZXJ9IGxlZnQgTGVmdCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtOdW1iZXJ9IHJpZ2h0IFJpZ2h0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge051bWJlcn0gYm90dG9tIEJvdHRvbSBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtOdW1iZXJ9IHRvcCBUb3AgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7TnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7TnVtYmVyfSBmYXIgRmFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQuZnJ1c3R1bSA9IGZ1bmN0aW9uIChvdXQsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgbmVhciwgZmFyKSB7XG4gICAgdmFyIHJsID0gMSAvIChyaWdodCAtIGxlZnQpLFxuICAgICAgICB0YiA9IDEgLyAodG9wIC0gYm90dG9tKSxcbiAgICAgICAgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICAgIG91dFswXSA9IChuZWFyICogMikgKiBybDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgICBvdXRbNF0gPSAwO1xuICAgIG91dFs1XSA9IChuZWFyICogMikgKiB0YjtcbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gKHJpZ2h0ICsgbGVmdCkgKiBybDtcbiAgICBvdXRbOV0gPSAodG9wICsgYm90dG9tKSAqIHRiO1xuICAgIG91dFsxMF0gPSAoZmFyICsgbmVhcikgKiBuZjtcbiAgICBvdXRbMTFdID0gLTE7XG4gICAgb3V0WzEyXSA9IDA7XG4gICAgb3V0WzEzXSA9IDA7XG4gICAgb3V0WzE0XSA9IChmYXIgKiBuZWFyICogMikgKiBuZjtcbiAgICBvdXRbMTVdID0gMDtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBwZXJzcGVjdGl2ZSBwcm9qZWN0aW9uIG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBib3VuZHNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXG4gKiBAcGFyYW0ge251bWJlcn0gZm92eSBWZXJ0aWNhbCBmaWVsZCBvZiB2aWV3IGluIHJhZGlhbnNcbiAqIEBwYXJhbSB7bnVtYmVyfSBhc3BlY3QgQXNwZWN0IHJhdGlvLiB0eXBpY2FsbHkgdmlld3BvcnQgd2lkdGgvaGVpZ2h0XG4gKiBAcGFyYW0ge251bWJlcn0gbmVhciBOZWFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5tYXQ0LnBlcnNwZWN0aXZlID0gZnVuY3Rpb24gKG91dCwgZm92eSwgYXNwZWN0LCBuZWFyLCBmYXIpIHtcbiAgICB2YXIgZiA9IDEuMCAvIE1hdGgudGFuKGZvdnkgLyAyKSxcbiAgICAgICAgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICAgIG91dFswXSA9IGYgLyBhc3BlY3Q7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNV0gPSBmO1xuICAgIG91dFs2XSA9IDA7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSAwO1xuICAgIG91dFs5XSA9IDA7XG4gICAgb3V0WzEwXSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICAgIG91dFsxMV0gPSAtMTtcbiAgICBvdXRbMTJdID0gMDtcbiAgICBvdXRbMTNdID0gMDtcbiAgICBvdXRbMTRdID0gKDIgKiBmYXIgKiBuZWFyKSAqIG5mO1xuICAgIG91dFsxNV0gPSAwO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHBlcnNwZWN0aXZlIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGZpZWxkIG9mIHZpZXcuXG4gKiBUaGlzIGlzIHByaW1hcmlseSB1c2VmdWwgZm9yIGdlbmVyYXRpbmcgcHJvamVjdGlvbiBtYXRyaWNlcyB0byBiZSB1c2VkXG4gKiB3aXRoIHRoZSBzdGlsbCBleHBlcmllbWVudGFsIFdlYlZSIEFQSS5cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXG4gKiBAcGFyYW0ge251bWJlcn0gZm92IE9iamVjdCBjb250YWluaW5nIHRoZSBmb2xsb3dpbmcgdmFsdWVzOiB1cERlZ3JlZXMsIGRvd25EZWdyZWVzLCBsZWZ0RGVncmVlcywgcmlnaHREZWdyZWVzXG4gKiBAcGFyYW0ge251bWJlcn0gbmVhciBOZWFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5tYXQ0LnBlcnNwZWN0aXZlRnJvbUZpZWxkT2ZWaWV3ID0gZnVuY3Rpb24gKG91dCwgZm92LCBuZWFyLCBmYXIpIHtcbiAgICB2YXIgdXBUYW4gPSBNYXRoLnRhbihmb3YudXBEZWdyZWVzICogTWF0aC5QSS8xODAuMCksXG4gICAgICAgIGRvd25UYW4gPSBNYXRoLnRhbihmb3YuZG93bkRlZ3JlZXMgKiBNYXRoLlBJLzE4MC4wKSxcbiAgICAgICAgbGVmdFRhbiA9IE1hdGgudGFuKGZvdi5sZWZ0RGVncmVlcyAqIE1hdGguUEkvMTgwLjApLFxuICAgICAgICByaWdodFRhbiA9IE1hdGgudGFuKGZvdi5yaWdodERlZ3JlZXMgKiBNYXRoLlBJLzE4MC4wKSxcbiAgICAgICAgeFNjYWxlID0gMi4wIC8gKGxlZnRUYW4gKyByaWdodFRhbiksXG4gICAgICAgIHlTY2FsZSA9IDIuMCAvICh1cFRhbiArIGRvd25UYW4pO1xuXG4gICAgb3V0WzBdID0geFNjYWxlO1xuICAgIG91dFsxXSA9IDAuMDtcbiAgICBvdXRbMl0gPSAwLjA7XG4gICAgb3V0WzNdID0gMC4wO1xuICAgIG91dFs0XSA9IDAuMDtcbiAgICBvdXRbNV0gPSB5U2NhbGU7XG4gICAgb3V0WzZdID0gMC4wO1xuICAgIG91dFs3XSA9IDAuMDtcbiAgICBvdXRbOF0gPSAtKChsZWZ0VGFuIC0gcmlnaHRUYW4pICogeFNjYWxlICogMC41KTtcbiAgICBvdXRbOV0gPSAoKHVwVGFuIC0gZG93blRhbikgKiB5U2NhbGUgKiAwLjUpO1xuICAgIG91dFsxMF0gPSBmYXIgLyAobmVhciAtIGZhcik7XG4gICAgb3V0WzExXSA9IC0xLjA7XG4gICAgb3V0WzEyXSA9IDAuMDtcbiAgICBvdXRbMTNdID0gMC4wO1xuICAgIG91dFsxNF0gPSAoZmFyICogbmVhcikgLyAobmVhciAtIGZhcik7XG4gICAgb3V0WzE1XSA9IDAuMDtcbiAgICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIG9ydGhvZ29uYWwgcHJvamVjdGlvbiBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtudW1iZXJ9IGxlZnQgTGVmdCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0IFJpZ2h0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gYm90dG9tIEJvdHRvbSBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IHRvcCBUb3AgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBmYXIgRmFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cbm1hdDQub3J0aG8gPSBmdW5jdGlvbiAob3V0LCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIG5lYXIsIGZhcikge1xuICAgIHZhciBsciA9IDEgLyAobGVmdCAtIHJpZ2h0KSxcbiAgICAgICAgYnQgPSAxIC8gKGJvdHRvbSAtIHRvcCksXG4gICAgICAgIG5mID0gMSAvIChuZWFyIC0gZmFyKTtcbiAgICBvdXRbMF0gPSAtMiAqIGxyO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IDA7XG4gICAgb3V0WzVdID0gLTIgKiBidDtcbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gMDtcbiAgICBvdXRbOV0gPSAwO1xuICAgIG91dFsxMF0gPSAyICogbmY7XG4gICAgb3V0WzExXSA9IDA7XG4gICAgb3V0WzEyXSA9IChsZWZ0ICsgcmlnaHQpICogbHI7XG4gICAgb3V0WzEzXSA9ICh0b3AgKyBib3R0b20pICogYnQ7XG4gICAgb3V0WzE0XSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICAgIG91dFsxNV0gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIGxvb2stYXQgbWF0cml4IHdpdGggdGhlIGdpdmVuIGV5ZSBwb3NpdGlvbiwgZm9jYWwgcG9pbnQsIGFuZCB1cCBheGlzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHt2ZWMzfSBleWUgUG9zaXRpb24gb2YgdGhlIHZpZXdlclxuICogQHBhcmFtIHt2ZWMzfSBjZW50ZXIgUG9pbnQgdGhlIHZpZXdlciBpcyBsb29raW5nIGF0XG4gKiBAcGFyYW0ge3ZlYzN9IHVwIHZlYzMgcG9pbnRpbmcgdXBcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xubWF0NC5sb29rQXQgPSBmdW5jdGlvbiAob3V0LCBleWUsIGNlbnRlciwgdXApIHtcbiAgICB2YXIgeDAsIHgxLCB4MiwgeTAsIHkxLCB5MiwgejAsIHoxLCB6MiwgbGVuLFxuICAgICAgICBleWV4ID0gZXllWzBdLFxuICAgICAgICBleWV5ID0gZXllWzFdLFxuICAgICAgICBleWV6ID0gZXllWzJdLFxuICAgICAgICB1cHggPSB1cFswXSxcbiAgICAgICAgdXB5ID0gdXBbMV0sXG4gICAgICAgIHVweiA9IHVwWzJdLFxuICAgICAgICBjZW50ZXJ4ID0gY2VudGVyWzBdLFxuICAgICAgICBjZW50ZXJ5ID0gY2VudGVyWzFdLFxuICAgICAgICBjZW50ZXJ6ID0gY2VudGVyWzJdO1xuXG4gICAgaWYgKE1hdGguYWJzKGV5ZXggLSBjZW50ZXJ4KSA8IGdsTWF0cml4LkVQU0lMT04gJiZcbiAgICAgICAgTWF0aC5hYnMoZXlleSAtIGNlbnRlcnkpIDwgZ2xNYXRyaXguRVBTSUxPTiAmJlxuICAgICAgICBNYXRoLmFicyhleWV6IC0gY2VudGVyeikgPCBnbE1hdHJpeC5FUFNJTE9OKSB7XG4gICAgICAgIHJldHVybiBtYXQ0LmlkZW50aXR5KG91dCk7XG4gICAgfVxuXG4gICAgejAgPSBleWV4IC0gY2VudGVyeDtcbiAgICB6MSA9IGV5ZXkgLSBjZW50ZXJ5O1xuICAgIHoyID0gZXlleiAtIGNlbnRlcno7XG5cbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KHowICogejAgKyB6MSAqIHoxICsgejIgKiB6Mik7XG4gICAgejAgKj0gbGVuO1xuICAgIHoxICo9IGxlbjtcbiAgICB6MiAqPSBsZW47XG5cbiAgICB4MCA9IHVweSAqIHoyIC0gdXB6ICogejE7XG4gICAgeDEgPSB1cHogKiB6MCAtIHVweCAqIHoyO1xuICAgIHgyID0gdXB4ICogejEgLSB1cHkgKiB6MDtcbiAgICBsZW4gPSBNYXRoLnNxcnQoeDAgKiB4MCArIHgxICogeDEgKyB4MiAqIHgyKTtcbiAgICBpZiAoIWxlbikge1xuICAgICAgICB4MCA9IDA7XG4gICAgICAgIHgxID0gMDtcbiAgICAgICAgeDIgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGxlbiA9IDEgLyBsZW47XG4gICAgICAgIHgwICo9IGxlbjtcbiAgICAgICAgeDEgKj0gbGVuO1xuICAgICAgICB4MiAqPSBsZW47XG4gICAgfVxuXG4gICAgeTAgPSB6MSAqIHgyIC0gejIgKiB4MTtcbiAgICB5MSA9IHoyICogeDAgLSB6MCAqIHgyO1xuICAgIHkyID0gejAgKiB4MSAtIHoxICogeDA7XG5cbiAgICBsZW4gPSBNYXRoLnNxcnQoeTAgKiB5MCArIHkxICogeTEgKyB5MiAqIHkyKTtcbiAgICBpZiAoIWxlbikge1xuICAgICAgICB5MCA9IDA7XG4gICAgICAgIHkxID0gMDtcbiAgICAgICAgeTIgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGxlbiA9IDEgLyBsZW47XG4gICAgICAgIHkwICo9IGxlbjtcbiAgICAgICAgeTEgKj0gbGVuO1xuICAgICAgICB5MiAqPSBsZW47XG4gICAgfVxuXG4gICAgb3V0WzBdID0geDA7XG4gICAgb3V0WzFdID0geTA7XG4gICAgb3V0WzJdID0gejA7XG4gICAgb3V0WzNdID0gMDtcbiAgICBvdXRbNF0gPSB4MTtcbiAgICBvdXRbNV0gPSB5MTtcbiAgICBvdXRbNl0gPSB6MTtcbiAgICBvdXRbN10gPSAwO1xuICAgIG91dFs4XSA9IHgyO1xuICAgIG91dFs5XSA9IHkyO1xuICAgIG91dFsxMF0gPSB6MjtcbiAgICBvdXRbMTFdID0gMDtcbiAgICBvdXRbMTJdID0gLSh4MCAqIGV5ZXggKyB4MSAqIGV5ZXkgKyB4MiAqIGV5ZXopO1xuICAgIG91dFsxM10gPSAtKHkwICogZXlleCArIHkxICogZXlleSArIHkyICogZXlleik7XG4gICAgb3V0WzE0XSA9IC0oejAgKiBleWV4ICsgejEgKiBleWV5ICsgejIgKiBleWV6KTtcbiAgICBvdXRbMTVdID0gMTtcblxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHttYXQ0fSBtYXQgbWF0cml4IHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcbiAqL1xubWF0NC5zdHIgPSBmdW5jdGlvbiAoYSkge1xuICAgIHJldHVybiAnbWF0NCgnICsgYVswXSArICcsICcgKyBhWzFdICsgJywgJyArIGFbMl0gKyAnLCAnICsgYVszXSArICcsICcgK1xuICAgICAgICAgICAgICAgICAgICBhWzRdICsgJywgJyArIGFbNV0gKyAnLCAnICsgYVs2XSArICcsICcgKyBhWzddICsgJywgJyArXG4gICAgICAgICAgICAgICAgICAgIGFbOF0gKyAnLCAnICsgYVs5XSArICcsICcgKyBhWzEwXSArICcsICcgKyBhWzExXSArICcsICcgKyBcbiAgICAgICAgICAgICAgICAgICAgYVsxMl0gKyAnLCAnICsgYVsxM10gKyAnLCAnICsgYVsxNF0gKyAnLCAnICsgYVsxNV0gKyAnKSc7XG59O1xuXG4vKipcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHttYXQ0fSBhIHRoZSBtYXRyaXggdG8gY2FsY3VsYXRlIEZyb2Jlbml1cyBub3JtIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBGcm9iZW5pdXMgbm9ybVxuICovXG5tYXQ0LmZyb2IgPSBmdW5jdGlvbiAoYSkge1xuICAgIHJldHVybihNYXRoLnNxcnQoTWF0aC5wb3coYVswXSwgMikgKyBNYXRoLnBvdyhhWzFdLCAyKSArIE1hdGgucG93KGFbMl0sIDIpICsgTWF0aC5wb3coYVszXSwgMikgKyBNYXRoLnBvdyhhWzRdLCAyKSArIE1hdGgucG93KGFbNV0sIDIpICsgTWF0aC5wb3coYVs2XSwgMikgKyBNYXRoLnBvdyhhWzddLCAyKSArIE1hdGgucG93KGFbOF0sIDIpICsgTWF0aC5wb3coYVs5XSwgMikgKyBNYXRoLnBvdyhhWzEwXSwgMikgKyBNYXRoLnBvdyhhWzExXSwgMikgKyBNYXRoLnBvdyhhWzEyXSwgMikgKyBNYXRoLnBvdyhhWzEzXSwgMikgKyBNYXRoLnBvdyhhWzE0XSwgMikgKyBNYXRoLnBvdyhhWzE1XSwgMikgKSlcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBtYXQ0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXgvbWF0NC5qc1xuICoqIG1vZHVsZSBpZCA9IDEyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiBDb3B5cmlnaHQgKGMpIDIwMTUsIEJyYW5kb24gSm9uZXMsIENvbGluIE1hY0tlbnppZSBJVi5cblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxub2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xudG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG5mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuXG5UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG5BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG5MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuVEhFIFNPRlRXQVJFLiAqL1xuXG52YXIgZ2xNYXRyaXggPSByZXF1aXJlKFwiLi9jb21tb24uanNcIik7XG52YXIgbWF0MyA9IHJlcXVpcmUoXCIuL21hdDMuanNcIik7XG52YXIgdmVjMyA9IHJlcXVpcmUoXCIuL3ZlYzMuanNcIik7XG52YXIgdmVjNCA9IHJlcXVpcmUoXCIuL3ZlYzQuanNcIik7XG5cbi8qKlxuICogQGNsYXNzIFF1YXRlcm5pb25cbiAqIEBuYW1lIHF1YXRcbiAqL1xudmFyIHF1YXQgPSB7fTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IHF1YXRcbiAqXG4gKiBAcmV0dXJucyB7cXVhdH0gYSBuZXcgcXVhdGVybmlvblxuICovXG5xdWF0LmNyZWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg0KTtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAxO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNldHMgYSBxdWF0ZXJuaW9uIHRvIHJlcHJlc2VudCB0aGUgc2hvcnRlc3Qgcm90YXRpb24gZnJvbSBvbmVcbiAqIHZlY3RvciB0byBhbm90aGVyLlxuICpcbiAqIEJvdGggdmVjdG9ycyBhcmUgYXNzdW1lZCB0byBiZSB1bml0IGxlbmd0aC5cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb24uXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGluaXRpYWwgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGIgdGhlIGRlc3RpbmF0aW9uIHZlY3RvclxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5xdWF0LnJvdGF0aW9uVG8gPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRtcHZlYzMgPSB2ZWMzLmNyZWF0ZSgpO1xuICAgIHZhciB4VW5pdFZlYzMgPSB2ZWMzLmZyb21WYWx1ZXMoMSwwLDApO1xuICAgIHZhciB5VW5pdFZlYzMgPSB2ZWMzLmZyb21WYWx1ZXMoMCwxLDApO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgICAgICB2YXIgZG90ID0gdmVjMy5kb3QoYSwgYik7XG4gICAgICAgIGlmIChkb3QgPCAtMC45OTk5OTkpIHtcbiAgICAgICAgICAgIHZlYzMuY3Jvc3ModG1wdmVjMywgeFVuaXRWZWMzLCBhKTtcbiAgICAgICAgICAgIGlmICh2ZWMzLmxlbmd0aCh0bXB2ZWMzKSA8IDAuMDAwMDAxKVxuICAgICAgICAgICAgICAgIHZlYzMuY3Jvc3ModG1wdmVjMywgeVVuaXRWZWMzLCBhKTtcbiAgICAgICAgICAgIHZlYzMubm9ybWFsaXplKHRtcHZlYzMsIHRtcHZlYzMpO1xuICAgICAgICAgICAgcXVhdC5zZXRBeGlzQW5nbGUob3V0LCB0bXB2ZWMzLCBNYXRoLlBJKTtcbiAgICAgICAgICAgIHJldHVybiBvdXQ7XG4gICAgICAgIH0gZWxzZSBpZiAoZG90ID4gMC45OTk5OTkpIHtcbiAgICAgICAgICAgIG91dFswXSA9IDA7XG4gICAgICAgICAgICBvdXRbMV0gPSAwO1xuICAgICAgICAgICAgb3V0WzJdID0gMDtcbiAgICAgICAgICAgIG91dFszXSA9IDE7XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmVjMy5jcm9zcyh0bXB2ZWMzLCBhLCBiKTtcbiAgICAgICAgICAgIG91dFswXSA9IHRtcHZlYzNbMF07XG4gICAgICAgICAgICBvdXRbMV0gPSB0bXB2ZWMzWzFdO1xuICAgICAgICAgICAgb3V0WzJdID0gdG1wdmVjM1syXTtcbiAgICAgICAgICAgIG91dFszXSA9IDEgKyBkb3Q7XG4gICAgICAgICAgICByZXR1cm4gcXVhdC5ub3JtYWxpemUob3V0LCBvdXQpO1xuICAgICAgICB9XG4gICAgfTtcbn0pKCk7XG5cbi8qKlxuICogU2V0cyB0aGUgc3BlY2lmaWVkIHF1YXRlcm5pb24gd2l0aCB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW5cbiAqIGF4ZXMuIEVhY2ggYXhpcyBpcyBhIHZlYzMgYW5kIGlzIGV4cGVjdGVkIHRvIGJlIHVuaXQgbGVuZ3RoIGFuZFxuICogcGVycGVuZGljdWxhciB0byBhbGwgb3RoZXIgc3BlY2lmaWVkIGF4ZXMuXG4gKlxuICogQHBhcmFtIHt2ZWMzfSB2aWV3ICB0aGUgdmVjdG9yIHJlcHJlc2VudGluZyB0aGUgdmlld2luZyBkaXJlY3Rpb25cbiAqIEBwYXJhbSB7dmVjM30gcmlnaHQgdGhlIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIGxvY2FsIFwicmlnaHRcIiBkaXJlY3Rpb25cbiAqIEBwYXJhbSB7dmVjM30gdXAgICAgdGhlIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIGxvY2FsIFwidXBcIiBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xucXVhdC5zZXRBeGVzID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBtYXRyID0gbWF0My5jcmVhdGUoKTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvdXQsIHZpZXcsIHJpZ2h0LCB1cCkge1xuICAgICAgICBtYXRyWzBdID0gcmlnaHRbMF07XG4gICAgICAgIG1hdHJbM10gPSByaWdodFsxXTtcbiAgICAgICAgbWF0cls2XSA9IHJpZ2h0WzJdO1xuXG4gICAgICAgIG1hdHJbMV0gPSB1cFswXTtcbiAgICAgICAgbWF0cls0XSA9IHVwWzFdO1xuICAgICAgICBtYXRyWzddID0gdXBbMl07XG5cbiAgICAgICAgbWF0clsyXSA9IC12aWV3WzBdO1xuICAgICAgICBtYXRyWzVdID0gLXZpZXdbMV07XG4gICAgICAgIG1hdHJbOF0gPSAtdmlld1syXTtcblxuICAgICAgICByZXR1cm4gcXVhdC5ub3JtYWxpemUob3V0LCBxdWF0LmZyb21NYXQzKG91dCwgbWF0cikpO1xuICAgIH07XG59KSgpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgcXVhdCBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IGEgcXVhdGVybmlvbiB0byBjbG9uZVxuICogQHJldHVybnMge3F1YXR9IGEgbmV3IHF1YXRlcm5pb25cbiAqIEBmdW5jdGlvblxuICovXG5xdWF0LmNsb25lID0gdmVjNC5jbG9uZTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHF1YXQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcgVyBjb21wb25lbnRcbiAqIEByZXR1cm5zIHtxdWF0fSBhIG5ldyBxdWF0ZXJuaW9uXG4gKiBAZnVuY3Rpb25cbiAqL1xucXVhdC5mcm9tVmFsdWVzID0gdmVjNC5mcm9tVmFsdWVzO1xuXG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBxdWF0IHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7cXVhdH0gYSB0aGUgc291cmNlIHF1YXRlcm5pb25cbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqIEBmdW5jdGlvblxuICovXG5xdWF0LmNvcHkgPSB2ZWM0LmNvcHk7XG5cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgcXVhdCB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0gdyBXIGNvbXBvbmVudFxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cbnF1YXQuc2V0ID0gdmVjNC5zZXQ7XG5cbi8qKlxuICogU2V0IGEgcXVhdCB0byB0aGUgaWRlbnRpdHkgcXVhdGVybmlvblxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5xdWF0LmlkZW50aXR5ID0gZnVuY3Rpb24ob3V0KSB7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTZXRzIGEgcXVhdCBmcm9tIHRoZSBnaXZlbiBhbmdsZSBhbmQgcm90YXRpb24gYXhpcyxcbiAqIHRoZW4gcmV0dXJucyBpdC5cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7dmVjM30gYXhpcyB0aGUgYXhpcyBhcm91bmQgd2hpY2ggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSBpbiByYWRpYW5zXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiovXG5xdWF0LnNldEF4aXNBbmdsZSA9IGZ1bmN0aW9uKG91dCwgYXhpcywgcmFkKSB7XG4gICAgcmFkID0gcmFkICogMC41O1xuICAgIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgICBvdXRbMF0gPSBzICogYXhpc1swXTtcbiAgICBvdXRbMV0gPSBzICogYXhpc1sxXTtcbiAgICBvdXRbMl0gPSBzICogYXhpc1syXTtcbiAgICBvdXRbM10gPSBNYXRoLmNvcyhyYWQpO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEFkZHMgdHdvIHF1YXQnc1xuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtxdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3F1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xucXVhdC5hZGQgPSB2ZWM0LmFkZDtcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBxdWF0J3NcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7cXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtxdWF0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5xdWF0Lm11bHRpcGx5ID0gZnVuY3Rpb24ob3V0LCBhLCBiKSB7XG4gICAgdmFyIGF4ID0gYVswXSwgYXkgPSBhWzFdLCBheiA9IGFbMl0sIGF3ID0gYVszXSxcbiAgICAgICAgYnggPSBiWzBdLCBieSA9IGJbMV0sIGJ6ID0gYlsyXSwgYncgPSBiWzNdO1xuXG4gICAgb3V0WzBdID0gYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieTtcbiAgICBvdXRbMV0gPSBheSAqIGJ3ICsgYXcgKiBieSArIGF6ICogYnggLSBheCAqIGJ6O1xuICAgIG91dFsyXSA9IGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYng7XG4gICAgb3V0WzNdID0gYXcgKiBidyAtIGF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHF1YXQubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xucXVhdC5tdWwgPSBxdWF0Lm11bHRpcGx5O1xuXG4vKipcbiAqIFNjYWxlcyBhIHF1YXQgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7cXVhdH0gYSB0aGUgdmVjdG9yIHRvIHNjYWxlXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cbnF1YXQuc2NhbGUgPSB2ZWM0LnNjYWxlO1xuXG4vKipcbiAqIFJvdGF0ZXMgYSBxdWF0ZXJuaW9uIGJ5IHRoZSBnaXZlbiBhbmdsZSBhYm91dCB0aGUgWCBheGlzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgcXVhdCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtxdWF0fSBhIHF1YXQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGFuZ2xlIChpbiByYWRpYW5zKSB0byByb3RhdGVcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xucXVhdC5yb3RhdGVYID0gZnVuY3Rpb24gKG91dCwgYSwgcmFkKSB7XG4gICAgcmFkICo9IDAuNTsgXG5cbiAgICB2YXIgYXggPSBhWzBdLCBheSA9IGFbMV0sIGF6ID0gYVsyXSwgYXcgPSBhWzNdLFxuICAgICAgICBieCA9IE1hdGguc2luKHJhZCksIGJ3ID0gTWF0aC5jb3MocmFkKTtcblxuICAgIG91dFswXSA9IGF4ICogYncgKyBhdyAqIGJ4O1xuICAgIG91dFsxXSA9IGF5ICogYncgKyBheiAqIGJ4O1xuICAgIG91dFsyXSA9IGF6ICogYncgLSBheSAqIGJ4O1xuICAgIG91dFszXSA9IGF3ICogYncgLSBheCAqIGJ4O1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJvdGF0ZXMgYSBxdWF0ZXJuaW9uIGJ5IHRoZSBnaXZlbiBhbmdsZSBhYm91dCB0aGUgWSBheGlzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgcXVhdCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtxdWF0fSBhIHF1YXQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGFuZ2xlIChpbiByYWRpYW5zKSB0byByb3RhdGVcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xucXVhdC5yb3RhdGVZID0gZnVuY3Rpb24gKG91dCwgYSwgcmFkKSB7XG4gICAgcmFkICo9IDAuNTsgXG5cbiAgICB2YXIgYXggPSBhWzBdLCBheSA9IGFbMV0sIGF6ID0gYVsyXSwgYXcgPSBhWzNdLFxuICAgICAgICBieSA9IE1hdGguc2luKHJhZCksIGJ3ID0gTWF0aC5jb3MocmFkKTtcblxuICAgIG91dFswXSA9IGF4ICogYncgLSBheiAqIGJ5O1xuICAgIG91dFsxXSA9IGF5ICogYncgKyBhdyAqIGJ5O1xuICAgIG91dFsyXSA9IGF6ICogYncgKyBheCAqIGJ5O1xuICAgIG91dFszXSA9IGF3ICogYncgLSBheSAqIGJ5O1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJvdGF0ZXMgYSBxdWF0ZXJuaW9uIGJ5IHRoZSBnaXZlbiBhbmdsZSBhYm91dCB0aGUgWiBheGlzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgcXVhdCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtxdWF0fSBhIHF1YXQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGFuZ2xlIChpbiByYWRpYW5zKSB0byByb3RhdGVcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xucXVhdC5yb3RhdGVaID0gZnVuY3Rpb24gKG91dCwgYSwgcmFkKSB7XG4gICAgcmFkICo9IDAuNTsgXG5cbiAgICB2YXIgYXggPSBhWzBdLCBheSA9IGFbMV0sIGF6ID0gYVsyXSwgYXcgPSBhWzNdLFxuICAgICAgICBieiA9IE1hdGguc2luKHJhZCksIGJ3ID0gTWF0aC5jb3MocmFkKTtcblxuICAgIG91dFswXSA9IGF4ICogYncgKyBheSAqIGJ6O1xuICAgIG91dFsxXSA9IGF5ICogYncgLSBheCAqIGJ6O1xuICAgIG91dFsyXSA9IGF6ICogYncgKyBhdyAqIGJ6O1xuICAgIG91dFszXSA9IGF3ICogYncgLSBheiAqIGJ6O1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIFcgY29tcG9uZW50IG9mIGEgcXVhdCBmcm9tIHRoZSBYLCBZLCBhbmQgWiBjb21wb25lbnRzLlxuICogQXNzdW1lcyB0aGF0IHF1YXRlcm5pb24gaXMgMSB1bml0IGluIGxlbmd0aC5cbiAqIEFueSBleGlzdGluZyBXIGNvbXBvbmVudCB3aWxsIGJlIGlnbm9yZWQuXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge3F1YXR9IGEgcXVhdCB0byBjYWxjdWxhdGUgVyBjb21wb25lbnQgb2ZcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xucXVhdC5jYWxjdWxhdGVXID0gZnVuY3Rpb24gKG91dCwgYSkge1xuICAgIHZhciB4ID0gYVswXSwgeSA9IGFbMV0sIHogPSBhWzJdO1xuXG4gICAgb3V0WzBdID0geDtcbiAgICBvdXRbMV0gPSB5O1xuICAgIG91dFsyXSA9IHo7XG4gICAgb3V0WzNdID0gTWF0aC5zcXJ0KE1hdGguYWJzKDEuMCAtIHggKiB4IC0geSAqIHkgLSB6ICogeikpO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byBxdWF0J3NcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7cXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcbiAqIEBmdW5jdGlvblxuICovXG5xdWF0LmRvdCA9IHZlYzQuZG90O1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gcXVhdCdzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge3F1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7cXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50IGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqIEBmdW5jdGlvblxuICovXG5xdWF0LmxlcnAgPSB2ZWM0LmxlcnA7XG5cbi8qKlxuICogUGVyZm9ybXMgYSBzcGhlcmljYWwgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gcXVhdFxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtxdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3F1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cbnF1YXQuc2xlcnAgPSBmdW5jdGlvbiAob3V0LCBhLCBiLCB0KSB7XG4gICAgLy8gYmVuY2htYXJrczpcbiAgICAvLyAgICBodHRwOi8vanNwZXJmLmNvbS9xdWF0ZXJuaW9uLXNsZXJwLWltcGxlbWVudGF0aW9uc1xuXG4gICAgdmFyIGF4ID0gYVswXSwgYXkgPSBhWzFdLCBheiA9IGFbMl0sIGF3ID0gYVszXSxcbiAgICAgICAgYnggPSBiWzBdLCBieSA9IGJbMV0sIGJ6ID0gYlsyXSwgYncgPSBiWzNdO1xuXG4gICAgdmFyICAgICAgICBvbWVnYSwgY29zb20sIHNpbm9tLCBzY2FsZTAsIHNjYWxlMTtcblxuICAgIC8vIGNhbGMgY29zaW5lXG4gICAgY29zb20gPSBheCAqIGJ4ICsgYXkgKiBieSArIGF6ICogYnogKyBhdyAqIGJ3O1xuICAgIC8vIGFkanVzdCBzaWducyAoaWYgbmVjZXNzYXJ5KVxuICAgIGlmICggY29zb20gPCAwLjAgKSB7XG4gICAgICAgIGNvc29tID0gLWNvc29tO1xuICAgICAgICBieCA9IC0gYng7XG4gICAgICAgIGJ5ID0gLSBieTtcbiAgICAgICAgYnogPSAtIGJ6O1xuICAgICAgICBidyA9IC0gYnc7XG4gICAgfVxuICAgIC8vIGNhbGN1bGF0ZSBjb2VmZmljaWVudHNcbiAgICBpZiAoICgxLjAgLSBjb3NvbSkgPiAwLjAwMDAwMSApIHtcbiAgICAgICAgLy8gc3RhbmRhcmQgY2FzZSAoc2xlcnApXG4gICAgICAgIG9tZWdhICA9IE1hdGguYWNvcyhjb3NvbSk7XG4gICAgICAgIHNpbm9tICA9IE1hdGguc2luKG9tZWdhKTtcbiAgICAgICAgc2NhbGUwID0gTWF0aC5zaW4oKDEuMCAtIHQpICogb21lZ2EpIC8gc2lub207XG4gICAgICAgIHNjYWxlMSA9IE1hdGguc2luKHQgKiBvbWVnYSkgLyBzaW5vbTtcbiAgICB9IGVsc2UgeyAgICAgICAgXG4gICAgICAgIC8vIFwiZnJvbVwiIGFuZCBcInRvXCIgcXVhdGVybmlvbnMgYXJlIHZlcnkgY2xvc2UgXG4gICAgICAgIC8vICAuLi4gc28gd2UgY2FuIGRvIGEgbGluZWFyIGludGVycG9sYXRpb25cbiAgICAgICAgc2NhbGUwID0gMS4wIC0gdDtcbiAgICAgICAgc2NhbGUxID0gdDtcbiAgICB9XG4gICAgLy8gY2FsY3VsYXRlIGZpbmFsIHZhbHVlc1xuICAgIG91dFswXSA9IHNjYWxlMCAqIGF4ICsgc2NhbGUxICogYng7XG4gICAgb3V0WzFdID0gc2NhbGUwICogYXkgKyBzY2FsZTEgKiBieTtcbiAgICBvdXRbMl0gPSBzY2FsZTAgKiBheiArIHNjYWxlMSAqIGJ6O1xuICAgIG91dFszXSA9IHNjYWxlMCAqIGF3ICsgc2NhbGUxICogYnc7XG4gICAgXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUGVyZm9ybXMgYSBzcGhlcmljYWwgbGluZWFyIGludGVycG9sYXRpb24gd2l0aCB0d28gY29udHJvbCBwb2ludHNcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7cXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtxdWF0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtxdWF0fSBjIHRoZSB0aGlyZCBvcGVyYW5kXG4gKiBAcGFyYW0ge3F1YXR9IGQgdGhlIGZvdXJ0aCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudFxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5xdWF0LnNxbGVycCA9IChmdW5jdGlvbiAoKSB7XG4gIHZhciB0ZW1wMSA9IHF1YXQuY3JlYXRlKCk7XG4gIHZhciB0ZW1wMiA9IHF1YXQuY3JlYXRlKCk7XG4gIFxuICByZXR1cm4gZnVuY3Rpb24gKG91dCwgYSwgYiwgYywgZCwgdCkge1xuICAgIHF1YXQuc2xlcnAodGVtcDEsIGEsIGQsIHQpO1xuICAgIHF1YXQuc2xlcnAodGVtcDIsIGIsIGMsIHQpO1xuICAgIHF1YXQuc2xlcnAob3V0LCB0ZW1wMSwgdGVtcDIsIDIgKiB0ICogKDEgLSB0KSk7XG4gICAgXG4gICAgcmV0dXJuIG91dDtcbiAgfTtcbn0oKSk7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgaW52ZXJzZSBvZiBhIHF1YXRcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7cXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBpbnZlcnNlIG9mXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cbnF1YXQuaW52ZXJ0ID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgdmFyIGEwID0gYVswXSwgYTEgPSBhWzFdLCBhMiA9IGFbMl0sIGEzID0gYVszXSxcbiAgICAgICAgZG90ID0gYTAqYTAgKyBhMSphMSArIGEyKmEyICsgYTMqYTMsXG4gICAgICAgIGludkRvdCA9IGRvdCA/IDEuMC9kb3QgOiAwO1xuICAgIFxuICAgIC8vIFRPRE86IFdvdWxkIGJlIGZhc3RlciB0byByZXR1cm4gWzAsMCwwLDBdIGltbWVkaWF0ZWx5IGlmIGRvdCA9PSAwXG5cbiAgICBvdXRbMF0gPSAtYTAqaW52RG90O1xuICAgIG91dFsxXSA9IC1hMSppbnZEb3Q7XG4gICAgb3V0WzJdID0gLWEyKmludkRvdDtcbiAgICBvdXRbM10gPSBhMyppbnZEb3Q7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY29uanVnYXRlIG9mIGEgcXVhdFxuICogSWYgdGhlIHF1YXRlcm5pb24gaXMgbm9ybWFsaXplZCwgdGhpcyBmdW5jdGlvbiBpcyBmYXN0ZXIgdGhhbiBxdWF0LmludmVyc2UgYW5kIHByb2R1Y2VzIHRoZSBzYW1lIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7cXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBjb25qdWdhdGUgb2ZcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xucXVhdC5jb25qdWdhdGUgPSBmdW5jdGlvbiAob3V0LCBhKSB7XG4gICAgb3V0WzBdID0gLWFbMF07XG4gICAgb3V0WzFdID0gLWFbMV07XG4gICAgb3V0WzJdID0gLWFbMl07XG4gICAgb3V0WzNdID0gYVszXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgYSBxdWF0XG4gKlxuICogQHBhcmFtIHtxdWF0fSBhIHZlY3RvciB0byBjYWxjdWxhdGUgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBsZW5ndGggb2YgYVxuICogQGZ1bmN0aW9uXG4gKi9cbnF1YXQubGVuZ3RoID0gdmVjNC5sZW5ndGg7XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0Lmxlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG5xdWF0LmxlbiA9IHF1YXQubGVuZ3RoO1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgbGVuZ3RoIG9mIGEgcXVhdFxuICpcbiAqIEBwYXJhbSB7cXVhdH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGxlbmd0aCBvZiBhXG4gKiBAZnVuY3Rpb25cbiAqL1xucXVhdC5zcXVhcmVkTGVuZ3RoID0gdmVjNC5zcXVhcmVkTGVuZ3RoO1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgcXVhdC5zcXVhcmVkTGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cbnF1YXQuc3FyTGVuID0gcXVhdC5zcXVhcmVkTGVuZ3RoO1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBhIHF1YXRcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7cXVhdH0gYSBxdWF0ZXJuaW9uIHRvIG5vcm1hbGl6ZVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cbnF1YXQubm9ybWFsaXplID0gdmVjNC5ub3JtYWxpemU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHF1YXRlcm5pb24gZnJvbSB0aGUgZ2l2ZW4gM3gzIHJvdGF0aW9uIG1hdHJpeC5cbiAqXG4gKiBOT1RFOiBUaGUgcmVzdWx0YW50IHF1YXRlcm5pb24gaXMgbm90IG5vcm1hbGl6ZWQsIHNvIHlvdSBzaG91bGQgYmUgc3VyZVxuICogdG8gcmVub3JtYWxpemUgdGhlIHF1YXRlcm5pb24geW91cnNlbGYgd2hlcmUgbmVjZXNzYXJ5LlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHttYXQzfSBtIHJvdGF0aW9uIG1hdHJpeFxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cbnF1YXQuZnJvbU1hdDMgPSBmdW5jdGlvbihvdXQsIG0pIHtcbiAgICAvLyBBbGdvcml0aG0gaW4gS2VuIFNob2VtYWtlJ3MgYXJ0aWNsZSBpbiAxOTg3IFNJR0dSQVBIIGNvdXJzZSBub3Rlc1xuICAgIC8vIGFydGljbGUgXCJRdWF0ZXJuaW9uIENhbGN1bHVzIGFuZCBGYXN0IEFuaW1hdGlvblwiLlxuICAgIHZhciBmVHJhY2UgPSBtWzBdICsgbVs0XSArIG1bOF07XG4gICAgdmFyIGZSb290O1xuXG4gICAgaWYgKCBmVHJhY2UgPiAwLjAgKSB7XG4gICAgICAgIC8vIHx3fCA+IDEvMiwgbWF5IGFzIHdlbGwgY2hvb3NlIHcgPiAxLzJcbiAgICAgICAgZlJvb3QgPSBNYXRoLnNxcnQoZlRyYWNlICsgMS4wKTsgIC8vIDJ3XG4gICAgICAgIG91dFszXSA9IDAuNSAqIGZSb290O1xuICAgICAgICBmUm9vdCA9IDAuNS9mUm9vdDsgIC8vIDEvKDR3KVxuICAgICAgICBvdXRbMF0gPSAobVs1XS1tWzddKSpmUm9vdDtcbiAgICAgICAgb3V0WzFdID0gKG1bNl0tbVsyXSkqZlJvb3Q7XG4gICAgICAgIG91dFsyXSA9IChtWzFdLW1bM10pKmZSb290O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHx3fCA8PSAxLzJcbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICBpZiAoIG1bNF0gPiBtWzBdIClcbiAgICAgICAgICBpID0gMTtcbiAgICAgICAgaWYgKCBtWzhdID4gbVtpKjMraV0gKVxuICAgICAgICAgIGkgPSAyO1xuICAgICAgICB2YXIgaiA9IChpKzEpJTM7XG4gICAgICAgIHZhciBrID0gKGkrMiklMztcbiAgICAgICAgXG4gICAgICAgIGZSb290ID0gTWF0aC5zcXJ0KG1baSozK2ldLW1baiozK2pdLW1bayozK2tdICsgMS4wKTtcbiAgICAgICAgb3V0W2ldID0gMC41ICogZlJvb3Q7XG4gICAgICAgIGZSb290ID0gMC41IC8gZlJvb3Q7XG4gICAgICAgIG91dFszXSA9IChtW2oqMytrXSAtIG1bayozK2pdKSAqIGZSb290O1xuICAgICAgICBvdXRbal0gPSAobVtqKjMraV0gKyBtW2kqMytqXSkgKiBmUm9vdDtcbiAgICAgICAgb3V0W2tdID0gKG1bayozK2ldICsgbVtpKjMra10pICogZlJvb3Q7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBxdWF0ZW5pb25cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IHZlYyB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxuICovXG5xdWF0LnN0ciA9IGZ1bmN0aW9uIChhKSB7XG4gICAgcmV0dXJuICdxdWF0KCcgKyBhWzBdICsgJywgJyArIGFbMV0gKyAnLCAnICsgYVsyXSArICcsICcgKyBhWzNdICsgJyknO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBxdWF0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXgvcXVhdC5qc1xuICoqIG1vZHVsZSBpZCA9IDEzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiBDb3B5cmlnaHQgKGMpIDIwMTUsIEJyYW5kb24gSm9uZXMsIENvbGluIE1hY0tlbnppZSBJVi5cblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxub2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xudG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG5mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuXG5UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG5BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG5MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuVEhFIFNPRlRXQVJFLiAqL1xuXG52YXIgZ2xNYXRyaXggPSByZXF1aXJlKFwiLi9jb21tb24uanNcIik7XG5cbi8qKlxuICogQGNsYXNzIDMgRGltZW5zaW9uYWwgVmVjdG9yXG4gKiBAbmFtZSB2ZWMzXG4gKi9cbnZhciB2ZWMzID0ge307XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgdmVjM1xuICpcbiAqIEByZXR1cm5zIHt2ZWMzfSBhIG5ldyAzRCB2ZWN0b3JcbiAqL1xudmVjMy5jcmVhdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWMzIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgdmVjdG9yXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBhIHZlY3RvciB0byBjbG9uZVxuICogQHJldHVybnMge3ZlYzN9IGEgbmV3IDNEIHZlY3RvclxuICovXG52ZWMzLmNsb25lID0gZnVuY3Rpb24oYSkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzMgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxuICogQHJldHVybnMge3ZlYzN9IGEgbmV3IDNEIHZlY3RvclxuICovXG52ZWMzLmZyb21WYWx1ZXMgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDMpO1xuICAgIG91dFswXSA9IHg7XG4gICAgb3V0WzFdID0geTtcbiAgICBvdXRbMl0gPSB6O1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSB2ZWMzIHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHRoZSBzb3VyY2UgdmVjdG9yXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMuY29weSA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVsxXTtcbiAgICBvdXRbMl0gPSBhWzJdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzMgdG8gdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMuc2V0ID0gZnVuY3Rpb24ob3V0LCB4LCB5LCB6KSB7XG4gICAgb3V0WzBdID0geDtcbiAgICBvdXRbMV0gPSB5O1xuICAgIG91dFsyXSA9IHo7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWRkcyB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLmFkZCA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICAgIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICAgIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFN1YnRyYWN0cyB2ZWN0b3IgYiBmcm9tIHZlY3RvciBhXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLnN1YnRyYWN0ID0gZnVuY3Rpb24ob3V0LCBhLCBiKSB7XG4gICAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gICAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gICAgb3V0WzJdID0gYVsyXSAtIGJbMl07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzMuc3ViID0gdmVjMy5zdWJ0cmFjdDtcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMubXVsdGlwbHkgPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgICBvdXRbMV0gPSBhWzFdICogYlsxXTtcbiAgICBvdXRbMl0gPSBhWzJdICogYlsyXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjMy5tdWwgPSB2ZWMzLm11bHRpcGx5O1xuXG4vKipcbiAqIERpdmlkZXMgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5kaXZpZGUgPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBhWzBdIC8gYlswXTtcbiAgICBvdXRbMV0gPSBhWzFdIC8gYlsxXTtcbiAgICBvdXRbMl0gPSBhWzJdIC8gYlsyXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMuZGl2aWRlfVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzMuZGl2ID0gdmVjMy5kaXZpZGU7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWluaW11bSBvZiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLm1pbiA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IE1hdGgubWluKGFbMF0sIGJbMF0pO1xuICAgIG91dFsxXSA9IE1hdGgubWluKGFbMV0sIGJbMV0pO1xuICAgIG91dFsyXSA9IE1hdGgubWluKGFbMl0sIGJbMl0pO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG1heGltdW0gb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5tYXggPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBNYXRoLm1heChhWzBdLCBiWzBdKTtcbiAgICBvdXRbMV0gPSBNYXRoLm1heChhWzFdLCBiWzFdKTtcbiAgICBvdXRbMl0gPSBNYXRoLm1heChhWzJdLCBiWzJdKTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTY2FsZXMgYSB2ZWMzIGJ5IGEgc2NhbGFyIG51bWJlclxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIHZlY3RvciB0byBzY2FsZVxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSB2ZWN0b3IgYnlcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5zY2FsZSA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gKiBiO1xuICAgIG91dFsxXSA9IGFbMV0gKiBiO1xuICAgIG91dFsyXSA9IGFbMl0gKiBiO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEFkZHMgdHdvIHZlYzMncyBhZnRlciBzY2FsaW5nIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZVxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIgYnkgYmVmb3JlIGFkZGluZ1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLnNjYWxlQW5kQWRkID0gZnVuY3Rpb24ob3V0LCBhLCBiLCBzY2FsZSkge1xuICAgIG91dFswXSA9IGFbMF0gKyAoYlswXSAqIHNjYWxlKTtcbiAgICBvdXRbMV0gPSBhWzFdICsgKGJbMV0gKiBzY2FsZSk7XG4gICAgb3V0WzJdID0gYVsyXSArIChiWzJdICogc2NhbGUpO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxuICovXG52ZWMzLmRpc3RhbmNlID0gZnVuY3Rpb24oYSwgYikge1xuICAgIHZhciB4ID0gYlswXSAtIGFbMF0sXG4gICAgICAgIHkgPSBiWzFdIC0gYVsxXSxcbiAgICAgICAgeiA9IGJbMl0gLSBhWzJdO1xuICAgIHJldHVybiBNYXRoLnNxcnQoeCp4ICsgeSp5ICsgeip6KTtcbn07XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLmRpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzMuZGlzdCA9IHZlYzMuZGlzdGFuY2U7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxuICovXG52ZWMzLnNxdWFyZWREaXN0YW5jZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgeCA9IGJbMF0gLSBhWzBdLFxuICAgICAgICB5ID0gYlsxXSAtIGFbMV0sXG4gICAgICAgIHogPSBiWzJdIC0gYVsyXTtcbiAgICByZXR1cm4geCp4ICsgeSp5ICsgeip6O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMuc3F1YXJlZERpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzMuc3FyRGlzdCA9IHZlYzMuc3F1YXJlZERpc3RhbmNlO1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGxlbmd0aCBvZiBhXG4gKi9cbnZlYzMubGVuZ3RoID0gZnVuY3Rpb24gKGEpIHtcbiAgICB2YXIgeCA9IGFbMF0sXG4gICAgICAgIHkgPSBhWzFdLFxuICAgICAgICB6ID0gYVsyXTtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KHgqeCArIHkqeSArIHoqeik7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5sZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjMy5sZW4gPSB2ZWMzLmxlbmd0aDtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGxlbmd0aCBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBzcXVhcmVkIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxuICovXG52ZWMzLnNxdWFyZWRMZW5ndGggPSBmdW5jdGlvbiAoYSkge1xuICAgIHZhciB4ID0gYVswXSxcbiAgICAgICAgeSA9IGFbMV0sXG4gICAgICAgIHogPSBhWzJdO1xuICAgIHJldHVybiB4KnggKyB5KnkgKyB6Kno7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5zcXVhcmVkTGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzMuc3FyTGVuID0gdmVjMy5zcXVhcmVkTGVuZ3RoO1xuXG4vKipcbiAqIE5lZ2F0ZXMgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjM30gYSB2ZWN0b3IgdG8gbmVnYXRlXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMubmVnYXRlID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgb3V0WzBdID0gLWFbMF07XG4gICAgb3V0WzFdID0gLWFbMV07XG4gICAgb3V0WzJdID0gLWFbMl07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaW52ZXJzZSBvZiB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHZlY3RvciB0byBpbnZlcnRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5pbnZlcnNlID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gIG91dFswXSA9IDEuMCAvIGFbMF07XG4gIG91dFsxXSA9IDEuMCAvIGFbMV07XG4gIG91dFsyXSA9IDEuMCAvIGFbMl07XG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHZlY3RvciB0byBub3JtYWxpemVcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5ub3JtYWxpemUgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICB2YXIgeCA9IGFbMF0sXG4gICAgICAgIHkgPSBhWzFdLFxuICAgICAgICB6ID0gYVsyXTtcbiAgICB2YXIgbGVuID0geCp4ICsgeSp5ICsgeip6O1xuICAgIGlmIChsZW4gPiAwKSB7XG4gICAgICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/XG4gICAgICAgIGxlbiA9IDEgLyBNYXRoLnNxcnQobGVuKTtcbiAgICAgICAgb3V0WzBdID0gYVswXSAqIGxlbjtcbiAgICAgICAgb3V0WzFdID0gYVsxXSAqIGxlbjtcbiAgICAgICAgb3V0WzJdID0gYVsyXSAqIGxlbjtcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gZG90IHByb2R1Y3Qgb2YgYSBhbmQgYlxuICovXG52ZWMzLmRvdCA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXTtcbn07XG5cbi8qKlxuICogQ29tcHV0ZXMgdGhlIGNyb3NzIHByb2R1Y3Qgb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5jcm9zcyA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIHZhciBheCA9IGFbMF0sIGF5ID0gYVsxXSwgYXogPSBhWzJdLFxuICAgICAgICBieCA9IGJbMF0sIGJ5ID0gYlsxXSwgYnogPSBiWzJdO1xuXG4gICAgb3V0WzBdID0gYXkgKiBieiAtIGF6ICogYnk7XG4gICAgb3V0WzFdID0gYXogKiBieCAtIGF4ICogYno7XG4gICAgb3V0WzJdID0gYXggKiBieSAtIGF5ICogYng7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUGVyZm9ybXMgYSBsaW5lYXIgaW50ZXJwb2xhdGlvbiBiZXR3ZWVuIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMubGVycCA9IGZ1bmN0aW9uIChvdXQsIGEsIGIsIHQpIHtcbiAgICB2YXIgYXggPSBhWzBdLFxuICAgICAgICBheSA9IGFbMV0sXG4gICAgICAgIGF6ID0gYVsyXTtcbiAgICBvdXRbMF0gPSBheCArIHQgKiAoYlswXSAtIGF4KTtcbiAgICBvdXRbMV0gPSBheSArIHQgKiAoYlsxXSAtIGF5KTtcbiAgICBvdXRbMl0gPSBheiArIHQgKiAoYlsyXSAtIGF6KTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGhlcm1pdGUgaW50ZXJwb2xhdGlvbiB3aXRoIHR3byBjb250cm9sIHBvaW50c1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYyB0aGUgdGhpcmQgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBkIHRoZSBmb3VydGggb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLmhlcm1pdGUgPSBmdW5jdGlvbiAob3V0LCBhLCBiLCBjLCBkLCB0KSB7XG4gIHZhciBmYWN0b3JUaW1lczIgPSB0ICogdCxcbiAgICAgIGZhY3RvcjEgPSBmYWN0b3JUaW1lczIgKiAoMiAqIHQgLSAzKSArIDEsXG4gICAgICBmYWN0b3IyID0gZmFjdG9yVGltZXMyICogKHQgLSAyKSArIHQsXG4gICAgICBmYWN0b3IzID0gZmFjdG9yVGltZXMyICogKHQgLSAxKSxcbiAgICAgIGZhY3RvcjQgPSBmYWN0b3JUaW1lczIgKiAoMyAtIDIgKiB0KTtcbiAgXG4gIG91dFswXSA9IGFbMF0gKiBmYWN0b3IxICsgYlswXSAqIGZhY3RvcjIgKyBjWzBdICogZmFjdG9yMyArIGRbMF0gKiBmYWN0b3I0O1xuICBvdXRbMV0gPSBhWzFdICogZmFjdG9yMSArIGJbMV0gKiBmYWN0b3IyICsgY1sxXSAqIGZhY3RvcjMgKyBkWzFdICogZmFjdG9yNDtcbiAgb3V0WzJdID0gYVsyXSAqIGZhY3RvcjEgKyBiWzJdICogZmFjdG9yMiArIGNbMl0gKiBmYWN0b3IzICsgZFsyXSAqIGZhY3RvcjQ7XG4gIFxuICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJlemllciBpbnRlcnBvbGF0aW9uIHdpdGggdHdvIGNvbnRyb2wgcG9pbnRzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMzfSBjIHRoZSB0aGlyZCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzN9IGQgdGhlIGZvdXJ0aCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMuYmV6aWVyID0gZnVuY3Rpb24gKG91dCwgYSwgYiwgYywgZCwgdCkge1xuICB2YXIgaW52ZXJzZUZhY3RvciA9IDEgLSB0LFxuICAgICAgaW52ZXJzZUZhY3RvclRpbWVzVHdvID0gaW52ZXJzZUZhY3RvciAqIGludmVyc2VGYWN0b3IsXG4gICAgICBmYWN0b3JUaW1lczIgPSB0ICogdCxcbiAgICAgIGZhY3RvcjEgPSBpbnZlcnNlRmFjdG9yVGltZXNUd28gKiBpbnZlcnNlRmFjdG9yLFxuICAgICAgZmFjdG9yMiA9IDMgKiB0ICogaW52ZXJzZUZhY3RvclRpbWVzVHdvLFxuICAgICAgZmFjdG9yMyA9IDMgKiBmYWN0b3JUaW1lczIgKiBpbnZlcnNlRmFjdG9yLFxuICAgICAgZmFjdG9yNCA9IGZhY3RvclRpbWVzMiAqIHQ7XG4gIFxuICBvdXRbMF0gPSBhWzBdICogZmFjdG9yMSArIGJbMF0gKiBmYWN0b3IyICsgY1swXSAqIGZhY3RvcjMgKyBkWzBdICogZmFjdG9yNDtcbiAgb3V0WzFdID0gYVsxXSAqIGZhY3RvcjEgKyBiWzFdICogZmFjdG9yMiArIGNbMV0gKiBmYWN0b3IzICsgZFsxXSAqIGZhY3RvcjQ7XG4gIG91dFsyXSA9IGFbMl0gKiBmYWN0b3IxICsgYlsyXSAqIGZhY3RvcjIgKyBjWzJdICogZmFjdG9yMyArIGRbMl0gKiBmYWN0b3I0O1xuICBcbiAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHZlY3RvciB3aXRoIHRoZSBnaXZlbiBzY2FsZVxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge051bWJlcn0gW3NjYWxlXSBMZW5ndGggb2YgdGhlIHJlc3VsdGluZyB2ZWN0b3IuIElmIG9tbWl0dGVkLCBhIHVuaXQgdmVjdG9yIHdpbGwgYmUgcmV0dXJuZWRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5yYW5kb20gPSBmdW5jdGlvbiAob3V0LCBzY2FsZSkge1xuICAgIHNjYWxlID0gc2NhbGUgfHwgMS4wO1xuXG4gICAgdmFyIHIgPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIuMCAqIE1hdGguUEk7XG4gICAgdmFyIHogPSAoZ2xNYXRyaXguUkFORE9NKCkgKiAyLjApIC0gMS4wO1xuICAgIHZhciB6U2NhbGUgPSBNYXRoLnNxcnQoMS4wLXoqeikgKiBzY2FsZTtcblxuICAgIG91dFswXSA9IE1hdGguY29zKHIpICogelNjYWxlO1xuICAgIG91dFsxXSA9IE1hdGguc2luKHIpICogelNjYWxlO1xuICAgIG91dFsyXSA9IHogKiBzY2FsZTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMzIHdpdGggYSBtYXQ0LlxuICogNHRoIHZlY3RvciBjb21wb25lbnQgaXMgaW1wbGljaXRseSAnMSdcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge21hdDR9IG0gbWF0cml4IHRvIHRyYW5zZm9ybSB3aXRoXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMudHJhbnNmb3JtTWF0NCA9IGZ1bmN0aW9uKG91dCwgYSwgbSkge1xuICAgIHZhciB4ID0gYVswXSwgeSA9IGFbMV0sIHogPSBhWzJdLFxuICAgICAgICB3ID0gbVszXSAqIHggKyBtWzddICogeSArIG1bMTFdICogeiArIG1bMTVdO1xuICAgIHcgPSB3IHx8IDEuMDtcbiAgICBvdXRbMF0gPSAobVswXSAqIHggKyBtWzRdICogeSArIG1bOF0gKiB6ICsgbVsxMl0pIC8gdztcbiAgICBvdXRbMV0gPSAobVsxXSAqIHggKyBtWzVdICogeSArIG1bOV0gKiB6ICsgbVsxM10pIC8gdztcbiAgICBvdXRbMl0gPSAobVsyXSAqIHggKyBtWzZdICogeSArIG1bMTBdICogeiArIG1bMTRdKSAvIHc7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjMyB3aXRoIGEgbWF0My5cbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge21hdDR9IG0gdGhlIDN4MyBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy50cmFuc2Zvcm1NYXQzID0gZnVuY3Rpb24ob3V0LCBhLCBtKSB7XG4gICAgdmFyIHggPSBhWzBdLCB5ID0gYVsxXSwgeiA9IGFbMl07XG4gICAgb3V0WzBdID0geCAqIG1bMF0gKyB5ICogbVszXSArIHogKiBtWzZdO1xuICAgIG91dFsxXSA9IHggKiBtWzFdICsgeSAqIG1bNF0gKyB6ICogbVs3XTtcbiAgICBvdXRbMl0gPSB4ICogbVsyXSArIHkgKiBtWzVdICsgeiAqIG1bOF07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjMyB3aXRoIGEgcXVhdFxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7cXVhdH0gcSBxdWF0ZXJuaW9uIHRvIHRyYW5zZm9ybSB3aXRoXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cbnZlYzMudHJhbnNmb3JtUXVhdCA9IGZ1bmN0aW9uKG91dCwgYSwgcSkge1xuICAgIC8vIGJlbmNobWFya3M6IGh0dHA6Ly9qc3BlcmYuY29tL3F1YXRlcm5pb24tdHJhbnNmb3JtLXZlYzMtaW1wbGVtZW50YXRpb25zXG5cbiAgICB2YXIgeCA9IGFbMF0sIHkgPSBhWzFdLCB6ID0gYVsyXSxcbiAgICAgICAgcXggPSBxWzBdLCBxeSA9IHFbMV0sIHF6ID0gcVsyXSwgcXcgPSBxWzNdLFxuXG4gICAgICAgIC8vIGNhbGN1bGF0ZSBxdWF0ICogdmVjXG4gICAgICAgIGl4ID0gcXcgKiB4ICsgcXkgKiB6IC0gcXogKiB5LFxuICAgICAgICBpeSA9IHF3ICogeSArIHF6ICogeCAtIHF4ICogeixcbiAgICAgICAgaXogPSBxdyAqIHogKyBxeCAqIHkgLSBxeSAqIHgsXG4gICAgICAgIGl3ID0gLXF4ICogeCAtIHF5ICogeSAtIHF6ICogejtcblxuICAgIC8vIGNhbGN1bGF0ZSByZXN1bHQgKiBpbnZlcnNlIHF1YXRcbiAgICBvdXRbMF0gPSBpeCAqIHF3ICsgaXcgKiAtcXggKyBpeSAqIC1xeiAtIGl6ICogLXF5O1xuICAgIG91dFsxXSA9IGl5ICogcXcgKyBpdyAqIC1xeSArIGl6ICogLXF4IC0gaXggKiAtcXo7XG4gICAgb3V0WzJdID0gaXogKiBxdyArIGl3ICogLXF6ICsgaXggKiAtcXkgLSBpeSAqIC1xeDtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBSb3RhdGUgYSAzRCB2ZWN0b3IgYXJvdW5kIHRoZSB4LWF4aXNcbiAqIEBwYXJhbSB7dmVjM30gb3V0IFRoZSByZWNlaXZpbmcgdmVjM1xuICogQHBhcmFtIHt2ZWMzfSBhIFRoZSB2ZWMzIHBvaW50IHRvIHJvdGF0ZVxuICogQHBhcmFtIHt2ZWMzfSBiIFRoZSBvcmlnaW4gb2YgdGhlIHJvdGF0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgYW5nbGUgb2Ygcm90YXRpb25cbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMy5yb3RhdGVYID0gZnVuY3Rpb24ob3V0LCBhLCBiLCBjKXtcbiAgIHZhciBwID0gW10sIHI9W107XG5cdCAgLy9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuXHQgIHBbMF0gPSBhWzBdIC0gYlswXTtcblx0ICBwWzFdID0gYVsxXSAtIGJbMV07XG4gIFx0cFsyXSA9IGFbMl0gLSBiWzJdO1xuXG5cdCAgLy9wZXJmb3JtIHJvdGF0aW9uXG5cdCAgclswXSA9IHBbMF07XG5cdCAgclsxXSA9IHBbMV0qTWF0aC5jb3MoYykgLSBwWzJdKk1hdGguc2luKGMpO1xuXHQgIHJbMl0gPSBwWzFdKk1hdGguc2luKGMpICsgcFsyXSpNYXRoLmNvcyhjKTtcblxuXHQgIC8vdHJhbnNsYXRlIHRvIGNvcnJlY3QgcG9zaXRpb25cblx0ICBvdXRbMF0gPSByWzBdICsgYlswXTtcblx0ICBvdXRbMV0gPSByWzFdICsgYlsxXTtcblx0ICBvdXRbMl0gPSByWzJdICsgYlsyXTtcblxuICBcdHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJvdGF0ZSBhIDNEIHZlY3RvciBhcm91bmQgdGhlIHktYXhpc1xuICogQHBhcmFtIHt2ZWMzfSBvdXQgVGhlIHJlY2VpdmluZyB2ZWMzXG4gKiBAcGFyYW0ge3ZlYzN9IGEgVGhlIHZlYzMgcG9pbnQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge3ZlYzN9IGIgVGhlIG9yaWdpbiBvZiB0aGUgcm90YXRpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSBhbmdsZSBvZiByb3RhdGlvblxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLnJvdGF0ZVkgPSBmdW5jdGlvbihvdXQsIGEsIGIsIGMpe1xuICBcdHZhciBwID0gW10sIHI9W107XG4gIFx0Ly9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuICBcdHBbMF0gPSBhWzBdIC0gYlswXTtcbiAgXHRwWzFdID0gYVsxXSAtIGJbMV07XG4gIFx0cFsyXSA9IGFbMl0gLSBiWzJdO1xuICBcbiAgXHQvL3BlcmZvcm0gcm90YXRpb25cbiAgXHRyWzBdID0gcFsyXSpNYXRoLnNpbihjKSArIHBbMF0qTWF0aC5jb3MoYyk7XG4gIFx0clsxXSA9IHBbMV07XG4gIFx0clsyXSA9IHBbMl0qTWF0aC5jb3MoYykgLSBwWzBdKk1hdGguc2luKGMpO1xuICBcbiAgXHQvL3RyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG4gIFx0b3V0WzBdID0gclswXSArIGJbMF07XG4gIFx0b3V0WzFdID0gclsxXSArIGJbMV07XG4gIFx0b3V0WzJdID0gclsyXSArIGJbMl07XG4gIFxuICBcdHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJvdGF0ZSBhIDNEIHZlY3RvciBhcm91bmQgdGhlIHotYXhpc1xuICogQHBhcmFtIHt2ZWMzfSBvdXQgVGhlIHJlY2VpdmluZyB2ZWMzXG4gKiBAcGFyYW0ge3ZlYzN9IGEgVGhlIHZlYzMgcG9pbnQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge3ZlYzN9IGIgVGhlIG9yaWdpbiBvZiB0aGUgcm90YXRpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSBhbmdsZSBvZiByb3RhdGlvblxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG52ZWMzLnJvdGF0ZVogPSBmdW5jdGlvbihvdXQsIGEsIGIsIGMpe1xuICBcdHZhciBwID0gW10sIHI9W107XG4gIFx0Ly9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuICBcdHBbMF0gPSBhWzBdIC0gYlswXTtcbiAgXHRwWzFdID0gYVsxXSAtIGJbMV07XG4gIFx0cFsyXSA9IGFbMl0gLSBiWzJdO1xuICBcbiAgXHQvL3BlcmZvcm0gcm90YXRpb25cbiAgXHRyWzBdID0gcFswXSpNYXRoLmNvcyhjKSAtIHBbMV0qTWF0aC5zaW4oYyk7XG4gIFx0clsxXSA9IHBbMF0qTWF0aC5zaW4oYykgKyBwWzFdKk1hdGguY29zKGMpO1xuICBcdHJbMl0gPSBwWzJdO1xuICBcbiAgXHQvL3RyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG4gIFx0b3V0WzBdID0gclswXSArIGJbMF07XG4gIFx0b3V0WzFdID0gclsxXSArIGJbMV07XG4gIFx0b3V0WzJdID0gclsyXSArIGJbMl07XG4gIFxuICBcdHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFBlcmZvcm0gc29tZSBvcGVyYXRpb24gb3ZlciBhbiBhcnJheSBvZiB2ZWMzcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhIHRoZSBhcnJheSBvZiB2ZWN0b3JzIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtIHtOdW1iZXJ9IHN0cmlkZSBOdW1iZXIgb2YgZWxlbWVudHMgYmV0d2VlbiB0aGUgc3RhcnQgb2YgZWFjaCB2ZWMzLiBJZiAwIGFzc3VtZXMgdGlnaHRseSBwYWNrZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXQgTnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBOdW1iZXIgb2YgdmVjM3MgdG8gaXRlcmF0ZSBvdmVyLiBJZiAwIGl0ZXJhdGVzIG92ZXIgZW50aXJlIGFycmF5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBGdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIHZlY3RvciBpbiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSBbYXJnXSBhZGRpdGlvbmFsIGFyZ3VtZW50IHRvIHBhc3MgdG8gZm5cbiAqIEByZXR1cm5zIHtBcnJheX0gYVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzMuZm9yRWFjaCA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgdmVjID0gdmVjMy5jcmVhdGUoKTtcblxuICAgIHJldHVybiBmdW5jdGlvbihhLCBzdHJpZGUsIG9mZnNldCwgY291bnQsIGZuLCBhcmcpIHtcbiAgICAgICAgdmFyIGksIGw7XG4gICAgICAgIGlmKCFzdHJpZGUpIHtcbiAgICAgICAgICAgIHN0cmlkZSA9IDM7XG4gICAgICAgIH1cblxuICAgICAgICBpZighb2Zmc2V0KSB7XG4gICAgICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBpZihjb3VudCkge1xuICAgICAgICAgICAgbCA9IE1hdGgubWluKChjb3VudCAqIHN0cmlkZSkgKyBvZmZzZXQsIGEubGVuZ3RoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGwgPSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcihpID0gb2Zmc2V0OyBpIDwgbDsgaSArPSBzdHJpZGUpIHtcbiAgICAgICAgICAgIHZlY1swXSA9IGFbaV07IHZlY1sxXSA9IGFbaSsxXTsgdmVjWzJdID0gYVtpKzJdO1xuICAgICAgICAgICAgZm4odmVjLCB2ZWMsIGFyZyk7XG4gICAgICAgICAgICBhW2ldID0gdmVjWzBdOyBhW2krMV0gPSB2ZWNbMV07IGFbaSsyXSA9IHZlY1syXTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbn0pKCk7XG5cbi8qKlxuICogR2V0IHRoZSBhbmdsZSBiZXR3ZWVuIHR3byAzRCB2ZWN0b3JzXG4gKiBAcGFyYW0ge3ZlYzN9IGEgVGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjM30gYiBUaGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBhbmdsZSBpbiByYWRpYW5zXG4gKi9cbnZlYzMuYW5nbGUgPSBmdW5jdGlvbihhLCBiKSB7XG4gICBcbiAgICB2YXIgdGVtcEEgPSB2ZWMzLmZyb21WYWx1ZXMoYVswXSwgYVsxXSwgYVsyXSk7XG4gICAgdmFyIHRlbXBCID0gdmVjMy5mcm9tVmFsdWVzKGJbMF0sIGJbMV0sIGJbMl0pO1xuIFxuICAgIHZlYzMubm9ybWFsaXplKHRlbXBBLCB0ZW1wQSk7XG4gICAgdmVjMy5ub3JtYWxpemUodGVtcEIsIHRlbXBCKTtcbiBcbiAgICB2YXIgY29zaW5lID0gdmVjMy5kb3QodGVtcEEsIHRlbXBCKTtcblxuICAgIGlmKGNvc2luZSA+IDEuMCl7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBNYXRoLmFjb3MoY29zaW5lKTtcbiAgICB9ICAgICBcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7dmVjM30gdmVjIHZlY3RvciB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yXG4gKi9cbnZlYzMuc3RyID0gZnVuY3Rpb24gKGEpIHtcbiAgICByZXR1cm4gJ3ZlYzMoJyArIGFbMF0gKyAnLCAnICsgYVsxXSArICcsICcgKyBhWzJdICsgJyknO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB2ZWMzO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtbWF0cml4L3NyYy9nbC1tYXRyaXgvdmVjMy5qc1xuICoqIG1vZHVsZSBpZCA9IDE0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiBDb3B5cmlnaHQgKGMpIDIwMTUsIEJyYW5kb24gSm9uZXMsIENvbGluIE1hY0tlbnppZSBJVi5cblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxub2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xudG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG5mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuXG5UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG5BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG5MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuVEhFIFNPRlRXQVJFLiAqL1xuXG52YXIgZ2xNYXRyaXggPSByZXF1aXJlKFwiLi9jb21tb24uanNcIik7XG5cbi8qKlxuICogQGNsYXNzIDQgRGltZW5zaW9uYWwgVmVjdG9yXG4gKiBAbmFtZSB2ZWM0XG4gKi9cbnZhciB2ZWM0ID0ge307XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgdmVjNFxuICpcbiAqIEByZXR1cm5zIHt2ZWM0fSBhIG5ldyA0RCB2ZWN0b3JcbiAqL1xudmVjNC5jcmVhdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdmVjdG9yIHRvIGNsb25lXG4gKiBAcmV0dXJucyB7dmVjNH0gYSBuZXcgNEQgdmVjdG9yXG4gKi9cbnZlYzQuY2xvbmUgPSBmdW5jdGlvbihhKSB7XG4gICAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVsxXTtcbiAgICBvdXRbMl0gPSBhWzJdO1xuICAgIG91dFszXSA9IGFbM107XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWM0IGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3IFcgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7dmVjNH0gYSBuZXcgNEQgdmVjdG9yXG4gKi9cbnZlYzQuZnJvbVZhbHVlcyA9IGZ1bmN0aW9uKHgsIHksIHosIHcpIHtcbiAgICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG4gICAgb3V0WzBdID0geDtcbiAgICBvdXRbMV0gPSB5O1xuICAgIG91dFsyXSA9IHo7XG4gICAgb3V0WzNdID0gdztcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgdmVjNCB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB0aGUgc291cmNlIHZlY3RvclxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LmNvcHkgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgb3V0WzJdID0gYVsyXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzQgdG8gdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0gdyBXIGNvbXBvbmVudFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LnNldCA9IGZ1bmN0aW9uKG91dCwgeCwgeSwgeiwgdykge1xuICAgIG91dFswXSA9IHg7XG4gICAgb3V0WzFdID0geTtcbiAgICBvdXRbMl0gPSB6O1xuICAgIG91dFszXSA9IHc7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWRkcyB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LmFkZCA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICAgIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICAgIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICAgIG91dFszXSA9IGFbM10gKyBiWzNdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFN1YnRyYWN0cyB2ZWN0b3IgYiBmcm9tIHZlY3RvciBhXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LnN1YnRyYWN0ID0gZnVuY3Rpb24ob3V0LCBhLCBiKSB7XG4gICAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gICAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gICAgb3V0WzJdID0gYVsyXSAtIGJbMl07XG4gICAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzQuc3ViID0gdmVjNC5zdWJ0cmFjdDtcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byB2ZWM0J3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cbnZlYzQubXVsdGlwbHkgPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgICBvdXRbMV0gPSBhWzFdICogYlsxXTtcbiAgICBvdXRbMl0gPSBhWzJdICogYlsyXTtcbiAgICBvdXRbM10gPSBhWzNdICogYlszXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjNC5tdWwgPSB2ZWM0Lm11bHRpcGx5O1xuXG4vKipcbiAqIERpdmlkZXMgdHdvIHZlYzQnc1xuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xudmVjNC5kaXZpZGUgPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBhWzBdIC8gYlswXTtcbiAgICBvdXRbMV0gPSBhWzFdIC8gYlsxXTtcbiAgICBvdXRbMl0gPSBhWzJdIC8gYlsyXTtcbiAgICBvdXRbM10gPSBhWzNdIC8gYlszXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQuZGl2aWRlfVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzQuZGl2ID0gdmVjNC5kaXZpZGU7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWluaW11bSBvZiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0Lm1pbiA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IE1hdGgubWluKGFbMF0sIGJbMF0pO1xuICAgIG91dFsxXSA9IE1hdGgubWluKGFbMV0sIGJbMV0pO1xuICAgIG91dFsyXSA9IE1hdGgubWluKGFbMl0sIGJbMl0pO1xuICAgIG91dFszXSA9IE1hdGgubWluKGFbM10sIGJbM10pO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG1heGltdW0gb2YgdHdvIHZlYzQnc1xuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xudmVjNC5tYXggPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBNYXRoLm1heChhWzBdLCBiWzBdKTtcbiAgICBvdXRbMV0gPSBNYXRoLm1heChhWzFdLCBiWzFdKTtcbiAgICBvdXRbMl0gPSBNYXRoLm1heChhWzJdLCBiWzJdKTtcbiAgICBvdXRbM10gPSBNYXRoLm1heChhWzNdLCBiWzNdKTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBTY2FsZXMgYSB2ZWM0IGJ5IGEgc2NhbGFyIG51bWJlclxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdGhlIHZlY3RvciB0byBzY2FsZVxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSB2ZWN0b3IgYnlcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xudmVjNC5zY2FsZSA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gKiBiO1xuICAgIG91dFsxXSA9IGFbMV0gKiBiO1xuICAgIG91dFsyXSA9IGFbMl0gKiBiO1xuICAgIG91dFszXSA9IGFbM10gKiBiO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEFkZHMgdHdvIHZlYzQncyBhZnRlciBzY2FsaW5nIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZVxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIgYnkgYmVmb3JlIGFkZGluZ1xuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LnNjYWxlQW5kQWRkID0gZnVuY3Rpb24ob3V0LCBhLCBiLCBzY2FsZSkge1xuICAgIG91dFswXSA9IGFbMF0gKyAoYlswXSAqIHNjYWxlKTtcbiAgICBvdXRbMV0gPSBhWzFdICsgKGJbMV0gKiBzY2FsZSk7XG4gICAgb3V0WzJdID0gYVsyXSArIChiWzJdICogc2NhbGUpO1xuICAgIG91dFszXSA9IGFbM10gKyAoYlszXSAqIHNjYWxlKTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcbiAqL1xudmVjNC5kaXN0YW5jZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgeCA9IGJbMF0gLSBhWzBdLFxuICAgICAgICB5ID0gYlsxXSAtIGFbMV0sXG4gICAgICAgIHogPSBiWzJdIC0gYVsyXSxcbiAgICAgICAgdyA9IGJbM10gLSBhWzNdO1xuICAgIHJldHVybiBNYXRoLnNxcnQoeCp4ICsgeSp5ICsgeip6ICsgdyp3KTtcbn07XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LmRpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzQuZGlzdCA9IHZlYzQuZGlzdGFuY2U7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxuICovXG52ZWM0LnNxdWFyZWREaXN0YW5jZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgeCA9IGJbMF0gLSBhWzBdLFxuICAgICAgICB5ID0gYlsxXSAtIGFbMV0sXG4gICAgICAgIHogPSBiWzJdIC0gYVsyXSxcbiAgICAgICAgdyA9IGJbM10gLSBhWzNdO1xuICAgIHJldHVybiB4KnggKyB5KnkgKyB6KnogKyB3Knc7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5zcXVhcmVkRGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjNC5zcXJEaXN0ID0gdmVjNC5zcXVhcmVkRGlzdGFuY2U7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcbiAqL1xudmVjNC5sZW5ndGggPSBmdW5jdGlvbiAoYSkge1xuICAgIHZhciB4ID0gYVswXSxcbiAgICAgICAgeSA9IGFbMV0sXG4gICAgICAgIHogPSBhWzJdLFxuICAgICAgICB3ID0gYVszXTtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KHgqeCArIHkqeSArIHoqeiArIHcqdyk7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5sZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjNC5sZW4gPSB2ZWM0Lmxlbmd0aDtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGxlbmd0aCBvZiBhIHZlYzRcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBzcXVhcmVkIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxuICovXG52ZWM0LnNxdWFyZWRMZW5ndGggPSBmdW5jdGlvbiAoYSkge1xuICAgIHZhciB4ID0gYVswXSxcbiAgICAgICAgeSA9IGFbMV0sXG4gICAgICAgIHogPSBhWzJdLFxuICAgICAgICB3ID0gYVszXTtcbiAgICByZXR1cm4geCp4ICsgeSp5ICsgeip6ICsgdyp3O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQuc3F1YXJlZExlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG52ZWM0LnNxckxlbiA9IHZlYzQuc3F1YXJlZExlbmd0aDtcblxuLyoqXG4gKiBOZWdhdGVzIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdmVjdG9yIHRvIG5lZ2F0ZVxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0Lm5lZ2F0ZSA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIG91dFswXSA9IC1hWzBdO1xuICAgIG91dFsxXSA9IC1hWzFdO1xuICAgIG91dFsyXSA9IC1hWzJdO1xuICAgIG91dFszXSA9IC1hWzNdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB2ZWN0b3IgdG8gaW52ZXJ0XG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cbnZlYzQuaW52ZXJzZSA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICBvdXRbMF0gPSAxLjAgLyBhWzBdO1xuICBvdXRbMV0gPSAxLjAgLyBhWzFdO1xuICBvdXRbMl0gPSAxLjAgLyBhWzJdO1xuICBvdXRbM10gPSAxLjAgLyBhWzNdO1xuICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBOb3JtYWxpemUgYSB2ZWM0XG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB2ZWN0b3IgdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cbnZlYzQubm9ybWFsaXplID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgdmFyIHggPSBhWzBdLFxuICAgICAgICB5ID0gYVsxXSxcbiAgICAgICAgeiA9IGFbMl0sXG4gICAgICAgIHcgPSBhWzNdO1xuICAgIHZhciBsZW4gPSB4KnggKyB5KnkgKyB6KnogKyB3Knc7XG4gICAgaWYgKGxlbiA+IDApIHtcbiAgICAgICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pO1xuICAgICAgICBvdXRbMF0gPSB4ICogbGVuO1xuICAgICAgICBvdXRbMV0gPSB5ICogbGVuO1xuICAgICAgICBvdXRbMl0gPSB6ICogbGVuO1xuICAgICAgICBvdXRbM10gPSB3ICogbGVuO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkb3QgcHJvZHVjdCBvZiBhIGFuZCBiXG4gKi9cbnZlYzQuZG90ID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXSArIGFbMl0gKiBiWzJdICsgYVszXSAqIGJbM107XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LmxlcnAgPSBmdW5jdGlvbiAob3V0LCBhLCBiLCB0KSB7XG4gICAgdmFyIGF4ID0gYVswXSxcbiAgICAgICAgYXkgPSBhWzFdLFxuICAgICAgICBheiA9IGFbMl0sXG4gICAgICAgIGF3ID0gYVszXTtcbiAgICBvdXRbMF0gPSBheCArIHQgKiAoYlswXSAtIGF4KTtcbiAgICBvdXRbMV0gPSBheSArIHQgKiAoYlsxXSAtIGF5KTtcbiAgICBvdXRbMl0gPSBheiArIHQgKiAoYlsyXSAtIGF6KTtcbiAgICBvdXRbM10gPSBhdyArIHQgKiAoYlszXSAtIGF3KTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSByYW5kb20gdmVjdG9yIHdpdGggdGhlIGdpdmVuIHNjYWxlXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2NhbGVdIExlbmd0aCBvZiB0aGUgcmVzdWx0aW5nIHZlY3Rvci4gSWYgb21taXR0ZWQsIGEgdW5pdCB2ZWN0b3Igd2lsbCBiZSByZXR1cm5lZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LnJhbmRvbSA9IGZ1bmN0aW9uIChvdXQsIHNjYWxlKSB7XG4gICAgc2NhbGUgPSBzY2FsZSB8fCAxLjA7XG5cbiAgICAvL1RPRE86IFRoaXMgaXMgYSBwcmV0dHkgYXdmdWwgd2F5IG9mIGRvaW5nIHRoaXMuIEZpbmQgc29tZXRoaW5nIGJldHRlci5cbiAgICBvdXRbMF0gPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgICBvdXRbMV0gPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgICBvdXRbMl0gPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgICBvdXRbM10gPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgICB2ZWM0Lm5vcm1hbGl6ZShvdXQsIG91dCk7XG4gICAgdmVjNC5zY2FsZShvdXQsIG91dCwgc2NhbGUpO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzQgd2l0aCBhIG1hdDQuXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjNH0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHttYXQ0fSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG52ZWM0LnRyYW5zZm9ybU1hdDQgPSBmdW5jdGlvbihvdXQsIGEsIG0pIHtcbiAgICB2YXIgeCA9IGFbMF0sIHkgPSBhWzFdLCB6ID0gYVsyXSwgdyA9IGFbM107XG4gICAgb3V0WzBdID0gbVswXSAqIHggKyBtWzRdICogeSArIG1bOF0gKiB6ICsgbVsxMl0gKiB3O1xuICAgIG91dFsxXSA9IG1bMV0gKiB4ICsgbVs1XSAqIHkgKyBtWzldICogeiArIG1bMTNdICogdztcbiAgICBvdXRbMl0gPSBtWzJdICogeCArIG1bNl0gKiB5ICsgbVsxMF0gKiB6ICsgbVsxNF0gKiB3O1xuICAgIG91dFszXSA9IG1bM10gKiB4ICsgbVs3XSAqIHkgKyBtWzExXSAqIHogKyBtWzE1XSAqIHc7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjNCB3aXRoIGEgcXVhdFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzR9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7cXVhdH0gcSBxdWF0ZXJuaW9uIHRvIHRyYW5zZm9ybSB3aXRoXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cbnZlYzQudHJhbnNmb3JtUXVhdCA9IGZ1bmN0aW9uKG91dCwgYSwgcSkge1xuICAgIHZhciB4ID0gYVswXSwgeSA9IGFbMV0sIHogPSBhWzJdLFxuICAgICAgICBxeCA9IHFbMF0sIHF5ID0gcVsxXSwgcXogPSBxWzJdLCBxdyA9IHFbM10sXG5cbiAgICAgICAgLy8gY2FsY3VsYXRlIHF1YXQgKiB2ZWNcbiAgICAgICAgaXggPSBxdyAqIHggKyBxeSAqIHogLSBxeiAqIHksXG4gICAgICAgIGl5ID0gcXcgKiB5ICsgcXogKiB4IC0gcXggKiB6LFxuICAgICAgICBpeiA9IHF3ICogeiArIHF4ICogeSAtIHF5ICogeCxcbiAgICAgICAgaXcgPSAtcXggKiB4IC0gcXkgKiB5IC0gcXogKiB6O1xuXG4gICAgLy8gY2FsY3VsYXRlIHJlc3VsdCAqIGludmVyc2UgcXVhdFxuICAgIG91dFswXSA9IGl4ICogcXcgKyBpdyAqIC1xeCArIGl5ICogLXF6IC0gaXogKiAtcXk7XG4gICAgb3V0WzFdID0gaXkgKiBxdyArIGl3ICogLXF5ICsgaXogKiAtcXggLSBpeCAqIC1xejtcbiAgICBvdXRbMl0gPSBpeiAqIHF3ICsgaXcgKiAtcXogKyBpeCAqIC1xeSAtIGl5ICogLXF4O1xuICAgIG91dFszXSA9IGFbM107XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUGVyZm9ybSBzb21lIG9wZXJhdGlvbiBvdmVyIGFuIGFycmF5IG9mIHZlYzRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGFycmF5IG9mIHZlY3RvcnMgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0ge051bWJlcn0gc3RyaWRlIE51bWJlciBvZiBlbGVtZW50cyBiZXR3ZWVuIHRoZSBzdGFydCBvZiBlYWNoIHZlYzQuIElmIDAgYXNzdW1lcyB0aWdodGx5IHBhY2tlZFxuICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gc2tpcCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBhcnJheVxuICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50IE51bWJlciBvZiB2ZWM0cyB0byBpdGVyYXRlIG92ZXIuIElmIDAgaXRlcmF0ZXMgb3ZlciBlbnRpcmUgYXJyYXlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggdmVjdG9yIGluIHRoZSBhcnJheVxuICogQHBhcmFtIHtPYmplY3R9IFthcmddIGFkZGl0aW9uYWwgYXJndW1lbnQgdG8gcGFzcyB0byBmblxuICogQHJldHVybnMge0FycmF5fSBhXG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjNC5mb3JFYWNoID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ZWMgPSB2ZWM0LmNyZWF0ZSgpO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGEsIHN0cmlkZSwgb2Zmc2V0LCBjb3VudCwgZm4sIGFyZykge1xuICAgICAgICB2YXIgaSwgbDtcbiAgICAgICAgaWYoIXN0cmlkZSkge1xuICAgICAgICAgICAgc3RyaWRlID0gNDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCFvZmZzZXQpIHtcbiAgICAgICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmKGNvdW50KSB7XG4gICAgICAgICAgICBsID0gTWF0aC5taW4oKGNvdW50ICogc3RyaWRlKSArIG9mZnNldCwgYS5sZW5ndGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbCA9IGEubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yKGkgPSBvZmZzZXQ7IGkgPCBsOyBpICs9IHN0cmlkZSkge1xuICAgICAgICAgICAgdmVjWzBdID0gYVtpXTsgdmVjWzFdID0gYVtpKzFdOyB2ZWNbMl0gPSBhW2krMl07IHZlY1szXSA9IGFbaSszXTtcbiAgICAgICAgICAgIGZuKHZlYywgdmVjLCBhcmcpO1xuICAgICAgICAgICAgYVtpXSA9IHZlY1swXTsgYVtpKzFdID0gdmVjWzFdOyBhW2krMl0gPSB2ZWNbMl07IGFbaSszXSA9IHZlY1szXTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbn0pKCk7XG5cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7dmVjNH0gdmVjIHZlY3RvciB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yXG4gKi9cbnZlYzQuc3RyID0gZnVuY3Rpb24gKGEpIHtcbiAgICByZXR1cm4gJ3ZlYzQoJyArIGFbMF0gKyAnLCAnICsgYVsxXSArICcsICcgKyBhWzJdICsgJywgJyArIGFbM10gKyAnKSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHZlYzQ7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nbC1tYXRyaXgvc3JjL2dsLW1hdHJpeC92ZWM0LmpzXG4gKiogbW9kdWxlIGlkID0gMTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIENvcHlyaWdodCAoYykgMjAxNSwgQnJhbmRvbiBKb25lcywgQ29saW4gTWFjS2VuemllIElWLlxuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG5vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG5pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG50byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG5jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG5hbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG5USEUgU09GVFdBUkUuICovXG5cbnZhciBnbE1hdHJpeCA9IHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKTtcblxuLyoqXG4gKiBAY2xhc3MgMiBEaW1lbnNpb25hbCBWZWN0b3JcbiAqIEBuYW1lIHZlYzJcbiAqL1xudmFyIHZlYzIgPSB7fTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWMyXG4gKlxuICogQHJldHVybnMge3ZlYzJ9IGEgbmV3IDJEIHZlY3RvclxuICovXG52ZWMyLmNyZWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWMyIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgdmVjdG9yXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBhIHZlY3RvciB0byBjbG9uZVxuICogQHJldHVybnMge3ZlYzJ9IGEgbmV3IDJEIHZlY3RvclxuICovXG52ZWMyLmNsb25lID0gZnVuY3Rpb24oYSkge1xuICAgIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWMyIGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHJldHVybnMge3ZlYzJ9IGEgbmV3IDJEIHZlY3RvclxuICovXG52ZWMyLmZyb21WYWx1ZXMgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDIpO1xuICAgIG91dFswXSA9IHg7XG4gICAgb3V0WzFdID0geTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgdmVjMiB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgc291cmNlIHZlY3RvclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLmNvcHkgPSBmdW5jdGlvbihvdXQsIGEpIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMV07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMiB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLnNldCA9IGZ1bmN0aW9uKG91dCwgeCwgeSkge1xuICAgIG91dFswXSA9IHg7XG4gICAgb3V0WzFdID0geTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBZGRzIHR3byB2ZWMyJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIuYWRkID0gZnVuY3Rpb24ob3V0LCBhLCBiKSB7XG4gICAgb3V0WzBdID0gYVswXSArIGJbMF07XG4gICAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogU3VidHJhY3RzIHZlY3RvciBiIGZyb20gdmVjdG9yIGFcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIuc3VidHJhY3QgPSBmdW5jdGlvbihvdXQsIGEsIGIpIHtcbiAgICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgICBvdXRbMV0gPSBhWzFdIC0gYlsxXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIuc3VidHJhY3R9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjMi5zdWIgPSB2ZWMyLnN1YnRyYWN0O1xuXG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIHZlYzInc1xuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xudmVjMi5tdWx0aXBseSA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gKiBiWzBdO1xuICAgIG91dFsxXSA9IGFbMV0gKiBiWzFdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG52ZWMyLm11bCA9IHZlYzIubXVsdGlwbHk7XG5cbi8qKlxuICogRGl2aWRlcyB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLmRpdmlkZSA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gLyBiWzBdO1xuICAgIG91dFsxXSA9IGFbMV0gLyBiWzFdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5kaXZpZGV9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjMi5kaXYgPSB2ZWMyLmRpdmlkZTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtaW5pbXVtIG9mIHR3byB2ZWMyJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIubWluID0gZnVuY3Rpb24ob3V0LCBhLCBiKSB7XG4gICAgb3V0WzBdID0gTWF0aC5taW4oYVswXSwgYlswXSk7XG4gICAgb3V0WzFdID0gTWF0aC5taW4oYVsxXSwgYlsxXSk7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWF4aW11bSBvZiB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLm1heCA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IE1hdGgubWF4KGFbMF0sIGJbMF0pO1xuICAgIG91dFsxXSA9IE1hdGgubWF4KGFbMV0sIGJbMV0pO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFNjYWxlcyBhIHZlYzIgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgdmVjdG9yIHRvIHNjYWxlXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieVxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLnNjYWxlID0gZnVuY3Rpb24ob3V0LCBhLCBiKSB7XG4gICAgb3V0WzBdID0gYVswXSAqIGI7XG4gICAgb3V0WzFdID0gYVsxXSAqIGI7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWRkcyB0d28gdmVjMidzIGFmdGVyIHNjYWxpbmcgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYiBieSBiZWZvcmUgYWRkaW5nXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIuc2NhbGVBbmRBZGQgPSBmdW5jdGlvbihvdXQsIGEsIGIsIHNjYWxlKSB7XG4gICAgb3V0WzBdID0gYVswXSArIChiWzBdICogc2NhbGUpO1xuICAgIG91dFsxXSA9IGFbMV0gKyAoYlsxXSAqIHNjYWxlKTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcbiAqL1xudmVjMi5kaXN0YW5jZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgeCA9IGJbMF0gLSBhWzBdLFxuICAgICAgICB5ID0gYlsxXSAtIGFbMV07XG4gICAgcmV0dXJuIE1hdGguc3FydCh4KnggKyB5KnkpO1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIuZGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xudmVjMi5kaXN0ID0gdmVjMi5kaXN0YW5jZTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWMyJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXG4gKi9cbnZlYzIuc3F1YXJlZERpc3RhbmNlID0gZnVuY3Rpb24oYSwgYikge1xuICAgIHZhciB4ID0gYlswXSAtIGFbMF0sXG4gICAgICAgIHkgPSBiWzFdIC0gYVsxXTtcbiAgICByZXR1cm4geCp4ICsgeSp5O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIuc3F1YXJlZERpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cbnZlYzIuc3FyRGlzdCA9IHZlYzIuc3F1YXJlZERpc3RhbmNlO1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIHZlYzJcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGxlbmd0aCBvZiBhXG4gKi9cbnZlYzIubGVuZ3RoID0gZnVuY3Rpb24gKGEpIHtcbiAgICB2YXIgeCA9IGFbMF0sXG4gICAgICAgIHkgPSBhWzFdO1xuICAgIHJldHVybiBNYXRoLnNxcnQoeCp4ICsgeSp5KTtcbn07XG5cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMyLmxlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG52ZWMyLmxlbiA9IHZlYzIubGVuZ3RoO1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgbGVuZ3RoIG9mIGEgdmVjMlxuICpcbiAqIEBwYXJhbSB7dmVjMn0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGxlbmd0aCBvZiBhXG4gKi9cbnZlYzIuc3F1YXJlZExlbmd0aCA9IGZ1bmN0aW9uIChhKSB7XG4gICAgdmFyIHggPSBhWzBdLFxuICAgICAgICB5ID0gYVsxXTtcbiAgICByZXR1cm4geCp4ICsgeSp5O1xufTtcblxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIuc3F1YXJlZExlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG52ZWMyLnNxckxlbiA9IHZlYzIuc3F1YXJlZExlbmd0aDtcblxuLyoqXG4gKiBOZWdhdGVzIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMlxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdmVjdG9yIHRvIG5lZ2F0ZVxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLm5lZ2F0ZSA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICAgIG91dFswXSA9IC1hWzBdO1xuICAgIG91dFsxXSA9IC1hWzFdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB2ZWN0b3IgdG8gaW52ZXJ0XG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIuaW52ZXJzZSA9IGZ1bmN0aW9uKG91dCwgYSkge1xuICBvdXRbMF0gPSAxLjAgLyBhWzBdO1xuICBvdXRbMV0gPSAxLjAgLyBhWzFdO1xuICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBOb3JtYWxpemUgYSB2ZWMyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB2ZWN0b3IgdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIubm9ybWFsaXplID0gZnVuY3Rpb24ob3V0LCBhKSB7XG4gICAgdmFyIHggPSBhWzBdLFxuICAgICAgICB5ID0gYVsxXTtcbiAgICB2YXIgbGVuID0geCp4ICsgeSp5O1xuICAgIGlmIChsZW4gPiAwKSB7XG4gICAgICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/XG4gICAgICAgIGxlbiA9IDEgLyBNYXRoLnNxcnQobGVuKTtcbiAgICAgICAgb3V0WzBdID0gYVswXSAqIGxlbjtcbiAgICAgICAgb3V0WzFdID0gYVsxXSAqIGxlbjtcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIHZlYzInc1xuICpcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHt2ZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gZG90IHByb2R1Y3Qgb2YgYSBhbmQgYlxuICovXG52ZWMyLmRvdCA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV07XG59O1xuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBjcm9zcyBwcm9kdWN0IG9mIHR3byB2ZWMyJ3NcbiAqIE5vdGUgdGhhdCB0aGUgY3Jvc3MgcHJvZHVjdCBtdXN0IGJ5IGRlZmluaXRpb24gcHJvZHVjZSBhIDNEIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xudmVjMi5jcm9zcyA9IGZ1bmN0aW9uKG91dCwgYSwgYikge1xuICAgIHZhciB6ID0gYVswXSAqIGJbMV0gLSBhWzFdICogYlswXTtcbiAgICBvdXRbMF0gPSBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IHo7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogUGVyZm9ybXMgYSBsaW5lYXIgaW50ZXJwb2xhdGlvbiBiZXR3ZWVuIHR3byB2ZWMyJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge3ZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIubGVycCA9IGZ1bmN0aW9uIChvdXQsIGEsIGIsIHQpIHtcbiAgICB2YXIgYXggPSBhWzBdLFxuICAgICAgICBheSA9IGFbMV07XG4gICAgb3V0WzBdID0gYXggKyB0ICogKGJbMF0gLSBheCk7XG4gICAgb3V0WzFdID0gYXkgKyB0ICogKGJbMV0gLSBheSk7XG4gICAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHZlY3RvciB3aXRoIHRoZSBnaXZlbiBzY2FsZVxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge051bWJlcn0gW3NjYWxlXSBMZW5ndGggb2YgdGhlIHJlc3VsdGluZyB2ZWN0b3IuIElmIG9tbWl0dGVkLCBhIHVuaXQgdmVjdG9yIHdpbGwgYmUgcmV0dXJuZWRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xudmVjMi5yYW5kb20gPSBmdW5jdGlvbiAob3V0LCBzY2FsZSkge1xuICAgIHNjYWxlID0gc2NhbGUgfHwgMS4wO1xuICAgIHZhciByID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyLjAgKiBNYXRoLlBJO1xuICAgIG91dFswXSA9IE1hdGguY29zKHIpICogc2NhbGU7XG4gICAgb3V0WzFdID0gTWF0aC5zaW4ocikgKiBzY2FsZTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMyIHdpdGggYSBtYXQyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHttYXQyfSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLnRyYW5zZm9ybU1hdDIgPSBmdW5jdGlvbihvdXQsIGEsIG0pIHtcbiAgICB2YXIgeCA9IGFbMF0sXG4gICAgICAgIHkgPSBhWzFdO1xuICAgIG91dFswXSA9IG1bMF0gKiB4ICsgbVsyXSAqIHk7XG4gICAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzNdICogeTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMyIHdpdGggYSBtYXQyZFxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7bWF0MmR9IG0gbWF0cml4IHRvIHRyYW5zZm9ybSB3aXRoXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbnZlYzIudHJhbnNmb3JtTWF0MmQgPSBmdW5jdGlvbihvdXQsIGEsIG0pIHtcbiAgICB2YXIgeCA9IGFbMF0sXG4gICAgICAgIHkgPSBhWzFdO1xuICAgIG91dFswXSA9IG1bMF0gKiB4ICsgbVsyXSAqIHkgKyBtWzRdO1xuICAgIG91dFsxXSA9IG1bMV0gKiB4ICsgbVszXSAqIHkgKyBtWzVdO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzIgd2l0aCBhIG1hdDNcbiAqIDNyZCB2ZWN0b3IgY29tcG9uZW50IGlzIGltcGxpY2l0bHkgJzEnXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHttYXQzfSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG52ZWMyLnRyYW5zZm9ybU1hdDMgPSBmdW5jdGlvbihvdXQsIGEsIG0pIHtcbiAgICB2YXIgeCA9IGFbMF0sXG4gICAgICAgIHkgPSBhWzFdO1xuICAgIG91dFswXSA9IG1bMF0gKiB4ICsgbVszXSAqIHkgKyBtWzZdO1xuICAgIG91dFsxXSA9IG1bMV0gKiB4ICsgbVs0XSAqIHkgKyBtWzddO1xuICAgIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzIgd2l0aCBhIG1hdDRcbiAqIDNyZCB2ZWN0b3IgY29tcG9uZW50IGlzIGltcGxpY2l0bHkgJzAnXG4gKiA0dGggdmVjdG9yIGNvbXBvbmVudCBpcyBpbXBsaWNpdGx5ICcxJ1xuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7bWF0NH0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xudmVjMi50cmFuc2Zvcm1NYXQ0ID0gZnVuY3Rpb24ob3V0LCBhLCBtKSB7XG4gICAgdmFyIHggPSBhWzBdLCBcbiAgICAgICAgeSA9IGFbMV07XG4gICAgb3V0WzBdID0gbVswXSAqIHggKyBtWzRdICogeSArIG1bMTJdO1xuICAgIG91dFsxXSA9IG1bMV0gKiB4ICsgbVs1XSAqIHkgKyBtWzEzXTtcbiAgICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBQZXJmb3JtIHNvbWUgb3BlcmF0aW9uIG92ZXIgYW4gYXJyYXkgb2YgdmVjMnMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYSB0aGUgYXJyYXkgb2YgdmVjdG9ycyB0byBpdGVyYXRlIG92ZXJcbiAqIEBwYXJhbSB7TnVtYmVyfSBzdHJpZGUgTnVtYmVyIG9mIGVsZW1lbnRzIGJldHdlZW4gdGhlIHN0YXJ0IG9mIGVhY2ggdmVjMi4gSWYgMCBhc3N1bWVzIHRpZ2h0bHkgcGFja2VkXG4gKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IE51bWJlciBvZiBlbGVtZW50cyB0byBza2lwIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5XG4gKiBAcGFyYW0ge051bWJlcn0gY291bnQgTnVtYmVyIG9mIHZlYzJzIHRvIGl0ZXJhdGUgb3Zlci4gSWYgMCBpdGVyYXRlcyBvdmVyIGVudGlyZSBhcnJheVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gRnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCB2ZWN0b3IgaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gW2FyZ10gYWRkaXRpb25hbCBhcmd1bWVudCB0byBwYXNzIHRvIGZuXG4gKiBAcmV0dXJucyB7QXJyYXl9IGFcbiAqIEBmdW5jdGlvblxuICovXG52ZWMyLmZvckVhY2ggPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZlYyA9IHZlYzIuY3JlYXRlKCk7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24oYSwgc3RyaWRlLCBvZmZzZXQsIGNvdW50LCBmbiwgYXJnKSB7XG4gICAgICAgIHZhciBpLCBsO1xuICAgICAgICBpZighc3RyaWRlKSB7XG4gICAgICAgICAgICBzdHJpZGUgPSAyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoIW9mZnNldCkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYoY291bnQpIHtcbiAgICAgICAgICAgIGwgPSBNYXRoLm1pbigoY291bnQgKiBzdHJpZGUpICsgb2Zmc2V0LCBhLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsID0gYS5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IoaSA9IG9mZnNldDsgaSA8IGw7IGkgKz0gc3RyaWRlKSB7XG4gICAgICAgICAgICB2ZWNbMF0gPSBhW2ldOyB2ZWNbMV0gPSBhW2krMV07XG4gICAgICAgICAgICBmbih2ZWMsIHZlYywgYXJnKTtcbiAgICAgICAgICAgIGFbaV0gPSB2ZWNbMF07IGFbaSsxXSA9IHZlY1sxXTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbn0pKCk7XG5cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7dmVjMn0gdmVjIHZlY3RvciB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yXG4gKi9cbnZlYzIuc3RyID0gZnVuY3Rpb24gKGEpIHtcbiAgICByZXR1cm4gJ3ZlYzIoJyArIGFbMF0gKyAnLCAnICsgYVsxXSArICcpJztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gdmVjMjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2dsLW1hdHJpeC9zcmMvZ2wtbWF0cml4L3ZlYzIuanNcbiAqKiBtb2R1bGUgaWQgPSAxNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQge1xuICAgIGluaXQ6IGZ1bmN0aW9uKGFyciwgdmFsKSB7XG4gICAgICAgIHZhciBsID0gYXJyLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGwtLSkge1xuICAgICAgICAgICAgYXJyW2xdID0gdmFsO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNodWZmbGVzIHRoZSBjb250ZW50IG9mIGFuIGFycmF5XG4gICAgICogQHJldHVybiB7QXJyYXl9IHRoZSBhcnJheSBpdHNlbGYgc2h1ZmZsZWRcbiAgICAgKi9cbiAgICBzaHVmZmxlOiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGkgPSBhcnIubGVuZ3RoIC0gMSwgaiwgeDtcbiAgICAgICAgZm9yIChpOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgaiA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGkpO1xuICAgICAgICAgICAgeCA9IGFycltpXTtcbiAgICAgICAgICAgIGFycltpXSA9IGFycltqXTtcbiAgICAgICAgICAgIGFycltqXSA9IHg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuXG4gICAgdG9Qb2ludExpc3Q6IGZ1bmN0aW9uKGFycikge1xuICAgICAgICB2YXIgaSwgaiwgcm93ID0gW10sIHJvd3MgPSBbXTtcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHJvdyA9IFtdO1xuICAgICAgICAgICAgZm9yICggaiA9IDA7IGogPCBhcnJbaV0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICByb3dbal0gPSBhcnJbaV1bal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByb3dzW2ldID0gXCJbXCIgKyByb3cuam9pbihcIixcIikgKyBcIl1cIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gXCJbXCIgKyByb3dzLmpvaW4oXCIsXFxyXFxuXCIpICsgXCJdXCI7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgdGhlIGVsZW1lbnRzIHdoaWNoJ3Mgc2NvcmUgaXMgYmlnZ2VyIHRoYW4gdGhlIHRocmVzaG9sZFxuICAgICAqIEByZXR1cm4ge0FycmF5fSB0aGUgcmVkdWNlZCBhcnJheVxuICAgICAqL1xuICAgIHRocmVzaG9sZDogZnVuY3Rpb24oYXJyLCB0aHJlc2hvbGQsIHNjb3JlRnVuYykge1xuICAgICAgICB2YXIgaSwgcXVldWUgPSBbXTtcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChzY29yZUZ1bmMuYXBwbHkoYXJyLCBbYXJyW2ldXSkgPj0gdGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgICAgcXVldWUucHVzaChhcnJbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBxdWV1ZTtcbiAgICB9LFxuXG4gICAgbWF4SW5kZXg6IGZ1bmN0aW9uKGFycikge1xuICAgICAgICB2YXIgaSwgbWF4ID0gMDtcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChhcnJbaV0gPiBhcnJbbWF4XSkge1xuICAgICAgICAgICAgICAgIG1heCA9IGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9LFxuXG4gICAgbWF4OiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGksIG1heCA9IDA7XG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoYXJyW2ldID4gbWF4KSB7XG4gICAgICAgICAgICAgICAgbWF4ID0gYXJyW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgfSxcblxuICAgIHN1bTogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBhcnIubGVuZ3RoLFxuICAgICAgICAgICAgc3VtID0gMDtcblxuICAgICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgICAgIHN1bSArPSBhcnJbbGVuZ3RoXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VtO1xuICAgIH1cbn07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9hcnJheV9oZWxwZXIuanNcbiAqKi8iLCJpbXBvcnQgSW1hZ2VXcmFwcGVyIGZyb20gJy4vaW1hZ2Vfd3JhcHBlcic7XG5pbXBvcnQgQ1ZVdGlscyBmcm9tICcuL2N2X3V0aWxzJztcbmltcG9ydCBSYXN0ZXJpemVyIGZyb20gJy4vcmFzdGVyaXplcic7XG5pbXBvcnQgVHJhY2VyIGZyb20gJy4vdHJhY2VyJztcbmltcG9ydCBza2VsZXRvbml6ZXIgZnJvbSAnLi9za2VsZXRvbml6ZXInO1xuaW1wb3J0IEFycmF5SGVscGVyIGZyb20gJy4vYXJyYXlfaGVscGVyJztcbmltcG9ydCBJbWFnZURlYnVnIGZyb20gJy4vaW1hZ2VfZGVidWcnO1xuaW1wb3J0IGdsTWF0cml4IGZyb20gJ2dsLW1hdHJpeCc7XG5cbnZhciBfY29uZmlnLFxuICAgIF9jdXJyZW50SW1hZ2VXcmFwcGVyLFxuICAgIF9za2VsSW1hZ2VXcmFwcGVyLFxuICAgIF9zdWJJbWFnZVdyYXBwZXIsXG4gICAgX2xhYmVsSW1hZ2VXcmFwcGVyLFxuICAgIF9wYXRjaEdyaWQsXG4gICAgX3BhdGNoTGFiZWxHcmlkLFxuICAgIF9pbWFnZVRvUGF0Y2hHcmlkLFxuICAgIF9iaW5hcnlJbWFnZVdyYXBwZXIsXG4gICAgX3BhdGNoU2l6ZSxcbiAgICBfY2FudmFzQ29udGFpbmVyID0ge1xuICAgICAgICBjdHg6IHtcbiAgICAgICAgICAgIGJpbmFyeTogbnVsbFxuICAgICAgICB9LFxuICAgICAgICBkb206IHtcbiAgICAgICAgICAgIGJpbmFyeTogbnVsbFxuICAgICAgICB9XG4gICAgfSxcbiAgICBfbnVtUGF0Y2hlcyA9IHt4OiAwLCB5OiAwfSxcbiAgICBfaW5wdXRJbWFnZVdyYXBwZXIsXG4gICAgX3NrZWxldG9uaXplcixcbiAgICB2ZWMyID0gZ2xNYXRyaXgudmVjMixcbiAgICBtYXQyID0gZ2xNYXRyaXgubWF0MjtcblxuZnVuY3Rpb24gaW5pdEJ1ZmZlcnMoKSB7XG4gICAgdmFyIHNrZWxldG9uSW1hZ2VEYXRhO1xuXG4gICAgaWYgKF9jb25maWcuaGFsZlNhbXBsZSkge1xuICAgICAgICBfY3VycmVudEltYWdlV3JhcHBlciA9IG5ldyBJbWFnZVdyYXBwZXIoe1xuICAgICAgICAgICAgeDogX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUueCAvIDIgfCAwLFxuICAgICAgICAgICAgeTogX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUueSAvIDIgfCAwXG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIF9jdXJyZW50SW1hZ2VXcmFwcGVyID0gX2lucHV0SW1hZ2VXcmFwcGVyO1xuICAgIH1cblxuICAgIF9wYXRjaFNpemUgPSBDVlV0aWxzLmNhbGN1bGF0ZVBhdGNoU2l6ZShfY29uZmlnLnBhdGNoU2l6ZSwgX2N1cnJlbnRJbWFnZVdyYXBwZXIuc2l6ZSk7XG5cbiAgICBfbnVtUGF0Y2hlcy54ID0gX2N1cnJlbnRJbWFnZVdyYXBwZXIuc2l6ZS54IC8gX3BhdGNoU2l6ZS54IHwgMDtcbiAgICBfbnVtUGF0Y2hlcy55ID0gX2N1cnJlbnRJbWFnZVdyYXBwZXIuc2l6ZS55IC8gX3BhdGNoU2l6ZS55IHwgMDtcblxuICAgIF9iaW5hcnlJbWFnZVdyYXBwZXIgPSBuZXcgSW1hZ2VXcmFwcGVyKF9jdXJyZW50SW1hZ2VXcmFwcGVyLnNpemUsIHVuZGVmaW5lZCwgVWludDhBcnJheSwgZmFsc2UpO1xuXG4gICAgX2xhYmVsSW1hZ2VXcmFwcGVyID0gbmV3IEltYWdlV3JhcHBlcihfcGF0Y2hTaXplLCB1bmRlZmluZWQsIEFycmF5LCB0cnVlKTtcblxuICAgIHNrZWxldG9uSW1hZ2VEYXRhID0gbmV3IEFycmF5QnVmZmVyKDY0ICogMTAyNCk7XG4gICAgX3N1YkltYWdlV3JhcHBlciA9IG5ldyBJbWFnZVdyYXBwZXIoX3BhdGNoU2l6ZSxcbiAgICAgICAgbmV3IFVpbnQ4QXJyYXkoc2tlbGV0b25JbWFnZURhdGEsIDAsIF9wYXRjaFNpemUueCAqIF9wYXRjaFNpemUueSkpO1xuICAgIF9za2VsSW1hZ2VXcmFwcGVyID0gbmV3IEltYWdlV3JhcHBlcihfcGF0Y2hTaXplLFxuICAgICAgICBuZXcgVWludDhBcnJheShza2VsZXRvbkltYWdlRGF0YSwgX3BhdGNoU2l6ZS54ICogX3BhdGNoU2l6ZS55ICogMywgX3BhdGNoU2l6ZS54ICogX3BhdGNoU2l6ZS55KSxcbiAgICAgICAgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICBfc2tlbGV0b25pemVyID0gc2tlbGV0b25pemVyKCh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgPyB3aW5kb3cgOiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnKSA/IHNlbGYgOiBnbG9iYWwsIHtcbiAgICAgICAgc2l6ZTogX3BhdGNoU2l6ZS54XG4gICAgfSwgc2tlbGV0b25JbWFnZURhdGEpO1xuXG4gICAgX2ltYWdlVG9QYXRjaEdyaWQgPSBuZXcgSW1hZ2VXcmFwcGVyKHtcbiAgICAgICAgeDogKF9jdXJyZW50SW1hZ2VXcmFwcGVyLnNpemUueCAvIF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS54KSB8IDAsXG4gICAgICAgIHk6IChfY3VycmVudEltYWdlV3JhcHBlci5zaXplLnkgLyBfc3ViSW1hZ2VXcmFwcGVyLnNpemUueSkgfCAwXG4gICAgfSwgdW5kZWZpbmVkLCBBcnJheSwgdHJ1ZSk7XG4gICAgX3BhdGNoR3JpZCA9IG5ldyBJbWFnZVdyYXBwZXIoX2ltYWdlVG9QYXRjaEdyaWQuc2l6ZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRydWUpO1xuICAgIF9wYXRjaExhYmVsR3JpZCA9IG5ldyBJbWFnZVdyYXBwZXIoX2ltYWdlVG9QYXRjaEdyaWQuc2l6ZSwgdW5kZWZpbmVkLCBJbnQzMkFycmF5LCB0cnVlKTtcbn1cblxuZnVuY3Rpb24gaW5pdENhbnZhcygpIHtcbiAgICBpZiAoX2NvbmZpZy51c2VXb3JrZXIgfHwgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5LmNsYXNzTmFtZSA9IFwiYmluYXJ5QnVmZmVyXCI7XG4gICAgaWYgKF9jb25maWcuc2hvd0NhbnZhcyA9PT0gdHJ1ZSkge1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2RlYnVnXCIpLmFwcGVuZENoaWxkKF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeSk7XG4gICAgfVxuICAgIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSA9IF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeS5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5LndpZHRoID0gX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLng7XG4gICAgX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5LmhlaWdodCA9IF9iaW5hcnlJbWFnZVdyYXBwZXIuc2l6ZS55O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBib3VuZGluZyBib3ggd2hpY2ggZW5jbG9zZXMgYWxsIHRoZSBnaXZlbiBwYXRjaGVzXG4gKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBtaW5pbWFsIGJvdW5kaW5nIGJveFxuICovXG5mdW5jdGlvbiBib3hGcm9tUGF0Y2hlcyhwYXRjaGVzKSB7XG4gICAgdmFyIG92ZXJBdmcsXG4gICAgICAgIGksXG4gICAgICAgIGosXG4gICAgICAgIHBhdGNoLFxuICAgICAgICB0cmFuc01hdCxcbiAgICAgICAgbWlueCA9XG4gICAgICAgIF9iaW5hcnlJbWFnZVdyYXBwZXIuc2l6ZS54LFxuICAgICAgICBtaW55ID0gX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLnksXG4gICAgICAgIG1heHggPSAtX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLngsXG4gICAgICAgIG1heHkgPSAtX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLnksXG4gICAgICAgIGJveCxcbiAgICAgICAgc2NhbGU7XG5cbiAgICAvLyBkcmF3IGFsbCBwYXRjaGVzIHdoaWNoIGFyZSB0byBiZSB0YWtlbiBpbnRvIGNvbnNpZGVyYXRpb25cbiAgICBvdmVyQXZnID0gMDtcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBhdGNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0Y2ggPSBwYXRjaGVzW2ldO1xuICAgICAgICBvdmVyQXZnICs9IHBhdGNoLnJhZDtcbiAgICAgICAgaWYgKF9jb25maWcuc2hvd1BhdGNoZXMpIHtcbiAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1JlY3QocGF0Y2gucG9zLCBfc3ViSW1hZ2VXcmFwcGVyLnNpemUsIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSwge2NvbG9yOiBcInJlZFwifSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvdmVyQXZnIC89IHBhdGNoZXMubGVuZ3RoO1xuICAgIG92ZXJBdmcgPSAob3ZlckF2ZyAqIDE4MCAvIE1hdGguUEkgKyA5MCkgJSAxODAgLSA5MDtcbiAgICBpZiAob3ZlckF2ZyA8IDApIHtcbiAgICAgICAgb3ZlckF2ZyArPSAxODA7XG4gICAgfVxuXG4gICAgb3ZlckF2ZyA9ICgxODAgLSBvdmVyQXZnKSAqIE1hdGguUEkgLyAxODA7XG4gICAgdHJhbnNNYXQgPSBtYXQyLmNsb25lKFtNYXRoLmNvcyhvdmVyQXZnKSwgTWF0aC5zaW4ob3ZlckF2ZyksIC1NYXRoLnNpbihvdmVyQXZnKSwgTWF0aC5jb3Mob3ZlckF2ZyldKTtcblxuICAgIC8vIGl0ZXJhdGUgb3ZlciBwYXRjaGVzIGFuZCByb3RhdGUgYnkgYW5nbGVcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBhdGNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0Y2ggPSBwYXRjaGVzW2ldO1xuICAgICAgICBmb3IgKCBqID0gMDsgaiA8IDQ7IGorKykge1xuICAgICAgICAgICAgdmVjMi50cmFuc2Zvcm1NYXQyKHBhdGNoLmJveFtqXSwgcGF0Y2guYm94W2pdLCB0cmFuc01hdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoX2NvbmZpZy5ib3hGcm9tUGF0Y2hlcy5zaG93VHJhbnNmb3JtZWQpIHtcbiAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgocGF0Y2guYm94LCB7eDogMCwgeTogMX0sIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSwge2NvbG9yOiAnIzk5ZmYwMCcsIGxpbmVXaWR0aDogMn0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZmluZCBib3VuZGluZyBib3hcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBhdGNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0Y2ggPSBwYXRjaGVzW2ldO1xuICAgICAgICBmb3IgKCBqID0gMDsgaiA8IDQ7IGorKykge1xuICAgICAgICAgICAgaWYgKHBhdGNoLmJveFtqXVswXSA8IG1pbngpIHtcbiAgICAgICAgICAgICAgICBtaW54ID0gcGF0Y2guYm94W2pdWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhdGNoLmJveFtqXVswXSA+IG1heHgpIHtcbiAgICAgICAgICAgICAgICBtYXh4ID0gcGF0Y2guYm94W2pdWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhdGNoLmJveFtqXVsxXSA8IG1pbnkpIHtcbiAgICAgICAgICAgICAgICBtaW55ID0gcGF0Y2guYm94W2pdWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhdGNoLmJveFtqXVsxXSA+IG1heHkpIHtcbiAgICAgICAgICAgICAgICBtYXh5ID0gcGF0Y2guYm94W2pdWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYm94ID0gW1ttaW54LCBtaW55XSwgW21heHgsIG1pbnldLCBbbWF4eCwgbWF4eV0sIFttaW54LCBtYXh5XV07XG5cbiAgICBpZiAoX2NvbmZpZy5ib3hGcm9tUGF0Y2hlcy5zaG93VHJhbnNmb3JtZWRCb3gpIHtcbiAgICAgICAgSW1hZ2VEZWJ1Zy5kcmF3UGF0aChib3gsIHt4OiAwLCB5OiAxfSwgX2NhbnZhc0NvbnRhaW5lci5jdHguYmluYXJ5LCB7Y29sb3I6ICcjZmYwMDAwJywgbGluZVdpZHRoOiAyfSk7XG4gICAgfVxuXG4gICAgc2NhbGUgPSBfY29uZmlnLmhhbGZTYW1wbGUgPyAyIDogMTtcbiAgICAvLyByZXZlcnNlIHJvdGF0aW9uO1xuICAgIHRyYW5zTWF0ID0gbWF0Mi5pbnZlcnQodHJhbnNNYXQsIHRyYW5zTWF0KTtcbiAgICBmb3IgKCBqID0gMDsgaiA8IDQ7IGorKykge1xuICAgICAgICB2ZWMyLnRyYW5zZm9ybU1hdDIoYm94W2pdLCBib3hbal0sIHRyYW5zTWF0KTtcbiAgICB9XG5cbiAgICBpZiAoX2NvbmZpZy5ib3hGcm9tUGF0Y2hlcy5zaG93QkIpIHtcbiAgICAgICAgSW1hZ2VEZWJ1Zy5kcmF3UGF0aChib3gsIHt4OiAwLCB5OiAxfSwgX2NhbnZhc0NvbnRhaW5lci5jdHguYmluYXJ5LCB7Y29sb3I6ICcjZmYwMDAwJywgbGluZVdpZHRoOiAyfSk7XG4gICAgfVxuXG4gICAgZm9yICggaiA9IDA7IGogPCA0OyBqKyspIHtcbiAgICAgICAgdmVjMi5zY2FsZShib3hbal0sIGJveFtqXSwgc2NhbGUpO1xuICAgIH1cblxuICAgIHJldHVybiBib3g7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJpbmFyeSBpbWFnZSBvZiB0aGUgY3VycmVudCBpbWFnZVxuICovXG5mdW5jdGlvbiBiaW5hcml6ZUltYWdlKCkge1xuICAgIENWVXRpbHMub3RzdVRocmVzaG9sZChfY3VycmVudEltYWdlV3JhcHBlciwgX2JpbmFyeUltYWdlV3JhcHBlcik7XG4gICAgX2JpbmFyeUltYWdlV3JhcHBlci56ZXJvQm9yZGVyKCk7XG4gICAgaWYgKF9jb25maWcuc2hvd0NhbnZhcykge1xuICAgICAgICBfYmluYXJ5SW1hZ2VXcmFwcGVyLnNob3coX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5LCAyNTUpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBJdGVyYXRlIG92ZXIgdGhlIGVudGlyZSBpbWFnZVxuICogZXh0cmFjdCBwYXRjaGVzXG4gKi9cbmZ1bmN0aW9uIGZpbmRQYXRjaGVzKCkge1xuICAgIHZhciBpLFxuICAgICAgICBqLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICBtb21lbnRzLFxuICAgICAgICBwYXRjaGVzRm91bmQgPSBbXSxcbiAgICAgICAgcmFzdGVyaXplcixcbiAgICAgICAgcmFzdGVyUmVzdWx0LFxuICAgICAgICBwYXRjaDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgX251bVBhdGNoZXMueDsgaSsrKSB7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBfbnVtUGF0Y2hlcy55OyBqKyspIHtcbiAgICAgICAgICAgIHggPSBfc3ViSW1hZ2VXcmFwcGVyLnNpemUueCAqIGk7XG4gICAgICAgICAgICB5ID0gX3N1YkltYWdlV3JhcHBlci5zaXplLnkgKiBqO1xuXG4gICAgICAgICAgICAvLyBzZXBlcmF0ZSBwYXJ0c1xuICAgICAgICAgICAgc2tlbGV0b25pemUoeCwgeSk7XG5cbiAgICAgICAgICAgIC8vIFJhc3Rlcml6ZSwgZmluZCBpbmRpdmlkdWFsIGJhcnNcbiAgICAgICAgICAgIF9za2VsSW1hZ2VXcmFwcGVyLnplcm9Cb3JkZXIoKTtcbiAgICAgICAgICAgIEFycmF5SGVscGVyLmluaXQoX2xhYmVsSW1hZ2VXcmFwcGVyLmRhdGEsIDApO1xuICAgICAgICAgICAgcmFzdGVyaXplciA9IFJhc3Rlcml6ZXIuY3JlYXRlKF9za2VsSW1hZ2VXcmFwcGVyLCBfbGFiZWxJbWFnZVdyYXBwZXIpO1xuICAgICAgICAgICAgcmFzdGVyUmVzdWx0ID0gcmFzdGVyaXplci5yYXN0ZXJpemUoMCk7XG5cbiAgICAgICAgICAgIGlmIChfY29uZmlnLnNob3dMYWJlbHMpIHtcbiAgICAgICAgICAgICAgICBfbGFiZWxJbWFnZVdyYXBwZXIub3ZlcmxheShfY2FudmFzQ29udGFpbmVyLmRvbS5iaW5hcnksIE1hdGguZmxvb3IoMzYwIC8gcmFzdGVyUmVzdWx0LmNvdW50KSxcbiAgICAgICAgICAgICAgICAgICAge3g6IHgsIHk6IHl9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIG1vbWVudHMgZnJvbSB0aGUgc2tlbGV0b25pemVkIHBhdGNoXG4gICAgICAgICAgICBtb21lbnRzID0gX2xhYmVsSW1hZ2VXcmFwcGVyLm1vbWVudHMocmFzdGVyUmVzdWx0LmNvdW50KTtcblxuICAgICAgICAgICAgLy8gZXh0cmFjdCBlbGlnaWJsZSBwYXRjaGVzXG4gICAgICAgICAgICBwYXRjaGVzRm91bmQgPSBwYXRjaGVzRm91bmQuY29uY2F0KGRlc2NyaWJlUGF0Y2gobW9tZW50cywgW2ksIGpdLCB4LCB5KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoX2NvbmZpZy5zaG93Rm91bmRQYXRjaGVzKSB7XG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgcGF0Y2hlc0ZvdW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBwYXRjaCA9IHBhdGNoZXNGb3VuZFtpXTtcbiAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1JlY3QocGF0Y2gucG9zLCBfc3ViSW1hZ2VXcmFwcGVyLnNpemUsIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSxcbiAgICAgICAgICAgICAgICB7Y29sb3I6IFwiIzk5ZmYwMFwiLCBsaW5lV2lkdGg6IDJ9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwYXRjaGVzRm91bmQ7XG59XG5cbi8qKlxuICogRmluZHMgdGhvc2UgY29ubmVjdGVkIGFyZWFzIHdoaWNoIGNvbnRhaW4gYXQgbGVhc3QgNiBwYXRjaGVzXG4gKiBhbmQgcmV0dXJucyB0aGVtIG9yZGVyZWQgREVTQyBieSB0aGUgbnVtYmVyIG9mIGNvbnRhaW5lZCBwYXRjaGVzXG4gKiBAcGFyYW0ge051bWJlcn0gbWF4TGFiZWxcbiAqL1xuZnVuY3Rpb24gZmluZEJpZ2dlc3RDb25uZWN0ZWRBcmVhcyhtYXhMYWJlbCl7XG4gICAgdmFyIGksXG4gICAgICAgIHN1bSxcbiAgICAgICAgbGFiZWxIaXN0ID0gW10sXG4gICAgICAgIHRvcExhYmVscyA9IFtdO1xuXG4gICAgZm9yICggaSA9IDA7IGkgPCBtYXhMYWJlbDsgaSsrKSB7XG4gICAgICAgIGxhYmVsSGlzdC5wdXNoKDApO1xuICAgIH1cbiAgICBzdW0gPSBfcGF0Y2hMYWJlbEdyaWQuZGF0YS5sZW5ndGg7XG4gICAgd2hpbGUgKHN1bS0tKSB7XG4gICAgICAgIGlmIChfcGF0Y2hMYWJlbEdyaWQuZGF0YVtzdW1dID4gMCkge1xuICAgICAgICAgICAgbGFiZWxIaXN0W19wYXRjaExhYmVsR3JpZC5kYXRhW3N1bV0gLSAxXSsrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGFiZWxIaXN0ID0gbGFiZWxIaXN0Lm1hcChmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiB2YWwsXG4gICAgICAgICAgICBsYWJlbDogaWR4ICsgMVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgbGFiZWxIaXN0LnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gYi52YWwgLSBhLnZhbDtcbiAgICB9KTtcblxuICAgIC8vIGV4dHJhY3QgdG9wIGFyZWFzIHdpdGggYXQgbGVhc3QgNiBwYXRjaGVzIHByZXNlbnRcbiAgICB0b3BMYWJlbHMgPSBsYWJlbEhpc3QuZmlsdGVyKGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgIHJldHVybiBlbC52YWwgPj0gNTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0b3BMYWJlbHM7XG59XG5cbi8qKlxuICpcbiAqL1xuZnVuY3Rpb24gZmluZEJveGVzKHRvcExhYmVscywgbWF4TGFiZWwpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgaixcbiAgICAgICAgc3VtLFxuICAgICAgICBwYXRjaGVzID0gW10sXG4gICAgICAgIHBhdGNoLFxuICAgICAgICBib3gsXG4gICAgICAgIGJveGVzID0gW10sXG4gICAgICAgIGhzdiA9IFswLCAxLCAxXSxcbiAgICAgICAgcmdiID0gWzAsIDAsIDBdO1xuXG4gICAgZm9yICggaSA9IDA7IGkgPCB0b3BMYWJlbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc3VtID0gX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoO1xuICAgICAgICBwYXRjaGVzLmxlbmd0aCA9IDA7XG4gICAgICAgIHdoaWxlIChzdW0tLSkge1xuICAgICAgICAgICAgaWYgKF9wYXRjaExhYmVsR3JpZC5kYXRhW3N1bV0gPT09IHRvcExhYmVsc1tpXS5sYWJlbCkge1xuICAgICAgICAgICAgICAgIHBhdGNoID0gX2ltYWdlVG9QYXRjaEdyaWQuZGF0YVtzdW1dO1xuICAgICAgICAgICAgICAgIHBhdGNoZXMucHVzaChwYXRjaCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYm94ID0gYm94RnJvbVBhdGNoZXMocGF0Y2hlcyk7XG4gICAgICAgIGlmIChib3gpIHtcbiAgICAgICAgICAgIGJveGVzLnB1c2goYm94KTtcblxuICAgICAgICAgICAgLy8gZHJhdyBwYXRjaC1sYWJlbHMgaWYgcmVxdWVzdGVkXG4gICAgICAgICAgICBpZiAoX2NvbmZpZy5zaG93UmVtYWluaW5nUGF0Y2hMYWJlbHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IHBhdGNoZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0Y2ggPSBwYXRjaGVzW2pdO1xuICAgICAgICAgICAgICAgICAgICBoc3ZbMF0gPSAodG9wTGFiZWxzW2ldLmxhYmVsIC8gKG1heExhYmVsICsgMSkpICogMzYwO1xuICAgICAgICAgICAgICAgICAgICBDVlV0aWxzLmhzdjJyZ2IoaHN2LCByZ2IpO1xuICAgICAgICAgICAgICAgICAgICBJbWFnZURlYnVnLmRyYXdSZWN0KHBhdGNoLnBvcywgX3N1YkltYWdlV3JhcHBlci5zaXplLCBfY2FudmFzQ29udGFpbmVyLmN0eC5iaW5hcnksXG4gICAgICAgICAgICAgICAgICAgICAgICB7Y29sb3I6IFwicmdiKFwiICsgcmdiLmpvaW4oXCIsXCIpICsgXCIpXCIsIGxpbmVXaWR0aDogMn0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYm94ZXM7XG59XG5cbi8qKlxuICogRmluZCBzaW1pbGFyIG1vbWVudHMgKHZpYSBjbHVzdGVyKVxuICogQHBhcmFtIHtPYmplY3R9IG1vbWVudHNcbiAqL1xuZnVuY3Rpb24gc2ltaWxhck1vbWVudHMobW9tZW50cykge1xuICAgIHZhciBjbHVzdGVycyA9IENWVXRpbHMuY2x1c3Rlcihtb21lbnRzLCAwLjkwKTtcbiAgICB2YXIgdG9wQ2x1c3RlciA9IENWVXRpbHMudG9wR2VuZXJpYyhjbHVzdGVycywgMSwgZnVuY3Rpb24oZSkge1xuICAgICAgICByZXR1cm4gZS5nZXRQb2ludHMoKS5sZW5ndGg7XG4gICAgfSk7XG4gICAgdmFyIHBvaW50cyA9IFtdLCByZXN1bHQgPSBbXTtcbiAgICBpZiAodG9wQ2x1c3Rlci5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcG9pbnRzID0gdG9wQ2x1c3RlclswXS5pdGVtLmdldFBvaW50cygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gocG9pbnRzW2ldLnBvaW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBza2VsZXRvbml6ZSh4LCB5KSB7XG4gICAgX2JpbmFyeUltYWdlV3JhcHBlci5zdWJJbWFnZUFzQ29weShfc3ViSW1hZ2VXcmFwcGVyLCBDVlV0aWxzLmltYWdlUmVmKHgsIHkpKTtcbiAgICBfc2tlbGV0b25pemVyLnNrZWxldG9uaXplKCk7XG5cbiAgICAvLyBTaG93IHNrZWxldG9uIGlmIHJlcXVlc3RlZFxuICAgIGlmIChfY29uZmlnLnNob3dTa2VsZXRvbikge1xuICAgICAgICBfc2tlbEltYWdlV3JhcHBlci5vdmVybGF5KF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeSwgMzYwLCBDVlV0aWxzLmltYWdlUmVmKHgsIHkpKTtcbiAgICB9XG59XG5cbi8qKlxuICogRXh0cmFjdHMgYW5kIGRlc2NyaWJlcyB0aG9zZSBwYXRjaGVzIHdoaWNoIHNlZW0gdG8gY29udGFpbiBhIGJhcmNvZGUgcGF0dGVyblxuICogQHBhcmFtIHtBcnJheX0gbW9tZW50c1xuICogQHBhcmFtIHtPYmplY3R9IHBhdGNoUG9zLFxuICogQHBhcmFtIHtOdW1iZXJ9IHhcbiAqIEBwYXJhbSB7TnVtYmVyfSB5XG4gKiBAcmV0dXJucyB7QXJyYXl9IGxpc3Qgb2YgcGF0Y2hlc1xuICovXG5mdW5jdGlvbiBkZXNjcmliZVBhdGNoKG1vbWVudHMsIHBhdGNoUG9zLCB4LCB5KSB7XG4gICAgdmFyIGssXG4gICAgICAgIGF2ZyxcbiAgICAgICAgZWxpZ2libGVNb21lbnRzID0gW10sXG4gICAgICAgIG1hdGNoaW5nTW9tZW50cyxcbiAgICAgICAgcGF0Y2gsXG4gICAgICAgIHBhdGNoZXNGb3VuZCA9IFtdLFxuICAgICAgICBtaW5Db21wb25lbnRXZWlnaHQgPSBNYXRoLmNlaWwoX3BhdGNoU2l6ZS54IC8gMyk7XG5cbiAgICBpZiAobW9tZW50cy5sZW5ndGggPj0gMikge1xuICAgICAgICAvLyBvbmx5IGNvbGxlY3QgbW9tZW50cyB3aGljaCdzIGFyZWEgY292ZXJzIGF0IGxlYXN0IG1pbkNvbXBvbmVudFdlaWdodCBwaXhlbHMuXG4gICAgICAgIGZvciAoIGsgPSAwOyBrIDwgbW9tZW50cy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgaWYgKG1vbWVudHNba10ubTAwID4gbWluQ29tcG9uZW50V2VpZ2h0KSB7XG4gICAgICAgICAgICAgICAgZWxpZ2libGVNb21lbnRzLnB1c2gobW9tZW50c1trXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBhdCBsZWFzdCAyIG1vbWVudHMgYXJlIGZvdW5kIHdoaWNoIGhhdmUgYXQgbGVhc3QgbWluQ29tcG9uZW50V2VpZ2h0cyBjb3ZlcmVkXG4gICAgICAgIGlmIChlbGlnaWJsZU1vbWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIG1hdGNoaW5nTW9tZW50cyA9IHNpbWlsYXJNb21lbnRzKGVsaWdpYmxlTW9tZW50cyk7XG4gICAgICAgICAgICBhdmcgPSAwO1xuICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIHRoZSBzaW1pbGFyaXR5IG9mIHRoZSBtb21lbnRzXG4gICAgICAgICAgICBmb3IgKCBrID0gMDsgayA8IG1hdGNoaW5nTW9tZW50cy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICAgIGF2ZyArPSBtYXRjaGluZ01vbWVudHNba10ucmFkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBPbmx5IHR3byBvZiB0aGUgbW9tZW50cyBhcmUgYWxsb3dlZCBub3QgdG8gZml0IGludG8gdGhlIGVxdWF0aW9uXG4gICAgICAgICAgICAvLyBhZGQgdGhlIHBhdGNoIHRvIHRoZSBzZXRcbiAgICAgICAgICAgIGlmIChtYXRjaGluZ01vbWVudHMubGVuZ3RoID4gMVxuICAgICAgICAgICAgICAgICAgICAmJiBtYXRjaGluZ01vbWVudHMubGVuZ3RoID49IChlbGlnaWJsZU1vbWVudHMubGVuZ3RoIC8gNCkgKiAzXG4gICAgICAgICAgICAgICAgICAgICYmIG1hdGNoaW5nTW9tZW50cy5sZW5ndGggPiBtb21lbnRzLmxlbmd0aCAvIDQpIHtcbiAgICAgICAgICAgICAgICBhdmcgLz0gbWF0Y2hpbmdNb21lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBwYXRjaCA9IHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHBhdGNoUG9zWzFdICogX251bVBhdGNoZXMueCArIHBhdGNoUG9zWzBdLFxuICAgICAgICAgICAgICAgICAgICBwb3M6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB5XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGJveDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjMi5jbG9uZShbeCwgeV0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmVjMi5jbG9uZShbeCArIF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS54LCB5XSksXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWMyLmNsb25lKFt4ICsgX3N1YkltYWdlV3JhcHBlci5zaXplLngsIHkgKyBfc3ViSW1hZ2VXcmFwcGVyLnNpemUueV0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmVjMi5jbG9uZShbeCwgeSArIF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS55XSlcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgbW9tZW50czogbWF0Y2hpbmdNb21lbnRzLFxuICAgICAgICAgICAgICAgICAgICByYWQ6IGF2ZyxcbiAgICAgICAgICAgICAgICAgICAgdmVjOiB2ZWMyLmNsb25lKFtNYXRoLmNvcyhhdmcpLCBNYXRoLnNpbihhdmcpXSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHBhdGNoZXNGb3VuZC5wdXNoKHBhdGNoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGF0Y2hlc0ZvdW5kO1xufVxuXG4vKipcbiAqIGZpbmRzIHBhdGNoZXMgd2hpY2ggYXJlIGNvbm5lY3RlZCBhbmQgc2hhcmUgdGhlIHNhbWUgb3JpZW50YXRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXRjaGVzRm91bmRcbiAqL1xuZnVuY3Rpb24gcmFzdGVyaXplQW5ndWxhclNpbWlsYXJpdHkocGF0Y2hlc0ZvdW5kKSB7XG4gICAgdmFyIGxhYmVsID0gMCxcbiAgICAgICAgdGhyZXNob2xkID0gMC45NSxcbiAgICAgICAgY3VycklkeCA9IDAsXG4gICAgICAgIGosXG4gICAgICAgIHBhdGNoLFxuICAgICAgICBoc3YgPSBbMCwgMSwgMV0sXG4gICAgICAgIHJnYiA9IFswLCAwLCAwXTtcblxuICAgIGZ1bmN0aW9uIG5vdFlldFByb2Nlc3NlZCgpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChfcGF0Y2hMYWJlbEdyaWQuZGF0YVtpXSA9PT0gMCAmJiBfcGF0Y2hHcmlkLmRhdGFbaV0gPT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX3BhdGNoTGFiZWxHcmlkLmxlbmd0aDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0cmFjZShjdXJyZW50SWR4KSB7XG4gICAgICAgIHZhciB4LFxuICAgICAgICAgICAgeSxcbiAgICAgICAgICAgIGN1cnJlbnRQYXRjaCxcbiAgICAgICAgICAgIGlkeCxcbiAgICAgICAgICAgIGRpcixcbiAgICAgICAgICAgIGN1cnJlbnQgPSB7XG4gICAgICAgICAgICAgICAgeDogY3VycmVudElkeCAlIF9wYXRjaExhYmVsR3JpZC5zaXplLngsXG4gICAgICAgICAgICAgICAgeTogKGN1cnJlbnRJZHggLyBfcGF0Y2hMYWJlbEdyaWQuc2l6ZS54KSB8IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaW1pbGFyaXR5O1xuXG4gICAgICAgIGlmIChjdXJyZW50SWR4IDwgX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICBjdXJyZW50UGF0Y2ggPSBfaW1hZ2VUb1BhdGNoR3JpZC5kYXRhW2N1cnJlbnRJZHhdO1xuICAgICAgICAgICAgLy8gYXNzaWduIGxhYmVsXG4gICAgICAgICAgICBfcGF0Y2hMYWJlbEdyaWQuZGF0YVtjdXJyZW50SWR4XSA9IGxhYmVsO1xuICAgICAgICAgICAgZm9yICggZGlyID0gMDsgZGlyIDwgVHJhY2VyLnNlYXJjaERpcmVjdGlvbnMubGVuZ3RoOyBkaXIrKykge1xuICAgICAgICAgICAgICAgIHkgPSBjdXJyZW50LnkgKyBUcmFjZXIuc2VhcmNoRGlyZWN0aW9uc1tkaXJdWzBdO1xuICAgICAgICAgICAgICAgIHggPSBjdXJyZW50LnggKyBUcmFjZXIuc2VhcmNoRGlyZWN0aW9uc1tkaXJdWzFdO1xuICAgICAgICAgICAgICAgIGlkeCA9IHkgKiBfcGF0Y2hMYWJlbEdyaWQuc2l6ZS54ICsgeDtcblxuICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIGlmIHBhdGNoIGVtcHR5XG4gICAgICAgICAgICAgICAgaWYgKF9wYXRjaEdyaWQuZGF0YVtpZHhdID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIF9wYXRjaExhYmVsR3JpZC5kYXRhW2lkeF0gPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoX3BhdGNoTGFiZWxHcmlkLmRhdGFbaWR4XSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBzaW1pbGFyaXR5ID0gTWF0aC5hYnModmVjMi5kb3QoX2ltYWdlVG9QYXRjaEdyaWQuZGF0YVtpZHhdLnZlYywgY3VycmVudFBhdGNoLnZlYykpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2ltaWxhcml0eSA+IHRocmVzaG9sZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2UoaWR4KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHByZXBhcmUgZm9yIGZpbmRpbmcgdGhlIHJpZ2h0IHBhdGNoZXNcbiAgICBBcnJheUhlbHBlci5pbml0KF9wYXRjaEdyaWQuZGF0YSwgMCk7XG4gICAgQXJyYXlIZWxwZXIuaW5pdChfcGF0Y2hMYWJlbEdyaWQuZGF0YSwgMCk7XG4gICAgQXJyYXlIZWxwZXIuaW5pdChfaW1hZ2VUb1BhdGNoR3JpZC5kYXRhLCBudWxsKTtcblxuICAgIGZvciAoIGogPSAwOyBqIDwgcGF0Y2hlc0ZvdW5kLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHBhdGNoID0gcGF0Y2hlc0ZvdW5kW2pdO1xuICAgICAgICBfaW1hZ2VUb1BhdGNoR3JpZC5kYXRhW3BhdGNoLmluZGV4XSA9IHBhdGNoO1xuICAgICAgICBfcGF0Y2hHcmlkLmRhdGFbcGF0Y2guaW5kZXhdID0gMTtcbiAgICB9XG5cbiAgICAvLyByYXN0ZXJpemUgdGhlIHBhdGNoZXMgZm91bmQgdG8gZGV0ZXJtaW5lIGFyZWFcbiAgICBfcGF0Y2hHcmlkLnplcm9Cb3JkZXIoKTtcblxuICAgIHdoaWxlICgoIGN1cnJJZHggPSBub3RZZXRQcm9jZXNzZWQoKSkgPCBfcGF0Y2hMYWJlbEdyaWQuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgbGFiZWwrKztcbiAgICAgICAgdHJhY2UoY3VycklkeCk7XG4gICAgfVxuXG4gICAgLy8gZHJhdyBwYXRjaC1sYWJlbHMgaWYgcmVxdWVzdGVkXG4gICAgaWYgKF9jb25maWcuc2hvd1BhdGNoTGFiZWxzKSB7XG4gICAgICAgIGZvciAoIGogPSAwOyBqIDwgX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChfcGF0Y2hMYWJlbEdyaWQuZGF0YVtqXSA+IDAgJiYgX3BhdGNoTGFiZWxHcmlkLmRhdGFbal0gPD0gbGFiZWwpIHtcbiAgICAgICAgICAgICAgICBwYXRjaCA9IF9pbWFnZVRvUGF0Y2hHcmlkLmRhdGFbal07XG4gICAgICAgICAgICAgICAgaHN2WzBdID0gKF9wYXRjaExhYmVsR3JpZC5kYXRhW2pdIC8gKGxhYmVsICsgMSkpICogMzYwO1xuICAgICAgICAgICAgICAgIENWVXRpbHMuaHN2MnJnYihoc3YsIHJnYik7XG4gICAgICAgICAgICAgICAgSW1hZ2VEZWJ1Zy5kcmF3UmVjdChwYXRjaC5wb3MsIF9zdWJJbWFnZVdyYXBwZXIuc2l6ZSwgX2NhbnZhc0NvbnRhaW5lci5jdHguYmluYXJ5LFxuICAgICAgICAgICAgICAgICAgICB7Y29sb3I6IFwicmdiKFwiICsgcmdiLmpvaW4oXCIsXCIpICsgXCIpXCIsIGxpbmVXaWR0aDogMn0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxhYmVsO1xufVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgaW5pdDogZnVuY3Rpb24oaW5wdXRJbWFnZVdyYXBwZXIsIGNvbmZpZykge1xuICAgICAgICBfY29uZmlnID0gY29uZmlnO1xuICAgICAgICBfaW5wdXRJbWFnZVdyYXBwZXIgPSBpbnB1dEltYWdlV3JhcHBlcjtcblxuICAgICAgICBpbml0QnVmZmVycygpO1xuICAgICAgICBpbml0Q2FudmFzKCk7XG4gICAgfSxcblxuICAgIGxvY2F0ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBwYXRjaGVzRm91bmQsXG4gICAgICAgICAgICB0b3BMYWJlbHMsXG4gICAgICAgICAgICBib3hlcztcblxuICAgICAgICBpZiAoX2NvbmZpZy5oYWxmU2FtcGxlKSB7XG4gICAgICAgICAgICBDVlV0aWxzLmhhbGZTYW1wbGUoX2lucHV0SW1hZ2VXcmFwcGVyLCBfY3VycmVudEltYWdlV3JhcHBlcik7XG4gICAgICAgIH1cblxuICAgICAgICBiaW5hcml6ZUltYWdlKCk7XG4gICAgICAgIHBhdGNoZXNGb3VuZCA9IGZpbmRQYXRjaGVzKCk7XG4gICAgICAgIC8vIHJldHVybiB1bmxlc3MgNSUgb3IgbW9yZSBwYXRjaGVzIGFyZSBmb3VuZFxuICAgICAgICBpZiAocGF0Y2hlc0ZvdW5kLmxlbmd0aCA8IF9udW1QYXRjaGVzLnggKiBfbnVtUGF0Y2hlcy55ICogMC4wNSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByYXN0ZXJyaXplIGFyZWEgYnkgY29tcGFyaW5nIGFuZ3VsYXIgc2ltaWxhcml0eTtcbiAgICAgICAgdmFyIG1heExhYmVsID0gcmFzdGVyaXplQW5ndWxhclNpbWlsYXJpdHkocGF0Y2hlc0ZvdW5kKTtcbiAgICAgICAgaWYgKG1heExhYmVsIDwgMSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZWFyY2ggZm9yIGFyZWEgd2l0aCB0aGUgbW9zdCBwYXRjaGVzIChiaWdnZXN0IGNvbm5lY3RlZCBhcmVhKVxuICAgICAgICB0b3BMYWJlbHMgPSBmaW5kQmlnZ2VzdENvbm5lY3RlZEFyZWFzKG1heExhYmVsKTtcbiAgICAgICAgaWYgKHRvcExhYmVscy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgYm94ZXMgPSBmaW5kQm94ZXModG9wTGFiZWxzLCBtYXhMYWJlbCk7XG4gICAgICAgIHJldHVybiBib3hlcztcbiAgICB9LFxuXG4gICAgY2hlY2tJbWFnZUNvbnN0cmFpbnRzOiBmdW5jdGlvbihpbnB1dFN0cmVhbSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwYXRjaFNpemUsXG4gICAgICAgICAgICB3aWR0aCA9IGlucHV0U3RyZWFtLmdldFdpZHRoKCksXG4gICAgICAgICAgICBoZWlnaHQgPSBpbnB1dFN0cmVhbS5nZXRIZWlnaHQoKSxcbiAgICAgICAgICAgIGhhbGZTYW1wbGUgPSBjb25maWcuaGFsZlNhbXBsZSA/IDAuNSA6IDEsXG4gICAgICAgICAgICBzaXplLFxuICAgICAgICAgICAgYXJlYTtcblxuICAgICAgICAvLyBjYWxjdWxhdGUgd2lkdGggYW5kIGhlaWdodCBiYXNlZCBvbiBhcmVhXG4gICAgICAgIGlmIChpbnB1dFN0cmVhbS5nZXRDb25maWcoKS5hcmVhKSB7XG4gICAgICAgICAgICBhcmVhID0gQ1ZVdGlscy5jb21wdXRlSW1hZ2VBcmVhKHdpZHRoLCBoZWlnaHQsIGlucHV0U3RyZWFtLmdldENvbmZpZygpLmFyZWEpO1xuICAgICAgICAgICAgaW5wdXRTdHJlYW0uc2V0VG9wUmlnaHQoe3g6IGFyZWEuc3gsIHk6IGFyZWEuc3l9KTtcbiAgICAgICAgICAgIGlucHV0U3RyZWFtLnNldENhbnZhc1NpemUoe3g6IHdpZHRoLCB5OiBoZWlnaHR9KTtcbiAgICAgICAgICAgIHdpZHRoID0gYXJlYS5zdztcbiAgICAgICAgICAgIGhlaWdodCA9IGFyZWEuc2g7XG4gICAgICAgIH1cblxuICAgICAgICBzaXplID0ge1xuICAgICAgICAgICAgeDogTWF0aC5mbG9vcih3aWR0aCAqIGhhbGZTYW1wbGUpLFxuICAgICAgICAgICAgeTogTWF0aC5mbG9vcihoZWlnaHQgKiBoYWxmU2FtcGxlKVxuICAgICAgICB9O1xuXG4gICAgICAgIHBhdGNoU2l6ZSA9IENWVXRpbHMuY2FsY3VsYXRlUGF0Y2hTaXplKGNvbmZpZy5wYXRjaFNpemUsIHNpemUpO1xuICAgICAgICBjb25zb2xlLmxvZyhcIlBhdGNoLVNpemU6IFwiICsgSlNPTi5zdHJpbmdpZnkocGF0Y2hTaXplKSk7XG5cbiAgICAgICAgaW5wdXRTdHJlYW0uc2V0V2lkdGgoTWF0aC5mbG9vcihNYXRoLmZsb29yKHNpemUueCAvIHBhdGNoU2l6ZS54KSAqICgxIC8gaGFsZlNhbXBsZSkgKiBwYXRjaFNpemUueCkpO1xuICAgICAgICBpbnB1dFN0cmVhbS5zZXRIZWlnaHQoTWF0aC5mbG9vcihNYXRoLmZsb29yKHNpemUueSAvIHBhdGNoU2l6ZS55KSAqICgxIC8gaGFsZlNhbXBsZSkgKiBwYXRjaFNpemUueSkpO1xuXG4gICAgICAgIGlmICgoaW5wdXRTdHJlYW0uZ2V0V2lkdGgoKSAlIHBhdGNoU2l6ZS54KSA9PT0gMCAmJiAoaW5wdXRTdHJlYW0uZ2V0SGVpZ2h0KCkgJSBwYXRjaFNpemUueSkgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW1hZ2UgZGltZW5zaW9ucyBkbyBub3QgY29tcGx5IHdpdGggdGhlIGN1cnJlbnQgc2V0dGluZ3M6IFdpZHRoIChcIiArXG4gICAgICAgICAgICB3aWR0aCArIFwiIClhbmQgaGVpZ2h0IChcIiArIGhlaWdodCArXG4gICAgICAgICAgICBcIikgbXVzdCBhIG11bHRpcGxlIG9mIFwiICsgcGF0Y2hTaXplLngpO1xuICAgIH1cbn07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9iYXJjb2RlX2xvY2F0b3IuanNcbiAqKi8iLCJpbXBvcnQgVHJhY2VyIGZyb20gJy4vdHJhY2VyJztcblxuLyoqXG4gKiBodHRwOi8vd3d3LmNvZGVwcm9qZWN0LmNvbS9UaXBzLzQwNzE3Mi9Db25uZWN0ZWQtQ29tcG9uZW50LUxhYmVsaW5nLWFuZC1WZWN0b3JpemF0aW9uXG4gKi9cbnZhciBSYXN0ZXJpemVyID0ge1xuICAgIGNyZWF0ZUNvbnRvdXIyRDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkaXI6IG51bGwsXG4gICAgICAgICAgICBpbmRleDogbnVsbCxcbiAgICAgICAgICAgIGZpcnN0VmVydGV4OiBudWxsLFxuICAgICAgICAgICAgaW5zaWRlQ29udG91cnM6IG51bGwsXG4gICAgICAgICAgICBuZXh0cGVlcjogbnVsbCxcbiAgICAgICAgICAgIHByZXZwZWVyOiBudWxsXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBDT05UT1VSX0RJUjoge1xuICAgICAgICBDV19ESVI6IDAsXG4gICAgICAgIENDV19ESVI6IDEsXG4gICAgICAgIFVOS05PV05fRElSOiAyXG4gICAgfSxcbiAgICBESVI6IHtcbiAgICAgICAgT1VUU0lERV9FREdFOiAtMzI3NjcsXG4gICAgICAgIElOU0lERV9FREdFOiAtMzI3NjZcbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBsYWJlbFdyYXBwZXIpIHtcbiAgICAgICAgdmFyIGltYWdlRGF0YSA9IGltYWdlV3JhcHBlci5kYXRhLFxuICAgICAgICAgICAgbGFiZWxEYXRhID0gbGFiZWxXcmFwcGVyLmRhdGEsXG4gICAgICAgICAgICB3aWR0aCA9IGltYWdlV3JhcHBlci5zaXplLngsXG4gICAgICAgICAgICBoZWlnaHQgPSBpbWFnZVdyYXBwZXIuc2l6ZS55LFxuICAgICAgICAgICAgdHJhY2VyID0gVHJhY2VyLmNyZWF0ZShpbWFnZVdyYXBwZXIsIGxhYmVsV3JhcHBlcik7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJhc3Rlcml6ZTogZnVuY3Rpb24oZGVwdGhsYWJlbCkge1xuICAgICAgICAgICAgICAgIHZhciBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgYmMsXG4gICAgICAgICAgICAgICAgICAgIGxjLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBjeCxcbiAgICAgICAgICAgICAgICAgICAgY3ksXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yTWFwID0gW10sXG4gICAgICAgICAgICAgICAgICAgIHZlcnRleCxcbiAgICAgICAgICAgICAgICAgICAgcCxcbiAgICAgICAgICAgICAgICAgICAgY2MsXG4gICAgICAgICAgICAgICAgICAgIHNjLFxuICAgICAgICAgICAgICAgICAgICBwb3MsXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZENvdW50ID0gMCxcbiAgICAgICAgICAgICAgICAgICAgaTtcblxuICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgNDAwOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29sb3JNYXBbaV0gPSAwO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbG9yTWFwWzBdID0gaW1hZ2VEYXRhWzBdO1xuICAgICAgICAgICAgICAgIGNjID0gbnVsbDtcbiAgICAgICAgICAgICAgICBmb3IgKCBjeSA9IDE7IGN5IDwgaGVpZ2h0IC0gMTsgY3krKykge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbGluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgYmMgPSBjb2xvck1hcFswXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICggY3ggPSAxOyBjeCA8IHdpZHRoIC0gMTsgY3grKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gY3kgKiB3aWR0aCArIGN4O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsRGF0YVtwb3NdID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBpbWFnZURhdGFbcG9zXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sb3IgIT09IGJjKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYWJlbGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYyA9IGNvbm5lY3RlZENvdW50ICsgMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTWFwW2xjXSA9IGNvbG9yO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmMgPSBjb2xvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRleCA9IHRyYWNlci5jb250b3VyVHJhY2luZyhjeSwgY3gsIGxjLCBjb2xvciwgUmFzdGVyaXplci5ESVIuT1VUU0lERV9FREdFKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ZXJ0ZXggIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0ZWRDb3VudCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsaW5kZXggPSBsYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwID0gUmFzdGVyaXplci5jcmVhdGVDb250b3VyMkQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmRpciA9IFJhc3Rlcml6ZXIuQ09OVE9VUl9ESVIuQ1dfRElSO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuaW5kZXggPSBsYWJlbGluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuZmlyc3RWZXJ0ZXggPSB2ZXJ0ZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5uZXh0cGVlciA9IGNjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuaW5zaWRlQ29udG91cnMgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYy5wcmV2cGVlciA9IHA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNjID0gcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRleCA9IHRyYWNlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb250b3VyVHJhY2luZyhjeSwgY3gsIFJhc3Rlcml6ZXIuRElSLklOU0lERV9FREdFLCBjb2xvciwgbGFiZWxpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmVydGV4ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcCA9IFJhc3Rlcml6ZXIuY3JlYXRlQ29udG91cjJEKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5maXJzdFZlcnRleCA9IHZlcnRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmluc2lkZUNvbnRvdXJzID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVwdGhsYWJlbCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmRpciA9IFJhc3Rlcml6ZXIuQ09OVE9VUl9ESVIuQ0NXX0RJUjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmRpciA9IFJhc3Rlcml6ZXIuQ09OVE9VUl9ESVIuQ1dfRElSO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmluZGV4ID0gZGVwdGhsYWJlbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYyA9IGNjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoc2MgIT09IG51bGwpICYmIHNjLmluZGV4ICE9PSBsYWJlbGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjID0gc2MubmV4dHBlZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzYyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLm5leHRwZWVyID0gc2MuaW5zaWRlQ29udG91cnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzYy5pbnNpZGVDb250b3VycyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2MuaW5zaWRlQ29udG91cnMucHJldnBlZXIgPSBwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjLmluc2lkZUNvbnRvdXJzID0gcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbERhdGFbcG9zXSA9IGxhYmVsaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsYWJlbERhdGFbcG9zXSA9PT0gUmFzdGVyaXplci5ESVIuT1VUU0lERV9FREdFXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGxhYmVsRGF0YVtwb3NdID09PSBSYXN0ZXJpemVyLkRJUi5JTlNJREVfRURHRSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsaW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYWJlbERhdGFbcG9zXSA9PT0gUmFzdGVyaXplci5ESVIuSU5TSURFX0VER0UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmMgPSBpbWFnZURhdGFbcG9zXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYyA9IGNvbG9yTWFwWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxpbmRleCA9IGxhYmVsRGF0YVtwb3NdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJjID0gY29sb3JNYXBbbGFiZWxpbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2MgPSBjYztcbiAgICAgICAgICAgICAgICB3aGlsZSAoc2MgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2MuaW5kZXggPSBkZXB0aGxhYmVsO1xuICAgICAgICAgICAgICAgICAgICBzYyA9IHNjLm5leHRwZWVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjYzogY2MsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50OiBjb25uZWN0ZWRDb3VudFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGVidWc6IHtcbiAgICAgICAgICAgICAgICBkcmF3Q29udG91cjogZnVuY3Rpb24oY2FudmFzLCBmaXJzdENvbnRvdXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICBwcSA9IGZpcnN0Q29udG91cixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlxLFxuICAgICAgICAgICAgICAgICAgICAgICAgcSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHA7XG5cbiAgICAgICAgICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gXCJyZWRcIjtcbiAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IFwicmVkXCI7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSAxO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXEgPSBwcS5pbnNpZGVDb250b3VycztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlxID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChwcSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlxICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcSA9IGlxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlxID0gaXEubmV4dHBlZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHEgPSBwcTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcSA9IHBxLm5leHRwZWVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcSA9IHBxLmluc2lkZUNvbnRvdXJzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlxID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocS5kaXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUmFzdGVyaXplci5DT05UT1VSX0RJUi5DV19ESVI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gXCJyZWRcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUmFzdGVyaXplci5DT05UT1VSX0RJUi5DQ1dfRElSOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiYmx1ZVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBSYXN0ZXJpemVyLkNPTlRPVVJfRElSLlVOS05PV05fRElSOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiZ3JlZW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcCA9IHEuZmlyc3RWZXJ0ZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHgubW92ZVRvKHAueCwgcC55KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwID0gcC5uZXh0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5saW5lVG8ocC54LCBwLnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAocCAhPT0gcS5maXJzdFZlcnRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgUmFzdGVyaXplcjtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL3Jhc3Rlcml6ZXIuanNcbiAqKi8iLCIvKipcbiAqIGh0dHA6Ly93d3cuY29kZXByb2plY3QuY29tL1RpcHMvNDA3MTcyL0Nvbm5lY3RlZC1Db21wb25lbnQtTGFiZWxpbmctYW5kLVZlY3Rvcml6YXRpb25cbiAqL1xudmFyIFRyYWNlciA9IHtcbiAgICBzZWFyY2hEaXJlY3Rpb25zOiBbWzAsIDFdLCBbMSwgMV0sIFsxLCAwXSwgWzEsIC0xXSwgWzAsIC0xXSwgWy0xLCAtMV0sIFstMSwgMF0sIFstMSwgMV1dLFxuICAgIGNyZWF0ZTogZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBsYWJlbFdyYXBwZXIpIHtcbiAgICAgICAgdmFyIGltYWdlRGF0YSA9IGltYWdlV3JhcHBlci5kYXRhLFxuICAgICAgICAgICAgbGFiZWxEYXRhID0gbGFiZWxXcmFwcGVyLmRhdGEsXG4gICAgICAgICAgICBzZWFyY2hEaXJlY3Rpb25zID0gdGhpcy5zZWFyY2hEaXJlY3Rpb25zLFxuICAgICAgICAgICAgd2lkdGggPSBpbWFnZVdyYXBwZXIuc2l6ZS54LFxuICAgICAgICAgICAgcG9zO1xuXG4gICAgICAgIGZ1bmN0aW9uIHRyYWNlKGN1cnJlbnQsIGNvbG9yLCBsYWJlbCwgZWRnZWxhYmVsKSB7XG4gICAgICAgICAgICB2YXIgaSxcbiAgICAgICAgICAgICAgICB5LFxuICAgICAgICAgICAgICAgIHg7XG5cbiAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgeSA9IGN1cnJlbnQuY3kgKyBzZWFyY2hEaXJlY3Rpb25zW2N1cnJlbnQuZGlyXVswXTtcbiAgICAgICAgICAgICAgICB4ID0gY3VycmVudC5jeCArIHNlYXJjaERpcmVjdGlvbnNbY3VycmVudC5kaXJdWzFdO1xuICAgICAgICAgICAgICAgIHBvcyA9IHkgKiB3aWR0aCArIHg7XG4gICAgICAgICAgICAgICAgaWYgKChpbWFnZURhdGFbcG9zXSA9PT0gY29sb3IpICYmICgobGFiZWxEYXRhW3Bvc10gPT09IDApIHx8IChsYWJlbERhdGFbcG9zXSA9PT0gbGFiZWwpKSkge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbERhdGFbcG9zXSA9IGxhYmVsO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmN5ID0geTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudC5jeCA9IHg7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsYWJlbERhdGFbcG9zXSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxEYXRhW3Bvc10gPSBlZGdlbGFiZWw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY3VycmVudC5kaXIgPSAoY3VycmVudC5kaXIgKyAxKSAlIDg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gdmVydGV4MkQoeCwgeSwgZGlyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGRpcjogZGlyLFxuICAgICAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgICAgICBuZXh0OiBudWxsLFxuICAgICAgICAgICAgICAgIHByZXY6IG51bGxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBjb250b3VyVHJhY2luZyhzeSwgc3gsIGxhYmVsLCBjb2xvciwgZWRnZWxhYmVsKSB7XG4gICAgICAgICAgICB2YXIgRnYgPSBudWxsLFxuICAgICAgICAgICAgICAgIEN2LFxuICAgICAgICAgICAgICAgIFAsXG4gICAgICAgICAgICAgICAgbGRpcixcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICBjeDogc3gsXG4gICAgICAgICAgICAgICAgICAgIGN5OiBzeSxcbiAgICAgICAgICAgICAgICAgICAgZGlyOiAwXG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRyYWNlKGN1cnJlbnQsIGNvbG9yLCBsYWJlbCwgZWRnZWxhYmVsKSkge1xuICAgICAgICAgICAgICAgIEZ2ID0gdmVydGV4MkQoc3gsIHN5LCBjdXJyZW50LmRpcik7XG4gICAgICAgICAgICAgICAgQ3YgPSBGdjtcbiAgICAgICAgICAgICAgICBsZGlyID0gY3VycmVudC5kaXI7XG4gICAgICAgICAgICAgICAgUCA9IHZlcnRleDJEKGN1cnJlbnQuY3gsIGN1cnJlbnQuY3ksIDApO1xuICAgICAgICAgICAgICAgIFAucHJldiA9IEN2O1xuICAgICAgICAgICAgICAgIEN2Lm5leHQgPSBQO1xuICAgICAgICAgICAgICAgIFAubmV4dCA9IG51bGw7XG4gICAgICAgICAgICAgICAgQ3YgPSBQO1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudC5kaXIgPSAoY3VycmVudC5kaXIgKyA2KSAlIDg7XG4gICAgICAgICAgICAgICAgICAgIHRyYWNlKGN1cnJlbnQsIGNvbG9yLCBsYWJlbCwgZWRnZWxhYmVsKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxkaXIgIT09IGN1cnJlbnQuZGlyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBDdi5kaXIgPSBjdXJyZW50LmRpcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIFAgPSB2ZXJ0ZXgyRChjdXJyZW50LmN4LCBjdXJyZW50LmN5LCAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFAucHJldiA9IEN2O1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3YubmV4dCA9IFA7XG4gICAgICAgICAgICAgICAgICAgICAgICBQLm5leHQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3YgPSBQO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3YuZGlyID0gbGRpcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIEN2LnggPSBjdXJyZW50LmN4O1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3YueSA9IGN1cnJlbnQuY3k7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGRpciA9IGN1cnJlbnQuZGlyO1xuICAgICAgICAgICAgICAgIH0gd2hpbGUgKGN1cnJlbnQuY3ggIT09IHN4IHx8IGN1cnJlbnQuY3kgIT09IHN5KTtcbiAgICAgICAgICAgICAgICBGdi5wcmV2ID0gQ3YucHJldjtcbiAgICAgICAgICAgICAgICBDdi5wcmV2Lm5leHQgPSBGdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBGdjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0cmFjZTogZnVuY3Rpb24oY3VycmVudCwgY29sb3IsIGxhYmVsLCBlZGdlbGFiZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJhY2UoY3VycmVudCwgY29sb3IsIGxhYmVsLCBlZGdlbGFiZWwpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbnRvdXJUcmFjaW5nOiBmdW5jdGlvbihzeSwgc3gsIGxhYmVsLCBjb2xvciwgZWRnZWxhYmVsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRvdXJUcmFjaW5nKHN5LCBzeCwgbGFiZWwsIGNvbG9yLCBlZGdlbGFiZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IChUcmFjZXIpO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvdHJhY2VyLmpzXG4gKiovIiwiLyogQHByZXNlcnZlIEFTTSBCRUdJTiAqL1xuLyogZXNsaW50LWRpc2FibGUgZXFlcWVxKi9cbmZ1bmN0aW9uIFNrZWxldG9uaXplcihzdGRsaWIsIGZvcmVpZ24sIGJ1ZmZlcikge1xuICAgIFwidXNlIGFzbVwiO1xuXG4gICAgdmFyIGltYWdlcyA9IG5ldyBzdGRsaWIuVWludDhBcnJheShidWZmZXIpLFxuICAgICAgICBzaXplID0gZm9yZWlnbi5zaXplIHwgMCxcbiAgICAgICAgaW11bCA9IHN0ZGxpYi5NYXRoLmltdWw7XG5cbiAgICBmdW5jdGlvbiBlcm9kZShpbkltYWdlUHRyLCBvdXRJbWFnZVB0cikge1xuICAgICAgICBpbkltYWdlUHRyID0gaW5JbWFnZVB0ciB8IDA7XG4gICAgICAgIG91dEltYWdlUHRyID0gb3V0SW1hZ2VQdHIgfCAwO1xuXG4gICAgICAgIHZhciB2ID0gMCxcbiAgICAgICAgICAgIHUgPSAwLFxuICAgICAgICAgICAgc3VtID0gMCxcbiAgICAgICAgICAgIHlTdGFydDEgPSAwLFxuICAgICAgICAgICAgeVN0YXJ0MiA9IDAsXG4gICAgICAgICAgICB4U3RhcnQxID0gMCxcbiAgICAgICAgICAgIHhTdGFydDIgPSAwLFxuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcblxuICAgICAgICBmb3IgKCB2ID0gMTsgKHYgfCAwKSA8ICgoc2l6ZSAtIDEpIHwgMCk7IHYgPSAodiArIDEpIHwgMCkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gKG9mZnNldCArIHNpemUpIHwgMDtcbiAgICAgICAgICAgIGZvciAoIHUgPSAxOyAodSB8IDApIDwgKChzaXplIC0gMSkgfCAwKTsgdSA9ICh1ICsgMSkgfCAwKSB7XG4gICAgICAgICAgICAgICAgeVN0YXJ0MSA9IChvZmZzZXQgLSBzaXplKSB8IDA7XG4gICAgICAgICAgICAgICAgeVN0YXJ0MiA9IChvZmZzZXQgKyBzaXplKSB8IDA7XG4gICAgICAgICAgICAgICAgeFN0YXJ0MSA9ICh1IC0gMSkgfCAwO1xuICAgICAgICAgICAgICAgIHhTdGFydDIgPSAodSArIDEpIHwgMDtcbiAgICAgICAgICAgICAgICBzdW0gPSAoKGltYWdlc1soaW5JbWFnZVB0ciArIHlTdGFydDEgKyB4U3RhcnQxKSB8IDBdIHwgMClcbiAgICAgICAgICAgICAgICAgICAgKyAoaW1hZ2VzWyhpbkltYWdlUHRyICsgeVN0YXJ0MSArIHhTdGFydDIpIHwgMF0gfCAwKVxuICAgICAgICAgICAgICAgICAgICArIChpbWFnZXNbKGluSW1hZ2VQdHIgKyBvZmZzZXQgKyB1KSB8IDBdIHwgMClcbiAgICAgICAgICAgICAgICAgICAgKyAoaW1hZ2VzWyhpbkltYWdlUHRyICsgeVN0YXJ0MiArIHhTdGFydDEpIHwgMF0gfCAwKVxuICAgICAgICAgICAgICAgICAgICArIChpbWFnZXNbKGluSW1hZ2VQdHIgKyB5U3RhcnQyICsgeFN0YXJ0MikgfCAwXSB8IDApKSB8IDA7XG4gICAgICAgICAgICAgICAgaWYgKChzdW0gfCAwKSA9PSAoNSB8IDApKSB7XG4gICAgICAgICAgICAgICAgICAgIGltYWdlc1sob3V0SW1hZ2VQdHIgKyBvZmZzZXQgKyB1KSB8IDBdID0gMTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpbWFnZXNbKG91dEltYWdlUHRyICsgb2Zmc2V0ICsgdSkgfCAwXSA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdWJ0cmFjdChhSW1hZ2VQdHIsIGJJbWFnZVB0ciwgb3V0SW1hZ2VQdHIpIHtcbiAgICAgICAgYUltYWdlUHRyID0gYUltYWdlUHRyIHwgMDtcbiAgICAgICAgYkltYWdlUHRyID0gYkltYWdlUHRyIHwgMDtcbiAgICAgICAgb3V0SW1hZ2VQdHIgPSBvdXRJbWFnZVB0ciB8IDA7XG5cbiAgICAgICAgdmFyIGxlbmd0aCA9IDA7XG5cbiAgICAgICAgbGVuZ3RoID0gaW11bChzaXplLCBzaXplKSB8IDA7XG5cbiAgICAgICAgd2hpbGUgKChsZW5ndGggfCAwKSA+IDApIHtcbiAgICAgICAgICAgIGxlbmd0aCA9IChsZW5ndGggLSAxKSB8IDA7XG4gICAgICAgICAgICBpbWFnZXNbKG91dEltYWdlUHRyICsgbGVuZ3RoKSB8IDBdID1cbiAgICAgICAgICAgICAgICAoKGltYWdlc1soYUltYWdlUHRyICsgbGVuZ3RoKSB8IDBdIHwgMCkgLSAoaW1hZ2VzWyhiSW1hZ2VQdHIgKyBsZW5ndGgpIHwgMF0gfCAwKSkgfCAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYml0d2lzZU9yKGFJbWFnZVB0ciwgYkltYWdlUHRyLCBvdXRJbWFnZVB0cikge1xuICAgICAgICBhSW1hZ2VQdHIgPSBhSW1hZ2VQdHIgfCAwO1xuICAgICAgICBiSW1hZ2VQdHIgPSBiSW1hZ2VQdHIgfCAwO1xuICAgICAgICBvdXRJbWFnZVB0ciA9IG91dEltYWdlUHRyIHwgMDtcblxuICAgICAgICB2YXIgbGVuZ3RoID0gMDtcblxuICAgICAgICBsZW5ndGggPSBpbXVsKHNpemUsIHNpemUpIHwgMDtcblxuICAgICAgICB3aGlsZSAoKGxlbmd0aCB8IDApID4gMCkge1xuICAgICAgICAgICAgbGVuZ3RoID0gKGxlbmd0aCAtIDEpIHwgMDtcbiAgICAgICAgICAgIGltYWdlc1sob3V0SW1hZ2VQdHIgKyBsZW5ndGgpIHwgMF0gPVxuICAgICAgICAgICAgICAgICgoaW1hZ2VzWyhhSW1hZ2VQdHIgKyBsZW5ndGgpIHwgMF0gfCAwKSB8IChpbWFnZXNbKGJJbWFnZVB0ciArIGxlbmd0aCkgfCAwXSB8IDApKSB8IDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb3VudE5vblplcm8oaW1hZ2VQdHIpIHtcbiAgICAgICAgaW1hZ2VQdHIgPSBpbWFnZVB0ciB8IDA7XG5cbiAgICAgICAgdmFyIHN1bSA9IDAsXG4gICAgICAgICAgICBsZW5ndGggPSAwO1xuXG4gICAgICAgIGxlbmd0aCA9IGltdWwoc2l6ZSwgc2l6ZSkgfCAwO1xuXG4gICAgICAgIHdoaWxlICgobGVuZ3RoIHwgMCkgPiAwKSB7XG4gICAgICAgICAgICBsZW5ndGggPSAobGVuZ3RoIC0gMSkgfCAwO1xuICAgICAgICAgICAgc3VtID0gKChzdW0gfCAwKSArIChpbWFnZXNbKGltYWdlUHRyICsgbGVuZ3RoKSB8IDBdIHwgMCkpIHwgMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoc3VtIHwgMCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5pdChpbWFnZVB0ciwgdmFsdWUpIHtcbiAgICAgICAgaW1hZ2VQdHIgPSBpbWFnZVB0ciB8IDA7XG4gICAgICAgIHZhbHVlID0gdmFsdWUgfCAwO1xuXG4gICAgICAgIHZhciBsZW5ndGggPSAwO1xuXG4gICAgICAgIGxlbmd0aCA9IGltdWwoc2l6ZSwgc2l6ZSkgfCAwO1xuXG4gICAgICAgIHdoaWxlICgobGVuZ3RoIHwgMCkgPiAwKSB7XG4gICAgICAgICAgICBsZW5ndGggPSAobGVuZ3RoIC0gMSkgfCAwO1xuICAgICAgICAgICAgaW1hZ2VzWyhpbWFnZVB0ciArIGxlbmd0aCkgfCAwXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlsYXRlKGluSW1hZ2VQdHIsIG91dEltYWdlUHRyKSB7XG4gICAgICAgIGluSW1hZ2VQdHIgPSBpbkltYWdlUHRyIHwgMDtcbiAgICAgICAgb3V0SW1hZ2VQdHIgPSBvdXRJbWFnZVB0ciB8IDA7XG5cbiAgICAgICAgdmFyIHYgPSAwLFxuICAgICAgICAgICAgdSA9IDAsXG4gICAgICAgICAgICBzdW0gPSAwLFxuICAgICAgICAgICAgeVN0YXJ0MSA9IDAsXG4gICAgICAgICAgICB5U3RhcnQyID0gMCxcbiAgICAgICAgICAgIHhTdGFydDEgPSAwLFxuICAgICAgICAgICAgeFN0YXJ0MiA9IDAsXG4gICAgICAgICAgICBvZmZzZXQgPSAwO1xuXG4gICAgICAgIGZvciAoIHYgPSAxOyAodiB8IDApIDwgKChzaXplIC0gMSkgfCAwKTsgdiA9ICh2ICsgMSkgfCAwKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSAob2Zmc2V0ICsgc2l6ZSkgfCAwO1xuICAgICAgICAgICAgZm9yICggdSA9IDE7ICh1IHwgMCkgPCAoKHNpemUgLSAxKSB8IDApOyB1ID0gKHUgKyAxKSB8IDApIHtcbiAgICAgICAgICAgICAgICB5U3RhcnQxID0gKG9mZnNldCAtIHNpemUpIHwgMDtcbiAgICAgICAgICAgICAgICB5U3RhcnQyID0gKG9mZnNldCArIHNpemUpIHwgMDtcbiAgICAgICAgICAgICAgICB4U3RhcnQxID0gKHUgLSAxKSB8IDA7XG4gICAgICAgICAgICAgICAgeFN0YXJ0MiA9ICh1ICsgMSkgfCAwO1xuICAgICAgICAgICAgICAgIHN1bSA9ICgoaW1hZ2VzWyhpbkltYWdlUHRyICsgeVN0YXJ0MSArIHhTdGFydDEpIHwgMF0gfCAwKVxuICAgICAgICAgICAgICAgICAgICArIChpbWFnZXNbKGluSW1hZ2VQdHIgKyB5U3RhcnQxICsgeFN0YXJ0MikgfCAwXSB8IDApXG4gICAgICAgICAgICAgICAgICAgICsgKGltYWdlc1soaW5JbWFnZVB0ciArIG9mZnNldCArIHUpIHwgMF0gfCAwKVxuICAgICAgICAgICAgICAgICAgICArIChpbWFnZXNbKGluSW1hZ2VQdHIgKyB5U3RhcnQyICsgeFN0YXJ0MSkgfCAwXSB8IDApXG4gICAgICAgICAgICAgICAgICAgICsgKGltYWdlc1soaW5JbWFnZVB0ciArIHlTdGFydDIgKyB4U3RhcnQyKSB8IDBdIHwgMCkpIHwgMDtcbiAgICAgICAgICAgICAgICBpZiAoKHN1bSB8IDApID4gKDAgfCAwKSkge1xuICAgICAgICAgICAgICAgICAgICBpbWFnZXNbKG91dEltYWdlUHRyICsgb2Zmc2V0ICsgdSkgfCAwXSA9IDE7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2VzWyhvdXRJbWFnZVB0ciArIG9mZnNldCArIHUpIHwgMF0gPSAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWVtY3B5KHNyY0ltYWdlUHRyLCBkc3RJbWFnZVB0cikge1xuICAgICAgICBzcmNJbWFnZVB0ciA9IHNyY0ltYWdlUHRyIHwgMDtcbiAgICAgICAgZHN0SW1hZ2VQdHIgPSBkc3RJbWFnZVB0ciB8IDA7XG5cbiAgICAgICAgdmFyIGxlbmd0aCA9IDA7XG5cbiAgICAgICAgbGVuZ3RoID0gaW11bChzaXplLCBzaXplKSB8IDA7XG5cbiAgICAgICAgd2hpbGUgKChsZW5ndGggfCAwKSA+IDApIHtcbiAgICAgICAgICAgIGxlbmd0aCA9IChsZW5ndGggLSAxKSB8IDA7XG4gICAgICAgICAgICBpbWFnZXNbKGRzdEltYWdlUHRyICsgbGVuZ3RoKSB8IDBdID0gKGltYWdlc1soc3JjSW1hZ2VQdHIgKyBsZW5ndGgpIHwgMF0gfCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHplcm9Cb3JkZXIoaW1hZ2VQdHIpIHtcbiAgICAgICAgaW1hZ2VQdHIgPSBpbWFnZVB0ciB8IDA7XG5cbiAgICAgICAgdmFyIHggPSAwLFxuICAgICAgICAgICAgeSA9IDA7XG5cbiAgICAgICAgZm9yICggeCA9IDA7ICh4IHwgMCkgPCAoKHNpemUgLSAxKSB8IDApOyB4ID0gKHggKyAxKSB8IDApIHtcbiAgICAgICAgICAgIGltYWdlc1soaW1hZ2VQdHIgKyB4KSB8IDBdID0gMDtcbiAgICAgICAgICAgIGltYWdlc1soaW1hZ2VQdHIgKyB5KSB8IDBdID0gMDtcbiAgICAgICAgICAgIHkgPSAoKHkgKyBzaXplKSAtIDEpIHwgMDtcbiAgICAgICAgICAgIGltYWdlc1soaW1hZ2VQdHIgKyB5KSB8IDBdID0gMDtcbiAgICAgICAgICAgIHkgPSAoeSArIDEpIHwgMDtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKCB4ID0gMDsgKHggfCAwKSA8IChzaXplIHwgMCk7IHggPSAoeCArIDEpIHwgMCkge1xuICAgICAgICAgICAgaW1hZ2VzWyhpbWFnZVB0ciArIHkpIHwgMF0gPSAwO1xuICAgICAgICAgICAgeSA9ICh5ICsgMSkgfCAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2tlbGV0b25pemUoKSB7XG4gICAgICAgIHZhciBzdWJJbWFnZVB0ciA9IDAsXG4gICAgICAgICAgICBlcm9kZWRJbWFnZVB0ciA9IDAsXG4gICAgICAgICAgICB0ZW1wSW1hZ2VQdHIgPSAwLFxuICAgICAgICAgICAgc2tlbEltYWdlUHRyID0gMCxcbiAgICAgICAgICAgIHN1bSA9IDAsXG4gICAgICAgICAgICBkb25lID0gMDtcblxuICAgICAgICBlcm9kZWRJbWFnZVB0ciA9IGltdWwoc2l6ZSwgc2l6ZSkgfCAwO1xuICAgICAgICB0ZW1wSW1hZ2VQdHIgPSAoZXJvZGVkSW1hZ2VQdHIgKyBlcm9kZWRJbWFnZVB0cikgfCAwO1xuICAgICAgICBza2VsSW1hZ2VQdHIgPSAodGVtcEltYWdlUHRyICsgZXJvZGVkSW1hZ2VQdHIpIHwgMDtcblxuICAgICAgICAvLyBpbml0IHNrZWwtaW1hZ2VcbiAgICAgICAgaW5pdChza2VsSW1hZ2VQdHIsIDApO1xuICAgICAgICB6ZXJvQm9yZGVyKHN1YkltYWdlUHRyKTtcblxuICAgICAgICBkbyB7XG4gICAgICAgICAgICBlcm9kZShzdWJJbWFnZVB0ciwgZXJvZGVkSW1hZ2VQdHIpO1xuICAgICAgICAgICAgZGlsYXRlKGVyb2RlZEltYWdlUHRyLCB0ZW1wSW1hZ2VQdHIpO1xuICAgICAgICAgICAgc3VidHJhY3Qoc3ViSW1hZ2VQdHIsIHRlbXBJbWFnZVB0ciwgdGVtcEltYWdlUHRyKTtcbiAgICAgICAgICAgIGJpdHdpc2VPcihza2VsSW1hZ2VQdHIsIHRlbXBJbWFnZVB0ciwgc2tlbEltYWdlUHRyKTtcbiAgICAgICAgICAgIG1lbWNweShlcm9kZWRJbWFnZVB0ciwgc3ViSW1hZ2VQdHIpO1xuICAgICAgICAgICAgc3VtID0gY291bnROb25aZXJvKHN1YkltYWdlUHRyKSB8IDA7XG4gICAgICAgICAgICBkb25lID0gKChzdW0gfCAwKSA9PSAwIHwgMCk7XG4gICAgICAgIH0gd2hpbGUgKCFkb25lKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBza2VsZXRvbml6ZTogc2tlbGV0b25pemVcbiAgICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBTa2VsZXRvbml6ZXI7XG4vKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSovXG4vKiBAcHJlc2VydmUgQVNNIEVORCAqL1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvc2tlbGV0b25pemVyLmpzXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQge1xuICAgIGRyYXdSZWN0OiBmdW5jdGlvbihwb3MsIHNpemUsIGN0eCwgc3R5bGUpe1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBzdHlsZS5jb2xvcjtcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IHN0eWxlLmNvbG9yO1xuICAgICAgICBjdHgubGluZVdpZHRoID0gMTtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHguc3Ryb2tlUmVjdChwb3MueCwgcG9zLnksIHNpemUueCwgc2l6ZS55KTtcbiAgICB9LFxuICAgIGRyYXdQYXRoOiBmdW5jdGlvbihwYXRoLCBkZWYsIGN0eCwgc3R5bGUpIHtcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3R5bGUuY29sb3I7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBzdHlsZS5jb2xvcjtcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHN0eWxlLmxpbmVXaWR0aDtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHgubW92ZVRvKHBhdGhbMF1bZGVmLnhdLCBwYXRoWzBdW2RlZi55XSk7XG4gICAgICAgIGZvciAodmFyIGogPSAxOyBqIDwgcGF0aC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgY3R4LmxpbmVUbyhwYXRoW2pdW2RlZi54XSwgcGF0aFtqXVtkZWYueV0pO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgIH0sXG4gICAgZHJhd0ltYWdlOiBmdW5jdGlvbihpbWFnZURhdGEsIHNpemUsIGN0eCkge1xuICAgICAgICB2YXIgY2FudmFzRGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgc2l6ZS54LCBzaXplLnkpLFxuICAgICAgICAgICAgZGF0YSA9IGNhbnZhc0RhdGEuZGF0YSxcbiAgICAgICAgICAgIGltYWdlRGF0YVBvcyA9IGltYWdlRGF0YS5sZW5ndGgsXG4gICAgICAgICAgICBjYW52YXNEYXRhUG9zID0gZGF0YS5sZW5ndGgsXG4gICAgICAgICAgICB2YWx1ZTtcblxuICAgICAgICBpZiAoY2FudmFzRGF0YVBvcyAvIGltYWdlRGF0YVBvcyAhPT0gNCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChpbWFnZURhdGFQb3MtLSl7XG4gICAgICAgICAgICB2YWx1ZSA9IGltYWdlRGF0YVtpbWFnZURhdGFQb3NdO1xuICAgICAgICAgICAgZGF0YVstLWNhbnZhc0RhdGFQb3NdID0gMjU1O1xuICAgICAgICAgICAgZGF0YVstLWNhbnZhc0RhdGFQb3NdID0gdmFsdWU7XG4gICAgICAgICAgICBkYXRhWy0tY2FudmFzRGF0YVBvc10gPSB2YWx1ZTtcbiAgICAgICAgICAgIGRhdGFbLS1jYW52YXNEYXRhUG9zXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2FudmFzRGF0YSwgMCwgMCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9pbWFnZV9kZWJ1Zy5qc1xuICoqLyIsImltcG9ydCBCcmVzZW5oYW0gZnJvbSAnLi9icmVzZW5oYW0nO1xuaW1wb3J0IEltYWdlRGVidWcgZnJvbSAnLi9pbWFnZV9kZWJ1Zyc7XG5pbXBvcnQgQ29kZTEyOFJlYWRlciBmcm9tICcuL2NvZGVfMTI4X3JlYWRlcic7XG5pbXBvcnQgRUFOUmVhZGVyIGZyb20gJy4vZWFuX3JlYWRlcic7XG5pbXBvcnQgQ29kZTM5UmVhZGVyIGZyb20gJy4vY29kZV8zOV9yZWFkZXInO1xuaW1wb3J0IENvZGUzOVZJTlJlYWRlciBmcm9tICcuL2NvZGVfMzlfdmluX3JlYWRlcic7XG5pbXBvcnQgQ29kYWJhclJlYWRlciBmcm9tICcuL2NvZGFiYXJfcmVhZGVyJztcbmltcG9ydCBVUENSZWFkZXIgZnJvbSAnLi91cGNfcmVhZGVyJztcbmltcG9ydCBFQU44UmVhZGVyIGZyb20gJy4vZWFuXzhfcmVhZGVyJztcbmltcG9ydCBVUENFUmVhZGVyIGZyb20gJy4vdXBjX2VfcmVhZGVyJztcbmltcG9ydCBJMm9mNVJlYWRlciBmcm9tICcuL2kyb2Y1X3JlYWRlcic7XG5cbmNvbnN0IFJFQURFUlMgPSB7XG4gICAgY29kZV8xMjhfcmVhZGVyOiBDb2RlMTI4UmVhZGVyLFxuICAgIGVhbl9yZWFkZXI6IEVBTlJlYWRlcixcbiAgICBlYW5fOF9yZWFkZXI6IEVBTjhSZWFkZXIsXG4gICAgY29kZV8zOV9yZWFkZXI6IENvZGUzOVJlYWRlcixcbiAgICBjb2RlXzM5X3Zpbl9yZWFkZXI6IENvZGUzOVZJTlJlYWRlcixcbiAgICBjb2RhYmFyX3JlYWRlcjogQ29kYWJhclJlYWRlcixcbiAgICB1cGNfcmVhZGVyOiBVUENSZWFkZXIsXG4gICAgdXBjX2VfcmVhZGVyOiBVUENFUmVhZGVyLFxuICAgIGkyb2Y1X3JlYWRlcjogSTJvZjVSZWFkZXJcbn07XG5leHBvcnQgZGVmYXVsdCB7XG4gICAgY3JlYXRlOiBmdW5jdGlvbihjb25maWcsIGlucHV0SW1hZ2VXcmFwcGVyKSB7XG4gICAgICAgIHZhciBfY2FudmFzID0ge1xuICAgICAgICAgICAgICAgIGN0eDoge1xuICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3k6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXk6IG51bGxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGRvbToge1xuICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3k6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXk6IG51bGxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgX2JhcmNvZGVSZWFkZXJzID0gW107XG5cbiAgICAgICAgaW5pdENhbnZhcygpO1xuICAgICAgICBpbml0UmVhZGVycygpO1xuICAgICAgICBpbml0Q29uZmlnKCk7XG5cbiAgICAgICAgZnVuY3Rpb24gaW5pdENhbnZhcygpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgdmFyICRkZWJ1ZyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjZGVidWcuZGV0ZWN0aW9uXCIpO1xuICAgICAgICAgICAgICAgIF9jYW52YXMuZG9tLmZyZXF1ZW5jeSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJjYW52YXMuZnJlcXVlbmN5XCIpO1xuICAgICAgICAgICAgICAgIGlmICghX2NhbnZhcy5kb20uZnJlcXVlbmN5KSB7XG4gICAgICAgICAgICAgICAgICAgIF9jYW52YXMuZG9tLmZyZXF1ZW5jeSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICAgICAgICAgICAgICAgIF9jYW52YXMuZG9tLmZyZXF1ZW5jeS5jbGFzc05hbWUgPSBcImZyZXF1ZW5jeVwiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJGRlYnVnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkZGVidWcuYXBwZW5kQ2hpbGQoX2NhbnZhcy5kb20uZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfY2FudmFzLmN0eC5mcmVxdWVuY3kgPSBfY2FudmFzLmRvbS5mcmVxdWVuY3kuZ2V0Q29udGV4dChcIjJkXCIpO1xuXG4gICAgICAgICAgICAgICAgX2NhbnZhcy5kb20ucGF0dGVybiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJjYW52YXMucGF0dGVybkJ1ZmZlclwiKTtcbiAgICAgICAgICAgICAgICBpZiAoIV9jYW52YXMuZG9tLnBhdHRlcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgX2NhbnZhcy5kb20ucGF0dGVybiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICAgICAgICAgICAgICAgIF9jYW52YXMuZG9tLnBhdHRlcm4uY2xhc3NOYW1lID0gXCJwYXR0ZXJuQnVmZmVyXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmICgkZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICRkZWJ1Zy5hcHBlbmRDaGlsZChfY2FudmFzLmRvbS5wYXR0ZXJuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfY2FudmFzLmN0eC5wYXR0ZXJuID0gX2NhbnZhcy5kb20ucGF0dGVybi5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgICAgICAgICAgICAgICBfY2FudmFzLmRvbS5vdmVybGF5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImNhbnZhcy5kcmF3aW5nQnVmZmVyXCIpO1xuICAgICAgICAgICAgICAgIGlmIChfY2FudmFzLmRvbS5vdmVybGF5KSB7XG4gICAgICAgICAgICAgICAgICAgIF9jYW52YXMuY3R4Lm92ZXJsYXkgPSBfY2FudmFzLmRvbS5vdmVybGF5LmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpbml0UmVhZGVycygpIHtcbiAgICAgICAgICAgIGNvbmZpZy5yZWFkZXJzLmZvckVhY2goZnVuY3Rpb24ocmVhZGVyQ29uZmlnKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbiA9IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZWFkZXJDb25maWcgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IHJlYWRlckNvbmZpZy5mb3JtYXQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24gPSByZWFkZXJDb25maWcuY29uZmlnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlYWRlckNvbmZpZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gcmVhZGVyQ29uZmlnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkJlZm9yZSByZWdpc3RlcmluZyByZWFkZXI6IFwiLCByZWFkZXIpO1xuICAgICAgICAgICAgICAgIF9iYXJjb2RlUmVhZGVycy5wdXNoKG5ldyBSRUFERVJTW3JlYWRlcl0oY29uZmlndXJhdGlvbikpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIlJlZ2lzdGVyZWQgUmVhZGVyczogXCIgKyBfYmFyY29kZVJlYWRlcnNcbiAgICAgICAgICAgICAgICAubWFwKChyZWFkZXIpID0+IEpTT04uc3RyaW5naWZ5KHtmb3JtYXQ6IHJlYWRlci5GT1JNQVQsIGNvbmZpZzogcmVhZGVyLmNvbmZpZ30pKVxuICAgICAgICAgICAgICAgIC5qb2luKCcsICcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGluaXRDb25maWcoKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHZhciBpLFxuICAgICAgICAgICAgICAgICAgICB2aXMgPSBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogX2NhbnZhcy5kb20uZnJlcXVlbmN5LFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcDogY29uZmlnLnNob3dGcmVxdWVuY3lcbiAgICAgICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogX2NhbnZhcy5kb20ucGF0dGVybixcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3A6IGNvbmZpZy5zaG93UGF0dGVyblxuICAgICAgICAgICAgICAgICAgICB9XTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2aXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZpc1tpXS5wcm9wID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNbaV0ubm9kZS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmlzW2ldLm5vZGUuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGV4dGVuZCB0aGUgbGluZSBvbiBib3RoIGVuZHNcbiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gbGluZVxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gYW5nbGVcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldEV4dGVuZGVkTGluZShsaW5lLCBhbmdsZSwgZXh0KSB7XG4gICAgICAgICAgICBmdW5jdGlvbiBleHRlbmRMaW5lKGFtb3VudCkge1xuICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgIHk6IGFtb3VudCAqIE1hdGguc2luKGFuZ2xlKSxcbiAgICAgICAgICAgICAgICAgICAgeDogYW1vdW50ICogTWF0aC5jb3MoYW5nbGUpXG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGxpbmVbMF0ueSAtPSBleHRlbnNpb24ueTtcbiAgICAgICAgICAgICAgICBsaW5lWzBdLnggLT0gZXh0ZW5zaW9uLng7XG4gICAgICAgICAgICAgICAgbGluZVsxXS55ICs9IGV4dGVuc2lvbi55O1xuICAgICAgICAgICAgICAgIGxpbmVbMV0ueCArPSBleHRlbnNpb24ueDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgaW5zaWRlIGltYWdlXG4gICAgICAgICAgICBleHRlbmRMaW5lKGV4dCk7XG4gICAgICAgICAgICB3aGlsZSAoZXh0ID4gMSAmJiAoIWlucHV0SW1hZ2VXcmFwcGVyLmluSW1hZ2VXaXRoQm9yZGVyKGxpbmVbMF0sIDApXG4gICAgICAgICAgICAgICAgICAgIHx8ICFpbnB1dEltYWdlV3JhcHBlci5pbkltYWdlV2l0aEJvcmRlcihsaW5lWzFdLCAwKSkpIHtcbiAgICAgICAgICAgICAgICBleHQgLT0gTWF0aC5jZWlsKGV4dCAvIDIpO1xuICAgICAgICAgICAgICAgIGV4dGVuZExpbmUoLWV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbGluZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldExpbmUoYm94KSB7XG4gICAgICAgICAgICByZXR1cm4gW3tcbiAgICAgICAgICAgICAgICB4OiAoYm94WzFdWzBdIC0gYm94WzBdWzBdKSAvIDIgKyBib3hbMF1bMF0sXG4gICAgICAgICAgICAgICAgeTogKGJveFsxXVsxXSAtIGJveFswXVsxXSkgLyAyICsgYm94WzBdWzFdXG4gICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgeDogKGJveFszXVswXSAtIGJveFsyXVswXSkgLyAyICsgYm94WzJdWzBdLFxuICAgICAgICAgICAgICAgIHk6IChib3hbM11bMV0gLSBib3hbMl1bMV0pIC8gMiArIGJveFsyXVsxXVxuICAgICAgICAgICAgfV07XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiB0cnlEZWNvZGUobGluZSkge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG51bGwsXG4gICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICBiYXJjb2RlTGluZSA9IEJyZXNlbmhhbS5nZXRCYXJjb2RlTGluZShpbnB1dEltYWdlV3JhcHBlciwgbGluZVswXSwgbGluZVsxXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuc2hvd0ZyZXF1ZW5jeSkge1xuICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgobGluZSwge3g6ICd4JywgeTogJ3knfSwgX2NhbnZhcy5jdHgub3ZlcmxheSwge2NvbG9yOiAncmVkJywgbGluZVdpZHRoOiAzfSk7XG4gICAgICAgICAgICAgICAgQnJlc2VuaGFtLmRlYnVnLnByaW50RnJlcXVlbmN5KGJhcmNvZGVMaW5lLmxpbmUsIF9jYW52YXMuZG9tLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBCcmVzZW5oYW0udG9CaW5hcnlMaW5lKGJhcmNvZGVMaW5lKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuc2hvd1BhdHRlcm4pIHtcbiAgICAgICAgICAgICAgICBCcmVzZW5oYW0uZGVidWcucHJpbnRQYXR0ZXJuKGJhcmNvZGVMaW5lLmxpbmUsIF9jYW52YXMuZG9tLnBhdHRlcm4pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKCBpID0gMDsgaSA8IF9iYXJjb2RlUmVhZGVycy5sZW5ndGggJiYgcmVzdWx0ID09PSBudWxsOyBpKyspIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBfYmFyY29kZVJlYWRlcnNbaV0uZGVjb2RlUGF0dGVybihiYXJjb2RlTGluZS5saW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwpe1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjb2RlUmVzdWx0OiByZXN1bHQsXG4gICAgICAgICAgICAgICAgYmFyY29kZUxpbmU6IGJhcmNvZGVMaW5lXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoaXMgbWV0aG9kIHNsaWNlcyB0aGUgZ2l2ZW4gYXJlYSBhcGFydCBhbmQgdHJpZXMgdG8gZGV0ZWN0IGEgYmFyY29kZS1wYXR0ZXJuXG4gICAgICAgICAqIGZvciBlYWNoIHNsaWNlLiBJdCByZXR1cm5zIHRoZSBkZWNvZGVkIGJhcmNvZGUsIG9yIG51bGwgaWYgbm90aGluZyB3YXMgZm91bmRcbiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gYm94XG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGxpbmVcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGxpbmVBbmdsZVxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gdHJ5RGVjb2RlQnJ1dGVGb3JjZShib3gsIGxpbmUsIGxpbmVBbmdsZSkge1xuICAgICAgICAgICAgdmFyIHNpZGVMZW5ndGggPSBNYXRoLnNxcnQoTWF0aC5wb3coYm94WzFdWzBdIC0gYm94WzBdWzBdLCAyKSArIE1hdGgucG93KChib3hbMV1bMV0gLSBib3hbMF1bMV0pLCAyKSksXG4gICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICBzbGljZXMgPSAxNixcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBudWxsLFxuICAgICAgICAgICAgICAgIGRpcixcbiAgICAgICAgICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICAgICAgICAgeGRpciA9IE1hdGguc2luKGxpbmVBbmdsZSksXG4gICAgICAgICAgICAgICAgeWRpciA9IE1hdGguY29zKGxpbmVBbmdsZSk7XG5cbiAgICAgICAgICAgIGZvciAoIGkgPSAxOyBpIDwgc2xpY2VzICYmIHJlc3VsdCA9PT0gbnVsbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gbW92ZSBsaW5lIHBlcnBlbmRpY3VsYXIgdG8gYW5nbGVcbiAgICAgICAgICAgICAgICBkaXIgPSBzaWRlTGVuZ3RoIC8gc2xpY2VzICogaSAqIChpICUgMiA9PT0gMCA/IC0xIDogMSk7XG4gICAgICAgICAgICAgICAgZXh0ZW5zaW9uID0ge1xuICAgICAgICAgICAgICAgICAgICB5OiBkaXIgKiB4ZGlyLFxuICAgICAgICAgICAgICAgICAgICB4OiBkaXIgKiB5ZGlyXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBsaW5lWzBdLnkgKz0gZXh0ZW5zaW9uLng7XG4gICAgICAgICAgICAgICAgbGluZVswXS54IC09IGV4dGVuc2lvbi55O1xuICAgICAgICAgICAgICAgIGxpbmVbMV0ueSArPSBleHRlbnNpb24ueDtcbiAgICAgICAgICAgICAgICBsaW5lWzFdLnggLT0gZXh0ZW5zaW9uLnk7XG5cbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnlEZWNvZGUobGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0TGluZUxlbmd0aChsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KFxuICAgICAgICAgICAgICAgIE1hdGgucG93KE1hdGguYWJzKGxpbmVbMV0ueSAtIGxpbmVbMF0ueSksIDIpICtcbiAgICAgICAgICAgICAgICBNYXRoLnBvdyhNYXRoLmFicyhsaW5lWzFdLnggLSBsaW5lWzBdLngpLCAyKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogV2l0aCB0aGUgaGVscCBvZiB0aGUgY29uZmlndXJlZCByZWFkZXJzIChDb2RlMTI4IG9yIEVBTikgdGhpcyBmdW5jdGlvbiB0cmllcyB0byBkZXRlY3QgYVxuICAgICAgICAgKiB2YWxpZCBiYXJjb2RlIHBhdHRlcm4gd2l0aGluIHRoZSBnaXZlbiBhcmVhLlxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gYm94IFRoZSBhcmVhIHRvIHNlYXJjaCBpblxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSB0aGUgcmVzdWx0IHtjb2RlUmVzdWx0LCBsaW5lLCBhbmdsZSwgcGF0dGVybiwgdGhyZXNob2xkfVxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZGVjb2RlRnJvbUJvdW5kaW5nQm94KGJveCkge1xuICAgICAgICAgICAgdmFyIGxpbmUsXG4gICAgICAgICAgICAgICAgbGluZUFuZ2xlLFxuICAgICAgICAgICAgICAgIGN0eCA9IF9jYW52YXMuY3R4Lm92ZXJsYXksXG4gICAgICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgICAgIGxpbmVMZW5ndGg7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuZHJhd0JvdW5kaW5nQm94ICYmIGN0eCkge1xuICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgoYm94LCB7eDogMCwgeTogMX0sIGN0eCwge2NvbG9yOiBcImJsdWVcIiwgbGluZVdpZHRoOiAyfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxpbmUgPSBnZXRMaW5lKGJveCk7XG4gICAgICAgICAgICBsaW5lTGVuZ3RoID0gZ2V0TGluZUxlbmd0aChsaW5lKTtcbiAgICAgICAgICAgIGxpbmVBbmdsZSA9IE1hdGguYXRhbjIobGluZVsxXS55IC0gbGluZVswXS55LCBsaW5lWzFdLnggLSBsaW5lWzBdLngpO1xuICAgICAgICAgICAgbGluZSA9IGdldEV4dGVuZGVkTGluZShsaW5lLCBsaW5lQW5nbGUsIE1hdGguZmxvb3IobGluZUxlbmd0aCAqIDAuMSkpO1xuICAgICAgICAgICAgaWYgKGxpbmUgPT09IG51bGwpe1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN1bHQgPSB0cnlEZWNvZGUobGluZSk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ5RGVjb2RlQnJ1dGVGb3JjZShib3gsIGxpbmUsIGxpbmVBbmdsZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiBjb25maWcuZHJhd1NjYW5saW5lICYmIGN0eCkge1xuICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgobGluZSwge3g6ICd4JywgeTogJ3knfSwgY3R4LCB7Y29sb3I6ICdyZWQnLCBsaW5lV2lkdGg6IDN9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjb2RlUmVzdWx0OiByZXN1bHQuY29kZVJlc3VsdCxcbiAgICAgICAgICAgICAgICBsaW5lOiBsaW5lLFxuICAgICAgICAgICAgICAgIGFuZ2xlOiBsaW5lQW5nbGUsXG4gICAgICAgICAgICAgICAgcGF0dGVybjogcmVzdWx0LmJhcmNvZGVMaW5lLmxpbmUsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiByZXN1bHQuYmFyY29kZUxpbmUudGhyZXNob2xkXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRlY29kZUZyb21Cb3VuZGluZ0JveDogZnVuY3Rpb24oYm94KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZUZyb21Cb3VuZGluZ0JveChib3gpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRlY29kZUZyb21Cb3VuZGluZ0JveGVzOiBmdW5jdGlvbihib3hlcykge1xuICAgICAgICAgICAgICAgIHZhciBpLCByZXN1bHQ7XG4gICAgICAgICAgICAgICAgZm9yICggaSA9IDA7IGkgPCBib3hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBkZWNvZGVGcm9tQm91bmRpbmdCb3goYm94ZXNbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdC5jb2RlUmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYm94ID0gYm94ZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFJlYWRlcnM6IGZ1bmN0aW9uKHJlYWRlcnMpIHtcbiAgICAgICAgICAgICAgICBjb25maWcucmVhZGVycyA9IHJlYWRlcnM7XG4gICAgICAgICAgICAgICAgX2JhcmNvZGVSZWFkZXJzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgaW5pdFJlYWRlcnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG59O1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvYmFyY29kZV9kZWNvZGVyLmpzXG4gKiovIiwiaW1wb3J0IENWVXRpbHMgZnJvbSAnLi9jdl91dGlscyc7XG5pbXBvcnQgSW1hZ2VXcmFwcGVyIGZyb20gJy4vaW1hZ2Vfd3JhcHBlcic7XG5cbnZhciBCcmVzZW5oYW0gPSB7fTtcblxudmFyIFNsb3BlID0ge1xuICAgIERJUjoge1xuICAgICAgICBVUDogMSxcbiAgICAgICAgRE9XTjogLTFcbiAgICB9XG59O1xuLyoqXG4gKiBTY2FucyBhIGxpbmUgb2YgdGhlIGdpdmVuIGltYWdlIGZyb20gcG9pbnQgcDEgdG8gcDIgYW5kIHJldHVybnMgYSByZXN1bHQgb2JqZWN0IGNvbnRhaW5pbmdcbiAqIGdyYXktc2NhbGUgdmFsdWVzICgwLTI1NSkgb2YgdGhlIHVuZGVybHlpbmcgcGl4ZWxzIGluIGFkZGl0aW9uIHRvIHRoZSBtaW5cbiAqIGFuZCBtYXggdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IGltYWdlV3JhcHBlclxuICogQHBhcmFtIHtPYmplY3R9IHAxIFRoZSBzdGFydCBwb2ludCB7eCx5fVxuICogQHBhcmFtIHtPYmplY3R9IHAyIFRoZSBlbmQgcG9pbnQge3gseX1cbiAqIEByZXR1cm5zIHtsaW5lLCBtaW4sIG1heH1cbiAqL1xuQnJlc2VuaGFtLmdldEJhcmNvZGVMaW5lID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBwMSwgcDIpIHtcbiAgICB2YXIgeDAgPSBwMS54IHwgMCxcbiAgICAgICAgeTAgPSBwMS55IHwgMCxcbiAgICAgICAgeDEgPSBwMi54IHwgMCxcbiAgICAgICAgeTEgPSBwMi55IHwgMCxcbiAgICAgICAgc3RlZXAgPSBNYXRoLmFicyh5MSAtIHkwKSA+IE1hdGguYWJzKHgxIC0geDApLFxuICAgICAgICBkZWx0YXgsXG4gICAgICAgIGRlbHRheSxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIHlzdGVwLFxuICAgICAgICB5LFxuICAgICAgICB0bXAsXG4gICAgICAgIHgsXG4gICAgICAgIGxpbmUgPSBbXSxcbiAgICAgICAgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGEsXG4gICAgICAgIHdpZHRoID0gaW1hZ2VXcmFwcGVyLnNpemUueCxcbiAgICAgICAgc3VtID0gMCxcbiAgICAgICAgdmFsLFxuICAgICAgICBtaW4gPSAyNTUsXG4gICAgICAgIG1heCA9IDA7XG5cbiAgICBmdW5jdGlvbiByZWFkKGEsIGIpIHtcbiAgICAgICAgdmFsID0gaW1hZ2VEYXRhW2IgKiB3aWR0aCArIGFdO1xuICAgICAgICBzdW0gKz0gdmFsO1xuICAgICAgICBtaW4gPSB2YWwgPCBtaW4gPyB2YWwgOiBtaW47XG4gICAgICAgIG1heCA9IHZhbCA+IG1heCA/IHZhbCA6IG1heDtcbiAgICAgICAgbGluZS5wdXNoKHZhbCk7XG4gICAgfVxuXG4gICAgaWYgKHN0ZWVwKSB7XG4gICAgICAgIHRtcCA9IHgwO1xuICAgICAgICB4MCA9IHkwO1xuICAgICAgICB5MCA9IHRtcDtcblxuICAgICAgICB0bXAgPSB4MTtcbiAgICAgICAgeDEgPSB5MTtcbiAgICAgICAgeTEgPSB0bXA7XG4gICAgfVxuICAgIGlmICh4MCA+IHgxKSB7XG4gICAgICAgIHRtcCA9IHgwO1xuICAgICAgICB4MCA9IHgxO1xuICAgICAgICB4MSA9IHRtcDtcblxuICAgICAgICB0bXAgPSB5MDtcbiAgICAgICAgeTAgPSB5MTtcbiAgICAgICAgeTEgPSB0bXA7XG4gICAgfVxuICAgIGRlbHRheCA9IHgxIC0geDA7XG4gICAgZGVsdGF5ID0gTWF0aC5hYnMoeTEgLSB5MCk7XG4gICAgZXJyb3IgPSAoZGVsdGF4IC8gMikgfCAwO1xuICAgIHkgPSB5MDtcbiAgICB5c3RlcCA9IHkwIDwgeTEgPyAxIDogLTE7XG4gICAgZm9yICggeCA9IHgwOyB4IDwgeDE7IHgrKykge1xuICAgICAgICBpZiAoc3RlZXApe1xuICAgICAgICAgICAgcmVhZCh5LCB4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlYWQoeCwgeSk7XG4gICAgICAgIH1cbiAgICAgICAgZXJyb3IgPSBlcnJvciAtIGRlbHRheTtcbiAgICAgICAgaWYgKGVycm9yIDwgMCkge1xuICAgICAgICAgICAgeSA9IHkgKyB5c3RlcDtcbiAgICAgICAgICAgIGVycm9yID0gZXJyb3IgKyBkZWx0YXg7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBsaW5lOiBsaW5lLFxuICAgICAgICBtaW46IG1pbixcbiAgICAgICAgbWF4OiBtYXhcbiAgICB9O1xufTtcblxuQnJlc2VuaGFtLnRvT3RzdUJpbmFyeUxpbmUgPSBmdW5jdGlvbihyZXN1bHQpIHtcbiAgICB2YXIgbGluZSA9IHJlc3VsdC5saW5lLFxuICAgICAgICBpbWFnZSA9IG5ldyBJbWFnZVdyYXBwZXIoe3g6IGxpbmUubGVuZ3RoIC0gMSwgeTogMX0sIGxpbmUpLFxuICAgICAgICB0aHJlc2hvbGQgPSBDVlV0aWxzLmRldGVybWluZU90c3VUaHJlc2hvbGQoaW1hZ2UsIDUpO1xuXG4gICAgbGluZSA9IENWVXRpbHMuc2hhcnBlbkxpbmUobGluZSk7XG4gICAgQ1ZVdGlscy50aHJlc2hvbGRJbWFnZShpbWFnZSwgdGhyZXNob2xkKTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGxpbmU6IGxpbmUsXG4gICAgICAgIHRocmVzaG9sZDogdGhyZXNob2xkXG4gICAgfTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhlIHJlc3VsdCBmcm9tIGdldEJhcmNvZGVMaW5lIGludG8gYSBiaW5hcnkgcmVwcmVzZW50YXRpb25cbiAqIGFsc28gY29uc2lkZXJpbmcgdGhlIGZyZXF1ZW5jeSBhbmQgc2xvcGUgb2YgdGhlIHNpZ25hbCBmb3IgbW9yZSByb2J1c3QgcmVzdWx0c1xuICogQHBhcmFtIHtPYmplY3R9IHJlc3VsdCB7bGluZSwgbWluLCBtYXh9XG4gKi9cbkJyZXNlbmhhbS50b0JpbmFyeUxpbmUgPSBmdW5jdGlvbihyZXN1bHQpIHtcbiAgICB2YXIgbWluID0gcmVzdWx0Lm1pbixcbiAgICAgICAgbWF4ID0gcmVzdWx0Lm1heCxcbiAgICAgICAgbGluZSA9IHJlc3VsdC5saW5lLFxuICAgICAgICBzbG9wZSxcbiAgICAgICAgc2xvcGUyLFxuICAgICAgICBjZW50ZXIgPSBtaW4gKyAobWF4IC0gbWluKSAvIDIsXG4gICAgICAgIGV4dHJlbWEgPSBbXSxcbiAgICAgICAgY3VycmVudERpcixcbiAgICAgICAgZGlyLFxuICAgICAgICB0aHJlc2hvbGQgPSAobWF4IC0gbWluKSAvIDEyLFxuICAgICAgICByVGhyZXNob2xkID0gLXRocmVzaG9sZCxcbiAgICAgICAgaSxcbiAgICAgICAgajtcblxuICAgIC8vIDEuIGZpbmQgZXh0cmVtYVxuICAgIGN1cnJlbnREaXIgPSBsaW5lWzBdID4gY2VudGVyID8gU2xvcGUuRElSLlVQIDogU2xvcGUuRElSLkRPV047XG4gICAgZXh0cmVtYS5wdXNoKHtcbiAgICAgICAgcG9zOiAwLFxuICAgICAgICB2YWw6IGxpbmVbMF1cbiAgICB9KTtcbiAgICBmb3IgKCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoIC0gMjsgaSsrKSB7XG4gICAgICAgIHNsb3BlID0gKGxpbmVbaSArIDFdIC0gbGluZVtpXSk7XG4gICAgICAgIHNsb3BlMiA9IChsaW5lW2kgKyAyXSAtIGxpbmVbaSArIDFdKTtcbiAgICAgICAgaWYgKChzbG9wZSArIHNsb3BlMikgPCByVGhyZXNob2xkICYmIGxpbmVbaSArIDFdIDwgKGNlbnRlciAqIDEuNSkpIHtcbiAgICAgICAgICAgIGRpciA9IFNsb3BlLkRJUi5ET1dOO1xuICAgICAgICB9IGVsc2UgaWYgKChzbG9wZSArIHNsb3BlMikgPiB0aHJlc2hvbGQgJiYgbGluZVtpICsgMV0gPiAoY2VudGVyICogMC41KSkge1xuICAgICAgICAgICAgZGlyID0gU2xvcGUuRElSLlVQO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGlyID0gY3VycmVudERpcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50RGlyICE9PSBkaXIpIHtcbiAgICAgICAgICAgIGV4dHJlbWEucHVzaCh7XG4gICAgICAgICAgICAgICAgcG9zOiBpLFxuICAgICAgICAgICAgICAgIHZhbDogbGluZVtpXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjdXJyZW50RGlyID0gZGlyO1xuICAgICAgICB9XG4gICAgfVxuICAgIGV4dHJlbWEucHVzaCh7XG4gICAgICAgIHBvczogbGluZS5sZW5ndGgsXG4gICAgICAgIHZhbDogbGluZVtsaW5lLmxlbmd0aCAtIDFdXG4gICAgfSk7XG5cbiAgICBmb3IgKCBqID0gZXh0cmVtYVswXS5wb3M7IGogPCBleHRyZW1hWzFdLnBvczsgaisrKSB7XG4gICAgICAgIGxpbmVbal0gPSBsaW5lW2pdID4gY2VudGVyID8gMCA6IDE7XG4gICAgfVxuXG4gICAgLy8gaXRlcmF0ZSBvdmVyIGV4dHJlbWEgYW5kIGNvbnZlcnQgdG8gYmluYXJ5IGJhc2VkIG9uIGF2ZyBiZXR3ZWVuIG1pbm1heFxuICAgIGZvciAoIGkgPSAxOyBpIDwgZXh0cmVtYS5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgaWYgKGV4dHJlbWFbaSArIDFdLnZhbCA+IGV4dHJlbWFbaV0udmFsKSB7XG4gICAgICAgICAgICB0aHJlc2hvbGQgPSAoZXh0cmVtYVtpXS52YWwgKyAoKGV4dHJlbWFbaSArIDFdLnZhbCAtIGV4dHJlbWFbaV0udmFsKSAvIDMpICogMikgfCAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyZXNob2xkID0gKGV4dHJlbWFbaSArIDFdLnZhbCArICgoZXh0cmVtYVtpXS52YWwgLSBleHRyZW1hW2kgKyAxXS52YWwpIC8gMykpIHwgMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoIGogPSBleHRyZW1hW2ldLnBvczsgaiA8IGV4dHJlbWFbaSArIDFdLnBvczsgaisrKSB7XG4gICAgICAgICAgICBsaW5lW2pdID0gbGluZVtqXSA+IHRocmVzaG9sZCA/IDAgOiAxO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgbGluZTogbGluZSxcbiAgICAgICAgdGhyZXNob2xkOiB0aHJlc2hvbGRcbiAgICB9O1xufTtcblxuLyoqXG4gKiBVc2VkIGZvciBkZXZlbG9wbWVudCBvbmx5XG4gKi9cbkJyZXNlbmhhbS5kZWJ1ZyA9IHtcbiAgICBwcmludEZyZXF1ZW5jeTogZnVuY3Rpb24obGluZSwgY2FudmFzKSB7XG4gICAgICAgIHZhciBpLFxuICAgICAgICAgICAgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgICAgY2FudmFzLndpZHRoID0gbGluZS5sZW5ndGg7XG4gICAgICAgIGNhbnZhcy5oZWlnaHQgPSAyNTY7XG5cbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBcImJsdWVcIjtcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjdHgubW92ZVRvKGksIDI1NSk7XG4gICAgICAgICAgICBjdHgubGluZVRvKGksIDI1NSAtIGxpbmVbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgIH0sXG5cbiAgICBwcmludFBhdHRlcm46IGZ1bmN0aW9uKGxpbmUsIGNhbnZhcykge1xuICAgICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSwgaTtcblxuICAgICAgICBjYW52YXMud2lkdGggPSBsaW5lLmxlbmd0aDtcbiAgICAgICAgY3R4LmZpbGxDb2xvciA9IFwiYmxhY2tcIjtcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAobGluZVtpXSA9PT0gMSkge1xuICAgICAgICAgICAgICAgIGN0eC5maWxsUmVjdChpLCAwLCAxLCAxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgQnJlc2VuaGFtO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvYnJlc2VuaGFtLmpzXG4gKiovIiwiaW1wb3J0IEJhcmNvZGVSZWFkZXIgZnJvbSAnLi9iYXJjb2RlX3JlYWRlcic7XG5cbmZ1bmN0aW9uIENvZGUxMjhSZWFkZXIoKSB7XG4gICAgQmFyY29kZVJlYWRlci5jYWxsKHRoaXMpO1xufVxuXG52YXIgcHJvcGVydGllcyA9IHtcbiAgICBDT0RFX1NISUZUOiB7dmFsdWU6IDk4fSxcbiAgICBDT0RFX0M6IHt2YWx1ZTogOTl9LFxuICAgIENPREVfQjoge3ZhbHVlOiAxMDB9LFxuICAgIENPREVfQToge3ZhbHVlOiAxMDF9LFxuICAgIFNUQVJUX0NPREVfQToge3ZhbHVlOiAxMDN9LFxuICAgIFNUQVJUX0NPREVfQjoge3ZhbHVlOiAxMDR9LFxuICAgIFNUQVJUX0NPREVfQzoge3ZhbHVlOiAxMDV9LFxuICAgIFNUT1BfQ09ERToge3ZhbHVlOiAxMDZ9LFxuICAgIE1PRFVMTzoge3ZhbHVlOiAxMX0sXG4gICAgQ09ERV9QQVRURVJOOiB7dmFsdWU6IFtcbiAgICAgICAgWzIsIDEsIDIsIDIsIDIsIDJdLFxuICAgICAgICBbMiwgMiwgMiwgMSwgMiwgMl0sXG4gICAgICAgIFsyLCAyLCAyLCAyLCAyLCAxXSxcbiAgICAgICAgWzEsIDIsIDEsIDIsIDIsIDNdLFxuICAgICAgICBbMSwgMiwgMSwgMywgMiwgMl0sXG4gICAgICAgIFsxLCAzLCAxLCAyLCAyLCAyXSxcbiAgICAgICAgWzEsIDIsIDIsIDIsIDEsIDNdLFxuICAgICAgICBbMSwgMiwgMiwgMywgMSwgMl0sXG4gICAgICAgIFsxLCAzLCAyLCAyLCAxLCAyXSxcbiAgICAgICAgWzIsIDIsIDEsIDIsIDEsIDNdLFxuICAgICAgICBbMiwgMiwgMSwgMywgMSwgMl0sXG4gICAgICAgIFsyLCAzLCAxLCAyLCAxLCAyXSxcbiAgICAgICAgWzEsIDEsIDIsIDIsIDMsIDJdLFxuICAgICAgICBbMSwgMiwgMiwgMSwgMywgMl0sXG4gICAgICAgIFsxLCAyLCAyLCAyLCAzLCAxXSxcbiAgICAgICAgWzEsIDEsIDMsIDIsIDIsIDJdLFxuICAgICAgICBbMSwgMiwgMywgMSwgMiwgMl0sXG4gICAgICAgIFsxLCAyLCAzLCAyLCAyLCAxXSxcbiAgICAgICAgWzIsIDIsIDMsIDIsIDEsIDFdLFxuICAgICAgICBbMiwgMiwgMSwgMSwgMywgMl0sXG4gICAgICAgIFsyLCAyLCAxLCAyLCAzLCAxXSxcbiAgICAgICAgWzIsIDEsIDMsIDIsIDEsIDJdLFxuICAgICAgICBbMiwgMiwgMywgMSwgMSwgMl0sXG4gICAgICAgIFszLCAxLCAyLCAxLCAzLCAxXSxcbiAgICAgICAgWzMsIDEsIDEsIDIsIDIsIDJdLFxuICAgICAgICBbMywgMiwgMSwgMSwgMiwgMl0sXG4gICAgICAgIFszLCAyLCAxLCAyLCAyLCAxXSxcbiAgICAgICAgWzMsIDEsIDIsIDIsIDEsIDJdLFxuICAgICAgICBbMywgMiwgMiwgMSwgMSwgMl0sXG4gICAgICAgIFszLCAyLCAyLCAyLCAxLCAxXSxcbiAgICAgICAgWzIsIDEsIDIsIDEsIDIsIDNdLFxuICAgICAgICBbMiwgMSwgMiwgMywgMiwgMV0sXG4gICAgICAgIFsyLCAzLCAyLCAxLCAyLCAxXSxcbiAgICAgICAgWzEsIDEsIDEsIDMsIDIsIDNdLFxuICAgICAgICBbMSwgMywgMSwgMSwgMiwgM10sXG4gICAgICAgIFsxLCAzLCAxLCAzLCAyLCAxXSxcbiAgICAgICAgWzEsIDEsIDIsIDMsIDEsIDNdLFxuICAgICAgICBbMSwgMywgMiwgMSwgMSwgM10sXG4gICAgICAgIFsxLCAzLCAyLCAzLCAxLCAxXSxcbiAgICAgICAgWzIsIDEsIDEsIDMsIDEsIDNdLFxuICAgICAgICBbMiwgMywgMSwgMSwgMSwgM10sXG4gICAgICAgIFsyLCAzLCAxLCAzLCAxLCAxXSxcbiAgICAgICAgWzEsIDEsIDIsIDEsIDMsIDNdLFxuICAgICAgICBbMSwgMSwgMiwgMywgMywgMV0sXG4gICAgICAgIFsxLCAzLCAyLCAxLCAzLCAxXSxcbiAgICAgICAgWzEsIDEsIDMsIDEsIDIsIDNdLFxuICAgICAgICBbMSwgMSwgMywgMywgMiwgMV0sXG4gICAgICAgIFsxLCAzLCAzLCAxLCAyLCAxXSxcbiAgICAgICAgWzMsIDEsIDMsIDEsIDIsIDFdLFxuICAgICAgICBbMiwgMSwgMSwgMywgMywgMV0sXG4gICAgICAgIFsyLCAzLCAxLCAxLCAzLCAxXSxcbiAgICAgICAgWzIsIDEsIDMsIDEsIDEsIDNdLFxuICAgICAgICBbMiwgMSwgMywgMywgMSwgMV0sXG4gICAgICAgIFsyLCAxLCAzLCAxLCAzLCAxXSxcbiAgICAgICAgWzMsIDEsIDEsIDEsIDIsIDNdLFxuICAgICAgICBbMywgMSwgMSwgMywgMiwgMV0sXG4gICAgICAgIFszLCAzLCAxLCAxLCAyLCAxXSxcbiAgICAgICAgWzMsIDEsIDIsIDEsIDEsIDNdLFxuICAgICAgICBbMywgMSwgMiwgMywgMSwgMV0sXG4gICAgICAgIFszLCAzLCAyLCAxLCAxLCAxXSxcbiAgICAgICAgWzMsIDEsIDQsIDEsIDEsIDFdLFxuICAgICAgICBbMiwgMiwgMSwgNCwgMSwgMV0sXG4gICAgICAgIFs0LCAzLCAxLCAxLCAxLCAxXSxcbiAgICAgICAgWzEsIDEsIDEsIDIsIDIsIDRdLFxuICAgICAgICBbMSwgMSwgMSwgNCwgMiwgMl0sXG4gICAgICAgIFsxLCAyLCAxLCAxLCAyLCA0XSxcbiAgICAgICAgWzEsIDIsIDEsIDQsIDIsIDFdLFxuICAgICAgICBbMSwgNCwgMSwgMSwgMiwgMl0sXG4gICAgICAgIFsxLCA0LCAxLCAyLCAyLCAxXSxcbiAgICAgICAgWzEsIDEsIDIsIDIsIDEsIDRdLFxuICAgICAgICBbMSwgMSwgMiwgNCwgMSwgMl0sXG4gICAgICAgIFsxLCAyLCAyLCAxLCAxLCA0XSxcbiAgICAgICAgWzEsIDIsIDIsIDQsIDEsIDFdLFxuICAgICAgICBbMSwgNCwgMiwgMSwgMSwgMl0sXG4gICAgICAgIFsxLCA0LCAyLCAyLCAxLCAxXSxcbiAgICAgICAgWzIsIDQsIDEsIDIsIDEsIDFdLFxuICAgICAgICBbMiwgMiwgMSwgMSwgMSwgNF0sXG4gICAgICAgIFs0LCAxLCAzLCAxLCAxLCAxXSxcbiAgICAgICAgWzIsIDQsIDEsIDEsIDEsIDJdLFxuICAgICAgICBbMSwgMywgNCwgMSwgMSwgMV0sXG4gICAgICAgIFsxLCAxLCAxLCAyLCA0LCAyXSxcbiAgICAgICAgWzEsIDIsIDEsIDEsIDQsIDJdLFxuICAgICAgICBbMSwgMiwgMSwgMiwgNCwgMV0sXG4gICAgICAgIFsxLCAxLCA0LCAyLCAxLCAyXSxcbiAgICAgICAgWzEsIDIsIDQsIDEsIDEsIDJdLFxuICAgICAgICBbMSwgMiwgNCwgMiwgMSwgMV0sXG4gICAgICAgIFs0LCAxLCAxLCAyLCAxLCAyXSxcbiAgICAgICAgWzQsIDIsIDEsIDEsIDEsIDJdLFxuICAgICAgICBbNCwgMiwgMSwgMiwgMSwgMV0sXG4gICAgICAgIFsyLCAxLCAyLCAxLCA0LCAxXSxcbiAgICAgICAgWzIsIDEsIDQsIDEsIDIsIDFdLFxuICAgICAgICBbNCwgMSwgMiwgMSwgMiwgMV0sXG4gICAgICAgIFsxLCAxLCAxLCAxLCA0LCAzXSxcbiAgICAgICAgWzEsIDEsIDEsIDMsIDQsIDFdLFxuICAgICAgICBbMSwgMywgMSwgMSwgNCwgMV0sXG4gICAgICAgIFsxLCAxLCA0LCAxLCAxLCAzXSxcbiAgICAgICAgWzEsIDEsIDQsIDMsIDEsIDFdLFxuICAgICAgICBbNCwgMSwgMSwgMSwgMSwgM10sXG4gICAgICAgIFs0LCAxLCAxLCAzLCAxLCAxXSxcbiAgICAgICAgWzEsIDEsIDMsIDEsIDQsIDFdLFxuICAgICAgICBbMSwgMSwgNCwgMSwgMywgMV0sXG4gICAgICAgIFszLCAxLCAxLCAxLCA0LCAxXSxcbiAgICAgICAgWzQsIDEsIDEsIDEsIDMsIDFdLFxuICAgICAgICBbMiwgMSwgMSwgNCwgMSwgMl0sXG4gICAgICAgIFsyLCAxLCAxLCAyLCAxLCA0XSxcbiAgICAgICAgWzIsIDEsIDEsIDIsIDMsIDJdLFxuICAgICAgICBbMiwgMywgMywgMSwgMSwgMSwgMl1cbiAgICBdfSxcbiAgICBTSU5HTEVfQ09ERV9FUlJPUjoge3ZhbHVlOiAxfSxcbiAgICBBVkdfQ09ERV9FUlJPUjoge3ZhbHVlOiAwLjV9LFxuICAgIEZPUk1BVDoge3ZhbHVlOiBcImNvZGVfMTI4XCIsIHdyaXRlYWJsZTogZmFsc2V9XG59O1xuXG5Db2RlMTI4UmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQmFyY29kZVJlYWRlci5wcm90b3R5cGUsIHByb3BlcnRpZXMpO1xuQ29kZTEyOFJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb2RlMTI4UmVhZGVyO1xuXG5Db2RlMTI4UmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlQ29kZSA9IGZ1bmN0aW9uKHN0YXJ0KSB7XG4gICAgdmFyIGNvdW50ZXIgPSBbMCwgMCwgMCwgMCwgMCwgMF0sXG4gICAgICAgIGksXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICBvZmZzZXQgPSBzdGFydCxcbiAgICAgICAgaXNXaGl0ZSA9ICFzZWxmLl9yb3dbb2Zmc2V0XSxcbiAgICAgICAgY291bnRlclBvcyA9IDAsXG4gICAgICAgIGJlc3RNYXRjaCA9IHtcbiAgICAgICAgICAgIGVycm9yOiBOdW1iZXIuTUFYX1ZBTFVFLFxuICAgICAgICAgICAgY29kZTogLTEsXG4gICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IHN0YXJ0XG4gICAgICAgIH0sXG4gICAgICAgIGNvZGUsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBub3JtYWxpemVkO1xuXG4gICAgZm9yICggaSA9IG9mZnNldDsgaSA8IHNlbGYuX3Jvdy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc2VsZi5fcm93W2ldIF4gaXNXaGl0ZSkge1xuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvdW50ZXJQb3MgPT09IGNvdW50ZXIubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlcik7XG4gICAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb2RlID0gMDsgY29kZSA8IHNlbGYuQ09ERV9QQVRURVJOLmxlbmd0aDsgY29kZSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHNlbGYuX21hdGNoUGF0dGVybihub3JtYWxpemVkLCBzZWxmLkNPREVfUEFUVEVSTltjb2RlXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPCBiZXN0TWF0Y2guZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guY29kZSA9IGNvZGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVuZCA9IGk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBiZXN0TWF0Y2g7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbkNvZGUxMjhSZWFkZXIucHJvdG90eXBlLl9maW5kU3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgY291bnRlciA9IFswLCAwLCAwLCAwLCAwLCAwXSxcbiAgICAgICAgaSxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIG9mZnNldCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93KSxcbiAgICAgICAgaXNXaGl0ZSA9IGZhbHNlLFxuICAgICAgICBjb3VudGVyUG9zID0gMCxcbiAgICAgICAgYmVzdE1hdGNoID0ge1xuICAgICAgICAgICAgZXJyb3I6IE51bWJlci5NQVhfVkFMVUUsXG4gICAgICAgICAgICBjb2RlOiAtMSxcbiAgICAgICAgICAgIHN0YXJ0OiAwLFxuICAgICAgICAgICAgZW5kOiAwXG4gICAgICAgIH0sXG4gICAgICAgIGNvZGUsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBqLFxuICAgICAgICBzdW0sXG4gICAgICAgIG5vcm1hbGl6ZWQ7XG5cbiAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gY291bnRlci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgc3VtID0gMDtcbiAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgc3VtICs9IGNvdW50ZXJbal07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlcik7XG4gICAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb2RlID0gc2VsZi5TVEFSVF9DT0RFX0E7IGNvZGUgPD0gc2VsZi5TVEFSVF9DT0RFX0M7IGNvZGUrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBzZWxmLl9tYXRjaFBhdHRlcm4obm9ybWFsaXplZCwgc2VsZi5DT0RFX1BBVFRFUk5bY29kZV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIDwgYmVzdE1hdGNoLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmNvZGUgPSBjb2RlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5lcnJvciA9IGVycm9yO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChiZXN0TWF0Y2guZXJyb3IgPCBzZWxmLkFWR19DT0RFX0VSUk9SKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guc3RhcnQgPSBpIC0gc3VtO1xuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVuZCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmVzdE1hdGNoO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm9yICggaiA9IDA7IGogPCA0OyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcltqXSA9IGNvdW50ZXJbaiArIDJdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb3VudGVyWzRdID0gMDtcbiAgICAgICAgICAgICAgICBjb3VudGVyWzVdID0gMDtcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zLS07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10gPSAxO1xuICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuQ29kZTEyOFJlYWRlci5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgc3RhcnRJbmZvID0gc2VsZi5fZmluZFN0YXJ0KCksXG4gICAgICAgIGNvZGUgPSBudWxsLFxuICAgICAgICBkb25lID0gZmFsc2UsXG4gICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICBtdWx0aXBsaWVyID0gMCxcbiAgICAgICAgY2hlY2tzdW0gPSAwLFxuICAgICAgICBjb2Rlc2V0LFxuICAgICAgICByYXdSZXN1bHQgPSBbXSxcbiAgICAgICAgZGVjb2RlZENvZGVzID0gW10sXG4gICAgICAgIHNoaWZ0TmV4dCA9IGZhbHNlLFxuICAgICAgICB1bnNoaWZ0LFxuICAgICAgICByZW1vdmVMYXN0Q2hhcmFjdGVyID0gdHJ1ZTtcblxuICAgIGlmIChzdGFydEluZm8gPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvZGUgPSB7XG4gICAgICAgIGNvZGU6IHN0YXJ0SW5mby5jb2RlLFxuICAgICAgICBzdGFydDogc3RhcnRJbmZvLnN0YXJ0LFxuICAgICAgICBlbmQ6IHN0YXJ0SW5mby5lbmRcbiAgICB9O1xuICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xuICAgIGNoZWNrc3VtID0gY29kZS5jb2RlO1xuICAgIHN3aXRjaCAoY29kZS5jb2RlKSB7XG4gICAgY2FzZSBzZWxmLlNUQVJUX0NPREVfQTpcbiAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9BO1xuICAgICAgICBicmVhaztcbiAgICBjYXNlIHNlbGYuU1RBUlRfQ09ERV9COlxuICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0I7XG4gICAgICAgIGJyZWFrO1xuICAgIGNhc2Ugc2VsZi5TVEFSVF9DT0RFX0M6XG4gICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQztcbiAgICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgd2hpbGUgKCFkb25lKSB7XG4gICAgICAgIHVuc2hpZnQgPSBzaGlmdE5leHQ7XG4gICAgICAgIHNoaWZ0TmV4dCA9IGZhbHNlO1xuICAgICAgICBjb2RlID0gc2VsZi5fZGVjb2RlQ29kZShjb2RlLmVuZCk7XG4gICAgICAgIGlmIChjb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoY29kZS5jb2RlICE9PSBzZWxmLlNUT1BfQ09ERSkge1xuICAgICAgICAgICAgICAgIHJlbW92ZUxhc3RDaGFyYWN0ZXIgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29kZS5jb2RlICE9PSBzZWxmLlNUT1BfQ09ERSkge1xuICAgICAgICAgICAgICAgIHJhd1Jlc3VsdC5wdXNoKGNvZGUuY29kZSk7XG4gICAgICAgICAgICAgICAgbXVsdGlwbGllcisrO1xuICAgICAgICAgICAgICAgIGNoZWNrc3VtICs9IG11bHRpcGxpZXIgKiBjb2RlLmNvZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcblxuICAgICAgICAgICAgc3dpdGNoIChjb2Rlc2V0KSB7XG4gICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9BOlxuICAgICAgICAgICAgICAgIGlmIChjb2RlLmNvZGUgPCA2NCkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKDMyICsgY29kZS5jb2RlKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb2RlLmNvZGUgPCA5Nikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUuY29kZSAtIDY0KSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvZGUuY29kZSAhPT0gc2VsZi5TVE9QX0NPREUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUxhc3RDaGFyYWN0ZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUuY29kZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9TSElGVDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0TmV4dCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0I7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfQjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9DOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9DO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5TVE9QX0NPREU6XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfQjpcbiAgICAgICAgICAgICAgICBpZiAoY29kZS5jb2RlIDwgOTYpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgzMiArIGNvZGUuY29kZSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2RlLmNvZGUgIT09IHNlbGYuU1RPUF9DT0RFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVMYXN0Q2hhcmFjdGVyID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlLmNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfU0hJRlQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBzaGlmdE5leHQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9BO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX0E6XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0E7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfQzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuU1RPUF9DT0RFOlxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX0M6XG4gICAgICAgICAgICAgICAgaWYgKGNvZGUuY29kZSA8IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjb2RlLmNvZGUgPCAxMCA/IFwiMFwiICsgY29kZS5jb2RlIDogY29kZS5jb2RlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29kZS5jb2RlICE9PSBzZWxmLlNUT1BfQ09ERSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTGFzdENoYXJhY3RlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZS5jb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX0E6XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0E7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfQjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuU1RPUF9DT0RFOlxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1bnNoaWZ0KSB7XG4gICAgICAgICAgICBjb2Rlc2V0ID0gY29kZXNldCA9PT0gc2VsZi5DT0RFX0EgPyBzZWxmLkNPREVfQiA6IHNlbGYuQ09ERV9BO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29kZS5lbmQgPSBzZWxmLl9uZXh0VW5zZXQoc2VsZi5fcm93LCBjb2RlLmVuZCk7XG4gICAgaWYgKCFzZWxmLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UoY29kZSkpe1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjaGVja3N1bSAtPSBtdWx0aXBsaWVyICogcmF3UmVzdWx0W3Jhd1Jlc3VsdC5sZW5ndGggLSAxXTtcbiAgICBpZiAoY2hlY2tzdW0gJSAxMDMgIT09IHJhd1Jlc3VsdFtyYXdSZXN1bHQubGVuZ3RoIC0gMV0pIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBsYXN0IGNvZGUgZnJvbSByZXN1bHQgKGNoZWNrc3VtKVxuICAgIGlmIChyZW1vdmVMYXN0Q2hhcmFjdGVyKSB7XG4gICAgICAgIHJlc3VsdC5zcGxpY2UocmVzdWx0Lmxlbmd0aCAtIDEsIDEpO1xuICAgIH1cblxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXG4gICAgICAgIHN0YXJ0OiBzdGFydEluZm8uc3RhcnQsXG4gICAgICAgIGVuZDogY29kZS5lbmQsXG4gICAgICAgIGNvZGVzZXQ6IGNvZGVzZXQsXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnRJbmZvLFxuICAgICAgICBkZWNvZGVkQ29kZXM6IGRlY29kZWRDb2RlcyxcbiAgICAgICAgZW5kSW5mbzogY29kZVxuICAgIH07XG59O1xuXG5cbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UgPSBmdW5jdGlvbihlbmRJbmZvKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICB0cmFpbGluZ1doaXRlc3BhY2VFbmQ7XG5cbiAgICB0cmFpbGluZ1doaXRlc3BhY2VFbmQgPSBlbmRJbmZvLmVuZCArICgoZW5kSW5mby5lbmQgLSBlbmRJbmZvLnN0YXJ0KSAvIDIpO1xuICAgIGlmICh0cmFpbGluZ1doaXRlc3BhY2VFbmQgPCBzZWxmLl9yb3cubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGVuZEluZm8uZW5kLCB0cmFpbGluZ1doaXRlc3BhY2VFbmQsIDApKSB7XG4gICAgICAgICAgICByZXR1cm4gZW5kSW5mbztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IENvZGUxMjhSZWFkZXI7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jb2RlXzEyOF9yZWFkZXIuanNcbiAqKi8iLCJmdW5jdGlvbiBCYXJjb2RlUmVhZGVyKGNvbmZpZykge1xuICAgIHRoaXMuX3JvdyA9IFtdO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5CYXJjb2RlUmVhZGVyLnByb3RvdHlwZS5fbmV4dFVuc2V0ID0gZnVuY3Rpb24obGluZSwgc3RhcnQpIHtcbiAgICB2YXIgaTtcblxuICAgIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN0YXJ0ID0gMDtcbiAgICB9XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghbGluZVtpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbmUubGVuZ3RoO1xufTtcblxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX21hdGNoUGF0dGVybiA9IGZ1bmN0aW9uKGNvdW50ZXIsIGNvZGUpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgZXJyb3IgPSAwLFxuICAgICAgICBzaW5nbGVFcnJvciA9IDAsXG4gICAgICAgIG1vZHVsbyA9IHRoaXMuTU9EVUxPLFxuICAgICAgICBtYXhTaW5nbGVFcnJvciA9IHRoaXMuU0lOR0xFX0NPREVfRVJST1IgfHwgMTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHNpbmdsZUVycm9yID0gTWF0aC5hYnMoY29kZVtpXSAtIGNvdW50ZXJbaV0pO1xuICAgICAgICBpZiAoc2luZ2xlRXJyb3IgPiBtYXhTaW5nbGVFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIE51bWJlci5NQVhfVkFMVUU7XG4gICAgICAgIH1cbiAgICAgICAgZXJyb3IgKz0gc2luZ2xlRXJyb3I7XG4gICAgfVxuICAgIHJldHVybiBlcnJvciAvIG1vZHVsbztcbn07XG5cbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl9uZXh0U2V0ID0gZnVuY3Rpb24obGluZSwgb2Zmc2V0KSB7XG4gICAgdmFyIGk7XG5cbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChsaW5lW2ldKSB7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGluZS5sZW5ndGg7XG59O1xuXG5CYXJjb2RlUmVhZGVyLnByb3RvdHlwZS5fbm9ybWFsaXplID0gZnVuY3Rpb24oY291bnRlciwgbW9kdWxvKSB7XG4gICAgdmFyIGksXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICBzdW0gPSAwLFxuICAgICAgICByYXRpbyxcbiAgICAgICAgbnVtT25lcyA9IDAsXG4gICAgICAgIG5vcm1hbGl6ZWQgPSBbXSxcbiAgICAgICAgbm9ybSA9IDA7XG5cbiAgICBpZiAoIW1vZHVsbykge1xuICAgICAgICBtb2R1bG8gPSBzZWxmLk1PRFVMTztcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGNvdW50ZXJbaV0gPT09IDEpIHtcbiAgICAgICAgICAgIG51bU9uZXMrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1bSArPSBjb3VudGVyW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJhdGlvID0gc3VtIC8gKG1vZHVsbyAtIG51bU9uZXMpO1xuICAgIGlmIChyYXRpbyA+IDEuMCkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnRlci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbm9ybSA9IGNvdW50ZXJbaV0gPT09IDEgPyBjb3VudGVyW2ldIDogY291bnRlcltpXSAvIHJhdGlvO1xuICAgICAgICAgICAgbm9ybWFsaXplZC5wdXNoKG5vcm0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmF0aW8gPSAoc3VtICsgbnVtT25lcykgLyBtb2R1bG87XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBub3JtID0gY291bnRlcltpXSAvIHJhdGlvO1xuICAgICAgICAgICAgbm9ybWFsaXplZC5wdXNoKG5vcm0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBub3JtYWxpemVkO1xufTtcblxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX21hdGNoVHJhY2UgPSBmdW5jdGlvbihjbXBDb3VudGVyLCBlcHNpbG9uKSB7XG4gICAgdmFyIGNvdW50ZXIgPSBbXSxcbiAgICAgICAgaSxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIG9mZnNldCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93KSxcbiAgICAgICAgaXNXaGl0ZSA9ICFzZWxmLl9yb3dbb2Zmc2V0XSxcbiAgICAgICAgY291bnRlclBvcyA9IDAsXG4gICAgICAgIGJlc3RNYXRjaCA9IHtcbiAgICAgICAgICAgIGVycm9yOiBOdW1iZXIuTUFYX1ZBTFVFLFxuICAgICAgICAgICAgY29kZTogLTEsXG4gICAgICAgICAgICBzdGFydDogMFxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjtcblxuICAgIGlmIChjbXBDb3VudGVyKSB7XG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgY21wQ291bnRlci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY291bnRlci5wdXNoKDApO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoIGkgPSBvZmZzZXQ7IGkgPCBzZWxmLl9yb3cubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XG4gICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSsrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gY291bnRlci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gc2VsZi5fbWF0Y2hQYXR0ZXJuKGNvdW50ZXIsIGNtcENvdW50ZXIpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IGVwc2lsb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5zdGFydCA9IGkgLSBvZmZzZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZW5kID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5jb3VudGVyID0gY291bnRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiZXN0TWF0Y2g7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSA9IDE7XG4gICAgICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY291bnRlci5wdXNoKDApO1xuICAgICAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5fcm93W2ldIF4gaXNXaGl0ZSkge1xuICAgICAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10rKztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY291bnRlclBvcysrO1xuICAgICAgICAgICAgICAgIGNvdW50ZXIucHVzaCgwKTtcbiAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcbiAgICAgICAgICAgICAgICBpc1doaXRlID0gIWlzV2hpdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiBjbXBDb3VudGVyIHdhcyBub3QgZ2l2ZW5cbiAgICBiZXN0TWF0Y2guc3RhcnQgPSBvZmZzZXQ7XG4gICAgYmVzdE1hdGNoLmVuZCA9IHNlbGYuX3Jvdy5sZW5ndGggLSAxO1xuICAgIGJlc3RNYXRjaC5jb3VudGVyID0gY291bnRlcjtcbiAgICByZXR1cm4gYmVzdE1hdGNoO1xufTtcblxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuZGVjb2RlUGF0dGVybiA9IGZ1bmN0aW9uKHBhdHRlcm4pIHtcbiAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgIHJlc3VsdDtcblxuICAgIHNlbGYuX3JvdyA9IHBhdHRlcm47XG4gICAgcmVzdWx0ID0gc2VsZi5fZGVjb2RlKCk7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICBzZWxmLl9yb3cucmV2ZXJzZSgpO1xuICAgICAgICByZXN1bHQgPSBzZWxmLl9kZWNvZGUoKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgcmVzdWx0LmRpcmVjdGlvbiA9IEJhcmNvZGVSZWFkZXIuRElSRUNUSU9OLlJFVkVSU0U7XG4gICAgICAgICAgICByZXN1bHQuc3RhcnQgPSBzZWxmLl9yb3cubGVuZ3RoIC0gcmVzdWx0LnN0YXJ0O1xuICAgICAgICAgICAgcmVzdWx0LmVuZCA9IHNlbGYuX3Jvdy5sZW5ndGggLSByZXN1bHQuZW5kO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LmRpcmVjdGlvbiA9IEJhcmNvZGVSZWFkZXIuRElSRUNUSU9OLkZPUldBUkQ7XG4gICAgfVxuICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgcmVzdWx0LmZvcm1hdCA9IHNlbGYuRk9STUFUO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX21hdGNoUmFuZ2UgPSBmdW5jdGlvbihzdGFydCwgZW5kLCB2YWx1ZSkge1xuICAgIHZhciBpO1xuXG4gICAgc3RhcnQgPSBzdGFydCA8IDAgPyAwIDogc3RhcnQ7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5fcm93W2ldICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX2ZpbGxDb3VudGVycyA9IGZ1bmN0aW9uKG9mZnNldCwgZW5kLCBpc1doaXRlKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBjb3VudGVyUG9zID0gMCxcbiAgICAgICAgaSxcbiAgICAgICAgY291bnRlcnMgPSBbXTtcblxuICAgIGlzV2hpdGUgPSAodHlwZW9mIGlzV2hpdGUgIT09ICd1bmRlZmluZWQnKSA/IGlzV2hpdGUgOiB0cnVlO1xuICAgIG9mZnNldCA9ICh0eXBlb2Ygb2Zmc2V0ICE9PSAndW5kZWZpbmVkJykgPyBvZmZzZXQgOiBzZWxmLl9uZXh0VW5zZXQoc2VsZi5fcm93KTtcbiAgICBlbmQgPSBlbmQgfHwgc2VsZi5fcm93Lmxlbmd0aDtcblxuICAgIGNvdW50ZXJzW2NvdW50ZXJQb3NdID0gMDtcbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICBpZiAoc2VsZi5fcm93W2ldIF4gaXNXaGl0ZSkge1xuICAgICAgICAgICAgY291bnRlcnNbY291bnRlclBvc10rKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcbiAgICAgICAgICAgIGNvdW50ZXJzW2NvdW50ZXJQb3NdID0gMTtcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY291bnRlcnM7XG59O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQmFyY29kZVJlYWRlci5wcm90b3R5cGUsIFwiRk9STUFUXCIsIHtcbiAgICB2YWx1ZTogJ3Vua25vd24nLFxuICAgIHdyaXRlYWJsZTogZmFsc2Vcbn0pO1xuXG5CYXJjb2RlUmVhZGVyLkRJUkVDVElPTiA9IHtcbiAgICBGT1JXQVJEOiAxLFxuICAgIFJFVkVSU0U6IC0xXG59O1xuXG5CYXJjb2RlUmVhZGVyLkV4Y2VwdGlvbiA9IHtcbiAgICBTdGFydE5vdEZvdW5kRXhjZXB0aW9uOiBcIlN0YXJ0LUluZm8gd2FzIG5vdCBmb3VuZCFcIixcbiAgICBDb2RlTm90Rm91bmRFeGNlcHRpb246IFwiQ29kZSBjb3VsZCBub3QgYmUgZm91bmQhXCIsXG4gICAgUGF0dGVybk5vdEZvdW5kRXhjZXB0aW9uOiBcIlBhdHRlcm4gY291bGQgbm90IGJlIGZvdW5kIVwiXG59O1xuXG5CYXJjb2RlUmVhZGVyLkNPTkZJR19LRVlTID0ge307XG5cbmV4cG9ydCBkZWZhdWx0IEJhcmNvZGVSZWFkZXI7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9iYXJjb2RlX3JlYWRlci5qc1xuICoqLyIsImltcG9ydCBCYXJjb2RlUmVhZGVyIGZyb20gJy4vYmFyY29kZV9yZWFkZXInO1xuXG5mdW5jdGlvbiBFQU5SZWFkZXIob3B0cykge1xuICAgIEJhcmNvZGVSZWFkZXIuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxudmFyIHByb3BlcnRpZXMgPSB7XG4gICAgQ09ERV9MX1NUQVJUOiB7dmFsdWU6IDB9LFxuICAgIE1PRFVMTzoge3ZhbHVlOiA3fSxcbiAgICBDT0RFX0dfU1RBUlQ6IHt2YWx1ZTogMTB9LFxuICAgIFNUQVJUX1BBVFRFUk46IHt2YWx1ZTogWzEgLyAzICogNywgMSAvIDMgKiA3LCAxIC8gMyAqIDddfSxcbiAgICBTVE9QX1BBVFRFUk46IHt2YWx1ZTogWzEgLyAzICogNywgMSAvIDMgKiA3LCAxIC8gMyAqIDddfSxcbiAgICBNSURETEVfUEFUVEVSTjoge3ZhbHVlOiBbMSAvIDUgKiA3LCAxIC8gNSAqIDcsIDEgLyA1ICogNywgMSAvIDUgKiA3LCAxIC8gNSAqIDddfSxcbiAgICBDT0RFX1BBVFRFUk46IHt2YWx1ZTogW1xuICAgICAgICBbMywgMiwgMSwgMV0sXG4gICAgICAgIFsyLCAyLCAyLCAxXSxcbiAgICAgICAgWzIsIDEsIDIsIDJdLFxuICAgICAgICBbMSwgNCwgMSwgMV0sXG4gICAgICAgIFsxLCAxLCAzLCAyXSxcbiAgICAgICAgWzEsIDIsIDMsIDFdLFxuICAgICAgICBbMSwgMSwgMSwgNF0sXG4gICAgICAgIFsxLCAzLCAxLCAyXSxcbiAgICAgICAgWzEsIDIsIDEsIDNdLFxuICAgICAgICBbMywgMSwgMSwgMl0sXG4gICAgICAgIFsxLCAxLCAyLCAzXSxcbiAgICAgICAgWzEsIDIsIDIsIDJdLFxuICAgICAgICBbMiwgMiwgMSwgMl0sXG4gICAgICAgIFsxLCAxLCA0LCAxXSxcbiAgICAgICAgWzIsIDMsIDEsIDFdLFxuICAgICAgICBbMSwgMywgMiwgMV0sXG4gICAgICAgIFs0LCAxLCAxLCAxXSxcbiAgICAgICAgWzIsIDEsIDMsIDFdLFxuICAgICAgICBbMywgMSwgMiwgMV0sXG4gICAgICAgIFsyLCAxLCAxLCAzXVxuICAgIF19LFxuICAgIENPREVfRlJFUVVFTkNZOiB7dmFsdWU6IFswLCAxMSwgMTMsIDE0LCAxOSwgMjUsIDI4LCAyMSwgMjIsIDI2XX0sXG4gICAgU0lOR0xFX0NPREVfRVJST1I6IHt2YWx1ZTogMC42N30sXG4gICAgQVZHX0NPREVfRVJST1I6IHt2YWx1ZTogMC4yN30sXG4gICAgRk9STUFUOiB7dmFsdWU6IFwiZWFuXzEzXCIsIHdyaXRlYWJsZTogZmFsc2V9XG59O1xuXG5FQU5SZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCYXJjb2RlUmVhZGVyLnByb3RvdHlwZSwgcHJvcGVydGllcyk7XG5FQU5SZWFkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRUFOUmVhZGVyO1xuXG5FQU5SZWFkZXIucHJvdG90eXBlLl9kZWNvZGVDb2RlID0gZnVuY3Rpb24oc3RhcnQsIGNvZGVyYW5nZSkge1xuICAgIHZhciBjb3VudGVyID0gWzAsIDAsIDAsIDBdLFxuICAgICAgICBpLFxuICAgICAgICBzZWxmID0gdGhpcyxcbiAgICAgICAgb2Zmc2V0ID0gc3RhcnQsXG4gICAgICAgIGlzV2hpdGUgPSAhc2VsZi5fcm93W29mZnNldF0sXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwLFxuICAgICAgICBiZXN0TWF0Y2ggPSB7XG4gICAgICAgICAgICBlcnJvcjogTnVtYmVyLk1BWF9WQUxVRSxcbiAgICAgICAgICAgIGNvZGU6IC0xLFxuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBzdGFydFxuICAgICAgICB9LFxuICAgICAgICBjb2RlLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbm9ybWFsaXplZDtcblxuICAgIGlmICghY29kZXJhbmdlKSB7XG4gICAgICAgIGNvZGVyYW5nZSA9IHNlbGYuQ09ERV9QQVRURVJOLmxlbmd0aDtcbiAgICB9XG5cbiAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gY291bnRlci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IHNlbGYuX25vcm1hbGl6ZShjb3VudGVyKTtcbiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZCkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgY29kZXJhbmdlOyBjb2RlKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gc2VsZi5fbWF0Y2hQYXR0ZXJuKG5vcm1hbGl6ZWQsIHNlbGYuQ09ERV9QQVRURVJOW2NvZGVdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IGJlc3RNYXRjaC5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5jb2RlID0gY29kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZW5kID0gaTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJlc3RNYXRjaC5lcnJvciA+IHNlbGYuQVZHX0NPREVfRVJST1IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBiZXN0TWF0Y2g7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbkVBTlJlYWRlci5wcm90b3R5cGUuX2ZpbmRQYXR0ZXJuID0gZnVuY3Rpb24ocGF0dGVybiwgb2Zmc2V0LCBpc1doaXRlLCB0cnlIYXJkZXIsIGVwc2lsb24pIHtcbiAgICB2YXIgY291bnRlciA9IFtdLFxuICAgICAgICBzZWxmID0gdGhpcyxcbiAgICAgICAgaSxcbiAgICAgICAgY291bnRlclBvcyA9IDAsXG4gICAgICAgIGJlc3RNYXRjaCA9IHtcbiAgICAgICAgICAgIGVycm9yOiBOdW1iZXIuTUFYX1ZBTFVFLFxuICAgICAgICAgICAgY29kZTogLTEsXG4gICAgICAgICAgICBzdGFydDogMCxcbiAgICAgICAgICAgIGVuZDogMFxuICAgICAgICB9LFxuICAgICAgICBlcnJvcixcbiAgICAgICAgaixcbiAgICAgICAgc3VtLFxuICAgICAgICBub3JtYWxpemVkO1xuXG4gICAgaWYgKCFvZmZzZXQpIHtcbiAgICAgICAgb2Zmc2V0ID0gc2VsZi5fbmV4dFNldChzZWxmLl9yb3cpO1xuICAgIH1cblxuICAgIGlmIChpc1doaXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaXNXaGl0ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0cnlIYXJkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0cnlIYXJkZXIgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICggZXBzaWxvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVwc2lsb24gPSBzZWxmLkFWR19DT0RFX0VSUk9SO1xuICAgIH1cblxuICAgIGZvciAoIGkgPSAwOyBpIDwgcGF0dGVybi5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb3VudGVyW2ldID0gMDtcbiAgICB9XG5cbiAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gY291bnRlci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgc3VtID0gMDtcbiAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgc3VtICs9IGNvdW50ZXJbal07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlcik7XG4gICAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBzZWxmLl9tYXRjaFBhdHRlcm4obm9ybWFsaXplZCwgcGF0dGVybik7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIDwgZXBzaWxvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guc3RhcnQgPSBpIC0gc3VtO1xuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVuZCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmVzdE1hdGNoO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0cnlIYXJkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yICggaiA9IDA7IGogPCBjb3VudGVyLmxlbmd0aCAtIDI7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcltqXSA9IGNvdW50ZXJbaiArIDJdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbY291bnRlci5sZW5ndGggLSAyXSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbY291bnRlci5sZW5ndGggLSAxXSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MtLTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10gPSAxO1xuICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuRUFOUmVhZGVyLnByb3RvdHlwZS5fZmluZFN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBsZWFkaW5nV2hpdGVzcGFjZVN0YXJ0LFxuICAgICAgICBvZmZzZXQgPSBzZWxmLl9uZXh0U2V0KHNlbGYuX3JvdyksXG4gICAgICAgIHN0YXJ0SW5mbztcblxuICAgIHdoaWxlICghc3RhcnRJbmZvKSB7XG4gICAgICAgIHN0YXJ0SW5mbyA9IHNlbGYuX2ZpbmRQYXR0ZXJuKHNlbGYuU1RBUlRfUEFUVEVSTiwgb2Zmc2V0KTtcbiAgICAgICAgaWYgKCFzdGFydEluZm8pIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxlYWRpbmdXaGl0ZXNwYWNlU3RhcnQgPSBzdGFydEluZm8uc3RhcnQgLSAoc3RhcnRJbmZvLmVuZCAtIHN0YXJ0SW5mby5zdGFydCk7XG4gICAgICAgIGlmIChsZWFkaW5nV2hpdGVzcGFjZVN0YXJ0ID49IDApIHtcbiAgICAgICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGxlYWRpbmdXaGl0ZXNwYWNlU3RhcnQsIHN0YXJ0SW5mby5zdGFydCwgMCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnRJbmZvO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG9mZnNldCA9IHN0YXJ0SW5mby5lbmQ7XG4gICAgICAgIHN0YXJ0SW5mbyA9IG51bGw7XG4gICAgfVxufTtcblxuRUFOUmVhZGVyLnByb3RvdHlwZS5fdmVyaWZ5VHJhaWxpbmdXaGl0ZXNwYWNlID0gZnVuY3Rpb24oZW5kSW5mbykge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kO1xuXG4gICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kID0gZW5kSW5mby5lbmQgKyAoZW5kSW5mby5lbmQgLSBlbmRJbmZvLnN0YXJ0KTtcbiAgICBpZiAodHJhaWxpbmdXaGl0ZXNwYWNlRW5kIDwgc2VsZi5fcm93Lmxlbmd0aCkge1xuICAgICAgICBpZiAoc2VsZi5fbWF0Y2hSYW5nZShlbmRJbmZvLmVuZCwgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kLCAwKSkge1xuICAgICAgICAgICAgcmV0dXJuIGVuZEluZm87XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuXG5FQU5SZWFkZXIucHJvdG90eXBlLl9maW5kRW5kID0gZnVuY3Rpb24ob2Zmc2V0LCBpc1doaXRlKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBlbmRJbmZvID0gc2VsZi5fZmluZFBhdHRlcm4oc2VsZi5TVE9QX1BBVFRFUk4sIG9mZnNldCwgaXNXaGl0ZSwgZmFsc2UpO1xuXG4gICAgcmV0dXJuIGVuZEluZm8gIT09IG51bGwgPyBzZWxmLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UoZW5kSW5mbykgOiBudWxsO1xufTtcblxuRUFOUmVhZGVyLnByb3RvdHlwZS5fY2FsY3VsYXRlRmlyc3REaWdpdCA9IGZ1bmN0aW9uKGNvZGVGcmVxdWVuY3kpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgc2VsZiA9IHRoaXM7XG5cbiAgICBmb3IgKCBpID0gMDsgaSA8IHNlbGYuQ09ERV9GUkVRVUVOQ1kubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGNvZGVGcmVxdWVuY3kgPT09IHNlbGYuQ09ERV9GUkVRVUVOQ1lbaV0pIHtcbiAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuRUFOUmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlUGF5bG9hZCA9IGZ1bmN0aW9uKGNvZGUsIHJlc3VsdCwgZGVjb2RlZENvZGVzKSB7XG4gICAgdmFyIGksXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICBjb2RlRnJlcXVlbmN5ID0gMHgwLFxuICAgICAgICBmaXJzdERpZ2l0O1xuXG4gICAgZm9yICggaSA9IDA7IGkgPCA2OyBpKyspIHtcbiAgICAgICAgY29kZSA9IHNlbGYuX2RlY29kZUNvZGUoY29kZS5lbmQpO1xuICAgICAgICBpZiAoIWNvZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2RlLmNvZGUgPj0gc2VsZi5DT0RFX0dfU1RBUlQpIHtcbiAgICAgICAgICAgIGNvZGUuY29kZSA9IGNvZGUuY29kZSAtIHNlbGYuQ09ERV9HX1NUQVJUO1xuICAgICAgICAgICAgY29kZUZyZXF1ZW5jeSB8PSAxIDw8ICg1IC0gaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb2RlRnJlcXVlbmN5IHw9IDAgPDwgKDUgLSBpKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucHVzaChjb2RlLmNvZGUpO1xuICAgICAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcbiAgICB9XG5cbiAgICBmaXJzdERpZ2l0ID0gc2VsZi5fY2FsY3VsYXRlRmlyc3REaWdpdChjb2RlRnJlcXVlbmN5KTtcbiAgICBpZiAoZmlyc3REaWdpdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmVzdWx0LnVuc2hpZnQoZmlyc3REaWdpdCk7XG5cbiAgICBjb2RlID0gc2VsZi5fZmluZFBhdHRlcm4oc2VsZi5NSURETEVfUEFUVEVSTiwgY29kZS5lbmQsIHRydWUsIGZhbHNlKTtcbiAgICBpZiAoY29kZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZGVjb2RlZENvZGVzLnB1c2goY29kZSk7XG5cbiAgICBmb3IgKCBpID0gMDsgaSA8IDY7IGkrKykge1xuICAgICAgICBjb2RlID0gc2VsZi5fZGVjb2RlQ29kZShjb2RlLmVuZCwgc2VsZi5DT0RFX0dfU1RBUlQpO1xuICAgICAgICBpZiAoIWNvZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xuICAgICAgICByZXN1bHQucHVzaChjb2RlLmNvZGUpO1xuICAgIH1cblxuICAgIHJldHVybiBjb2RlO1xufTtcblxuRUFOUmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN0YXJ0SW5mbyxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIGNvZGUsXG4gICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICBkZWNvZGVkQ29kZXMgPSBbXTtcblxuICAgIHN0YXJ0SW5mbyA9IHNlbGYuX2ZpbmRTdGFydCgpO1xuICAgIGlmICghc3RhcnRJbmZvKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb2RlID0ge1xuICAgICAgICBjb2RlOiBzdGFydEluZm8uY29kZSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0SW5mby5zdGFydCxcbiAgICAgICAgZW5kOiBzdGFydEluZm8uZW5kXG4gICAgfTtcbiAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcbiAgICBjb2RlID0gc2VsZi5fZGVjb2RlUGF5bG9hZChjb2RlLCByZXN1bHQsIGRlY29kZWRDb2Rlcyk7XG4gICAgaWYgKCFjb2RlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb2RlID0gc2VsZi5fZmluZEVuZChjb2RlLmVuZCwgZmFsc2UpO1xuICAgIGlmICghY29kZSl7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xuXG4gICAgLy8gQ2hlY2tzdW1cbiAgICBpZiAoIXNlbGYuX2NoZWNrc3VtKHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXG4gICAgICAgIHN0YXJ0OiBzdGFydEluZm8uc3RhcnQsXG4gICAgICAgIGVuZDogY29kZS5lbmQsXG4gICAgICAgIGNvZGVzZXQ6IFwiXCIsXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnRJbmZvLFxuICAgICAgICBkZWNvZGVkQ29kZXM6IGRlY29kZWRDb2Rlc1xuICAgIH07XG59O1xuXG5FQU5SZWFkZXIucHJvdG90eXBlLl9jaGVja3N1bSA9IGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgIHZhciBzdW0gPSAwLCBpO1xuXG4gICAgZm9yICggaSA9IHJlc3VsdC5sZW5ndGggLSAyOyBpID49IDA7IGkgLT0gMikge1xuICAgICAgICBzdW0gKz0gcmVzdWx0W2ldO1xuICAgIH1cbiAgICBzdW0gKj0gMztcbiAgICBmb3IgKCBpID0gcmVzdWx0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAyKSB7XG4gICAgICAgIHN1bSArPSByZXN1bHRbaV07XG4gICAgfVxuICAgIHJldHVybiBzdW0gJSAxMCA9PT0gMDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IChFQU5SZWFkZXIpO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvZWFuX3JlYWRlci5qc1xuICoqLyIsImltcG9ydCBCYXJjb2RlUmVhZGVyIGZyb20gJy4vYmFyY29kZV9yZWFkZXInO1xuaW1wb3J0IEFycmF5SGVscGVyIGZyb20gJy4vYXJyYXlfaGVscGVyJztcblxuZnVuY3Rpb24gQ29kZTM5UmVhZGVyKCkge1xuICAgIEJhcmNvZGVSZWFkZXIuY2FsbCh0aGlzKTtcbn1cblxudmFyIHByb3BlcnRpZXMgPSB7XG4gICAgQUxQSEFCRVRIX1NUUklORzoge3ZhbHVlOiBcIjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWi0uICokLyslXCJ9LFxuICAgIEFMUEhBQkVUOiB7dmFsdWU6IFs0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LFxuICAgICAgICA3OSwgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA0NSwgNDYsIDMyLCA0MiwgMzYsIDQ3LCA0MywgMzddfSxcbiAgICBDSEFSQUNURVJfRU5DT0RJTkdTOiB7dmFsdWU6IFsweDAzNCwgMHgxMjEsIDB4MDYxLCAweDE2MCwgMHgwMzEsIDB4MTMwLCAweDA3MCwgMHgwMjUsIDB4MTI0LCAweDA2NCwgMHgxMDksIDB4MDQ5LFxuICAgICAgICAweDE0OCwgMHgwMTksIDB4MTE4LCAweDA1OCwgMHgwMEQsIDB4MTBDLCAweDA0QywgMHgwMUMsIDB4MTAzLCAweDA0MywgMHgxNDIsIDB4MDEzLCAweDExMiwgMHgwNTIsIDB4MDA3LCAweDEwNixcbiAgICAgICAgMHgwNDYsIDB4MDE2LCAweDE4MSwgMHgwQzEsIDB4MUMwLCAweDA5MSwgMHgxOTAsIDB4MEQwLCAweDA4NSwgMHgxODQsIDB4MEM0LCAweDA5NCwgMHgwQTgsIDB4MEEyLCAweDA4QSwgMHgwMkFcbiAgICBdfSxcbiAgICBBU1RFUklTSzoge3ZhbHVlOiAweDA5NH0sXG4gICAgRk9STUFUOiB7dmFsdWU6IFwiY29kZV8zOVwiLCB3cml0ZWFibGU6IGZhbHNlfVxufTtcblxuQ29kZTM5UmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQmFyY29kZVJlYWRlci5wcm90b3R5cGUsIHByb3BlcnRpZXMpO1xuQ29kZTM5UmVhZGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IENvZGUzOVJlYWRlcjtcblxuQ29kZTM5UmVhZGVyLnByb3RvdHlwZS5fdG9Db3VudGVycyA9IGZ1bmN0aW9uKHN0YXJ0LCBjb3VudGVyKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBudW1Db3VudGVycyA9IGNvdW50ZXIubGVuZ3RoLFxuICAgICAgICBlbmQgPSBzZWxmLl9yb3cubGVuZ3RoLFxuICAgICAgICBpc1doaXRlID0gIXNlbGYuX3Jvd1tzdGFydF0sXG4gICAgICAgIGksXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwO1xuXG4gICAgQXJyYXlIZWxwZXIuaW5pdChjb3VudGVyLCAwKTtcblxuICAgIGZvciAoIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb3VudGVyUG9zKys7XG4gICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gbnVtQ291bnRlcnMpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSA9IDE7XG4gICAgICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdW50ZXI7XG59O1xuXG5Db2RlMzlSZWFkZXIucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgIGNvdW50ZXJzID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdLFxuICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgc3RhcnQgPSBzZWxmLl9maW5kU3RhcnQoKSxcbiAgICAgICAgZGVjb2RlZENoYXIsXG4gICAgICAgIGxhc3RTdGFydCxcbiAgICAgICAgcGF0dGVybixcbiAgICAgICAgbmV4dFN0YXJ0O1xuXG4gICAgaWYgKCFzdGFydCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgbmV4dFN0YXJ0ID0gc2VsZi5fbmV4dFNldChzZWxmLl9yb3csIHN0YXJ0LmVuZCk7XG5cbiAgICBkbyB7XG4gICAgICAgIGNvdW50ZXJzID0gc2VsZi5fdG9Db3VudGVycyhuZXh0U3RhcnQsIGNvdW50ZXJzKTtcbiAgICAgICAgcGF0dGVybiA9IHNlbGYuX3RvUGF0dGVybihjb3VudGVycyk7XG4gICAgICAgIGlmIChwYXR0ZXJuIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZGVjb2RlZENoYXIgPSBzZWxmLl9wYXR0ZXJuVG9DaGFyKHBhdHRlcm4pO1xuICAgICAgICBpZiAoZGVjb2RlZENoYXIgPCAwKXtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKGRlY29kZWRDaGFyKTtcbiAgICAgICAgbGFzdFN0YXJ0ID0gbmV4dFN0YXJ0O1xuICAgICAgICBuZXh0U3RhcnQgKz0gQXJyYXlIZWxwZXIuc3VtKGNvdW50ZXJzKTtcbiAgICAgICAgbmV4dFN0YXJ0ID0gc2VsZi5fbmV4dFNldChzZWxmLl9yb3csIG5leHRTdGFydCk7XG4gICAgfSB3aGlsZSAoZGVjb2RlZENoYXIgIT09ICcqJyk7XG4gICAgcmVzdWx0LnBvcCgpO1xuXG4gICAgaWYgKCFyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICghc2VsZi5fdmVyaWZ5VHJhaWxpbmdXaGl0ZXNwYWNlKGxhc3RTdGFydCwgbmV4dFN0YXJ0LCBjb3VudGVycykpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXG4gICAgICAgIHN0YXJ0OiBzdGFydC5zdGFydCxcbiAgICAgICAgZW5kOiBuZXh0U3RhcnQsXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnQsXG4gICAgICAgIGRlY29kZWRDb2RlczogcmVzdWx0XG4gICAgfTtcbn07XG5cbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuX3ZlcmlmeVRyYWlsaW5nV2hpdGVzcGFjZSA9IGZ1bmN0aW9uKGxhc3RTdGFydCwgbmV4dFN0YXJ0LCBjb3VudGVycykge1xuICAgIHZhciB0cmFpbGluZ1doaXRlc3BhY2VFbmQsXG4gICAgICAgIHBhdHRlcm5TaXplID0gQXJyYXlIZWxwZXIuc3VtKGNvdW50ZXJzKTtcblxuICAgIHRyYWlsaW5nV2hpdGVzcGFjZUVuZCA9IG5leHRTdGFydCAtIGxhc3RTdGFydCAtIHBhdHRlcm5TaXplO1xuICAgIGlmICgodHJhaWxpbmdXaGl0ZXNwYWNlRW5kICogMykgPj0gcGF0dGVyblNpemUpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuX3BhdHRlcm5Ub0NoYXIgPSBmdW5jdGlvbihwYXR0ZXJuKSB7XG4gICAgdmFyIGksXG4gICAgICAgIHNlbGYgPSB0aGlzO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHNlbGYuQ0hBUkFDVEVSX0VOQ09ESU5HUy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc2VsZi5DSEFSQUNURVJfRU5DT0RJTkdTW2ldID09PSBwYXR0ZXJuKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShzZWxmLkFMUEhBQkVUW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59O1xuXG5Db2RlMzlSZWFkZXIucHJvdG90eXBlLl9maW5kTmV4dFdpZHRoID0gZnVuY3Rpb24oY291bnRlcnMsIGN1cnJlbnQpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgbWluV2lkdGggPSBOdW1iZXIuTUFYX1ZBTFVFO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChjb3VudGVyc1tpXSA8IG1pbldpZHRoICYmIGNvdW50ZXJzW2ldID4gY3VycmVudCkge1xuICAgICAgICAgICAgbWluV2lkdGggPSBjb3VudGVyc1tpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtaW5XaWR0aDtcbn07XG5cbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuX3RvUGF0dGVybiA9IGZ1bmN0aW9uKGNvdW50ZXJzKSB7XG4gICAgdmFyIG51bUNvdW50ZXJzID0gY291bnRlcnMubGVuZ3RoLFxuICAgICAgICBtYXhOYXJyb3dXaWR0aCA9IDAsXG4gICAgICAgIG51bVdpZGVCYXJzID0gbnVtQ291bnRlcnMsXG4gICAgICAgIHdpZGVCYXJXaWR0aCA9IDAsXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICBwYXR0ZXJuLFxuICAgICAgICBpO1xuXG4gICAgd2hpbGUgKG51bVdpZGVCYXJzID4gMykge1xuICAgICAgICBtYXhOYXJyb3dXaWR0aCA9IHNlbGYuX2ZpbmROZXh0V2lkdGgoY291bnRlcnMsIG1heE5hcnJvd1dpZHRoKTtcbiAgICAgICAgbnVtV2lkZUJhcnMgPSAwO1xuICAgICAgICBwYXR0ZXJuID0gMDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bUNvdW50ZXJzOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChjb3VudGVyc1tpXSA+IG1heE5hcnJvd1dpZHRoKSB7XG4gICAgICAgICAgICAgICAgcGF0dGVybiB8PSAxIDw8IChudW1Db3VudGVycyAtIDEgLSBpKTtcbiAgICAgICAgICAgICAgICBudW1XaWRlQmFycysrO1xuICAgICAgICAgICAgICAgIHdpZGVCYXJXaWR0aCArPSBjb3VudGVyc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChudW1XaWRlQmFycyA9PT0gMykge1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bUNvdW50ZXJzICYmIG51bVdpZGVCYXJzID4gMDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvdW50ZXJzW2ldID4gbWF4TmFycm93V2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbnVtV2lkZUJhcnMtLTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChjb3VudGVyc1tpXSAqIDIpID49IHdpZGVCYXJXaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHBhdHRlcm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufTtcblxuQ29kZTM5UmVhZGVyLnByb3RvdHlwZS5fZmluZFN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBvZmZzZXQgPSBzZWxmLl9uZXh0U2V0KHNlbGYuX3JvdyksXG4gICAgICAgIHBhdHRlcm5TdGFydCA9IG9mZnNldCxcbiAgICAgICAgY291bnRlciA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXSxcbiAgICAgICAgY291bnRlclBvcyA9IDAsXG4gICAgICAgIGlzV2hpdGUgPSBmYWxzZSxcbiAgICAgICAgaSxcbiAgICAgICAgaixcbiAgICAgICAgd2hpdGVTcGFjZU11c3RTdGFydDtcblxuICAgIGZvciAoIGkgPSBvZmZzZXQ7IGkgPCBzZWxmLl9yb3cubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHNlbGYuX3Jvd1tpXSBeIGlzV2hpdGUpIHtcbiAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10rKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb3VudGVyUG9zID09PSBjb3VudGVyLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAvLyBmaW5kIHN0YXJ0IHBhdHRlcm5cbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5fdG9QYXR0ZXJuKGNvdW50ZXIpID09PSBzZWxmLkFTVEVSSVNLKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoaXRlU3BhY2VNdXN0U3RhcnQgPSBNYXRoLmZsb29yKE1hdGgubWF4KDAsIHBhdHRlcm5TdGFydCAtICgoaSAtIHBhdHRlcm5TdGFydCkgLyA0KSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5fbWF0Y2hSYW5nZSh3aGl0ZVNwYWNlTXVzdFN0YXJ0LCBwYXR0ZXJuU3RhcnQsIDApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBwYXR0ZXJuU3RhcnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBpXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGF0dGVyblN0YXJ0ICs9IGNvdW50ZXJbMF0gKyBjb3VudGVyWzFdO1xuICAgICAgICAgICAgICAgIGZvciAoIGogPSAwOyBqIDwgNzsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbal0gPSBjb3VudGVyW2ogKyAyXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY291bnRlcls3XSA9IDA7XG4gICAgICAgICAgICAgICAgY291bnRlcls4XSA9IDA7XG4gICAgICAgICAgICAgICAgY291bnRlclBvcy0tO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IENvZGUzOVJlYWRlcjtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2NvZGVfMzlfcmVhZGVyLmpzXG4gKiovIiwiaW1wb3J0IENvZGUzOVJlYWRlciBmcm9tICcuL2NvZGVfMzlfcmVhZGVyJztcblxuZnVuY3Rpb24gQ29kZTM5VklOUmVhZGVyKCkge1xuICAgIENvZGUzOVJlYWRlci5jYWxsKHRoaXMpO1xufVxuXG52YXIgcGF0dGVybnMgPSB7XG4gICAgSU9ROiAvW0lPUV0vZyxcbiAgICBBWjA5OiAvW0EtWjAtOV17MTd9L1xufTtcblxuQ29kZTM5VklOUmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29kZTM5UmVhZGVyLnByb3RvdHlwZSk7XG5Db2RlMzlWSU5SZWFkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ29kZTM5VklOUmVhZGVyO1xuXG4vLyBDcmliYmVkIGZyb206XG4vLyBodHRwczovL2dpdGh1Yi5jb20venhpbmcvenhpbmcvYmxvYi9tYXN0ZXIvY29yZS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvenhpbmcvY2xpZW50L3Jlc3VsdC9WSU5SZXN1bHRQYXJzZXIuamF2YVxuQ29kZTM5VklOUmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdCA9IENvZGUzOVJlYWRlci5wcm90b3R5cGUuX2RlY29kZS5hcHBseSh0aGlzKTtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgY29kZSA9IHJlc3VsdC5jb2RlO1xuXG4gICAgaWYgKCFjb2RlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UocGF0dGVybnMuSU9RLCAnJyk7XG5cbiAgICBpZiAoIWNvZGUubWF0Y2gocGF0dGVybnMuQVowOSkpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ0ZhaWxlZCBBWjA5IHBhdHRlcm4gY29kZTonLCBjb2RlKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl9jaGVja0NoZWNrc3VtKGNvZGUpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJlc3VsdC5jb2RlID0gY29kZTtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxuQ29kZTM5VklOUmVhZGVyLnByb3RvdHlwZS5fY2hlY2tDaGVja3N1bSA9IGZ1bmN0aW9uKGNvZGUpIHtcbiAgICAvLyBUT0RPXG4gICAgcmV0dXJuICEhY29kZTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IENvZGUzOVZJTlJlYWRlcjtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2NvZGVfMzlfdmluX3JlYWRlci5qc1xuICoqLyIsImltcG9ydCBCYXJjb2RlUmVhZGVyIGZyb20gJy4vYmFyY29kZV9yZWFkZXInO1xuXG5mdW5jdGlvbiBDb2RhYmFyUmVhZGVyKCkge1xuICAgIEJhcmNvZGVSZWFkZXIuY2FsbCh0aGlzKTtcbiAgICB0aGlzLl9jb3VudGVycyA9IFtdO1xufVxuXG52YXIgcHJvcGVydGllcyA9IHtcbiAgICBBTFBIQUJFVEhfU1RSSU5HOiB7dmFsdWU6IFwiMDEyMzQ1Njc4OS0kOi8uK0FCQ0RcIn0sXG4gICAgQUxQSEFCRVQ6IHt2YWx1ZTogWzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA0NSwgMzYsIDU4LCA0NywgNDYsIDQzLCA2NSwgNjYsIDY3LCA2OF19LFxuICAgIENIQVJBQ1RFUl9FTkNPRElOR1M6IHt2YWx1ZTogWzB4MDAzLCAweDAwNiwgMHgwMDksIDB4MDYwLCAweDAxMiwgMHgwNDIsIDB4MDIxLCAweDAyNCwgMHgwMzAsIDB4MDQ4LCAweDAwYywgMHgwMTgsXG4gICAgICAgIDB4MDQ1LCAweDA1MSwgMHgwNTQsIDB4MDE1LCAweDAxQSwgMHgwMjksIDB4MDBCLCAweDAwRV19LFxuICAgIFNUQVJUX0VORDoge3ZhbHVlOiBbMHgwMUEsIDB4MDI5LCAweDAwQiwgMHgwMEVdfSxcbiAgICBNSU5fRU5DT0RFRF9DSEFSUzoge3ZhbHVlOiA0fSxcbiAgICBNQVhfQUNDRVBUQUJMRToge3ZhbHVlOiAyLjB9LFxuICAgIFBBRERJTkc6IHt2YWx1ZTogMS41fSxcbiAgICBGT1JNQVQ6IHt2YWx1ZTogXCJjb2RhYmFyXCIsIHdyaXRlYWJsZTogZmFsc2V9XG59O1xuXG5Db2RhYmFyUmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQmFyY29kZVJlYWRlci5wcm90b3R5cGUsIHByb3BlcnRpZXMpO1xuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb2RhYmFyUmVhZGVyO1xuXG5Db2RhYmFyUmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIGRlY29kZWRDaGFyLFxuICAgICAgICBwYXR0ZXJuLFxuICAgICAgICBuZXh0U3RhcnQsXG4gICAgICAgIGVuZDtcblxuICAgIHRoaXMuX2NvdW50ZXJzID0gc2VsZi5fZmlsbENvdW50ZXJzKCk7XG4gICAgc3RhcnQgPSBzZWxmLl9maW5kU3RhcnQoKTtcbiAgICBpZiAoIXN0YXJ0KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBuZXh0U3RhcnQgPSBzdGFydC5zdGFydENvdW50ZXI7XG5cbiAgICBkbyB7XG4gICAgICAgIHBhdHRlcm4gPSBzZWxmLl90b1BhdHRlcm4obmV4dFN0YXJ0KTtcbiAgICAgICAgaWYgKHBhdHRlcm4gPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkZWNvZGVkQ2hhciA9IHNlbGYuX3BhdHRlcm5Ub0NoYXIocGF0dGVybik7XG4gICAgICAgIGlmIChkZWNvZGVkQ2hhciA8IDApe1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnB1c2goZGVjb2RlZENoYXIpO1xuICAgICAgICBuZXh0U3RhcnQgKz0gODtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPiAxICYmIHNlbGYuX2lzU3RhcnRFbmQocGF0dGVybikpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSB3aGlsZSAobmV4dFN0YXJ0IDwgc2VsZi5fY291bnRlcnMubGVuZ3RoKTtcblxuICAgIC8vIHZlcmlmeSBlbmRcbiAgICBpZiAoKHJlc3VsdC5sZW5ndGggLSAyKSA8IHNlbGYuTUlOX0VOQ09ERURfQ0hBUlMgfHwgIXNlbGYuX2lzU3RhcnRFbmQocGF0dGVybikpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gdmVyaWZ5IGVuZCB3aGl0ZSBzcGFjZVxuICAgIGlmICghc2VsZi5fdmVyaWZ5V2hpdGVzcGFjZShzdGFydC5zdGFydENvdW50ZXIsIG5leHRTdGFydCAtIDgpKXtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFzZWxmLl92YWxpZGF0ZVJlc3VsdChyZXN1bHQsIHN0YXJ0LnN0YXJ0Q291bnRlcikpe1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBuZXh0U3RhcnQgPSBuZXh0U3RhcnQgPiBzZWxmLl9jb3VudGVycy5sZW5ndGggPyBzZWxmLl9jb3VudGVycy5sZW5ndGggOiBuZXh0U3RhcnQ7XG4gICAgZW5kID0gc3RhcnQuc3RhcnQgKyBzZWxmLl9zdW1Db3VudGVycyhzdGFydC5zdGFydENvdW50ZXIsIG5leHRTdGFydCAtIDgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXG4gICAgICAgIHN0YXJ0OiBzdGFydC5zdGFydCxcbiAgICAgICAgZW5kOiBlbmQsXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnQsXG4gICAgICAgIGRlY29kZWRDb2RlczogcmVzdWx0XG4gICAgfTtcbn07XG5cbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlXaGl0ZXNwYWNlID0gZnVuY3Rpb24oc3RhcnRDb3VudGVyLCBlbmRDb3VudGVyKSB7XG4gICAgaWYgKChzdGFydENvdW50ZXIgLSAxIDw9IDApXG4gICAgICAgICAgICB8fCB0aGlzLl9jb3VudGVyc1tzdGFydENvdW50ZXIgLSAxXSA+PSAodGhpcy5fY2FsY3VsYXRlUGF0dGVybkxlbmd0aChzdGFydENvdW50ZXIpIC8gMi4wKSkge1xuICAgICAgICBpZiAoKGVuZENvdW50ZXIgKyA4ID49IHRoaXMuX2NvdW50ZXJzLmxlbmd0aClcbiAgICAgICAgICAgICAgICB8fCB0aGlzLl9jb3VudGVyc1tlbmRDb3VudGVyICsgN10gPj0gKHRoaXMuX2NhbGN1bGF0ZVBhdHRlcm5MZW5ndGgoZW5kQ291bnRlcikgLyAyLjApKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5Db2RhYmFyUmVhZGVyLnByb3RvdHlwZS5fY2FsY3VsYXRlUGF0dGVybkxlbmd0aCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgIHZhciBpLFxuICAgICAgICBzdW0gPSAwO1xuXG4gICAgZm9yIChpID0gb2Zmc2V0OyBpIDwgb2Zmc2V0ICsgNzsgaSsrKSB7XG4gICAgICAgIHN1bSArPSB0aGlzLl9jb3VudGVyc1tpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VtO1xufTtcblxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX3RocmVzaG9sZFJlc3VsdFBhdHRlcm4gPSBmdW5jdGlvbihyZXN1bHQsIHN0YXJ0Q291bnRlcil7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBjYXRlZ29yaXphdGlvbiA9IHtcbiAgICAgICAgICAgIHNwYWNlOiB7XG4gICAgICAgICAgICAgICAgbmFycm93OiB7IHNpemU6IDAsIGNvdW50czogMCwgbWluOiAwLCBtYXg6IE51bWJlci5NQVhfVkFMVUV9LFxuICAgICAgICAgICAgICAgIHdpZGU6IHtzaXplOiAwLCBjb3VudHM6IDAsIG1pbjogMCwgbWF4OiBOdW1iZXIuTUFYX1ZBTFVFfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJhcjoge1xuICAgICAgICAgICAgICAgIG5hcnJvdzogeyBzaXplOiAwLCBjb3VudHM6IDAsIG1pbjogMCwgbWF4OiBOdW1iZXIuTUFYX1ZBTFVFfSxcbiAgICAgICAgICAgICAgICB3aWRlOiB7IHNpemU6IDAsIGNvdW50czogMCwgbWluOiAwLCBtYXg6IE51bWJlci5NQVhfVkFMVUV9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGtpbmQsXG4gICAgICAgIGNhdCxcbiAgICAgICAgaSxcbiAgICAgICAgaixcbiAgICAgICAgcG9zID0gc3RhcnRDb3VudGVyLFxuICAgICAgICBwYXR0ZXJuO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7IGkrKyl7XG4gICAgICAgIHBhdHRlcm4gPSBzZWxmLl9jaGFyVG9QYXR0ZXJuKHJlc3VsdFtpXSk7XG4gICAgICAgIGZvciAoaiA9IDY7IGogPj0gMDsgai0tKSB7XG4gICAgICAgICAgICBraW5kID0gKGogJiAxKSA9PT0gMiA/IGNhdGVnb3JpemF0aW9uLmJhciA6IGNhdGVnb3JpemF0aW9uLnNwYWNlO1xuICAgICAgICAgICAgY2F0ID0gKHBhdHRlcm4gJiAxKSA9PT0gMSA/IGtpbmQud2lkZSA6IGtpbmQubmFycm93O1xuICAgICAgICAgICAgY2F0LnNpemUgKz0gc2VsZi5fY291bnRlcnNbcG9zICsgal07XG4gICAgICAgICAgICBjYXQuY291bnRzKys7XG4gICAgICAgICAgICBwYXR0ZXJuID4+PSAxO1xuICAgICAgICB9XG4gICAgICAgIHBvcyArPSA4O1xuICAgIH1cblxuICAgIFtcInNwYWNlXCIsIFwiYmFyXCJdLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHZhciBuZXdraW5kID0gY2F0ZWdvcml6YXRpb25ba2V5XTtcbiAgICAgICAgbmV3a2luZC53aWRlLm1pbiA9XG4gICAgICAgICAgICBNYXRoLmZsb29yKChuZXdraW5kLm5hcnJvdy5zaXplIC8gbmV3a2luZC5uYXJyb3cuY291bnRzICsgbmV3a2luZC53aWRlLnNpemUgLyBuZXdraW5kLndpZGUuY291bnRzKSAvIDIpO1xuICAgICAgICBuZXdraW5kLm5hcnJvdy5tYXggPSBNYXRoLmNlaWwobmV3a2luZC53aWRlLm1pbik7XG4gICAgICAgIG5ld2tpbmQud2lkZS5tYXggPSBNYXRoLmNlaWwoKG5ld2tpbmQud2lkZS5zaXplICogc2VsZi5NQVhfQUNDRVBUQUJMRSArIHNlbGYuUEFERElORykgLyBuZXdraW5kLndpZGUuY291bnRzKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjYXRlZ29yaXphdGlvbjtcbn07XG5cbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl9jaGFyVG9QYXR0ZXJuID0gZnVuY3Rpb24oY2hhcikge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgY2hhckNvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMCksXG4gICAgICAgIGk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc2VsZi5BTFBIQUJFVC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc2VsZi5BTFBIQUJFVFtpXSA9PT0gY2hhckNvZGUpe1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuQ0hBUkFDVEVSX0VOQ09ESU5HU1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gMHgwO1xufTtcblxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX3ZhbGlkYXRlUmVzdWx0ID0gZnVuY3Rpb24ocmVzdWx0LCBzdGFydENvdW50ZXIpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgIHRocmVzaG9sZHMgPSBzZWxmLl90aHJlc2hvbGRSZXN1bHRQYXR0ZXJuKHJlc3VsdCwgc3RhcnRDb3VudGVyKSxcbiAgICAgICAgaSxcbiAgICAgICAgaixcbiAgICAgICAga2luZCxcbiAgICAgICAgY2F0LFxuICAgICAgICBzaXplLFxuICAgICAgICBwb3MgPSBzdGFydENvdW50ZXIsXG4gICAgICAgIHBhdHRlcm47XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHBhdHRlcm4gPSBzZWxmLl9jaGFyVG9QYXR0ZXJuKHJlc3VsdFtpXSk7XG4gICAgICAgIGZvciAoaiA9IDY7IGogPj0gMDsgai0tKSB7XG4gICAgICAgICAgICBraW5kID0gKGogJiAxKSA9PT0gMCA/IHRocmVzaG9sZHMuYmFyIDogdGhyZXNob2xkcy5zcGFjZTtcbiAgICAgICAgICAgIGNhdCA9IChwYXR0ZXJuICYgMSkgPT09IDEgPyBraW5kLndpZGUgOiBraW5kLm5hcnJvdztcbiAgICAgICAgICAgIHNpemUgPSBzZWxmLl9jb3VudGVyc1twb3MgKyBqXTtcbiAgICAgICAgICAgIGlmIChzaXplIDwgY2F0Lm1pbiB8fCBzaXplID4gY2F0Lm1heCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhdHRlcm4gPj49IDE7XG4gICAgICAgIH1cbiAgICAgICAgcG9zICs9IDg7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX3BhdHRlcm5Ub0NoYXIgPSBmdW5jdGlvbihwYXR0ZXJuKSB7XG4gICAgdmFyIGksXG4gICAgICAgIHNlbGYgPSB0aGlzO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHNlbGYuQ0hBUkFDVEVSX0VOQ09ESU5HUy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc2VsZi5DSEFSQUNURVJfRU5DT0RJTkdTW2ldID09PSBwYXR0ZXJuKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShzZWxmLkFMUEhBQkVUW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59O1xuXG5Db2RhYmFyUmVhZGVyLnByb3RvdHlwZS5fY29tcHV0ZUFsdGVybmF0aW5nVGhyZXNob2xkID0gZnVuY3Rpb24ob2Zmc2V0LCBlbmQpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgbWluID0gTnVtYmVyLk1BWF9WQUxVRSxcbiAgICAgICAgbWF4ID0gMCxcbiAgICAgICAgY291bnRlcjtcblxuICAgIGZvciAoaSA9IG9mZnNldDsgaSA8IGVuZDsgaSArPSAyKXtcbiAgICAgICAgY291bnRlciA9IHRoaXMuX2NvdW50ZXJzW2ldO1xuICAgICAgICBpZiAoY291bnRlciA+IG1heCkge1xuICAgICAgICAgICAgbWF4ID0gY291bnRlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY291bnRlciA8IG1pbikge1xuICAgICAgICAgICAgbWluID0gY291bnRlcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoKG1pbiArIG1heCkgLyAyLjApIHwgMDtcbn07XG5cbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl90b1BhdHRlcm4gPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgICB2YXIgbnVtQ291bnRlcnMgPSA3LFxuICAgICAgICBlbmQgPSBvZmZzZXQgKyBudW1Db3VudGVycyxcbiAgICAgICAgYmFyVGhyZXNob2xkLFxuICAgICAgICBzcGFjZVRocmVzaG9sZCxcbiAgICAgICAgYml0bWFzayA9IDEgPDwgKG51bUNvdW50ZXJzIC0gMSksXG4gICAgICAgIHBhdHRlcm4gPSAwLFxuICAgICAgICBpLFxuICAgICAgICB0aHJlc2hvbGQ7XG5cbiAgICBpZiAoZW5kID4gdGhpcy5fY291bnRlcnMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICBiYXJUaHJlc2hvbGQgPSB0aGlzLl9jb21wdXRlQWx0ZXJuYXRpbmdUaHJlc2hvbGQob2Zmc2V0LCBlbmQpO1xuICAgIHNwYWNlVGhyZXNob2xkID0gdGhpcy5fY29tcHV0ZUFsdGVybmF0aW5nVGhyZXNob2xkKG9mZnNldCArIDEsIGVuZCk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQ291bnRlcnM7IGkrKyl7XG4gICAgICAgIHRocmVzaG9sZCA9IChpICYgMSkgPT09IDAgPyBiYXJUaHJlc2hvbGQgOiBzcGFjZVRocmVzaG9sZDtcbiAgICAgICAgaWYgKHRoaXMuX2NvdW50ZXJzW29mZnNldCArIGldID4gdGhyZXNob2xkKSB7XG4gICAgICAgICAgICBwYXR0ZXJuIHw9IGJpdG1hc2s7XG4gICAgICAgIH1cbiAgICAgICAgYml0bWFzayA+Pj0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0dGVybjtcbn07XG5cbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl9pc1N0YXJ0RW5kID0gZnVuY3Rpb24ocGF0dGVybikge1xuICAgIHZhciBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMuU1RBUlRfRU5ELmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLlNUQVJUX0VORFtpXSA9PT0gcGF0dGVybikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX3N1bUNvdW50ZXJzID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHZhciBpLFxuICAgICAgICBzdW0gPSAwO1xuXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICBzdW0gKz0gdGhpcy5fY291bnRlcnNbaV07XG4gICAgfVxuICAgIHJldHVybiBzdW07XG59O1xuXG5Db2RhYmFyUmVhZGVyLnByb3RvdHlwZS5fZmluZFN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBpLFxuICAgICAgICBwYXR0ZXJuLFxuICAgICAgICBzdGFydCA9IHNlbGYuX25leHRVbnNldChzZWxmLl9yb3cpLFxuICAgICAgICBlbmQ7XG5cbiAgICBmb3IgKGkgPSAxOyBpIDwgdGhpcy5fY291bnRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0dGVybiA9IHNlbGYuX3RvUGF0dGVybihpKTtcbiAgICAgICAgaWYgKHBhdHRlcm4gIT09IC0xICYmIHNlbGYuX2lzU3RhcnRFbmQocGF0dGVybikpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IExvb2sgZm9yIHdoaXRlc3BhY2UgYWhlYWRcbiAgICAgICAgICAgIHN0YXJ0ICs9IHNlbGYuX3N1bUNvdW50ZXJzKDAsIGkpO1xuICAgICAgICAgICAgZW5kID0gc3RhcnQgKyBzZWxmLl9zdW1Db3VudGVycyhpLCBpICsgOCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgICAgICBlbmQ6IGVuZCxcbiAgICAgICAgICAgICAgICBzdGFydENvdW50ZXI6IGksXG4gICAgICAgICAgICAgICAgZW5kQ291bnRlcjogaSArIDhcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBDb2RhYmFyUmVhZGVyO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY29kYWJhcl9yZWFkZXIuanNcbiAqKi8iLCJpbXBvcnQgRUFOUmVhZGVyIGZyb20gJy4vZWFuX3JlYWRlcic7XG5cbmZ1bmN0aW9uIFVQQ1JlYWRlcigpIHtcbiAgICBFQU5SZWFkZXIuY2FsbCh0aGlzKTtcbn1cblxudmFyIHByb3BlcnRpZXMgPSB7XG4gICAgRk9STUFUOiB7dmFsdWU6IFwidXBjX2FcIiwgd3JpdGVhYmxlOiBmYWxzZX1cbn07XG5cblVQQ1JlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVBTlJlYWRlci5wcm90b3R5cGUsIHByb3BlcnRpZXMpO1xuVVBDUmVhZGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFVQQ1JlYWRlcjtcblxuVVBDUmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdCA9IEVBTlJlYWRlci5wcm90b3R5cGUuX2RlY29kZS5jYWxsKHRoaXMpO1xuXG4gICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuY29kZSAmJiByZXN1bHQuY29kZS5sZW5ndGggPT09IDEzICYmIHJlc3VsdC5jb2RlLmNoYXJBdCgwKSA9PT0gXCIwXCIpIHtcbiAgICAgICAgcmVzdWx0LmNvZGUgPSByZXN1bHQuY29kZS5zdWJzdHJpbmcoMSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgVVBDUmVhZGVyO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvdXBjX3JlYWRlci5qc1xuICoqLyIsImltcG9ydCBFQU5SZWFkZXIgZnJvbSAnLi9lYW5fcmVhZGVyJztcblxuZnVuY3Rpb24gRUFOOFJlYWRlcigpIHtcbiAgICBFQU5SZWFkZXIuY2FsbCh0aGlzKTtcbn1cblxudmFyIHByb3BlcnRpZXMgPSB7XG4gICAgRk9STUFUOiB7dmFsdWU6IFwiZWFuXzhcIiwgd3JpdGVhYmxlOiBmYWxzZX1cbn07XG5cbkVBTjhSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFQU5SZWFkZXIucHJvdG90eXBlLCBwcm9wZXJ0aWVzKTtcbkVBTjhSZWFkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRUFOOFJlYWRlcjtcblxuRUFOOFJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBheWxvYWQgPSBmdW5jdGlvbihjb2RlLCByZXN1bHQsIGRlY29kZWRDb2Rlcykge1xuICAgIHZhciBpLFxuICAgICAgICBzZWxmID0gdGhpcztcblxuICAgIGZvciAoIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgIGNvZGUgPSBzZWxmLl9kZWNvZGVDb2RlKGNvZGUuZW5kLCBzZWxmLkNPREVfR19TVEFSVCk7XG4gICAgICAgIGlmICghY29kZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnB1c2goY29kZS5jb2RlKTtcbiAgICAgICAgZGVjb2RlZENvZGVzLnB1c2goY29kZSk7XG4gICAgfVxuXG4gICAgY29kZSA9IHNlbGYuX2ZpbmRQYXR0ZXJuKHNlbGYuTUlERExFX1BBVFRFUk4sIGNvZGUuZW5kLCB0cnVlLCBmYWxzZSk7XG4gICAgaWYgKGNvZGUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xuXG4gICAgZm9yICggaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgICAgY29kZSA9IHNlbGYuX2RlY29kZUNvZGUoY29kZS5lbmQsIHNlbGYuQ09ERV9HX1NUQVJUKTtcbiAgICAgICAgaWYgKCFjb2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcbiAgICAgICAgcmVzdWx0LnB1c2goY29kZS5jb2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29kZTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEVBTjhSZWFkZXI7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9lYW5fOF9yZWFkZXIuanNcbiAqKi8iLCJpbXBvcnQgRUFOUmVhZGVyIGZyb20gJy4vZWFuX3JlYWRlcic7XG5cbmZ1bmN0aW9uIFVQQ0VSZWFkZXIoKSB7XG4gICAgRUFOUmVhZGVyLmNhbGwodGhpcyk7XG59XG5cbnZhciBwcm9wZXJ0aWVzID0ge1xuICAgIENPREVfRlJFUVVFTkNZOiB7dmFsdWU6IFtcbiAgICAgICAgWyA1NiwgNTIsIDUwLCA0OSwgNDQsIDM4LCAzNSwgNDIsIDQxLCAzNyBdLFxuICAgICAgICBbNywgMTEsIDEzLCAxNCwgMTksIDI1LCAyOCwgMjEsIDIyLCAyNl1dfSxcbiAgICBTVE9QX1BBVFRFUk46IHsgdmFsdWU6IFsxIC8gNiAqIDcsIDEgLyA2ICogNywgMSAvIDYgKiA3LCAxIC8gNiAqIDcsIDEgLyA2ICogNywgMSAvIDYgKiA3XX0sXG4gICAgRk9STUFUOiB7dmFsdWU6IFwidXBjX2VcIiwgd3JpdGVhYmxlOiBmYWxzZX1cbn07XG5cblVQQ0VSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFQU5SZWFkZXIucHJvdG90eXBlLCBwcm9wZXJ0aWVzKTtcblVQQ0VSZWFkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVVBDRVJlYWRlcjtcblxuVVBDRVJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBheWxvYWQgPSBmdW5jdGlvbihjb2RlLCByZXN1bHQsIGRlY29kZWRDb2Rlcykge1xuICAgIHZhciBpLFxuICAgICAgICBzZWxmID0gdGhpcyxcbiAgICAgICAgY29kZUZyZXF1ZW5jeSA9IDB4MDtcblxuICAgIGZvciAoIGkgPSAwOyBpIDwgNjsgaSsrKSB7XG4gICAgICAgIGNvZGUgPSBzZWxmLl9kZWNvZGVDb2RlKGNvZGUuZW5kKTtcbiAgICAgICAgaWYgKCFjb2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29kZS5jb2RlID49IHNlbGYuQ09ERV9HX1NUQVJUKSB7XG4gICAgICAgICAgICBjb2RlLmNvZGUgPSBjb2RlLmNvZGUgLSBzZWxmLkNPREVfR19TVEFSVDtcbiAgICAgICAgICAgIGNvZGVGcmVxdWVuY3kgfD0gMSA8PCAoNSAtIGkpO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKGNvZGUuY29kZSk7XG4gICAgICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xuICAgIH1cbiAgICBpZiAoIXNlbGYuX2RldGVybWluZVBhcml0eShjb2RlRnJlcXVlbmN5LCByZXN1bHQpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBjb2RlO1xufTtcblxuVVBDRVJlYWRlci5wcm90b3R5cGUuX2RldGVybWluZVBhcml0eSA9IGZ1bmN0aW9uKGNvZGVGcmVxdWVuY3ksIHJlc3VsdCkge1xuICAgIHZhciBpLFxuICAgICAgICBuclN5c3RlbTtcblxuICAgIGZvciAobnJTeXN0ZW0gPSAwOyBuclN5c3RlbSA8IHRoaXMuQ09ERV9GUkVRVUVOQ1kubGVuZ3RoOyBuclN5c3RlbSsrKXtcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCB0aGlzLkNPREVfRlJFUVVFTkNZW25yU3lzdGVtXS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGNvZGVGcmVxdWVuY3kgPT09IHRoaXMuQ09ERV9GUkVRVUVOQ1lbbnJTeXN0ZW1dW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnVuc2hpZnQobnJTeXN0ZW0pO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGkpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cblVQQ0VSZWFkZXIucHJvdG90eXBlLl9jb252ZXJ0VG9VUENBID0gZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgdmFyIHVwY2EgPSBbcmVzdWx0WzBdXSxcbiAgICAgICAgbGFzdERpZ2l0ID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAyXTtcblxuICAgIGlmIChsYXN0RGlnaXQgPD0gMikge1xuICAgICAgICB1cGNhID0gdXBjYS5jb25jYXQocmVzdWx0LnNsaWNlKDEsIDMpKVxuICAgICAgICAgICAgLmNvbmNhdChbbGFzdERpZ2l0LCAwLCAwLCAwLCAwXSlcbiAgICAgICAgICAgIC5jb25jYXQocmVzdWx0LnNsaWNlKDMsIDYpKTtcbiAgICB9IGVsc2UgaWYgKGxhc3REaWdpdCA9PT0gMykge1xuICAgICAgICB1cGNhID0gdXBjYS5jb25jYXQocmVzdWx0LnNsaWNlKDEsIDQpKVxuICAgICAgICAgICAgLmNvbmNhdChbMCwgMCwgMCwgMCwgMF0pXG4gICAgICAgICAgICAuY29uY2F0KHJlc3VsdC5zbGljZSg0LCA2KSk7XG4gICAgfSBlbHNlIGlmIChsYXN0RGlnaXQgPT09IDQpIHtcbiAgICAgICAgdXBjYSA9IHVwY2EuY29uY2F0KHJlc3VsdC5zbGljZSgxLCA1KSlcbiAgICAgICAgICAgIC5jb25jYXQoWzAsIDAsIDAsIDAsIDAsIHJlc3VsdFs1XV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVwY2EgPSB1cGNhLmNvbmNhdChyZXN1bHQuc2xpY2UoMSwgNikpXG4gICAgICAgICAgICAuY29uY2F0KFswLCAwLCAwLCAwLCBsYXN0RGlnaXRdKTtcbiAgICB9XG5cbiAgICB1cGNhLnB1c2gocmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSk7XG4gICAgcmV0dXJuIHVwY2E7XG59O1xuXG5VUENFUmVhZGVyLnByb3RvdHlwZS5fY2hlY2tzdW0gPSBmdW5jdGlvbihyZXN1bHQpIHtcbiAgICByZXR1cm4gRUFOUmVhZGVyLnByb3RvdHlwZS5fY2hlY2tzdW0uY2FsbCh0aGlzLCB0aGlzLl9jb252ZXJ0VG9VUENBKHJlc3VsdCkpO1xufTtcblxuVVBDRVJlYWRlci5wcm90b3R5cGUuX2ZpbmRFbmQgPSBmdW5jdGlvbihvZmZzZXQsIGlzV2hpdGUpIHtcbiAgICBpc1doaXRlID0gdHJ1ZTtcbiAgICByZXR1cm4gRUFOUmVhZGVyLnByb3RvdHlwZS5fZmluZEVuZC5jYWxsKHRoaXMsIG9mZnNldCwgaXNXaGl0ZSk7XG59O1xuXG5VUENFUmVhZGVyLnByb3RvdHlwZS5fdmVyaWZ5VHJhaWxpbmdXaGl0ZXNwYWNlID0gZnVuY3Rpb24oZW5kSW5mbykge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kO1xuXG4gICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kID0gZW5kSW5mby5lbmQgKyAoKGVuZEluZm8uZW5kIC0gZW5kSW5mby5zdGFydCkgLyAyKTtcbiAgICBpZiAodHJhaWxpbmdXaGl0ZXNwYWNlRW5kIDwgc2VsZi5fcm93Lmxlbmd0aCkge1xuICAgICAgICBpZiAoc2VsZi5fbWF0Y2hSYW5nZShlbmRJbmZvLmVuZCwgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kLCAwKSkge1xuICAgICAgICAgICAgcmV0dXJuIGVuZEluZm87XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBVUENFUmVhZGVyO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvdXBjX2VfcmVhZGVyLmpzXG4gKiovIiwiaW1wb3J0IEJhcmNvZGVSZWFkZXIgZnJvbSAnLi9iYXJjb2RlX3JlYWRlcic7XG5jb25zdCBtZXJnZSA9IHJlcXVpcmUoJ2xvZGFzaC9vYmplY3QvbWVyZ2UnKTtcblxuZnVuY3Rpb24gSTJvZjVSZWFkZXIob3B0cykge1xuICAgIG9wdHMgPSBtZXJnZShnZXREZWZhdWxDb25maWcoKSwgb3B0cyk7XG4gICAgQmFyY29kZVJlYWRlci5jYWxsKHRoaXMsIG9wdHMpO1xuICAgIHRoaXMuYmFyU3BhY2VSYXRpbyA9IFsxLCAxXTtcbiAgICBpZiAob3B0cy5ub3JtYWxpemVCYXJTcGFjZVdpZHRoKSB7XG4gICAgICAgIHRoaXMuU0lOR0xFX0NPREVfRVJST1IgPSAwLjM4O1xuICAgICAgICB0aGlzLkFWR19DT0RFX0VSUk9SID0gMC4wOTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bENvbmZpZygpIHtcbiAgICB2YXIgY29uZmlnID0ge307XG5cbiAgICBPYmplY3Qua2V5cyhJMm9mNVJlYWRlci5DT05GSUdfS0VZUykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgY29uZmlnW2tleV0gPSBJMm9mNVJlYWRlci5DT05GSUdfS0VZU1trZXldLmRlZmF1bHQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cblxudmFyIE4gPSAxLFxuICAgIFcgPSAzLFxuICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgIE1PRFVMTzoge3ZhbHVlOiAxMH0sXG4gICAgICAgIFNUQVJUX1BBVFRFUk46IHt2YWx1ZTogW04gKiAyLjUsIE4gKiAyLjUsIE4gKiAyLjUsIE4gKiAyLjVdfSxcbiAgICAgICAgU1RPUF9QQVRURVJOOiB7dmFsdWU6IFtOICogMiwgTiAqIDIsIFcgKiAyXX0sXG4gICAgICAgIENPREVfUEFUVEVSTjoge3ZhbHVlOiBbXG4gICAgICAgICAgICBbTiwgTiwgVywgVywgTl0sXG4gICAgICAgICAgICBbVywgTiwgTiwgTiwgV10sXG4gICAgICAgICAgICBbTiwgVywgTiwgTiwgV10sXG4gICAgICAgICAgICBbVywgVywgTiwgTiwgTl0sXG4gICAgICAgICAgICBbTiwgTiwgVywgTiwgV10sXG4gICAgICAgICAgICBbVywgTiwgVywgTiwgTl0sXG4gICAgICAgICAgICBbTiwgVywgVywgTiwgTl0sXG4gICAgICAgICAgICBbTiwgTiwgTiwgVywgV10sXG4gICAgICAgICAgICBbVywgTiwgTiwgVywgTl0sXG4gICAgICAgICAgICBbTiwgVywgTiwgVywgTl1cbiAgICAgICAgXX0sXG4gICAgICAgIFNJTkdMRV9DT0RFX0VSUk9SOiB7dmFsdWU6IDAuNzgsIHdyaXRhYmxlOiB0cnVlfSxcbiAgICAgICAgQVZHX0NPREVfRVJST1I6IHt2YWx1ZTogMC4zOCwgd3JpdGFibGU6IHRydWV9LFxuICAgICAgICBNQVhfQ09SUkVDVElPTl9GQUNUT1I6IHt2YWx1ZTogNX0sXG4gICAgICAgIEZPUk1BVDoge3ZhbHVlOiBcImkyb2Y1XCJ9XG4gICAgfTtcblxuSTJvZjVSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCYXJjb2RlUmVhZGVyLnByb3RvdHlwZSwgcHJvcGVydGllcyk7XG5JMm9mNVJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBJMm9mNVJlYWRlcjtcblxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl9tYXRjaFBhdHRlcm4gPSBmdW5jdGlvbihjb3VudGVyLCBjb2RlKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm5vcm1hbGl6ZUJhclNwYWNlV2lkdGgpIHtcbiAgICAgICAgdmFyIGksXG4gICAgICAgICAgICBjb3VudGVyU3VtID0gWzAsIDBdLFxuICAgICAgICAgICAgY29kZVN1bSA9IFswLCAwXSxcbiAgICAgICAgICAgIGNvcnJlY3Rpb24gPSBbMCwgMF0sXG4gICAgICAgICAgICBjb3JyZWN0aW9uUmF0aW8gPSB0aGlzLk1BWF9DT1JSRUNUSU9OX0ZBQ1RPUixcbiAgICAgICAgICAgIGNvcnJlY3Rpb25SYXRpb0ludmVyc2UgPSAxIC8gY29ycmVjdGlvblJhdGlvO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb3VudGVyU3VtW2kgJSAyXSArPSBjb3VudGVyW2ldO1xuICAgICAgICAgICAgY29kZVN1bVtpICUgMl0gKz0gY29kZVtpXTtcbiAgICAgICAgfVxuICAgICAgICBjb3JyZWN0aW9uWzBdID0gY29kZVN1bVswXSAvIGNvdW50ZXJTdW1bMF07XG4gICAgICAgIGNvcnJlY3Rpb25bMV0gPSBjb2RlU3VtWzFdIC8gY291bnRlclN1bVsxXTtcblxuICAgICAgICBjb3JyZWN0aW9uWzBdID0gTWF0aC5tYXgoTWF0aC5taW4oY29ycmVjdGlvblswXSwgY29ycmVjdGlvblJhdGlvKSwgY29ycmVjdGlvblJhdGlvSW52ZXJzZSk7XG4gICAgICAgIGNvcnJlY3Rpb25bMV0gPSBNYXRoLm1heChNYXRoLm1pbihjb3JyZWN0aW9uWzFdLCBjb3JyZWN0aW9uUmF0aW8pLCBjb3JyZWN0aW9uUmF0aW9JbnZlcnNlKTtcbiAgICAgICAgdGhpcy5iYXJTcGFjZVJhdGlvID0gY29ycmVjdGlvbjtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvdW50ZXJbaV0gKj0gdGhpcy5iYXJTcGFjZVJhdGlvW2kgJSAyXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX21hdGNoUGF0dGVybi5jYWxsKHRoaXMsIGNvdW50ZXIsIGNvZGUpO1xufTtcblxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl9maW5kUGF0dGVybiA9IGZ1bmN0aW9uKHBhdHRlcm4sIG9mZnNldCwgaXNXaGl0ZSwgdHJ5SGFyZGVyKSB7XG4gICAgdmFyIGNvdW50ZXIgPSBbXSxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIGksXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwLFxuICAgICAgICBiZXN0TWF0Y2ggPSB7XG4gICAgICAgICAgICBlcnJvcjogTnVtYmVyLk1BWF9WQUxVRSxcbiAgICAgICAgICAgIGNvZGU6IC0xLFxuICAgICAgICAgICAgc3RhcnQ6IDAsXG4gICAgICAgICAgICBlbmQ6IDBcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGosXG4gICAgICAgIHN1bSxcbiAgICAgICAgbm9ybWFsaXplZCxcbiAgICAgICAgZXBzaWxvbiA9IHNlbGYuQVZHX0NPREVfRVJST1I7XG5cbiAgICBpc1doaXRlID0gaXNXaGl0ZSB8fCBmYWxzZTtcbiAgICB0cnlIYXJkZXIgPSB0cnlIYXJkZXIgfHwgZmFsc2U7XG5cbiAgICBpZiAoIW9mZnNldCkge1xuICAgICAgICBvZmZzZXQgPSBzZWxmLl9uZXh0U2V0KHNlbGYuX3Jvdyk7XG4gICAgfVxuXG4gICAgZm9yICggaSA9IDA7IGkgPCBwYXR0ZXJuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvdW50ZXJbaV0gPSAwO1xuICAgIH1cblxuICAgIGZvciAoIGkgPSBvZmZzZXQ7IGkgPCBzZWxmLl9yb3cubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHNlbGYuX3Jvd1tpXSBeIGlzV2hpdGUpIHtcbiAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10rKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb3VudGVyUG9zID09PSBjb3VudGVyLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBzdW0gPSAwO1xuICAgICAgICAgICAgICAgIGZvciAoIGogPSAwOyBqIDwgY291bnRlci5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICBzdW0gKz0gY291bnRlcltqXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IHNlbGYuX25vcm1hbGl6ZShjb3VudGVyKTtcbiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHNlbGYuX21hdGNoUGF0dGVybihub3JtYWxpemVkLCBwYXR0ZXJuKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPCBlcHNpbG9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5zdGFydCA9IGkgLSBzdW07XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZW5kID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiZXN0TWF0Y2g7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRyeUhhcmRlcikge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY291bnRlci5sZW5ndGggLSAyOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbal0gPSBjb3VudGVyW2ogKyAyXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXIubGVuZ3RoIC0gMl0gPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXIubGVuZ3RoIC0gMV0gPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb3VudGVyUG9zLS07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fZmluZFN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICBsZWFkaW5nV2hpdGVzcGFjZVN0YXJ0LFxuICAgICAgICBvZmZzZXQgPSBzZWxmLl9uZXh0U2V0KHNlbGYuX3JvdyksXG4gICAgICAgIHN0YXJ0SW5mbyxcbiAgICAgICAgbmFycm93QmFyV2lkdGggPSAxO1xuXG4gICAgd2hpbGUgKCFzdGFydEluZm8pIHtcbiAgICAgICAgc3RhcnRJbmZvID0gc2VsZi5fZmluZFBhdHRlcm4oc2VsZi5TVEFSVF9QQVRURVJOLCBvZmZzZXQsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgaWYgKCFzdGFydEluZm8pIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIG5hcnJvd0JhcldpZHRoID0gTWF0aC5mbG9vcigoc3RhcnRJbmZvLmVuZCAtIHN0YXJ0SW5mby5zdGFydCkgLyA0KTtcbiAgICAgICAgbGVhZGluZ1doaXRlc3BhY2VTdGFydCA9IHN0YXJ0SW5mby5zdGFydCAtIG5hcnJvd0JhcldpZHRoICogMTA7XG4gICAgICAgIGlmIChsZWFkaW5nV2hpdGVzcGFjZVN0YXJ0ID49IDApIHtcbiAgICAgICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGxlYWRpbmdXaGl0ZXNwYWNlU3RhcnQsIHN0YXJ0SW5mby5zdGFydCwgMCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnRJbmZvO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG9mZnNldCA9IHN0YXJ0SW5mby5lbmQ7XG4gICAgICAgIHN0YXJ0SW5mbyA9IG51bGw7XG4gICAgfVxufTtcblxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UgPSBmdW5jdGlvbihlbmRJbmZvKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgICB0cmFpbGluZ1doaXRlc3BhY2VFbmQ7XG5cbiAgICB0cmFpbGluZ1doaXRlc3BhY2VFbmQgPSBlbmRJbmZvLmVuZCArICgoZW5kSW5mby5lbmQgLSBlbmRJbmZvLnN0YXJ0KSAvIDIpO1xuICAgIGlmICh0cmFpbGluZ1doaXRlc3BhY2VFbmQgPCBzZWxmLl9yb3cubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGVuZEluZm8uZW5kLCB0cmFpbGluZ1doaXRlc3BhY2VFbmQsIDApKSB7XG4gICAgICAgICAgICByZXR1cm4gZW5kSW5mbztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fZmluZEVuZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgZW5kSW5mbyxcbiAgICAgICAgdG1wO1xuXG4gICAgc2VsZi5fcm93LnJldmVyc2UoKTtcbiAgICBlbmRJbmZvID0gc2VsZi5fZmluZFBhdHRlcm4oc2VsZi5TVE9QX1BBVFRFUk4pO1xuICAgIHNlbGYuX3Jvdy5yZXZlcnNlKCk7XG5cbiAgICBpZiAoZW5kSW5mbyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyByZXZlcnNlIG51bWJlcnNcbiAgICB0bXAgPSBlbmRJbmZvLnN0YXJ0O1xuICAgIGVuZEluZm8uc3RhcnQgPSBzZWxmLl9yb3cubGVuZ3RoIC0gZW5kSW5mby5lbmQ7XG4gICAgZW5kSW5mby5lbmQgPSBzZWxmLl9yb3cubGVuZ3RoIC0gdG1wO1xuXG4gICAgcmV0dXJuIGVuZEluZm8gIT09IG51bGwgPyBzZWxmLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UoZW5kSW5mbykgOiBudWxsO1xufTtcblxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl9kZWNvZGVQYWlyID0gZnVuY3Rpb24oY291bnRlclBhaXIpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgY29kZSxcbiAgICAgICAgY29kZXMgPSBbXSxcbiAgICAgICAgc2VsZiA9IHRoaXM7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgY291bnRlclBhaXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29kZSA9IHNlbGYuX2RlY29kZUNvZGUoY291bnRlclBhaXJbaV0pO1xuICAgICAgICBpZiAoIWNvZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvZGVzLnB1c2goY29kZSk7XG4gICAgfVxuICAgIHJldHVybiBjb2Rlcztcbn07XG5cbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlQ29kZSA9IGZ1bmN0aW9uKGNvdW50ZXIpIHtcbiAgICB2YXIgaixcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIHN1bSA9IDAsXG4gICAgICAgIG5vcm1hbGl6ZWQsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBlcHNpbG9uID0gc2VsZi5BVkdfQ09ERV9FUlJPUixcbiAgICAgICAgY29kZSxcbiAgICAgICAgYmVzdE1hdGNoID0ge1xuICAgICAgICAgICAgZXJyb3I6IE51bWJlci5NQVhfVkFMVUUsXG4gICAgICAgICAgICBjb2RlOiAtMSxcbiAgICAgICAgICAgIHN0YXJ0OiAwLFxuICAgICAgICAgICAgZW5kOiAwXG4gICAgICAgIH07XG5cbiAgICBmb3IgKCBqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgc3VtICs9IGNvdW50ZXJbal07XG4gICAgfVxuICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlcik7XG4gICAgaWYgKG5vcm1hbGl6ZWQpIHtcbiAgICAgICAgZm9yIChjb2RlID0gMDsgY29kZSA8IHNlbGYuQ09ERV9QQVRURVJOLmxlbmd0aDsgY29kZSsrKSB7XG4gICAgICAgICAgICBlcnJvciA9IHNlbGYuX21hdGNoUGF0dGVybihub3JtYWxpemVkLCBzZWxmLkNPREVfUEFUVEVSTltjb2RlXSk7XG4gICAgICAgICAgICBpZiAoZXJyb3IgPCBiZXN0TWF0Y2guZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBiZXN0TWF0Y2guY29kZSA9IGNvZGU7XG4gICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVycm9yID0gZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJlc3RNYXRjaC5lcnJvciA8IGVwc2lsb24pIHtcbiAgICAgICAgICAgIHJldHVybiBiZXN0TWF0Y2g7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuXG5JMm9mNVJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBheWxvYWQgPSBmdW5jdGlvbihjb3VudGVycywgcmVzdWx0LCBkZWNvZGVkQ29kZXMpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIHBvcyA9IDAsXG4gICAgICAgIGNvdW50ZXJMZW5ndGggPSBjb3VudGVycy5sZW5ndGgsXG4gICAgICAgIGNvdW50ZXJQYWlyID0gW1swLCAwLCAwLCAwLCAwXSwgWzAsIDAsIDAsIDAsIDBdXSxcbiAgICAgICAgY29kZXM7XG5cbiAgICB3aGlsZSAocG9zIDwgY291bnRlckxlbmd0aCkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgICAgICAgICBjb3VudGVyUGFpclswXVtpXSA9IGNvdW50ZXJzW3Bvc10gKiB0aGlzLmJhclNwYWNlUmF0aW9bMF07XG4gICAgICAgICAgICBjb3VudGVyUGFpclsxXVtpXSA9IGNvdW50ZXJzW3BvcyArIDFdICogdGhpcy5iYXJTcGFjZVJhdGlvWzFdO1xuICAgICAgICAgICAgcG9zICs9IDI7XG4gICAgICAgIH1cbiAgICAgICAgY29kZXMgPSBzZWxmLl9kZWNvZGVQYWlyKGNvdW50ZXJQYWlyKTtcbiAgICAgICAgaWYgKCFjb2Rlcykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChjb2Rlc1tpXS5jb2RlICsgXCJcIik7XG4gICAgICAgICAgICBkZWNvZGVkQ29kZXMucHVzaChjb2Rlc1tpXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvZGVzO1xufTtcblxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlDb3VudGVyTGVuZ3RoID0gZnVuY3Rpb24oY291bnRlcnMpIHtcbiAgICByZXR1cm4gKGNvdW50ZXJzLmxlbmd0aCAlIDEwID09PSAwKTtcbn07XG5cbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN0YXJ0SW5mbyxcbiAgICAgICAgZW5kSW5mbyxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIGNvZGUsXG4gICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICBkZWNvZGVkQ29kZXMgPSBbXSxcbiAgICAgICAgY291bnRlcnM7XG5cbiAgICBzdGFydEluZm8gPSBzZWxmLl9maW5kU3RhcnQoKTtcbiAgICBpZiAoIXN0YXJ0SW5mbykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZGVjb2RlZENvZGVzLnB1c2goc3RhcnRJbmZvKTtcblxuICAgIGVuZEluZm8gPSBzZWxmLl9maW5kRW5kKCk7XG4gICAgaWYgKCFlbmRJbmZvKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvdW50ZXJzID0gc2VsZi5fZmlsbENvdW50ZXJzKHN0YXJ0SW5mby5lbmQsIGVuZEluZm8uc3RhcnQsIGZhbHNlKTtcbiAgICBpZiAoIXNlbGYuX3ZlcmlmeUNvdW50ZXJMZW5ndGgoY291bnRlcnMpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb2RlID0gc2VsZi5fZGVjb2RlUGF5bG9hZChjb3VudGVycywgcmVzdWx0LCBkZWNvZGVkQ29kZXMpO1xuICAgIGlmICghY29kZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC5sZW5ndGggJSAyICE9PSAwIHx8XG4gICAgICAgICAgICByZXN1bHQubGVuZ3RoIDwgNikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBkZWNvZGVkQ29kZXMucHVzaChlbmRJbmZvKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiByZXN1bHQuam9pbihcIlwiKSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0SW5mby5zdGFydCxcbiAgICAgICAgZW5kOiBlbmRJbmZvLmVuZCxcbiAgICAgICAgc3RhcnRJbmZvOiBzdGFydEluZm8sXG4gICAgICAgIGRlY29kZWRDb2RlczogZGVjb2RlZENvZGVzXG4gICAgfTtcbn07XG5cbkkyb2Y1UmVhZGVyLkNPTkZJR19LRVlTID0ge1xuICAgIG5vcm1hbGl6ZUJhclNwYWNlV2lkdGg6IHtcbiAgICAgICAgJ3R5cGUnOiAnYm9vbGVhbicsXG4gICAgICAgICdkZWZhdWx0JzogZmFsc2UsXG4gICAgICAgICdkZXNjcmlwdGlvbic6ICdJZiB0cnVlLCB0aGUgcmVhZGVyIHRyaWVzIHRvIG5vcm1hbGl6ZSB0aGUnICtcbiAgICAgICAgJ3dpZHRoLWRpZmZlcmVuY2UgYmV0d2VlbiBiYXJzIGFuZCBzcGFjZXMnXG4gICAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgSTJvZjVSZWFkZXI7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9pMm9mNV9yZWFkZXIuanNcbiAqKi8iLCJ2YXIgYmFzZU1lcmdlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1lcmdlJyksXG4gICAgY3JlYXRlQXNzaWduZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVBc3NpZ25lcicpO1xuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IG1lcmdlcyBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIHRoZSBzb3VyY2Ugb2JqZWN0KHMpLCB0aGF0XG4gKiBkb24ndCByZXNvbHZlIHRvIGB1bmRlZmluZWRgIGludG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdC4gU3Vic2VxdWVudCBzb3VyY2VzXG4gKiBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy4gSWYgYGN1c3RvbWl6ZXJgIGlzXG4gKiBwcm92aWRlZCBpdCdzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgbWVyZ2VkIHZhbHVlcyBvZiB0aGUgZGVzdGluYXRpb24gYW5kXG4gKiBzb3VyY2UgcHJvcGVydGllcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAgbWVyZ2luZyBpcyBoYW5kbGVkXG4gKiBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkXG4gKiB3aXRoIGZpdmUgYXJndW1lbnRzOiAob2JqZWN0VmFsdWUsIHNvdXJjZVZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHVzZXJzID0ge1xuICogICAnZGF0YSc6IFt7ICd1c2VyJzogJ2Jhcm5leScgfSwgeyAndXNlcic6ICdmcmVkJyB9XVxuICogfTtcbiAqXG4gKiB2YXIgYWdlcyA9IHtcbiAqICAgJ2RhdGEnOiBbeyAnYWdlJzogMzYgfSwgeyAnYWdlJzogNDAgfV1cbiAqIH07XG4gKlxuICogXy5tZXJnZSh1c2VycywgYWdlcyk7XG4gKiAvLyA9PiB7ICdkYXRhJzogW3sgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH0sIHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9XSB9XG4gKlxuICogLy8gdXNpbmcgYSBjdXN0b21pemVyIGNhbGxiYWNrXG4gKiB2YXIgb2JqZWN0ID0ge1xuICogICAnZnJ1aXRzJzogWydhcHBsZSddLFxuICogICAndmVnZXRhYmxlcyc6IFsnYmVldCddXG4gKiB9O1xuICpcbiAqIHZhciBvdGhlciA9IHtcbiAqICAgJ2ZydWl0cyc6IFsnYmFuYW5hJ10sXG4gKiAgICd2ZWdldGFibGVzJzogWydjYXJyb3QnXVxuICogfTtcbiAqXG4gKiBfLm1lcmdlKG9iamVjdCwgb3RoZXIsIGZ1bmN0aW9uKGEsIGIpIHtcbiAqICAgaWYgKF8uaXNBcnJheShhKSkge1xuICogICAgIHJldHVybiBhLmNvbmNhdChiKTtcbiAqICAgfVxuICogfSk7XG4gKiAvLyA9PiB7ICdmcnVpdHMnOiBbJ2FwcGxlJywgJ2JhbmFuYSddLCAndmVnZXRhYmxlcyc6IFsnYmVldCcsICdjYXJyb3QnXSB9XG4gKi9cbnZhciBtZXJnZSA9IGNyZWF0ZUFzc2lnbmVyKGJhc2VNZXJnZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gbWVyZ2U7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvb2JqZWN0L21lcmdlLmpzXG4gKiogbW9kdWxlIGlkID0gMzVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhcnJheUVhY2ggPSByZXF1aXJlKCcuL2FycmF5RWFjaCcpLFxuICAgIGJhc2VNZXJnZURlZXAgPSByZXF1aXJlKCcuL2Jhc2VNZXJnZURlZXAnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1lcmdlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICogbXVsdGlwbGUgc291cmNlcywgYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBtZXJnZWQgdmFsdWVzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0I9W11dIEFzc29jaWF0ZXMgdmFsdWVzIHdpdGggc291cmNlIGNvdW50ZXJwYXJ0cy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VNZXJnZShvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplciwgc3RhY2tBLCBzdGFja0IpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICB2YXIgaXNTcmNBcnIgPSBpc0FycmF5TGlrZShzb3VyY2UpICYmIChpc0FycmF5KHNvdXJjZSkgfHwgaXNUeXBlZEFycmF5KHNvdXJjZSkpLFxuICAgICAgcHJvcHMgPSBpc1NyY0FyciA/IHVuZGVmaW5lZCA6IGtleXMoc291cmNlKTtcblxuICBhcnJheUVhY2gocHJvcHMgfHwgc291cmNlLCBmdW5jdGlvbihzcmNWYWx1ZSwga2V5KSB7XG4gICAgaWYgKHByb3BzKSB7XG4gICAgICBrZXkgPSBzcmNWYWx1ZTtcbiAgICAgIHNyY1ZhbHVlID0gc291cmNlW2tleV07XG4gICAgfVxuICAgIGlmIChpc09iamVjdExpa2Uoc3JjVmFsdWUpKSB7XG4gICAgICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgICAgIHN0YWNrQiB8fCAoc3RhY2tCID0gW10pO1xuICAgICAgYmFzZU1lcmdlRGVlcChvYmplY3QsIHNvdXJjZSwga2V5LCBiYXNlTWVyZ2UsIGN1c3RvbWl6ZXIsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB2YXIgdmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcih2YWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGlzQ29tbW9uID0gcmVzdWx0ID09PSB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChpc0NvbW1vbikge1xuICAgICAgICByZXN1bHQgPSBzcmNWYWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmICgocmVzdWx0ICE9PSB1bmRlZmluZWQgfHwgKGlzU3JjQXJyICYmICEoa2V5IGluIG9iamVjdCkpKSAmJlxuICAgICAgICAgIChpc0NvbW1vbiB8fCAocmVzdWx0ID09PSByZXN1bHQgPyAocmVzdWx0ICE9PSB2YWx1ZSkgOiAodmFsdWUgPT09IHZhbHVlKSkpKSB7XG4gICAgICAgIG9iamVjdFtrZXldID0gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1lcmdlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2Jhc2VNZXJnZS5qc1xuICoqIG1vZHVsZSBpZCA9IDM2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheUVhY2goYXJyYXksIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlFYWNoO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2FycmF5RWFjaC5qc1xuICoqIG1vZHVsZSBpZCA9IDM3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNQbGFpbk9iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICAgIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNUeXBlZEFycmF5JyksXG4gICAgdG9QbGFpbk9iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvdG9QbGFpbk9iamVjdCcpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZU1lcmdlYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gKiBkZWVwIG1lcmdlcyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBtZXJnZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIG1lcmdlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWVyZ2VGdW5jIFRoZSBmdW5jdGlvbiB0byBtZXJnZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBtZXJnZWQgdmFsdWVzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0I9W11dIEFzc29jaWF0ZXMgdmFsdWVzIHdpdGggc291cmNlIGNvdW50ZXJwYXJ0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlTWVyZ2VEZWVwKG9iamVjdCwgc291cmNlLCBrZXksIG1lcmdlRnVuYywgY3VzdG9taXplciwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGgsXG4gICAgICBzcmNWYWx1ZSA9IHNvdXJjZVtrZXldO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBzcmNWYWx1ZSkge1xuICAgICAgb2JqZWN0W2tleV0gPSBzdGFja0JbbGVuZ3RoXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cbiAgdmFyIHZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcih2YWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpIDogdW5kZWZpbmVkLFxuICAgICAgaXNDb21tb24gPSByZXN1bHQgPT09IHVuZGVmaW5lZDtcblxuICBpZiAoaXNDb21tb24pIHtcbiAgICByZXN1bHQgPSBzcmNWYWx1ZTtcbiAgICBpZiAoaXNBcnJheUxpa2Uoc3JjVmFsdWUpICYmIChpc0FycmF5KHNyY1ZhbHVlKSB8fCBpc1R5cGVkQXJyYXkoc3JjVmFsdWUpKSkge1xuICAgICAgcmVzdWx0ID0gaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgPyB2YWx1ZVxuICAgICAgICA6IChpc0FycmF5TGlrZSh2YWx1ZSkgPyBhcnJheUNvcHkodmFsdWUpIDogW10pO1xuICAgIH1cbiAgICBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHNyY1ZhbHVlKSB8fCBpc0FyZ3VtZW50cyhzcmNWYWx1ZSkpIHtcbiAgICAgIHJlc3VsdCA9IGlzQXJndW1lbnRzKHZhbHVlKVxuICAgICAgICA/IHRvUGxhaW5PYmplY3QodmFsdWUpXG4gICAgICAgIDogKGlzUGxhaW5PYmplY3QodmFsdWUpID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIHRoZSBzb3VyY2UgdmFsdWUgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzIGFuZCBhc3NvY2lhdGVcbiAgLy8gaXQgd2l0aCBpdHMgbWVyZ2VkIHZhbHVlLlxuICBzdGFja0EucHVzaChzcmNWYWx1ZSk7XG4gIHN0YWNrQi5wdXNoKHJlc3VsdCk7XG5cbiAgaWYgKGlzQ29tbW9uKSB7XG4gICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgb2JqZWN0W2tleV0gPSBtZXJnZUZ1bmMocmVzdWx0LCBzcmNWYWx1ZSwgY3VzdG9taXplciwgc3RhY2tBLCBzdGFja0IpO1xuICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlc3VsdCAhPT0gdmFsdWUpIDogKHZhbHVlID09PSB2YWx1ZSkpIHtcbiAgICBvYmplY3Rba2V5XSA9IHJlc3VsdDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNZXJnZURlZXA7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1lcmdlRGVlcC5qc1xuICoqIG1vZHVsZSBpZCA9IDM4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5Q29weShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUNvcHk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlDb3B5LmpzXG4gKiogbW9kdWxlIGlkID0gMzlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNBcnJheUxpa2UodmFsdWUpICYmXG4gICAgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvbGFuZy9pc0FyZ3VtZW50cy5qc1xuICoqIG1vZHVsZSBpZCA9IDQwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaW50ZXJuYWwvaXNBcnJheUxpa2UuanNcbiAqKiBtb2R1bGUgaWQgPSA0MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYmFzZVByb3BlcnR5Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSB2YWx1ZSBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGF2b2lkIGEgW0pJVCBidWddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3OTIpXG4gKiB0aGF0IGFmZmVjdHMgU2FmYXJpIG9uIGF0IGxlYXN0IGlPUyA4LjEtOC4zIEFSTTY0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgXCJsZW5ndGhcIiB2YWx1ZS5cbiAqL1xudmFyIGdldExlbmd0aCA9IGJhc2VQcm9wZXJ0eSgnbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TGVuZ3RoO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2dldExlbmd0aC5qc1xuICoqIG1vZHVsZSBpZCA9IDQyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pbnRlcm5hbC9iYXNlUHJvcGVydHkuanNcbiAqKiBtb2R1bGUgaWQgPSA0M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgYmFzZWQgb24gW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pbnRlcm5hbC9pc0xlbmd0aC5qc1xuICoqIG1vZHVsZSBpZCA9IDQ0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2lzT2JqZWN0TGlrZS5qc1xuICoqIG1vZHVsZSBpZCA9IDQ1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVJc0FycmF5ID0gZ2V0TmF0aXZlKEFycmF5LCAnaXNBcnJheScpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheShmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGFycmF5VGFnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2xhbmcvaXNBcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDQ2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNOYXRpdmUgPSByZXF1aXJlKCcuLi9sYW5nL2lzTmF0aXZlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbmF0aXZlIGZ1bmN0aW9uIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZCB0byBnZXQuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkge1xuICB2YXIgdmFsdWUgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICByZXR1cm4gaXNOYXRpdmUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TmF0aXZlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2dldE5hdGl2ZS5qc1xuICoqIG1vZHVsZSBpZCA9IDQ3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4vaXNGdW5jdGlvbicpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSA+IDUpLiAqL1xudmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovXG52YXIgZm5Ub1N0cmluZyA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi9cbnZhciByZUlzTmF0aXZlID0gUmVnRXhwKCdeJyArXG4gIGZuVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSkucmVwbGFjZSgvW1xcXFxeJC4qKz8oKVtcXF17fXxdL2csICdcXFxcJCYnKVxuICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbik7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNOYXRpdmUoQXJyYXkucHJvdG90eXBlLnB1c2gpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNOYXRpdmUoXyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc05hdGl2ZSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICByZXR1cm4gcmVJc05hdGl2ZS50ZXN0KGZuVG9TdHJpbmcuY2FsbCh2YWx1ZSkpO1xuICB9XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIHJlSXNIb3N0Q3Rvci50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9sYW5nL2lzTmF0aXZlLmpzXG4gKiogbW9kdWxlIGlkID0gNDhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gb2xkZXIgdmVyc2lvbnMgb2YgQ2hyb21lIGFuZCBTYWZhcmkgd2hpY2ggcmV0dXJuICdmdW5jdGlvbicgZm9yIHJlZ2V4ZXNcbiAgLy8gYW5kIFNhZmFyaSA4IHdoaWNoIHJldHVybnMgJ29iamVjdCcgZm9yIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9ycy5cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBmdW5jVGFnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb247XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvbGFuZy9pc0Z1bmN0aW9uLmpzXG4gKiogbW9kdWxlIGlkID0gNDlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvbGFuZy9pc09iamVjdC5qc1xuICoqIG1vZHVsZSBpZCA9IDUwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZvckluJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwbGFpbiBvYmplY3QsIHRoYXQgaXMsIGFuIG9iamVjdCBjcmVhdGVkIGJ5IHRoZVxuICogYE9iamVjdGAgY29uc3RydWN0b3Igb3Igb25lIHdpdGggYSBgW1tQcm90b3R5cGVdXWAgb2YgYG51bGxgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBhc3N1bWVzIG9iamVjdHMgY3JlYXRlZCBieSB0aGUgYE9iamVjdGAgY29uc3RydWN0b3JcbiAqIGhhdmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwbGFpbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogfVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICB2YXIgQ3RvcjtcblxuICAvLyBFeGl0IGVhcmx5IGZvciBub24gYE9iamVjdGAgb2JqZWN0cy5cbiAgaWYgKCEoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBvYmplY3RUYWcgJiYgIWlzQXJndW1lbnRzKHZhbHVlKSkgfHxcbiAgICAgICghaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NvbnN0cnVjdG9yJykgJiYgKEN0b3IgPSB2YWx1ZS5jb25zdHJ1Y3RvciwgdHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhKEN0b3IgaW5zdGFuY2VvZiBDdG9yKSkpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIElFIDwgOSBpdGVyYXRlcyBpbmhlcml0ZWQgcHJvcGVydGllcyBiZWZvcmUgb3duIHByb3BlcnRpZXMuIElmIHRoZSBmaXJzdFxuICAvLyBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3QncyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkXG4gIC8vIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgdmFyIHJlc3VsdDtcbiAgLy8gSW4gbW9zdCBlbnZpcm9ubWVudHMgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMgYXJlIGl0ZXJhdGVkIGJlZm9yZVxuICAvLyBpdHMgaW5oZXJpdGVkIHByb3BlcnRpZXMuIElmIHRoZSBsYXN0IGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzXG4gIC8vIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICBiYXNlRm9ySW4odmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHQgPSBrZXk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgfHwgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgcmVzdWx0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1BsYWluT2JqZWN0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2xhbmcvaXNQbGFpbk9iamVjdC5qc1xuICoqIG1vZHVsZSBpZCA9IDUxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaW50ZXJuYWwvYmFzZUZvckluLmpzXG4gKiogbW9kdWxlIGlkID0gNTJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaW50ZXJuYWwvYmFzZUZvci5qc1xuICoqIG1vZHVsZSBpZCA9IDUzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJhc2UgZnVuY3Rpb24gZm9yIGBfLmZvckluYCBvciBgXy5mb3JJblJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICB2YXIgaXRlcmFibGUgPSB0b09iamVjdChvYmplY3QpLFxuICAgICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksXG4gICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMTtcblxuICAgIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2tleV0sIGtleSwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRm9yO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2NyZWF0ZUJhc2VGb3IuanNcbiAqKiBtb2R1bGUgaWQgPSA1NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gb2JqZWN0IGlmIGl0J3Mgbm90IG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gdG9PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pbnRlcm5hbC90b09iamVjdC5qc1xuICoqIG1vZHVsZSBpZCA9IDU1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXNJbihuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJywgJ2MnXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBrZXlzSW4ob2JqZWN0KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgfVxuICB2YXIgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDtcbiAgbGVuZ3RoID0gKGxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKSAmJiBsZW5ndGgpIHx8IDA7XG5cbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBpbmRleCA9IC0xLFxuICAgICAgaXNQcm90byA9IHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCksXG4gICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDA7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gKGluZGV4ICsgJycpO1xuICB9XG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwSW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgJiZcbiAgICAgICAgIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzSW47XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvb2JqZWN0L2tleXNJbi5qc1xuICoqIG1vZHVsZSBpZCA9IDU2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG52YXIgcmVJc1VpbnQgPSAvXlxcZCskLztcblxuLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgcmV0dXJuIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pbnRlcm5hbC9pc0luZGV4LmpzXG4gKiogbW9kdWxlIGlkID0gNTdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xudmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG50eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbnR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbnR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbnR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID1cbnR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG50eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tvYmpUb1N0cmluZy5jYWxsKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUeXBlZEFycmF5O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2xhbmcvaXNUeXBlZEFycmF5LmpzXG4gKiogbW9kdWxlIGlkID0gNThcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBiYXNlQ29weSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VDb3B5JyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBwbGFpbiBvYmplY3QgZmxhdHRlbmluZyBpbmhlcml0ZWQgZW51bWVyYWJsZVxuICogcHJvcGVydGllcyBvZiBgdmFsdWVgIHRvIG93biBwcm9wZXJ0aWVzIG9mIHRoZSBwbGFpbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29udmVydGVkIHBsYWluIG9iamVjdC5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5hc3NpZ24oeyAnYSc6IDEgfSwgbmV3IEZvbyk7XG4gKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAqXG4gKiBfLmFzc2lnbih7ICdhJzogMSB9LCBfLnRvUGxhaW5PYmplY3QobmV3IEZvbykpO1xuICogLy8gPT4geyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH1cbiAqL1xuZnVuY3Rpb24gdG9QbGFpbk9iamVjdCh2YWx1ZSkge1xuICByZXR1cm4gYmFzZUNvcHkodmFsdWUsIGtleXNJbih2YWx1ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGxhaW5PYmplY3Q7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvbGFuZy90b1BsYWluT2JqZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gNTlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUNvcHkoc291cmNlLCBwcm9wcywgb2JqZWN0KSB7XG4gIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNvcHk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaW50ZXJuYWwvYmFzZUNvcHkuanNcbiAqKiBtb2R1bGUgaWQgPSA2MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNBcnJheUxpa2UnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBzaGltS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3NoaW1LZXlzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ICE9ICdmdW5jdGlvbicgJiYgaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL29iamVjdC9rZXlzLmpzXG4gKiogbW9kdWxlIGlkID0gNjFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBvZiBgT2JqZWN0LmtleXNgIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlXG4gKiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gc2hpbUtleXMob2JqZWN0KSB7XG4gIHZhciBwcm9wcyA9IGtleXNJbihvYmplY3QpLFxuICAgICAgcHJvcHNMZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICBsZW5ndGggPSBwcm9wc0xlbmd0aCAmJiBvYmplY3QubGVuZ3RoO1xuXG4gIHZhciBhbGxvd0luZGV4ZXMgPSAhIWxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgcHJvcHNMZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIGlmICgoYWxsb3dJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaGltS2V5cztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pbnRlcm5hbC9zaGltS2V5cy5qc1xuICoqIG1vZHVsZSBpZCA9IDYyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmluZENhbGxiYWNrID0gcmVxdWlyZSgnLi9iaW5kQ2FsbGJhY2snKSxcbiAgICBpc0l0ZXJhdGVlQ2FsbCA9IHJlcXVpcmUoJy4vaXNJdGVyYXRlZUNhbGwnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuLi9mdW5jdGlvbi9yZXN0UGFyYW0nKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uYXNzaWduYCwgYF8uZGVmYXVsdHNgLCBvciBgXy5tZXJnZWAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbmVyIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYXNzaWduZXIgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7XG4gIHJldHVybiByZXN0UGFyYW0oZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG9iamVjdCA9PSBudWxsID8gMCA6IHNvdXJjZXMubGVuZ3RoLFxuICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoID4gMiA/IHNvdXJjZXNbbGVuZ3RoIC0gMl0gOiB1bmRlZmluZWQsXG4gICAgICAgIGd1YXJkID0gbGVuZ3RoID4gMiA/IHNvdXJjZXNbMl0gOiB1bmRlZmluZWQsXG4gICAgICAgIHRoaXNBcmcgPSBsZW5ndGggPiAxID8gc291cmNlc1tsZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcblxuICAgIGlmICh0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjdXN0b21pemVyID0gYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDUpO1xuICAgICAgbGVuZ3RoIC09IDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgdGhpc0FyZyA9PSAnZnVuY3Rpb24nID8gdGhpc0FyZyA6IHVuZGVmaW5lZDtcbiAgICAgIGxlbmd0aCAtPSAoY3VzdG9taXplciA/IDEgOiAwKTtcbiAgICB9XG4gICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHNvdXJjZXNbMF0sIHNvdXJjZXNbMV0sIGd1YXJkKSkge1xuICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiBjdXN0b21pemVyO1xuICAgICAgbGVuZ3RoID0gMTtcbiAgICB9XG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgYXNzaWduZXIob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVBc3NpZ25lcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVBc3NpZ25lci5qc1xuICoqIG1vZHVsZSBpZCA9IDYzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2JpbmRDYWxsYmFjay5qc1xuICoqIG1vZHVsZSBpZCA9IDY0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IHByb3ZpZGVkIHRvIGl0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICogQHBhcmFtIHsqfSB2YWx1ZSBBbnkgdmFsdWUuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyBgdmFsdWVgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICpcbiAqIF8uaWRlbnRpdHkob2JqZWN0KSA9PT0gb2JqZWN0O1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpZGVudGl0eSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaWRlbnRpdHk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvdXRpbGl0eS9pZGVudGl0eS5qc1xuICoqIG1vZHVsZSBpZCA9IDY1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSkge1xuICAgIHZhciBvdGhlciA9IG9iamVjdFtpbmRleF07XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSXRlcmF0ZWVDYWxsO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2ludGVybmFsL2lzSXRlcmF0ZWVDYWxsLmpzXG4gKiogbW9kdWxlIGlkID0gNjZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZVxuICogY3JlYXRlZCBmdW5jdGlvbiBhbmQgYXJndW1lbnRzIGZyb20gYHN0YXJ0YCBhbmQgYmV5b25kIHByb3ZpZGVkIGFzIGFuIGFycmF5LlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGUgW3Jlc3QgcGFyYW1ldGVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvRnVuY3Rpb25zL3Jlc3RfcGFyYW1ldGVycykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgc2F5ID0gXy5yZXN0UGFyYW0oZnVuY3Rpb24od2hhdCwgbmFtZXMpIHtcbiAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gKiB9KTtcbiAqXG4gKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAqIC8vID0+ICdoZWxsbyBmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gcmVzdFBhcmFtKGZ1bmMsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0ID09PSB1bmRlZmluZWQgPyAoZnVuYy5sZW5ndGggLSAxKSA6ICgrc3RhcnQgfHwgMCksIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgcmVzdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdFtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgIH1cbiAgICBzd2l0Y2ggKHN0YXJ0KSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpcywgcmVzdCk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgcmVzdCk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSwgcmVzdCk7XG4gICAgfVxuICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgIGluZGV4ID0gLTE7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gcmVzdDtcbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBvdGhlckFyZ3MpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RQYXJhbTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9mdW5jdGlvbi9yZXN0UGFyYW0uanNcbiAqKiBtb2R1bGUgaWQgPSA2N1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQge1xuICAgIGlucHV0U3RyZWFtOiB7XG4gICAgICAgIG5hbWU6IFwiTGl2ZVwiLFxuICAgICAgICB0eXBlOiBcIkxpdmVTdHJlYW1cIixcbiAgICAgICAgY29uc3RyYWludHM6IHtcbiAgICAgICAgICAgIHdpZHRoOiA2NDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDQ4MCxcbiAgICAgICAgICAgIG1pbkFzcGVjdFJhdGlvOiAwLFxuICAgICAgICAgICAgbWF4QXNwZWN0UmF0aW86IDEwMCxcbiAgICAgICAgICAgIGZhY2luZzogXCJlbnZpcm9ubWVudFwiIC8vIG9yIHVzZXJcbiAgICAgICAgfSxcbiAgICAgICAgYXJlYToge1xuICAgICAgICAgICAgdG9wOiBcIjAlXCIsXG4gICAgICAgICAgICByaWdodDogXCIwJVwiLFxuICAgICAgICAgICAgbGVmdDogXCIwJVwiLFxuICAgICAgICAgICAgYm90dG9tOiBcIjAlXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2luZ2xlQ2hhbm5lbDogZmFsc2UgLy8gdHJ1ZTogb25seSB0aGUgcmVkIGNvbG9yLWNoYW5uZWwgaXMgcmVhZFxuICAgIH0sXG4gICAgdHJhY2tpbmc6IGZhbHNlLFxuICAgIGRlYnVnOiBmYWxzZSxcbiAgICBjb250cm9sczogZmFsc2UsXG4gICAgbG9jYXRlOiB0cnVlLFxuICAgIG51bU9mV29ya2VyczogNCxcbiAgICB2aXN1YWw6IHtcbiAgICAgICAgc2hvdzogdHJ1ZVxuICAgIH0sXG4gICAgZGVjb2Rlcjoge1xuICAgICAgICBkcmF3Qm91bmRpbmdCb3g6IGZhbHNlLFxuICAgICAgICBzaG93RnJlcXVlbmN5OiBmYWxzZSxcbiAgICAgICAgZHJhd1NjYW5saW5lOiBmYWxzZSxcbiAgICAgICAgc2hvd1BhdHRlcm46IGZhbHNlLFxuICAgICAgICByZWFkZXJzOiBbXG4gICAgICAgICAgICAnY29kZV8xMjhfcmVhZGVyJ1xuICAgICAgICBdXG4gICAgfSxcbiAgICBsb2NhdG9yOiB7XG4gICAgICAgIGhhbGZTYW1wbGU6IHRydWUsXG4gICAgICAgIHBhdGNoU2l6ZTogXCJtZWRpdW1cIiwgLy8geC1zbWFsbCwgc21hbGwsIG1lZGl1bSwgbGFyZ2UsIHgtbGFyZ2VcbiAgICAgICAgc2hvd0NhbnZhczogZmFsc2UsXG4gICAgICAgIHNob3dQYXRjaGVzOiBmYWxzZSxcbiAgICAgICAgc2hvd0ZvdW5kUGF0Y2hlczogZmFsc2UsXG4gICAgICAgIHNob3dTa2VsZXRvbjogZmFsc2UsXG4gICAgICAgIHNob3dMYWJlbHM6IGZhbHNlLFxuICAgICAgICBzaG93UGF0Y2hMYWJlbHM6IGZhbHNlLFxuICAgICAgICBzaG93UmVtYWluaW5nUGF0Y2hMYWJlbHM6IGZhbHNlLFxuICAgICAgICBib3hGcm9tUGF0Y2hlczoge1xuICAgICAgICAgICAgc2hvd1RyYW5zZm9ybWVkOiBmYWxzZSxcbiAgICAgICAgICAgIHNob3dUcmFuc2Zvcm1lZEJveDogZmFsc2UsXG4gICAgICAgICAgICBzaG93QkI6IGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY29uZmlnLmpzXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uKCkge1xuICAgIHZhciBldmVudHMgPSB7fTtcblxuICAgIGZ1bmN0aW9uIGdldEV2ZW50KGV2ZW50TmFtZSkge1xuICAgICAgICBpZiAoIWV2ZW50c1tldmVudE5hbWVdKSB7XG4gICAgICAgICAgICBldmVudHNbZXZlbnROYW1lXSA9IHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyczogW11cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV2ZW50c1tldmVudE5hbWVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFyRXZlbnRzKCl7XG4gICAgICAgIGV2ZW50cyA9IHt9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHB1Ymxpc2hTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uLCBkYXRhKSB7XG4gICAgICAgIGlmIChzdWJzY3JpcHRpb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLmNhbGxiYWNrKGRhdGEpO1xuICAgICAgICAgICAgfSwgNCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdWJzY3JpcHRpb24uY2FsbGJhY2soZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdWJzY3JpYmUoZXZlbnQsIGNhbGxiYWNrLCBhc3luYykge1xuICAgICAgICB2YXIgc3Vic2NyaXB0aW9uO1xuXG4gICAgICAgIGlmICggdHlwZW9mIGNhbGxiYWNrID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgYXN5bmM6IGFzeW5jXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3Vic2NyaXB0aW9uID0gY2FsbGJhY2s7XG4gICAgICAgICAgICBpZiAoIXN1YnNjcmlwdGlvbi5jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIHRocm93IFwiQ2FsbGJhY2sgd2FzIG5vdCBzcGVjaWZpZWQgb24gb3B0aW9uc1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZ2V0RXZlbnQoZXZlbnQpLnN1YnNjcmliZXJzLnB1c2goc3Vic2NyaXB0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBzdWJzY3JpYmU6IGZ1bmN0aW9uKGV2ZW50LCBjYWxsYmFjaywgYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBzdWJzY3JpYmUoZXZlbnQsIGNhbGxiYWNrLCBhc3luYyk7XG4gICAgICAgIH0sXG4gICAgICAgIHB1Ymxpc2g6IGZ1bmN0aW9uKGV2ZW50TmFtZSwgZGF0YSkge1xuICAgICAgICAgICAgdmFyIGV2ZW50ID0gZ2V0RXZlbnQoZXZlbnROYW1lKSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVycyA9IGV2ZW50LnN1YnNjcmliZXJzO1xuXG4gICAgICAgICAgICBldmVudC5zdWJzY3JpYmVycyA9IHN1YnNjcmliZXJzLmZpbHRlcihmdW5jdGlvbihzdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgcHVibGlzaFN1YnNjcmlwdGlvbihzdWJzY3JpYmVyLCBkYXRhKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXN1YnNjcmliZXIub25jZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBvbmNlOiBmdW5jdGlvbihldmVudCwgY2FsbGJhY2ssIGFzeW5jKSB7XG4gICAgICAgICAgICBzdWJzY3JpYmUoZXZlbnQsIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgYXN5bmM6IGFzeW5jLFxuICAgICAgICAgICAgICAgIG9uY2U6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICB1bnN1YnNjcmliZTogZnVuY3Rpb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIGV2ZW50O1xuXG4gICAgICAgICAgICBpZiAoZXZlbnROYW1lKSB7XG4gICAgICAgICAgICAgICAgZXZlbnQgPSBnZXRFdmVudChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5zdWJzY3JpYmVycyA9IGV2ZW50LnN1YnNjcmliZXJzLmZpbHRlcihmdW5jdGlvbihzdWJzY3JpYmVyKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJzY3JpYmVyLmNhbGxiYWNrICE9PSBjYWxsYmFjaztcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3Vic2NyaWJlcnMgPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNsZWFyRXZlbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufSkoKTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2V2ZW50cy5qc1xuICoqLyIsImNvbnN0IG1lcmdlID0gcmVxdWlyZSgnbG9kYXNoL29iamVjdC9tZXJnZScpO1xuXG52YXIgc3RyZWFtUmVmLFxuICAgIGxvYWRlZERhdGFIYW5kbGVyO1xuXG4vKipcbiAqIFdyYXBzIGJyb3dzZXItc3BlY2lmaWMgZ2V0VXNlck1lZGlhXG4gKiBAcGFyYW0ge09iamVjdH0gY29uc3RyYWludHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdWNjZXNzIENhbGxiYWNrXG4gKiBAcGFyYW0ge09iamVjdH0gZmFpbHVyZSBDYWxsYmFja1xuICovXG5mdW5jdGlvbiBnZXRVc2VyTWVkaWEoY29uc3RyYWludHMsIHN1Y2Nlc3MsIGZhaWx1cmUpIHtcbiAgICBpZiAodHlwZW9mIG5hdmlnYXRvci5nZXRVc2VyTWVkaWEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMsIGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgICAgICAgICAgIHN0cmVhbVJlZiA9IHN0cmVhbTtcbiAgICAgICAgICAgIHZhciB2aWRlb1NyYyA9ICh3aW5kb3cuVVJMICYmIHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSkpIHx8IHN0cmVhbTtcbiAgICAgICAgICAgIHN1Y2Nlc3MuYXBwbHkobnVsbCwgW3ZpZGVvU3JjXSk7XG4gICAgICAgIH0sIGZhaWx1cmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZhaWx1cmUobmV3IFR5cGVFcnJvcihcImdldFVzZXJNZWRpYSBub3QgYXZhaWxhYmxlXCIpKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRlZERhdGEodmlkZW8sIGNhbGxiYWNrKSB7XG4gICAgdmFyIGF0dGVtcHRzID0gMTA7XG5cbiAgICBmdW5jdGlvbiBjaGVja1ZpZGVvKCkge1xuICAgICAgICBpZiAoYXR0ZW1wdHMgPiAwKSB7XG4gICAgICAgICAgICBpZiAodmlkZW8udmlkZW9XaWR0aCA+IDAgJiYgdmlkZW8udmlkZW9IZWlnaHQgPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codmlkZW8udmlkZW9XaWR0aCArIFwicHggeCBcIiArIHZpZGVvLnZpZGVvSGVpZ2h0ICsgXCJweFwiKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChjaGVja1ZpZGVvLCA1MDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2soJ1VuYWJsZSB0byBwbGF5IHZpZGVvIHN0cmVhbS4gSXMgd2ViY2FtIHdvcmtpbmc/Jyk7XG4gICAgICAgIH1cbiAgICAgICAgYXR0ZW1wdHMtLTtcbiAgICB9XG4gICAgY2hlY2tWaWRlbygpO1xufVxuXG4vKipcbiAqIFRyaWVzIHRvIGF0dGFjaCB0aGUgY2FtZXJhLXN0cmVhbSB0byBhIGdpdmVuIHZpZGVvLWVsZW1lbnRcbiAqIGFuZCBjYWxscyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gd2hlbiB0aGUgY29udGVudCBpcyByZWFkeVxuICogQHBhcmFtIHtPYmplY3R9IGNvbnN0cmFpbnRzXG4gKiBAcGFyYW0ge09iamVjdH0gdmlkZW9cbiAqIEBwYXJhbSB7T2JqZWN0fSBjYWxsYmFja1xuICovXG5mdW5jdGlvbiBpbml0Q2FtZXJhKGNvbnN0cmFpbnRzLCB2aWRlbywgY2FsbGJhY2spIHtcbiAgICBnZXRVc2VyTWVkaWEoY29uc3RyYWludHMsIGZ1bmN0aW9uKHNyYykge1xuICAgICAgICB2aWRlby5zcmMgPSBzcmM7XG4gICAgICAgIGlmIChsb2FkZWREYXRhSGFuZGxlcikge1xuICAgICAgICAgICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImxvYWRlZGRhdGFcIiwgbG9hZGVkRGF0YUhhbmRsZXIsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBsb2FkZWREYXRhSGFuZGxlciA9IGxvYWRlZERhdGEuYmluZChudWxsLCB2aWRlbywgY2FsbGJhY2spO1xuICAgICAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdsb2FkZWRkYXRhJywgbG9hZGVkRGF0YUhhbmRsZXIsIGZhbHNlKTtcbiAgICAgICAgdmlkZW8ucGxheSgpO1xuICAgIH0sIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgY2FsbGJhY2soZSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyB0aGUgaW5jb21pbmcgY29uc3RyYWludHMgdG8gc2F0aXNmeSB0aGUgY3VycmVudCBicm93c2VyXG4gKiBAcGFyYW0gY29uZmlnXG4gKiBAcGFyYW0gY2IgQ2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW5ldmVyIGNvbnN0cmFpbnRzIGFyZSBjcmVhdGVkXG4gKiBAcmV0dXJucyB7Kn1cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplQ29uc3RyYWludHMoY29uZmlnLCBjYikge1xuICAgIHZhciBjb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgIGF1ZGlvOiBmYWxzZSxcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIHZpZGVvQ29uc3RyYWludHMgPSBtZXJnZSh7XG4gICAgICAgICAgICB3aWR0aDogNjQwLFxuICAgICAgICAgICAgaGVpZ2h0OiA0ODAsXG4gICAgICAgICAgICBtaW5Bc3BlY3RSYXRpbzogMCxcbiAgICAgICAgICAgIG1heEFzcGVjdFJhdGlvOiAxMDAsXG4gICAgICAgICAgICBmYWNpbmc6IFwiZW52aXJvbm1lbnRcIlxuICAgICAgICB9LCBjb25maWcpO1xuXG4gICAgaWYgKCB0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2suZ2V0U291cmNlcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgTWVkaWFTdHJlYW1UcmFjay5nZXRTb3VyY2VzKGZ1bmN0aW9uKHNvdXJjZUluZm9zKSB7XG4gICAgICAgICAgICB2YXIgdmlkZW9Tb3VyY2VJZDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlSW5mb3MubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICB2YXIgc291cmNlSW5mbyA9IHNvdXJjZUluZm9zW2ldO1xuICAgICAgICAgICAgICAgIGlmIChzb3VyY2VJbmZvLmtpbmQgPT09IFwidmlkZW9cIiAmJiBzb3VyY2VJbmZvLmZhY2luZyA9PT0gdmlkZW9Db25zdHJhaW50cy5mYWNpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9Tb3VyY2VJZCA9IHNvdXJjZUluZm8uaWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3RyYWludHMudmlkZW8gPSB7XG4gICAgICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgICAgIG1pbldpZHRoOiB2aWRlb0NvbnN0cmFpbnRzLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICBtaW5IZWlnaHQ6IHZpZGVvQ29uc3RyYWludHMuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICBtaW5Bc3BlY3RSYXRpbzogdmlkZW9Db25zdHJhaW50cy5taW5Bc3BlY3RSYXRpbyxcbiAgICAgICAgICAgICAgICAgICAgbWF4QXNwZWN0UmF0aW86IHZpZGVvQ29uc3RyYWludHMubWF4QXNwZWN0UmF0aW9cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBbe1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2VJZDogdmlkZW9Tb3VyY2VJZFxuICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIGNiKGNvbnN0cmFpbnRzKTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3RyYWludHMudmlkZW8gPSB7XG4gICAgICAgICAgICBtZWRpYVNvdXJjZTogXCJjYW1lcmFcIixcbiAgICAgICAgICAgIHdpZHRoOiB7IG1pbjogdmlkZW9Db25zdHJhaW50cy53aWR0aCwgbWF4OiB2aWRlb0NvbnN0cmFpbnRzLndpZHRoIH0sXG4gICAgICAgICAgICBoZWlnaHQ6IHsgbWluOiB2aWRlb0NvbnN0cmFpbnRzLmhlaWdodCwgbWF4OiB2aWRlb0NvbnN0cmFpbnRzLmhlaWdodCB9LFxuICAgICAgICAgICAgcmVxdWlyZTogW1wid2lkdGhcIiwgXCJoZWlnaHRcIl1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNiKGNvbnN0cmFpbnRzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUmVxdWVzdHMgdGhlIGJhY2stZmFjaW5nIGNhbWVyYSBvZiB0aGUgdXNlci4gVGhlIGNhbGxiYWNrIGlzIGNhbGxlZFxuICogd2hlbmV2ZXIgdGhlIHN0cmVhbSBpcyByZWFkeSB0byBiZSBjb25zdW1lZCwgb3IgaWYgYW4gZXJyb3Igb2NjdXJlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSB2aWRlb1xuICogQHBhcmFtIHtPYmplY3R9IGNhbGxiYWNrXG4gKi9cbmZ1bmN0aW9uIHJlcXVlc3QodmlkZW8sIHZpZGVvQ29uc3RyYWludHMsIGNhbGxiYWNrKSB7XG4gICAgbm9ybWFsaXplQ29uc3RyYWludHModmlkZW9Db25zdHJhaW50cywgZnVuY3Rpb24oY29uc3RyYWludHMpIHtcbiAgICAgICAgaW5pdENhbWVyYShjb25zdHJhaW50cywgdmlkZW8sIGNhbGxiYWNrKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIHJlcXVlc3Q6IGZ1bmN0aW9uKHZpZGVvLCBjb25zdHJhaW50cywgY2FsbGJhY2spIHtcbiAgICAgICAgcmVxdWVzdCh2aWRlbywgY29uc3RyYWludHMsIGNhbGxiYWNrKTtcbiAgICB9LFxuICAgIHJlbGVhc2U6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdHJhY2tzID0gc3RyZWFtUmVmICYmIHN0cmVhbVJlZi5nZXRWaWRlb1RyYWNrcygpO1xuICAgICAgICBpZiAodHJhY2tzLmxlbmd0aCkge1xuICAgICAgICAgICAgdHJhY2tzWzBdLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICBzdHJlYW1SZWYgPSBudWxsO1xuICAgIH1cbn07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jYW1lcmFfYWNjZXNzLmpzXG4gKiovIiwiaW1wb3J0IEltYWdlRGVidWcgZnJvbSAnLi9pbWFnZV9kZWJ1Zyc7XG5cbmZ1bmN0aW9uIGNvbnRhaW5zKGNvZGVSZXN1bHQsIGxpc3QpIHtcbiAgICBpZiAobGlzdCkge1xuICAgICAgICByZXR1cm4gbGlzdC5zb21lKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoaXRlbSkuZXZlcnkoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtW2tleV0gPT09IGNvZGVSZXN1bHRba2V5XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBwYXNzZXNGaWx0ZXIoY29kZVJlc3VsdCwgZmlsdGVyKSB7XG4gICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIGZpbHRlcihjb2RlUmVzdWx0KTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBjcmVhdGU6IGZ1bmN0aW9uKGNvbmZpZykge1xuICAgICAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKSxcbiAgICAgICAgICAgIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIiksXG4gICAgICAgICAgICByZXN1bHRzID0gW10sXG4gICAgICAgICAgICBjYXBhY2l0eSA9IGNvbmZpZy5jYXBhY2l0eSB8fCAyMCxcbiAgICAgICAgICAgIGNhcHR1cmUgPSBjb25maWcuY2FwdHVyZSA9PT0gdHJ1ZTtcblxuICAgICAgICBmdW5jdGlvbiBtYXRjaGVzQ29uc3RyYWludHMoY29kZVJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhcGFjaXR5XG4gICAgICAgICAgICAgICAgJiYgY29kZVJlc3VsdFxuICAgICAgICAgICAgICAgICYmICFjb250YWlucyhjb2RlUmVzdWx0LCBjb25maWcuYmxhY2tsaXN0KVxuICAgICAgICAgICAgICAgICYmIHBhc3Nlc0ZpbHRlcihjb2RlUmVzdWx0LCBjb25maWcuZmlsdGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhZGRSZXN1bHQ6IGZ1bmN0aW9uKGRhdGEsIGltYWdlU2l6ZSwgY29kZVJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB7fTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzQ29uc3RyYWludHMoY29kZVJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FwYWNpdHktLTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmNvZGVSZXN1bHQgPSBjb2RlUmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2FwdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FudmFzLndpZHRoID0gaW1hZ2VTaXplLng7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2VTaXplLnk7XG4gICAgICAgICAgICAgICAgICAgICAgICBJbWFnZURlYnVnLmRyYXdJbWFnZShkYXRhLCBpbWFnZVNpemUsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuZnJhbWUgPSBjYW52YXMudG9EYXRhVVJMKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldFJlc3VsdHM6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbn07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9yZXN1bHRfY29sbGVjdG9yLmpzXG4gKiovIiwiaW1wb3J0IEltYWdlTG9hZGVyIGZyb20gJy4vaW1hZ2VfbG9hZGVyJztcblxudmFyIElucHV0U3RyZWFtID0ge307XG5JbnB1dFN0cmVhbS5jcmVhdGVWaWRlb1N0cmVhbSA9IGZ1bmN0aW9uKHZpZGVvKSB7XG4gICAgdmFyIHRoYXQgPSB7fSxcbiAgICAgICAgX2NvbmZpZyA9IG51bGwsXG4gICAgICAgIF9ldmVudE5hbWVzID0gWydjYW5yZWNvcmQnLCAnZW5kZWQnXSxcbiAgICAgICAgX2V2ZW50SGFuZGxlcnMgPSB7fSxcbiAgICAgICAgX2NhbGN1bGF0ZWRXaWR0aCxcbiAgICAgICAgX2NhbGN1bGF0ZWRIZWlnaHQsXG4gICAgICAgIF90b3BSaWdodCA9IHt4OiAwLCB5OiAwfSxcbiAgICAgICAgX2NhbnZhc1NpemUgPSB7eDogMCwgeTogMH07XG5cbiAgICBmdW5jdGlvbiBpbml0U2l6ZSgpIHtcbiAgICAgICAgdmFyIHdpZHRoID0gdmlkZW8udmlkZW9XaWR0aCxcbiAgICAgICAgICAgIGhlaWdodCA9IHZpZGVvLnZpZGVvSGVpZ2h0O1xuXG4gICAgICAgIF9jYWxjdWxhdGVkV2lkdGggPVxuICAgICAgICAgICAgX2NvbmZpZy5zaXplID8gd2lkdGggLyBoZWlnaHQgPiAxID8gX2NvbmZpZy5zaXplIDogTWF0aC5mbG9vcigod2lkdGggLyBoZWlnaHQpICogX2NvbmZpZy5zaXplKSA6IHdpZHRoO1xuICAgICAgICBfY2FsY3VsYXRlZEhlaWdodCA9XG4gICAgICAgICAgICBfY29uZmlnLnNpemUgPyB3aWR0aCAvIGhlaWdodCA+IDEgPyBNYXRoLmZsb29yKChoZWlnaHQgLyB3aWR0aCkgKiBfY29uZmlnLnNpemUpIDogX2NvbmZpZy5zaXplIDogaGVpZ2h0O1xuXG4gICAgICAgIF9jYW52YXNTaXplLnggPSBfY2FsY3VsYXRlZFdpZHRoO1xuICAgICAgICBfY2FudmFzU2l6ZS55ID0gX2NhbGN1bGF0ZWRIZWlnaHQ7XG4gICAgfVxuXG4gICAgdGhhdC5nZXRSZWFsV2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHZpZGVvLnZpZGVvV2lkdGg7XG4gICAgfTtcblxuICAgIHRoYXQuZ2V0UmVhbEhlaWdodCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdmlkZW8udmlkZW9IZWlnaHQ7XG4gICAgfTtcblxuICAgIHRoYXQuZ2V0V2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9jYWxjdWxhdGVkV2lkdGg7XG4gICAgfTtcblxuICAgIHRoYXQuZ2V0SGVpZ2h0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBfY2FsY3VsYXRlZEhlaWdodDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRXaWR0aCA9IGZ1bmN0aW9uKHdpZHRoKSB7XG4gICAgICAgIF9jYWxjdWxhdGVkV2lkdGggPSB3aWR0aDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRIZWlnaHQgPSBmdW5jdGlvbihoZWlnaHQpIHtcbiAgICAgICAgX2NhbGN1bGF0ZWRIZWlnaHQgPSBoZWlnaHQ7XG4gICAgfTtcblxuICAgIHRoYXQuc2V0SW5wdXRTdHJlYW0gPSBmdW5jdGlvbihjb25maWcpIHtcbiAgICAgICAgX2NvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdmlkZW8uc3JjID0gKHR5cGVvZiBjb25maWcuc3JjICE9PSAndW5kZWZpbmVkJykgPyBjb25maWcuc3JjIDogJyc7XG4gICAgfTtcblxuICAgIHRoYXQuZW5kZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHZpZGVvLmVuZGVkO1xuICAgIH07XG5cbiAgICB0aGF0LmdldENvbmZpZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gX2NvbmZpZztcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgICB2aWRlby5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICB0aGF0LnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZpZGVvLnBhdXNlKCk7XG4gICAgfTtcblxuICAgIHRoYXQucGxheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2aWRlby5wbGF5KCk7XG4gICAgfTtcblxuICAgIHRoYXQuc2V0Q3VycmVudFRpbWUgPSBmdW5jdGlvbih0aW1lKSB7XG4gICAgICAgIGlmIChfY29uZmlnLnR5cGUgIT09IFwiTGl2ZVN0cmVhbVwiKSB7XG4gICAgICAgICAgICB2aWRlby5jdXJyZW50VGltZSA9IHRpbWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhhdC5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGYsIGJvb2wpIHtcbiAgICAgICAgaWYgKF9ldmVudE5hbWVzLmluZGV4T2YoZXZlbnQpICE9PSAtMSkge1xuICAgICAgICAgICAgaWYgKCFfZXZlbnRIYW5kbGVyc1tldmVudF0pIHtcbiAgICAgICAgICAgICAgICBfZXZlbnRIYW5kbGVyc1tldmVudF0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ldmVudEhhbmRsZXJzW2V2ZW50XS5wdXNoKGYpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgZiwgYm9vbCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhhdC5jbGVhckV2ZW50SGFuZGxlcnMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgX2V2ZW50TmFtZXMuZm9yRWFjaChmdW5jdGlvbihldmVudE5hbWUpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGVycyA9IF9ldmVudEhhbmRsZXJzW2V2ZW50TmFtZV07XG4gICAgICAgICAgICBpZiAoaGFuZGxlcnMgJiYgaGFuZGxlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzLmZvckVhY2goZnVuY3Rpb24oaGFuZGxlcikge1xuICAgICAgICAgICAgICAgICAgICB2aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICB0aGF0LnRyaWdnZXIgPSBmdW5jdGlvbihldmVudE5hbWUsIGFyZ3MpIHtcbiAgICAgICAgdmFyIGosXG4gICAgICAgICAgICBoYW5kbGVycyA9IF9ldmVudEhhbmRsZXJzW2V2ZW50TmFtZV07XG5cbiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2NhbnJlY29yZCcpIHtcbiAgICAgICAgICAgIGluaXRTaXplKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhbmRsZXJzICYmIGhhbmRsZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoIGogPSAwOyBqIDwgaGFuZGxlcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVyc1tqXS5hcHBseSh0aGF0LCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB0aGF0LnNldFRvcFJpZ2h0ID0gZnVuY3Rpb24odG9wUmlnaHQpIHtcbiAgICAgICAgX3RvcFJpZ2h0LnggPSB0b3BSaWdodC54O1xuICAgICAgICBfdG9wUmlnaHQueSA9IHRvcFJpZ2h0Lnk7XG4gICAgfTtcblxuICAgIHRoYXQuZ2V0VG9wUmlnaHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF90b3BSaWdodDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRDYW52YXNTaXplID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgICBfY2FudmFzU2l6ZS54ID0gc2l6ZS54O1xuICAgICAgICBfY2FudmFzU2l6ZS55ID0gc2l6ZS55O1xuICAgIH07XG5cbiAgICB0aGF0LmdldENhbnZhc1NpemUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9jYW52YXNTaXplO1xuICAgIH07XG5cbiAgICB0aGF0LmdldEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2aWRlbztcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoYXQ7XG59O1xuXG5JbnB1dFN0cmVhbS5jcmVhdGVMaXZlU3RyZWFtID0gZnVuY3Rpb24odmlkZW8pIHtcbiAgICB2aWRlby5zZXRBdHRyaWJ1dGUoXCJhdXRvcGxheVwiLCB0cnVlKTtcbiAgICB2YXIgdGhhdCA9IElucHV0U3RyZWFtLmNyZWF0ZVZpZGVvU3RyZWFtKHZpZGVvKTtcblxuICAgIHRoYXQuZW5kZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICByZXR1cm4gdGhhdDtcbn07XG5cbklucHV0U3RyZWFtLmNyZWF0ZUltYWdlU3RyZWFtID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRoYXQgPSB7fTtcbiAgICB2YXIgX2NvbmZpZyA9IG51bGw7XG5cbiAgICB2YXIgd2lkdGggPSAwLFxuICAgICAgICBoZWlnaHQgPSAwLFxuICAgICAgICBmcmFtZUlkeCA9IDAsXG4gICAgICAgIHBhdXNlZCA9IHRydWUsXG4gICAgICAgIGxvYWRlZCA9IGZhbHNlLFxuICAgICAgICBpbWdBcnJheSA9IG51bGwsXG4gICAgICAgIHNpemUgPSAwLFxuICAgICAgICBvZmZzZXQgPSAxLFxuICAgICAgICBiYXNlVXJsID0gbnVsbCxcbiAgICAgICAgZW5kZWQgPSBmYWxzZSxcbiAgICAgICAgY2FsY3VsYXRlZFdpZHRoLFxuICAgICAgICBjYWxjdWxhdGVkSGVpZ2h0LFxuICAgICAgICBfZXZlbnROYW1lcyA9IFsnY2FucmVjb3JkJywgJ2VuZGVkJ10sXG4gICAgICAgIF9ldmVudEhhbmRsZXJzID0ge30sXG4gICAgICAgIF90b3BSaWdodCA9IHt4OiAwLCB5OiAwfSxcbiAgICAgICAgX2NhbnZhc1NpemUgPSB7eDogMCwgeTogMH07XG5cbiAgICBmdW5jdGlvbiBsb2FkSW1hZ2VzKCkge1xuICAgICAgICBsb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgSW1hZ2VMb2FkZXIubG9hZChiYXNlVXJsLCBmdW5jdGlvbihpbWdzKSB7XG4gICAgICAgICAgICBpbWdBcnJheSA9IGltZ3M7XG4gICAgICAgICAgICB3aWR0aCA9IGltZ3NbMF0ud2lkdGg7XG4gICAgICAgICAgICBoZWlnaHQgPSBpbWdzWzBdLmhlaWdodDtcbiAgICAgICAgICAgIGNhbGN1bGF0ZWRXaWR0aCA9XG4gICAgICAgICAgICAgICAgX2NvbmZpZy5zaXplID8gd2lkdGggLyBoZWlnaHQgPiAxID8gX2NvbmZpZy5zaXplIDogTWF0aC5mbG9vcigod2lkdGggLyBoZWlnaHQpICogX2NvbmZpZy5zaXplKSA6IHdpZHRoO1xuICAgICAgICAgICAgY2FsY3VsYXRlZEhlaWdodCA9XG4gICAgICAgICAgICAgICAgX2NvbmZpZy5zaXplID8gd2lkdGggLyBoZWlnaHQgPiAxID8gTWF0aC5mbG9vcigoaGVpZ2h0IC8gd2lkdGgpICogX2NvbmZpZy5zaXplKSA6IF9jb25maWcuc2l6ZSA6IGhlaWdodDtcbiAgICAgICAgICAgIF9jYW52YXNTaXplLnggPSBjYWxjdWxhdGVkV2lkdGg7XG4gICAgICAgICAgICBfY2FudmFzU2l6ZS55ID0gY2FsY3VsYXRlZEhlaWdodDtcbiAgICAgICAgICAgIGxvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICBmcmFtZUlkeCA9IDA7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hFdmVudChcImNhbnJlY29yZFwiLCBbXSk7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfSwgb2Zmc2V0LCBzaXplLCBfY29uZmlnLnNlcXVlbmNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwdWJsaXNoRXZlbnQoZXZlbnROYW1lLCBhcmdzKSB7XG4gICAgICAgIHZhciBqLFxuICAgICAgICAgICAgaGFuZGxlcnMgPSBfZXZlbnRIYW5kbGVyc1tldmVudE5hbWVdO1xuXG4gICAgICAgIGlmIChoYW5kbGVycyAmJiBoYW5kbGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IGhhbmRsZXJzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlcnNbal0uYXBwbHkodGhhdCwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIHRoYXQudHJpZ2dlciA9IHB1Ymxpc2hFdmVudDtcblxuICAgIHRoYXQuZ2V0V2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNhbGN1bGF0ZWRXaWR0aDtcbiAgICB9O1xuXG4gICAgdGhhdC5nZXRIZWlnaHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNhbGN1bGF0ZWRIZWlnaHQ7XG4gICAgfTtcblxuICAgIHRoYXQuc2V0V2lkdGggPSBmdW5jdGlvbihuZXdXaWR0aCkge1xuICAgICAgICBjYWxjdWxhdGVkV2lkdGggPSBuZXdXaWR0aDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRIZWlnaHQgPSBmdW5jdGlvbihuZXdIZWlnaHQpIHtcbiAgICAgICAgY2FsY3VsYXRlZEhlaWdodCA9IG5ld0hlaWdodDtcbiAgICB9O1xuXG4gICAgdGhhdC5nZXRSZWFsV2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHdpZHRoO1xuICAgIH07XG5cbiAgICB0aGF0LmdldFJlYWxIZWlnaHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGhlaWdodDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRJbnB1dFN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICBfY29uZmlnID0gc3RyZWFtO1xuICAgICAgICBpZiAoc3RyZWFtLnNlcXVlbmNlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYmFzZVVybCA9IHN0cmVhbS5zcmM7XG4gICAgICAgICAgICBzaXplID0gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJhc2VVcmwgPSBzdHJlYW0uc3JjO1xuICAgICAgICAgICAgc2l6ZSA9IHN0cmVhbS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgbG9hZEltYWdlcygpO1xuICAgIH07XG5cbiAgICB0aGF0LmVuZGVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBlbmRlZDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgdGhhdC5nZXRDb25maWcgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9jb25maWc7XG4gICAgfTtcblxuICAgIHRoYXQucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcGF1c2VkID0gdHJ1ZTtcbiAgICB9O1xuXG4gICAgdGhhdC5wbGF5ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgIH07XG5cbiAgICB0aGF0LnNldEN1cnJlbnRUaW1lID0gZnVuY3Rpb24odGltZSkge1xuICAgICAgICBmcmFtZUlkeCA9IHRpbWU7XG4gICAgfTtcblxuICAgIHRoYXQuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmKSB7XG4gICAgICAgIGlmIChfZXZlbnROYW1lcy5pbmRleE9mKGV2ZW50KSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGlmICghX2V2ZW50SGFuZGxlcnNbZXZlbnRdKSB7XG4gICAgICAgICAgICAgICAgX2V2ZW50SGFuZGxlcnNbZXZlbnRdID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfZXZlbnRIYW5kbGVyc1tldmVudF0ucHVzaChmKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB0aGF0LnNldFRvcFJpZ2h0ID0gZnVuY3Rpb24odG9wUmlnaHQpIHtcbiAgICAgICAgX3RvcFJpZ2h0LnggPSB0b3BSaWdodC54O1xuICAgICAgICBfdG9wUmlnaHQueSA9IHRvcFJpZ2h0Lnk7XG4gICAgfTtcblxuICAgIHRoYXQuZ2V0VG9wUmlnaHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF90b3BSaWdodDtcbiAgICB9O1xuXG4gICAgdGhhdC5zZXRDYW52YXNTaXplID0gZnVuY3Rpb24oY2FudmFzU2l6ZSkge1xuICAgICAgICBfY2FudmFzU2l6ZS54ID0gY2FudmFzU2l6ZS54O1xuICAgICAgICBfY2FudmFzU2l6ZS55ID0gY2FudmFzU2l6ZS55O1xuICAgIH07XG5cbiAgICB0aGF0LmdldENhbnZhc1NpemUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9jYW52YXNTaXplO1xuICAgIH07XG5cbiAgICB0aGF0LmdldEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBmcmFtZTtcblxuICAgICAgICBpZiAoIWxvYWRlZCl7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhdXNlZCkge1xuICAgICAgICAgICAgZnJhbWUgPSBpbWdBcnJheVtmcmFtZUlkeF07XG4gICAgICAgICAgICBpZiAoZnJhbWVJZHggPCAoc2l6ZSAtIDEpKSB7XG4gICAgICAgICAgICAgICAgZnJhbWVJZHgrKztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgZW5kZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBwdWJsaXNoRXZlbnQoXCJlbmRlZFwiLCBbXSk7XG4gICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZyYW1lO1xuICAgIH07XG5cbiAgICByZXR1cm4gdGhhdDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IElucHV0U3RyZWFtO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvaW5wdXRfc3RyZWFtLmpzXG4gKiovIiwidmFyIEltYWdlTG9hZGVyID0ge307XG5JbWFnZUxvYWRlci5sb2FkID0gZnVuY3Rpb24oZGlyZWN0b3J5LCBjYWxsYmFjaywgb2Zmc2V0LCBzaXplLCBzZXF1ZW5jZSkge1xuICAgIHZhciBodG1sSW1hZ2VzU3JjQXJyYXkgPSBuZXcgQXJyYXkoc2l6ZSksXG4gICAgICAgIGh0bWxJbWFnZXNBcnJheSA9IG5ldyBBcnJheShodG1sSW1hZ2VzU3JjQXJyYXkubGVuZ3RoKSxcbiAgICAgICAgaSxcbiAgICAgICAgaW1nLFxuICAgICAgICBudW07XG5cbiAgICBpZiAoc2VxdWVuY2UgPT09IGZhbHNlKSB7XG4gICAgICAgIGh0bWxJbWFnZXNTcmNBcnJheVswXSA9IGRpcmVjdG9yeTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGh0bWxJbWFnZXNTcmNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbnVtID0gKG9mZnNldCArIGkpO1xuICAgICAgICAgICAgaHRtbEltYWdlc1NyY0FycmF5W2ldID0gZGlyZWN0b3J5ICsgXCJpbWFnZS1cIiArIChcIjAwXCIgKyBudW0pLnNsaWNlKC0zKSArIFwiLmpwZ1wiO1xuICAgICAgICB9XG4gICAgfVxuICAgIGh0bWxJbWFnZXNBcnJheS5ub3RMb2FkZWQgPSBbXTtcbiAgICBodG1sSW1hZ2VzQXJyYXkuYWRkSW1hZ2UgPSBmdW5jdGlvbihpbWFnZSkge1xuICAgICAgICBodG1sSW1hZ2VzQXJyYXkubm90TG9hZGVkLnB1c2goaW1hZ2UpO1xuICAgIH07XG4gICAgaHRtbEltYWdlc0FycmF5LmxvYWRlZCA9IGZ1bmN0aW9uKGxvYWRlZEltZykge1xuICAgICAgICB2YXIgbm90bG9hZGVkSW1ncyA9IGh0bWxJbWFnZXNBcnJheS5ub3RMb2FkZWQ7XG4gICAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgbm90bG9hZGVkSW1ncy5sZW5ndGg7IHgrKykge1xuICAgICAgICAgICAgaWYgKG5vdGxvYWRlZEltZ3NbeF0gPT09IGxvYWRlZEltZykge1xuICAgICAgICAgICAgICAgIG5vdGxvYWRlZEltZ3Muc3BsaWNlKHgsIDEpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgaHRtbEltYWdlc1NyY0FycmF5Lmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbWdOYW1lID0gaHRtbEltYWdlc1NyY0FycmF5W3ldLnN1YnN0cihodG1sSW1hZ2VzU3JjQXJyYXlbeV0ubGFzdEluZGV4T2YoXCIvXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWRlZEltZy5zcmMubGFzdEluZGV4T2YoaW1nTmFtZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBodG1sSW1hZ2VzQXJyYXlbeV0gPSBsb2FkZWRJbWc7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobm90bG9hZGVkSW1ncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiSW1hZ2VzIGxvYWRlZFwiKTtcbiAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KG51bGwsIFtodG1sSW1hZ2VzQXJyYXldKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKCBpID0gMDsgaSA8IGh0bWxJbWFnZXNTcmNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaHRtbEltYWdlc0FycmF5LmFkZEltYWdlKGltZyk7XG4gICAgICAgIGFkZE9ubG9hZEhhbmRsZXIoaW1nLCBodG1sSW1hZ2VzQXJyYXkpO1xuICAgICAgICBpbWcuc3JjID0gaHRtbEltYWdlc1NyY0FycmF5W2ldO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGFkZE9ubG9hZEhhbmRsZXIoaW1nLCBodG1sSW1hZ2VzQXJyYXkpIHtcbiAgICBpbWcub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGh0bWxJbWFnZXNBcnJheS5sb2FkZWQodGhpcyk7XG4gICAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgKEltYWdlTG9hZGVyKTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2ltYWdlX2xvYWRlci5qc1xuICoqLyIsImltcG9ydCBDVlV0aWxzIGZyb20gJy4vY3ZfdXRpbHMnO1xuXG52YXIgRnJhbWVHcmFiYmVyID0ge307XG5cbkZyYW1lR3JhYmJlci5jcmVhdGUgPSBmdW5jdGlvbihpbnB1dFN0cmVhbSwgY2FudmFzKSB7XG4gICAgdmFyIF90aGF0ID0ge30sXG4gICAgICAgIF9zdHJlYW1Db25maWcgPSBpbnB1dFN0cmVhbS5nZXRDb25maWcoKSxcbiAgICAgICAgX3ZpZGVvX3NpemUgPSBDVlV0aWxzLmltYWdlUmVmKGlucHV0U3RyZWFtLmdldFJlYWxXaWR0aCgpLCBpbnB1dFN0cmVhbS5nZXRSZWFsSGVpZ2h0KCkpLFxuICAgICAgICBfY2FudmFzU2l6ZSA9IGlucHV0U3RyZWFtLmdldENhbnZhc1NpemUoKSxcbiAgICAgICAgX3NpemUgPSBDVlV0aWxzLmltYWdlUmVmKGlucHV0U3RyZWFtLmdldFdpZHRoKCksIGlucHV0U3RyZWFtLmdldEhlaWdodCgpKSxcbiAgICAgICAgdG9wUmlnaHQgPSBpbnB1dFN0cmVhbS5nZXRUb3BSaWdodCgpLFxuICAgICAgICBfc3ggPSB0b3BSaWdodC54LFxuICAgICAgICBfc3kgPSB0b3BSaWdodC55LFxuICAgICAgICBfY2FudmFzLFxuICAgICAgICBfY3R4ID0gbnVsbCxcbiAgICAgICAgX2RhdGEgPSBudWxsO1xuXG4gICAgX2NhbnZhcyA9IGNhbnZhcyA/IGNhbnZhcyA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgX2NhbnZhcy53aWR0aCA9IF9jYW52YXNTaXplLng7XG4gICAgX2NhbnZhcy5oZWlnaHQgPSBfY2FudmFzU2l6ZS55O1xuICAgIF9jdHggPSBfY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICBfZGF0YSA9IG5ldyBVaW50OEFycmF5KF9zaXplLnggKiBfc2l6ZS55KTtcbiAgICBjb25zb2xlLmxvZyhcIkZyYW1lR3JhYmJlclwiLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHNpemU6IF9zaXplLFxuICAgICAgICB0b3BSaWdodDogdG9wUmlnaHQsXG4gICAgICAgIHZpZGVvU2l6ZTogX3ZpZGVvX3NpemUsXG4gICAgICAgIGNhbnZhc1NpemU6IF9jYW52YXNTaXplXG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogVXNlcyB0aGUgZ2l2ZW4gYXJyYXkgYXMgZnJhbWUtYnVmZmVyXG4gICAgICovXG4gICAgX3RoYXQuYXR0YWNoRGF0YSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgICAgX2RhdGEgPSBkYXRhO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB1c2VkIGZyYW1lLWJ1ZmZlclxuICAgICAqL1xuICAgIF90aGF0LmdldERhdGEgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9kYXRhO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIGEgZnJhbWUgZnJvbSB0aGUgaW5wdXQtc3RyZWFtIGFuZCBwdXRzIGludG8gdGhlIGZyYW1lLWJ1ZmZlci5cbiAgICAgKiBUaGUgaW1hZ2UtZGF0YSBpcyBjb252ZXJ0ZWQgdG8gZ3JheS1zY2FsZSBhbmQgdGhlbiBoYWxmLXNhbXBsZWQgaWYgY29uZmlndXJlZC5cbiAgICAgKi9cbiAgICBfdGhhdC5ncmFiID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBkb0hhbGZTYW1wbGUgPSBfc3RyZWFtQ29uZmlnLmhhbGZTYW1wbGUsXG4gICAgICAgICAgICBmcmFtZSA9IGlucHV0U3RyZWFtLmdldEZyYW1lKCksXG4gICAgICAgICAgICBjdHhEYXRhO1xuICAgICAgICBpZiAoZnJhbWUpIHtcbiAgICAgICAgICAgIF9jdHguZHJhd0ltYWdlKGZyYW1lLCAwLCAwLCBfY2FudmFzU2l6ZS54LCBfY2FudmFzU2l6ZS55KTtcbiAgICAgICAgICAgIGN0eERhdGEgPSBfY3R4LmdldEltYWdlRGF0YShfc3gsIF9zeSwgX3NpemUueCwgX3NpemUueSkuZGF0YTtcbiAgICAgICAgICAgIGlmIChkb0hhbGZTYW1wbGUpe1xuICAgICAgICAgICAgICAgIENWVXRpbHMuZ3JheUFuZEhhbGZTYW1wbGVGcm9tQ2FudmFzRGF0YShjdHhEYXRhLCBfc2l6ZSwgX2RhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBDVlV0aWxzLmNvbXB1dGVHcmF5KGN0eERhdGEsIF9kYXRhLCBfc3RyZWFtQ29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIF90aGF0LmdldFNpemUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9zaXplO1xuICAgIH07XG5cbiAgICByZXR1cm4gX3RoYXQ7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBGcmFtZUdyYWJiZXI7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9mcmFtZV9ncmFiYmVyLmpzXG4gKiovIl0sInNvdXJjZVJvb3QiOiIifQ== |