Skip to content

Instantly share code, notes, and snippets.

@jtenner
Last active August 28, 2017 16:53
Show Gist options
  • Save jtenner/f71a39927ec3bd34d51cee862bae2a0f to your computer and use it in GitHub Desktop.
Save jtenner/f71a39927ec3bd34d51cee862bae2a0f to your computer and use it in GitHub Desktop.
requirebin sketch
const repatch = require('repatch');
const e2d = require('e2d');
const components = [];
const app = { pointer: false, mouseData: null, activeRegions: null };
const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = 400;
ctx.canvas.height = 300;
document.body.appendChild(ctx.canvas);
e2d.raf(() => {
app.mouseData = e2d.mouseData(ctx);
app.activeRegions = e2d.activeRegions(ctx);
app.pointer = false;
components.forEach(x => {
const region = app.activeRegions[x.id];
const prevActive = x.active;
x.hover = !!region;
if (region.clicked) {
x.active = true;
}
if (x.active && x.hover && !app.mouseData.state) {
x.onClick(app);
}
if (!app.mouseData.state) {
x.active = false;
}
x.dirty = x.update(app) || x.dirty || (prevActive !== x.active);
});
components.sort((x, y) => x.zIndex < y.zIndex ? -1 : x.zIndex > y.zIndex ? 1 : 0);
const view = components.map(x => x.dirty ? x._cache = x.render() : x._cache);
components.forEach(x => (x.dirty = false, true));
e2d.render(
e2d.clearRect(ctx.canvas.width, ctx.canvas.height),
view,
ctx
);
})
let id = -1;
class Component {
constructor({ position = [0, 0], scale = [1, 1], rotation = 0, alpha = 0, center = [0, 0], onClick = x => {} }) {
this.id = (++id).toString(36);
this.position = position;
this.scale = scale;
this.center = center;
this.rotation = rotaion;
this.alpha = alpha;
this.dirty = true;
this.active = false;
this.hover = false;
this._cache = [];
this.onClick = onClick;
}
render(...children) {
return e2d.translate(this.position[0], this.position[1],
e2d.rotate(this.rotation,
e2d.scale(this.scale[0], this.scale[1],
e2d.translate(-this.center[0], -this.center[1], ...children)
)
)
);
}
}
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"repatch":[function(require,module,exports){
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Repatch = {})));
}(this, (function (exports) { 'use strict';
var thunkFactory = function (extraArgument) {
var thunk = (function (store) { return function (next) { return function (reducer) {
if (typeof reducer !== 'function')
throw new Error('Thunk reducer must return a function');
var result = reducer(store.getState());
if (typeof result === 'function')
return result(store.dispatch, store.getState, extraArgument);
else
return next(function (_) { return result; });
}; }; });
thunk.withExtraArgument = thunkFactory;
return thunk;
};
var thunk = thunkFactory();
var Store = (function () {
function Store(initialState) {
var _this = this;
this.listeners = [];
this.getState = function () { return _this.state; };
this.dispatch = function (reducer) {
if (typeof reducer !== 'function')
throw new Error('Reducer is not a function: dispatch takes only reducers as functions.');
_this.state = reducer(_this.state);
_this.listeners.forEach(function (listener) { return listener(); });
return _this.state;
};
this.subscribe = function (listener) {
if (typeof listener !== 'function')
throw new Error('Listener is not a function: subscribe takes only listeners as functions.');
_this.listeners = _this.listeners.concat([listener]);
return function () { return (_this.listeners = _this.listeners.filter(function (lis) { return lis !== listener; })); };
};
this.addMiddleware = function () {
var middlewares = [];
for (var _i = 0; _i < arguments.length; _i++) {
middlewares[_i] = arguments[_i];
}
if (middlewares.some(function (middleware) { return typeof middleware !== 'function'; }))
throw new Error('Middleware is not a function: addMiddleware takes only middlewares as functions.');
middlewares.forEach(function (middleware) { return (_this.dispatch = middleware(_this)(_this.dispatch)); });
return _this;
};
this.state = initialState;
}
return Store;
}());
exports.Store = Store;
exports['default'] = Store;
exports.thunk = thunk;
Object.defineProperty(exports, '__esModule', { value: true });
})));
},{}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsInJlcGF0Y2giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuXHQoZmFjdG9yeSgoZ2xvYmFsLlJlcGF0Y2ggPSB7fSkpKTtcbn0odGhpcywgKGZ1bmN0aW9uIChleHBvcnRzKSB7ICd1c2Ugc3RyaWN0JztcblxudmFyIHRodW5rRmFjdG9yeSA9IGZ1bmN0aW9uIChleHRyYUFyZ3VtZW50KSB7XHJcbiAgICB2YXIgdGh1bmsgPSAoZnVuY3Rpb24gKHN0b3JlKSB7IHJldHVybiBmdW5jdGlvbiAobmV4dCkgeyByZXR1cm4gZnVuY3Rpb24gKHJlZHVjZXIpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHJlZHVjZXIgIT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGh1bmsgcmVkdWNlciBtdXN0IHJldHVybiBhIGZ1bmN0aW9uJyk7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlZHVjZXIoc3RvcmUuZ2V0U3RhdGUoKSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQoc3RvcmUuZGlzcGF0Y2gsIHN0b3JlLmdldFN0YXRlLCBleHRyYUFyZ3VtZW50KTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiBuZXh0KGZ1bmN0aW9uIChfKSB7IHJldHVybiByZXN1bHQ7IH0pO1xyXG4gICAgfTsgfTsgfSk7XHJcbiAgICB0aHVuay53aXRoRXh0cmFBcmd1bWVudCA9IHRodW5rRmFjdG9yeTtcclxuICAgIHJldHVybiB0aHVuaztcclxufTtcclxudmFyIHRodW5rID0gdGh1bmtGYWN0b3J5KCk7XG5cbnZhciBTdG9yZSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBTdG9yZShpbml0aWFsU3RhdGUpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XHJcbiAgICAgICAgdGhpcy5nZXRTdGF0ZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIF90aGlzLnN0YXRlOyB9O1xyXG4gICAgICAgIHRoaXMuZGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVkdWNlcikge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHJlZHVjZXIgIT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZXIgaXMgbm90IGEgZnVuY3Rpb246IGRpc3BhdGNoIHRha2VzIG9ubHkgcmVkdWNlcnMgYXMgZnVuY3Rpb25zLicpO1xyXG4gICAgICAgICAgICBfdGhpcy5zdGF0ZSA9IHJlZHVjZXIoX3RoaXMuc3RhdGUpO1xyXG4gICAgICAgICAgICBfdGhpcy5saXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAobGlzdGVuZXIpIHsgcmV0dXJuIGxpc3RlbmVyKCk7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuc3RhdGU7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMaXN0ZW5lciBpcyBub3QgYSBmdW5jdGlvbjogc3Vic2NyaWJlIHRha2VzIG9ubHkgbGlzdGVuZXJzIGFzIGZ1bmN0aW9ucy4nKTtcclxuICAgICAgICAgICAgX3RoaXMubGlzdGVuZXJzID0gX3RoaXMubGlzdGVuZXJzLmNvbmNhdChbbGlzdGVuZXJdKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuIChfdGhpcy5saXN0ZW5lcnMgPSBfdGhpcy5saXN0ZW5lcnMuZmlsdGVyKGZ1bmN0aW9uIChsaXMpIHsgcmV0dXJuIGxpcyAhPT0gbGlzdGVuZXI7IH0pKTsgfTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMuYWRkTWlkZGxld2FyZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG1pZGRsZXdhcmVzID0gW107XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBtaWRkbGV3YXJlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChtaWRkbGV3YXJlcy5zb21lKGZ1bmN0aW9uIChtaWRkbGV3YXJlKSB7IHJldHVybiB0eXBlb2YgbWlkZGxld2FyZSAhPT0gJ2Z1bmN0aW9uJzsgfSkpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pZGRsZXdhcmUgaXMgbm90IGEgZnVuY3Rpb246IGFkZE1pZGRsZXdhcmUgdGFrZXMgb25seSBtaWRkbGV3YXJlcyBhcyBmdW5jdGlvbnMuJyk7XHJcbiAgICAgICAgICAgIG1pZGRsZXdhcmVzLmZvckVhY2goZnVuY3Rpb24gKG1pZGRsZXdhcmUpIHsgcmV0dXJuIChfdGhpcy5kaXNwYXRjaCA9IG1pZGRsZXdhcmUoX3RoaXMpKF90aGlzLmRpc3BhdGNoKSk7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gaW5pdGlhbFN0YXRlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN0b3JlO1xyXG59KCkpO1xuXG5leHBvcnRzLlN0b3JlID0gU3RvcmU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBTdG9yZTtcbmV4cG9ydHMudGh1bmsgPSB0aHVuaztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxufSkpKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlcGF0Y2guanMubWFwXG4iXX0=
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"e2d":[function(require,module,exports){
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["e2d"] = factory();
else
root["e2d"] = factory();
})(this, function() {
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] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.l = 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;
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 58);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {
class Instruction {
constructor(type, props) {
this.type = type;
this.props = props;
return Object.seal(this);
}
}
Object.seal(Instruction);
Object.seal(Instruction.prototype);
module.exports = Instruction;
/***/ },
/* 1 */
/***/ function(module, exports) {
let transformPoints = (points, matrix) => {
let result = [],
x, y;
for(let i = 0; i < points.length; i++) {
[x, y] = points[i];
result.push([
matrix[0] * x + matrix[2] * y + matrix[4],
matrix[1] * x + matrix[3] * y + matrix[5]
]);
}
return result;
};
module.exports = transformPoints;
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0),
cache = new Instruction('beginPath');
let beginPath = () => cache;
module.exports = beginPath;
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let cache = new Instruction('closePath');
let closePath = () => cache;
module.exports = closePath;
/***/ },
/* 4 */
/***/ function(module, exports) {
let cycleMouseData = (ctx) => {
let mouseData = ctx.canvas[Symbol.for('mouseData')];
if (mouseData) {
mouseData.dx = mouseData.x - mouseData.previousX;
mouseData.dy = mouseData.y - mouseData.previousY;
mouseData.previousX = mouseData.x;
mouseData.previousY = mouseData.y;
mouseData.clicked = 0;
}
};
module.exports = cycleMouseData;
/***/ },
/* 5 */
/***/ function(module, exports) {
let det = 0;
let invertMatrix = ([a, b, c, d, e, f]) => (
det = 1 / (a * d - c * b),
[
d * det,
-c * det,
-b * det,
a * det,
(b * f - e * d) * det,
(e * b - a * f) * det
]
);
module.exports = invertMatrix;
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let lineTo = (x, y) => new Instruction('lineTo', { x, y });
module.exports = lineTo;
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let moveTo = (x, y) => new Instruction('moveTo', { x, y });
module.exports = moveTo;
/***/ },
/* 8 */
/***/ function(module, exports) {
let pointInRect = ([px, py], [[x, y], [width, height]]) => px > x && py > y && px < width && py < height;
module.exports = pointInRect;
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let setTransform = (matrix, ...children) => [
new Instruction('setTransform', [
matrix[0],
matrix[1],
matrix[2],
matrix[3],
matrix[4],
matrix[5]
]),
children,
end
];
module.exports = setTransform;
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
let pointInPolygon = __webpack_require__(57);
let transformPoints = __webpack_require__(1);
let invertMatrix = __webpack_require__(5);
let pointInRect = __webpack_require__(8);
let matrix = new Float64Array(6);
module.exports = (ctx) => {
let regions = ctx.canvas[Symbol.for('regions')],
mousePoints = ctx.canvas[Symbol.for('mousePoints')],
mouseData = ctx.canvas[Symbol.for('mouseData')],
results = {};
//the mouse might have held still, add the current mouse position
if (mousePoints.length === 0) {
mousePoints.push([mouseData.x, mouseData.y, mouseData.state]);
}
for(let region of regions) {
//invert the region matrix and transform the mouse points
let transformedMousePoints = transformPoints(mousePoints, invertMatrix(region.matrix));
//the mouse points are now relative to the mouse region
if (!region.polygon) {
for (let mousePoint of transformedMousePoints) {
if (pointInRect(mousePoint, region.points)) {
region.hover = true;
region.clicked = !!mouseData.clicked;
results[region.id] = region;
break;
}
}
continue;
}
//loop over each point until one is matched
for(let mousePoint of transformedMousePoints) {
if (pointInPolygon(mousePoint, region.points)) {
region.hover = true;
region.clicked = !!mouseData.clicked;
results[region.id] = region;
break;
}
}
}
return results;
};
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0),
pi2 = Math.PI * 2;
let arc = (...args) => {
let [x, y, r, startAngle, endAngle, counterclockwise] = args;
let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false };
if (args.length > 3) {
props.startAngle = startAngle;
props.endAngle = endAngle;
props.counterclockwise = !!counterclockwise;
}
if (args.length > 1){
props.x = x;
props.y = y;
props.r = r;
}
return new Instruction("arc", props);
};
module.exports = arc;
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let arcTo = (x1, y1, x2, y2, r) => new Instruction('arcTo', { x1, y1, x2, y2, r });
module.exports = arcTo;
/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let bezierCurveTo = (cp1x, cp1y, cp2x, cp2y, x, y) => new Instruction('bezierCurveTo', {
cp1x,
cp1y,
cp2x,
cp2y,
x,
y
});
module.exports = bezierCurveTo;
/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let clearRect = (...args) => new Instruction('clearRect',
args.length > 2 ?
{ x: args[0], y: args[1], width: args[2], height: args[3] } :
{ x: 0, y: 0, width: args[0], height: args[1] }
);
module.exports = clearRect;
/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let begin = new Instruction('beginClip'),
performClip = new Instruction('clip'),
end = new Instruction('endClip');
let clip = (path, ...children) => [
begin,
path,
performClip,
children,
end
];
module.exports = clip;
/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let cache = new Instruction('clipPath');
let clipPath = () => cache;
module.exports = clipPath;
/***/ },
/* 17 */
/***/ function(module, exports) {
let createRegularPolygon = (radius = 0, position = [0, 0], sides = 3) => {
let polygon = [];
for(let i = 0; i < sides; i++) {
polygon.push([
position[0] + radius * Math.cos(Math.PI * 2 * i / sides),
position[1] + radius * Math.sin(Math.PI * 2 * i / sides)
]);
}
return polygon;
};
module.exports = createRegularPolygon;
/***/ },
/* 18 */
/***/ function(module, exports) {
let concat = [].concat;
let createWrapper = (...args) => {
for(let i = 0; i < args.length; i++) {
//parse and flatten the arguments
while (args[i] && args[i].constructor === Array) {
args = concat.apply([], args).filter(Boolean);
}
if (!args[i]) {
continue;
}
let { type } = args[i];
if (type === 'placeholder') {
// i is set to the placeholder index now
//now grab all the elements to the left of the placeHolder
let left = args.splice(0, i);
//remove the placeHolder from the array
args.shift();
return (...children) => [left, children, args];
}
}
throw new Error('Could not find placeholder, did you forget the e2d.placeHolder() call?');
};
module.exports = concat;
/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let drawImage = (...args) => {
let [img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight] = args;
if (args.length === 9) {
return new Instruction('drawImageSource', {
img,
sx,
sy,
sWidth,
sHeight,
dx,
dy,
dWidth,
dHeight
});
}
if (args.length >= 5) {
return new Instruction('drawImageSize', {
img,
dx: sx,
dy: sy,
dWidth: sWidth,
dHeight: sHeight
});
}
if (args.length >= 3) {
return new Instruction('drawImage', {
img,
dx: sx,
dy: sy
});
}
return new Instruction('drawImage', {
img,
dx: 0,
dy: 0
});
};
module.exports = drawImage;
/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0),
pi2 = Math.PI * 2;
let ellipse = (...args) => {
let [x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise] = args;
let props = { x: 0, y: 0, radiusX: x, radiusY: y, rotation: 0, startAngle: 0, endAngle: pi2, anticlockwise: false };
if (args.length > 5) {
props.startAngle = startAngle;
props.endAngle = endAngle;
props.anticlockwise = !!anticlockwise;
}
if (args.length > 4) {
props.rotation = rotation;
}
if (args.length > 2){
props.x = x;
props.y = y;
props.radiusX = radiusX;
props.radiusY = radiusY;
}
return new Instruction("ellipse", props);
};
module.exports = ellipse;
/***/ },
/* 21 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let cache = new Instruction('fill');
let fill = () => cache;
module.exports = fill;
/***/ },
/* 22 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0),
pi2 = Math.PI * 2;
let fillArc = (...args) => {
let [x, y, r, startAngle, endAngle, counterclockwise] = args;
let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false };
if (args.length > 3) {
props.startAngle = startAngle;
props.endAngle = endAngle;
props.counterclockwise = !!counterclockwise;
}
if (args.length >= 2) {
props.x = x;
props.y = y;
props.r = r;
}
return new Instruction("fillArc", props);
};
module.exports = fillArc;
/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let fillRect = (...args) => new Instruction('fillRect',
args.length > 2 ?
{ x: args[0], y: args[1], width: args[2], height: args[3] } :
{ x: 0, y: 0, width: args[0], height: args[1] }
);
module.exports = fillRect;
/***/ },
/* 24 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endFillStyle');
let fillStyle = (value, ...children) => [
new Instruction('fillStyle', { value }),
children,
end
];
module.exports = fillStyle;
/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let fillText = (...args) => {
let [text, x, y, maxWidth] = args;
if (args.length < 4) {
maxWidth = null;
}
if (args.length < 3) {
x = 0;
y = 0;
}
return new Instruction('fillText', { text, x, y, maxWidth });
};
module.exports = fillText;
/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endGlobalAlpha');
let globalAlpha = (value, ...children) => [
new Instruction('globalAlpha', { value }),
children,
end
];
module.exports = globalAlpha;
/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {
var Instruction = __webpack_require__(0);
let end = new Instruction('endGlobalCompositeOperation');
let globalCompositeOperation = (value, ...children) => [
new Instruction('globalCompositeOperation', { value }),
children,
end
];
module.exports = globalCompositeOperation;
/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let hitRect = (id, ...args) => {
let [x, y, width, height] = args;
if (args.length <= 3) {
width = x;
height = y;
x = 0;
y = 0;
}
return new Instruction('hitRect', {
id,
points: [
[x, y],
[x + width, y + height]
]
});
};
module.exports = hitRect;
/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let hitRegion = (id, points) => new Instruction('hitRegion', { id, points });
module.exports = hitRegion;
/***/ },
/* 30 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endImageSmoothingEnabled');
let imageSmoothingEnabled = (value, ...children) => [
new Instruction('imageSmoothingEnabled', { value }),
children,
end
];
module.exports = imageSmoothingEnabled;
/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {
let keycode = __webpack_require__(56);
module.exports = (ctx) => {
let { canvas } = ctx;
//mouseData
canvas[Symbol.for('mouseData')] = {
x: 0,
y: 0,
dx: 0,
dy: 0,
previousX: 0,
previousY: 0,
state: false,
clicked: 0
};
let keys = canvas[Symbol.for('keyData')] = {};
for (let name in keycode.code) {
if (keycode.code.hasOwnProperty(name)) {
keys[name] = false;
}
}
//mouse regions
canvas[Symbol.for('regions')] = [];
canvas[Symbol.for('mousePoints')] = [];
//make the canvas receive touch and mouse events
canvas.tabIndex = 1;
let mouseMove = (evt) => {
let { clientX, clientY } = evt;
//get left and top coordinates
let { left, top } = canvas.getBoundingClientRect();
let mouseData = canvas[Symbol.for('mouseData')];
let point = [clientX - left, clientY - top, mouseData.state];
mouseData.x = point[0];
mouseData.y = point[1];
let points = canvas[Symbol.for('mousePoints')];
points.push(point);
//store the last 100 stored positions for hover detection
if (points.length > 100) {
points.splice(0, points.length - 100);
}
evt.preventDefault();
return false;
};
canvas.addEventListener('mousemove', (evt) => mouseMove(evt));
canvas.addEventListener('mousedown', (evt) => {
let { target } = evt;
if (target === canvas) {
let mouseData = canvas[Symbol.for('mouseData')];
if (!mouseData.state) {
mouseData.clicked += 1;
}
mouseData.state = true;
return mouseMove(evt);
}
});
canvas.addEventListener('mouseup', (evt) => {
let mouseData = canvas[Symbol.for('mouseData')];
mouseData.state = false;
return mouseMove(evt);
});
canvas.addEventListener('keydown', (evt) => {
canvas[Symbol.for('keyData')][keycode(evt.keyCode)] = true;
evt.preventDefault();
return false;
});
canvas.addEventListener('keyup', (evt) => {
canvas[Symbol.for('keyData')][keycode(evt.keyCode)] = false;
evt.preventDefault();
return false;
});
};
/***/ },
/* 32 */
/***/ function(module, exports) {
module.exports = (ctx) => ctx.canvas[Symbol.for('keyData')];
/***/ },
/* 33 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endLineStyle');
let lineStyle = (value, ...children) => {
value = value || {};
var result = {
lineWidth: null,
lineCap: null,
lineJoin: null,
miterLimit: null,
lineDash: null,
lineDashOffset: null
};
if (typeof value.lineWidth !== 'undefined') {
result.lineWidth = value.lineWidth;
}
if (typeof value.lineCap !== 'undefined') {
result.lineCap = value.lineCap;
}
if (typeof value.lineJoin !== 'undefined') {
result.lineJoin = value.lineJoin;
}
if (typeof value.miterLimit !== 'undefined') {
result.miterLimit = value.miterLimit;
}
if (typeof value.lineDash !== 'undefined') {
result.lineDash = value.lineDash || [];
}
if (typeof value.lineDashOffset !== 'undefined') {
result.lineDashOffset = value.lineDashOffset;
}
return [
new Instruction('lineStyle', result),
children,
end
];
};
module.exports = lineStyle;
/***/ },
/* 34 */
/***/ function(module, exports) {
module.exports = (ctx) => ctx.canvas[Symbol.for('mouseData')];
/***/ },
/* 35 */
/***/ function(module, exports, __webpack_require__) {
let moveTo = __webpack_require__(7), lineTo = __webpack_require__(6);
let moveToLineTo = (point, index) => index === 0 ?
moveTo(point[0], point[1]) :
lineTo(point[0], point[1]);
module.exports = moveToLineTo;
/***/ },
/* 36 */
/***/ function(module, exports, __webpack_require__) {
let beginPath = __webpack_require__(2)(),
closePath = __webpack_require__(3)();
let path = (...children) => [
beginPath,
children,
closePath
];
module.exports = path;
/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let cache = new Instruction('placeholder');
let placeHolder = () => cache;
module.exports = placeHolder;
/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let quadraticCurveTo = (cpx, cpy, x, y) => new Instruction('quadraticCurveTo', {
cpx,
cpy,
x,
y
});
module.exports = quadraticCurveTo;
/***/ },
/* 39 */
/***/ function(module, exports) {
let raf = (func) => {
requestAnimationFrame(() => raf(func));
return func();
};
module.exports = raf;
/***/ },
/* 40 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let rect = (...args) => new Instruction('rect',
args.length > 2 ?
{ x: args[0], y: args[1], width: args[2], height: args[3] } :
{ x: 0, y: 0, width: args[0], height: args[1] }
);
module.exports = rect;
/***/ },
/* 41 */
/***/ function(module, exports, __webpack_require__) {
//initialize all the properties
let identity = [1, 0, 0, 1, 0, 0],
matrix = new Float64Array(identity),
fillStyleStack = [],
strokeStyleStack = [],
lineStyleStack = [],
textStyleStack = [],
shadowStyleStack = [],
globalCompositeOperationStack = [],
globalAlphaStack = [],
imageSmoothingEnabledStack = [],
transformStack = new Float64Array(501 * 6),
transformStackIndex = 6,
concat = [].concat,
supportsEllipse = false;
if (typeof CanvasRenderingContext2D !== 'undefined') {
supportsEllipse = CanvasRenderingContext2D.prototype.hasOwnProperty('ellipse');
}
//transform points function
const transformPoints = __webpack_require__(1);
const cycleMouseData = __webpack_require__(4);
const increaseTransformStackSize = () => {
let cache = transformStack;
transformStack = new Float64Array(transformStack.length + 600); //add 100 more
transformStack.set(cache);
return this;
};
transformStack.set(identity);
const PI2 = Math.PI * 2;
let empty = (target) => target && target.splice(0, target.length);
module.exports = (...args) => {
let children = args.slice(0, -1),
ctx = args[args.length - 1];
let regions = ctx.canvas[Symbol.for('regions')],
mousePoints = ctx.canvas[Symbol.for('mousePoints')],
extensions = ctx.canvas[Symbol.for('extensions')];
let cache;
cycleMouseData(ctx);
empty(regions);
empty(mousePoints);
let len = children.length;
//flatten children during the loop process to save cpu
for (let i = 0; i < len; i++) {
let child = children[i];
//flattening algorithm
if (child && child.constructor === Array) {
children = concat.apply([], children);
child = children[i];
//repeat as necessary
while (child && child.constructor === Array) {
children = concat.apply([], children);
child = children[i];
}
len = children.length;
}
//child must be truthy
if (!child) {
continue;
}
let { props, type } = child;
if (type === 'transform') {
//copy transformStack values to matrix
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
//increase the index
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
//perform the transform math
transformStack[transformStackIndex - 6] = //d
matrix[0] * props[0] + matrix[2] * props[1];
transformStack[transformStackIndex - 5] = //b
matrix[1] * props[0] + matrix[3] * props[1];
transformStack[transformStackIndex - 4] = //c
matrix[0] * props[2] + matrix[2] * props[3];
transformStack[transformStackIndex - 3] = //d
matrix[1] * props[2] + matrix[3] * props[3];
transformStack[transformStackIndex - 2] = //e
matrix[0] * props[4] + matrix[2] * props[5] + matrix[4];
transformStack[transformStackIndex - 1] = //f
matrix[1] * props[4] + matrix[3] * props[5] + matrix[5];
//modify the ctx
ctx.setTransform(
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
);
continue;
}
if (type === 'setTransform') {
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
transformStack[transformStackIndex - 6] = props[0];//a
transformStack[transformStackIndex - 5] = props[1];//b
transformStack[transformStackIndex - 4] = props[2];//c
transformStack[transformStackIndex - 3] = props[3];//d
transformStack[transformStackIndex - 2] = props[4];//e
transformStack[transformStackIndex - 1] = props[5];//f
ctx.setTransform(props[0], props[1], props[2], props[3], props[4], props[5]);
continue;
}
if (type === 'scale') {
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
transformStack[transformStackIndex - 6] = matrix[0] * props.x; //a
transformStack[transformStackIndex - 5] = matrix[1] * props.x; //b
transformStack[transformStackIndex - 4] = matrix[2] * props.y; //c
transformStack[transformStackIndex - 3] = matrix[3] * props.y; //d
transformStack[transformStackIndex - 2] = matrix[4]; //e
transformStack[transformStackIndex - 1] = matrix[5]; //f
ctx.setTransform(
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
);
continue;
}
if (type === 'translate') {
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
transformStack[transformStackIndex - 6] = matrix[0]; //a
transformStack[transformStackIndex - 5] = matrix[1]; //b
transformStack[transformStackIndex - 4] = matrix[2]; //c
transformStack[transformStackIndex - 3] = matrix[3]; //d
transformStack[transformStackIndex - 2] = matrix[4] + matrix[0] * props.x + matrix[2] * props.y; //e
transformStack[transformStackIndex - 1] = matrix[5] + matrix[1] * props.x + matrix[3] * props.y; //f
ctx.setTransform(
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
);
continue;
}
if (type === 'rotate') {
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
transformStack[transformStackIndex - 6] =
matrix[0] * props.cos + matrix[2] * props.sin; //a
transformStack[transformStackIndex - 5] =
matrix[1] * props.cos + matrix[3] * props.sin; //b
transformStack[transformStackIndex - 4] =
matrix[0] * -props.sin + matrix[2] * props.cos; //c
transformStack[transformStackIndex - 3] =
matrix[1] * -props.sin + matrix[3] * props.cos; //d
transformStack[transformStackIndex - 2] = matrix[4]; //e
transformStack[transformStackIndex - 1] = matrix[5];//f
ctx.setTransform(
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
);
continue;
}
if (type === 'skewX') {
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
transformStack[transformStackIndex - 6] = matrix[0]; //a
transformStack[transformStackIndex - 5] = matrix[1]; //b
transformStack[transformStackIndex - 4] = //c
matrix[0] * props.x + matrix[2];
transformStack[transformStackIndex - 3] = //d
matrix[1] * props.x + matrix[3];
transformStack[transformStackIndex - 2] = matrix[4]; //e
transformStack[transformStackIndex - 1] = matrix[5]; //f
ctx.setTransform(
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
);
continue;
}
if (type === 'skewY') {
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
transformStackIndex += 6;
if (transformStackIndex > transformStack.length) {
increaseTransformStackSize();
}
transformStack[transformStackIndex - 6] =
matrix[0] * 1 + matrix[2] * props.y; //a
transformStack[transformStackIndex - 5] =
matrix[1] * 1 + matrix[3] * props.y; //b
transformStack[transformStackIndex - 4] = matrix[2]; //c
transformStack[transformStackIndex - 3] = matrix[3]; //d
transformStack[transformStackIndex - 2] = matrix[4]; //e
transformStack[transformStackIndex - 1] = matrix[5]; //f
ctx.setTransform(
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
);
continue;
}
if (type === 'restore') {
transformStackIndex -= 6;
matrix[0] = transformStack[transformStackIndex - 6];
matrix[1] = transformStack[transformStackIndex - 5];
matrix[2] = transformStack[transformStackIndex - 4];
matrix[3] = transformStack[transformStackIndex - 3];
matrix[4] = transformStack[transformStackIndex - 2];
matrix[5] = transformStack[transformStackIndex - 1];
ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
continue;
}
if (type === 'fillRect') {
ctx.fillRect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'strokeRect') {
ctx.strokeRect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'clearRect') {
ctx.clearRect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'rect') {
ctx.rect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'fillStyle') {
fillStyleStack.push(ctx.fillStyle);
ctx.fillStyle = props.value;
continue;
}
if (type === 'strokeStyle') {
strokeStyleStack.push(ctx.strokeStyle);
ctx.strokeStyle = props.value;
continue;
}
if (type === 'endFillStyle') {
ctx.fillStyle = fillStyleStack.pop();
continue;
}
if (type === 'endStrokeStyle') {
ctx.strokeStyle = strokeStyleStack.pop();
continue;
}
if (type === 'lineStyle') {
lineStyleStack.push({
lineWidth: ctx.lineWidth,
lineCap: ctx.lineCap,
lineJoin: ctx.lineJoin,
miterLimit: ctx.miterLimit,
lineDash: ctx.getLineDash(),
lineDashOffset: ctx.lineDashOffset
});
if (props.lineWidth !== null) {
ctx.lineWidth = props.lineWidth;
}
if (props.lineCap !== null) {
ctx.lineCap = props.lineCap;
}
if (props.lineJoin !== null) {
ctx.lineJoin = props.lineJoin;
}
if (props.miterLimit !== null) {
ctx.miterLimit = props.miterLimit;
}
if (props.lineDash !== null) {
ctx.setLineDash(props.lineDash);
}
if (props.lineDashOffset !== null) {
ctx.lineDashOffset = props.lineDashOffset;
}
continue;
}
if (type === 'endLineStyle') {
cache = lineStyleStack.pop();
ctx.lineWidth = cache.lineWidth;
ctx.lineCap = cache.lineCap;
ctx.lineJoin = cache.lineJoin;
ctx.miterLimit = cache.miterLimit;
ctx.setLineDash(cache.lineDash);
ctx.lineDashOffset = cache.lineDashOffset;
continue;
}
if (type === 'textStyle') {
textStyleStack.push({
font: ctx.font,
textAlign: ctx.textAlign,
textBaseline: ctx.textBaseline,
direction: ctx.direction
});
if (props.font !== null) {
ctx.font = props.font;
}
if (props.textAlign !== null) {
ctx.textAlign = props.textAlign;
}
if (props.textBaseline !== null) {
ctx.textBaseline = props.textBaseline;
}
if (props.direction !== null) {
ctx.direction = props.direction;
}
continue;
}
if (type === 'endTextStyle') {
cache = textStyleStack.pop();
ctx.font = cache.font;
ctx.textAlign = cache.textAlign;
ctx.textBaseline = cache.textBaseline;
ctx.direction = cache.direction;
continue;
}
if (type === 'shadowStyle') {
shadowStyleStack.push({
shadowBlur: ctx.shadowBlur,
shadowColor: ctx.shadowColor,
shadowOffsetX: ctx.shadowOffsetX,
shadowOffsetY: ctx.shadowOffsetY
});
if (props.shadowBlur !== null) {
ctx.shadowBlur = props.shadowBlur;
}
if (props.shadowColor !== null) {
ctx.shadowColor = props.shadowColor;
}
if (props.shadowOffsetX !== null) {
ctx.shadowOffsetX = props.shadowOffsetX;
}
if (props.shadowOffsetY !== null) {
ctx.shadowOffsetY = props.shadowOffsetY;
}
continue;
}
if (type === 'endShadowStyle') {
cache = shadowStyleStack.pop();
ctx.shadowBlur = cache.shadowBlur;
ctx.shadowColor = cache.shadowColor;
ctx.shadowOffsetX = cache.shadowOffsetX;
ctx.shadowOffsetY = cache.shadowOffsetY;
continue;
}
if (type === 'strokeText') {
if (props.maxWidth) {
ctx.strokeText(props.text, props.x, props.y, props.maxWidth);
continue;
}
ctx.strokeText(props.text, props.x, props.y);
continue;
}
if (type === 'fillText') {
if (props.maxWidth) {
ctx.fillText(props.text, props.x, props.y, props.maxWidth);
continue;
}
ctx.fillText(props.text, props.x, props.y);
continue;
}
if (type === 'drawImage') {
ctx.drawImage(props.img, props.dx, props.dy);
continue;
}
if (type === 'drawImageSize') {
ctx.drawImage(props.img, props.dx, props.dy, props.dWidth, props.dHeight);
continue;
}
if (type === 'drawImageSource') {
ctx.drawImage(props.img, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight);
continue;
}
if (type === 'strokeArc') {
ctx.beginPath();
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise);
ctx.closePath();
ctx.stroke();
continue;
}
if (type === 'fillArc') {
ctx.beginPath();
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise);
ctx.closePath();
ctx.fill();
continue;
}
if (type === 'moveTo') {
ctx.moveTo(props.x, props.y);
continue;
}
if (type === 'lineTo') {
ctx.lineTo(props.x, props.y);
continue;
}
if (type === 'bezierCurveTo') {
ctx.bezierCurveTo(props.cp1x, props.cp1y, props.cp2x, props.cp2y, props.x, props.y);
continue;
}
if (type === 'quadraticCurveTo') {
ctx.quadraticCurveTo(props.cpx, props.cpy, props.x, props.y);
continue;
}
if (type === 'arc') {
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise);
continue;
}
if (type === 'arcTo') {
ctx.arcTo(props.x1, props.y1, props.x2, props.y2, props.r);
continue;
}
if (type === 'ellipse') {
//if the method is provided by the browser
if (supportsEllipse) {
ctx.ellipse(
props.x,
props.y,
props.radiusX,
props.radiusY,
props.rotation,
props.startAngle,
props.endAngle,
props.anticlockwise
);
continue;
}
ctx.save();
ctx.translate(props.x, props.y);
ctx.rotate(props.rotation);
ctx.scale(props.radiusX, props.radiusY);
ctx.arc(0, 0, 1, props.startAngle, props.endAngle, props.anticlockwise);
ctx.restore();
continue;
}
if (type === 'globalCompositeOperation') {
globalCompositeOperationStack.push(ctx.globalCompositeOperation);
ctx.globalCompositeOperation = props.value;
continue;
}
if (type === 'endGlobalCompositeOperation') {
ctx.globalCompositeOperation = globalCompositeOperationStack.pop();
continue;
}
if (type === 'fill') {
ctx.fill();
continue;
}
if (type === 'stroke') {
ctx.stroke();
continue;
}
if (type === 'beginClip') {
ctx.save();
ctx.beginPath();
continue;
}
if (type === 'clip') {
ctx.clip();
continue;
}
if (type === 'endClip') {
ctx.restore();
continue;
}
if (type === 'beginPath') {
ctx.beginPath();
continue;
}
if (type === 'closePath') {
ctx.closePath();
continue;
}
if (type === 'globalAlpha') {
globalAlphaStack.push(ctx.globalAlpha);
ctx.globalAlpha *= props.value;
continue;
}
if (type === 'endGlobalAlpha') {
ctx.globalAlpha = globalAlphaStack.pop();
continue;
}
if (type === 'hitRect' && regions) {
cache = [
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
];
regions.push({
id: props.id,
points: props.points,
matrix: cache,
//rectangle!
polygon: false,
hover: false,
touched: false,
clicked: false
});
}
if (type === 'hitRegion' && regions) {
cache = [
transformStack[transformStackIndex - 6],
transformStack[transformStackIndex - 5],
transformStack[transformStackIndex - 4],
transformStack[transformStackIndex - 3],
transformStack[transformStackIndex - 2],
transformStack[transformStackIndex - 1]
];
regions.push({
id: props.id,
points: props.points,
matrix: cache,
polygon: true,
hover: false,
touched: false,
clicked: false
});
continue;
}
if (type === 'imageSmoothingEnabled') {
imageSmoothingEnabledStack.push(ctx.imageSmoothingEnabled);
ctx.imageSmoothingEnabled = props.value;
continue;
}
if (type === 'endImageSmoothingEnabled') {
ctx.imageSmoothingEnabled = imageSmoothingEnabledStack.pop();
continue;
}
if (extensions && extensions[type]) {
extensions[type](props, ctx);
continue;
}
}
};
/***/ },
/* 42 */
/***/ function(module, exports, __webpack_require__) {
let setTransform = __webpack_require__(9);
let resetTransform = (...children) => setTransform([1, 0, 0, 1, 0, 0], children);
module.exports = resetTransform;
/***/ },
/* 43 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let rotate = (r, ...children) => [
new Instruction('rotate', { cos: Math.cos(r), sin: Math.sin(r) }),
children,
end
];
module.exports = rotate;
/***/ },
/* 44 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let scale = (x, y, ...children) => {
if (typeof y !== 'number') {
children = [y].concat(children);
y = x;
}
return [
new Instruction('scale', { x, y }),
children,
end
];
};
module.exports = scale;
/***/ },
/* 45 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endShadowStyle');
let shadowStyle = (value, ...children) => {
value = value || {};
var result = {
shadowBlur: null,
shadowColor: null,
shadowOffsetX: null,
shadowOffsetY: null
};
if (typeof value.shadowBlur !== 'undefined') {
result.shadowBlur = value.shadowBlur;
}
if (typeof value.shadowColor !== 'undefined') {
result.shadowColor = value.shadowColor;
}
if (typeof value.shadowOffsetX !== 'undefined') {
result.shadowOffsetX = value.shadowOffsetX;
}
if (typeof value.direction !== 'undefined') {
result.shadowOffsetY = value.shadowOffsetY;
}
return [
new Instruction('shadowStyle', value),
children,
end
];
};
module.exports = shadowStyle;
/***/ },
/* 46 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let skewX = (x, ...children) => [
new Instruction('skewX', { x: Math.tan(x) }),
children,
end
];
module.exports = skewX;
/***/ },
/* 47 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let skewY = (x, ...children) => [
new Instruction('skewY', { y: Math.tan(y) }),
children,
end
];
module.exports = skewY;
/***/ },
/* 48 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let cache = new Instruction('stroke');
let stroke = () => cache;
module.exports = stroke;
/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0),
pi2 = Math.PI * 2;
let strokeArc = (...args) => {
let [x, y, r, startAngle, endAngle, counterclockwise] = args;
let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false };
if (args.length > 3) {
props.startAngle = startAngle;
props.endAngle = endAngle;
props.counterclockwise = !!counterclockwise;
}
if (args.length > 1){
props.x = x;
props.y = y;
props.r = r;
}
return new Instruction("strokeArc", props);
};
module.exports = strokeArc;
/***/ },
/* 50 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let strokeRect = (...args) => new Instruction('strokeRect',
args.length > 2 ?
{ x: args[0], y: args[1], width: args[2], height: args[3] } :
{ x: 0, y: 0, width: args[0], height: args[1] }
);
module.exports = strokeRect;
/***/ },
/* 51 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endStrokeStyle');
let strokeStyle = (value, ...children) => [
new Instruction('strokeStyle', { value }),
children,
end
];
module.exports = strokeStyle;
/***/ },
/* 52 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let strokeText = (...args) => {
let [text, x, y, maxWidth] = args;
if (args.length < 4) {
maxWidth = null;
}
if (args.length < 3) {
x = 0;
y = 0;
}
return new Instruction('strokeText', {
text,
x,
y,
maxWidth
});
};
module.exports = strokeText;
/***/ },
/* 53 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('endTextStyle');
let textStyle = (value, ...children) => {
value = value || {};
var result = {
font: null,
textAlign: null,
textBaseline: null,
direction: null
};
if (typeof value.font !== 'undefined') {
result.font = value.font;
}
if (typeof value.textAlign !== 'undefined') {
result.textAlign = value.textAlign;
}
if (typeof value.textBaseline !== 'undefined') {
result.textBaseline = value.textBaseline;
}
if (typeof value.direction !== 'undefined') {
result.direction = value.direction;
}
return [
new Instruction('textStyle', result),
children,
end
];
};
module.exports = textStyle;
/***/ },
/* 54 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let transform = (values, ...children) => {
return [
new Instruction('transform',[
values[0],
values[1],
values[2],
values[3],
values[4],
values[5]
]),
children,
end
];
};
module.exports = transform;
/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {
let Instruction = __webpack_require__(0);
let end = new Instruction('restore');
let translate = (x, y, ...children) => [
new Instruction('translate', { x: x, y: y }),
children,
end
];
module.exports = translate;
/***/ },
/* 56 */
/***/ function(module, exports) {
// Source: http://jsfiddle.net/vWx8V/
// http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes
/**
* Conenience method returns corresponding value for given keyName or keyCode.
*
* @param {Mixed} keyCode {Number} or keyName {String}
* @return {Mixed}
* @api public
*/
exports = module.exports = function(searchInput) {
// Keyboard Events
if (searchInput && 'object' === typeof searchInput) {
var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode
if (hasKeyCode) searchInput = hasKeyCode
}
// Numbers
if ('number' === typeof searchInput) return names[searchInput]
// Everything else (cast to string)
var search = String(searchInput)
// check codes
var foundNamedKey = codes[search.toLowerCase()]
if (foundNamedKey) return foundNamedKey
// check aliases
var foundNamedKey = aliases[search.toLowerCase()]
if (foundNamedKey) return foundNamedKey
// weird character?
if (search.length === 1) return search.charCodeAt(0)
return undefined
}
/**
* Get by name
*
* exports.code['enter'] // => 13
*/
var codes = exports.code = exports.codes = {
'backspace': 8,
'tab': 9,
'enter': 13,
'shift': 16,
'ctrl': 17,
'alt': 18,
'pause/break': 19,
'caps lock': 20,
'esc': 27,
'space': 32,
'page up': 33,
'page down': 34,
'end': 35,
'home': 36,
'left': 37,
'up': 38,
'right': 39,
'down': 40,
'insert': 45,
'delete': 46,
'command': 91,
'left command': 91,
'right command': 93,
'numpad *': 106,
'numpad +': 107,
'numpad -': 109,
'numpad .': 110,
'numpad /': 111,
'num lock': 144,
'scroll lock': 145,
'my computer': 182,
'my calculator': 183,
';': 186,
'=': 187,
',': 188,
'-': 189,
'.': 190,
'/': 191,
'`': 192,
'[': 219,
'\\': 220,
']': 221,
"'": 222
}
// Helper aliases
var aliases = exports.aliases = {
'windows': 91,
'⇧': 16,
'⌥': 18,
'⌃': 17,
'⌘': 91,
'ctl': 17,
'control': 17,
'option': 18,
'pause': 19,
'break': 19,
'caps': 20,
'return': 13,
'escape': 27,
'spc': 32,
'pgup': 33,
'pgdn': 34,
'ins': 45,
'del': 46,
'cmd': 91
}
/*!
* Programatically add the following
*/
// lower case chars
for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32
// numbers
for (var i = 48; i < 58; i++) codes[i - 48] = i
// function keys
for (i = 1; i < 13; i++) codes['f'+i] = i + 111
// numpad keys
for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96
/**
* Get by code
*
* exports.name[13] // => 'Enter'
*/
var names = exports.names = exports.title = {} // title for backward compat
// Create reverse mapping
for (i in codes) names[codes[i]] = i
// Add aliases
for (var alias in aliases) {
codes[alias] = aliases[alias]
}
/***/ },
/* 57 */
/***/ function(module, exports) {
module.exports = function (point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0], yi = vs[i][1];
var xj = vs[j][0], yj = vs[j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
/***/ },
/* 58 */
/***/ function(module, exports, __webpack_require__) {
module.exports = {
'activeRegions': __webpack_require__(10),
'arc': __webpack_require__(11),
'arcTo': __webpack_require__(12),
'beginPath': __webpack_require__(2),
'bezierCurveTo': __webpack_require__(13),
'clearRect': __webpack_require__(14),
'clip': __webpack_require__(15),
'clipPath': __webpack_require__(16),
'closePath': __webpack_require__(3),
'createRegularPolygon': __webpack_require__(17),
'createWrapper': __webpack_require__(18),
'cycleMouseData': __webpack_require__(4),
'drawImage': __webpack_require__(19),
'ellipse': __webpack_require__(20),
'fill': __webpack_require__(21),
'fillArc': __webpack_require__(22),
'fillRect': __webpack_require__(23),
'fillStyle': __webpack_require__(24),
'fillText': __webpack_require__(25),
'globalAlpha': __webpack_require__(26),
'globalCompositeOperation': __webpack_require__(27),
'hitRect': __webpack_require__(28),
'hitRegion': __webpack_require__(29),
'imageSmoothingEnabled': __webpack_require__(30),
'initialize': __webpack_require__(31),
'Instruction': __webpack_require__(0),
'invertMatrix': __webpack_require__(5),
'keyData': __webpack_require__(32),
'lineStyle': __webpack_require__(33),
'lineTo': __webpack_require__(6),
'mouseData': __webpack_require__(34),
'moveTo': __webpack_require__(7),
'moveToLineTo': __webpack_require__(35),
'path': __webpack_require__(36),
'placeHolder': __webpack_require__(37),
'pointInRect': __webpack_require__(8),
'quadraticCurveTo': __webpack_require__(38),
'raf': __webpack_require__(39),
'rect': __webpack_require__(40),
'render': __webpack_require__(41),
'resetTransform': __webpack_require__(42),
'rotate': __webpack_require__(43),
'scale': __webpack_require__(44),
'setTransform': __webpack_require__(9),
'shadowStyle': __webpack_require__(45),
'skewX': __webpack_require__(46),
'skewY': __webpack_require__(47),
'stroke': __webpack_require__(48),
'strokeArc': __webpack_require__(49),
'strokeRect': __webpack_require__(50),
'strokeStyle': __webpack_require__(51),
'strokeText': __webpack_require__(52),
'textStyle': __webpack_require__(53),
'transform': __webpack_require__(54),
'transformPoints': __webpack_require__(1),
'translate': __webpack_require__(55)
};
/***/ }
/******/ ]);
});
},{}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImUyZCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcImUyZFwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJlMmRcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuLyoqKioqKi8gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuLyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuXG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbi8qKioqKiovIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4vKioqKioqLyBcdFx0XHRpOiBtb2R1bGVJZCxcbi8qKioqKiovIFx0XHRcdGw6IGZhbHNlLFxuLyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge31cbi8qKioqKiovIFx0XHR9O1xuXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4vKioqKioqLyBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbi8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4vKioqKioqLyBcdH1cblxuXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuLyoqKioqKi8gXHQvLyBpZGVudGl0eSBmdW5jdGlvbiBmb3IgY2FsbGluZyBoYXJtb255IGltcG9ydHMgd2l0aCB0aGUgY29ycmVjdCBjb250ZXh0XG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uaSA9IGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiB2YWx1ZTsgfTtcblxuLyoqKioqKi8gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4vKioqKioqLyBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbi8qKioqKiovIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbi8qKioqKiovIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbi8qKioqKiovIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbi8qKioqKiovIFx0XHRcdH0pO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0fTtcblxuLyoqKioqKi8gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbi8qKioqKiovIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbi8qKioqKiovIFx0XHRyZXR1cm4gZ2V0dGVyO1xuLyoqKioqKi8gXHR9O1xuXG4vKioqKioqLyBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gNTgpO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmNsYXNzIEluc3RydWN0aW9uIHtcclxuICBjb25zdHJ1Y3Rvcih0eXBlLCBwcm9wcykge1xyXG4gICAgdGhpcy50eXBlID0gdHlwZTtcclxuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcclxuICAgIHJldHVybiBPYmplY3Quc2VhbCh0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcbk9iamVjdC5zZWFsKEluc3RydWN0aW9uKTtcclxuT2JqZWN0LnNlYWwoSW5zdHJ1Y3Rpb24ucHJvdG90eXBlKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gSW5zdHJ1Y3Rpb247XHJcblxuXG4vKioqLyB9LFxuLyogMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCB0cmFuc2Zvcm1Qb2ludHMgPSAocG9pbnRzLCBtYXRyaXgpID0+IHtcclxuICBsZXQgcmVzdWx0ID0gW10sXHJcbiAgICAgIHgsIHk7XHJcblxyXG4gIGZvcihsZXQgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcclxuICAgIFt4LCB5XSA9IHBvaW50c1tpXTtcclxuICAgIHJlc3VsdC5wdXNoKFtcclxuICAgICAgbWF0cml4WzBdICogeCArIG1hdHJpeFsyXSAqIHkgKyBtYXRyaXhbNF0sXHJcbiAgICAgIG1hdHJpeFsxXSAqIHggKyBtYXRyaXhbM10gKiB5ICsgbWF0cml4WzVdXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtUG9pbnRzO1xyXG5cblxuLyoqKi8gfSxcbi8qIDIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gIGNhY2hlID0gbmV3IEluc3RydWN0aW9uKCdiZWdpblBhdGgnKTtcclxuXHJcbmxldCBiZWdpblBhdGggPSAoKSA9PiBjYWNoZTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYmVnaW5QYXRoO1xuXG4vKioqLyB9LFxuLyogMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignY2xvc2VQYXRoJyk7XHJcblxyXG5sZXQgY2xvc2VQYXRoID0gKCkgPT4gY2FjaGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsb3NlUGF0aDtcclxuXG5cbi8qKiovIH0sXG4vKiA0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHJcbmxldCBjeWNsZU1vdXNlRGF0YSA9IChjdHgpID0+IHtcclxuICBsZXQgbW91c2VEYXRhID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV07XHJcbiAgaWYgKG1vdXNlRGF0YSkge1xyXG4gICAgbW91c2VEYXRhLmR4ID0gbW91c2VEYXRhLnggLSBtb3VzZURhdGEucHJldmlvdXNYO1xyXG4gICAgbW91c2VEYXRhLmR5ID0gbW91c2VEYXRhLnkgLSBtb3VzZURhdGEucHJldmlvdXNZO1xyXG5cclxuICAgIG1vdXNlRGF0YS5wcmV2aW91c1ggPSBtb3VzZURhdGEueDtcclxuICAgIG1vdXNlRGF0YS5wcmV2aW91c1kgPSBtb3VzZURhdGEueTtcclxuXHJcbiAgICBtb3VzZURhdGEuY2xpY2tlZCA9IDA7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjeWNsZU1vdXNlRGF0YTtcblxuLyoqKi8gfSxcbi8qIDUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5sZXQgZGV0ID0gMDtcclxubGV0IGludmVydE1hdHJpeCA9IChbYSwgYiwgYywgZCwgZSwgZl0pID0+IChcclxuICBkZXQgPSAxIC8gKGEgKiBkIC0gYyAqIGIpLFxyXG4gIFtcclxuICAgIGQgKiBkZXQsXHJcbiAgICAtYyAqIGRldCxcclxuICAgIC1iICogZGV0LFxyXG4gICAgYSAqIGRldCxcclxuICAgIChiICogZiAtIGUgKiBkKSAqIGRldCxcclxuICAgIChlICogYiAtIGEgKiBmKSAqIGRldFxyXG4gIF1cclxuKTtcclxuIG1vZHVsZS5leHBvcnRzID0gaW52ZXJ0TWF0cml4O1xuXG4vKioqLyB9LFxuLyogNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgbGluZVRvID0gKHgsIHkpID0+IG5ldyBJbnN0cnVjdGlvbignbGluZVRvJywgeyB4LCB5IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBsaW5lVG87XHJcblxuXG4vKioqLyB9LFxuLyogNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgbW92ZVRvID0gKHgsIHkpID0+IG5ldyBJbnN0cnVjdGlvbignbW92ZVRvJywgeyB4LCB5IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBtb3ZlVG87XHJcblxuXG4vKioqLyB9LFxuLyogOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCBwb2ludEluUmVjdCA9IChbcHgsIHB5XSwgW1t4LCB5XSwgW3dpZHRoLCBoZWlnaHRdXSkgPT4gcHggPiB4ICYmIHB5ID4geSAmJiBweCA8IHdpZHRoICYmIHB5IDwgaGVpZ2h0O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwb2ludEluUmVjdDtcblxuLyoqKi8gfSxcbi8qIDkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5sZXQgZW5kID0gbmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJyk7XHJcblxyXG5sZXQgc2V0VHJhbnNmb3JtID0gKG1hdHJpeCwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ3NldFRyYW5zZm9ybScsIFtcclxuICAgIG1hdHJpeFswXSxcclxuICAgIG1hdHJpeFsxXSxcclxuICAgIG1hdHJpeFsyXSxcclxuICAgIG1hdHJpeFszXSxcclxuICAgIG1hdHJpeFs0XSxcclxuICAgIG1hdHJpeFs1XVxyXG4gIF0pLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGVuZFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzZXRUcmFuc2Zvcm07XG5cbi8qKiovIH0sXG4vKiAxMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBwb2ludEluUG9seWdvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNTcpO1xyXG5sZXQgdHJhbnNmb3JtUG9pbnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcclxubGV0IGludmVydE1hdHJpeCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XHJcbmxldCBwb2ludEluUmVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oOCk7XHJcblxyXG5sZXQgbWF0cml4ID0gbmV3IEZsb2F0NjRBcnJheSg2KTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4ge1xyXG4gIGxldCByZWdpb25zID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdyZWdpb25zJyldLFxyXG4gICAgbW91c2VQb2ludHMgPSBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlUG9pbnRzJyldLFxyXG4gICAgbW91c2VEYXRhID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV0sXHJcbiAgICByZXN1bHRzID0ge307XHJcblxyXG4gIC8vdGhlIG1vdXNlIG1pZ2h0IGhhdmUgaGVsZCBzdGlsbCwgYWRkIHRoZSBjdXJyZW50IG1vdXNlIHBvc2l0aW9uXHJcbiAgaWYgKG1vdXNlUG9pbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgbW91c2VQb2ludHMucHVzaChbbW91c2VEYXRhLngsIG1vdXNlRGF0YS55LCBtb3VzZURhdGEuc3RhdGVdKTtcclxuICB9XHJcblxyXG4gIGZvcihsZXQgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcclxuXHJcbiAgICAvL2ludmVydCB0aGUgcmVnaW9uIG1hdHJpeCBhbmQgdHJhbnNmb3JtIHRoZSBtb3VzZSBwb2ludHNcclxuICAgIGxldCB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzID0gdHJhbnNmb3JtUG9pbnRzKG1vdXNlUG9pbnRzLCBpbnZlcnRNYXRyaXgocmVnaW9uLm1hdHJpeCkpO1xyXG4gICAgLy90aGUgbW91c2UgcG9pbnRzIGFyZSBub3cgcmVsYXRpdmUgdG8gdGhlIG1vdXNlIHJlZ2lvblxyXG5cclxuICAgIGlmICghcmVnaW9uLnBvbHlnb24pIHtcclxuICAgICAgZm9yIChsZXQgbW91c2VQb2ludCBvZiB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzKSB7XHJcbiAgICAgICAgaWYgKHBvaW50SW5SZWN0KG1vdXNlUG9pbnQsIHJlZ2lvbi5wb2ludHMpKSB7XHJcbiAgICAgICAgICByZWdpb24uaG92ZXIgPSB0cnVlO1xyXG4gICAgICAgICAgcmVnaW9uLmNsaWNrZWQgPSAhIW1vdXNlRGF0YS5jbGlja2VkO1xyXG4gICAgICAgICAgcmVzdWx0c1tyZWdpb24uaWRdID0gcmVnaW9uO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vbG9vcCBvdmVyIGVhY2ggcG9pbnQgdW50aWwgb25lIGlzIG1hdGNoZWRcclxuICAgIGZvcihsZXQgbW91c2VQb2ludCBvZiB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzKSB7XHJcbiAgICAgIGlmIChwb2ludEluUG9seWdvbihtb3VzZVBvaW50LCByZWdpb24ucG9pbnRzKSkge1xyXG4gICAgICAgIHJlZ2lvbi5ob3ZlciA9IHRydWU7XHJcbiAgICAgICAgcmVnaW9uLmNsaWNrZWQgPSAhIW1vdXNlRGF0YS5jbGlja2VkO1xyXG4gICAgICAgIHJlc3VsdHNbcmVnaW9uLmlkXSA9IHJlZ2lvbjtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gcmVzdWx0cztcclxufTtcblxuLyoqKi8gfSxcbi8qIDExICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxubGV0IGFyYyA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0ICBbeCwgeSwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNvdW50ZXJjbG9ja3dpc2VdID0gYXJncztcclxuICBsZXQgcHJvcHMgPSB7IHg6IDAsIHk6IDAsIHI6IHgsIHN0YXJ0QW5nbGU6IDAsIGVuZEFuZ2xlOiBwaTIsIGNvdW50ZXJjbG9ja3dpc2U6IGZhbHNlIH07XHJcblxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XHJcbiAgICBwcm9wcy5zdGFydEFuZ2xlID0gc3RhcnRBbmdsZTtcclxuICAgIHByb3BzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XHJcbiAgICBwcm9wcy5jb3VudGVyY2xvY2t3aXNlID0gISFjb3VudGVyY2xvY2t3aXNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMSl7XHJcbiAgICBwcm9wcy54ID0geDtcclxuICAgIHByb3BzLnkgPSB5O1xyXG4gICAgcHJvcHMuciA9IHI7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiYXJjXCIsICBwcm9wcyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGFyYztcclxuXG5cbi8qKiovIH0sXG4vKiAxMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgYXJjVG8gPSAoeDEsIHkxLCB4MiwgeTIsIHIpID0+IG5ldyBJbnN0cnVjdGlvbignYXJjVG8nLCB7IHgxLCB5MSwgeDIsIHkyLCByIH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmNUbztcclxuXG5cbi8qKiovIH0sXG4vKiAxMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgYmV6aWVyQ3VydmVUbyA9IChjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ2JlemllckN1cnZlVG8nLCB7XHJcbiAgY3AxeCxcclxuICBjcDF5LFxyXG4gIGNwMngsXHJcbiAgY3AyeSxcclxuICB4LFxyXG4gIHlcclxufSk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBiZXppZXJDdXJ2ZVRvO1xyXG5cblxuLyoqKi8gfSxcbi8qIDE0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBjbGVhclJlY3QgPSAoLi4uYXJncykgPT4gbmV3IEluc3RydWN0aW9uKCdjbGVhclJlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xlYXJSZWN0O1xyXG5cblxuLyoqKi8gfSxcbi8qIDE1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBiZWdpbiA9IG5ldyBJbnN0cnVjdGlvbignYmVnaW5DbGlwJyksXHJcbiAgcGVyZm9ybUNsaXAgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2NsaXAnKSxcclxuICBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZENsaXAnKTtcclxuXHJcbmxldCBjbGlwID0gKHBhdGgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgYmVnaW4sXHJcbiAgcGF0aCxcclxuICBwZXJmb3JtQ2xpcCxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xpcDtcclxuXG5cbi8qKiovIH0sXG4vKiAxNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignY2xpcFBhdGgnKTtcclxuXHJcbmxldCBjbGlwUGF0aCA9ICgpID0+IGNhY2hlO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGlwUGF0aDtcclxuXG5cbi8qKiovIH0sXG4vKiAxNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCBjcmVhdGVSZWd1bGFyUG9seWdvbiA9IChyYWRpdXMgPSAwLCBwb3NpdGlvbiA9IFswLCAwXSwgc2lkZXMgPSAzKSA9PiB7XHJcbiAgbGV0IHBvbHlnb24gPSBbXTtcclxuICBmb3IobGV0IGkgPSAwOyBpIDwgc2lkZXM7IGkrKykge1xyXG4gICAgcG9seWdvbi5wdXNoKFtcclxuICAgICAgcG9zaXRpb25bMF0gKyByYWRpdXMgKiBNYXRoLmNvcyhNYXRoLlBJICogMiAqIGkgLyBzaWRlcyksXHJcbiAgICAgIHBvc2l0aW9uWzFdICsgcmFkaXVzICogTWF0aC5zaW4oTWF0aC5QSSAqIDIgKiBpIC8gc2lkZXMpXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIHBvbHlnb247XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlZ3VsYXJQb2x5Z29uO1xyXG5cblxuLyoqKi8gfSxcbi8qIDE4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubGV0IGNvbmNhdCA9IFtdLmNvbmNhdDtcclxuXHJcbmxldCBjcmVhdGVXcmFwcGVyID0gKC4uLmFyZ3MpID0+IHtcclxuICBmb3IobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xyXG4gICAgLy9wYXJzZSBhbmQgZmxhdHRlbiB0aGUgYXJndW1lbnRzXHJcbiAgICB3aGlsZSAoYXJnc1tpXSAmJiBhcmdzW2ldLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICBhcmdzID0gY29uY2F0LmFwcGx5KFtdLCBhcmdzKS5maWx0ZXIoQm9vbGVhbik7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFhcmdzW2ldKSB7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCB7IHR5cGUgfSA9IGFyZ3NbaV07XHJcbiAgICBpZiAodHlwZSA9PT0gJ3BsYWNlaG9sZGVyJykge1xyXG4gICAgICAvLyBpIGlzIHNldCB0byB0aGUgcGxhY2Vob2xkZXIgaW5kZXggbm93XHJcblxyXG4gICAgICAvL25vdyBncmFiIGFsbCB0aGUgZWxlbWVudHMgdG8gdGhlIGxlZnQgb2YgdGhlIHBsYWNlSG9sZGVyXHJcbiAgICAgIGxldCBsZWZ0ID0gYXJncy5zcGxpY2UoMCwgaSk7XHJcblxyXG4gICAgICAvL3JlbW92ZSB0aGUgcGxhY2VIb2xkZXIgZnJvbSB0aGUgYXJyYXlcclxuICAgICAgYXJncy5zaGlmdCgpO1xyXG5cclxuICAgICAgcmV0dXJuICguLi5jaGlsZHJlbikgPT4gW2xlZnQsIGNoaWxkcmVuLCBhcmdzXTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgcGxhY2Vob2xkZXIsIGRpZCB5b3UgZm9yZ2V0IHRoZSBlMmQucGxhY2VIb2xkZXIoKSBjYWxsPycpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjb25jYXQ7XHJcblxuXG4vKioqLyB9LFxuLyogMTkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IGRyYXdJbWFnZSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0IFtpbWcsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodF0gPSBhcmdzO1xyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPT09IDkpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNvdXJjZScsIHtcclxuICAgICAgaW1nLFxyXG4gICAgICBzeCxcclxuICAgICAgc3ksXHJcbiAgICAgIHNXaWR0aCxcclxuICAgICAgc0hlaWdodCxcclxuICAgICAgZHgsXHJcbiAgICAgIGR5LFxyXG4gICAgICBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID49IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNpemUnLCB7XHJcbiAgICAgIGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3ksXHJcbiAgICAgIGRXaWR0aDogc1dpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBzSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdkcmF3SW1hZ2UnLCB7XHJcbiAgICAgIGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3lcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgaW1nLFxyXG4gICAgZHg6IDAsXHJcbiAgICBkeTogMFxyXG4gIH0pO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmF3SW1hZ2U7XHJcblxuXG4vKioqLyB9LFxuLyogMjAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgZWxsaXBzZSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0IFt4LCB5LCByYWRpdXNYLCByYWRpdXNZLCByb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFudGljbG9ja3dpc2VdID0gYXJncztcclxuXHJcbiAgbGV0IHByb3BzID0geyB4OiAwLCB5OiAwLCByYWRpdXNYOiB4LCByYWRpdXNZOiB5LCByb3RhdGlvbjogMCwgc3RhcnRBbmdsZTogMCwgZW5kQW5nbGU6IHBpMiwgYW50aWNsb2Nrd2lzZTogZmFsc2UgfTtcclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gNSkge1xyXG4gICAgcHJvcHMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XHJcbiAgICBwcm9wcy5lbmRBbmdsZSA9IGVuZEFuZ2xlO1xyXG4gICAgcHJvcHMuYW50aWNsb2Nrd2lzZSA9ICEhYW50aWNsb2Nrd2lzZTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+IDQpIHtcclxuICAgIHByb3BzLnJvdGF0aW9uID0gcm90YXRpb247XHJcbiAgfVxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAyKXtcclxuICAgIHByb3BzLnggPSB4O1xyXG4gICAgcHJvcHMueSA9IHk7XHJcbiAgICBwcm9wcy5yYWRpdXNYID0gcmFkaXVzWDtcclxuICAgIHByb3BzLnJhZGl1c1kgPSByYWRpdXNZO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImVsbGlwc2VcIiwgIHByb3BzKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZWxsaXBzZTtcclxuXG5cbi8qKiovIH0sXG4vKiAyMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignZmlsbCcpO1xyXG5cclxubGV0IGZpbGwgPSAoKSA9PiBjYWNoZTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbDtcclxuXG5cbi8qKiovIH0sXG4vKiAyMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxubGV0IGZpbGxBcmMgPSAoLi4uYXJncykgPT4ge1xyXG4gIGxldCBbeCwgeSwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNvdW50ZXJjbG9ja3dpc2VdID0gYXJncztcclxuICBsZXQgcHJvcHMgPSB7IHg6IDAsIHk6IDAsIHI6IHgsIHN0YXJ0QW5nbGU6IDAsIGVuZEFuZ2xlOiBwaTIsIGNvdW50ZXJjbG9ja3dpc2U6IGZhbHNlIH07XHJcblxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XHJcbiAgICBwcm9wcy5zdGFydEFuZ2xlID0gc3RhcnRBbmdsZTtcclxuICAgIHByb3BzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XHJcbiAgICBwcm9wcy5jb3VudGVyY2xvY2t3aXNlID0gISFjb3VudGVyY2xvY2t3aXNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID49IDIpIHtcclxuICAgIHByb3BzLnggPSB4O1xyXG4gICAgcHJvcHMueSA9IHk7XHJcbiAgICBwcm9wcy5yID0gcjtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJmaWxsQXJjXCIsICBwcm9wcyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxBcmM7XHJcblxuXG4vKioqLyB9LFxuLyogMjMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IGZpbGxSZWN0ID0gKC4uLmFyZ3MpID0+IG5ldyBJbnN0cnVjdGlvbignZmlsbFJlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDtcclxuXG5cbi8qKiovIH0sXG4vKiAyNCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEZpbGxTdHlsZScpO1xyXG5cclxubGV0IGZpbGxTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignZmlsbFN0eWxlJywgeyB2YWx1ZSB9KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxTdHlsZTtcclxuXG5cbi8qKiovIH0sXG4vKiAyNSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgZmlsbFRleHQgPSAoLi4uYXJncykgPT4ge1xyXG4gIGxldCBbdGV4dCwgeCwgeSwgbWF4V2lkdGhdID0gYXJncztcclxuICBpZiAoYXJncy5sZW5ndGggPCA0KSB7XHJcbiAgICBtYXhXaWR0aCA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChhcmdzLmxlbmd0aCA8IDMpIHtcclxuICAgIHggPSAwO1xyXG4gICAgeSA9IDA7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxUZXh0JywgeyB0ZXh0LCB4LCB5LCBtYXhXaWR0aCB9KTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbFRleHQ7XG5cbi8qKiovIH0sXG4vKiAyNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbignZW5kR2xvYmFsQWxwaGEnKTtcclxuXHJcbmxldCBnbG9iYWxBbHBoYSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2dsb2JhbEFscGhhJywgeyB2YWx1ZSB9KSxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxubW9kdWxlLmV4cG9ydHMgPSBnbG9iYWxBbHBoYTtcclxuXG5cbi8qKiovIH0sXG4vKiAyNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxudmFyIEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbicpO1xyXG5cclxubGV0IGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbicsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbjtcclxuXG5cbi8qKiovIH0sXG4vKiAyOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgaGl0UmVjdCA9IChpZCwgLi4uYXJncykgPT4ge1xyXG4gIGxldCBbeCwgeSwgd2lkdGgsIGhlaWdodF0gPSBhcmdzO1xyXG4gIGlmIChhcmdzLmxlbmd0aCA8PSAzKSB7XHJcbiAgICB3aWR0aCA9IHg7XHJcbiAgICBoZWlnaHQgPSB5O1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignaGl0UmVjdCcsIHtcclxuICAgIGlkLFxyXG4gICAgcG9pbnRzOiBbXHJcbiAgICAgIFt4LCB5XSxcclxuICAgICAgW3ggKyB3aWR0aCwgeSArIGhlaWdodF1cclxuICAgIF1cclxuICB9KTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gaGl0UmVjdDtcblxuLyoqKi8gfSxcbi8qIDI5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBoaXRSZWdpb24gPSAoaWQsIHBvaW50cykgPT4gbmV3IEluc3RydWN0aW9uKCdoaXRSZWdpb24nLCB7IGlkLCBwb2ludHMgfSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGhpdFJlZ2lvbjtcclxuXG5cbi8qKiovIH0sXG4vKiAzMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEltYWdlU21vb3RoaW5nRW5hYmxlZCcpO1xyXG5cclxubGV0IGltYWdlU21vb3RoaW5nRW5hYmxlZCA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2ltYWdlU21vb3RoaW5nRW5hYmxlZCcsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcbm1vZHVsZS5leHBvcnRzID0gaW1hZ2VTbW9vdGhpbmdFbmFibGVkO1xyXG5cblxuLyoqKi8gfSxcbi8qIDMxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IGtleWNvZGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDU2KTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4ge1xyXG4gIGxldCB7IGNhbnZhcyB9ID0gY3R4O1xyXG5cclxuICAvL21vdXNlRGF0YVxyXG4gIGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV0gPSB7XHJcbiAgICB4OiAwLFxyXG4gICAgeTogMCxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDAsXHJcbiAgICBwcmV2aW91c1g6IDAsXHJcbiAgICBwcmV2aW91c1k6IDAsXHJcbiAgICBzdGF0ZTogZmFsc2UsXHJcbiAgICBjbGlja2VkOiAwXHJcbiAgfTtcclxuXHJcbiAgbGV0IGtleXMgPSBjYW52YXNbU3ltYm9sLmZvcigna2V5RGF0YScpXSA9IHt9O1xyXG5cclxuICBmb3IgKGxldCBuYW1lIGluIGtleWNvZGUuY29kZSkge1xyXG4gICAgaWYgKGtleWNvZGUuY29kZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICBrZXlzW25hbWVdID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvL21vdXNlIHJlZ2lvbnNcclxuICBjYW52YXNbU3ltYm9sLmZvcigncmVnaW9ucycpXSA9IFtdO1xyXG4gIGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXSA9IFtdO1xyXG5cclxuICAvL21ha2UgdGhlIGNhbnZhcyByZWNlaXZlIHRvdWNoIGFuZCBtb3VzZSBldmVudHNcclxuICBjYW52YXMudGFiSW5kZXggPSAxO1xyXG5cclxuICBsZXQgbW91c2VNb3ZlID0gKGV2dCkgPT4ge1xyXG4gICAgbGV0IHsgY2xpZW50WCwgY2xpZW50WSB9ID0gZXZ0O1xyXG4gICAgLy9nZXQgbGVmdCBhbmQgdG9wIGNvb3JkaW5hdGVzXHJcbiAgICBsZXQgeyBsZWZ0LCB0b3AgfSA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBsZXQgbW91c2VEYXRhID0gY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcclxuXHJcbiAgICBsZXQgcG9pbnQgPSBbY2xpZW50WCAtIGxlZnQsIGNsaWVudFkgLSB0b3AsIG1vdXNlRGF0YS5zdGF0ZV07XHJcblxyXG4gICAgbW91c2VEYXRhLnggPSBwb2ludFswXTtcclxuICAgIG1vdXNlRGF0YS55ID0gcG9pbnRbMV07XHJcblxyXG4gICAgbGV0IHBvaW50cyA9IGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXTtcclxuXHJcbiAgICBwb2ludHMucHVzaChwb2ludCk7XHJcblxyXG4gICAgLy9zdG9yZSB0aGUgbGFzdCAxMDAgc3RvcmVkIHBvc2l0aW9ucyBmb3IgaG92ZXIgZGV0ZWN0aW9uXHJcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDEwMCkge1xyXG4gICAgICBwb2ludHMuc3BsaWNlKDAsIHBvaW50cy5sZW5ndGggLSAxMDApO1xyXG4gICAgfVxyXG5cclxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH07XHJcblxyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZXZ0KSA9PiBtb3VzZU1vdmUoZXZ0KSk7XHJcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChldnQpID0+IHtcclxuICAgIGxldCB7IHRhcmdldCB9ID0gZXZ0O1xyXG4gICAgaWYgKHRhcmdldCA9PT0gY2FudmFzKSB7XHJcbiAgICAgIGxldCBtb3VzZURhdGEgPSBjYW52YXNbU3ltYm9sLmZvcignbW91c2VEYXRhJyldO1xyXG5cclxuICAgICAgaWYgKCFtb3VzZURhdGEuc3RhdGUpIHtcclxuICAgICAgICBtb3VzZURhdGEuY2xpY2tlZCArPSAxO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBtb3VzZURhdGEuc3RhdGUgPSB0cnVlO1xyXG4gICAgICByZXR1cm4gbW91c2VNb3ZlKGV2dCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoZXZ0KSA9PiB7XHJcbiAgICBsZXQgbW91c2VEYXRhID0gY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcclxuICAgIG1vdXNlRGF0YS5zdGF0ZSA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIG1vdXNlTW92ZShldnQpO1xyXG4gIH0pO1xyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGV2dCkgPT4ge1xyXG4gICAgY2FudmFzW1N5bWJvbC5mb3IoJ2tleURhdGEnKV1ba2V5Y29kZShldnQua2V5Q29kZSldID0gdHJ1ZTtcclxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH0pO1xyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIChldnQpID0+IHtcclxuICAgIGNhbnZhc1tTeW1ib2wuZm9yKCdrZXlEYXRhJyldW2tleWNvZGUoZXZ0LmtleUNvZGUpXSA9IGZhbHNlO1xyXG4gICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfSk7XHJcbn07XG5cbi8qKiovIH0sXG4vKiAzMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdrZXlEYXRhJyldO1xuXG4vKioqLyB9LFxuLyogMzMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5sZXQgZW5kID0gbmV3IEluc3RydWN0aW9uKCdlbmRMaW5lU3R5bGUnKTtcclxuXHJcbmxldCBsaW5lU3R5bGUgPSAodmFsdWUsIC4uLmNoaWxkcmVuKSA9PiB7XHJcblxyXG4gIHZhbHVlID0gdmFsdWUgfHwge307XHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIGxpbmVXaWR0aDogbnVsbCxcclxuICAgIGxpbmVDYXA6IG51bGwsXHJcbiAgICBsaW5lSm9pbjogbnVsbCxcclxuICAgIG1pdGVyTGltaXQ6IG51bGwsXHJcbiAgICBsaW5lRGFzaDogbnVsbCxcclxuICAgIGxpbmVEYXNoT2Zmc2V0OiBudWxsXHJcbiAgfTtcclxuXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lV2lkdGggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZVdpZHRoID0gdmFsdWUubGluZVdpZHRoO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVDYXAgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZUNhcCA9IHZhbHVlLmxpbmVDYXA7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZUpvaW4gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZUpvaW4gPSB2YWx1ZS5saW5lSm9pbjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5taXRlckxpbWl0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0Lm1pdGVyTGltaXQgPSB2YWx1ZS5taXRlckxpbWl0O1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVEYXNoICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmxpbmVEYXNoID0gdmFsdWUubGluZURhc2ggfHwgW107XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZURhc2hPZmZzZXQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZURhc2hPZmZzZXQgPSB2YWx1ZS5saW5lRGFzaE9mZnNldDtcclxuICB9XHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignbGluZVN0eWxlJywgcmVzdWx0KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbiAgXTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZVN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubW9kdWxlLmV4cG9ydHMgPSAoY3R4KSA9PiBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcblxuLyoqKi8gfSxcbi8qIDM1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IG1vdmVUbyA9IF9fd2VicGFja19yZXF1aXJlX18oNyksIGxpbmVUbyA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XHJcblxyXG5sZXQgbW92ZVRvTGluZVRvID0gKHBvaW50LCBpbmRleCkgPT4gaW5kZXggPT09IDAgP1xyXG4gIG1vdmVUbyhwb2ludFswXSwgcG9pbnRbMV0pIDpcclxuICBsaW5lVG8ocG9pbnRbMF0sIHBvaW50WzFdKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbW92ZVRvTGluZVRvO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IGJlZ2luUGF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oMikoKSxcclxuICAgIGNsb3NlUGF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oMykoKTtcclxuXHJcbmxldCBwYXRoID0gKC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgYmVnaW5QYXRoLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGNsb3NlUGF0aFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwYXRoO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbigncGxhY2Vob2xkZXInKTtcclxubGV0IHBsYWNlSG9sZGVyID0gKCkgPT4gY2FjaGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHBsYWNlSG9sZGVyO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBxdWFkcmF0aWNDdXJ2ZVRvID0gKGNweCwgY3B5LCB4LCB5KSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1YWRyYXRpY0N1cnZlVG8nLCB7XHJcbiAgY3B4LFxyXG4gIGNweSxcclxuICB4LFxyXG4gIHlcclxufSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHF1YWRyYXRpY0N1cnZlVG87XHJcblxuXG4vKioqLyB9LFxuLyogMzkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5sZXQgcmFmID0gKGZ1bmMpID0+IHtcclxuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gcmFmKGZ1bmMpKTtcclxuICByZXR1cm4gZnVuYygpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByYWY7XG5cbi8qKiovIH0sXG4vKiA0MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgcmVjdCA9ICguLi5hcmdzKSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ3JlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZWN0O1xyXG5cblxuLyoqKi8gfSxcbi8qIDQxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHJcbi8vaW5pdGlhbGl6ZSBhbGwgdGhlIHByb3BlcnRpZXNcclxuXHJcbmxldCBpZGVudGl0eSA9IFsxLCAwLCAwLCAxLCAwLCAwXSxcclxuICBtYXRyaXggPSBuZXcgRmxvYXQ2NEFycmF5KGlkZW50aXR5KSxcclxuICBmaWxsU3R5bGVTdGFjayA9IFtdLFxyXG4gIHN0cm9rZVN0eWxlU3RhY2sgPSBbXSxcclxuICBsaW5lU3R5bGVTdGFjayA9IFtdLFxyXG4gIHRleHRTdHlsZVN0YWNrID0gW10sXHJcbiAgc2hhZG93U3R5bGVTdGFjayA9IFtdLFxyXG4gIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrID0gW10sXHJcbiAgZ2xvYmFsQWxwaGFTdGFjayA9IFtdLFxyXG4gIGltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrID0gW10sXHJcbiAgdHJhbnNmb3JtU3RhY2sgPSBuZXcgRmxvYXQ2NEFycmF5KDUwMSAqIDYpLFxyXG4gIHRyYW5zZm9ybVN0YWNrSW5kZXggPSA2LFxyXG4gIGNvbmNhdCA9IFtdLmNvbmNhdCxcclxuICBzdXBwb3J0c0VsbGlwc2UgPSBmYWxzZTtcclxuXHJcbmlmICh0eXBlb2YgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEICE9PSAndW5kZWZpbmVkJykge1xyXG4gIHN1cHBvcnRzRWxsaXBzZSA9IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkoJ2VsbGlwc2UnKTtcclxufVxyXG5cclxuLy90cmFuc2Zvcm0gcG9pbnRzIGZ1bmN0aW9uXHJcbmNvbnN0IHRyYW5zZm9ybVBvaW50cyA9IF9fd2VicGFja19yZXF1aXJlX18oMSk7XHJcbmNvbnN0IGN5Y2xlTW91c2VEYXRhID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcclxuXHJcbmNvbnN0IGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplID0gKCkgPT4ge1xyXG4gIGxldCBjYWNoZSA9IHRyYW5zZm9ybVN0YWNrO1xyXG4gIHRyYW5zZm9ybVN0YWNrID0gbmV3IEZsb2F0NjRBcnJheSh0cmFuc2Zvcm1TdGFjay5sZW5ndGggKyA2MDApOyAvL2FkZCAxMDAgbW9yZVxyXG4gIHRyYW5zZm9ybVN0YWNrLnNldChjYWNoZSk7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG50cmFuc2Zvcm1TdGFjay5zZXQoaWRlbnRpdHkpO1xyXG5cclxuY29uc3QgUEkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgZW1wdHkgPSAodGFyZ2V0KSA9PiB0YXJnZXQgJiYgdGFyZ2V0LnNwbGljZSgwLCB0YXJnZXQubGVuZ3RoKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgY2hpbGRyZW4gPSBhcmdzLnNsaWNlKDAsIC0xKSxcclxuICAgY3R4ID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdO1xyXG5cclxuICBsZXQgcmVnaW9ucyA9IGN0eC5jYW52YXNbU3ltYm9sLmZvcigncmVnaW9ucycpXSxcclxuICAgIG1vdXNlUG9pbnRzID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXSxcclxuICAgIGV4dGVuc2lvbnMgPSBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ2V4dGVuc2lvbnMnKV07XHJcblxyXG4gIGxldCBjYWNoZTtcclxuXHJcbiAgY3ljbGVNb3VzZURhdGEoY3R4KTtcclxuXHJcbiAgZW1wdHkocmVnaW9ucyk7XHJcbiAgZW1wdHkobW91c2VQb2ludHMpO1xyXG5cclxuICBsZXQgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG5cclxuICAvL2ZsYXR0ZW4gY2hpbGRyZW4gZHVyaW5nIHRoZSBsb29wIHByb2Nlc3MgdG8gc2F2ZSBjcHVcclxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuXHJcbiAgICAvL2ZsYXR0ZW5pbmcgYWxnb3JpdGhtXHJcbiAgICBpZiAoY2hpbGQgJiYgY2hpbGQuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XHJcbiAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcblxyXG4gICAgICAvL3JlcGVhdCBhcyBuZWNlc3NhcnlcclxuICAgICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8vY2hpbGQgbXVzdCBiZSB0cnV0aHlcclxuICAgIGlmICghY2hpbGQpIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHsgcHJvcHMsIHR5cGUgfSA9IGNoaWxkO1xyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNmb3JtJykge1xyXG5cclxuICAgICAgLy9jb3B5IHRyYW5zZm9ybVN0YWNrIHZhbHVlcyB0byBtYXRyaXhcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIC8vaW5jcmVhc2UgdGhlIGluZGV4XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvL3BlcmZvcm0gdGhlIHRyYW5zZm9ybSBtYXRoXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzBdICsgbWF0cml4WzJdICogcHJvcHNbMV07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IC8vYlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzBdICsgbWF0cml4WzNdICogcHJvcHNbMV07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IC8vY1xyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzJdICsgbWF0cml4WzJdICogcHJvcHNbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzJdICsgbWF0cml4WzNdICogcHJvcHNbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IC8vZVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzRdICsgbWF0cml4WzJdICogcHJvcHNbNV0gKyBtYXRyaXhbNF07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IC8vZlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzRdICsgbWF0cml4WzNdICogcHJvcHNbNV0gKyBtYXRyaXhbNV07XHJcblxyXG4gICAgICAvL21vZGlmeSB0aGUgY3R4XHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzZXRUcmFuc2Zvcm0nKSB7XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBwcm9wc1swXTsvL2FcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdID0gcHJvcHNbMV07Ly9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IHByb3BzWzJdOy8vY1xyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBwcm9wc1szXTsvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gcHJvcHNbNF07Ly9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IHByb3BzWzVdOy8vZlxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKHByb3BzWzBdLCBwcm9wc1sxXSwgcHJvcHNbMl0sIHByb3BzWzNdLCBwcm9wc1s0XSwgcHJvcHNbNV0pO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzY2FsZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBtYXRyaXhbMF0gKiBwcm9wcy54OyAvL2FcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdID0gbWF0cml4WzFdICogcHJvcHMueDsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vY1xyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBtYXRyaXhbM10gKiBwcm9wcy55OyAvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gbWF0cml4WzRdOyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOyAvL2ZcclxuXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNsYXRlJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IG1hdHJpeFsxXTsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXTsgLy9jXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IG1hdHJpeFszXTsgLy9kXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XSArIG1hdHJpeFswXSAqIHByb3BzLnggKyBtYXRyaXhbMl0gKiBwcm9wcy55OyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdICsgbWF0cml4WzFdICogcHJvcHMueCArIG1hdHJpeFszXSAqIHByb3BzLnk7IC8vZlxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3JvdGF0ZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzLmNvcyArIG1hdHJpeFsyXSAqIHByb3BzLnNpbjsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9XHJcbiAgICAgICAgbWF0cml4WzFdICogcHJvcHMuY29zICsgbWF0cml4WzNdICogcHJvcHMuc2luOyAvL2JcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID1cclxuICAgICAgICBtYXRyaXhbMF0gKiAtcHJvcHMuc2luICsgbWF0cml4WzJdICogcHJvcHMuY29zOyAvL2NcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID1cclxuICAgICAgICBtYXRyaXhbMV0gKiAtcHJvcHMuc2luICsgbWF0cml4WzNdICogcHJvcHMuY29zOyAvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gbWF0cml4WzRdOyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOy8vZlxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NrZXdYJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IG1hdHJpeFsxXTsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IC8vY1xyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzLnggKyBtYXRyaXhbMl07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzLnggKyBtYXRyaXhbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IG1hdHJpeFs1XTsgLy9mXHJcblxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NrZXdZJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9XHJcbiAgICAgICAgbWF0cml4WzBdICogMSArIG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vYVxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPVxyXG4gICAgICAgIG1hdHJpeFsxXSAqIDEgKyBtYXRyaXhbM10gKiBwcm9wcy55OyAvL2JcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gbWF0cml4WzJdOyAvL2NcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gbWF0cml4WzNdOyAvL2RcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IG1hdHJpeFs1XTsgLy9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncmVzdG9yZScpIHtcclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCAtPSA2O1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsUmVjdCcpIHtcclxuICAgICAgY3R4LmZpbGxSZWN0KHByb3BzLngsIHByb3BzLnksIHByb3BzLndpZHRoLCBwcm9wcy5oZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVJlY3QnKSB7XHJcbiAgICAgIGN0eC5zdHJva2VSZWN0KHByb3BzLngsIHByb3BzLnksIHByb3BzLndpZHRoLCBwcm9wcy5oZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsZWFyUmVjdCcpIHtcclxuICAgICAgY3R4LmNsZWFyUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdyZWN0Jykge1xyXG4gICAgICBjdHgucmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsU3R5bGUnKSB7XHJcbiAgICAgIGZpbGxTdHlsZVN0YWNrLnB1c2goY3R4LmZpbGxTdHlsZSk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2VTdHlsZScpIHtcclxuICAgICAgc3Ryb2tlU3R5bGVTdGFjay5wdXNoKGN0eC5zdHJva2VTdHlsZSk7XHJcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHByb3BzLnZhbHVlO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZEZpbGxTdHlsZScpIHtcclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IGZpbGxTdHlsZVN0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRTdHJva2VTdHlsZScpIHtcclxuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3Ryb2tlU3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZSA9PT0gJ2xpbmVTdHlsZScpIHtcclxuICAgICAgbGluZVN0eWxlU3RhY2sucHVzaCh7XHJcbiAgICAgICAgbGluZVdpZHRoOiBjdHgubGluZVdpZHRoLFxyXG4gICAgICAgIGxpbmVDYXA6IGN0eC5saW5lQ2FwLFxyXG4gICAgICAgIGxpbmVKb2luOiBjdHgubGluZUpvaW4sXHJcbiAgICAgICAgbWl0ZXJMaW1pdDogY3R4Lm1pdGVyTGltaXQsXHJcbiAgICAgICAgbGluZURhc2g6IGN0eC5nZXRMaW5lRGFzaCgpLFxyXG4gICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBjdHgubGluZURhc2hPZmZzZXRcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZVdpZHRoICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHByb3BzLmxpbmVXaWR0aDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUNhcCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5saW5lQ2FwID0gcHJvcHMubGluZUNhcDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUpvaW4gIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZUpvaW4gPSBwcm9wcy5saW5lSm9pbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubWl0ZXJMaW1pdCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5taXRlckxpbWl0ID0gcHJvcHMubWl0ZXJMaW1pdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2ggIT09IG51bGwpIHtcclxuICAgICAgICBjdHguc2V0TGluZURhc2gocHJvcHMubGluZURhc2gpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2hPZmZzZXQgIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBwcm9wcy5saW5lRGFzaE9mZnNldDtcclxuICAgICAgfVxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZExpbmVTdHlsZScpIHtcclxuICAgICAgY2FjaGUgPSBsaW5lU3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmxpbmVXaWR0aCA9IGNhY2hlLmxpbmVXaWR0aDtcclxuICAgICAgY3R4LmxpbmVDYXAgPSBjYWNoZS5saW5lQ2FwO1xyXG4gICAgICBjdHgubGluZUpvaW4gPSBjYWNoZS5saW5lSm9pbjtcclxuICAgICAgY3R4Lm1pdGVyTGltaXQgPSBjYWNoZS5taXRlckxpbWl0O1xyXG4gICAgICBjdHguc2V0TGluZURhc2goY2FjaGUubGluZURhc2gpO1xyXG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBjYWNoZS5saW5lRGFzaE9mZnNldDtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICd0ZXh0U3R5bGUnKSB7XHJcbiAgICAgIHRleHRTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIGZvbnQ6IGN0eC5mb250LFxyXG4gICAgICAgIHRleHRBbGlnbjogY3R4LnRleHRBbGlnbixcclxuICAgICAgICB0ZXh0QmFzZWxpbmU6IGN0eC50ZXh0QmFzZWxpbmUsXHJcbiAgICAgICAgZGlyZWN0aW9uOiBjdHguZGlyZWN0aW9uXHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAocHJvcHMuZm9udCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5mb250ID0gcHJvcHMuZm9udDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMudGV4dEFsaWduICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnRleHRBbGlnbiA9IHByb3BzLnRleHRBbGlnbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMudGV4dEJhc2VsaW5lICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnRleHRCYXNlbGluZSA9IHByb3BzLnRleHRCYXNlbGluZTtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMuZGlyZWN0aW9uICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmRpcmVjdGlvbiA9IHByb3BzLmRpcmVjdGlvbjtcclxuICAgICAgfVxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZFRleHRTdHlsZScpIHtcclxuICAgICAgY2FjaGUgPSB0ZXh0U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmZvbnQgPSBjYWNoZS5mb250O1xyXG4gICAgICBjdHgudGV4dEFsaWduID0gY2FjaGUudGV4dEFsaWduO1xyXG4gICAgICBjdHgudGV4dEJhc2VsaW5lID0gY2FjaGUudGV4dEJhc2VsaW5lO1xyXG4gICAgICBjdHguZGlyZWN0aW9uID0gY2FjaGUuZGlyZWN0aW9uO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NoYWRvd1N0eWxlJykge1xyXG4gICAgICBzaGFkb3dTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIHNoYWRvd0JsdXI6IGN0eC5zaGFkb3dCbHVyLFxyXG4gICAgICAgIHNoYWRvd0NvbG9yOiBjdHguc2hhZG93Q29sb3IsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WDogY3R4LnNoYWRvd09mZnNldFgsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WTogY3R4LnNoYWRvd09mZnNldFlcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dCbHVyICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBwcm9wcy5zaGFkb3dCbHVyO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dDb2xvciAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5zaGFkb3dDb2xvciA9IHByb3BzLnNoYWRvd0NvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRYICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBwcm9wcy5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRZICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFkgPSBwcm9wcy5zaGFkb3dPZmZzZXRZO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kU2hhZG93U3R5bGUnKSB7XHJcbiAgICAgIGNhY2hlID0gc2hhZG93U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LnNoYWRvd0JsdXIgPSBjYWNoZS5zaGFkb3dCbHVyO1xyXG4gICAgICBjdHguc2hhZG93Q29sb3IgPSBjYWNoZS5zaGFkb3dDb2xvcjtcclxuICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjYWNoZS5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WSA9IGNhY2hlLnNoYWRvd09mZnNldFk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlVGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoKSB7XHJcbiAgICAgICAgY3R4LnN0cm9rZVRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSwgcHJvcHMubWF4V2lkdGgpO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxUZXh0Jykge1xyXG4gICAgICBpZiAocHJvcHMubWF4V2lkdGgpIHtcclxuICAgICAgICBjdHguZmlsbFRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSwgcHJvcHMubWF4V2lkdGgpO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5maWxsVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3SW1hZ2UnKSB7XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLCBwcm9wcy5keCwgcHJvcHMuZHkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdJbWFnZVNpemUnKSB7XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLCBwcm9wcy5keCwgcHJvcHMuZHksIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZHJhd0ltYWdlU291cmNlJykge1xyXG4gICAgICBjdHguZHJhd0ltYWdlKHByb3BzLmltZywgcHJvcHMuc3gsIHByb3BzLnN5LCBwcm9wcy5zV2lkdGgsIHByb3BzLnNIZWlnaHQsIHByb3BzLmR4LCBwcm9wcy5keSwgcHJvcHMuZFdpZHRoLCBwcm9wcy5kSGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2VBcmMnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxBcmMnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LmZpbGwoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdtb3ZlVG8nKSB7XHJcbiAgICAgIGN0eC5tb3ZlVG8ocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnbGluZVRvJykge1xyXG4gICAgICBjdHgubGluZVRvKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlemllckN1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHByb3BzLmNwMXgsIHByb3BzLmNwMXksIHByb3BzLmNwMngsIHByb3BzLmNwMnksIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3F1YWRyYXRpY0N1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHByb3BzLmNweCwgcHJvcHMuY3B5LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdhcmMnKSB7XHJcbiAgICAgIGN0eC5hcmMocHJvcHMueCwgcHJvcHMueSwgcHJvcHMuciwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUsIHByb3BzLmNvdW50ZXJjbG9ja3dpc2UpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FyY1RvJykge1xyXG4gICAgICBjdHguYXJjVG8ocHJvcHMueDEsIHByb3BzLnkxLCBwcm9wcy54MiwgcHJvcHMueTIsIHByb3BzLnIpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VsbGlwc2UnKSB7XHJcbiAgICAgIC8vaWYgdGhlIG1ldGhvZCBpcyBwcm92aWRlZCBieSB0aGUgYnJvd3NlclxyXG4gICAgICBpZiAoc3VwcG9ydHNFbGxpcHNlKSB7XHJcbiAgICAgICAgY3R4LmVsbGlwc2UoXHJcbiAgICAgICAgICBwcm9wcy54LFxyXG4gICAgICAgICAgcHJvcHMueSxcclxuICAgICAgICAgIHByb3BzLnJhZGl1c1gsXHJcbiAgICAgICAgICBwcm9wcy5yYWRpdXNZLFxyXG4gICAgICAgICAgcHJvcHMucm90YXRpb24sXHJcbiAgICAgICAgICBwcm9wcy5zdGFydEFuZ2xlLFxyXG4gICAgICAgICAgcHJvcHMuZW5kQW5nbGUsXHJcbiAgICAgICAgICBwcm9wcy5hbnRpY2xvY2t3aXNlXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjdHgucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgY3R4LnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICBjdHguYXJjKDAsIDAsIDEsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlLCBwcm9wcy5hbnRpY2xvY2t3aXNlKTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrLnB1c2goY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbik7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBnbG9iYWxDb21wb3NpdGVPcGVyYXRpb25TdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsJykge1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZScpIHtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlZ2luQ2xpcCcpIHtcclxuICAgICAgY3R4LnNhdmUoKTtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsaXAnKSB7XHJcbiAgICAgIGN0eC5jbGlwKCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kQ2xpcCcpIHtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdiZWdpblBhdGgnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdjbG9zZVBhdGgnKSB7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxBbHBoYScpIHtcclxuICAgICAgZ2xvYmFsQWxwaGFTdGFjay5wdXNoKGN0eC5nbG9iYWxBbHBoYSk7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSAqPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxBbHBoYScpIHtcclxuICAgICAgY3R4Lmdsb2JhbEFscGhhID0gZ2xvYmFsQWxwaGFTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdoaXRSZWN0JyAmJiByZWdpb25zKSB7XHJcbiAgICAgIGNhY2hlID0gW1xyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgIF07XHJcblxyXG4gICAgICByZWdpb25zLnB1c2goe1xyXG4gICAgICAgIGlkOiBwcm9wcy5pZCxcclxuICAgICAgICBwb2ludHM6IHByb3BzLnBvaW50cyxcclxuICAgICAgICBtYXRyaXg6IGNhY2hlLFxyXG4gICAgICAgIC8vcmVjdGFuZ2xlIVxyXG4gICAgICAgIHBvbHlnb246IGZhbHNlLFxyXG4gICAgICAgIGhvdmVyOiBmYWxzZSxcclxuICAgICAgICB0b3VjaGVkOiBmYWxzZSxcclxuICAgICAgICBjbGlja2VkOiBmYWxzZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2hpdFJlZ2lvbicgJiYgcmVnaW9ucykge1xyXG4gICAgICBjYWNoZSA9IFtcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICBdO1xyXG5cclxuICAgICAgcmVnaW9ucy5wdXNoKHtcclxuICAgICAgICBpZDogcHJvcHMuaWQsXHJcbiAgICAgICAgcG9pbnRzOiBwcm9wcy5wb2ludHMsXHJcbiAgICAgICAgbWF0cml4OiBjYWNoZSxcclxuICAgICAgICBwb2x5Z29uOiB0cnVlLFxyXG4gICAgICAgIGhvdmVyOiBmYWxzZSxcclxuICAgICAgICB0b3VjaGVkOiBmYWxzZSxcclxuICAgICAgICBjbGlja2VkOiBmYWxzZVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICBpbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjay5wdXNoKGN0eC5pbWFnZVNtb290aGluZ0VuYWJsZWQpO1xyXG4gICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gcHJvcHMudmFsdWU7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZEltYWdlU21vb3RoaW5nRW5hYmxlZCcpIHtcclxuICAgICAgY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrLnBvcCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXh0ZW5zaW9ucyAmJiBleHRlbnNpb25zW3R5cGVdKSB7XHJcbiAgICAgIGV4dGVuc2lvbnNbdHlwZV0ocHJvcHMsIGN0eCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG4gIH1cclxufTtcblxuLyoqKi8gfSxcbi8qIDQyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IHNldFRyYW5zZm9ybSA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XHJcblxyXG5sZXQgcmVzZXRUcmFuc2Zvcm0gPSAoLi4uY2hpbGRyZW4pID0+IHNldFRyYW5zZm9ybShbMSwgMCwgMCwgMSwgMCwgMF0sIGNoaWxkcmVuKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVzZXRUcmFuc2Zvcm07XG5cbi8qKiovIH0sXG4vKiA0MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKTtcclxuXHJcbmxldCByb3RhdGUgPSAociwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ3JvdGF0ZScsIHsgY29zOiBNYXRoLmNvcyhyKSwgc2luOiBNYXRoLnNpbihyKSB9KSxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcm90YXRlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNjYWxlID0gKHgsIHksIC4uLmNoaWxkcmVuKSA9PiB7XHJcbiAgaWYgKHR5cGVvZiB5ICE9PSAnbnVtYmVyJykge1xyXG4gICAgY2hpbGRyZW4gPSBbeV0uY29uY2F0KGNoaWxkcmVuKTtcclxuICAgIHkgPSB4O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignc2NhbGUnLCB7IHgsIHkgfSksXHJcbiAgICBjaGlsZHJlbixcclxuICAgIGVuZFxyXG4gIF07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNjYWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbignZW5kU2hhZG93U3R5bGUnKTtcclxuXHJcbmxldCBzaGFkb3dTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IHtcclxuICB2YWx1ZSA9IHZhbHVlIHx8IHt9O1xyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBzaGFkb3dCbHVyOiBudWxsLFxyXG4gICAgc2hhZG93Q29sb3I6IG51bGwsXHJcbiAgICBzaGFkb3dPZmZzZXRYOiBudWxsLFxyXG4gICAgc2hhZG93T2Zmc2V0WTogbnVsbFxyXG4gIH07XHJcblxyXG4gIGlmICh0eXBlb2YgdmFsdWUuc2hhZG93Qmx1ciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dCbHVyID0gdmFsdWUuc2hhZG93Qmx1cjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5zaGFkb3dDb2xvciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dDb2xvciA9IHZhbHVlLnNoYWRvd0NvbG9yO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd09mZnNldFggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93T2Zmc2V0WCA9IHZhbHVlLnNoYWRvd09mZnNldFg7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUuZGlyZWN0aW9uICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnNoYWRvd09mZnNldFkgPSB2YWx1ZS5zaGFkb3dPZmZzZXRZO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignc2hhZG93U3R5bGUnLCB2YWx1ZSksXHJcbiAgICBjaGlsZHJlbixcclxuICAgIGVuZFxyXG4gIF07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNoYWRvd1N0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNrZXdYID0gKHgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdza2V3WCcsIHsgeDogTWF0aC50YW4oeCkgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNrZXdYO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNrZXdZID0gKHgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdza2V3WScsIHsgeTogTWF0aC50YW4oeSkgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNrZXdZO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGNhY2hlID0gbmV3IEluc3RydWN0aW9uKCdzdHJva2UnKTtcclxuXHJcbmxldCBzdHJva2UgPSAoKSA9PiBjYWNoZTtcclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2U7XHJcblxuXG4vKioqLyB9LFxuLyogNDkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgc3Ryb2tlQXJjID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgW3gsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlXSA9IGFyZ3M7XHJcbiAgbGV0IHByb3BzID0geyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyLCBjb3VudGVyY2xvY2t3aXNlOiBmYWxzZSB9O1xyXG5cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMykge1xyXG4gICAgcHJvcHMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XHJcbiAgICBwcm9wcy5lbmRBbmdsZSA9IGVuZEFuZ2xlO1xyXG4gICAgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSA9ICEhY291bnRlcmNsb2Nrd2lzZTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpe1xyXG4gICAgcHJvcHMueCA9IHg7XHJcbiAgICBwcm9wcy55ID0geTtcclxuICAgIHByb3BzLnIgPSByO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCAgcHJvcHMpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2VBcmM7XHJcblxuXG4vKioqLyB9LFxuLyogNTAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IHN0cm9rZVJlY3QgPSAoLi4uYXJncykgPT4gbmV3IEluc3RydWN0aW9uKCdzdHJva2VSZWN0JyxcclxuICBhcmdzLmxlbmd0aCA+IDIgP1xyXG4gICAgeyB4OiBhcmdzWzBdLCB5OiBhcmdzWzFdLCB3aWR0aDogYXJnc1syXSwgaGVpZ2h0OiBhcmdzWzNdIH0gOlxyXG4gICAgeyB4OiAwLCB5OiAwLCB3aWR0aDogYXJnc1swXSwgaGVpZ2h0OiBhcmdzWzFdIH1cclxuKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3Ryb2tlUmVjdDtcclxuXG5cbi8qKiovIH0sXG4vKiA1MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZFN0cm9rZVN0eWxlJyk7XHJcblxyXG5sZXQgc3Ryb2tlU3R5bGUgPSAodmFsdWUsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdzdHJva2VTdHlsZScsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZVN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDUyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBzdHJva2VUZXh0ID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgW3RleHQsIHgsIHksIG1heFdpZHRoXSA9IGFyZ3M7XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA8IDQpIHtcclxuICAgIG1heFdpZHRoID0gbnVsbDtcclxuICB9XHJcbiAgaWYgKGFyZ3MubGVuZ3RoIDwgMykge1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignc3Ryb2tlVGV4dCcsIHtcclxuICAgIHRleHQsXHJcbiAgICB4LFxyXG4gICAgeSxcclxuICAgIG1heFdpZHRoXHJcbiAgfSk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZVRleHQ7XG5cbi8qKiovIH0sXG4vKiA1MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZFRleHRTdHlsZScpO1xyXG5cclxubGV0IHRleHRTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IHtcclxuICB2YWx1ZSA9IHZhbHVlIHx8IHt9O1xyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBmb250OiBudWxsLFxyXG4gICAgdGV4dEFsaWduOiBudWxsLFxyXG4gICAgdGV4dEJhc2VsaW5lOiBudWxsLFxyXG4gICAgZGlyZWN0aW9uOiBudWxsXHJcbiAgfTtcclxuXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5mb250ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmZvbnQgPSB2YWx1ZS5mb250O1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnRleHRBbGlnbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC50ZXh0QWxpZ24gPSB2YWx1ZS50ZXh0QWxpZ247XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUudGV4dEJhc2VsaW5lICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnRleHRCYXNlbGluZSA9IHZhbHVlLnRleHRCYXNlbGluZTtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5kaXJlY3Rpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuZGlyZWN0aW9uID0gdmFsdWUuZGlyZWN0aW9uO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbigndGV4dFN0eWxlJywgcmVzdWx0KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbiAgXTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dFN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDU0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHRyYW5zZm9ybSA9ICh2YWx1ZXMsIC4uLmNoaWxkcmVuKSA9PiB7XHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbigndHJhbnNmb3JtJyxbXHJcbiAgICAgIHZhbHVlc1swXSxcclxuICAgICAgdmFsdWVzWzFdLFxyXG4gICAgICB2YWx1ZXNbMl0sXHJcbiAgICAgIHZhbHVlc1szXSxcclxuICAgICAgdmFsdWVzWzRdLFxyXG4gICAgICB2YWx1ZXNbNV1cclxuICAgIF0pLFxyXG4gICAgY2hpbGRyZW4sXHJcbiAgICBlbmRcclxuICBdO1xyXG59O1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtO1xyXG5cblxuLyoqKi8gfSxcbi8qIDU1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHRyYW5zbGF0ZSA9ICh4LCB5LCAuLi5jaGlsZHJlbikgPT4gW1xyXG4gIG5ldyBJbnN0cnVjdGlvbigndHJhbnNsYXRlJywgeyB4OiB4LCB5OiB5IH0pLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGVuZFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2xhdGU7XHJcblxuXG4vKioqLyB9LFxuLyogNTYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vLyBTb3VyY2U6IGh0dHA6Ly9qc2ZpZGRsZS5uZXQvdld4OFYvXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU2MDMxOTUvZnVsbC1saXN0LW9mLWphdmFzY3JpcHQta2V5Y29kZXNcblxuLyoqXG4gKiBDb25lbmllbmNlIG1ldGhvZCByZXR1cm5zIGNvcnJlc3BvbmRpbmcgdmFsdWUgZm9yIGdpdmVuIGtleU5hbWUgb3Iga2V5Q29kZS5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBrZXlDb2RlIHtOdW1iZXJ9IG9yIGtleU5hbWUge1N0cmluZ31cbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzZWFyY2hJbnB1dCkge1xuICAvLyBLZXlib2FyZCBFdmVudHNcbiAgaWYgKHNlYXJjaElucHV0ICYmICdvYmplY3QnID09PSB0eXBlb2Ygc2VhcmNoSW5wdXQpIHtcbiAgICB2YXIgaGFzS2V5Q29kZSA9IHNlYXJjaElucHV0LndoaWNoIHx8IHNlYXJjaElucHV0LmtleUNvZGUgfHwgc2VhcmNoSW5wdXQuY2hhckNvZGVcbiAgICBpZiAoaGFzS2V5Q29kZSkgc2VhcmNoSW5wdXQgPSBoYXNLZXlDb2RlXG4gIH1cblxuICAvLyBOdW1iZXJzXG4gIGlmICgnbnVtYmVyJyA9PT0gdHlwZW9mIHNlYXJjaElucHV0KSByZXR1cm4gbmFtZXNbc2VhcmNoSW5wdXRdXG5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIChjYXN0IHRvIHN0cmluZylcbiAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hJbnB1dClcblxuICAvLyBjaGVjayBjb2Rlc1xuICB2YXIgZm91bmROYW1lZEtleSA9IGNvZGVzW3NlYXJjaC50b0xvd2VyQ2FzZSgpXVxuICBpZiAoZm91bmROYW1lZEtleSkgcmV0dXJuIGZvdW5kTmFtZWRLZXlcblxuICAvLyBjaGVjayBhbGlhc2VzXG4gIHZhciBmb3VuZE5hbWVkS2V5ID0gYWxpYXNlc1tzZWFyY2gudG9Mb3dlckNhc2UoKV1cbiAgaWYgKGZvdW5kTmFtZWRLZXkpIHJldHVybiBmb3VuZE5hbWVkS2V5XG5cbiAgLy8gd2VpcmQgY2hhcmFjdGVyP1xuICBpZiAoc2VhcmNoLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHNlYXJjaC5jaGFyQ29kZUF0KDApXG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEdldCBieSBuYW1lXG4gKlxuICogICBleHBvcnRzLmNvZGVbJ2VudGVyJ10gLy8gPT4gMTNcbiAqL1xuXG52YXIgY29kZXMgPSBleHBvcnRzLmNvZGUgPSBleHBvcnRzLmNvZGVzID0ge1xuICAnYmFja3NwYWNlJzogOCxcbiAgJ3RhYic6IDksXG4gICdlbnRlcic6IDEzLFxuICAnc2hpZnQnOiAxNixcbiAgJ2N0cmwnOiAxNyxcbiAgJ2FsdCc6IDE4LFxuICAncGF1c2UvYnJlYWsnOiAxOSxcbiAgJ2NhcHMgbG9jayc6IDIwLFxuICAnZXNjJzogMjcsXG4gICdzcGFjZSc6IDMyLFxuICAncGFnZSB1cCc6IDMzLFxuICAncGFnZSBkb3duJzogMzQsXG4gICdlbmQnOiAzNSxcbiAgJ2hvbWUnOiAzNixcbiAgJ2xlZnQnOiAzNyxcbiAgJ3VwJzogMzgsXG4gICdyaWdodCc6IDM5LFxuICAnZG93bic6IDQwLFxuICAnaW5zZXJ0JzogNDUsXG4gICdkZWxldGUnOiA0NixcbiAgJ2NvbW1hbmQnOiA5MSxcbiAgJ2xlZnQgY29tbWFuZCc6IDkxLFxuICAncmlnaHQgY29tbWFuZCc6IDkzLFxuICAnbnVtcGFkIConOiAxMDYsXG4gICdudW1wYWQgKyc6IDEwNyxcbiAgJ251bXBhZCAtJzogMTA5LFxuICAnbnVtcGFkIC4nOiAxMTAsXG4gICdudW1wYWQgLyc6IDExMSxcbiAgJ251bSBsb2NrJzogMTQ0LFxuICAnc2Nyb2xsIGxvY2snOiAxNDUsXG4gICdteSBjb21wdXRlcic6IDE4MixcbiAgJ215IGNhbGN1bGF0b3InOiAxODMsXG4gICc7JzogMTg2LFxuICAnPSc6IDE4NyxcbiAgJywnOiAxODgsXG4gICctJzogMTg5LFxuICAnLic6IDE5MCxcbiAgJy8nOiAxOTEsXG4gICdgJzogMTkyLFxuICAnWyc6IDIxOSxcbiAgJ1xcXFwnOiAyMjAsXG4gICddJzogMjIxLFxuICBcIidcIjogMjIyXG59XG5cbi8vIEhlbHBlciBhbGlhc2VzXG5cbnZhciBhbGlhc2VzID0gZXhwb3J0cy5hbGlhc2VzID0ge1xuICAnd2luZG93cyc6IDkxLFxuICAn4oenJzogMTYsXG4gICfijKUnOiAxOCxcbiAgJ+KMgyc6IDE3LFxuICAn4oyYJzogOTEsXG4gICdjdGwnOiAxNyxcbiAgJ2NvbnRyb2wnOiAxNyxcbiAgJ29wdGlvbic6IDE4LFxuICAncGF1c2UnOiAxOSxcbiAgJ2JyZWFrJzogMTksXG4gICdjYXBzJzogMjAsXG4gICdyZXR1cm4nOiAxMyxcbiAgJ2VzY2FwZSc6IDI3LFxuICAnc3BjJzogMzIsXG4gICdwZ3VwJzogMzMsXG4gICdwZ2RuJzogMzQsXG4gICdpbnMnOiA0NSxcbiAgJ2RlbCc6IDQ2LFxuICAnY21kJzogOTFcbn1cblxuXG4vKiFcbiAqIFByb2dyYW1hdGljYWxseSBhZGQgdGhlIGZvbGxvd2luZ1xuICovXG5cbi8vIGxvd2VyIGNhc2UgY2hhcnNcbmZvciAoaSA9IDk3OyBpIDwgMTIzOyBpKyspIGNvZGVzW1N0cmluZy5mcm9tQ2hhckNvZGUoaSldID0gaSAtIDMyXG5cbi8vIG51bWJlcnNcbmZvciAodmFyIGkgPSA0ODsgaSA8IDU4OyBpKyspIGNvZGVzW2kgLSA0OF0gPSBpXG5cbi8vIGZ1bmN0aW9uIGtleXNcbmZvciAoaSA9IDE7IGkgPCAxMzsgaSsrKSBjb2Rlc1snZicraV0gPSBpICsgMTExXG5cbi8vIG51bXBhZCBrZXlzXG5mb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgY29kZXNbJ251bXBhZCAnK2ldID0gaSArIDk2XG5cbi8qKlxuICogR2V0IGJ5IGNvZGVcbiAqXG4gKiAgIGV4cG9ydHMubmFtZVsxM10gLy8gPT4gJ0VudGVyJ1xuICovXG5cbnZhciBuYW1lcyA9IGV4cG9ydHMubmFtZXMgPSBleHBvcnRzLnRpdGxlID0ge30gLy8gdGl0bGUgZm9yIGJhY2t3YXJkIGNvbXBhdFxuXG4vLyBDcmVhdGUgcmV2ZXJzZSBtYXBwaW5nXG5mb3IgKGkgaW4gY29kZXMpIG5hbWVzW2NvZGVzW2ldXSA9IGlcblxuLy8gQWRkIGFsaWFzZXNcbmZvciAodmFyIGFsaWFzIGluIGFsaWFzZXMpIHtcbiAgY29kZXNbYWxpYXNdID0gYWxpYXNlc1thbGlhc11cbn1cblxuXG4vKioqLyB9LFxuLyogNTcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwb2ludCwgdnMpIHtcbiAgICAvLyByYXktY2FzdGluZyBhbGdvcml0aG0gYmFzZWQgb25cbiAgICAvLyBodHRwOi8vd3d3LmVjc2UucnBpLmVkdS9Ib21lcGFnZXMvd3JmL1Jlc2VhcmNoL1Nob3J0X05vdGVzL3BucG9seS5odG1sXG4gICAgXG4gICAgdmFyIHggPSBwb2ludFswXSwgeSA9IHBvaW50WzFdO1xuICAgIFxuICAgIHZhciBpbnNpZGUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IHZzLmxlbmd0aCAtIDE7IGkgPCB2cy5sZW5ndGg7IGogPSBpKyspIHtcbiAgICAgICAgdmFyIHhpID0gdnNbaV1bMF0sIHlpID0gdnNbaV1bMV07XG4gICAgICAgIHZhciB4aiA9IHZzW2pdWzBdLCB5aiA9IHZzW2pdWzFdO1xuICAgICAgICBcbiAgICAgICAgdmFyIGludGVyc2VjdCA9ICgoeWkgPiB5KSAhPSAoeWogPiB5KSlcbiAgICAgICAgICAgICYmICh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBpbnNpZGU7XG59O1xuXG5cbi8qKiovIH0sXG4vKiA1OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAnYWN0aXZlUmVnaW9ucyc6IF9fd2VicGFja19yZXF1aXJlX18oMTApLFxuICAnYXJjJzogX193ZWJwYWNrX3JlcXVpcmVfXygxMSksXG4gICdhcmNUbyc6IF9fd2VicGFja19yZXF1aXJlX18oMTIpLFxuICAnYmVnaW5QYXRoJzogX193ZWJwYWNrX3JlcXVpcmVfXygyKSxcbiAgJ2JlemllckN1cnZlVG8nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzKSxcbiAgJ2NsZWFyUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMTQpLFxuICAnY2xpcCc6IF9fd2VicGFja19yZXF1aXJlX18oMTUpLFxuICAnY2xpcFBhdGgnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2KSxcbiAgJ2Nsb3NlUGF0aCc6IF9fd2VicGFja19yZXF1aXJlX18oMyksXG4gICdjcmVhdGVSZWd1bGFyUG9seWdvbic6IF9fd2VicGFja19yZXF1aXJlX18oMTcpLFxuICAnY3JlYXRlV3JhcHBlcic6IF9fd2VicGFja19yZXF1aXJlX18oMTgpLFxuICAnY3ljbGVNb3VzZURhdGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpLFxuICAnZHJhd0ltYWdlJzogX193ZWJwYWNrX3JlcXVpcmVfXygxOSksXG4gICdlbGxpcHNlJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMCksXG4gICdmaWxsJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMSksXG4gICdmaWxsQXJjJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMiksXG4gICdmaWxsUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMjMpLFxuICAnZmlsbFN0eWxlJzogX193ZWJwYWNrX3JlcXVpcmVfXygyNCksXG4gICdmaWxsVGV4dCc6IF9fd2VicGFja19yZXF1aXJlX18oMjUpLFxuICAnZ2xvYmFsQWxwaGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDI2KSxcbiAgJ2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbic6IF9fd2VicGFja19yZXF1aXJlX18oMjcpLFxuICAnaGl0UmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMjgpLFxuICAnaGl0UmVnaW9uJzogX193ZWJwYWNrX3JlcXVpcmVfXygyOSksXG4gICdpbWFnZVNtb290aGluZ0VuYWJsZWQnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMwKSxcbiAgJ2luaXRpYWxpemUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMxKSxcbiAgJ0luc3RydWN0aW9uJzogX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcbiAgJ2ludmVydE1hdHJpeCc6IF9fd2VicGFja19yZXF1aXJlX18oNSksXG4gICdrZXlEYXRhJzogX193ZWJwYWNrX3JlcXVpcmVfXygzMiksXG4gICdsaW5lU3R5bGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMzKSxcbiAgJ2xpbmVUbyc6IF9fd2VicGFja19yZXF1aXJlX18oNiksXG4gICdtb3VzZURhdGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM0KSxcbiAgJ21vdmVUbyc6IF9fd2VicGFja19yZXF1aXJlX18oNyksXG4gICdtb3ZlVG9MaW5lVG8nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM1KSxcbiAgJ3BhdGgnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM2KSxcbiAgJ3BsYWNlSG9sZGVyJzogX193ZWJwYWNrX3JlcXVpcmVfXygzNyksXG4gICdwb2ludEluUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oOCksXG4gICdxdWFkcmF0aWNDdXJ2ZVRvJzogX193ZWJwYWNrX3JlcXVpcmVfXygzOCksXG4gICdyYWYnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM5KSxcbiAgJ3JlY3QnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQwKSxcbiAgJ3JlbmRlcic6IF9fd2VicGFja19yZXF1aXJlX18oNDEpLFxuICAncmVzZXRUcmFuc2Zvcm0nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQyKSxcbiAgJ3JvdGF0ZSc6IF9fd2VicGFja19yZXF1aXJlX18oNDMpLFxuICAnc2NhbGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ0KSxcbiAgJ3NldFRyYW5zZm9ybSc6IF9fd2VicGFja19yZXF1aXJlX18oOSksXG4gICdzaGFkb3dTdHlsZSc6IF9fd2VicGFja19yZXF1aXJlX18oNDUpLFxuICAnc2tld1gnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ2KSxcbiAgJ3NrZXdZJzogX193ZWJwYWNrX3JlcXVpcmVfXyg0NyksXG4gICdzdHJva2UnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ4KSxcbiAgJ3N0cm9rZUFyYyc6IF9fd2VicGFja19yZXF1aXJlX18oNDkpLFxuICAnc3Ryb2tlUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oNTApLFxuICAnc3Ryb2tlU3R5bGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDUxKSxcbiAgJ3N0cm9rZVRleHQnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDUyKSxcbiAgJ3RleHRTdHlsZSc6IF9fd2VicGFja19yZXF1aXJlX18oNTMpLFxuICAndHJhbnNmb3JtJzogX193ZWJwYWNrX3JlcXVpcmVfXyg1NCksXG4gICd0cmFuc2Zvcm1Qb2ludHMnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpLFxuICAndHJhbnNsYXRlJzogX193ZWJwYWNrX3JlcXVpcmVfXyg1NSlcbn07XG5cbi8qKiovIH1cbi8qKioqKiovIF0pO1xufSk7Il19
const repatch = require('repatch');
const e2d = require('e2d');
const components = [];
const app = { pointer: false, mouseData: null, activeRegions: null };
const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = 400;
ctx.canvas.height = 300;
document.body.appendChild(ctx.canvas);
e2d.raf(() => {
app.mouseData = e2d.mouseData(ctx);
app.activeRegions = e2d.activeRegions(ctx);
app.pointer = false;
components.forEach(x => {
const region = app.activeRegions[x.id];
const prevActive = x.active;
x.hover = !!region;
if (region.clicked) {
x.active = true;
}
if (x.active && x.hover && !app.mouseData.state) {
x.onClick(app);
}
if (!app.mouseData.state) {
x.active = false;
}
x.dirty = x.update(app) || x.dirty || (prevActive !== x.active);
});
components.sort((x, y) => x.zIndex < y.zIndex ? -1 : x.zIndex > y.zIndex ? 1 : 0);
const view = components.map(x => x.dirty ? x._cache = x.render() : x._cache);
components.forEach(x => (x.dirty = false, true));
e2d.render(
e2d.clearRect(ctx.canvas.width, ctx.canvas.height),
view,
ctx
);
})
let id = -1;
class Component {
constructor({ position = [0, 0], scale = [1, 1], rotation = 0, alpha = 0, center = [0, 0], onClick = x => {} }) {
this.id = (++id).toString(36);
this.position = position;
this.scale = scale;
this.center = center;
this.rotation = rotaion;
this.alpha = alpha;
this.dirty = true;
this.active = false;
this.hover = false;
this._cache = [];
this.onClick = onClick;
}
render(...children) {
return e2d.translate(this.position[0], this.position[1],
e2d.rotate(this.rotation,
e2d.scale(this.scale[0], this.scale[1],
e2d.translate(-this.center[0], -this.center[1], ...children)
)
)
);
}
}
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"repatch": "1.3.2",
"e2d": "4.0.0-rc.1"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment