From 9962d8d85135d53338eabe30d2a92118c0a2ccf9 Mon Sep 17 00:00:00 2001 From: Ian McGregor Date: Wed, 16 Dec 2015 18:25:26 -0800 Subject: [PATCH] v0.2.2 --- bower.json | 2 +- dist/boid.js | 158 +++++++++++++++++++++++++++++++---------------- dist/boid.min.js | 2 +- package.json | 2 +- 4 files changed, 107 insertions(+), 57 deletions(-) diff --git a/bower.json b/bower.json index 6fe8749..e1e91f4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "boid", - "version": "0.2.0", + "version": "0.2.2", "homepage": "https://github.com/ianmcgregor/boid", "authors": [ "Ian McGregor " diff --git a/dist/boid.js b/dist/boid.js index 54f9d13..f9c0d72 100644 --- a/dist/boid.js +++ b/dist/boid.js @@ -3,40 +3,61 @@ var Vec2 = require('./vec2.js'); -function Boid() { - var position = Vec2.get(); - var velocity = Vec2.get(); - var steeringForce = Vec2.get(); - var bounds = { +var defaults = { + bounds: { x: 0, y: 0, width: 640, height: 480 - }; - var edgeBehavior = Boid.EDGE_BOUNCE; - var mass = 1.0; - var maxSpeed = 10; + }, + edgeBehavior: 'bounce', + mass: 1.0, + maxSpeed: 10, + maxForce: 1, + arriveThreshold: 50, + wanderDistance: 10, + wanderRadius: 5, + wanderAngle: 0, + wanderRange: 1, + avoidDistance: 300, + avoidBuffer: 20, + pathThreshold: 20, + maxDistance: 300, + minDistance: 60 +}; + +function Boid(options) { + options = configure(options); + + var position = Vec2.get(); + var velocity = Vec2.get(); + var steeringForce = Vec2.get(); + + var bounds = options.bounds; + var edgeBehavior = options.edgeBehavior; + var mass = options.mass; + var maxSpeed = options.maxSpeed; var maxSpeedSq = maxSpeed * maxSpeed; - var maxForce = 1; + var maxForce = options.maxForce; // arrive - var arriveThreshold = 50; + var arriveThreshold = options.arriveThreshold; var arriveThresholdSq = arriveThreshold * arriveThreshold; // wander - var wanderDistance = 10; - var wanderRadius = 5; - var wanderAngle = 0; - var wanderRange = 1; + var wanderDistance = options.wanderDistance; + var wanderRadius = options.wanderRadius; + var wanderAngle = options.wanderAngle; + var wanderRange = options.wanderRange; // avoid - var avoidDistance = 300; - var avoidBuffer = 20; + var avoidDistance = options.avoidDistance; + var avoidBuffer = options.avoidBuffer; // follow path var pathIndex = 0; - var pathThreshold = 20; + var pathThreshold = options.pathThreshold; var pathThresholdSq = pathThreshold * pathThreshold; // flock - var maxDistance = 300; + var maxDistance = options.maxDistance; var maxDistanceSq = maxDistance * maxDistance; - var minDistance = 60; + var minDistance = options.minDistance; var minDistanceSq = minDistance * minDistance; var setBounds = function(width, height, x, y) { @@ -473,6 +494,22 @@ Boid.obstacle = function(radius, x, y) { }; }; +function setDefaults(opts, defs) { + Object.keys(defs).forEach(function(key) { + if (typeof opts[key] === 'undefined') { + opts[key] = defs[key]; + } + }); +} + +function configure(options) { + options = options || {}; + options.bounds = options.bounds || {}; + setDefaults(options, defaults); + setDefaults(options.bounds, defaults.bounds); + return options; +} + if (typeof module === 'object' && module.exports) { module.exports = Boid; } @@ -498,10 +535,13 @@ Vec2.prototype = { }, normalize: function() { var l = this.length; - if(l === 0) { + if (l === 0) { this.x = 1; return this; } + if (l === 1) { + return this; + } this.x /= l; this.y /= l; return this; @@ -509,8 +549,8 @@ Vec2.prototype = { isNormalized: function() { return this.length === 1; }, - truncate: function(max) { - if(this.length > max) { + truncate: function(max) { + if (this.length > max) { this.length = max; } return this; @@ -535,9 +575,14 @@ Vec2.prototype = { }, dotProduct: function(vec) { /* - If A and B are perpendicular (at 90 degrees to each other), the result of the dot product will be zero, because cos(Θ) will be zero. - If the angle between A and B are less than 90 degrees, the dot product will be positive (greater than zero), as cos(Θ) will be positive, and the vector lengths are always positive values. - If the angle between A and B are greater than 90 degrees, the dot product will be negative (less than zero), as cos(Θ) will be negative, and the vector lengths are always positive values + If A and B are perpendicular (at 90 degrees to each other), the result + of the dot product will be zero, because cos(Θ) will be zero. + If the angle between A and B are less than 90 degrees, the dot product + will be positive (greater than zero), as cos(Θ) will be positive, and + the vector lengths are always positive values. + If the angle between A and B are greater than 90 degrees, the dot + product will be negative (less than zero), as cos(Θ) will be negative, + and the vector lengths are always positive values */ return this.x * vec.x + this.y * vec.y; }, @@ -587,31 +632,31 @@ Vec2.prototype = { // getters / setters Object.defineProperties(Vec2.prototype, { - lengthSquared: { - get: function() { - return this.x * this.x + this.y * this.y; - } - }, - length: { - get: function() { - return Math.sqrt(this.lengthSquared); - }, - set: function(value) { - var a = this.angle; - this.x = Math.cos(a) * value; - this.y = Math.sin(a) * value; - } - }, - angle: { - get: function() { - return Math.atan2(this.y, this.x); - }, - set: function(value) { - var l = this.length; - this.x = Math.cos(value) * l; - this.y = Math.sin(value) * l; - } - } + lengthSquared: { + get: function() { + return this.x * this.x + this.y * this.y; + } + }, + length: { + get: function() { + return Math.sqrt(this.lengthSquared); + }, + set: function(value) { + var a = this.angle; + this.x = Math.cos(a) * value; + this.y = Math.sin(a) * value; + } + }, + angle: { + get: function() { + return Math.atan2(this.y, this.x); + }, + set: function(value) { + var l = this.length; + this.x = Math.cos(value) * l; + this.y = Math.sin(value) * l; + } + } }); // static @@ -630,8 +675,12 @@ Vec2.fill = function(n) { }; Vec2.angleBetween = function(a, b) { - if(!a.isNormalized()) { a = a.clone().normalize(); } - if(!b.isNormalized()) { b = b.clone().normalize(); } + if (!a.isNormalized()) { + a = a.clone().normalize(); + } + if (!b.isNormalized()) { + b = b.clone().normalize(); + } return Math.acos(a.dotProduct(b)); }; @@ -640,4 +689,5 @@ if (typeof module === 'object' && module.exports) { } },{}]},{},[1])(1) -}); \ No newline at end of file +}); +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYm9pZC5qcyIsInNyYy92ZWMyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVmVjMiA9IHJlcXVpcmUoJy4vdmVjMi5qcycpO1xuXG52YXIgZGVmYXVsdHMgPSB7XG4gICAgYm91bmRzOiB7XG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDAsXG4gICAgICAgIHdpZHRoOiA2NDAsXG4gICAgICAgIGhlaWdodDogNDgwXG4gICAgfSxcbiAgICBlZGdlQmVoYXZpb3I6ICdib3VuY2UnLFxuICAgIG1hc3M6IDEuMCxcbiAgICBtYXhTcGVlZDogMTAsXG4gICAgbWF4Rm9yY2U6IDEsXG4gICAgYXJyaXZlVGhyZXNob2xkOiA1MCxcbiAgICB3YW5kZXJEaXN0YW5jZTogMTAsXG4gICAgd2FuZGVyUmFkaXVzOiA1LFxuICAgIHdhbmRlckFuZ2xlOiAwLFxuICAgIHdhbmRlclJhbmdlOiAxLFxuICAgIGF2b2lkRGlzdGFuY2U6IDMwMCxcbiAgICBhdm9pZEJ1ZmZlcjogMjAsXG4gICAgcGF0aFRocmVzaG9sZDogMjAsXG4gICAgbWF4RGlzdGFuY2U6IDMwMCxcbiAgICBtaW5EaXN0YW5jZTogNjBcbn07XG5cbmZ1bmN0aW9uIEJvaWQob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBjb25maWd1cmUob3B0aW9ucyk7XG5cbiAgICB2YXIgcG9zaXRpb24gPSBWZWMyLmdldCgpO1xuICAgIHZhciB2ZWxvY2l0eSA9IFZlYzIuZ2V0KCk7XG4gICAgdmFyIHN0ZWVyaW5nRm9yY2UgPSBWZWMyLmdldCgpO1xuXG4gICAgdmFyIGJvdW5kcyA9IG9wdGlvbnMuYm91bmRzO1xuICAgIHZhciBlZGdlQmVoYXZpb3IgPSBvcHRpb25zLmVkZ2VCZWhhdmlvcjtcbiAgICB2YXIgbWFzcyA9IG9wdGlvbnMubWFzcztcbiAgICB2YXIgbWF4U3BlZWQgPSBvcHRpb25zLm1heFNwZWVkO1xuICAgIHZhciBtYXhTcGVlZFNxID0gbWF4U3BlZWQgKiBtYXhTcGVlZDtcbiAgICB2YXIgbWF4Rm9yY2UgPSBvcHRpb25zLm1heEZvcmNlO1xuICAgIC8vIGFycml2ZVxuICAgIHZhciBhcnJpdmVUaHJlc2hvbGQgPSBvcHRpb25zLmFycml2ZVRocmVzaG9sZDtcbiAgICB2YXIgYXJyaXZlVGhyZXNob2xkU3EgPSBhcnJpdmVUaHJlc2hvbGQgKiBhcnJpdmVUaHJlc2hvbGQ7XG4gICAgLy8gd2FuZGVyXG4gICAgdmFyIHdhbmRlckRpc3RhbmNlID0gb3B0aW9ucy53YW5kZXJEaXN0YW5jZTtcbiAgICB2YXIgd2FuZGVyUmFkaXVzID0gb3B0aW9ucy53YW5kZXJSYWRpdXM7XG4gICAgdmFyIHdhbmRlckFuZ2xlID0gb3B0aW9ucy53YW5kZXJBbmdsZTtcbiAgICB2YXIgd2FuZGVyUmFuZ2UgPSBvcHRpb25zLndhbmRlclJhbmdlO1xuICAgIC8vIGF2b2lkXG4gICAgdmFyIGF2b2lkRGlzdGFuY2UgPSBvcHRpb25zLmF2b2lkRGlzdGFuY2U7XG4gICAgdmFyIGF2b2lkQnVmZmVyID0gb3B0aW9ucy5hdm9pZEJ1ZmZlcjtcbiAgICAvLyBmb2xsb3cgcGF0aFxuICAgIHZhciBwYXRoSW5kZXggPSAwO1xuICAgIHZhciBwYXRoVGhyZXNob2xkID0gb3B0aW9ucy5wYXRoVGhyZXNob2xkO1xuICAgIHZhciBwYXRoVGhyZXNob2xkU3EgPSBwYXRoVGhyZXNob2xkICogcGF0aFRocmVzaG9sZDtcbiAgICAvLyBmbG9ja1xuICAgIHZhciBtYXhEaXN0YW5jZSA9IG9wdGlvbnMubWF4RGlzdGFuY2U7XG4gICAgdmFyIG1heERpc3RhbmNlU3EgPSBtYXhEaXN0YW5jZSAqIG1heERpc3RhbmNlO1xuICAgIHZhciBtaW5EaXN0YW5jZSA9IG9wdGlvbnMubWluRGlzdGFuY2U7XG4gICAgdmFyIG1pbkRpc3RhbmNlU3EgPSBtaW5EaXN0YW5jZSAqIG1pbkRpc3RhbmNlO1xuXG4gICAgdmFyIHNldEJvdW5kcyA9IGZ1bmN0aW9uKHdpZHRoLCBoZWlnaHQsIHgsIHkpIHtcbiAgICAgICAgYm91bmRzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIGJvdW5kcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIGJvdW5kcy54ID0geCB8fCAwO1xuICAgICAgICBib3VuZHMueSA9IHkgfHwgMDtcblxuICAgICAgICByZXR1cm4gYm9pZDtcbiAgICB9O1xuXG4gICAgdmFyIHVwZGF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBzdGVlcmluZ0ZvcmNlLnRydW5jYXRlKG1heEZvcmNlKTtcbiAgICAgICAgc3RlZXJpbmdGb3JjZS5kaXZpZGVCeShtYXNzKTtcbiAgICAgICAgdmVsb2NpdHkuYWRkKHN0ZWVyaW5nRm9yY2UpO1xuICAgICAgICBzdGVlcmluZ0ZvcmNlLnJlc2V0KCk7XG4gICAgICAgIHZlbG9jaXR5LnRydW5jYXRlKG1heFNwZWVkKTtcbiAgICAgICAgcG9zaXRpb24uYWRkKHZlbG9jaXR5KTtcblxuICAgICAgICBpZiAoZWRnZUJlaGF2aW9yID09PSBCb2lkLkVER0VfQk9VTkNFKSB7XG4gICAgICAgICAgICBib3VuY2UoKTtcbiAgICAgICAgfSBlbHNlIGlmIChlZGdlQmVoYXZpb3IgPT09IEJvaWQuRURHRV9XUkFQKSB7XG4gICAgICAgICAgICB3cmFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJvaWQ7XG4gICAgfTtcblxuICAgIHZhciBib3VuY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHBvc2l0aW9uLnggPiBib3VuZHMud2lkdGgpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggPSBib3VuZHMud2lkdGg7XG4gICAgICAgICAgICB2ZWxvY2l0eS54ICo9IC0xO1xuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uLnggPCBib3VuZHMueCkge1xuICAgICAgICAgICAgcG9zaXRpb24ueCA9IGJvdW5kcy54O1xuICAgICAgICAgICAgdmVsb2NpdHkueCAqPSAtMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb24ueSA+IGJvdW5kcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnkgPSBib3VuZHMuaGVpZ2h0O1xuICAgICAgICAgICAgdmVsb2NpdHkueSAqPSAtMTtcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbi55IDwgYm91bmRzLnkpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnkgPSBib3VuZHMueTtcbiAgICAgICAgICAgIHZlbG9jaXR5LnkgKj0gLTE7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHdyYXAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHBvc2l0aW9uLnggPiBib3VuZHMud2lkdGgpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggPSBib3VuZHMueDtcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbi54IDwgYm91bmRzLngpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggPSBib3VuZHMud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uLnkgPiBib3VuZHMuaGVpZ2h0KSB7XG4gICAgICAgICAgICBwb3NpdGlvbi55ID0gYm91bmRzLnk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24ueSA8IGJvdW5kcy55KSB7XG4gICAgICAgICAgICBwb3NpdGlvbi55ID0gYm91bmRzLmhlaWdodDtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgc2VlayA9IGZ1bmN0aW9uKHRhcmdldFZlYykge1xuICAgICAgICB2YXIgZGVzaXJlZFZlbG9jaXR5ID0gdGFyZ2V0VmVjLmNsb25lKCkuc3VidHJhY3QocG9zaXRpb24pO1xuICAgICAgICBkZXNpcmVkVmVsb2NpdHkubm9ybWFsaXplKCk7XG4gICAgICAgIGRlc2lyZWRWZWxvY2l0eS5zY2FsZUJ5KG1heFNwZWVkKTtcblxuICAgICAgICB2YXIgZm9yY2UgPSBkZXNpcmVkVmVsb2NpdHkuc3VidHJhY3QodmVsb2NpdHkpO1xuICAgICAgICBzdGVlcmluZ0ZvcmNlLmFkZChmb3JjZSk7XG4gICAgICAgIGZvcmNlLmRpc3Bvc2UoKTtcblxuICAgICAgICByZXR1cm4gYm9pZDtcbiAgICB9O1xuXG4gICAgdmFyIGZsZWUgPSBmdW5jdGlvbih0YXJnZXRWZWMpIHtcbiAgICAgICAgdmFyIGRlc2lyZWRWZWxvY2l0eSA9IHRhcmdldFZlYy5jbG9uZSgpLnN1YnRyYWN0KHBvc2l0aW9uKTtcbiAgICAgICAgZGVzaXJlZFZlbG9jaXR5Lm5vcm1hbGl6ZSgpO1xuICAgICAgICBkZXNpcmVkVmVsb2NpdHkuc2NhbGVCeShtYXhTcGVlZCk7XG5cbiAgICAgICAgdmFyIGZvcmNlID0gZGVzaXJlZFZlbG9jaXR5LnN1YnRyYWN0KHZlbG9jaXR5KTtcbiAgICAgICAgc3RlZXJpbmdGb3JjZS5zdWJ0cmFjdChmb3JjZSk7XG4gICAgICAgIGZvcmNlLmRpc3Bvc2UoKTtcblxuICAgICAgICByZXR1cm4gYm9pZDtcbiAgICB9O1xuXG4gICAgLy8gc2VlayB1bnRpbCB3aXRoaW4gYXJyaXZlVGhyZXNob2xkXG4gICAgdmFyIGFycml2ZSA9IGZ1bmN0aW9uKHRhcmdldFZlYykge1xuICAgICAgICB2YXIgZGVzaXJlZFZlbG9jaXR5ID0gdGFyZ2V0VmVjLmNsb25lKCkuc3VidHJhY3QocG9zaXRpb24pO1xuICAgICAgICBkZXNpcmVkVmVsb2NpdHkubm9ybWFsaXplKCk7XG5cbiAgICAgICAgdmFyIGRpc3RhbmNlU3EgPSBwb3NpdGlvbi5kaXN0YW5jZVNxKHRhcmdldFZlYyk7XG4gICAgICAgIGlmIChkaXN0YW5jZVNxID4gYXJyaXZlVGhyZXNob2xkU3EpIHtcbiAgICAgICAgICAgIGRlc2lyZWRWZWxvY2l0eS5zY2FsZUJ5KG1heFNwZWVkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBzY2FsYXIgPSBtYXhTcGVlZCAqIGRpc3RhbmNlU3EgLyBhcnJpdmVUaHJlc2hvbGRTcTtcbiAgICAgICAgICAgIGRlc2lyZWRWZWxvY2l0eS5zY2FsZUJ5KHNjYWxhcik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZvcmNlID0gZGVzaXJlZFZlbG9jaXR5LnN1YnRyYWN0KHZlbG9jaXR5KTtcbiAgICAgICAgc3RlZXJpbmdGb3JjZS5hZGQoZm9yY2UpO1xuICAgICAgICBmb3JjZS5kaXNwb3NlKCk7XG5cbiAgICAgICAgcmV0dXJuIGJvaWQ7XG4gICAgfTtcblxuICAgIC8vIGxvb2sgYXQgdmVsb2NpdHkgb2YgYm9pZCBhbmQgdHJ5IHRvIHByZWRpY3Qgd2hlcmUgaXQncyBnb2luZ1xuICAgIHZhciBwdXJzdWUgPSBmdW5jdGlvbih0YXJnZXRCb2lkKSB7XG4gICAgICAgIHZhciBsb29rQWhlYWRUaW1lID0gcG9zaXRpb24uZGlzdGFuY2VTcSh0YXJnZXRCb2lkLnBvc2l0aW9uKSAvIG1heFNwZWVkU3E7XG5cbiAgICAgICAgdmFyIHNjYWxlZFZlbG9jaXR5ID0gdGFyZ2V0Qm9pZC52ZWxvY2l0eS5jbG9uZSgpLnNjYWxlQnkobG9va0FoZWFkVGltZSk7XG4gICAgICAgIHZhciBwcmVkaWN0ZWRUYXJnZXQgPSB0YXJnZXRCb2lkLnBvc2l0aW9uLmNsb25lKCkuYWRkKHNjYWxlZFZlbG9jaXR5KTtcblxuICAgICAgICBzZWVrKHByZWRpY3RlZFRhcmdldCk7XG5cbiAgICAgICAgc2NhbGVkVmVsb2NpdHkuZGlzcG9zZSgpO1xuICAgICAgICBwcmVkaWN0ZWRUYXJnZXQuZGlzcG9zZSgpO1xuXG4gICAgICAgIHJldHVybiBib2lkO1xuICAgIH07XG5cbiAgICAvLyBsb29rIGF0IHZlbG9jaXR5IG9mIGJvaWQgYW5kIHRyeSB0byBwcmVkaWN0IHdoZXJlIGl0J3MgZ29pbmdcbiAgICB2YXIgZXZhZGUgPSBmdW5jdGlvbih0YXJnZXRCb2lkKSB7XG4gICAgICAgIHZhciBsb29rQWhlYWRUaW1lID0gcG9zaXRpb24uZGlzdGFuY2VTcSh0YXJnZXRCb2lkLnBvc2l0aW9uKSAvIG1heFNwZWVkU3E7XG5cbiAgICAgICAgdmFyIHNjYWxlZFZlbG9jaXR5ID0gdGFyZ2V0Qm9pZC52ZWxvY2l0eS5jbG9uZSgpLnNjYWxlQnkobG9va0FoZWFkVGltZSk7XG4gICAgICAgIHZhciBwcmVkaWN0ZWRUYXJnZXQgPSB0YXJnZXRCb2lkLnBvc2l0aW9uLmNsb25lKCkuYWRkKHNjYWxlZFZlbG9jaXR5KTtcblxuICAgICAgICBmbGVlKHByZWRpY3RlZFRhcmdldCk7XG5cbiAgICAgICAgc2NhbGVkVmVsb2NpdHkuZGlzcG9zZSgpO1xuICAgICAgICBwcmVkaWN0ZWRUYXJnZXQuZGlzcG9zZSgpO1xuXG4gICAgICAgIHJldHVybiBib2lkO1xuICAgIH07XG5cbiAgICAvLyB3YW5kZXIgYXJvdW5kLCBjaGFuZ2luZyBhbmdsZSBieSBhIGxpbWl0ZWQgYW1vdW50IGVhY2ggdGlja1xuICAgIHZhciB3YW5kZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNlbnRlciA9IHZlbG9jaXR5LmNsb25lKCkubm9ybWFsaXplKCkuc2NhbGVCeSh3YW5kZXJEaXN0YW5jZSk7XG5cbiAgICAgICAgdmFyIG9mZnNldCA9IFZlYzIuZ2V0KCk7XG4gICAgICAgIG9mZnNldC5sZW5ndGggPSB3YW5kZXJSYWRpdXM7XG4gICAgICAgIG9mZnNldC5hbmdsZSA9IHdhbmRlckFuZ2xlO1xuICAgICAgICB3YW5kZXJBbmdsZSArPSBNYXRoLnJhbmRvbSgpICogd2FuZGVyUmFuZ2UgLSB3YW5kZXJSYW5nZSAqIDAuNTtcblxuICAgICAgICB2YXIgZm9yY2UgPSBjZW50ZXIuYWRkKG9mZnNldCk7XG4gICAgICAgIHN0ZWVyaW5nRm9yY2UuYWRkKGZvcmNlKTtcblxuICAgICAgICBvZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICBmb3JjZS5kaXNwb3NlKCk7XG5cbiAgICAgICAgcmV0dXJuIGJvaWQ7XG4gICAgfTtcblxuICAgIC8vIGdldHMgYSBiaXQgcm91Z2ggdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIHNlZWtpbmcgYXMgdGhlIGJvaWQgYXR0ZW1wdHNcbiAgICAvLyB0byBzZWVrIHN0cmFpZ2h0IHRocm91Z2ggYW4gb2JqZWN0IHdoaWxlIHNpbXVsdGFuZW91c2x5IHRyeWluZyB0byBhdm9pZCBpdFxuICAgIHZhciBhdm9pZCA9IGZ1bmN0aW9uKG9ic3RhY2xlcykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9ic3RhY2xlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIG9ic3RhY2xlID0gb2JzdGFjbGVzW2ldO1xuICAgICAgICAgICAgdmFyIGhlYWRpbmcgPSB2ZWxvY2l0eS5jbG9uZSgpLm5vcm1hbGl6ZSgpO1xuXG4gICAgICAgICAgICAvLyB2ZWMgYmV0d2VlbiBvYnN0YWNsZSBhbmQgYm9pZFxuICAgICAgICAgICAgdmFyIGRpZmZlcmVuY2UgPSBvYnN0YWNsZS5wb3NpdGlvbi5jbG9uZSgpLnN1YnRyYWN0KHBvc2l0aW9uKTtcbiAgICAgICAgICAgIHZhciBkb3RQcm9kID0gZGlmZmVyZW5jZS5kb3RQcm9kdWN0KGhlYWRpbmcpO1xuXG4gICAgICAgICAgICAvLyBpZiBvYnN0YWNsZSBpbiBmcm9udCBvZiBib2lkXG4gICAgICAgICAgICBpZiAoZG90UHJvZCA+IDApIHtcbiAgICAgICAgICAgICAgICAvLyB2ZWMgdG8gcmVwcmVzZW50ICdmZWVsZXInIGFybVxuICAgICAgICAgICAgICAgIHZhciBmZWVsZXIgPSBoZWFkaW5nLmNsb25lKCkuc2NhbGVCeShhdm9pZERpc3RhbmNlKTtcbiAgICAgICAgICAgICAgICAvLyBwcm9qZWN0IGRpZmZlcmVuY2Ugb250byBmZWVsZXJcbiAgICAgICAgICAgICAgICB2YXIgcHJvamVjdGlvbiA9IGhlYWRpbmcuY2xvbmUoKS5zY2FsZUJ5KGRvdFByb2QpO1xuICAgICAgICAgICAgICAgIC8vIGRpc3RhbmNlIGZyb20gb2JzdGFjbGUgdG8gZmVlbGVyXG4gICAgICAgICAgICAgICAgdmFyIHZlY0Rpc3RhbmNlID0gcHJvamVjdGlvbi5zdWJ0cmFjdChkaWZmZXJlbmNlKTtcbiAgICAgICAgICAgICAgICB2YXIgZGlzdGFuY2UgPSB2ZWNEaXN0YW5jZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgLy8gaWYgZmVlbGVyIGludGVyc2VjdHMgb2JzdGFjbGUgKHBsdXMgYnVmZmVyKSwgYW5kIHByb2plY3Rpb25cbiAgICAgICAgICAgICAgICAvLyBsZXNzIHRoYW4gZmVlbGVyIGxlbmd0aCwgd2lsbCBjb2xsaWRlXG4gICAgICAgICAgICAgICAgaWYgKGRpc3RhbmNlIDwgKG9ic3RhY2xlLnJhZGl1cyB8fCAwKSArIGF2b2lkQnVmZmVyICYmIHByb2plY3Rpb24ubGVuZ3RoIDwgZmVlbGVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjYWxjIGEgZm9yY2UgKy8tIDkwIGRlZyBmcm9tIHZlYyB0byBjaXJjXG4gICAgICAgICAgICAgICAgICAgIHZhciBmb3JjZSA9IGhlYWRpbmcuY2xvbmUoKS5zY2FsZUJ5KG1heFNwZWVkKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yY2UuYW5nbGUgKz0gZGlmZmVyZW5jZS5zaWduKHZlbG9jaXR5KSAqIE1hdGguUEkgLyAyO1xuICAgICAgICAgICAgICAgICAgICAvLyBzY2FsZSBmb3JjZSBieSBkaXN0YW5jZSAoZnVydGhlciA9IHNtYWxsZXIgZm9yY2UpXG4gICAgICAgICAgICAgICAgICAgIGZvcmNlLnNjYWxlQnkoMSAtIHByb2plY3Rpb24ubGVuZ3RoIC8gZmVlbGVyLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCB0byBzdGVlcmluZyBmb3JjZVxuICAgICAgICAgICAgICAgICAgICBzdGVlcmluZ0ZvcmNlLmFkZChmb3JjZSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGJyYWtpbmcgZm9yY2UgLSBzbG93cyBib2lkIGRvd24gc28gaXQgaGFzIHRpbWUgdG8gdHVybiAoY2xvc2VyID0gaGFyZGVyKVxuICAgICAgICAgICAgICAgICAgICB2ZWxvY2l0eS5zY2FsZUJ5KHByb2plY3Rpb24ubGVuZ3RoIC8gZmVlbGVyLmxlbmd0aCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yY2UuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmZWVsZXIuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIHByb2plY3Rpb24uZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIHZlY0Rpc3RhbmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhlYWRpbmcuZGlzcG9zZSgpO1xuICAgICAgICAgICAgZGlmZmVyZW5jZS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJvaWQ7XG4gICAgfTtcblxuICAgIC8vIGZvbGxvdyBhIHBhdGggbWFkZSB1cCBvZiBhbiBhcnJheSBvciB2ZWN0b3JzXG4gICAgdmFyIGZvbGxvd1BhdGggPSBmdW5jdGlvbihwYXRoLCBsb29wKSB7XG4gICAgICAgIGxvb3AgPSAhIWxvb3A7XG5cbiAgICAgICAgdmFyIHdheVBvaW50ID0gcGF0aFtwYXRoSW5kZXhdO1xuICAgICAgICBpZiAoIXdheVBvaW50KSB7XG4gICAgICAgICAgICBwYXRoSW5kZXggPSAwO1xuICAgICAgICAgICAgcmV0dXJuIGJvaWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uLmRpc3RhbmNlU3Eod2F5UG9pbnQpIDwgcGF0aFRocmVzaG9sZFNxKSB7XG4gICAgICAgICAgICBpZiAocGF0aEluZGV4ID49IHBhdGgubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhdGhJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXRoSW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocGF0aEluZGV4ID49IHBhdGgubGVuZ3RoIC0gMSAmJiAhbG9vcCkge1xuICAgICAgICAgICAgYXJyaXZlKHdheVBvaW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlZWsod2F5UG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib2lkO1xuICAgIH07XG5cbiAgICAvLyBmbG9jayAtIGdyb3VwIG9mIGJvaWRzIGxvb3NlbHkgbW92ZSB0b2dldGhlclxuICAgIHZhciBmbG9jayA9IGZ1bmN0aW9uKGJvaWRzKSB7XG4gICAgICAgIHZhciBhdmVyYWdlVmVsb2NpdHkgPSB2ZWxvY2l0eS5jbG9uZSgpO1xuICAgICAgICB2YXIgYXZlcmFnZVBvc2l0aW9uID0gVmVjMi5nZXQoKTtcbiAgICAgICAgdmFyIGluU2lnaHRDb3VudCA9IDA7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYm9pZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBiID0gYm9pZHNbaV07XG4gICAgICAgICAgICBpZiAoYiAhPT0gYm9pZCAmJiBpblNpZ2h0KGIpKSB7XG4gICAgICAgICAgICAgICAgYXZlcmFnZVZlbG9jaXR5LmFkZChiLnZlbG9jaXR5KTtcbiAgICAgICAgICAgICAgICBhdmVyYWdlUG9zaXRpb24uYWRkKGIucG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIGlmICh0b29DbG9zZShiKSkge1xuICAgICAgICAgICAgICAgICAgICBmbGVlKGIucG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpblNpZ2h0Q291bnQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5TaWdodENvdW50ID4gMCkge1xuICAgICAgICAgICAgYXZlcmFnZVZlbG9jaXR5LmRpdmlkZUJ5KGluU2lnaHRDb3VudCk7XG4gICAgICAgICAgICBhdmVyYWdlUG9zaXRpb24uZGl2aWRlQnkoaW5TaWdodENvdW50KTtcbiAgICAgICAgICAgIHNlZWsoYXZlcmFnZVBvc2l0aW9uKTtcbiAgICAgICAgICAgIHN0ZWVyaW5nRm9yY2UuYWRkKGF2ZXJhZ2VWZWxvY2l0eS5zdWJ0cmFjdCh2ZWxvY2l0eSkpO1xuICAgICAgICB9XG4gICAgICAgIGF2ZXJhZ2VWZWxvY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIGF2ZXJhZ2VQb3NpdGlvbi5kaXNwb3NlKCk7XG5cbiAgICAgICAgcmV0dXJuIGJvaWQ7XG4gICAgfTtcblxuICAgIC8vIGlzIGJvaWQgY2xvc2UgZW5vdWdoIHRvIGJlIGluIHNpZ2h0IGFuZCBmYWNpbmdcbiAgICB2YXIgaW5TaWdodCA9IGZ1bmN0aW9uKGJvaWQpIHtcbiAgICAgICAgaWYgKHBvc2l0aW9uLmRpc3RhbmNlU3EoYm9pZC5wb3NpdGlvbikgPiBtYXhEaXN0YW5jZVNxKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGhlYWRpbmcgPSB2ZWxvY2l0eS5jbG9uZSgpLm5vcm1hbGl6ZSgpO1xuICAgICAgICB2YXIgZGlmZmVyZW5jZSA9IGJvaWQucG9zaXRpb24uY2xvbmUoKS5zdWJ0cmFjdChwb3NpdGlvbik7XG4gICAgICAgIHZhciBkb3RQcm9kID0gZGlmZmVyZW5jZS5kb3RQcm9kdWN0KGhlYWRpbmcpO1xuXG4gICAgICAgIGhlYWRpbmcuZGlzcG9zZSgpO1xuICAgICAgICBkaWZmZXJlbmNlLmRpc3Bvc2UoKTtcblxuICAgICAgICBpZiAoZG90UHJvZCA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgLy8gaXMgYm9pZCB0b28gY2xvc2U/XG4gICAgdmFyIHRvb0Nsb3NlID0gZnVuY3Rpb24oYm9pZCkge1xuICAgICAgICByZXR1cm4gcG9zaXRpb24uZGlzdGFuY2VTcShib2lkLnBvc2l0aW9uKSA8IG1pbkRpc3RhbmNlU3E7XG4gICAgfTtcblxuICAgIC8vIG1ldGhvZHNcbiAgICB2YXIgYm9pZCA9IHtcbiAgICAgICAgc2V0Qm91bmRzOiBzZXRCb3VuZHMsXG4gICAgICAgIHVwZGF0ZTogdXBkYXRlLFxuICAgICAgICBwdXJzdWU6IHB1cnN1ZSxcbiAgICAgICAgZXZhZGU6IGV2YWRlLFxuICAgICAgICB3YW5kZXI6IHdhbmRlcixcbiAgICAgICAgYXZvaWQ6IGF2b2lkLFxuICAgICAgICBmb2xsb3dQYXRoOiBmb2xsb3dQYXRoLFxuICAgICAgICBmbG9jazogZmxvY2ssXG4gICAgICAgIGFycml2ZTogYXJyaXZlLFxuICAgICAgICBmbGVlOiBmbGVlLFxuICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgIHZlbG9jaXR5OiB2ZWxvY2l0eSxcbiAgICAgICAgdXNlckRhdGE6IHt9XG4gICAgfTtcblxuICAgIC8vIGdldHRlcnMgLyBzZXR0ZXJzXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoYm9pZCwge1xuICAgICAgICBlZGdlQmVoYXZpb3I6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVkZ2VCZWhhdmlvcjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZWRnZUJlaGF2aW9yID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG1hc3M6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hc3M7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG1hc3MgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgbWF4U3BlZWQ6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1heFNwZWVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBtYXhTcGVlZCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG1heFNwZWVkU3EgPSB2YWx1ZSAqIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBtYXhGb3JjZToge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF4Rm9yY2U7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG1heEZvcmNlID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIGFycml2ZVxuICAgICAgICBhcnJpdmVUaHJlc2hvbGQ6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycml2ZVRocmVzaG9sZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXJyaXZlVGhyZXNob2xkID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgYXJyaXZlVGhyZXNob2xkU3EgPSB2YWx1ZSAqIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAvLyB3YW5kZXJcbiAgICAgICAgd2FuZGVyRGlzdGFuY2U6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdhbmRlckRpc3RhbmNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICB3YW5kZXJEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB3YW5kZXJSYWRpdXM6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdhbmRlclJhZGl1cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgd2FuZGVyUmFkaXVzID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHdhbmRlclJhbmdlOiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB3YW5kZXJSYW5nZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgd2FuZGVyUmFuZ2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLy8gYXZvaWRcbiAgICAgICAgYXZvaWREaXN0YW5jZToge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXZvaWREaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXZvaWREaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBhdm9pZEJ1ZmZlcjoge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXZvaWRCdWZmZXI7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGF2b2lkQnVmZmVyID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIGZvbGxvd1BhdGhcbiAgICAgICAgcGF0aEluZGV4OiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoSW5kZXg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhdGhJbmRleCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBwYXRoVGhyZXNob2xkOiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoVGhyZXNob2xkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYXRoVGhyZXNob2xkID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGF0aFRocmVzaG9sZFNxID0gdmFsdWUgKiB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLy8gIGZsb2NrXG4gICAgICAgIG1heERpc3RhbmNlOiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXhEaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBtYXhEaXN0YW5jZVNxID0gdmFsdWUgKiB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgbWluRGlzdGFuY2U6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pbkRpc3RhbmNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBtaW5EaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG1pbkRpc3RhbmNlU3EgPSB2YWx1ZSAqIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gT2JqZWN0LmZyZWV6ZShib2lkKTtcbn1cblxuLy8gZWRnZSBiZWhhdmlvcnNcbkJvaWQuRURHRV9OT05FID0gJ25vbmUnO1xuQm9pZC5FREdFX0JPVU5DRSA9ICdib3VuY2UnO1xuQm9pZC5FREdFX1dSQVAgPSAnd3JhcCc7XG5cbi8vIHZlYzJcbkJvaWQuVmVjMiA9IFZlYzI7XG5cbkJvaWQudmVjMiA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICByZXR1cm4gVmVjMi5nZXQoeCwgeSk7XG59O1xuXG4vLyBmb3IgZGVmaW5pbmcgb2JzdGFjbGVzIG9yIGFyZWFzIHRvIGF2b2lkXG5Cb2lkLm9ic3RhY2xlID0gZnVuY3Rpb24ocmFkaXVzLCB4LCB5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmFkaXVzOiByYWRpdXMsXG4gICAgICAgIHBvc2l0aW9uOiBWZWMyLmdldCh4LCB5KVxuICAgIH07XG59O1xuXG5mdW5jdGlvbiBzZXREZWZhdWx0cyhvcHRzLCBkZWZzKSB7XG4gICAgT2JqZWN0LmtleXMoZGVmcykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRzW2tleV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBvcHRzW2tleV0gPSBkZWZzW2tleV07XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gY29uZmlndXJlKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBvcHRpb25zLmJvdW5kcyA9IG9wdGlvbnMuYm91bmRzIHx8IHt9O1xuICAgIHNldERlZmF1bHRzKG9wdGlvbnMsIGRlZmF1bHRzKTtcbiAgICBzZXREZWZhdWx0cyhvcHRpb25zLmJvdW5kcywgZGVmYXVsdHMuYm91bmRzKTtcbiAgICByZXR1cm4gb3B0aW9ucztcbn1cblxuaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBCb2lkO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBWZWMyKHgsIHkpIHtcbiAgICB0aGlzLnggPSB4IHx8IDA7XG4gICAgdGhpcy55ID0geSB8fCAwO1xufVxuXG5WZWMyLnByb3RvdHlwZSA9IHtcbiAgICBhZGQ6IGZ1bmN0aW9uKHZlYykge1xuICAgICAgICB0aGlzLnggPSB0aGlzLnggKyB2ZWMueDtcbiAgICAgICAgdGhpcy55ID0gdGhpcy55ICsgdmVjLnk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgc3VidHJhY3Q6IGZ1bmN0aW9uKHZlYykge1xuICAgICAgICB0aGlzLnggPSB0aGlzLnggLSB2ZWMueDtcbiAgICAgICAgdGhpcy55ID0gdGhpcy55IC0gdmVjLnk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgbm9ybWFsaXplOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGwgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgaWYgKGwgPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMueCA9IDE7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBpZiAobCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54IC89IGw7XG4gICAgICAgIHRoaXMueSAvPSBsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGlzTm9ybWFsaXplZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA9PT0gMTtcbiAgICB9LFxuICAgIHRydW5jYXRlOiBmdW5jdGlvbihtYXgpIHtcbiAgICAgICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSB7XG4gICAgICAgICAgICB0aGlzLmxlbmd0aCA9IG1heDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIHNjYWxlQnk6IGZ1bmN0aW9uKG11bCkge1xuICAgICAgICB0aGlzLnggKj0gbXVsO1xuICAgICAgICB0aGlzLnkgKj0gbXVsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGRpdmlkZUJ5OiBmdW5jdGlvbihkaXYpIHtcbiAgICAgICAgdGhpcy54IC89IGRpdjtcbiAgICAgICAgdGhpcy55IC89IGRpdjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBlcXVhbHM6IGZ1bmN0aW9uKHZlYykge1xuICAgICAgICByZXR1cm4gdGhpcy54ID09PSB2ZWMueCAmJiB0aGlzLnkgPT09IHZlYy55O1xuICAgIH0sXG4gICAgbmVnYXRlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy54ID0gLXRoaXMueDtcbiAgICAgICAgdGhpcy55ID0gLXRoaXMueTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBkb3RQcm9kdWN0OiBmdW5jdGlvbih2ZWMpIHtcbiAgICAgICAgLypcbiAgICAgICAgSWYgQSBhbmQgQiBhcmUgcGVycGVuZGljdWxhciAoYXQgOTAgZGVncmVlcyB0byBlYWNoIG90aGVyKSwgdGhlIHJlc3VsdFxuICAgICAgICBvZiB0aGUgZG90IHByb2R1Y3Qgd2lsbCBiZSB6ZXJvLCBiZWNhdXNlIGNvcyjOmCkgd2lsbCBiZSB6ZXJvLlxuICAgICAgICBJZiB0aGUgYW5nbGUgYmV0d2VlbiBBIGFuZCBCIGFyZSBsZXNzIHRoYW4gOTAgZGVncmVlcywgdGhlIGRvdCBwcm9kdWN0XG4gICAgICAgIHdpbGwgYmUgcG9zaXRpdmUgKGdyZWF0ZXIgdGhhbiB6ZXJvKSwgYXMgY29zKM6YKSB3aWxsIGJlIHBvc2l0aXZlLCBhbmRcbiAgICAgICAgdGhlIHZlY3RvciBsZW5ndGhzIGFyZSBhbHdheXMgcG9zaXRpdmUgdmFsdWVzLlxuICAgICAgICBJZiB0aGUgYW5nbGUgYmV0d2VlbiBBIGFuZCBCIGFyZSBncmVhdGVyIHRoYW4gOTAgZGVncmVlcywgdGhlIGRvdFxuICAgICAgICBwcm9kdWN0IHdpbGwgYmUgbmVnYXRpdmUgKGxlc3MgdGhhbiB6ZXJvKSwgYXMgY29zKM6YKSB3aWxsIGJlIG5lZ2F0aXZlLFxuICAgICAgICBhbmQgdGhlIHZlY3RvciBsZW5ndGhzIGFyZSBhbHdheXMgcG9zaXRpdmUgdmFsdWVzXG4gICAgICAgICovXG4gICAgICAgIHJldHVybiB0aGlzLnggKiB2ZWMueCArIHRoaXMueSAqIHZlYy55O1xuICAgIH0sXG4gICAgY3Jvc3NQcm9kdWN0OiBmdW5jdGlvbih2ZWMpIHtcbiAgICAgICAgLypcbiAgICAgICAgVGhlIHNpZ24gdGVsbHMgdXMgaWYgdmVjIHRvIHRoZSBsZWZ0ICgtKSBvciB0aGUgcmlnaHQgKCspIG9mIHRoaXMgdmVjXG4gICAgICAgICovXG4gICAgICAgIHJldHVybiB0aGlzLnggKiB2ZWMueSAtIHRoaXMueSAqIHZlYy54O1xuICAgIH0sXG4gICAgZGlzdGFuY2VTcTogZnVuY3Rpb24odmVjKSB7XG4gICAgICAgIHZhciBkeCA9IHZlYy54IC0gdGhpcy54O1xuICAgICAgICB2YXIgZHkgPSB2ZWMueSAtIHRoaXMueTtcbiAgICAgICAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xuICAgIH0sXG4gICAgZGlzdGFuY2U6IGZ1bmN0aW9uKHZlYykge1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KHRoaXMuZGlzdGFuY2VTcSh2ZWMpKTtcbiAgICB9LFxuICAgIGNsb25lOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIFZlYzIuZ2V0KHRoaXMueCwgdGhpcy55KTtcbiAgICB9LFxuICAgIHJlc2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy54ID0gMDtcbiAgICAgICAgdGhpcy55ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBwZXJwZW5kaWN1bGFyOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIFZlYzIuZ2V0KC10aGlzLnksIHRoaXMueCk7XG4gICAgfSxcbiAgICBzaWduOiBmdW5jdGlvbih2ZWMpIHtcbiAgICAgICAgLy8gRGV0ZXJtaW5lcyBpZiBhIGdpdmVuIHZlY3RvciBpcyB0byB0aGUgcmlnaHQgb3IgbGVmdCBvZiB0aGlzIHZlY3Rvci5cbiAgICAgICAgLy8gSWYgdG8gdGhlIGxlZnQsIHJldHVybnMgLTEuIElmIHRvIHRoZSByaWdodCwgKzEuXG4gICAgICAgIHZhciBwID0gdGhpcy5wZXJwZW5kaWN1bGFyKCk7XG4gICAgICAgIHZhciBzID0gcC5kb3RQcm9kdWN0KHZlYykgPCAwID8gLTEgOiAxO1xuICAgICAgICBwLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgICAgdGhpcy54ID0geCB8fCAwO1xuICAgICAgICB0aGlzLnkgPSB5IHx8IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgZGlzcG9zZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIFZlYzIucG9vbC5wdXNoKHRoaXMucmVzZXQoKSk7XG4gICAgfVxufTtcblxuLy8gZ2V0dGVycyAvIHNldHRlcnNcblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoVmVjMi5wcm90b3R5cGUsIHtcbiAgICBsZW5ndGhTcXVhcmVkOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy54ICogdGhpcy54ICsgdGhpcy55ICogdGhpcy55O1xuICAgICAgICB9XG4gICAgfSxcbiAgICBsZW5ndGg6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnNxcnQodGhpcy5sZW5ndGhTcXVhcmVkKTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgdmFyIGEgPSB0aGlzLmFuZ2xlO1xuICAgICAgICAgICAgdGhpcy54ID0gTWF0aC5jb3MoYSkgKiB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMueSA9IE1hdGguc2luKGEpICogdmFsdWU7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFuZ2xlOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5hdGFuMih0aGlzLnksIHRoaXMueCk7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIHZhciBsID0gdGhpcy5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnggPSBNYXRoLmNvcyh2YWx1ZSkgKiBsO1xuICAgICAgICAgICAgdGhpcy55ID0gTWF0aC5zaW4odmFsdWUpICogbDtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuXG4vLyBzdGF0aWNcblxuVmVjMi5wb29sID0gW107XG5WZWMyLmdldCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB2YXIgdiA9IFZlYzIucG9vbC5sZW5ndGggPiAwID8gVmVjMi5wb29sLnBvcCgpIDogbmV3IFZlYzIoKTtcbiAgICB2LnNldCh4LCB5KTtcbiAgICByZXR1cm4gdjtcbn07XG5cblZlYzIuZmlsbCA9IGZ1bmN0aW9uKG4pIHtcbiAgICB3aGlsZSAoVmVjMi5wb29sLmxlbmd0aCA8IG4pIHtcbiAgICAgICAgVmVjMi5wb29sLnB1c2gobmV3IFZlYzIoKSk7XG4gICAgfVxufTtcblxuVmVjMi5hbmdsZUJldHdlZW4gPSBmdW5jdGlvbihhLCBiKSB7XG4gICAgaWYgKCFhLmlzTm9ybWFsaXplZCgpKSB7XG4gICAgICAgIGEgPSBhLmNsb25lKCkubm9ybWFsaXplKCk7XG4gICAgfVxuICAgIGlmICghYi5pc05vcm1hbGl6ZWQoKSkge1xuICAgICAgICBiID0gYi5jbG9uZSgpLm5vcm1hbGl6ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5hY29zKGEuZG90UHJvZHVjdChiKSk7XG59O1xuXG5pZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IFZlYzI7XG59XG4iXX0= diff --git a/dist/boid.min.js b/dist/boid.min.js index 6d9bdd8..146c4ce 100644 --- a/dist/boid.min.js +++ b/dist/boid.min.js @@ -1 +1 @@ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Boid=t()}}(function(){return function t(e,n,i){function r(s,u){if(!n[s]){if(!e[s]){var c="function"==typeof require&&require;if(!u&&c)return c(s,!0);if(o)return o(s,!0);var a=new Error("Cannot find module '"+s+"'");throw a.code="MODULE_NOT_FOUND",a}var h=n[s]={exports:{}};e[s][0].call(h.exports,function(t){var n=e[s][1][t];return r(n?n:t)},h,h.exports,t,e,n,i)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;so.width?(t.x=o.width,e.x*=-1):t.xo.height?(t.y=o.height,e.y*=-1):t.yo.width?t.x=o.x:t.xo.height?t.y=o.y:t.yf)r.scaleBy(c);else{var s=c*o/f;r.scaleBy(s)}var u=r.subtract(e);return n.add(u),u.dispose(),I},_=function(e){var n=t.distanceSq(e.position)/a,i=e.velocity.clone().scaleBy(n),r=e.position.clone().add(i);return N(r),i.dispose(),r.dispose(),I},G=function(e){var n=t.distanceSq(e.position)/a,i=e.velocity.clone().scaleBy(n),r=e.position.clone().add(i);return O(r),i.dispose(),r.dispose(),I},U=function(){var t=e.clone().normalize().scaleBy(l),i=r.get();i.length=p,i.angle=y,y+=Math.random()*g-.5*g;var o=t.add(i);return n.add(o),i.dispose(),o.dispose(),I},C=function(i){for(var r=0;r0){var h=s.clone().scaleBy(x),d=s.clone().scaleBy(a),f=d.subtract(u),l=f.length;if(l<(o.radius||0)+v&&d.length=e.length-1?n&&(B=0):B++),B>=e.length-1&&!n?j(i):N(i),I):(B=0,I)},T=function(t){for(var i=e.clone(),o=r.get(),s=0,u=0;u0&&(i.divideBy(s),o.divideBy(s),N(o),n.add(i.subtract(e))),i.dispose(),o.dispose(),I},A=function(n){if(t.distanceSq(n.position)>E)return!1;var i=e.clone().normalize(),r=n.position.clone().subtract(t),o=r.dotProduct(i);return i.dispose(),r.dispose(),0>o?!1:!0},F=function(e){return t.distanceSq(e.position)t&&(this.length=t),this},scaleBy:function(t){return this.x*=t,this.y*=t,this},divideBy:function(t){return this.x/=t,this.y/=t,this},equals:function(t){return this.x===t.x&&this.y===t.y},negate:function(){return this.x=-this.x,this.y=-this.y,this},dotProduct:function(t){return this.x*t.x+this.y*t.y},crossProduct:function(t){return this.x*t.y-this.y*t.x},distanceSq:function(t){var e=t.x-this.x,n=t.y-this.y;return e*e+n*n},distance:function(t){return Math.sqrt(this.distanceSq(t))},clone:function(){return i.get(this.x,this.y)},reset:function(){return this.x=0,this.y=0,this},perpendicular:function(){return i.get(-this.y,this.x)},sign:function(t){var e=this.perpendicular(),n=e.dotProduct(t)<0?-1:1;return e.dispose(),n},set:function(t,e){return this.x=t||0,this.y=e||0,this},dispose:function(){i.pool.push(this.reset())}},Object.defineProperties(i.prototype,{lengthSquared:{get:function(){return this.x*this.x+this.y*this.y}},length:{get:function(){return Math.sqrt(this.lengthSquared)},set:function(t){var e=this.angle;this.x=Math.cos(e)*t,this.y=Math.sin(e)*t}},angle:{get:function(){return Math.atan2(this.y,this.x)},set:function(t){var e=this.length;this.x=Math.cos(t)*e,this.y=Math.sin(t)*e}}}),i.pool=[],i.get=function(t,e){var n=i.pool.length>0?i.pool.pop():new i;return n.set(t,e),n},i.fill=function(t){for(;i.pool.lengthu.width?(e.x=u.width,n.x*=-1):e.xu.height?(e.y=u.height,n.y*=-1):e.yu.width?e.x=u.x:e.xu.height?e.y=u.y:e.yp)i.scaleBy(d);else{var s=d*o/p;i.scaleBy(s)}var u=i.subtract(n);return r.add(u),u.dispose(),W},_=function(t){var n=e.distanceSq(t.position)/h,i=t.velocity.clone().scaleBy(n),r=t.position.clone().add(i);return N(r),i.dispose(),r.dispose(),W},G=function(t){var n=e.distanceSq(t.position)/h,i=t.velocity.clone().scaleBy(n),r=t.position.clone().add(i);return R(r),i.dispose(),r.dispose(),W},A=function(){var t=n.clone().normalize().scaleBy(y),e=s.get();e.length=g,e.angle=x,x+=Math.random()*v-.5*v;var i=t.add(e);return r.add(i),e.dispose(),i.dispose(),W},F=function(t){for(var i=0;i0){var c=s.clone().scaleBy(m),h=s.clone().scaleBy(a),f=h.subtract(u),l=f.length;if(l<(o.radius||0)+b&&h.length=t.length-1?n&&(w=0):w++),w>=t.length-1&&!n?T(i):N(i),W):(w=0,W)},C=function(t){for(var e=n.clone(),i=s.get(),o=0,u=0;u0&&(e.divideBy(o),i.divideBy(o),N(i),r.add(e.subtract(n))),e.dispose(),i.dispose(),W},k=function(t){if(e.distanceSq(t.position)>E)return!1;var i=n.clone().normalize(),r=t.position.clone().subtract(e),o=r.dotProduct(i);return i.dispose(),r.dispose(),0>o?!1:!0},I=function(t){return e.distanceSq(t.position)t&&(this.length=t),this},scaleBy:function(t){return this.x*=t,this.y*=t,this},divideBy:function(t){return this.x/=t,this.y/=t,this},equals:function(t){return this.x===t.x&&this.y===t.y},negate:function(){return this.x=-this.x,this.y=-this.y,this},dotProduct:function(t){return this.x*t.x+this.y*t.y},crossProduct:function(t){return this.x*t.y-this.y*t.x},distanceSq:function(t){var e=t.x-this.x,n=t.y-this.y;return e*e+n*n},distance:function(t){return Math.sqrt(this.distanceSq(t))},clone:function(){return i.get(this.x,this.y)},reset:function(){return this.x=0,this.y=0,this},perpendicular:function(){return i.get(-this.y,this.x)},sign:function(t){var e=this.perpendicular(),n=e.dotProduct(t)<0?-1:1;return e.dispose(),n},set:function(t,e){return this.x=t||0,this.y=e||0,this},dispose:function(){i.pool.push(this.reset())}},Object.defineProperties(i.prototype,{lengthSquared:{get:function(){return this.x*this.x+this.y*this.y}},length:{get:function(){return Math.sqrt(this.lengthSquared)},set:function(t){var e=this.angle;this.x=Math.cos(e)*t,this.y=Math.sin(e)*t}},angle:{get:function(){return Math.atan2(this.y,this.x)},set:function(t){var e=this.length;this.x=Math.cos(t)*e,this.y=Math.sin(t)*e}}}),i.pool=[],i.get=function(t,e){var n=i.pool.length>0?i.pool.pop():new i;return n.set(t,e),n},i.fill=function(t){for(;i.pool.length