UNPKG

gd-canvas

Version:

This set of libraries was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.0 and no dependencies accept gd-tree (it has jquery and jstree) and gd-graph (it has jquery and chart.js).

190 lines 31.3 kB
import { Point } from 'gd-common'; var Tools = /** @class */ (function () { function Tools() { } Tools.prototype.Rotate = function (point, center, angle) { var origin = new Point(point.x - center.x, point.y - center.y); if (angle === 0) { return origin; } var radians = angle * Math.PI / 180.0; var nx = origin.x * Math.cos(radians) - origin.y * Math.sin(radians); var ny = origin.x * Math.sin(radians) + origin.y * Math.cos(radians); return new Point(nx, ny); }; Tools.prototype.Normal = function (point, start, end) { if (end.x === start.x) return new Point(start.x, point.y); if (end.y === start.y) return new Point(point.x, start.y); var k1 = (end.y - start.y) / (end.x - start.x); var k2 = (start.x - end.x) / (end.y - start.y); var b1 = start.y - k1 * start.x; var b2 = point.y - k2 * point.x; var x = (b2 - b1) / (k1 - k2); var y = k1 * x + b1; return new Point(x, y); }; Tools.prototype.DistanceTo = function (point, start, end) { return Math.abs((end.y - start.y) * point.x - (end.x - start.x) * point.y + end.x * start.y - end.y * start.x) / Math.sqrt(Math.pow(end.y - start.y, 2) + Math.pow(end.x - start.x, 2)); }; Tools.prototype.Intersect_OLD = function (a, b, c, d) { /* (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy) r = ----------------------------- (eqn 1) (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) */ var p = this.Intersection(a, b, c, d); return (p.x !== 0 && p.y !== 0); }; Tools.prototype.Intersect = function (a, b, c, d) { return this.doIntersect(a, b, c, d); }; // Given three colinear points p, q, r, the function checks if // point q lies on line segment 'pr' Tools.prototype.onSegment = function (p, q, r) { if (q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y)) return true; return false; }; // To find orientation of ordered triplet (p, q, r). // The function returns following values // 0 --> p, q and r are colinear // 1 --> Clockwise // 2 --> Counterclockwise Tools.prototype.orientation = function (p, q, r) { // See https://www.geeksforgeeks.org/orientation-3-ordered-points/ // for details of below formula. var val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); if (val === 0) return 0; // colinear return (val > 0 ? 1 : 2); // clock or counterclock wise }; // The main function that returns true if line segment 'p1q1' // and 'p2q2' intersect. Tools.prototype.doIntersect = function (p1, q1, p2, q2) { // Find the four orientations needed for general and // special cases var o1 = this.orientation(p1, q1, p2); var o2 = this.orientation(p1, q1, q2); var o3 = this.orientation(p2, q2, p1); var o4 = this.orientation(p2, q2, q1); // General case if (o1 !== o2 && o3 !== o4) return true; // Special Cases // p1, q1 and p2 are colinear and p2 lies on segment p1q1 if (o1 === 0 && this.onSegment(p1, p2, q1)) return true; // p1, q1 and q2 are colinear and q2 lies on segment p1q1 if (o2 === 0 && this.onSegment(p1, q2, q1)) return true; // p2, q2 and p1 are colinear and p1 lies on segment p2q2 if (o3 === 0 && this.onSegment(p2, p1, q2)) return true; // p2, q2 and q1 are colinear and q1 lies on segment p2q2 if (o4 === 0 && this.onSegment(p2, q1, q2)) return true; return false; // Doesn't fall in any of the above cases }; Tools.prototype.Intersection = function (p1, p2, p3, p4) { // calculate differences var xD1 = p2.x - p1.x; var yD1 = p2.y - p1.y; var xD2 = p4.x - p3.x; var yD2 = p4.y - p3.y; var xD3 = p1.x - p3.x; var yD3 = p1.y - p3.y; // calculate the lengths of the two lines var Len1 = Math.sqrt(xD1 * xD1 + yD1 * yD1); var Len2 = Math.sqrt(xD2 * xD2 + yD2 * yD2); // calculate angle between the two lines. var dot = (xD1 * xD2 + yD1 * yD2); // dot product var deg = dot / (Len1 * Len2); // if Math.Abs(angle)==1 then the lines are parallell, // so no intersection is possible if (Math.abs(deg) === 1) return new Point(0, 0); // find intersection Pt between two lines var pt = new Point(0, 0); var div = yD2 * xD1 - xD2 * yD1; var ua = (xD2 * yD3 - yD2 * xD3) / div; var ub = (xD1 * yD3 - yD1 * xD3) / div; pt.x = p1.x + ua * xD1; pt.y = p1.y + ua * yD1; // calculate the combined length of the two segments // between Pt-p1 and Pt-p2 xD1 = pt.x - p1.x; yD1 = pt.y - p1.y; xD2 = pt.x - p2.x; yD2 = pt.y - p2.y; var len1 = Math.sqrt(xD1 * xD1 + yD1 * yD1) + Math.sqrt(xD2 * xD2 + yD2 * yD2); // calculate the combined length of the two segments // between Pt-p3 and Pt-p4 xD1 = pt.x - p3.x; yD1 = pt.y - p3.y; xD2 = pt.x - p4.x; yD2 = pt.y - p4.y; var len2 = Math.sqrt(xD1 * xD1 + yD1 * yD1) + Math.sqrt(xD2 * xD2 + yD2 * yD2); var diff1 = Math.abs(Len1 - len1); var diff2 = Math.abs(Len2 - len2); if (diff1 > 0.01 || diff2 > 0.01) return new Point(0, 0); return pt; }; Tools.prototype.PointSide = function (point, start, end) { var D = (point.x - start.x) * (end.y - start.y) - (point.y - start.y) * (end.x - start.x); var result = (D === 0 ? 'INSIDE' : (D > 0 ? 'RIGHT' : 'LEFT')); return result; }; Tools.prototype.RoundRect = function (ctx, x, y, width, height, radius, fill, stroke) { if (typeof stroke === 'undefined') { stroke = true; } if (typeof radius === 'undefined') { radius = 5; } // --width; // --height; // x -= 0.5; // y -= 0.5; ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.lineTo(x + width - radius, y); ctx.quadraticCurveTo(x + width, y, x + width, y + radius); ctx.lineTo(x + width, y + height - radius); ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); ctx.lineTo(x + radius, y + height); ctx.quadraticCurveTo(x, y + height, x, y + height - radius); ctx.lineTo(x, y + radius); ctx.quadraticCurveTo(x, y, x + radius, y); ctx.closePath(); if (fill) ctx.fill(); if (stroke) ctx.stroke(); }; Tools.prototype.MeasureText = function (text, font, style) { var div = document.createElement('div'); document.body.appendChild(div); div.style.font = font; div.style.position = 'absolute'; div.style.left = '-1000'; div.style.top = '-1000'; div.style.fontStyle = style; div.innerHTML = text; var result = { width: div.clientWidth, height: div.clientHeight }; document.body.removeChild(div); div = null; return result; }; return Tools; }()); export { Tools }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2QtY2FudmFzLnRvb2xzLmpzIiwic291cmNlUm9vdCI6Im5nOi8vZ2QtY2FudmFzLyIsInNvdXJjZXMiOlsibGliL2dkLWNhbnZhcy50b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWxDO0lBQUE7SUF1T0EsQ0FBQztJQXJPVSxzQkFBTSxHQUFiLFVBQWUsS0FBYSxFQUFFLE1BQWMsRUFBRSxLQUFjO1FBRXhELElBQTJCLE1BQU0sR0FBSSxJQUFJLEtBQUssQ0FBRSxLQUFLLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUM7UUFDekYsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFHO1lBQUUsT0FBTyxNQUFNLENBQUM7U0FBRTtRQUVwQyxJQUFNLE9BQU8sR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFFeEMsSUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2RSxJQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXZFLE9BQU8sSUFBSSxLQUFLLENBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBRSxDQUFDO0lBQy9CLENBQUM7SUFFTSxzQkFBTSxHQUFiLFVBQWUsS0FBYSxFQUFFLEtBQWEsRUFBRSxHQUFXO1FBRXBELElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQztZQUFH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O1FBRTNCLElBQU0sTUFBTSxHQUNaO1lBQ0ksS0FBSyxFQUFHLEdBQUcsQ0FBQyxXQUFXO1lBQ3ZCLE1BQU0sRUFBRSxHQUFHLENBQUMsWUFBWTtTQUMzQixDQUFDO1FBRUYsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsR0FBRyxHQUFHLElBQUksQ0FBQztRQUVYLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFDTCxZQUFDO0FBQUQsQ0FBQyxBQXZPRCxJQXVPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBvaW50IH0gZnJvbSAnZ2QtY29tbW9uJztcclxuXHJcbmV4cG9ydCBjbGFzcyBUb29sc1xyXG57XHJcbiAgICBwdWJsaWMgUm90YXRlKCBwb2ludCA6IFBvaW50LCBjZW50ZXIgOiBQb2ludCwgYW5nbGUgOiBudW1iZXIgKSA6IFBvaW50XHJcbiAgICB7XHJcbiAgICAgICAgY29uc3QgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luICA9IG5ldyBQb2ludCggcG9pbnQueCAtIGNlbnRlci54LCBwb2ludC55IC0gY2VudGVyLnkgKTtcclxuICAgICAgICBpZiggYW5nbGUgPT09IDAgKSB7IHJldHVybiBvcmlnaW47IH1cclxuXHJcbiAgICAgICAgY29uc3QgcmFkaWFucyA9IGFuZ2xlICogTWF0aC5QSSAvIDE4MC4wO1xyXG5cclxuICAgICAgICBjb25zdCBueCA9IG9yaWdpbi54ICogTWF0aC5jb3MocmFkaWFucykgLSBvcmlnaW4ueSAqIE1hdGguc2luKHJhZGlhbnMpO1xyXG4gICAgICAgIGNvbnN0IG55ID0gb3JpZ2luLnggKiBNYXRoLnNpbihyYWRpYW5zKSArIG9yaWdpbi55ICogTWF0aC5jb3MocmFkaWFucyk7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUG9pbnQoIG54LCBueSApO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBOb3JtYWwoIHBvaW50IDogUG9pbnQsIHN0YXJ0IDogUG9pbnQsIGVuZCA6IFBvaW50ICkgOiBQb2ludFxyXG4gICAge1xyXG4gICAgICAgIGlmKCBlbmQueCA9PT0gc3RhcnQueCApIHJldHVybiBuZXcgUG9pbnQoc3RhcnQueCwgcG9pbnQueSk7XHJcbiAgICAgICAgaWYoIGVuZC55ID09PSBzdGFydC55ICkgcmV0dXJuIG5ldyBQb2ludChwb2ludC54LCBzdGFydC55KTtcclxuXHJcbiAgICAgICAgY29uc3QgazEgPSAoZW5kLnkgLSBzdGFydC55KSAvIChlbmQueCAtIHN0YXJ0LngpO1xyXG4gICAgICAgIGNvbnN0IGsyID0gKHN0YXJ0LnggLSBlbmQueCkgLyAoZW5kLnkgLSBzdGFydC55KTtcclxuXHJcbiAgICAgICAgY29uc3QgYjEgPSBzdGFydC55IC0gazEgKiBzdGFydC54O1xyXG4gICAgICAgIGNvbnN0IGIyID0gcG9pbnQueSAtIGsyICogcG9pbnQueDtcclxuXHJcbiAgICAgICAgY29uc3QgeCAgPSAoYjIgLSBiMSkgLyAoazEgLSBrMik7XHJcbiAgICAgICAgY29uc3QgeSAgPSBrMSAqIHggKyBiMTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQb2ludCh4LHkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBEaXN0YW5jZVRvKCBwb2ludCA6IFBvaW50LCBzdGFydCA6IFBvaW50LCBlbmQgOiBQb2ludCApXHJcbiAgICB7XHJcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzICggKGVuZC55LXN0YXJ0LnkpKnBvaW50LnggLSAoZW5kLngtc3RhcnQueCkqcG9pbnQueSArIGVuZC54ICogc3RhcnQueSAtIGVuZC55ICogc3RhcnQueCkgL1xyXG4gICAgICAgICAgICAgICBNYXRoLnNxcnQoIE1hdGgucG93KGVuZC55LXN0YXJ0LnksIDIpICsgTWF0aC5wb3coZW5kLngtc3RhcnQueCwgMikgKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgSW50ZXJzZWN0X09MRCggYSA6IFBvaW50LCBiIDogUG9pbnQsIGMgOiBQb2ludCwgZCA6IFBvaW50ICkgOiBib29sZWFuXHJcbiAgICB7XHJcbiAgICAgICAgLypcclxuICAgICAgICAgICAgICAgKEF5LUN5KShEeC1DeCktKEF4LUN4KShEeS1DeSlcclxuICAgICAgICAgICByID0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIChlcW4gMSlcclxuICAgICAgICAgICAgICAgKEJ4LUF4KShEeS1DeSktKEJ5LUF5KShEeC1DeClcclxuICAgICAgICAqL1xyXG5cclxuICAgICAgIGNvbnN0ICAgcCAgPSB0aGlzLkludGVyc2VjdGlvbihhLCBiLCBjLCBkKTtcclxuICAgICAgIHJldHVybiAocC54ICE9PSAwICYmIHAueSAhPT0gMCApO1xyXG4gICAgfVxyXG4gICAgcHVibGljIEludGVyc2VjdCggYSA6IFBvaW50LCBiIDogUG9pbnQsIGMgOiBQb2ludCwgZCA6IFBvaW50ICkgOiBib29sZWFuXHJcbiAgICB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9JbnRlcnNlY3QoIGEsIGIsIGMsIGQgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBHaXZlbiB0aHJlZSBjb2xpbmVhciBwb2ludHMgcCwgcSwgciwgdGhlIGZ1bmN0aW9uIGNoZWNrcyBpZlxyXG4gICAgLy8gcG9pbnQgcSBsaWVzIG9uIGxpbmUgc2VnbWVudCAncHInXHJcbiAgICBwdWJsaWMgb25TZWdtZW50KCBwIDogUG9pbnQsIHEgOiBQb2ludCwgciA6IFBvaW50KSA6IGJvb2xlYW5cclxuICAgIHtcclxuICAgICAgICBpZiggcS54IDw9IE1hdGgubWF4KHAueCwgci54KSAmJiBxLnggPj0gTWF0aC5taW4ocC54LCByLngpICYmXHJcbiAgICAgICAgICAgIHEueSA8PSBNYXRoLm1heChwLnksIHIueSkgJiYgcS55ID49IE1hdGgubWluKHAueSwgci55KSApIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVG8gZmluZCBvcmllbnRhdGlvbiBvZiBvcmRlcmVkIHRyaXBsZXQgKHAsIHEsIHIpLlxyXG4gICAgLy8gVGhlIGZ1bmN0aW9uIHJldHVybnMgZm9sbG93aW5nIHZhbHVlc1xyXG4gICAgLy8gMCAtLT4gcCwgcSBhbmQgciBhcmUgY29saW5lYXJcclxuICAgIC8vIDEgLS0+IENsb2Nrd2lzZVxyXG4gICAgLy8gMiAtLT4gQ291bnRlcmNsb2Nrd2lzZVxyXG4gICAgcHVibGljIG9yaWVudGF0aW9uKHAgOiBQb2ludCwgcTogUG9pbnQsIHI6IFBvaW50KSA6IG51bWJlclxyXG4gICAge1xyXG4gICAgICAgIC8vIFNlZSBodHRwczovL3d3dy5nZWVrc2ZvcmdlZWtzLm9yZy9vcmllbnRhdGlvbi0zLW9yZGVyZWQtcG9pbnRzL1xyXG4gICAgICAgIC8vIGZvciBkZXRhaWxzIG9mIGJlbG93IGZvcm11bGEuXHJcbiAgICAgICAgY29uc3QgdmFsID0gKHEueSAtIHAueSkgKiAoci54IC0gcS54KSAtXHJcbiAgICAgICAgICAgICAgICAgICAgKHEueCAtIHAueCkgKiAoci55IC0gcS55KTtcclxuXHJcbiAgICAgICAgaWYoIHZhbCA9PT0gMCApIHJldHVybiAwOyAgLy8gY29saW5lYXJcclxuXHJcbiAgICAgICAgcmV0dXJuICh2YWwgPiAwID8gMTogMik7IC8vIGNsb2NrIG9yIGNvdW50ZXJjbG9jayB3aXNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGhlIG1haW4gZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgbGluZSBzZWdtZW50ICdwMXExJ1xyXG4gICAgLy8gYW5kICdwMnEyJyBpbnRlcnNlY3QuXHJcbiAgICBwdWJsaWMgZG9JbnRlcnNlY3QoIHAxOiBQb2ludCwgcTE6IFBvaW50LCBwMjogUG9pbnQsIHEyOiBQb2ludCApXHJcbiAgICB7XHJcbiAgICAgICAgLy8gRmluZCB0aGUgZm91ciBvcmllbnRhdGlvbnMgbmVlZGVkIGZvciBnZW5lcmFsIGFuZFxyXG4gICAgICAgIC8vIHNwZWNpYWwgY2FzZXNcclxuICAgICAgICBjb25zdCBvMSA9IHRoaXMub3JpZW50YXRpb24oIHAxLCBxMSwgcDIgKTtcclxuICAgICAgICBjb25zdCBvMiA9IHRoaXMub3JpZW50YXRpb24oIHAxLCBxMSwgcTIgKTtcclxuICAgICAgICBjb25zdCBvMyA9IHRoaXMub3JpZW50YXRpb24oIHAyLCBxMiwgcDEgKTtcclxuICAgICAgICBjb25zdCBvNCA9IHRoaXMub3JpZW50YXRpb24oIHAyLCBxMiwgcTEgKTtcclxuXHJcbiAgICAgICAgLy8gR2VuZXJhbCBjYXNlXHJcbiAgICAgICAgaWYoIG8xICE9PSBvMiAmJiBvMyAhPT0gbzQgKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gU3BlY2lhbCBDYXNlc1xyXG4gICAgICAgIC8vIHAxLCBxMSBhbmQgcDIgYXJlIGNvbGluZWFyIGFuZCBwMiBsaWVzIG9uIHNlZ21lbnQgcDFxMVxyXG4gICAgICAgIGlmKCBvMSA9PT0gMCAmJiB0aGlzLm9uU2VnbWVudChwMSwgcDIsIHExKSkgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIC8vIHAxLCBxMSBhbmQgcTIgYXJlIGNvbGluZWFyIGFuZCBxMiBsaWVzIG9uIHNlZ21lbnQgcDFxMVxyXG4gICAgICAgIGlmIChvMiA9PT0gMCAmJiB0aGlzLm9uU2VnbWVudChwMSwgcTIsIHExKSkgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIC8vIHAyLCBxMiBhbmQgcDEgYXJlIGNvbGluZWFyIGFuZCBwMSBsaWVzIG9uIHNlZ21lbnQgcDJxMlxyXG4gICAgICAgIGlmIChvMyA9PT0gMCAmJiB0aGlzLm9uU2VnbWVudChwMiwgcDEsIHEyKSkgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIC8vIHAyLCBxMiBhbmQgcTEgYXJlIGNvbGluZWFyIGFuZCBxMSBsaWVzIG9uIHNlZ21lbnQgcDJxMlxyXG4gICAgICAgIGlmIChvNCA9PT0gMCAmJiB0aGlzLm9uU2VnbWVudChwMiwgcTEsIHEyKSkgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8gRG9lc24ndCBmYWxsIGluIGFueSBvZiB0aGUgYWJvdmUgY2FzZXNcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgSW50ZXJzZWN0aW9uKCBwMSA6IFBvaW50LCBwMiA6IFBvaW50LCBwMyA6IFBvaW50LCBwNCA6IFBvaW50ICkgOiBQb2ludFxyXG4gICAge1xyXG4gICAgICAgIC8vIGNhbGN1bGF0ZSBkaWZmZXJlbmNlc1xyXG4gICAgICAgIGxldCAgIHhEMSA9IHAyLnggLSBwMS54O1xyXG4gICAgICAgIGxldCAgIHlEMSA9IHAyLnkgLSBwMS55O1xyXG5cclxuICAgICAgICBsZXQgICB4RDIgPSBwNC54IC0gcDMueDtcclxuICAgICAgICBsZXQgICB5RDIgPSBwNC55IC0gcDMueTtcclxuXHJcbiAgICAgICAgY29uc3QgeEQzID0gcDEueCAtIHAzLng7XHJcbiAgICAgICAgY29uc3QgeUQzID0gcDEueSAtIHAzLnk7XHJcblxyXG4gICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgbGVuZ3RocyBvZiB0aGUgdHdvIGxpbmVzXHJcbiAgICAgICAgY29uc3QgTGVuMSA9IE1hdGguc3FydCggeEQxICogeEQxICsgeUQxICogeUQxICk7XHJcbiAgICAgICAgY29uc3QgTGVuMiA9IE1hdGguc3FydCggeEQyICogeEQyICsgeUQyICogeUQyICk7XHJcblxyXG4gICAgICAgIC8vIGNhbGN1bGF0ZSBhbmdsZSBiZXR3ZWVuIHRoZSB0d28gbGluZXMuXHJcbiAgICAgICAgY29uc3QgZG90ID0gKHhEMSAqIHhEMiArIHlEMSAqIHlEMik7IC8vIGRvdCBwcm9kdWN0XHJcbiAgICAgICAgY29uc3QgZGVnID0gZG90IC8gKExlbjEgKiBMZW4yKTtcclxuXHJcbiAgICAgICAgLy8gaWYgTWF0aC5BYnMoYW5nbGUpPT0xIHRoZW4gdGhlIGxpbmVzIGFyZSBwYXJhbGxlbGwsXHJcbiAgICAgICAgLy8gc28gbm8gaW50ZXJzZWN0aW9uIGlzIHBvc3NpYmxlXHJcbiAgICAgICAgaWYoIE1hdGguYWJzKGRlZykgPT09IDEgKSByZXR1cm4gbmV3IFBvaW50KDAsMCk7XHJcblxyXG4gICAgICAgIC8vIGZpbmQgaW50ZXJzZWN0aW9uIFB0IGJldHdlZW4gdHdvIGxpbmVzXHJcbiAgICAgICAgY29uc3QgcHQgPSBuZXcgUG9pbnQoMCwgMCk7XHJcbiAgICAgICAgY29uc3QgZGl2ID0geUQyICogeEQxIC0geEQyICogeUQxO1xyXG4gICAgICAgIGNvbnN0IHVhID0gKHhEMiAqIHlEMyAtIHlEMiAqIHhEMykgLyBkaXY7XHJcbiAgICAgICAgY29uc3QgdWIgPSAoeEQxICogeUQzIC0geUQxICogeEQzKSAvIGRpdjtcclxuXHJcbiAgICAgICAgcHQueCA9IHAxLnggKyB1YSAqIHhEMTtcclxuICAgICAgICBwdC55ID0gcDEueSArIHVhICogeUQxO1xyXG5cclxuICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIGNvbWJpbmVkIGxlbmd0aCBvZiB0aGUgdHdvIHNlZ21lbnRzXHJcbiAgICAgICAgLy8gYmV0d2VlbiBQdC1wMSBhbmQgUHQtcDJcclxuICAgICAgICB4RDEgPSBwdC54IC0gcDEueDtcclxuICAgICAgICB5RDEgPSBwdC55IC0gcDEueTtcclxuXHJcbiAgICAgICAgeEQyID0gcHQueCAtIHAyLng7XHJcbiAgICAgICAgeUQyID0gcHQueSAtIHAyLnk7XHJcblxyXG4gICAgICAgIGNvbnN0IGxlbjEgPSBNYXRoLnNxcnQoeEQxICogeEQxICsgeUQxICogeUQxKSArIE1hdGguc3FydCh4RDIgKiB4RDIgKyB5RDIgKiB5RDIpO1xyXG5cclxuICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIGNvbWJpbmVkIGxlbmd0aCBvZiB0aGUgdHdvIHNlZ21lbnRzXHJcbiAgICAgICAgLy8gYmV0d2VlbiBQdC1wMyBhbmQgUHQtcDRcclxuICAgICAgICB4RDEgPSBwdC54IC0gcDMueDtcclxuICAgICAgICB5RDEgPSBwdC55IC0gcDMueTtcclxuXHJcbiAgICAgICAgeEQyID0gcHQueCAtIHA0Lng7XHJcbiAgICAgICAgeUQyID0gcHQueSAtIHA0Lnk7XHJcblxyXG4gICAgICAgIGNvbnN0IGxlbjIgPSBNYXRoLnNxcnQoeEQxICogeEQxICsgeUQxICogeUQxKSArIE1hdGguc3FydCh4RDIgKiB4RDIgKyB5RDIgKiB5RDIpO1xyXG5cclxuICAgICAgICBjb25zdCAgZGlmZjEgPSBNYXRoLmFicyhMZW4xIC0gbGVuMSk7XHJcbiAgICAgICAgY29uc3QgIGRpZmYyID0gTWF0aC5hYnMoTGVuMiAtIGxlbjIpO1xyXG5cclxuICAgICAgICBpZiggZGlmZjEgPiAwLjAxIHx8IGRpZmYyID4gMC4wMSApICByZXR1cm4gbmV3IFBvaW50KDAsMCk7XHJcblxyXG4gICAgICAgIHJldHVybiBwdDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgUG9pbnRTaWRlKCBwb2ludCA6IFBvaW50LCBzdGFydCA6IFBvaW50LCBlbmQgOiBQb2ludCApIDogc3RyaW5nXHJcbiAgICB7XHJcbiAgICAgICAgY29uc3QgRCA9IChwb2ludC54IC0gc3RhcnQueCkgKiAoZW5kLnkgLSBzdGFydC55KSAtIChwb2ludC55IC0gc3RhcnQueSkgKiAoZW5kLnggLSBzdGFydC54KTtcclxuXHJcbiAgICAgICAgY29uc3QgIHJlc3VsdCA9IChEID09PSAwID8gJ0lOU0lERScgOiAoRCA+IDAgPyAnUklHSFQnIDogJ0xFRlQnKSk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgUm91bmRSZWN0KCBjdHggOiBhbnksIHggOiBhbnksIHkgOiBhbnksIHdpZHRoIDogYW55LCBoZWlnaHQgOiBhbnksIHJhZGl1cyA6IGFueSwgZmlsbCA6IGFueSwgc3Ryb2tlIDogYW55IClcclxuICAgIHtcclxuICAgICAgICBpZiggdHlwZW9mIHN0cm9rZSA9PT0gJ3VuZGVmaW5lZCcgKSB7IHN0cm9rZSA9IHRydWU7IH1cclxuICAgICAgICBpZiggdHlwZW9mIHJhZGl1cyA9PT0gJ3VuZGVmaW5lZCcgKSB7IHJhZGl1cyA9IDU7ICAgIH1cclxuXHJcbiAgICAgICAgLy8gLS13aWR0aDtcclxuICAgICAgICAvLyAtLWhlaWdodDtcclxuXHJcbiAgICAgICAgLy8geCAtPSAwLjU7XHJcbiAgICAgICAgLy8geSAtPSAwLjU7XHJcblxyXG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgICBjdHgubW92ZVRvKHggKyByYWRpdXMsIHkpO1xyXG4gICAgICAgIGN0eC5saW5lVG8oeCArIHdpZHRoIC0gcmFkaXVzLCB5KTtcclxuICAgICAgICBjdHgucXVhZHJhdGljQ3VydmVUbyh4ICsgd2lkdGgsIHksIHggKyB3aWR0aCwgeSArIHJhZGl1cyk7XHJcbiAgICAgICAgY3R4LmxpbmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQgLSByYWRpdXMpO1xyXG4gICAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHggKyB3aWR0aCwgeSArIGhlaWdodCwgeCArIHdpZHRoIC0gcmFkaXVzLCB5ICsgaGVpZ2h0KTtcclxuICAgICAgICBjdHgubGluZVRvKHggKyByYWRpdXMsIHkgKyBoZWlnaHQpO1xyXG4gICAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHkgKyBoZWlnaHQsIHgsIHkgKyBoZWlnaHQgLSByYWRpdXMpO1xyXG4gICAgICAgIGN0eC5saW5lVG8oeCwgeSArIHJhZGl1cyk7XHJcbiAgICAgICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8oeCwgeSwgeCArIHJhZGl1cywgeSk7XHJcbiAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xyXG5cclxuICAgICAgICBpZiggZmlsbCAgICkgY3R4LmZpbGwoKTtcclxuICAgICAgICBpZiggc3Ryb2tlICkgY3R4LnN0cm9rZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBNZWFzdXJlVGV4dCggdGV4dCA6IHN0cmluZywgZm9udCA6IHN0cmluZywgc3R5bGUgOiBzdHJpbmcgKVxyXG4gICAge1xyXG4gICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuXHJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpO1xyXG5cclxuICAgICAgICBkaXYuc3R5bGUuZm9udCAgICAgID0gZm9udDtcclxuICAgICAgICBkaXYuc3R5bGUucG9zaXRpb24gID0gJ2Fic29sdXRlJztcclxuICAgICAgICBkaXYuc3R5bGUubGVmdCAgICAgID0gJy0xMDAwJztcclxuICAgICAgICBkaXYuc3R5bGUudG9wICAgICAgID0gJy0xMDAwJztcclxuICAgICAgICBkaXYuc3R5bGUuZm9udFN0eWxlID0gc3R5bGU7XHJcbiAgICAgICAgZGl2LmlubmVySFRNTCAgICAgICA9IHRleHQ7XHJcblxyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9XHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB3aWR0aCA6IGRpdi5jbGllbnRXaWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0OiBkaXYuY2xpZW50SGVpZ2h0XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChkaXYpO1xyXG4gICAgICAgIGRpdiA9IG51bGw7XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbn1cclxuIl19