From 81823ca3f6781ff429cbb825d7e365a180019a7a Mon Sep 17 00:00:00 2001 From: Anjaliavv51 <154777864+Anjaliavv51@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:53:30 +0530 Subject: [PATCH] Skiing Game #1086 --- .../apple-touch-icon-114x114-precomposed.png | Bin 0 -> 5642 bytes .../apple-touch-icon-57x57-precomposed.png | Bin 0 -> 2961 bytes .../apple-touch-icon-72x72-precomposed.png | Bin 0 -> 3784 bytes .../Skii Game/apple-touch-icon.png | Bin 0 -> 2961 bytes SinglePlayer - Games/Skii Game/css/main.css | 298 + .../Skii Game/css/normalize.css | 504 ++ .../Skii Game/css/skifree.css | 69 + .../Skii Game/dist/skifree.js | 6082 +++++++++++++++++ .../Skii Game/dist/skifree.min.js | 2 + SinglePlayer - Games/Skii Game/index.html | 52 + .../lib/canvasRenderingContext2DExtensions.js | 97 + .../Skii Game/js/lib/commonjs-require.js | 13 + .../Skii Game/js/lib/extenders.js | 14 + SinglePlayer - Games/Skii Game/js/lib/game.js | 161 + SinglePlayer - Games/Skii Game/js/lib/guid.js | 25 + .../Skii Game/js/lib/infoBox.js | 50 + .../Skii Game/js/lib/input.js | 11 + .../Skii Game/js/lib/isMobileDevice.js | 17 + .../Skii Game/js/lib/monster.js | 65 + .../Skii Game/js/lib/plugins.js | 22 + .../Skii Game/js/lib/skiLift.js | 24 + .../Skii Game/js/lib/skier.js | 503 ++ .../Skii Game/js/lib/snowboarder.js | 57 + .../Skii Game/js/lib/sprite.js | 399 ++ .../Skii Game/js/lib/spriteArray.js | 39 + SinglePlayer - Games/Skii Game/js/main.js | 282 + .../Skii Game/js/spriteInfo.js | 178 + .../Skii Game/js/vendor/jquery-1.8.3.min.js | 2 + .../js/vendor/modernizr-2.6.2.min.js | 4 + .../Skii Game/js/vendor/sugar-1.3.7.min.js | 120 + SinglePlayer - Games/Skii Game/manifest.json | 10 + .../Skii Game/skifree-blogpost-banner.png | Bin 0 -> 3048 bytes .../Skii Game/skifree-github-banner.png | Bin 0 -> 3114 bytes .../Skii Game/skifree-objects.png | Bin 0 -> 10203 bytes .../Skii Game/sprite-characters.png | Bin 0 -> 24664 bytes .../Skii Game/sprite-characters.psd | Bin 0 -> 269487 bytes .../Skii Game/test/skier.test.js | 357 + .../Skii Game/test/sprite.test.js | 370 + SinglePlayer - Games/Skii Game/yeti-big.png | Bin 0 -> 59015 bytes 39 files changed, 9827 insertions(+) create mode 100644 SinglePlayer - Games/Skii Game/apple-touch-icon-114x114-precomposed.png create mode 100644 SinglePlayer - Games/Skii Game/apple-touch-icon-57x57-precomposed.png create mode 100644 SinglePlayer - Games/Skii Game/apple-touch-icon-72x72-precomposed.png create mode 100644 SinglePlayer - Games/Skii Game/apple-touch-icon.png create mode 100644 SinglePlayer - Games/Skii Game/css/main.css create mode 100644 SinglePlayer - Games/Skii Game/css/normalize.css create mode 100644 SinglePlayer - Games/Skii Game/css/skifree.css create mode 100644 SinglePlayer - Games/Skii Game/dist/skifree.js create mode 100644 SinglePlayer - Games/Skii Game/dist/skifree.min.js create mode 100644 SinglePlayer - Games/Skii Game/index.html create mode 100644 SinglePlayer - Games/Skii Game/js/lib/canvasRenderingContext2DExtensions.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/commonjs-require.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/extenders.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/game.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/guid.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/infoBox.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/input.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/isMobileDevice.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/monster.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/plugins.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/skiLift.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/skier.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/snowboarder.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/sprite.js create mode 100644 SinglePlayer - Games/Skii Game/js/lib/spriteArray.js create mode 100644 SinglePlayer - Games/Skii Game/js/main.js create mode 100644 SinglePlayer - Games/Skii Game/js/spriteInfo.js create mode 100644 SinglePlayer - Games/Skii Game/js/vendor/jquery-1.8.3.min.js create mode 100644 SinglePlayer - Games/Skii Game/js/vendor/modernizr-2.6.2.min.js create mode 100644 SinglePlayer - Games/Skii Game/js/vendor/sugar-1.3.7.min.js create mode 100644 SinglePlayer - Games/Skii Game/manifest.json create mode 100644 SinglePlayer - Games/Skii Game/skifree-blogpost-banner.png create mode 100644 SinglePlayer - Games/Skii Game/skifree-github-banner.png create mode 100644 SinglePlayer - Games/Skii Game/skifree-objects.png create mode 100644 SinglePlayer - Games/Skii Game/sprite-characters.png create mode 100644 SinglePlayer - Games/Skii Game/sprite-characters.psd create mode 100644 SinglePlayer - Games/Skii Game/test/skier.test.js create mode 100644 SinglePlayer - Games/Skii Game/test/sprite.test.js create mode 100644 SinglePlayer - Games/Skii Game/yeti-big.png diff --git a/SinglePlayer - Games/Skii Game/apple-touch-icon-114x114-precomposed.png b/SinglePlayer - Games/Skii Game/apple-touch-icon-114x114-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..27cf2a488176981ea8bda20e3cd67ce517675699 GIT binary patch literal 5642 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 k8&22INpr(07*qoM6N<$f>?dTCjbBd literal 0 HcmV?d00001 diff --git a/SinglePlayer - Games/Skii Game/apple-touch-icon-57x57-precomposed.png b/SinglePlayer - Games/Skii Game/apple-touch-icon-57x57-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..2bcad51a6cfeabfb2e9addcf8279cd166dac9d5c GIT binary patch literal 2961 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 2) { + spriteVersion = 0.1; + } else { + spriteVersion += 0.1; + } + if (xDiff >= 0) { + return 'sEast' + Math.ceil(spriteVersion); + } else if (xDiff < 0) { + return 'sWest' + Math.ceil(spriteVersion); + } + }; + + return super_draw(dContext, spritePartToUse()); + }; + + function startEating (whenDone) { + eatingStage += 1; + that.isEating = true; + that.isMoving = false; + if (eatingStage < 6) { + setTimeout(function () { + startEating(whenDone); + }, 300); + } else { + eatingStage = 0; + that.isEating = false; + that.isMoving = true; + whenDone(); + } + } + + that.startEating = startEating; + + return that; + } + + global.monster = Monster; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.monster; +} +},{"./sprite":11}],8:[function(require,module,exports){ +// Avoid `console` errors in browsers that lack a console. +(function() { + var method; + var noop = function noop() {}; + var methods = [ + 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', + 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', + 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', + 'timeStamp', 'trace', 'warn' + ]; + var length = methods.length; + var console = (window.console = window.console || {}); + + while (length--) { + method = methods[length]; + + // Only stub undefined methods. + if (!console[method]) { + console[method] = noop; + } + } +}()); +},{}],9:[function(require,module,exports){ +var Sprite = require('./sprite'); +if (typeof navigator !== 'undefined') { + navigator.vibrate = navigator.vibrate || + navigator.webkitVibrate || + navigator.mozVibrate || + navigator.msVibrate; +} else { + navigator = { + vibrate: false + }; +} + +(function(global) { + function Skier(data) { + var discreteDirections = { + 'west': 270, + 'wsWest': 240, + 'sWest': 195, + 'south': 180, + 'sEast': 165, + 'esEast': 120, + 'east': 90 + }; + var that = new Sprite(data); + var sup = { + draw: that.superior('draw'), + cycle: that.superior('cycle'), + getSpeedX: that.superior('getSpeedX'), + getSpeedY: that.superior('getSpeedY'), + hits: that.superior('hits') + }; + var directions = { + esEast: function(xDiff) { return xDiff > 300; }, + sEast: function(xDiff) { return xDiff > 75; }, + wsWest: function(xDiff) { return xDiff < -300; }, + sWest: function(xDiff) { return xDiff < -75; } + }; + + var cancelableStateTimeout; + var cancelableStateInterval; + + var canSpeedBoost = true; + + var obstaclesHit = []; + var pixelsTravelled = 0; + var standardSpeed = 5; + var boostMultiplier = 2; + var turnEaseCycles = 70; + var speedX = 0; + var speedXFactor = 0; + var speedY = 0; + var speedYFactor = 1; + var trickStep = 0; // There are three of these + + that.isMoving = true; + that.hasBeenHit = false; + that.isJumping = false; + that.isPerformingTrick = false; + that.onHitObstacleCb = function() {}; + that.setSpeed(standardSpeed); + + that.reset = function () { + obstaclesHit = []; + pixelsTravelled = 0; + that.isMoving = true; + that.hasBeenHit = false; + canSpeedBoost = true; + setNormal(); + }; + + function setNormal() { + that.setSpeed(standardSpeed); + that.isMoving = true; + that.hasBeenHit = false; + that.isJumping = false; + that.isPerformingTrick = false; + if (cancelableStateInterval) { + clearInterval(cancelableStateInterval); + } + that.setMapPosition(undefined, undefined, 0); + } + + function setCrashed() { + that.isMoving = false; + that.hasBeenHit = true; + that.isJumping = false; + that.isPerformingTrick = false; + if (cancelableStateInterval) { + clearInterval(cancelableStateInterval); + } + that.setMapPosition(undefined, undefined, 0); + } + + function setJumping() { + var currentSpeed = that.getSpeed(); + that.setSpeed(currentSpeed + 2); + that.setSpeedY(currentSpeed + 2); + that.isMoving = true; + that.hasBeenHit = false; + that.isJumping = true; + that.setMapPosition(undefined, undefined, 1); + } + + function getDiscreteDirection() { + if (that.direction) { + if (that.direction <= 90) { + return 'east'; + } else if (that.direction > 90 && that.direction < 150) { + return 'esEast'; + } else if (that.direction >= 150 && that.direction < 180) { + return 'sEast'; + } else if (that.direction === 180) { + return 'south'; + } else if (that.direction > 180 && that.direction <= 210) { + return 'sWest'; + } else if (that.direction > 210 && that.direction < 270) { + return 'wsWest'; + } else if (that.direction >= 270) { + return 'west'; + } else { + return 'south'; + } + } else { + var xDiff = that.movingToward[0] - that.mapPosition[0]; + var yDiff = that.movingToward[1] - that.mapPosition[1]; + if (yDiff <= 0) { + if (xDiff > 0) { + return 'east'; + } else { + return 'west'; + } + } + + if (directions.esEast(xDiff)) { + return 'esEast'; + } else if (directions.sEast(xDiff)) { + return 'sEast'; + } else if (directions.wsWest(xDiff)) { + return 'wsWest'; + } else if (directions.sWest(xDiff)) { + return 'sWest'; + } + } + return 'south'; + } + + function setDiscreteDirection(d) { + if (discreteDirections[d]) { + that.setDirection(discreteDirections[d]); + } + + if (d === 'west' || d === 'east') { + that.isMoving = false; + } else { + that.isMoving = true; + } + } + + function getBeingEatenSprite() { + return 'blank'; + } + + function getJumpingSprite() { + return 'jumping'; + } + + function getTrickSprite() { + console.log('Trick step is', trickStep); + if (trickStep === 0) { + return 'jumping'; + } else if (trickStep === 1) { + return 'somersault1'; + } else { + return 'somersault2'; + } + } + + that.stop = function () { + if (that.direction > 180) { + setDiscreteDirection('west'); + } else { + setDiscreteDirection('east'); + } + }; + + that.turnEast = function () { + var discreteDirection = getDiscreteDirection(); + + switch (discreteDirection) { + case 'west': + setDiscreteDirection('wsWest'); + break; + case 'wsWest': + setDiscreteDirection('sWest'); + break; + case 'sWest': + setDiscreteDirection('south'); + break; + case 'south': + setDiscreteDirection('sEast'); + break; + case 'sEast': + setDiscreteDirection('esEast'); + break; + case 'esEast': + setDiscreteDirection('east'); + break; + default: + setDiscreteDirection('south'); + break; + } + }; + + that.turnWest = function () { + var discreteDirection = getDiscreteDirection(); + + switch (discreteDirection) { + case 'east': + setDiscreteDirection('esEast'); + break; + case 'esEast': + setDiscreteDirection('sEast'); + break; + case 'sEast': + setDiscreteDirection('south'); + break; + case 'south': + setDiscreteDirection('sWest'); + break; + case 'sWest': + setDiscreteDirection('wsWest'); + break; + case 'wsWest': + setDiscreteDirection('west'); + break; + default: + setDiscreteDirection('south'); + break; + } + }; + + that.stepWest = function () { + that.mapPosition[0] -= that.speed * 2; + }; + + that.stepEast = function () { + that.mapPosition[0] += that.speed * 2; + }; + + that.setMapPositionTarget = function (x, y) { + if (that.hasBeenHit) return; + + if (Math.abs(that.mapPosition[0] - x) <= 75) { + x = that.mapPosition[0]; + } + + that.movingToward = [ x, y ]; + + // that.resetDirection(); + }; + + that.startMovingIfPossible = function () { + if (!that.hasBeenHit && !that.isBeingEaten) { + that.isMoving = true; + } + }; + + that.setTurnEaseCycles = function (c) { + turnEaseCycles = c; + }; + + that.getPixelsTravelledDownMountain = function () { + return pixelsTravelled; + }; + + that.resetSpeed = function () { + that.setSpeed(standardSpeed); + }; + + that.cycle = function () { + if ( that.getSpeedX() <= 0 && that.getSpeedY() <= 0 ) { + that.isMoving = false; + } + if (that.isMoving) { + pixelsTravelled += that.speed; + } + + if (that.isJumping) { + that.setMapPositionTarget(undefined, that.mapPosition[1] + that.getSpeed()); + } + + sup.cycle(); + + that.checkHittableObjects(); + }; + + that.draw = function(dContext) { + var spritePartToUse = function () { + if (that.isBeingEaten) { + return getBeingEatenSprite(); + } + + if (that.isJumping) { + if (that.isPerformingTrick) { + return getTrickSprite(); + } + return getJumpingSprite(); + } + + if (that.hasBeenHit) { + return 'hit'; + } + + return getDiscreteDirection(); + }; + + return sup.draw(dContext, spritePartToUse()); + }; + + that.hits = function (obs) { + if (obstaclesHit.indexOf(obs.id) !== -1) { + return false; + } + + if (!obs.occupiesZIndex(that.mapPosition[2])) { + return false; + } + + if (sup.hits(obs)) { + return true; + } + + return false; + }; + + that.speedBoost = function () { + var originalSpeed = that.speed; + if (canSpeedBoost) { + canSpeedBoost = false; + that.setSpeed(that.speed * boostMultiplier); + setTimeout(function () { + that.setSpeed(originalSpeed); + setTimeout(function () { + canSpeedBoost = true; + }, 10000); + }, 2000); + } + }; + + that.attemptTrick = function () { + if (that.isJumping) { + that.isPerformingTrick = true; + cancelableStateInterval = setInterval(function () { + if (trickStep >= 2) { + trickStep = 0; + } else { + trickStep += 1; + } + }, 300); + } + }; + + that.getStandardSpeed = function () { + return standardSpeed; + }; + + function easeSpeedToTargetUsingFactor(sp, targetSpeed, f) { + if (f === 0 || f === 1) { + return targetSpeed; + } + + if (sp < targetSpeed) { + sp += that.getSpeed() * (f / turnEaseCycles); + } + + if (sp > targetSpeed) { + sp -= that.getSpeed() * (f / turnEaseCycles); + } + + return sp; + } + + that.getSpeedX = function () { + if (getDiscreteDirection() === 'esEast' || getDiscreteDirection() === 'wsWest') { + speedXFactor = 0.5; + speedX = easeSpeedToTargetUsingFactor(speedX, that.getSpeed() * speedXFactor, speedXFactor); + + return speedX; + } + + if (getDiscreteDirection() === 'sEast' || getDiscreteDirection() === 'sWest') { + speedXFactor = 0.33; + speedX = easeSpeedToTargetUsingFactor(speedX, that.getSpeed() * speedXFactor, speedXFactor); + + return speedX; + } + + // So it must be south + + speedX = easeSpeedToTargetUsingFactor(speedX, 0, speedXFactor); + + return speedX; + }; + + that.setSpeedY = function(sy) { + speedY = sy; + }; + + that.getSpeedY = function () { + var targetSpeed; + + if (that.isJumping) { + return speedY; + } + + if (getDiscreteDirection() === 'esEast' || getDiscreteDirection() === 'wsWest') { + speedYFactor = 0.6; + speedY = easeSpeedToTargetUsingFactor(speedY, that.getSpeed() * 0.6, 0.6); + + return speedY; + } + + if (getDiscreteDirection() === 'sEast' || getDiscreteDirection() === 'sWest') { + speedYFactor = 0.85; + speedY = easeSpeedToTargetUsingFactor(speedY, that.getSpeed() * 0.85, 0.85); + + return speedY; + } + + if (getDiscreteDirection() === 'east' || getDiscreteDirection() === 'west') { + speedYFactor = 1; + speedY = 0; + + return speedY; + } + + // So it must be south + + speedY = easeSpeedToTargetUsingFactor(speedY, that.getSpeed(), speedYFactor); + + return speedY; + }; + + that.hasHitObstacle = function (obs) { + setCrashed(); + + if (navigator.vibrate) { + navigator.vibrate(500); + } + + obstaclesHit.push(obs.id); + + that.resetSpeed(); + that.onHitObstacleCb(obs); + + if (cancelableStateTimeout) { + clearTimeout(cancelableStateTimeout); + } + cancelableStateTimeout = setTimeout(function() { + setNormal(); + }, 1500); + }; + + that.hasHitJump = function () { + setJumping(); + + if (cancelableStateTimeout) { + clearTimeout(cancelableStateTimeout); + } + cancelableStateTimeout = setTimeout(function() { + setNormal(); + }, 1000); + }; + + that.isEatenBy = function (monster, whenEaten) { + that.hasHitObstacle(monster); + monster.startEating(whenEaten); + obstaclesHit.push(monster.id); + that.isMoving = false; + that.isBeingEaten = true; + }; + + that.reset = function () { + obstaclesHit = []; + pixelsTravelled = 0; + that.isMoving = true; + that.isJumping = false; + that.hasBeenHit = false; + canSpeedBoost = true; + }; + + that.setHitObstacleCb = function (fn) { + that.onHitObstacleCb = fn || function() {}; + }; + return that; + } + + global.skier = Skier; +})(this); + +if (typeof module !== 'undefined') { + module.exports = this.skier; +} + +},{"./sprite":11}],10:[function(require,module,exports){ +var Sprite = require('./sprite'); + +(function(global) { + function Snowboarder(data) { + var that = new Sprite(data); + var sup = { + draw: that.superior('draw'), + cycle: that.superior('cycle') + }; + var directions = { + sEast: function(xDiff) { return xDiff > 0; }, + sWest: function(xDiff) { return xDiff <= 0; } + }; + var standardSpeed = 3; + + that.setSpeed(standardSpeed); + + function getDirection() { + var xDiff = that.movingToward[0] - that.mapPosition[0]; + var yDiff = that.movingToward[1] - that.mapPosition[1]; + + if (directions.sEast(xDiff)) { + return 'sEast'; + } else { + return 'sWest'; + } + } + + that.cycle = function (dContext) { + if (Number.random(10) === 1) { + that.setMapPositionTarget(dContext.getRandomlyInTheCentreOfMap()); + that.setSpeed(standardSpeed + Number.random(-1, 1)); + } + + that.setMapPositionTarget(undefined, dContext.getMapBelowViewport() + 600); + + sup.cycle(); + }; + + that.draw = function(dContext) { + var spritePartToUse = function () { + return getDirection(); + }; + + return sup.draw(dContext, spritePartToUse()); + }; + + return that; + } + + global.snowboarder = Snowboarder; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.snowboarder; +} +},{"./sprite":11}],11:[function(require,module,exports){ +(function (global) { + var GUID = require('./guid'); + function Sprite (data) { + var hittableObjects = {}; + var zIndexesOccupied = [ 0 ]; + var that = this; + var trackedSpriteToMoveToward; + that.direction = undefined; + that.mapPosition = [0, 0, 0]; + that.id = GUID(); + that.canvasX = 0; + that.canvasY = 0; + that.canvasZ = 0; + that.height = 0; + that.speed = 0; + that.data = data || { parts : {} }; + that.movingToward = [ 0, 0 ]; + that.metresDownTheMountain = 0; + that.movingWithConviction = false; + that.deleted = false; + that.maxHeight = (function () { + return Object.values(that.data.parts).map(function (p) { return p[3]; }).max(); + }()); + that.isMoving = true; + + if (!that.data.parts) { + that.data.parts = {}; + } + + if (data && data.id){ + that.id = data.id; + } + + if (data && data.zIndexesOccupied) { + zIndexesOccupied = data.zIndexesOccupied; + } + + function incrementX(amount) { + that.canvasX += amount.toNumber(); + } + + function incrementY(amount) { + that.canvasY += amount.toNumber(); + } + + function getHitBox(forZIndex) { + if (that.data.hitBoxes) { + if (data.hitBoxes[forZIndex]) { + return data.hitBoxes[forZIndex]; + } + } + } + + function roundHalf(num) { + num = Math.round(num*2)/2; + return num; + } + + function move() { + if (!that.isMoving) { + return; + } + + var currentX = that.mapPosition[0]; + var currentY = that.mapPosition[1]; + + if (typeof that.direction !== 'undefined') { + // For this we need to modify the that.direction so it relates to the horizontal + var d = that.direction - 90; + if (d < 0) d = 360 + d; + currentX += roundHalf(that.speed * Math.cos(d * (Math.PI / 180))); + currentY += roundHalf(that.speed * Math.sin(d * (Math.PI / 180))); + } else { + if (typeof that.movingToward[0] !== 'undefined') { + if (currentX > that.movingToward[0]) { + currentX -= Math.min(that.getSpeedX(), Math.abs(currentX - that.movingToward[0])); + } else if (currentX < that.movingToward[0]) { + currentX += Math.min(that.getSpeedX(), Math.abs(currentX - that.movingToward[0])); + } + } + + if (typeof that.movingToward[1] !== 'undefined') { + if (currentY > that.movingToward[1]) { + currentY -= Math.min(that.getSpeedY(), Math.abs(currentY - that.movingToward[1])); + } else if (currentY < that.movingToward[1]) { + currentY += Math.min(that.getSpeedY(), Math.abs(currentY - that.movingToward[1])); + } + } + } + + that.setMapPosition(currentX, currentY); + } + + this.draw = function (dCtx, spriteFrame) { + var fr = that.data.parts[spriteFrame]; + that.height = fr[3]; + that.width = fr[2]; + + var newCanvasPosition = dCtx.mapPositionToCanvasPosition(that.mapPosition); + that.setCanvasPosition(newCanvasPosition[0], newCanvasPosition[1]); + + dCtx.drawImage(dCtx.getLoadedImage(that.data.$imageFile), fr[0], fr[1], fr[2], fr[3], that.canvasX, that.canvasY, fr[2], fr[3]); + }; + + this.setMapPosition = function (x, y, z) { + if (typeof x === 'undefined') { + x = that.mapPosition[0]; + } + if (typeof y === 'undefined') { + y = that.mapPosition[1]; + } + if (typeof z === 'undefined') { + z = that.mapPosition[2]; + } else { + that.zIndexesOccupied = [ z ]; + } + that.mapPosition = [x, y, z]; + }; + + this.setCanvasPosition = function (cx, cy) { + if (cx) { + if (Object.isString(cx) && (cx.first() === '+' || cx.first() === '-')) incrementX(cx); + else that.canvasX = cx; + } + + if (cy) { + if (Object.isString(cy) && (cy.first() === '+' || cy.first() === '-')) incrementY(cy); + else that.canvasY = cy; + } + }; + + this.getCanvasPositionX = function () { + return that.canvasX; + }; + + this.getCanvasPositionY = function () { + return that.canvasY; + }; + + this.getLeftHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + var lhbe = this.getCanvasPositionX(); + if (getHitBox(zIndex)) { + lhbe += getHitBox(zIndex)[0]; + } + return lhbe; + }; + + this.getTopHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + var thbe = this.getCanvasPositionY(); + if (getHitBox(zIndex)) { + thbe += getHitBox(zIndex)[1]; + } + return thbe; + }; + + this.getRightHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + + if (getHitBox(zIndex)) { + return that.canvasX + getHitBox(zIndex)[2]; + } + + return that.canvasX + that.width; + }; + + this.getBottomHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + + if (getHitBox(zIndex)) { + return that.canvasY + getHitBox(zIndex)[3]; + } + + return that.canvasY + that.height; + }; + + this.getPositionInFrontOf = function () { + return [that.canvasX, that.canvasY + that.height]; + }; + + this.setSpeed = function (s) { + that.speed = s; + that.speedX = s; + that.speedY = s; + }; + + this.incrementSpeedBy = function (s) { + that.speed += s; + }; + + that.getSpeed = function getSpeed () { + return that.speed; + }; + + that.getSpeedX = function () { + return that.speed; + }; + + that.getSpeedY = function () { + return that.speed; + }; + + this.setHeight = function (h) { + that.height = h; + }; + + this.setWidth = function (w) { + that.width = w; + }; + + this.getMaxHeight = function () { + return that.maxHeight; + }; + + that.getMovingTowardOpposite = function () { + if (!that.isMoving) { + return [0, 0]; + } + + var dx = (that.movingToward[0] - that.mapPosition[0]); + var dy = (that.movingToward[1] - that.mapPosition[1]); + + var oppositeX = (Math.abs(dx) > 75 ? 0 - dx : 0); + var oppositeY = -dy; + + return [ oppositeX, oppositeY ]; + }; + + this.checkHittableObjects = function () { + Object.keys(hittableObjects, function (k, objectData) { + if (objectData.object.deleted) { + delete hittableObjects[k]; + } else { + if (objectData.object.hits(that)) { + objectData.callbacks.each(function (callback) { + callback(that, objectData.object); + }); + } + } + }); + }; + + this.cycle = function () { + that.checkHittableObjects(); + + if (trackedSpriteToMoveToward) { + that.setMapPositionTarget(trackedSpriteToMoveToward.mapPosition[0], trackedSpriteToMoveToward.mapPosition[1], true); + } + + move(); + }; + + this.setMapPositionTarget = function (x, y, override) { + if (override) { + that.movingWithConviction = false; + } + + if (!that.movingWithConviction) { + if (typeof x === 'undefined') { + x = that.movingToward[0]; + } + + if (typeof y === 'undefined') { + y = that.movingToward[1]; + } + + that.movingToward = [ x, y ]; + + that.movingWithConviction = false; + } + + // that.resetDirection(); + }; + + this.setDirection = function (angle) { + if (angle >= 360) { + angle = 360 - angle; + } + that.direction = angle; + that.movingToward = undefined; + }; + + this.resetDirection = function () { + that.direction = undefined; + }; + + this.setMapPositionTargetWithConviction = function (cx, cy) { + that.setMapPositionTarget(cx, cy); + that.movingWithConviction = true; + // that.resetDirection(); + }; + + this.follow = function (sprite) { + trackedSpriteToMoveToward = sprite; + // that.resetDirection(); + }; + + this.stopFollowing = function () { + trackedSpriteToMoveToward = false; + }; + + this.onHitting = function (objectToHit, callback) { + if (hittableObjects[objectToHit.id]) { + return hittableObjects[objectToHit.id].callbacks.push(callback); + } + + hittableObjects[objectToHit.id] = { + object: objectToHit, + callbacks: [ callback ] + }; + }; + + this.deleteOnNextCycle = function () { + that.deleted = true; + }; + + this.occupiesZIndex = function (z) { + return zIndexesOccupied.indexOf(z) >= 0; + }; + + this.hits = function (other) { + var verticalIntersect = false; + var horizontalIntersect = false; + + // Test that THIS has a bottom edge inside of the other object + if (other.getTopHitBoxEdge(that.mapPosition[2]) <= that.getBottomHitBoxEdge(that.mapPosition[2]) && other.getBottomHitBoxEdge(that.mapPosition[2]) >= that.getBottomHitBoxEdge(that.mapPosition[2])) { + verticalIntersect = true; + } + + // Test that THIS has a top edge inside of the other object + if (other.getTopHitBoxEdge(that.mapPosition[2]) <= that.getTopHitBoxEdge(that.mapPosition[2]) && other.getBottomHitBoxEdge(that.mapPosition[2]) >= that.getTopHitBoxEdge(that.mapPosition[2])) { + verticalIntersect = true; + } + + // Test that THIS has a right edge inside of the other object + if (other.getLeftHitBoxEdge(that.mapPosition[2]) <= that.getRightHitBoxEdge(that.mapPosition[2]) && other.getRightHitBoxEdge(that.mapPosition[2]) >= that.getRightHitBoxEdge(that.mapPosition[2])) { + horizontalIntersect = true; + } + + // Test that THIS has a left edge inside of the other object + if (other.getLeftHitBoxEdge(that.mapPosition[2]) <= that.getLeftHitBoxEdge(that.mapPosition[2]) && other.getRightHitBoxEdge(that.mapPosition[2]) >= that.getLeftHitBoxEdge(that.mapPosition[2])) { + horizontalIntersect = true; + } + + return verticalIntersect && horizontalIntersect; + }; + + this.isAboveOnCanvas = function (cy) { + return (that.canvasY + that.height) < cy; + }; + + this.isBelowOnCanvas = function (cy) { + return (that.canvasY) > cy; + }; + + return that; + } + + Sprite.createObjects = function createObjects(spriteInfoArray, opts) { + if (!Array.isArray(spriteInfoArray)) spriteInfoArray = [ spriteInfoArray ]; + opts = Object.merge(opts, { + rateModifier: 0, + dropRate: 1, + position: [0, 0] + }, false, false); + + function createOne (spriteInfo) { + var position = opts.position; + if (Number.random(100 + opts.rateModifier) <= spriteInfo.dropRate) { + var sprite = new Sprite(spriteInfo.sprite); + sprite.setSpeed(0); + + if (Object.isFunction(position)) { + position = position(); + } + + sprite.setMapPosition(position[0], position[1]); + + if (spriteInfo.sprite.hitBehaviour && spriteInfo.sprite.hitBehaviour.skier && opts.player) { + sprite.onHitting(opts.player, spriteInfo.sprite.hitBehaviour.skier); + } + + return sprite; + } + } + + var objects = spriteInfoArray.map(createOne).remove(undefined); + + return objects; + }; + + global.sprite = Sprite; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.sprite; +} +},{"./guid":4}],12:[function(require,module,exports){ +(function (global) { + function SpriteArray() { + this.pushHandlers = []; + + return this; + } + + SpriteArray.prototype = Object.create(Array.prototype); + + SpriteArray.prototype.onPush = function(f, retroactive) { + this.pushHandlers.push(f); + + if (retroactive) { + this.each(f); + } + }; + + SpriteArray.prototype.push = function(obj) { + Array.prototype.push.call(this, obj); + this.pushHandlers.each(function(handler) { + handler(obj); + }); + }; + + SpriteArray.prototype.cull = function() { + this.each(function (obj, i) { + if (obj.deleted) { + return (delete this[i]); + } + }); + }; + + global.spriteArray = SpriteArray; +})(this); + + +if (typeof module !== 'undefined') { + module.exports = this.spriteArray; +} +},{}],13:[function(require,module,exports){ +// Global dependencies which return no modules +require('./lib/canvasRenderingContext2DExtensions'); +require('./lib/extenders'); +require('./lib/plugins'); + +// External dependencies +var Hammer = require('hammerjs'); +var Mousetrap = require('br-mousetrap'); + +// Method modules +var isMobileDevice = require('./lib/isMobileDevice'); + +// Game Objects +var SpriteArray = require('./lib/spriteArray'); +var Monster = require('./lib/monster'); +var Sprite = require('./lib/sprite'); +var Snowboarder = require('./lib/snowboarder'); +var Skier = require('./lib/skier'); +var InfoBox = require('./lib/infoBox'); +var Game = require('./lib/game'); + +// Local variables for starting the game +var mainCanvas = document.getElementById('skifree-canvas'); +var dContext = mainCanvas.getContext('2d'); +var imageSources = [ 'sprite-characters.png', 'skifree-objects.png' ]; +var global = this; +var infoBoxControls = 'Use the mouse or WASD to control the player'; +if (isMobileDevice()) infoBoxControls = 'Tap or drag on the piste to control the player'; +var sprites = require('./spriteInfo'); + +var pixelsPerMetre = 18; +var distanceTravelledInMetres = 0; +var monsterDistanceThreshold = 2000; +var livesLeft = 5; +var highScore = 0; +var loseLifeOnObstacleHit = false; +var dropRates = {smallTree: 4, tallTree: 2, jump: 1, thickSnow: 1, rock: 1}; +if (localStorage.getItem('highScore')) highScore = localStorage.getItem('highScore'); + +function loadImages (sources, next) { + var loaded = 0; + var images = {}; + + function finish () { + loaded += 1; + if (loaded === sources.length) { + next(images); + } + } + + sources.each(function (src) { + var im = new Image(); + im.onload = finish; + im.src = src; + dContext.storeLoadedImage(src, im); + }); +} + +function monsterHitsSkierBehaviour(monster, skier) { + skier.isEatenBy(monster, function () { + livesLeft -= 1; + monster.isFull = true; + monster.isEating = false; + skier.isBeingEaten = false; + monster.setSpeed(skier.getSpeed()); + monster.stopFollowing(); + var randomPositionAbove = dContext.getRandomMapPositionAboveViewport(); + monster.setMapPositionTarget(randomPositionAbove[0], randomPositionAbove[1]); + }); +} + +function startNeverEndingGame (images) { + var player; + var startSign; + var infoBox; + var game; + + function resetGame () { + distanceTravelledInMetres = 0; + livesLeft = 5; + highScore = localStorage.getItem('highScore'); + game.reset(); + game.addStaticObject(startSign); + } + + function detectEnd () { + if (!game.isPaused()) { + highScore = localStorage.setItem('highScore', distanceTravelledInMetres); + infoBox.setLines([ + 'Game over!', + 'Hit space to restart' + ]); + game.pause(); + game.cycle(); + } + } + + function randomlySpawnNPC(spawnFunction, dropRate) { + var rateModifier = Math.max(800 - mainCanvas.width, 0); + if (Number.random(1000 + rateModifier) <= dropRate) { + spawnFunction(); + } + } + + function spawnMonster () { + var newMonster = new Monster(sprites.monster); + var randomPosition = dContext.getRandomMapPositionAboveViewport(); + newMonster.setMapPosition(randomPosition[0], randomPosition[1]); + newMonster.follow(player); + newMonster.setSpeed(player.getStandardSpeed()); + newMonster.onHitting(player, monsterHitsSkierBehaviour); + + game.addMovingObject(newMonster, 'monster'); + } + + function spawnBoarder () { + var newBoarder = new Snowboarder(sprites.snowboarder); + var randomPositionAbove = dContext.getRandomMapPositionAboveViewport(); + var randomPositionBelow = dContext.getRandomMapPositionBelowViewport(); + newBoarder.setMapPosition(randomPositionAbove[0], randomPositionAbove[1]); + newBoarder.setMapPositionTarget(randomPositionBelow[0], randomPositionBelow[1]); + newBoarder.onHitting(player, sprites.snowboarder.hitBehaviour.skier); + + game.addMovingObject(newBoarder); + } + + player = new Skier(sprites.skier); + player.setMapPosition(0, 0); + player.setMapPositionTarget(0, -10); + if ( loseLifeOnObstacleHit ) { + player.setHitObstacleCb(function() { + livesLeft -= 1; + }); + } + + game = new Game(mainCanvas, player); + + startSign = new Sprite(sprites.signStart); + game.addStaticObject(startSign); + startSign.setMapPosition(-50, 0); + dContext.followSprite(player); + + infoBox = new InfoBox({ + initialLines : [ + 'SkiFree.js', + infoBoxControls, + 'Travelled 0m', + 'High Score: ' + highScore, + 'Skiers left: ' + livesLeft, + 'Created by Dan Hough (@basicallydan)' + ], + position: { + top: 15, + right: 10 + } + }); + + game.beforeCycle(function () { + var newObjects = []; + if (player.isMoving) { + newObjects = Sprite.createObjects([ + { sprite: sprites.smallTree, dropRate: dropRates.smallTree }, + { sprite: sprites.tallTree, dropRate: dropRates.tallTree }, + { sprite: sprites.jump, dropRate: dropRates.jump }, + { sprite: sprites.thickSnow, dropRate: dropRates.thickSnow }, + { sprite: sprites.rock, dropRate: dropRates.rock }, + ], { + rateModifier: Math.max(800 - mainCanvas.width, 0), + position: function () { + return dContext.getRandomMapPositionBelowViewport(); + }, + player: player + }); + } + if (!game.isPaused()) { + game.addStaticObjects(newObjects); + + randomlySpawnNPC(spawnBoarder, 0.1); + distanceTravelledInMetres = parseFloat(player.getPixelsTravelledDownMountain() / pixelsPerMetre).toFixed(1); + + if (distanceTravelledInMetres > monsterDistanceThreshold) { + randomlySpawnNPC(spawnMonster, 0.001); + } + + infoBox.setLines([ + 'SkiFree.js', + infoBoxControls, + 'Travelled ' + distanceTravelledInMetres + 'm', + 'Skiers left: ' + livesLeft, + 'High Score: ' + highScore, + 'Created by Dan Hough (@basicallydan)', + 'Current Speed: ' + player.getSpeed()/*, + 'Skier Map Position: ' + player.mapPosition[0].toFixed(1) + ', ' + player.mapPosition[1].toFixed(1), + 'Mouse Map Position: ' + mouseMapPosition[0].toFixed(1) + ', ' + mouseMapPosition[1].toFixed(1)*/ + ]); + } + }); + + game.afterCycle(function() { + if (livesLeft === 0) { + detectEnd(); + } + }); + + game.addUIElement(infoBox); + + $(mainCanvas) + .mousemove(function (e) { + game.setMouseX(e.pageX); + game.setMouseY(e.pageY); + player.resetDirection(); + player.startMovingIfPossible(); + }) + .bind('click', function (e) { + game.setMouseX(e.pageX); + game.setMouseY(e.pageY); + player.resetDirection(); + player.startMovingIfPossible(); + }) + .focus(); // So we can listen to events immediately + + Mousetrap.bind('f', player.speedBoost); + Mousetrap.bind('t', player.attemptTrick); + Mousetrap.bind(['w', 'up'], function () { + player.stop(); + }); + Mousetrap.bind(['a', 'left'], function () { + if (player.direction === 270) { + player.stepWest(); + } else { + player.turnWest(); + } + }); + Mousetrap.bind(['s', 'down'], function () { + player.setDirection(180); + player.startMovingIfPossible(); + }); + Mousetrap.bind(['d', 'right'], function () { + if (player.direction === 90) { + player.stepEast(); + } else { + player.turnEast(); + } + }); + Mousetrap.bind('m', spawnMonster); + Mousetrap.bind('b', spawnBoarder); + Mousetrap.bind('space', resetGame); + + var hammertime = Hammer(mainCanvas).on('press', function (e) { + e.preventDefault(); + game.setMouseX(e.center.x); + game.setMouseY(e.center.y); + }).on('tap', function (e) { + game.setMouseX(e.center.x); + game.setMouseY(e.center.y); + }).on('pan', function (e) { + game.setMouseX(e.center.x); + game.setMouseY(e.center.y); + player.resetDirection(); + player.startMovingIfPossible(); + }).on('doubletap', function (e) { + player.speedBoost(); + }); + + player.isMoving = false; + player.setDirection(270); + + game.start(); +} + +function resizeCanvas() { + mainCanvas.width = window.innerWidth; + mainCanvas.height = window.innerHeight; +} + +window.addEventListener('resize', resizeCanvas, false); + +resizeCanvas(); + +loadImages(imageSources, startNeverEndingGame); + +this.exports = window; + +},{"./lib/canvasRenderingContext2DExtensions":1,"./lib/extenders":2,"./lib/game":3,"./lib/infoBox":5,"./lib/isMobileDevice":6,"./lib/monster":7,"./lib/plugins":8,"./lib/skier":9,"./lib/snowboarder":10,"./lib/sprite":11,"./lib/spriteArray":12,"./spriteInfo":14,"br-mousetrap":15,"hammerjs":18}],14:[function(require,module,exports){ +(function (global) { + var sprites = { + 'skier' : { + $imageFile : 'sprite-characters.png', + parts : { + blank : [ 0, 0, 0, 0 ], + east : [ 0, 0, 24, 34 ], + esEast : [ 24, 0, 24, 34 ], + sEast : [ 49, 0, 17, 34 ], + south : [ 65, 0, 17, 34 ], + sWest : [ 49, 37, 17, 34 ], + wsWest : [ 24, 37, 24, 34 ], + west : [ 0, 37, 24, 34 ], + hit : [ 0, 78, 31, 31 ], + jumping : [ 84, 0, 32, 34 ], + somersault1 : [ 116, 0, 32, 34 ], + somersault2 : [ 148, 0, 32, 34 ] + }, + hitBoxes: { + 0: [ 7, 20, 27, 34 ] + }, + id : 'player', + hitBehaviour: {} + }, + 'smallTree' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 0, 28, 30, 34 ] + }, + hitBoxes: { + 0: [ 0, 18, 30, 34 ] + }, + hitBehaviour: {} + }, + 'tallTree' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 95, 66, 32, 64 ] + }, + zIndexesOccupied : [0, 1], + hitBoxes: { + 0: [0, 54, 32, 64], + 1: [0, 10, 32, 54] + }, + hitBehaviour: {} + }, + 'thickSnow' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 143, 53, 43, 10 ] + }, + hitBehaviour: {} + }, + 'rock' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 30, 52, 23, 11 ] + }, + hitBehaviour: {} + }, + 'monster' : { + $imageFile : 'sprite-characters.png', + parts : { + sEast1 : [ 64, 112, 26, 43 ], + sEast2 : [ 90, 112, 32, 43 ], + sWest1 : [ 64, 158, 26, 43 ], + sWest2 : [ 90, 158, 32, 43 ], + eating1 : [ 122, 112, 34, 43 ], + eating2 : [ 156, 112, 31, 43 ], + eating3 : [ 187, 112, 31, 43 ], + eating4 : [ 219, 112, 25, 43 ], + eating5 : [ 243, 112, 26, 43 ] + }, + hitBehaviour: {} + }, + 'jump' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 109, 55, 32, 8 ] + }, + hitBehaviour: {} + }, + 'signStart' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 260, 103, 42, 27 ] + }, + hitBehaviour: {} + }, + 'snowboarder' : { + $imageFile : 'sprite-characters.png', + parts : { + sEast : [ 73, 229, 20, 29 ], + sWest : [ 95, 228, 26, 30 ] + }, + hitBehaviour: {} + }, + 'emptyChairLift': { + $imageFile : 'skifree-objects.png', + parts: { + main : [ 92, 136, 26, 30 ] + }, + zIndexesOccupied : [1], + } + }; + + function monsterHitsTreeBehaviour(monster) { + monster.deleteOnNextCycle(); + } + + sprites.monster.hitBehaviour.tree = monsterHitsTreeBehaviour; + + function treeHitsMonsterBehaviour(tree, monster) { + monster.deleteOnNextCycle(); + } + + sprites.smallTree.hitBehaviour.monster = treeHitsMonsterBehaviour; + sprites.tallTree.hitBehaviour.monster = treeHitsMonsterBehaviour; + + function skierHitsTreeBehaviour(skier, tree) { + skier.hasHitObstacle(tree); + } + + function treeHitsSkierBehaviour(tree, skier) { + skier.hasHitObstacle(tree); + } + + sprites.smallTree.hitBehaviour.skier = treeHitsSkierBehaviour; + sprites.tallTree.hitBehaviour.skier = treeHitsSkierBehaviour; + + function rockHitsSkierBehaviour(rock, skier) { + skier.hasHitObstacle(rock); + } + + sprites.rock.hitBehaviour.skier = rockHitsSkierBehaviour; + + function skierHitsJumpBehaviour(skier, jump) { + skier.hasHitJump(jump); + } + + function jumpHitsSkierBehaviour(jump, skier) { + skier.hasHitJump(jump); + } + + sprites.jump.hitBehaviour.skier = jumpHitsSkierBehaviour; + +// Really not a fan of this behaviour. +/* function skierHitsThickSnowBehaviour(skier, thickSnow) { + // Need to implement this properly + skier.setSpeed(2); + setTimeout(function() { + skier.resetSpeed(); + }, 700); + } + + function thickSnowHitsSkierBehaviour(thickSnow, skier) { + // Need to implement this properly + skier.setSpeed(2); + setTimeout(function() { + skier.resetSpeed(); + }, 300); + }*/ + + // sprites.thickSnow.hitBehaviour.skier = thickSnowHitsSkierBehaviour; + + function snowboarderHitsSkierBehaviour(snowboarder, skier) { + skier.hasHitObstacle(snowboarder); + } + + sprites.snowboarder.hitBehaviour.skier = snowboarderHitsSkierBehaviour; + + global.spriteInfo = sprites; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.spriteInfo; +} +},{}],15:[function(require,module,exports){ +/** + * Copyright 2012 Craig Campbell + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Mousetrap is a simple keyboard shortcut library for Javascript with + * no external dependencies + * + * @version 1.1.3 + * @url craig.is/killing/mice + */ +(function() { + + /** + * mapping of special keycodes to their corresponding keys + * + * everything in this dictionary cannot use keypress events + * so it has to be here to map to the correct keycodes for + * keyup/keydown events + * + * @type {Object} + */ + var _MAP = { + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 16: 'shift', + 17: 'ctrl', + 18: 'alt', + 20: 'capslock', + 27: 'esc', + 32: 'space', + 33: 'pageup', + 34: 'pagedown', + 35: 'end', + 36: 'home', + 37: 'left', + 38: 'up', + 39: 'right', + 40: 'down', + 45: 'ins', + 46: 'del', + 91: 'meta', + 93: 'meta', + 224: 'meta' + }, + + /** + * mapping for special characters so they can support + * + * this dictionary is only used incase you want to bind a + * keyup or keydown event to one of these keys + * + * @type {Object} + */ + _KEYCODE_MAP = { + 106: '*', + 107: '+', + 109: '-', + 110: '.', + 111 : '/', + 186: ';', + 187: '=', + 188: ',', + 189: '-', + 190: '.', + 191: '/', + 192: '`', + 219: '[', + 220: '\\', + 221: ']', + 222: '\'' + }, + + /** + * this is a mapping of keys that require shift on a US keypad + * back to the non shift equivelents + * + * this is so you can use keyup events with these keys + * + * note that this will only work reliably on US keyboards + * + * @type {Object} + */ + _SHIFT_MAP = { + '~': '`', + '!': '1', + '@': '2', + '#': '3', + '$': '4', + '%': '5', + '^': '6', + '&': '7', + '*': '8', + '(': '9', + ')': '0', + '_': '-', + '+': '=', + ':': ';', + '\"': '\'', + '<': ',', + '>': '.', + '?': '/', + '|': '\\' + }, + + /** + * this is a list of special strings you can use to map + * to modifier keys when you specify your keyboard shortcuts + * + * @type {Object} + */ + _SPECIAL_ALIASES = { + 'option': 'alt', + 'command': 'meta', + 'return': 'enter', + 'escape': 'esc' + }, + + /** + * variable to store the flipped version of _MAP from above + * needed to check if we should use keypress or not when no action + * is specified + * + * @type {Object|undefined} + */ + _REVERSE_MAP, + + /** + * a list of all the callbacks setup via Mousetrap.bind() + * + * @type {Object} + */ + _callbacks = {}, + + /** + * direct map of string combinations to callbacks used for trigger() + * + * @type {Object} + */ + _direct_map = {}, + + /** + * keeps track of what level each sequence is at since multiple + * sequences can start out with the same sequence + * + * @type {Object} + */ + _sequence_levels = {}, + + /** + * variable to store the setTimeout call + * + * @type {null|number} + */ + _reset_timer, + + /** + * temporary state where we will ignore the next keyup + * + * @type {boolean|string} + */ + _ignore_next_keyup = false, + + /** + * are we currently inside of a sequence? + * type of action ("keyup" or "keydown" or "keypress") or false + * + * @type {boolean|string} + */ + _inside_sequence = false; + + /** + * loop through the f keys, f1 to f19 and add them to the map + * programatically + */ + for (var i = 1; i < 20; ++i) { + _MAP[111 + i] = 'f' + i; + } + + /** + * loop through to map numbers on the numeric keypad + */ + for (i = 0; i <= 9; ++i) { + _MAP[i + 96] = i; + } + + /** + * cross browser add event method + * + * @param {Element|HTMLDocument} object + * @param {string} type + * @param {Function} callback + * @returns void + */ + function _addEvent(object, type, callback) { + if (object.addEventListener) { + object.addEventListener(type, callback, false); + return; + } + + object.attachEvent('on' + type, callback); + } + + /** + * takes the event and returns the key character + * + * @param {Event} e + * @return {string} + */ + function _characterFromEvent(e) { + + // for keypress events we should return the character as is + if (e.type == 'keypress') { + return String.fromCharCode(e.which); + } + + // for non keypress events the special maps are needed + if (_MAP[e.which]) { + return _MAP[e.which]; + } + + if (_KEYCODE_MAP[e.which]) { + return _KEYCODE_MAP[e.which]; + } + + // if it is not in the special map + return String.fromCharCode(e.which).toLowerCase(); + } + + /** + * checks if two arrays are equal + * + * @param {Array} modifiers1 + * @param {Array} modifiers2 + * @returns {boolean} + */ + function _modifiersMatch(modifiers1, modifiers2) { + return modifiers1.sort().join(',') === modifiers2.sort().join(','); + } + + /** + * resets all sequence counters except for the ones passed in + * + * @param {Object} do_not_reset + * @returns void + */ + function _resetSequences(do_not_reset) { + do_not_reset = do_not_reset || {}; + + var active_sequences = false, + key; + + for (key in _sequence_levels) { + if (do_not_reset[key]) { + active_sequences = true; + continue; + } + _sequence_levels[key] = 0; + } + + if (!active_sequences) { + _inside_sequence = false; + } + } + + /** + * finds all callbacks that match based on the keycode, modifiers, + * and action + * + * @param {string} character + * @param {Array} modifiers + * @param {Event|Object} e + * @param {boolean=} remove - should we remove any matches + * @param {string=} combination + * @returns {Array} + */ + function _getMatches(character, modifiers, e, remove, combination) { + var i, + callback, + matches = [], + action = e.type; + + // if there are no events related to this keycode + if (!_callbacks[character]) { + return []; + } + + // if a modifier key is coming up on its own we should allow it + if (action == 'keyup' && _isModifier(character)) { + modifiers = [character]; + } + + // loop through all callbacks for the key that was pressed + // and see if any of them match + for (i = 0; i < _callbacks[character].length; ++i) { + callback = _callbacks[character][i]; + + // if this is a sequence but it is not at the right level + // then move onto the next match + if (callback.seq && _sequence_levels[callback.seq] != callback.level) { + continue; + } + + // if the action we are looking for doesn't match the action we got + // then we should keep going + if (action != callback.action) { + continue; + } + + // if this is a keypress event and the meta key and control key + // are not pressed that means that we need to only look at the + // character, otherwise check the modifiers as well + // + // chrome will not fire a keypress if meta or control is down + // safari will fire a keypress if meta or meta+shift is down + // firefox will fire a keypress if meta or control is down + if ((action == 'keypress' && !e.metaKey && !e.ctrlKey) || _modifiersMatch(modifiers, callback.modifiers)) { + + // remove is used so if you change your mind and call bind a + // second time with a new function the first one is overwritten + if (remove && callback.combo == combination) { + _callbacks[character].splice(i, 1); + } + + matches.push(callback); + } + } + + return matches; + } + + /** + * takes a key event and figures out what the modifiers are + * + * @param {Event} e + * @returns {Array} + */ + function _eventModifiers(e) { + var modifiers = []; + + if (e.shiftKey) { + modifiers.push('shift'); + } + + if (e.altKey) { + modifiers.push('alt'); + } + + if (e.ctrlKey) { + modifiers.push('ctrl'); + } + + if (e.metaKey) { + modifiers.push('meta'); + } + + return modifiers; + } + + /** + * actually calls the callback function + * + * if your callback function returns false this will use the jquery + * convention - prevent default and stop propogation on the event + * + * @param {Function} callback + * @param {Event} e + * @returns void + */ + function _fireCallback(callback, e) { + if (callback(e) === false) { + if (e.preventDefault) { + e.preventDefault(); + } + + if (e.stopPropagation) { + e.stopPropagation(); + } + + e.returnValue = false; + e.cancelBubble = true; + } + } + + /** + * handles a character key event + * + * @param {string} character + * @param {Event} e + * @returns void + */ + function _handleCharacter(character, e) { + + // if this event should not happen stop here + if (Mousetrap.stopCallback(e, e.target || e.srcElement)) { + return; + } + + var callbacks = _getMatches(character, _eventModifiers(e), e), + i, + do_not_reset = {}, + processed_sequence_callback = false; + + // loop through matching callbacks for this key event + for (i = 0; i < callbacks.length; ++i) { + + // fire for all sequence callbacks + // this is because if for example you have multiple sequences + // bound such as "g i" and "g t" they both need to fire the + // callback for matching g cause otherwise you can only ever + // match the first one + if (callbacks[i].seq) { + processed_sequence_callback = true; + + // keep a list of which sequences were matches for later + do_not_reset[callbacks[i].seq] = 1; + _fireCallback(callbacks[i].callback, e); + continue; + } + + // if there were no sequence matches but we are still here + // that means this is a regular match so we should fire that + if (!processed_sequence_callback && !_inside_sequence) { + _fireCallback(callbacks[i].callback, e); + } + } + + // if you are inside of a sequence and the key you are pressing + // is not a modifier key then we should reset all sequences + // that were not matched by this key event + if (e.type == _inside_sequence && !_isModifier(character)) { + _resetSequences(do_not_reset); + } + } + + /** + * handles a keydown event + * + * @param {Event} e + * @returns void + */ + function _handleKey(e) { + + // normalize e.which for key events + // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion + e.which = typeof e.which == "number" ? e.which : e.keyCode; + + var character = _characterFromEvent(e); + + // no character found then stop + if (!character) { + return; + } + + if (e.type == 'keyup' && _ignore_next_keyup == character) { + _ignore_next_keyup = false; + return; + } + + _handleCharacter(character, e); + } + + /** + * determines if the keycode specified is a modifier key or not + * + * @param {string} key + * @returns {boolean} + */ + function _isModifier(key) { + return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta'; + } + + /** + * called to set a 1 second timeout on the specified sequence + * + * this is so after each key press in the sequence you have 1 second + * to press the next key before you have to start over + * + * @returns void + */ + function _resetSequenceTimer() { + clearTimeout(_reset_timer); + _reset_timer = setTimeout(_resetSequences, 1000); + } + + /** + * reverses the map lookup so that we can look for specific keys + * to see what can and can't use keypress + * + * @return {Object} + */ + function _getReverseMap() { + if (!_REVERSE_MAP) { + _REVERSE_MAP = {}; + for (var key in _MAP) { + + // pull out the numeric keypad from here cause keypress should + // be able to detect the keys from the character + if (key > 95 && key < 112) { + continue; + } + + if (_MAP.hasOwnProperty(key)) { + _REVERSE_MAP[_MAP[key]] = key; + } + } + } + return _REVERSE_MAP; + } + + /** + * picks the best action based on the key combination + * + * @param {string} key - character for key + * @param {Array} modifiers + * @param {string=} action passed in + */ + function _pickBestAction(key, modifiers, action) { + + // if no action was picked in we should try to pick the one + // that we think would work best for this key + if (!action) { + action = _getReverseMap()[key] ? 'keydown' : 'keypress'; + } + + // modifier keys don't work as expected with keypress, + // switch to keydown + if (action == 'keypress' && modifiers.length) { + action = 'keydown'; + } + + return action; + } + + /** + * binds a key sequence to an event + * + * @param {string} combo - combo specified in bind call + * @param {Array} keys + * @param {Function} callback + * @param {string=} action + * @returns void + */ + function _bindSequence(combo, keys, callback, action) { + + // start off by adding a sequence level record for this combination + // and setting the level to 0 + _sequence_levels[combo] = 0; + + // if there is no action pick the best one for the first key + // in the sequence + if (!action) { + action = _pickBestAction(keys[0], []); + } + + /** + * callback to increase the sequence level for this sequence and reset + * all other sequences that were active + * + * @param {Event} e + * @returns void + */ + var _increaseSequence = function(e) { + _inside_sequence = action; + ++_sequence_levels[combo]; + _resetSequenceTimer(); + }, + + /** + * wraps the specified callback inside of another function in order + * to reset all sequence counters as soon as this sequence is done + * + * @param {Event} e + * @returns void + */ + _callbackAndReset = function(e) { + _fireCallback(callback, e); + + // we should ignore the next key up if the action is key down + // or keypress. this is so if you finish a sequence and + // release the key the final key will not trigger a keyup + if (action !== 'keyup') { + _ignore_next_keyup = _characterFromEvent(e); + } + + // weird race condition if a sequence ends with the key + // another sequence begins with + setTimeout(_resetSequences, 10); + }, + i; + + // loop through keys one at a time and bind the appropriate callback + // function. for any key leading up to the final one it should + // increase the sequence. after the final, it should reset all sequences + for (i = 0; i < keys.length; ++i) { + _bindSingle(keys[i], i < keys.length - 1 ? _increaseSequence : _callbackAndReset, action, combo, i); + } + } + + /** + * binds a single keyboard combination + * + * @param {string} combination + * @param {Function} callback + * @param {string=} action + * @param {string=} sequence_name - name of sequence if part of sequence + * @param {number=} level - what part of the sequence the command is + * @returns void + */ + function _bindSingle(combination, callback, action, sequence_name, level) { + + // make sure multiple spaces in a row become a single space + combination = combination.replace(/\s+/g, ' '); + + var sequence = combination.split(' '), + i, + key, + keys, + modifiers = []; + + // if this pattern is a sequence of keys then run through this method + // to reprocess each pattern one key at a time + if (sequence.length > 1) { + _bindSequence(combination, sequence, callback, action); + return; + } + + // take the keys from this pattern and figure out what the actual + // pattern is all about + keys = combination === '+' ? ['+'] : combination.split('+'); + + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + + // normalize key names + if (_SPECIAL_ALIASES[key]) { + key = _SPECIAL_ALIASES[key]; + } + + // if this is not a keypress event then we should + // be smart about using shift keys + // this will only work for US keyboards however + if (action && action != 'keypress' && _SHIFT_MAP[key]) { + key = _SHIFT_MAP[key]; + modifiers.push('shift'); + } + + // if this key is a modifier then add it to the list of modifiers + if (_isModifier(key)) { + modifiers.push(key); + } + } + + // depending on what the key combination is + // we will try to pick the best event for it + action = _pickBestAction(key, modifiers, action); + + // make sure to initialize array if this is the first time + // a callback is added for this key + if (!_callbacks[key]) { + _callbacks[key] = []; + } + + // remove an existing match if there is one + _getMatches(key, modifiers, {type: action}, !sequence_name, combination); + + // add this call back to the array + // if it is a sequence put it at the beginning + // if not put it at the end + // + // this is important because the way these are processed expects + // the sequence ones to come first + _callbacks[key][sequence_name ? 'unshift' : 'push']({ + callback: callback, + modifiers: modifiers, + action: action, + seq: sequence_name, + level: level, + combo: combination + }); + } + + /** + * binds multiple combinations to the same callback + * + * @param {Array} combinations + * @param {Function} callback + * @param {string|undefined} action + * @returns void + */ + function _bindMultiple(combinations, callback, action) { + for (var i = 0; i < combinations.length; ++i) { + _bindSingle(combinations[i], callback, action); + } + } + + // start! + _addEvent(document, 'keypress', _handleKey); + _addEvent(document, 'keydown', _handleKey); + _addEvent(document, 'keyup', _handleKey); + + var Mousetrap = { + + /** + * binds an event to mousetrap + * + * can be a single key, a combination of keys separated with +, + * an array of keys, or a sequence of keys separated by spaces + * + * be sure to list the modifier keys first to make sure that the + * correct key ends up getting bound (the last key in the pattern) + * + * @param {string|Array} keys + * @param {Function} callback + * @param {string=} action - 'keypress', 'keydown', or 'keyup' + * @returns void + */ + bind: function(keys, callback, action) { + _bindMultiple(keys instanceof Array ? keys : [keys], callback, action); + _direct_map[keys + ':' + action] = callback; + return this; + }, + + /** + * unbinds an event to mousetrap + * + * the unbinding sets the callback function of the specified key combo + * to an empty function and deletes the corresponding key in the + * _direct_map dict. + * + * the keycombo+action has to be exactly the same as + * it was defined in the bind method + * + * TODO: actually remove this from the _callbacks dictionary instead + * of binding an empty function + * + * @param {string|Array} keys + * @param {string} action + * @returns void + */ + unbind: function(keys, action) { + if (_direct_map[keys + ':' + action]) { + delete _direct_map[keys + ':' + action]; + this.bind(keys, function() {}, action); + } + return this; + }, + + /** + * triggers an event that has already been bound + * + * @param {string} keys + * @param {string=} action + * @returns void + */ + trigger: function(keys, action) { + _direct_map[keys + ':' + action](); + return this; + }, + + /** + * resets the library back to its initial state. this is useful + * if you want to clear out the current keyboard shortcuts and bind + * new ones - for example if you switch to another page + * + * @returns void + */ + reset: function() { + _callbacks = {}; + _direct_map = {}; + return this; + }, + + /** + * should we stop this event before firing off callbacks + * + * @param {Event} e + * @param {Element} element + * @return {boolean} + */ + stopCallback: function(e, element) { + + // if the element has the class "mousetrap" then no need to stop + if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) { + return false; + } + + // stop for input, select, and textarea + return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || (element.contentEditable && element.contentEditable == 'true'); + } + }; + + // expose mousetrap to the global object + window.Mousetrap = Mousetrap; + + // expose mousetrap as an AMD module + if (typeof define == 'function' && define.amd) { + define('mousetrap', function() { return Mousetrap; }); + } + // browserify support + if(typeof module === 'object' && module.exports) { + module.exports = Mousetrap; + } +}) (); + +},{}],16:[function(require,module,exports){ +(function (global){ +(function() { + var root = this; + var EventEmitter = require('events').EventEmitter; + var _ = require('underscore'); + var intervalParser = /([0-9\.]+)(ms|s|m|h)?/; + var root = global || window; + + // Lil bit of useful polyfill... + if (typeof(Function.prototype.inherits) === 'undefined') { + Function.prototype.inherits = function(parent) { + this.prototype = Object.create(parent.prototype); + }; + } + + if (typeof(Array.prototype.removeOne) === 'undefined') { + Array.prototype.removeOne = function() { + var what, a = arguments, L = a.length, ax; + while (L && this.length) { + what = a[--L]; + while ((ax = this.indexOf(what)) !== -1) { + return this.splice(ax, 1); + } + } + }; + } + + function greatestCommonFactor(intervals) { + var sumOfModuli = 1; + var interval = _.min(intervals); + while (sumOfModuli !== 0) { + sumOfModuli = _.reduce(intervals, function(memo, i){ return memo + (i % interval); }, 0); + if (sumOfModuli !== 0) { + interval -= 10; + } + } + return interval; + } + + function parseEvent(e) { + var intervalGroups = intervalParser.exec(e); + if (!intervalGroups) { + throw new Error('I don\'t understand that particular interval'); + } + var intervalAmount = +intervalGroups[1]; + var intervalType = intervalGroups[2] || 'ms'; + if (intervalType === 's') { + intervalAmount = intervalAmount * 1000; + } else if (intervalType === 'm') { + intervalAmount = intervalAmount * 1000 * 60; + } else if (intervalType === 'h') { + intervalAmount = intervalAmount * 1000 * 60 * 60; + } else if (!!intervalType && intervalType !== 'ms') { + throw new Error('You can only specify intervals of ms, s, m, or h'); + } + if (intervalAmount < 10 || intervalAmount % 10 !== 0) { + // We only deal in 10's of milliseconds for simplicity + throw new Error('You can only specify 10s of milliseconds, trust me on this one'); + } + return { + amount:intervalAmount, + type:intervalType + }; + } + + function EventedLoop() { + this.intervalId = undefined; + this.intervalLength = undefined; + this.intervalsToEmit = {}; + this.currentTick = 1; + this.maxTicks = 0; + this.listeningForFocus = false; + + // Private method + var determineIntervalLength = function () { + var potentialIntervalLength = greatestCommonFactor(_.keys(this.intervalsToEmit)); + var changed = false; + + if (this.intervalLength) { + if (potentialIntervalLength !== this.intervalLength) { + // Looks like we need a new interval + this.intervalLength = potentialIntervalLength; + changed = true; + } + } else { + this.intervalLength = potentialIntervalLength; + } + + this.maxTicks = _.max(_.map(_.keys(this.intervalsToEmit), function(a) { return +a; })) / this.intervalLength; + return changed; + }.bind(this); + + this.on('newListener', function (e) { + if (e === 'removeListener' || e === 'newListener') return; // We don't care about that one + var intervalInfo = parseEvent(e); + var intervalAmount = intervalInfo.amount; + + this.intervalsToEmit[+intervalAmount] = _.union(this.intervalsToEmit[+intervalAmount] || [], [e]); + + if (determineIntervalLength() && this.isStarted()) { + this.stop().start(); + } + }); + + this.on('removeListener', function (e) { + if (EventEmitter.listenerCount(this, e) > 0) return; + var intervalInfo = parseEvent(e); + var intervalAmount = intervalInfo.amount; + + var removedEvent = this.intervalsToEmit[+intervalAmount].removeOne(e); + if (this.intervalsToEmit[+intervalAmount].length === 0) { + delete this.intervalsToEmit[+intervalAmount]; + } + console.log('Determining interval length after removal of', removedEvent); + determineIntervalLength(); + + if (determineIntervalLength() && this.isStarted()) { + this.stop().start(); + } + }); + } + + EventedLoop.inherits(EventEmitter); + + // Public methods + EventedLoop.prototype.tick = function () { + var milliseconds = this.currentTick * this.intervalLength; + _.each(this.intervalsToEmit, function (events, key) { + if (milliseconds % key === 0) { + _.each(events, function(e) { this.emit(e, e, key); }.bind(this)); + } + }.bind(this)); + this.currentTick += 1; + if (this.currentTick > this.maxTicks) { + this.currentTick = 1; + } + return this; + }; + + EventedLoop.prototype.start = function () { + if (!this.intervalLength) { + throw new Error('You haven\'t specified any interval callbacks. Use EventedLoop.on(\'500ms\', function () { ... }) to do so, and then you can start'); + } + if (this.intervalId) { + return console.log('No need to start the loop again, it\'s already started.'); + } + + this.intervalId = setInterval(this.tick.bind(this), this.intervalLength); + + if (root && !this.listeningForFocus && root.addEventListener) { + root.addEventListener('focus', function() { + this.start(); + }.bind(this)); + + root.addEventListener('blur', function() { + this.stop(); + }.bind(this)); + + this.listeningForFocus = true; + } + return this; + }; + + EventedLoop.prototype.stop = function () { + clearInterval(this.intervalId); + this.intervalId = undefined; + return this; + }; + + EventedLoop.prototype.isStarted = function () { + return !!this.intervalId; + }; + + EventedLoop.prototype.every = EventedLoop.prototype.on; + + // Export the EventedLoop object for **Node.js** or other + // commonjs systems. Otherwise, add it as a global object to the root + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = EventedLoop; + } + exports.EventedLoop = EventedLoop; + } + if (typeof window !== 'undefined') { + window.EventedLoop = EventedLoop; + } +}).call(this); +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"events":19,"underscore":17}],17:[function(require,module,exports){ +// Underscore.js 1.6.0 +// http://underscorejs.org +// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + concat = ArrayProto.concat, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.6.0'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return obj; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, length = obj.length; i < length; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; + } + } + return obj; + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results.push(iterator.call(context, value, index, list)); + }); + return results; + }; + + var reduceError = 'Reduce of empty array with no initial value'; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var length = obj.length; + if (length !== +length) { + var keys = _.keys(obj); + length = keys.length; + } + each(obj, function(value, index, list) { + index = keys ? keys[--length] : --length; + if (!initial) { + memo = obj[index]; + initial = true; + } else { + memo = iterator.call(context, memo, obj[index], index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var result; + any(obj, function(value, index, list) { + if (predicate.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); + each(obj, function(value, index, list) { + if (predicate.call(context, value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, function(value, index, list) { + return !predicate.call(context, value, index, list); + }, context); + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate || (predicate = _.identity); + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context); + each(obj, function(value, index, list) { + if (!(result = result && predicate.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, predicate, context) { + predicate || (predicate = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); + each(obj, function(value, index, list) { + if (result || (result = predicate.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if the array or object contains a given value (using `===`). + // Aliased as `include`. + _.contains = _.include = function(obj, target) { + if (obj == null) return false; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + return any(obj, function(value) { + return value === target; + }); + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + return (isFunc ? method : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matches(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matches(attrs)); + }; + + // Return the maximum element or (element-based computation). + // Can't optimize arrays of integers longer than 65,535 elements. + // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797) + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.max.apply(Math, obj); + } + var result = -Infinity, lastComputed = -Infinity; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + if (computed > lastComputed) { + result = value; + lastComputed = computed; + } + }); + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.min.apply(Math, obj); + } + var result = Infinity, lastComputed = Infinity; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + if (computed < lastComputed) { + result = value; + lastComputed = computed; + } + }); + return result; + }; + + // Shuffle an array, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var rand; + var index = 0; + var shuffled = []; + each(obj, function(value) { + rand = _.random(index++); + shuffled[index - 1] = shuffled[rand]; + shuffled[rand] = value; + }); + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (obj.length !== +obj.length) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // An internal function to generate lookup iterators. + var lookupIterator = function(value) { + if (value == null) return _.identity; + if (_.isFunction(value)) return value; + return _.property(value); + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + iterator = lookupIterator(iterator); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iterator, context) { + var result = {}; + iterator = lookupIterator(iterator); + each(obj, function(value, index) { + var key = iterator.call(context, value, index, obj); + behavior(result, key, value); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, key, value) { + _.has(result, key) ? result[key].push(value) : result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, key, value) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, key) { + _.has(result, key) ? result[key]++ : result[key] = 1; + }); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator, context) { + iterator = lookupIterator(iterator); + var value = iterator.call(context, obj); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >>> 1; + iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (obj.length === +obj.length) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) return array[0]; + if (n < 0) return []; + return slice.call(array, 0, n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) return array[array.length - 1]; + return slice.call(array, Math.max(array.length - n, 0)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, (n == null) || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, output) { + if (shallow && _.every(input, _.isArray)) { + return concat.apply(output, input); + } + each(input, function(value) { + if (_.isArray(value) || _.isArguments(value)) { + shallow ? push.apply(output, value) : flatten(value, shallow, output); + } else { + output.push(value); + } + }); + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Split an array into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(array, predicate) { + var pass = [], fail = []; + each(array, function(elem) { + (predicate(elem) ? pass : fail).push(elem); + }); + return [pass, fail]; + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator, context) { + if (_.isFunction(isSorted)) { + context = iterator; + iterator = isSorted; + isSorted = false; + } + var initial = iterator ? _.map(array, iterator, context) : array; + var results = []; + var seen = []; + each(initial, function(value, index) { + if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { + seen.push(value); + results.push(array[index]); + } + }); + return results; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.contains(other, item); + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.contains(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var length = _.max(_.pluck(arguments, 'length').concat(0)); + var results = new Array(length); + for (var i = 0; i < length; i++) { + results[i] = _.pluck(arguments, '' + i); + } + return results; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + if (list == null) return {}; + var result = {}; + for (var i = 0, length = list.length; i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i = 0, length = array.length; + if (isSorted) { + if (typeof isSorted == 'number') { + i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted); + } else { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); + for (; i < length; i++) if (array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item, from) { + if (array == null) return -1; + var hasIndex = from != null; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { + return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); + } + var i = (hasIndex ? from : array.length); + while (i--) if (array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(length); + + while(idx < length) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + var args, bound; + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + ctor.prototype = null; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + return function() { + var position = 0; + var args = boundArgs.slice(); + for (var i = 0, length = args.length; i < length; i++) { + if (args[i] === _) args[i] = arguments[position++]; + } + while (position < arguments.length) args.push(arguments[position++]); + return func.apply(this, args); + }; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length === 0) throw new Error('bindAll must be passed function names'); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(null, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + options || (options = {}); + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) { + timeout = setTimeout(later, wait); + } + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + memo = func.apply(this, arguments); + func = null; + return memo; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = new Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = new Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + } + }); + return obj; + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + each(keys, function(key) { + if (key in obj) copy[key] = obj[key]; + }); + return copy; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + for (var key in obj) { + if (!_.contains(keys, key)) copy[key] = obj[key]; + } + return copy; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + if (obj[prop] === void 0) obj[prop] = source[prop]; + } + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) return bStack[length] == b; + } + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && + _.isFunction(bCtor) && (bCtor instanceof bCtor)) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + if (!(result = eq(a[size], b[size], aStack, bStack))) break; + } + } + } else { + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return result; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, [], []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. + each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) == '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Optimize `isFunction` if appropriate. + if (typeof (/./) !== 'function') { + _.isFunction = function(obj) { + return typeof obj === 'function'; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj != +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + _.constant = function(value) { + return function () { + return value; + }; + }; + + _.property = function(key) { + return function(obj) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of `key:value` pairs. + _.matches = function(attrs) { + return function(obj) { + if (obj === attrs) return true; //avoid comparing an object to itself. + for (var key in attrs) { + if (attrs[key] !== obj[key]) + return false; + } + return true; + } + }; + + // Run a function **n** times. + _.times = function(n, iterator, context) { + var accum = Array(Math.max(0, n)); + for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { return new Date().getTime(); }; + + // List of HTML entities for escaping. + var entityMap = { + escape: { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + } + }; + entityMap.unescape = _.invert(entityMap.escape); + + // Regexes containing the keys and values listed immediately above. + var entityRegexes = { + escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), + unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') + }; + + // Functions for escaping and unescaping strings to/from HTML interpolation. + _.each(['escape', 'unescape'], function(method) { + _[method] = function(string) { + if (string == null) return ''; + return ('' + string).replace(entityRegexes[method], function(match) { + return entityMap[method][match]; + }); + }; + }); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property) { + if (object == null) return void 0; + var value = object[property]; + return _.isFunction(value) ? value.call(object) : value; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result.call(this, func.apply(_, args)); + }; + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(text, data, settings) { + var render; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = new RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset) + .replace(escaper, function(match) { return '\\' + escapes[match]; }); + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } + if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + index = offset + match.length; + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + "return __p;\n"; + + try { + render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + if (data) return render(data, _); + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled function source as a convenience for precompilation. + template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(obj) { + return this._chain ? _(obj).chain() : obj; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; + return result.call(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result.call(this, method.apply(this._wrapped, arguments)); + }; + }); + + _.extend(_.prototype, { + + // Start chaining a wrapped Underscore object. + chain: function() { + this._chain = true; + return this; + }, + + // Extracts the result from a wrapped and chained object. + value: function() { + return this._wrapped; + } + + }); + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}).call(this); + +},{}],18:[function(require,module,exports){ +/*! Hammer.JS - v1.0.7dev - 2014-02-18 + * http://eightmedia.github.com/hammer.js + * + * Copyright (c) 2014 Jorik Tangelder ; + * Licensed under the MIT license */ + +(function(window, undefined) { + 'use strict'; + +/** + * Hammer + * use this to create instances + * @param {HTMLElement} element + * @param {Object} options + * @returns {Hammer.Instance} + * @constructor + */ +var Hammer = function(element, options) { + return new Hammer.Instance(element, options || {}); +}; + +// default settings +Hammer.defaults = { + // add styles and attributes to the element to prevent the browser from doing + // its native behavior. this doesnt prevent the scrolling, but cancels + // the contextmenu, tap highlighting etc + // set to false to disable this + stop_browser_behavior: { + // this also triggers onselectstart=false for IE + userSelect : 'none', + // this makes the element blocking in IE10 >, you could experiment with the value + // see for more options this issue; https://github.com/EightMedia/hammer.js/issues/241 + touchAction : 'none', + touchCallout : 'none', + contentZooming : 'none', + userDrag : 'none', + tapHighlightColor: 'rgba(0,0,0,0)' + } + + // + // more settings are defined per gesture at gestures.js + // +}; + +// detect touchevents +Hammer.HAS_POINTEREVENTS = window.navigator.pointerEnabled || window.navigator.msPointerEnabled; +Hammer.HAS_TOUCHEVENTS = ('ontouchstart' in window); + +// dont use mouseevents on mobile devices +Hammer.MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android|silk/i; +Hammer.NO_MOUSEEVENTS = Hammer.HAS_TOUCHEVENTS && window.navigator.userAgent.match(Hammer.MOBILE_REGEX); + +// eventtypes per touchevent (start, move, end) +// are filled by Hammer.event.determineEventTypes on setup +Hammer.EVENT_TYPES = {}; + +// direction defines +Hammer.DIRECTION_DOWN = 'down'; +Hammer.DIRECTION_LEFT = 'left'; +Hammer.DIRECTION_UP = 'up'; +Hammer.DIRECTION_RIGHT = 'right'; + +// pointer type +Hammer.POINTER_MOUSE = 'mouse'; +Hammer.POINTER_TOUCH = 'touch'; +Hammer.POINTER_PEN = 'pen'; + +// interval in which Hammer recalculates current velocity in ms +Hammer.UPDATE_VELOCITY_INTERVAL = 20; + +// touch event defines +Hammer.EVENT_START = 'start'; +Hammer.EVENT_MOVE = 'move'; +Hammer.EVENT_END = 'end'; + +// hammer document where the base events are added at +Hammer.DOCUMENT = window.document; + +// plugins and gestures namespaces +Hammer.plugins = Hammer.plugins || {}; +Hammer.gestures = Hammer.gestures || {}; + + +// if the window events are set... +Hammer.READY = false; + +/** + * setup events to detect gestures on the document + */ +function setup() { + if(Hammer.READY) { + return; + } + + // find what eventtypes we add listeners to + Hammer.event.determineEventTypes(); + + // Register all gestures inside Hammer.gestures + Hammer.utils.each(Hammer.gestures, function(gesture){ + Hammer.detection.register(gesture); + }); + + // Add touch events on the document + Hammer.event.onTouch(Hammer.DOCUMENT, Hammer.EVENT_MOVE, Hammer.detection.detect); + Hammer.event.onTouch(Hammer.DOCUMENT, Hammer.EVENT_END, Hammer.detection.detect); + + // Hammer is ready...! + Hammer.READY = true; +} + +Hammer.utils = { + /** + * extend method, + * also used for cloning when dest is an empty object + * @param {Object} dest + * @param {Object} src + * @parm {Boolean} merge do a merge + * @returns {Object} dest + */ + extend: function extend(dest, src, merge) { + for(var key in src) { + if(dest[key] !== undefined && merge) { + continue; + } + dest[key] = src[key]; + } + return dest; + }, + + + /** + * for each + * @param obj + * @param iterator + */ + each: function(obj, iterator, context) { + var i, length; + // native forEach on arrays + if ('forEach' in obj) { + obj.forEach(iterator, context); + } + // arrays + else if(obj.length !== undefined) { + for (i = 0, length = obj.length; i < length; i++) { + if (iterator.call(context, obj[i], i, obj) === false) { + return; + } + } + } + // objects + else { + for (i in obj) { + if (obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj) === false) { + return; + } + } + } + }, + + /** + * find if a node is in the given parent + * used for event delegation tricks + * @param {HTMLElement} node + * @param {HTMLElement} parent + * @returns {boolean} has_parent + */ + hasParent: function(node, parent) { + while(node) { + if(node == parent) { + return true; + } + node = node.parentNode; + } + return false; + }, + + + /** + * get the center of all the touches + * @param {Array} touches + * @returns {Object} center + */ + getCenter: function getCenter(touches) { + var valuesX = [], valuesY = []; + + Hammer.utils.each(touches, function(touch) { + // I prefer clientX because it ignore the scrolling position + valuesX.push(typeof touch.clientX !== 'undefined' ? touch.clientX : touch.pageX ); + valuesY.push(typeof touch.clientY !== 'undefined' ? touch.clientY : touch.pageY ); + }); + + return { + pageX: ((Math.min.apply(Math, valuesX) + Math.max.apply(Math, valuesX)) / 2), + pageY: ((Math.min.apply(Math, valuesY) + Math.max.apply(Math, valuesY)) / 2) + }; + }, + + + /** + * calculate the velocity between two points + * @param {Number} delta_time + * @param {Number} delta_x + * @param {Number} delta_y + * @returns {Object} velocity + */ + getVelocity: function getVelocity(delta_time, delta_x, delta_y) { + return { + x: Math.abs(delta_x / delta_time) || 0, + y: Math.abs(delta_y / delta_time) || 0 + }; + }, + + + /** + * calculate the angle between two coordinates + * @param {Touch} touch1 + * @param {Touch} touch2 + * @returns {Number} angle + */ + getAngle: function getAngle(touch1, touch2) { + var y = touch2.pageY - touch1.pageY, + x = touch2.pageX - touch1.pageX; + return Math.atan2(y, x) * 180 / Math.PI; + }, + + + /** + * angle to direction define + * @param {Touch} touch1 + * @param {Touch} touch2 + * @returns {String} direction constant, like Hammer.DIRECTION_LEFT + */ + getDirection: function getDirection(touch1, touch2) { + var x = Math.abs(touch1.pageX - touch2.pageX), + y = Math.abs(touch1.pageY - touch2.pageY); + + if(x >= y) { + return touch1.pageX - touch2.pageX > 0 ? Hammer.DIRECTION_LEFT : Hammer.DIRECTION_RIGHT; + } + else { + return touch1.pageY - touch2.pageY > 0 ? Hammer.DIRECTION_UP : Hammer.DIRECTION_DOWN; + } + }, + + + /** + * calculate the distance between two touches + * @param {Touch} touch1 + * @param {Touch} touch2 + * @returns {Number} distance + */ + getDistance: function getDistance(touch1, touch2) { + var x = touch2.pageX - touch1.pageX, + y = touch2.pageY - touch1.pageY; + return Math.sqrt((x * x) + (y * y)); + }, + + + /** + * calculate the scale factor between two touchLists (fingers) + * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out + * @param {Array} start + * @param {Array} end + * @returns {Number} scale + */ + getScale: function getScale(start, end) { + // need two fingers... + if(start.length >= 2 && end.length >= 2) { + return this.getDistance(end[0], end[1]) / + this.getDistance(start[0], start[1]); + } + return 1; + }, + + + /** + * calculate the rotation degrees between two touchLists (fingers) + * @param {Array} start + * @param {Array} end + * @returns {Number} rotation + */ + getRotation: function getRotation(start, end) { + // need two fingers + if(start.length >= 2 && end.length >= 2) { + return this.getAngle(end[1], end[0]) - + this.getAngle(start[1], start[0]); + } + return 0; + }, + + + /** + * boolean if the direction is vertical + * @param {String} direction + * @returns {Boolean} is_vertical + */ + isVertical: function isVertical(direction) { + return (direction == Hammer.DIRECTION_UP || direction == Hammer.DIRECTION_DOWN); + }, + + + /** + * stop browser default behavior with css props + * @param {HtmlElement} element + * @param {Object} css_props + */ + stopDefaultBrowserBehavior: function stopDefaultBrowserBehavior(element, css_props) { + if(!css_props || !element || !element.style) { + return; + } + + // with css properties for modern browsers + Hammer.utils.each(['webkit', 'khtml', 'moz', 'Moz', 'ms', 'o', ''], function(vendor) { + Hammer.utils.each(css_props, function(value, prop) { + // vender prefix at the property + if(vendor) { + prop = vendor + prop.substring(0, 1).toUpperCase() + prop.substring(1); + } + // set the style + if(prop in element.style) { + element.style[prop] = value; + } + }); + }); + + // also the disable onselectstart + if(css_props.userSelect == 'none') { + element.onselectstart = function() { + return false; + }; + } + + // and disable ondragstart + if(css_props.userDrag == 'none') { + element.ondragstart = function() { + return false; + }; + } + }, + + + /** + * reverts all changes made by 'stopDefaultBrowserBehavior' + * @param {HtmlElement} element + * @param {Object} css_props + */ + startDefaultBrowserBehavior: function startDefaultBrowserBehavior(element, css_props) { + if(!css_props || !element || !element.style) { + return; + } + + // with css properties for modern browsers + Hammer.utils.each(['webkit', 'khtml', 'moz', 'Moz', 'ms', 'o', ''], function(vendor) { + Hammer.utils.each(css_props, function(value, prop) { + // vender prefix at the property + if(vendor) { + prop = vendor + prop.substring(0, 1).toUpperCase() + prop.substring(1); + } + // reset the style + if(prop in element.style) { + element.style[prop] = ''; + } + }); + }); + + // also the enable onselectstart + if(css_props.userSelect == 'none') { + element.onselectstart = null; + } + + // and enable ondragstart + if(css_props.userDrag == 'none') { + element.ondragstart = null; + } + } +}; + + +/** + * create new hammer instance + * all methods should return the instance itself, so it is chainable. + * @param {HTMLElement} element + * @param {Object} [options={}] + * @returns {Hammer.Instance} + * @constructor + */ +Hammer.Instance = function(element, options) { + var self = this; + + // setup HammerJS window events and register all gestures + // this also sets up the default options + setup(); + + this.element = element; + + // start/stop detection option + this.enabled = true; + + // merge options + this.options = Hammer.utils.extend( + Hammer.utils.extend({}, Hammer.defaults), + options || {}); + + // add some css to the element to prevent the browser from doing its native behavoir + if(this.options.stop_browser_behavior) { + Hammer.utils.stopDefaultBrowserBehavior(this.element, this.options.stop_browser_behavior); + } + + // start detection on touchstart + this._eventStartHandler = Hammer.event.onTouch(element, Hammer.EVENT_START, function(ev) { + if(self.enabled) { + Hammer.detection.startDetect(self, ev); + } + }); + + // keep a list of user event handlers which needs to be removed when calling 'dispose' + this._eventHandler = []; + + // return instance + return this; +}; + + +Hammer.Instance.prototype = { + /** + * bind events to the instance + * @param {String} gesture + * @param {Function} handler + * @returns {Hammer.Instance} + */ + on: function onEvent(gesture, handler) { + var gestures = gesture.split(' '); + Hammer.utils.each(gestures, function(gesture) { + this.element.addEventListener(gesture, handler, false); + this._eventHandler.push({ gesture: gesture, handler: handler }); + }, this); + return this; + }, + + + /** + * unbind events to the instance + * @param {String} gesture + * @param {Function} handler + * @returns {Hammer.Instance} + */ + off: function offEvent(gesture, handler) { + var gestures = gesture.split(' '); + Hammer.utils.each(gestures, function(gesture) { + this.element.removeEventListener(gesture, handler, false); + + // remove the event handler from the internal list + var index = -1; + Hammer.utils.each(this._eventHandler, function(eventHandler, i) { + if (index === -1 && eventHandler.gesture === gesture && eventHandler.handler === handler) { + index = i; + } + }, this); + + if (index > -1) { + this._eventHandler.splice(index, 1); + } + }, this); + return this; + }, + + + /** + * trigger gesture event + * @param {String} gesture + * @param {Object} [eventData] + * @returns {Hammer.Instance} + */ + trigger: function triggerEvent(gesture, eventData) { + // optional + if(!eventData) { + eventData = {}; + } + + // create DOM event + var event = Hammer.DOCUMENT.createEvent('Event'); + event.initEvent(gesture, true, true); + event.gesture = eventData; + + // trigger on the target if it is in the instance element, + // this is for event delegation tricks + var element = this.element; + if(Hammer.utils.hasParent(eventData.target, element)) { + element = eventData.target; + } + + element.dispatchEvent(event); + return this; + }, + + + /** + * enable of disable hammer.js detection + * @param {Boolean} state + * @returns {Hammer.Instance} + */ + enable: function enable(state) { + this.enabled = state; + return this; + }, + + + /** + * dispose this hammer instance + * @returns {Hammer.Instance} + */ + dispose: function dispose() { + + // undo all changes made by stop_browser_behavior + if(this.options.stop_browser_behavior) { + Hammer.utils.startDefaultBrowserBehavior(this.element, this.options.stop_browser_behavior); + } + + // unbind all custom event handlers + Hammer.utils.each(this._eventHandler, function(eventHandler) { + this.element.removeEventListener(eventHandler.gesture, eventHandler.handler, false); + }, this); + this._eventHandler.length = 0; + + // unbind the start event listener + Hammer.event.unbindDom(this.element, Hammer.EVENT_TYPES[Hammer.EVENT_START], this._eventStartHandler); + return this; + } +}; + + +/** + * this holds the last move event, + * used to fix empty touchend issue + * see the onTouch event for an explanation + * @type {Object} + */ +var last_move_event = null; + + +/** + * when the mouse is hold down, this is true + * @type {Boolean} + */ +var enable_detect = false; + + +/** + * when touch events have been fired, this is true + * @type {Boolean} + */ +var touch_triggered = false; + + +Hammer.event = { + /** + * simple addEventListener + * @param {HTMLElement} element + * @param {String} type + * @param {Function} handler + */ + bindDom: function(element, type, handler) { + var types = type.split(' '); + Hammer.utils.each(types, function(type){ + element.addEventListener(type, handler, false); + }); + }, + + + /** + * simple removeEventListener + * @param {HTMLElement} element + * @param {String} type + * @param {Function} handler + */ + unbindDom: function(element, type, handler) { + var types = type.split(' '); + Hammer.utils.each(types, function(type){ + element.removeEventListener(type, handler, false); + }); + }, + + + /** + * touch events with mouse fallback + * @param {HTMLElement} element + * @param {String} eventType like Hammer.EVENT_MOVE + * @param {Function} handler + */ + onTouch: function onTouch(element, eventType, handler) { + var self = this; + + var fn = function bindDomOnTouch(ev) { + var sourceEventType = ev.type.toLowerCase(); + + // onmouseup, but when touchend has been fired we do nothing. + // this is for touchdevices which also fire a mouseup on touchend + if(sourceEventType.match(/mouse/) && touch_triggered) { + return; + } + + // mousebutton must be down or a touch event + else if(sourceEventType.match(/touch/) || // touch events are always on screen + sourceEventType.match(/pointerdown/) || // pointerevents touch + (sourceEventType.match(/mouse/) && ev.which === 1) // mouse is pressed + ) { + enable_detect = true; + } + + // mouse isn't pressed + else if(sourceEventType.match(/mouse/) && !ev.which) { + enable_detect = false; + } + + + // we are in a touch event, set the touch triggered bool to true, + // this for the conflicts that may occur on ios and android + if(sourceEventType.match(/touch|pointer/)) { + touch_triggered = true; + } + + // count the total touches on the screen + var count_touches = 0; + + // when touch has been triggered in this detection session + // and we are now handling a mouse event, we stop that to prevent conflicts + if(enable_detect) { + // update pointerevent + if(Hammer.HAS_POINTEREVENTS && eventType != Hammer.EVENT_END) { + count_touches = Hammer.PointerEvent.updatePointer(eventType, ev); + } + // touch + else if(sourceEventType.match(/touch/)) { + count_touches = ev.touches.length; + } + // mouse + else if(!touch_triggered) { + count_touches = sourceEventType.match(/up/) ? 0 : 1; + } + + // if we are in a end event, but when we remove one touch and + // we still have enough, set eventType to move + if(count_touches > 0 && eventType == Hammer.EVENT_END) { + eventType = Hammer.EVENT_MOVE; + } + // no touches, force the end event + else if(!count_touches) { + eventType = Hammer.EVENT_END; + } + + // store the last move event + if(count_touches || last_move_event === null) { + last_move_event = ev; + } + + // trigger the handler + handler.call(Hammer.detection, self.collectEventData(element, eventType, self.getTouchList(last_move_event, eventType), ev)); + + // remove pointerevent from list + if(Hammer.HAS_POINTEREVENTS && eventType == Hammer.EVENT_END) { + count_touches = Hammer.PointerEvent.updatePointer(eventType, ev); + } + } + + // on the end we reset everything + if(!count_touches) { + last_move_event = null; + enable_detect = false; + touch_triggered = false; + Hammer.PointerEvent.reset(); + } + }; + + this.bindDom(element, Hammer.EVENT_TYPES[eventType], fn); + + // return the bound function to be able to unbind it later + return fn; + }, + + + /** + * we have different events for each device/browser + * determine what we need and set them in the Hammer.EVENT_TYPES constant + */ + determineEventTypes: function determineEventTypes() { + // determine the eventtype we want to set + var types; + + // pointerEvents magic + if(Hammer.HAS_POINTEREVENTS) { + types = Hammer.PointerEvent.getEvents(); + } + // on Android, iOS, blackberry, windows mobile we dont want any mouseevents + else if(Hammer.NO_MOUSEEVENTS) { + types = [ + 'touchstart', + 'touchmove', + 'touchend touchcancel']; + } + // for non pointer events browsers and mixed browsers, + // like chrome on windows8 touch laptop + else { + types = [ + 'touchstart mousedown', + 'touchmove mousemove', + 'touchend touchcancel mouseup']; + } + + Hammer.EVENT_TYPES[Hammer.EVENT_START] = types[0]; + Hammer.EVENT_TYPES[Hammer.EVENT_MOVE] = types[1]; + Hammer.EVENT_TYPES[Hammer.EVENT_END] = types[2]; + }, + + + /** + * create touchlist depending on the event + * @param {Object} ev + * @param {String} eventType used by the fakemultitouch plugin + */ + getTouchList: function getTouchList(ev/*, eventType*/) { + // get the fake pointerEvent touchlist + if(Hammer.HAS_POINTEREVENTS) { + return Hammer.PointerEvent.getTouchList(); + } + // get the touchlist + else if(ev.touches) { + return ev.touches; + } + // make fake touchlist from mouse position + else { + ev.identifier = 1; + return [ev]; + } + }, + + + /** + * collect event data for Hammer js + * @param {HTMLElement} element + * @param {String} eventType like Hammer.EVENT_MOVE + * @param {Object} eventData + */ + collectEventData: function collectEventData(element, eventType, touches, ev) { + // find out pointerType + var pointerType = Hammer.POINTER_TOUCH; + if(ev.type.match(/mouse/) || Hammer.PointerEvent.matchType(Hammer.POINTER_MOUSE, ev)) { + pointerType = Hammer.POINTER_MOUSE; + } + + return { + center : Hammer.utils.getCenter(touches), + timeStamp : new Date().getTime(), + target : ev.target, + touches : touches, + eventType : eventType, + pointerType: pointerType, + srcEvent : ev, + + /** + * prevent the browser default actions + * mostly used to disable scrolling of the browser + */ + preventDefault: function() { + if(this.srcEvent.preventManipulation) { + this.srcEvent.preventManipulation(); + } + + if(this.srcEvent.preventDefault) { + this.srcEvent.preventDefault(); + } + }, + + /** + * stop bubbling the event up to its parents + */ + stopPropagation: function() { + this.srcEvent.stopPropagation(); + }, + + /** + * immediately stop gesture detection + * might be useful after a swipe was detected + * @return {*} + */ + stopDetect: function() { + return Hammer.detection.stopDetect(); + } + }; + } +}; + +Hammer.PointerEvent = { + /** + * holds all pointers + * @type {Object} + */ + pointers: {}, + + /** + * get a list of pointers + * @returns {Array} touchlist + */ + getTouchList: function() { + var self = this; + var touchlist = []; + + // we can use forEach since pointerEvents only is in IE10 + Hammer.utils.each(self.pointers, function(pointer){ + touchlist.push(pointer); + }); + + return touchlist; + }, + + /** + * update the position of a pointer + * @param {String} type Hammer.EVENT_END + * @param {Object} pointerEvent + */ + updatePointer: function(type, pointerEvent) { + if(type == Hammer.EVENT_END) { + delete this.pointers[pointerEvent.pointerId]; + } + else { + pointerEvent.identifier = pointerEvent.pointerId; + this.pointers[pointerEvent.pointerId] = pointerEvent; + } + + return Object.keys(this.pointers).length; + }, + + /** + * check if ev matches pointertype + * @param {String} pointerType Hammer.POINTER_MOUSE + * @param {PointerEvent} ev + */ + matchType: function(pointerType, ev) { + if(!ev.pointerType) { + return false; + } + + var pt = ev.pointerType, + types = {}; + types[Hammer.POINTER_MOUSE] = (pt === ev.MSPOINTER_TYPE_MOUSE || pt === Hammer.POINTER_MOUSE); + types[Hammer.POINTER_TOUCH] = (pt === ev.MSPOINTER_TYPE_TOUCH || pt === Hammer.POINTER_TOUCH); + types[Hammer.POINTER_PEN] = (pt === ev.MSPOINTER_TYPE_PEN || pt === Hammer.POINTER_PEN); + return types[pointerType]; + }, + + + /** + * get events + */ + getEvents: function() { + return [ + 'pointerdown MSPointerDown', + 'pointermove MSPointerMove', + 'pointerup pointercancel MSPointerUp MSPointerCancel' + ]; + }, + + /** + * reset the list + */ + reset: function() { + this.pointers = {}; + } +}; + + +Hammer.detection = { + // contains all registred Hammer.gestures in the correct order + gestures: [], + + // data of the current Hammer.gesture detection session + current : null, + + // the previous Hammer.gesture session data + // is a full clone of the previous gesture.current object + previous: null, + + // when this becomes true, no gestures are fired + stopped : false, + + + /** + * start Hammer.gesture detection + * @param {Hammer.Instance} inst + * @param {Object} eventData + */ + startDetect: function startDetect(inst, eventData) { + // already busy with a Hammer.gesture detection on an element + if(this.current) { + return; + } + + this.stopped = false; + + this.current = { + inst : inst, // reference to HammerInstance we're working for + startEvent: Hammer.utils.extend({}, eventData), // start eventData for distances, timing etc + lastEvent : false, // last eventData + lastVEvent: false, // last eventData for velocity. + velocity : false, // current velocity + name : '' // current gesture we're in/detected, can be 'tap', 'hold' etc + }; + + this.detect(eventData); + }, + + + /** + * Hammer.gesture detection + * @param {Object} eventData + */ + detect: function detect(eventData) { + if(!this.current || this.stopped) { + return; + } + + // extend event data with calculations about scale, distance etc + eventData = this.extendEventData(eventData); + + // instance options + var inst_options = this.current.inst.options; + + // call Hammer.gesture handlers + Hammer.utils.each(this.gestures, function(gesture) { + // only when the instance options have enabled this gesture + if(!this.stopped && inst_options[gesture.name] !== false) { + // if a handler returns false, we stop with the detection + if(gesture.handler.call(gesture, eventData, this.current.inst) === false) { + this.stopDetect(); + return false; + } + } + }, this); + + // store as previous event event + if(this.current) { + this.current.lastEvent = eventData; + } + + // endevent, but not the last touch, so dont stop + if(eventData.eventType == Hammer.EVENT_END && !eventData.touches.length - 1) { + this.stopDetect(); + } + + return eventData; + }, + + + /** + * clear the Hammer.gesture vars + * this is called on endDetect, but can also be used when a final Hammer.gesture has been detected + * to stop other Hammer.gestures from being fired + */ + stopDetect: function stopDetect() { + // clone current data to the store as the previous gesture + // used for the double tap gesture, since this is an other gesture detect session + this.previous = Hammer.utils.extend({}, this.current); + + // reset the current + this.current = null; + + // stopped! + this.stopped = true; + }, + + + /** + * extend eventData for Hammer.gestures + * @param {Object} ev + * @returns {Object} ev + */ + extendEventData: function extendEventData(ev) { + var startEv = this.current.startEvent, + lastVEv = this.current.lastVEvent; + + // if the touches change, set the new touches over the startEvent touches + // this because touchevents don't have all the touches on touchstart, or the + // user must place his fingers at the EXACT same time on the screen, which is not realistic + // but, sometimes it happens that both fingers are touching at the EXACT same time + if(startEv && (ev.touches.length != startEv.touches.length || ev.touches === startEv.touches)) { + // extend 1 level deep to get the touchlist with the touch objects + startEv.touches = []; + Hammer.utils.each(ev.touches, function(touch) { + startEv.touches.push(Hammer.utils.extend({}, touch)); + }); + } + + var delta_time = ev.timeStamp - startEv.timeStamp + , delta_x = ev.center.pageX - startEv.center.pageX + , delta_y = ev.center.pageY - startEv.center.pageY + , interimAngle + , interimDirection + , velocity = this.current.velocity; + + if (lastVEv !== false && ev.timeStamp - lastVEv.timeStamp > Hammer.UPDATE_VELOCITY_INTERVAL) { + + velocity = Hammer.utils.getVelocity(ev.timeStamp - lastVEv.timeStamp, ev.center.pageX - lastVEv.center.pageX, ev.center.pageY - lastVEv.center.pageY); + this.current.lastVEvent = ev; + + if (velocity.x > 0 && velocity.y > 0) { + this.current.velocity = velocity; + } + + } else if(this.current.velocity === false) { + velocity = Hammer.utils.getVelocity(delta_time, delta_x, delta_y); + this.current.velocity = velocity; + this.current.lastVEvent = ev; + } + + // end events (e.g. dragend) don't have useful values for interimDirection & interimAngle + // because the previous event has exactly the same coordinates + // so for end events, take the previous values of interimDirection & interimAngle + // instead of recalculating them and getting a spurious '0' + if(ev.eventType === 'end') { + interimAngle = this.current.lastEvent && this.current.lastEvent.interimAngle; + interimDirection = this.current.lastEvent && this.current.lastEvent.interimDirection; + } + else { + interimAngle = this.current.lastEvent && Hammer.utils.getAngle(this.current.lastEvent.center, ev.center); + interimDirection = this.current.lastEvent && Hammer.utils.getDirection(this.current.lastEvent.center, ev.center); + } + + Hammer.utils.extend(ev, { + deltaTime: delta_time, + + deltaX: delta_x, + deltaY: delta_y, + + velocityX: velocity.x, + velocityY: velocity.y, + + distance: Hammer.utils.getDistance(startEv.center, ev.center), + + angle: Hammer.utils.getAngle(startEv.center, ev.center), + interimAngle: interimAngle, + + direction: Hammer.utils.getDirection(startEv.center, ev.center), + interimDirection: interimDirection, + + scale: Hammer.utils.getScale(startEv.touches, ev.touches), + rotation: Hammer.utils.getRotation(startEv.touches, ev.touches), + + startEvent: startEv + }); + + return ev; + }, + + + /** + * register new gesture + * @param {Object} gesture object, see gestures.js for documentation + * @returns {Array} gestures + */ + register: function register(gesture) { + // add an enable gesture options if there is no given + var options = gesture.defaults || {}; + if(options[gesture.name] === undefined) { + options[gesture.name] = true; + } + + // extend Hammer default options with the Hammer.gesture options + Hammer.utils.extend(Hammer.defaults, options, true); + + // set its index + gesture.index = gesture.index || 1000; + + // add Hammer.gesture to the list + this.gestures.push(gesture); + + // sort the list by index + this.gestures.sort(function(a, b) { + if(a.index < b.index) { return -1; } + if(a.index > b.index) { return 1; } + return 0; + }); + + return this.gestures; + } +}; + + +/** + * Drag + * Move with x fingers (default 1) around on the page. Blocking the scrolling when + * moving left and right is a good practice. When all the drag events are blocking + * you disable scrolling on that area. + * @events drag, drapleft, dragright, dragup, dragdown + */ +Hammer.gestures.Drag = { + name : 'drag', + index : 50, + defaults : { + drag_min_distance : 10, + + // Set correct_for_drag_min_distance to true to make the starting point of the drag + // be calculated from where the drag was triggered, not from where the touch started. + // Useful to avoid a jerk-starting drag, which can make fine-adjustments + // through dragging difficult, and be visually unappealing. + correct_for_drag_min_distance: true, + + // set 0 for unlimited, but this can conflict with transform + drag_max_touches : 1, + + // prevent default browser behavior when dragging occurs + // be careful with it, it makes the element a blocking element + // when you are using the drag gesture, it is a good practice to set this true + drag_block_horizontal : false, + drag_block_vertical : false, + + // drag_lock_to_axis keeps the drag gesture on the axis that it started on, + // It disallows vertical directions if the initial direction was horizontal, and vice versa. + drag_lock_to_axis : false, + + // drag lock only kicks in when distance > drag_lock_min_distance + // This way, locking occurs only when the distance has become large enough to reliably determine the direction + drag_lock_min_distance : 25 + }, + + triggered: false, + handler : function dragGesture(ev, inst) { + // current gesture isnt drag, but dragged is true + // this means an other gesture is busy. now call dragend + if(Hammer.detection.current.name != this.name && this.triggered) { + inst.trigger(this.name + 'end', ev); + this.triggered = false; + return; + } + + // max touches + if(inst.options.drag_max_touches > 0 && + ev.touches.length > inst.options.drag_max_touches) { + return; + } + + switch(ev.eventType) { + case Hammer.EVENT_START: + this.triggered = false; + break; + + case Hammer.EVENT_MOVE: + // when the distance we moved is too small we skip this gesture + // or we can be already in dragging + if(ev.distance < inst.options.drag_min_distance && + Hammer.detection.current.name != this.name) { + return; + } + + // we are dragging! + if(Hammer.detection.current.name != this.name) { + Hammer.detection.current.name = this.name; + if(inst.options.correct_for_drag_min_distance && ev.distance > 0) { + // When a drag is triggered, set the event center to drag_min_distance pixels from the original event center. + // Without this correction, the dragged distance would jumpstart at drag_min_distance pixels instead of at 0. + // It might be useful to save the original start point somewhere + var factor = Math.abs(inst.options.drag_min_distance / ev.distance); + Hammer.detection.current.startEvent.center.pageX += ev.deltaX * factor; + Hammer.detection.current.startEvent.center.pageY += ev.deltaY * factor; + + // recalculate event data using new start point + ev = Hammer.detection.extendEventData(ev); + } + } + + // lock drag to axis? + if(Hammer.detection.current.lastEvent.drag_locked_to_axis || (inst.options.drag_lock_to_axis && inst.options.drag_lock_min_distance <= ev.distance)) { + ev.drag_locked_to_axis = true; + } + var last_direction = Hammer.detection.current.lastEvent.direction; + if(ev.drag_locked_to_axis && last_direction !== ev.direction) { + // keep direction on the axis that the drag gesture started on + if(Hammer.utils.isVertical(last_direction)) { + ev.direction = (ev.deltaY < 0) ? Hammer.DIRECTION_UP : Hammer.DIRECTION_DOWN; + } + else { + ev.direction = (ev.deltaX < 0) ? Hammer.DIRECTION_LEFT : Hammer.DIRECTION_RIGHT; + } + } + + // first time, trigger dragstart event + if(!this.triggered) { + inst.trigger(this.name + 'start', ev); + this.triggered = true; + } + + // trigger normal event + inst.trigger(this.name, ev); + + // direction event, like dragdown + inst.trigger(this.name + ev.direction, ev); + + // block the browser events + if((inst.options.drag_block_vertical && Hammer.utils.isVertical(ev.direction)) || + (inst.options.drag_block_horizontal && !Hammer.utils.isVertical(ev.direction))) { + ev.preventDefault(); + } + break; + + case Hammer.EVENT_END: + // trigger dragend + if(this.triggered) { + inst.trigger(this.name + 'end', ev); + } + + this.triggered = false; + break; + } + } +}; + +/** + * Hold + * Touch stays at the same place for x time + * @events hold + */ +Hammer.gestures.Hold = { + name : 'hold', + index : 10, + defaults: { + hold_timeout : 500, + hold_threshold: 1 + }, + timer : null, + handler : function holdGesture(ev, inst) { + switch(ev.eventType) { + case Hammer.EVENT_START: + // clear any running timers + clearTimeout(this.timer); + + // set the gesture so we can check in the timeout if it still is + Hammer.detection.current.name = this.name; + + // set timer and if after the timeout it still is hold, + // we trigger the hold event + this.timer = setTimeout(function() { + if(Hammer.detection.current.name == 'hold') { + inst.trigger('hold', ev); + } + }, inst.options.hold_timeout); + break; + + // when you move or end we clear the timer + case Hammer.EVENT_MOVE: + if(ev.distance > inst.options.hold_threshold) { + clearTimeout(this.timer); + } + break; + + case Hammer.EVENT_END: + clearTimeout(this.timer); + break; + } + } +}; + +/** + * Release + * Called as last, tells the user has released the screen + * @events release + */ +Hammer.gestures.Release = { + name : 'release', + index : Infinity, + handler: function releaseGesture(ev, inst) { + if(ev.eventType == Hammer.EVENT_END) { + inst.trigger(this.name, ev); + } + } +}; + +/** + * Swipe + * triggers swipe events when the end velocity is above the threshold + * @events swipe, swipeleft, swiperight, swipeup, swipedown + */ +Hammer.gestures.Swipe = { + name : 'swipe', + index : 40, + defaults: { + // set 0 for unlimited, but this can conflict with transform + swipe_min_touches: 1, + swipe_max_touches: 1, + swipe_velocity : 0.7 + }, + handler : function swipeGesture(ev, inst) { + if(ev.eventType == Hammer.EVENT_END) { + // max touches + if(inst.options.swipe_max_touches > 0 && + ev.touches.length < inst.options.swipe_min_touches && + ev.touches.length > inst.options.swipe_max_touches) { + return; + } + + // when the distance we moved is too small we skip this gesture + // or we can be already in dragging + if(ev.velocityX > inst.options.swipe_velocity || + ev.velocityY > inst.options.swipe_velocity) { + // trigger swipe events + inst.trigger(this.name, ev); + inst.trigger(this.name + ev.direction, ev); + } + } + } +}; + +/** + * Tap/DoubleTap + * Quick touch at a place or double at the same place + * @events tap, doubletap + */ +Hammer.gestures.Tap = { + name : 'tap', + index : 100, + defaults: { + tap_max_touchtime : 250, + tap_max_distance : 10, + tap_always : true, + doubletap_distance: 20, + doubletap_interval: 300 + }, + handler : function tapGesture(ev, inst) { + if(ev.eventType == Hammer.EVENT_MOVE && !Hammer.detection.current.reachedTapMaxDistance) { + //Track the distance we've moved. If it's above the max ONCE, remember that (fixes #406). + Hammer.detection.current.reachedTapMaxDistance = (ev.distance > inst.options.tap_max_distance); + } else if(ev.eventType == Hammer.EVENT_END && ev.srcEvent.type != 'touchcancel') { + // previous gesture, for the double tap since these are two different gesture detections + var prev = Hammer.detection.previous, + did_doubletap = false; + + // when the touchtime is higher then the max touch time + // or when the moving distance is too much + if(Hammer.detection.current.reachedTapMaxDistance || ev.deltaTime > inst.options.tap_max_touchtime) { + return; + } + + // check if double tap + if(prev && prev.name == 'tap' && + (ev.timeStamp - prev.lastEvent.timeStamp) < inst.options.doubletap_interval && + ev.distance < inst.options.doubletap_distance) { + inst.trigger('doubletap', ev); + did_doubletap = true; + } + + // do a single tap + if(!did_doubletap || inst.options.tap_always) { + Hammer.detection.current.name = 'tap'; + inst.trigger(Hammer.detection.current.name, ev); + } + } + } +}; + +/** + * Touch + * Called as first, tells the user has touched the screen + * @events touch + */ +Hammer.gestures.Touch = { + name : 'touch', + index : -Infinity, + defaults: { + // call preventDefault at touchstart, and makes the element blocking by + // disabling the scrolling of the page, but it improves gestures like + // transforming and dragging. + // be careful with using this, it can be very annoying for users to be stuck + // on the page + prevent_default : false, + + // disable mouse events, so only touch (or pen!) input triggers events + prevent_mouseevents: false + }, + handler : function touchGesture(ev, inst) { + if(inst.options.prevent_mouseevents && ev.pointerType == Hammer.POINTER_MOUSE) { + ev.stopDetect(); + return; + } + + if(inst.options.prevent_default) { + ev.preventDefault(); + } + + if(ev.eventType == Hammer.EVENT_START) { + inst.trigger(this.name, ev); + } + } +}; + + +/** + * Transform + * User want to scale or rotate with 2 fingers + * @events transform, pinch, pinchin, pinchout, rotate + */ +Hammer.gestures.Transform = { + name : 'transform', + index : 45, + defaults : { + // factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1 + transform_min_scale : 0.01, + // rotation in degrees + transform_min_rotation: 1, + // prevent default browser behavior when two touches are on the screen + // but it makes the element a blocking element + // when you are using the transform gesture, it is a good practice to set this true + transform_always_block: false + }, + triggered: false, + handler : function transformGesture(ev, inst) { + // current gesture isnt drag, but dragged is true + // this means an other gesture is busy. now call dragend + if(Hammer.detection.current.name != this.name && this.triggered) { + inst.trigger(this.name + 'end', ev); + this.triggered = false; + return; + } + + // atleast multitouch + if(ev.touches.length < 2) { + return; + } + + // prevent default when two fingers are on the screen + if(inst.options.transform_always_block) { + ev.preventDefault(); + } + + switch(ev.eventType) { + case Hammer.EVENT_START: + this.triggered = false; + break; + + case Hammer.EVENT_MOVE: + var scale_threshold = Math.abs(1 - ev.scale); + var rotation_threshold = Math.abs(ev.rotation); + + // when the distance we moved is too small we skip this gesture + // or we can be already in dragging + if(scale_threshold < inst.options.transform_min_scale && + rotation_threshold < inst.options.transform_min_rotation) { + return; + } + + // we are transforming! + Hammer.detection.current.name = this.name; + + // first time, trigger dragstart event + if(!this.triggered) { + inst.trigger(this.name + 'start', ev); + this.triggered = true; + } + + inst.trigger(this.name, ev); // basic transform event + + // trigger rotate event + if(rotation_threshold > inst.options.transform_min_rotation) { + inst.trigger('rotate', ev); + } + + // trigger pinch event + if(scale_threshold > inst.options.transform_min_scale) { + inst.trigger('pinch', ev); + inst.trigger('pinch' + ((ev.scale < 1) ? 'in' : 'out'), ev); + } + break; + + case Hammer.EVENT_END: + // trigger dragend + if(this.triggered) { + inst.trigger(this.name + 'end', ev); + } + + this.triggered = false; + break; + } + } +}; + + // Based off Lo-Dash's excellent UMD wrapper (slightly modified) - https://github.com/bestiejs/lodash/blob/master/lodash.js#L5515-L5543 + // some AMD build optimizers, like r.js, check for specific condition patterns like the following: + if(typeof define == 'function' && define.amd) { + // define as an anonymous module + define(function() { return Hammer; }); + } + + // check for `exports` after `define` in case a build optimizer adds an `exports` object + else if(typeof module === 'object' && module.exports) { + module.exports = Hammer; + } + + else { + window.Hammer = Hammer; + } + +})(window); + +},{}],19:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}]},{},[13]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi91c3IvbG9jYWwvbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvanMvbGliL2NhbnZhc1JlbmRlcmluZ0NvbnRleHQyREV4dGVuc2lvbnMuanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvanMvbGliL2V4dGVuZGVycy5qcyIsIi9Vc2Vycy9kYW4vRGV2ZWxvcG1lbnQvc2tpZnJlZS1qcy9qcy9saWIvZ2FtZS5qcyIsIi9Vc2Vycy9kYW4vRGV2ZWxvcG1lbnQvc2tpZnJlZS1qcy9qcy9saWIvZ3VpZC5qcyIsIi9Vc2Vycy9kYW4vRGV2ZWxvcG1lbnQvc2tpZnJlZS1qcy9qcy9saWIvaW5mb0JveC5qcyIsIi9Vc2Vycy9kYW4vRGV2ZWxvcG1lbnQvc2tpZnJlZS1qcy9qcy9saWIvaXNNb2JpbGVEZXZpY2UuanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvanMvbGliL21vbnN0ZXIuanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvanMvbGliL3BsdWdpbnMuanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvanMvbGliL3NraWVyLmpzIiwiL1VzZXJzL2Rhbi9EZXZlbG9wbWVudC9za2lmcmVlLWpzL2pzL2xpYi9zbm93Ym9hcmRlci5qcyIsIi9Vc2Vycy9kYW4vRGV2ZWxvcG1lbnQvc2tpZnJlZS1qcy9qcy9saWIvc3ByaXRlLmpzIiwiL1VzZXJzL2Rhbi9EZXZlbG9wbWVudC9za2lmcmVlLWpzL2pzL2xpYi9zcHJpdGVBcnJheS5qcyIsIi9Vc2Vycy9kYW4vRGV2ZWxvcG1lbnQvc2tpZnJlZS1qcy9qcy9tYWluLmpzIiwiL1VzZXJzL2Rhbi9EZXZlbG9wbWVudC9za2lmcmVlLWpzL2pzL3Nwcml0ZUluZm8uanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvbm9kZV9tb2R1bGVzL2JyLW1vdXNldHJhcC9tb3VzZXRyYXAuanMiLCIvVXNlcnMvZGFuL0RldmVsb3BtZW50L3NraWZyZWUtanMvbm9kZV9tb2R1bGVzL2V2ZW50ZWRsb29wL2xpYi9tYWluLmpzIiwiL1VzZXJzL2Rhbi9EZXZlbG9wbWVudC9za2lmcmVlLWpzL25vZGVfbW9kdWxlcy9ldmVudGVkbG9vcC9ub2RlX21vZHVsZXMvdW5kZXJzY29yZS91bmRlcnNjb3JlLmpzIiwiL1VzZXJzL2Rhbi9EZXZlbG9wbWVudC9za2lmcmVlLWpzL25vZGVfbW9kdWxlcy9oYW1tZXJqcy9oYW1tZXIuanMiLCIvdXNyL2xvY2FsL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy95QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy96Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5zdG9yZUxvYWRlZEltYWdlID0gZnVuY3Rpb24gKGtleSwgaW1hZ2UpIHtcblx0aWYgKCF0aGlzLmltYWdlcykge1xuXHRcdHRoaXMuaW1hZ2VzID0ge307XG5cdH1cblxuXHR0aGlzLmltYWdlc1trZXldID0gaW1hZ2U7XG59O1xuXG5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLmdldExvYWRlZEltYWdlID0gZnVuY3Rpb24gKGtleSkge1xuXHRpZiAodGhpcy5pbWFnZXNba2V5XSkge1xuXHRcdHJldHVybiB0aGlzLmltYWdlc1trZXldO1xuXHR9XG59O1xuXG5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLmZvbGxvd1Nwcml0ZSA9IGZ1bmN0aW9uIChzcHJpdGUpIHtcblx0dGhpcy5jZW50cmFsU3ByaXRlID0gc3ByaXRlO1xufTtcblxuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5nZXRDZW50cmFsUG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG5cdHJldHVybiB7XG5cdFx0bWFwOiB0aGlzLmNlbnRyYWxTcHJpdGUubWFwUG9zaXRpb24sXG5cdFx0Y2FudmFzOiBbIE1hdGgucm91bmQodGhpcy5jYW52YXMud2lkdGggKiAwLjUpLCBNYXRoLnJvdW5kKHRoaXMuY2FudmFzLmhlaWdodCAqIDAuNSksIDBdXG5cdH07XG59O1xuXG5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLm1hcFBvc2l0aW9uVG9DYW52YXNQb3NpdGlvbiA9IGZ1bmN0aW9uIChwb3NpdGlvbikge1xuXHR2YXIgY2VudHJhbCA9IHRoaXMuZ2V0Q2VudHJhbFBvc2l0aW9uKCk7XG5cdHZhciBjZW50cmFsTWFwUG9zaXRpb24gPSBjZW50cmFsLm1hcDtcblx0dmFyIGNlbnRyYWxDYW52YXNQb3NpdGlvbiA9IGNlbnRyYWwuY2FudmFzO1xuXHR2YXIgbWFwRGlmZmVyZW5jZVggPSBjZW50cmFsTWFwUG9zaXRpb25bMF0gLSBwb3NpdGlvblswXTtcblx0dmFyIG1hcERpZmZlcmVuY2VZID0gY2VudHJhbE1hcFBvc2l0aW9uWzFdIC0gcG9zaXRpb25bMV07XG5cdHJldHVybiBbIGNlbnRyYWxDYW52YXNQb3NpdGlvblswXSAtIG1hcERpZmZlcmVuY2VYLCBjZW50cmFsQ2FudmFzUG9zaXRpb25bMV0gLSBtYXBEaWZmZXJlbmNlWSBdO1xufTtcblxuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5jYW52YXNQb3NpdGlvblRvTWFwUG9zaXRpb24gPSBmdW5jdGlvbiAocG9zaXRpb24pIHtcblx0dmFyIGNlbnRyYWwgPSB0aGlzLmdldENlbnRyYWxQb3NpdGlvbigpO1xuXHR2YXIgY2VudHJhbE1hcFBvc2l0aW9uID0gY2VudHJhbC5tYXA7XG5cdHZhciBjZW50cmFsQ2FudmFzUG9zaXRpb24gPSBjZW50cmFsLmNhbnZhcztcblx0dmFyIG1hcERpZmZlcmVuY2VYID0gY2VudHJhbENhbnZhc1Bvc2l0aW9uWzBdIC0gcG9zaXRpb25bMF07XG5cdHZhciBtYXBEaWZmZXJlbmNlWSA9IGNlbnRyYWxDYW52YXNQb3NpdGlvblsxXSAtIHBvc2l0aW9uWzFdO1xuXHRyZXR1cm4gWyBjZW50cmFsTWFwUG9zaXRpb25bMF0gLSBtYXBEaWZmZXJlbmNlWCwgY2VudHJhbE1hcFBvc2l0aW9uWzFdIC0gbWFwRGlmZmVyZW5jZVkgXTtcbn07XG5cbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuZ2V0Q2VudHJlT2ZWaWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuICh0aGlzLmNhbnZhcy53aWR0aCAvIDIpLmZsb29yKCk7XG59O1xuXG4vLyBZLXBvcyBjYW52YXMgZnVuY3Rpb25zXG5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLmdldE1pZGRsZU9mVmlld3BvcnQgPSBmdW5jdGlvbiAoKSB7XG5cdHJldHVybiAodGhpcy5jYW52YXMuaGVpZ2h0IC8gMikuZmxvb3IoKTtcbn07XG5cbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuZ2V0QmVsb3dWaWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIHRoaXMuY2FudmFzLmhlaWdodC5mbG9vcigpO1xufTtcblxuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5nZXRNYXBCZWxvd1ZpZXdwb3J0ID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgYmVsb3cgPSB0aGlzLmdldEJlbG93Vmlld3BvcnQoKTtcblx0cmV0dXJuIHRoaXMuY2FudmFzUG9zaXRpb25Ub01hcFBvc2l0aW9uKFsgMCwgYmVsb3cgXSlbMV07XG59O1xuXG5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLmdldFJhbmRvbWx5SW5UaGVDZW50cmVPZkNhbnZhcyA9IGZ1bmN0aW9uIChidWZmZXIpIHtcblx0dmFyIG1pbiA9IDA7XG5cdHZhciBtYXggPSB0aGlzLmNhbnZhcy53aWR0aDtcblxuXHRpZiAoYnVmZmVyKSB7XG5cdFx0bWluIC09IGJ1ZmZlcjtcblx0XHRtYXggKz0gYnVmZmVyO1xuXHR9XG5cblx0cmV0dXJuIE51bWJlci5yYW5kb20obWluLCBtYXgpO1xufTtcblxuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5nZXRSYW5kb21seUluVGhlQ2VudHJlT2ZNYXAgPSBmdW5jdGlvbiAoYnVmZmVyKSB7XG5cdHZhciByYW5kb20gPSB0aGlzLmdldFJhbmRvbWx5SW5UaGVDZW50cmVPZkNhbnZhcyhidWZmZXIpO1xuXHRyZXR1cm4gdGhpcy5jYW52YXNQb3NpdGlvblRvTWFwUG9zaXRpb24oWyByYW5kb20sIDAgXSlbMF07XG59O1xuXG5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLmdldFJhbmRvbU1hcFBvc2l0aW9uQmVsb3dWaWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIHhDYW52YXMgPSB0aGlzLmdldFJhbmRvbWx5SW5UaGVDZW50cmVPZkNhbnZhcygpO1xuXHR2YXIgeUNhbnZhcyA9IHRoaXMuZ2V0QmVsb3dWaWV3cG9ydCgpO1xuXHRyZXR1cm4gdGhpcy5jYW52YXNQb3NpdGlvblRvTWFwUG9zaXRpb24oWyB4Q2FudmFzLCB5Q2FudmFzIF0pO1xufTtcblxuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5nZXRSYW5kb21NYXBQb3NpdGlvbkFib3ZlVmlld3BvcnQgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciB4Q2FudmFzID0gdGhpcy5nZXRSYW5kb21seUluVGhlQ2VudHJlT2ZDYW52YXMoKTtcblx0dmFyIHlDYW52YXMgPSB0aGlzLmdldEFib3ZlVmlld3BvcnQoKTtcblx0cmV0dXJuIHRoaXMuY2FudmFzUG9zaXRpb25Ub01hcFBvc2l0aW9uKFsgeENhbnZhcywgeUNhbnZhcyBdKTtcbn07XG5cbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuZ2V0VG9wT2ZWaWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIHRoaXMuY2FudmFzUG9zaXRpb25Ub01hcFBvc2l0aW9uKFsgMCwgMCBdKVsxXTtcbn07XG5cbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuZ2V0QWJvdmVWaWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIDAgLSAodGhpcy5jYW52YXMuaGVpZ2h0IC8gNCkuZmxvb3IoKTtcbn07IiwiLy8gRXh0ZW5kcyBmdW5jdGlvbiBzbyB0aGF0IG5ldy1hYmxlIG9iamVjdHMgY2FuIGJlIGdpdmVuIG5ldyBtZXRob2RzIGVhc2lseVxuRnVuY3Rpb24ucHJvdG90eXBlLm1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmdW5jKSB7XG4gICAgdGhpcy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLy8gV2lsbCByZXR1cm4gdGhlIG9yaWdpbmFsIG1ldGhvZCBvZiBhbiBvYmplY3Qgd2hlbiBpbmhlcml0aW5nIGZyb20gYW5vdGhlclxuT2JqZWN0Lm1ldGhvZCgnc3VwZXJpb3InLCBmdW5jdGlvbiAobmFtZSkge1xuICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICB2YXIgbWV0aG9kID0gdGhhdFtuYW1lXTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBtZXRob2QuYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgICB9O1xufSk7IiwidmFyIFNwcml0ZUFycmF5ID0gcmVxdWlyZSgnLi9zcHJpdGVBcnJheScpO1xudmFyIEV2ZW50ZWRMb29wID0gcmVxdWlyZSgnZXZlbnRlZGxvb3AnKTtcblxuKGZ1bmN0aW9uIChnbG9iYWwpIHtcblx0ZnVuY3Rpb24gR2FtZSAobWFpbkNhbnZhcywgcGxheWVyKSB7XG5cdFx0dmFyIHN0YXRpY09iamVjdHMgPSBuZXcgU3ByaXRlQXJyYXkoKTtcblx0XHR2YXIgbW92aW5nT2JqZWN0cyA9IG5ldyBTcHJpdGVBcnJheSgpO1xuXHRcdHZhciB1aUVsZW1lbnRzID0gbmV3IFNwcml0ZUFycmF5KCk7XG5cdFx0dmFyIGRDb250ZXh0ID0gbWFpbkNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXHRcdHZhciBtb3VzZVggPSBkQ29udGV4dC5nZXRDZW50cmVPZlZpZXdwb3J0KCk7XG5cdFx0dmFyIG1vdXNlWSA9IDA7XG5cdFx0dmFyIHBhdXNlZCA9IGZhbHNlO1xuXHRcdHZhciB0aGF0ID0gdGhpcztcblx0XHR2YXIgYmVmb3JlQ3ljbGVDYWxsYmFja3MgPSBbXTtcblx0XHR2YXIgYWZ0ZXJDeWNsZUNhbGxiYWNrcyA9IFtdO1xuXHRcdHZhciBnYW1lTG9vcCA9IG5ldyBFdmVudGVkTG9vcCgpO1xuXG5cdFx0dGhpcy5hZGRTdGF0aWNPYmplY3QgPSBmdW5jdGlvbiAoc3ByaXRlKSB7XG5cdFx0XHRzdGF0aWNPYmplY3RzLnB1c2goc3ByaXRlKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5hZGRTdGF0aWNPYmplY3RzID0gZnVuY3Rpb24gKHNwcml0ZXMpIHtcblx0XHRcdHNwcml0ZXMuZm9yRWFjaCh0aGlzLmFkZFN0YXRpY09iamVjdC5iaW5kKHRoaXMpKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5hZGRNb3ZpbmdPYmplY3QgPSBmdW5jdGlvbiAobW92aW5nT2JqZWN0LCBtb3ZpbmdPYmplY3RUeXBlKSB7XG5cdFx0XHRpZiAobW92aW5nT2JqZWN0VHlwZSkge1xuXHRcdFx0XHRzdGF0aWNPYmplY3RzLm9uUHVzaChmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRcdFx0aWYgKG9iai5kYXRhICYmIG9iai5kYXRhLmhpdEJlaGF2aW91clttb3ZpbmdPYmplY3RUeXBlXSkge1xuXHRcdFx0XHRcdFx0b2JqLm9uSGl0dGluZyhtb3ZpbmdPYmplY3QsIG9iai5kYXRhLmhpdEJlaGF2aW91clttb3ZpbmdPYmplY3RUeXBlXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdFx0bW92aW5nT2JqZWN0cy5wdXNoKG1vdmluZ09iamVjdCk7XG5cdFx0fTtcblxuXHRcdHRoaXMuYWRkVUlFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcblx0XHRcdHVpRWxlbWVudHMucHVzaChlbGVtZW50KTtcblx0XHR9O1xuXG5cdFx0dGhpcy5iZWZvcmVDeWNsZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXHRcdFx0YmVmb3JlQ3ljbGVDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG5cdFx0fTtcblxuXHRcdHRoaXMuYWZ0ZXJDeWNsZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXHRcdFx0YWZ0ZXJDeWNsZUNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRNb3VzZVggPSBmdW5jdGlvbiAoeCkge1xuXHRcdFx0bW91c2VYID0geDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRNb3VzZVkgPSBmdW5jdGlvbiAoeSkge1xuXHRcdFx0bW91c2VZID0geTtcblx0XHR9O1xuXG5cdFx0cGxheWVyLnNldE1hcFBvc2l0aW9uKDAsIDApO1xuXHRcdHBsYXllci5zZXRNYXBQb3NpdGlvblRhcmdldCgwLCAtMTApO1xuXHRcdGRDb250ZXh0LmZvbGxvd1Nwcml0ZShwbGF5ZXIpO1xuXG5cdFx0dmFyIGludGVydmFsTnVtID0gMDtcblxuXHRcdHRoaXMuY3ljbGUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRiZWZvcmVDeWNsZUNhbGxiYWNrcy5lYWNoKGZ1bmN0aW9uKGMpIHtcblx0XHRcdFx0YygpO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIENsZWFyIGNhbnZhc1xuXHRcdFx0dmFyIG1vdXNlTWFwUG9zaXRpb24gPSBkQ29udGV4dC5jYW52YXNQb3NpdGlvblRvTWFwUG9zaXRpb24oW21vdXNlWCwgbW91c2VZXSk7XG5cblx0XHRcdGlmICghcGxheWVyLmlzSnVtcGluZykge1xuXHRcdFx0XHRwbGF5ZXIuc2V0TWFwUG9zaXRpb25UYXJnZXQobW91c2VNYXBQb3NpdGlvblswXSwgbW91c2VNYXBQb3NpdGlvblsxXSk7XG5cdFx0XHR9XG5cblx0XHRcdGludGVydmFsTnVtKys7XG5cblx0XHRcdHBsYXllci5jeWNsZSgpO1xuXG5cdFx0XHRtb3ZpbmdPYmplY3RzLmVhY2goZnVuY3Rpb24gKG1vdmluZ09iamVjdCwgaSkge1xuXHRcdFx0XHRtb3ZpbmdPYmplY3QuY3ljbGUoZENvbnRleHQpO1xuXHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdHN0YXRpY09iamVjdHMuY3VsbCgpO1xuXHRcdFx0c3RhdGljT2JqZWN0cy5lYWNoKGZ1bmN0aW9uIChzdGF0aWNPYmplY3QsIGkpIHtcblx0XHRcdFx0aWYgKHN0YXRpY09iamVjdC5jeWNsZSkge1xuXHRcdFx0XHRcdHN0YXRpY09iamVjdC5jeWNsZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0dWlFbGVtZW50cy5lYWNoKGZ1bmN0aW9uICh1aUVsZW1lbnQsIGkpIHtcblx0XHRcdFx0aWYgKHVpRWxlbWVudC5jeWNsZSkge1xuXHRcdFx0XHRcdHVpRWxlbWVudC5jeWNsZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0YWZ0ZXJDeWNsZUNhbGxiYWNrcy5lYWNoKGZ1bmN0aW9uKGMpIHtcblx0XHRcdFx0YygpO1xuXHRcdFx0fSk7XG5cdFx0fTtcblxuXHRcdHRoYXQuZHJhdyA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdC8vIENsZWFyIGNhbnZhc1xuXHRcdFx0bWFpbkNhbnZhcy53aWR0aCA9IG1haW5DYW52YXMud2lkdGg7XG5cblx0XHRcdHBsYXllci5kcmF3KGRDb250ZXh0KTtcblxuXHRcdFx0cGxheWVyLmN5Y2xlKCk7XG5cblx0XHRcdG1vdmluZ09iamVjdHMuZWFjaChmdW5jdGlvbiAobW92aW5nT2JqZWN0LCBpKSB7XG5cdFx0XHRcdG1vdmluZ09iamVjdC5kcmF3KGRDb250ZXh0KTtcblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHRzdGF0aWNPYmplY3RzLmVhY2goZnVuY3Rpb24gKHN0YXRpY09iamVjdCwgaSkge1xuXHRcdFx0XHRpZiAoc3RhdGljT2JqZWN0LmRyYXcpIHtcblx0XHRcdFx0XHRzdGF0aWNPYmplY3QuZHJhdyhkQ29udGV4dCwgJ21haW4nKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdHVpRWxlbWVudHMuZWFjaChmdW5jdGlvbiAodWlFbGVtZW50LCBpKSB7XG5cdFx0XHRcdGlmICh1aUVsZW1lbnQuZHJhdykge1xuXHRcdFx0XHRcdHVpRWxlbWVudC5kcmF3KGRDb250ZXh0LCAnbWFpbicpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zdGFydCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGdhbWVMb29wLnN0YXJ0KCk7XG5cdFx0fTtcblxuXHRcdHRoaXMucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRwYXVzZWQgPSB0cnVlO1xuXHRcdFx0Z2FtZUxvb3Auc3RvcCgpO1xuXHRcdH07XG5cblx0XHR0aGlzLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHBhdXNlZDtcblx0XHR9O1xuXG5cdFx0dGhpcy5yZXNldCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHBhdXNlZCA9IGZhbHNlO1xuXHRcdFx0c3RhdGljT2JqZWN0cyA9IG5ldyBTcHJpdGVBcnJheSgpO1xuXHRcdFx0bW92aW5nT2JqZWN0cyA9IG5ldyBTcHJpdGVBcnJheSgpO1xuXHRcdFx0bW91c2VYID0gZENvbnRleHQuZ2V0Q2VudHJlT2ZWaWV3cG9ydCgpO1xuXHRcdFx0bW91c2VZID0gMDtcblx0XHRcdHBsYXllci5yZXNldCgpO1xuXHRcdFx0cGxheWVyLnNldE1hcFBvc2l0aW9uKDAsIDAsIDApO1xuXHRcdFx0dGhpcy5zdGFydCgpO1xuXHRcdH0uYmluZCh0aGlzKTtcblxuXHRcdGdhbWVMb29wLm9uKCcyMCcsIHRoaXMuY3ljbGUpO1xuXHRcdGdhbWVMb29wLm9uKCcyMCcsIHRoaXMuZHJhdyk7XG5cdH1cblxuXHRnbG9iYWwuZ2FtZSA9IEdhbWU7XG59KSggdGhpcyApO1xuXG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHRoaXMuZ2FtZTtcbn0iLCIvLyBDcmVhdGVzIGEgcmFuZG9tIElEIHN0cmluZ1xuKGZ1bmN0aW9uKGdsb2JhbCkge1xuICAgIGZ1bmN0aW9uIGd1aWQgKClcbiAgICB7XG4gICAgICAgIHZhciBTNCA9IGZ1bmN0aW9uICgpXG4gICAgICAgIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKFxuICAgICAgICAgICAgICAgICAgICBNYXRoLnJhbmRvbSgpICogMHgxMDAwMCAvKiA2NTUzNiAqL1xuICAgICAgICAgICAgICAgICkudG9TdHJpbmcoMTYpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgUzQoKSArIFM0KCkgKyBcIi1cIiArXG4gICAgICAgICAgICAgICAgUzQoKSArIFwiLVwiICtcbiAgICAgICAgICAgICAgICBTNCgpICsgXCItXCIgK1xuICAgICAgICAgICAgICAgIFM0KCkgKyBcIi1cIiArXG4gICAgICAgICAgICAgICAgUzQoKSArIFM0KCkgKyBTNCgpXG4gICAgICAgICAgICApO1xuICAgIH1cbiAgICBnbG9iYWwuZ3VpZCA9IGd1aWQ7XG59KSh0aGlzKTtcblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSB0aGlzLmd1aWQ7XG59IiwiZnVuY3Rpb24gSW5mb0JveChkYXRhKSB7XG5cdHZhciB0aGF0ID0gdGhpcztcblxuXHR0aGF0LmxpbmVzID0gZGF0YS5pbml0aWFsTGluZXM7XG5cblx0dGhhdC50b3AgPSBkYXRhLnBvc2l0aW9uLnRvcDtcblx0dGhhdC5yaWdodCA9IGRhdGEucG9zaXRpb24ucmlnaHQ7XG5cdHRoYXQuYm90dG9tID0gZGF0YS5wb3NpdGlvbi5ib3R0b207XG5cdHRoYXQubGVmdCA9IGRhdGEucG9zaXRpb24ubGVmdDtcblxuXHR0aGF0LndpZHRoID0gZGF0YS53aWR0aDtcblx0dGhhdC5oZWlnaHQgPSBkYXRhLmhlaWdodDtcblxuXHR0aGF0LnNldExpbmVzID0gZnVuY3Rpb24gKGxpbmVzKSB7XG5cdFx0dGhhdC5saW5lcyA9IGxpbmVzO1xuXHR9O1xuXG5cdHRoYXQuZHJhdyA9IGZ1bmN0aW9uIChkQ29udGV4dCkge1xuXHRcdGRDb250ZXh0LmZvbnQgPSAnMTFweCBtb25vc3BhY2UnO1xuXHRcdHZhciB5T2Zmc2V0ID0gMDtcblx0XHR0aGF0LmxpbmVzLmVhY2goZnVuY3Rpb24gKGxpbmUpIHtcblx0XHRcdHZhciBmb250U2l6ZSA9ICtkQ29udGV4dC5mb250LnNsaWNlKDAsMik7XG5cdFx0XHR2YXIgdGV4dFdpZHRoID0gZENvbnRleHQubWVhc3VyZVRleHQobGluZSkud2lkdGg7XG5cdFx0XHR2YXIgdGV4dEhlaWdodCA9IGZvbnRTaXplICogMS41O1xuXHRcdFx0dmFyIHhQb3MsIHlQb3M7XG5cdFx0XHRpZiAodGhhdC50b3ApIHtcblx0XHRcdFx0eVBvcyA9IHRoYXQudG9wICsgeU9mZnNldDtcblx0XHRcdH0gZWxzZSBpZiAodGhhdC5ib3R0b20pIHtcblx0XHRcdFx0eVBvcyA9IGRDb250ZXh0LmNhbnZhcy5oZWlnaHQgLSB0aGF0LnRvcCAtIHRleHRIZWlnaHQgKyB5T2Zmc2V0O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhhdC5yaWdodCkge1xuXHRcdFx0XHR4UG9zID0gZENvbnRleHQuY2FudmFzLndpZHRoIC0gdGhhdC5yaWdodCAtIHRleHRXaWR0aDtcblx0XHRcdH0gZWxzZSBpZiAodGhhdC5sZWZ0KSB7XG5cdFx0XHRcdHhQb3MgPSB0aGF0LmxlZnQ7XG5cdFx0XHR9XG5cblx0XHRcdHlPZmZzZXQgKz0gdGV4dEhlaWdodDtcblxuXG5cdFx0XHRkQ29udGV4dC5maWxsVGV4dChsaW5lLCB4UG9zLCB5UG9zKTtcblx0XHR9KTtcblx0fTtcblxuXHRyZXR1cm4gdGhhdDtcbn1cblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XG5cdG1vZHVsZS5leHBvcnRzID0gSW5mb0JveDtcbn1cbiIsImZ1bmN0aW9uIGlzTW9iaWxlRGV2aWNlKCkge1xuXHRpZihuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpIHx8XG5cdFx0bmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvd2ViT1MvaSkgfHxcblx0XHRuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgfHxcblx0XHRuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGFkL2kpIHx8XG5cdFx0bmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBvZC9pKSB8fFxuXHRcdG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0JsYWNrQmVycnkvaSkgfHxcblx0XHRuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9XaW5kb3dzIFBob25lL2kpXG5cdCkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdGVsc2Uge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTW9iaWxlRGV2aWNlOyIsInZhciBTcHJpdGUgPSByZXF1aXJlKCcuL3Nwcml0ZScpO1xuXG4oZnVuY3Rpb24oZ2xvYmFsKSB7XG5cdGZ1bmN0aW9uIE1vbnN0ZXIoZGF0YSkge1xuXHRcdHZhciB0aGF0ID0gbmV3IFNwcml0ZShkYXRhKTtcblx0XHR2YXIgc3VwZXJfZHJhdyA9IHRoYXQuc3VwZXJpb3IoJ2RyYXcnKTtcblx0XHR2YXIgc3ByaXRlVmVyc2lvbiA9IDE7XG5cdFx0dmFyIGVhdGluZ1N0YWdlID0gMDtcblx0XHR2YXIgc3RhbmRhcmRTcGVlZCA9IDY7XG5cblx0XHR0aGF0LmlzRWF0aW5nID0gZmFsc2U7XG5cdFx0dGhhdC5pc0Z1bGwgPSBmYWxzZTtcblx0XHR0aGF0LnNldFNwZWVkKHN0YW5kYXJkU3BlZWQpO1xuXG5cdFx0dGhhdC5kcmF3ID0gZnVuY3Rpb24oZENvbnRleHQpIHtcblx0XHRcdHZhciBzcHJpdGVQYXJ0VG9Vc2UgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHZhciB4RGlmZiA9IHRoYXQubW92aW5nVG93YXJkWzBdIC0gdGhhdC5jYW52YXNYO1xuXG5cdFx0XHRcdGlmICh0aGF0LmlzRWF0aW5nKSB7XG5cdFx0XHRcdFx0cmV0dXJuICdlYXRpbmcnICsgZWF0aW5nU3RhZ2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoc3ByaXRlVmVyc2lvbiArIDAuMSA+IDIpIHtcblx0XHRcdFx0XHRzcHJpdGVWZXJzaW9uID0gMC4xO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHNwcml0ZVZlcnNpb24gKz0gMC4xO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh4RGlmZiA+PSAwKSB7XG5cdFx0XHRcdFx0cmV0dXJuICdzRWFzdCcgKyBNYXRoLmNlaWwoc3ByaXRlVmVyc2lvbik7XG5cdFx0XHRcdH0gZWxzZSBpZiAoeERpZmYgPCAwKSB7XG5cdFx0XHRcdFx0cmV0dXJuICdzV2VzdCcgKyBNYXRoLmNlaWwoc3ByaXRlVmVyc2lvbik7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRcdHJldHVybiBzdXBlcl9kcmF3KGRDb250ZXh0LCBzcHJpdGVQYXJ0VG9Vc2UoKSk7XG5cdFx0fTtcblxuXHRcdGZ1bmN0aW9uIHN0YXJ0RWF0aW5nICh3aGVuRG9uZSkge1xuXHRcdFx0ZWF0aW5nU3RhZ2UgKz0gMTtcblx0XHRcdHRoYXQuaXNFYXRpbmcgPSB0cnVlO1xuXHRcdFx0dGhhdC5pc01vdmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKGVhdGluZ1N0YWdlIDwgNikge1xuXHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRzdGFydEVhdGluZyh3aGVuRG9uZSk7XG5cdFx0XHRcdH0sIDMwMCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlYXRpbmdTdGFnZSA9IDA7XG5cdFx0XHRcdHRoYXQuaXNFYXRpbmcgPSBmYWxzZTtcblx0XHRcdFx0dGhhdC5pc01vdmluZyA9IHRydWU7XG5cdFx0XHRcdHdoZW5Eb25lKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhhdC5zdGFydEVhdGluZyA9IHN0YXJ0RWF0aW5nO1xuXG5cdFx0cmV0dXJuIHRoYXQ7XG5cdH1cblxuXHRnbG9iYWwubW9uc3RlciA9IE1vbnN0ZXI7XG59KSggdGhpcyApO1xuXG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHRoaXMubW9uc3Rlcjtcbn0iLCIvLyBBdm9pZCBgY29uc29sZWAgZXJyb3JzIGluIGJyb3dzZXJzIHRoYXQgbGFjayBhIGNvbnNvbGUuXG4oZnVuY3Rpb24oKSB7XG4gICAgdmFyIG1ldGhvZDtcbiAgICB2YXIgbm9vcCA9IGZ1bmN0aW9uIG5vb3AoKSB7fTtcbiAgICB2YXIgbWV0aG9kcyA9IFtcbiAgICAgICAgJ2Fzc2VydCcsICdjbGVhcicsICdjb3VudCcsICdkZWJ1ZycsICdkaXInLCAnZGlyeG1sJywgJ2Vycm9yJyxcbiAgICAgICAgJ2V4Y2VwdGlvbicsICdncm91cCcsICdncm91cENvbGxhcHNlZCcsICdncm91cEVuZCcsICdpbmZvJywgJ2xvZycsXG4gICAgICAgICdtYXJrVGltZWxpbmUnLCAncHJvZmlsZScsICdwcm9maWxlRW5kJywgJ3RhYmxlJywgJ3RpbWUnLCAndGltZUVuZCcsXG4gICAgICAgICd0aW1lU3RhbXAnLCAndHJhY2UnLCAnd2FybidcbiAgICBdO1xuICAgIHZhciBsZW5ndGggPSBtZXRob2RzLmxlbmd0aDtcbiAgICB2YXIgY29uc29sZSA9ICh3aW5kb3cuY29uc29sZSA9IHdpbmRvdy5jb25zb2xlIHx8IHt9KTtcblxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICBtZXRob2QgPSBtZXRob2RzW2xlbmd0aF07XG5cbiAgICAgICAgLy8gT25seSBzdHViIHVuZGVmaW5lZCBtZXRob2RzLlxuICAgICAgICBpZiAoIWNvbnNvbGVbbWV0aG9kXSkge1xuICAgICAgICAgICAgY29uc29sZVttZXRob2RdID0gbm9vcDtcbiAgICAgICAgfVxuICAgIH1cbn0oKSk7IiwidmFyIFNwcml0ZSA9IHJlcXVpcmUoJy4vc3ByaXRlJyk7XG5pZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0bmF2aWdhdG9yLnZpYnJhdGUgPSBuYXZpZ2F0b3IudmlicmF0ZSB8fFxuXHRcdG5hdmlnYXRvci53ZWJraXRWaWJyYXRlIHx8XG5cdFx0bmF2aWdhdG9yLm1velZpYnJhdGUgfHxcblx0XHRuYXZpZ2F0b3IubXNWaWJyYXRlO1xufSBlbHNlIHtcblx0bmF2aWdhdG9yID0ge1xuXHRcdHZpYnJhdGU6IGZhbHNlXG5cdH07XG59XG5cbihmdW5jdGlvbihnbG9iYWwpIHtcblx0ZnVuY3Rpb24gU2tpZXIoZGF0YSkge1xuXHRcdHZhciBkaXNjcmV0ZURpcmVjdGlvbnMgPSB7XG5cdFx0XHQnd2VzdCc6IDI3MCxcblx0XHRcdCd3c1dlc3QnOiAyNDAsXG5cdFx0XHQnc1dlc3QnOiAxOTUsXG5cdFx0XHQnc291dGgnOiAxODAsXG5cdFx0XHQnc0Vhc3QnOiAxNjUsXG5cdFx0XHQnZXNFYXN0JzogMTIwLFxuXHRcdFx0J2Vhc3QnOiA5MFxuXHRcdH07XG5cdFx0dmFyIHRoYXQgPSBuZXcgU3ByaXRlKGRhdGEpO1xuXHRcdHZhciBzdXAgPSB7XG5cdFx0XHRkcmF3OiB0aGF0LnN1cGVyaW9yKCdkcmF3JyksXG5cdFx0XHRjeWNsZTogdGhhdC5zdXBlcmlvcignY3ljbGUnKSxcblx0XHRcdGdldFNwZWVkWDogdGhhdC5zdXBlcmlvcignZ2V0U3BlZWRYJyksXG5cdFx0XHRnZXRTcGVlZFk6IHRoYXQuc3VwZXJpb3IoJ2dldFNwZWVkWScpLFxuXHRcdFx0aGl0czogdGhhdC5zdXBlcmlvcignaGl0cycpXG5cdFx0fTtcblx0XHR2YXIgZGlyZWN0aW9ucyA9IHtcblx0XHRcdGVzRWFzdDogZnVuY3Rpb24oeERpZmYpIHsgcmV0dXJuIHhEaWZmID4gMzAwOyB9LFxuXHRcdFx0c0Vhc3Q6IGZ1bmN0aW9uKHhEaWZmKSB7IHJldHVybiB4RGlmZiA+IDc1OyB9LFxuXHRcdFx0d3NXZXN0OiBmdW5jdGlvbih4RGlmZikgeyByZXR1cm4geERpZmYgPCAtMzAwOyB9LFxuXHRcdFx0c1dlc3Q6IGZ1bmN0aW9uKHhEaWZmKSB7IHJldHVybiB4RGlmZiA8IC03NTsgfVxuXHRcdH07XG5cblx0XHR2YXIgY2FuY2VsYWJsZVN0YXRlVGltZW91dDtcblx0XHR2YXIgY2FuY2VsYWJsZVN0YXRlSW50ZXJ2YWw7XG5cblx0XHR2YXIgY2FuU3BlZWRCb29zdCA9IHRydWU7XG5cblx0XHR2YXIgb2JzdGFjbGVzSGl0ID0gW107XG5cdFx0dmFyIHBpeGVsc1RyYXZlbGxlZCA9IDA7XG5cdFx0dmFyIHN0YW5kYXJkU3BlZWQgPSA1O1xuXHRcdHZhciBib29zdE11bHRpcGxpZXIgPSAyO1xuXHRcdHZhciB0dXJuRWFzZUN5Y2xlcyA9IDcwO1xuXHRcdHZhciBzcGVlZFggPSAwO1xuXHRcdHZhciBzcGVlZFhGYWN0b3IgPSAwO1xuXHRcdHZhciBzcGVlZFkgPSAwO1xuXHRcdHZhciBzcGVlZFlGYWN0b3IgPSAxO1xuXHRcdHZhciB0cmlja1N0ZXAgPSAwOyAvLyBUaGVyZSBhcmUgdGhyZWUgb2YgdGhlc2VcblxuXHRcdHRoYXQuaXNNb3ZpbmcgPSB0cnVlO1xuXHRcdHRoYXQuaGFzQmVlbkhpdCA9IGZhbHNlO1xuXHRcdHRoYXQuaXNKdW1waW5nID0gZmFsc2U7XG5cdFx0dGhhdC5pc1BlcmZvcm1pbmdUcmljayA9IGZhbHNlO1xuXHRcdHRoYXQub25IaXRPYnN0YWNsZUNiID0gZnVuY3Rpb24oKSB7fTtcblx0XHR0aGF0LnNldFNwZWVkKHN0YW5kYXJkU3BlZWQpO1xuXG5cdFx0dGhhdC5yZXNldCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdG9ic3RhY2xlc0hpdCA9IFtdO1xuXHRcdFx0cGl4ZWxzVHJhdmVsbGVkID0gMDtcblx0XHRcdHRoYXQuaXNNb3ZpbmcgPSB0cnVlO1xuXHRcdFx0dGhhdC5oYXNCZWVuSGl0ID0gZmFsc2U7XG5cdFx0XHRjYW5TcGVlZEJvb3N0ID0gdHJ1ZTtcblx0XHRcdHNldE5vcm1hbCgpO1xuXHRcdH07XG5cblx0XHRmdW5jdGlvbiBzZXROb3JtYWwoKSB7XG5cdFx0XHR0aGF0LnNldFNwZWVkKHN0YW5kYXJkU3BlZWQpO1xuXHRcdFx0dGhhdC5pc01vdmluZyA9IHRydWU7XG5cdFx0XHR0aGF0Lmhhc0JlZW5IaXQgPSBmYWxzZTtcblx0XHRcdHRoYXQuaXNKdW1waW5nID0gZmFsc2U7XG5cdFx0XHR0aGF0LmlzUGVyZm9ybWluZ1RyaWNrID0gZmFsc2U7XG5cdFx0XHRpZiAoY2FuY2VsYWJsZVN0YXRlSW50ZXJ2YWwpIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbChjYW5jZWxhYmxlU3RhdGVJbnRlcnZhbCk7XG5cdFx0XHR9XG5cdFx0XHR0aGF0LnNldE1hcFBvc2l0aW9uKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAwKTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBzZXRDcmFzaGVkKCkge1xuXHRcdFx0dGhhdC5pc01vdmluZyA9IGZhbHNlO1xuXHRcdFx0dGhhdC5oYXNCZWVuSGl0ID0gdHJ1ZTtcblx0XHRcdHRoYXQuaXNKdW1waW5nID0gZmFsc2U7XG5cdFx0XHR0aGF0LmlzUGVyZm9ybWluZ1RyaWNrID0gZmFsc2U7XG5cdFx0XHRpZiAoY2FuY2VsYWJsZVN0YXRlSW50ZXJ2YWwpIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbChjYW5jZWxhYmxlU3RhdGVJbnRlcnZhbCk7XG5cdFx0XHR9XG5cdFx0XHR0aGF0LnNldE1hcFBvc2l0aW9uKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAwKTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBzZXRKdW1waW5nKCkge1xuXHRcdFx0dmFyIGN1cnJlbnRTcGVlZCA9IHRoYXQuZ2V0U3BlZWQoKTtcblx0XHRcdHRoYXQuc2V0U3BlZWQoY3VycmVudFNwZWVkICsgMik7XG5cdFx0XHR0aGF0LnNldFNwZWVkWShjdXJyZW50U3BlZWQgKyAyKTtcblx0XHRcdHRoYXQuaXNNb3ZpbmcgPSB0cnVlO1xuXHRcdFx0dGhhdC5oYXNCZWVuSGl0ID0gZmFsc2U7XG5cdFx0XHR0aGF0LmlzSnVtcGluZyA9IHRydWU7XG5cdFx0XHR0aGF0LnNldE1hcFBvc2l0aW9uKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAxKTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBnZXREaXNjcmV0ZURpcmVjdGlvbigpIHtcblx0XHRcdGlmICh0aGF0LmRpcmVjdGlvbikge1xuXHRcdFx0XHRpZiAodGhhdC5kaXJlY3Rpb24gPD0gOTApIHtcblx0XHRcdFx0XHRyZXR1cm4gJ2Vhc3QnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRoYXQuZGlyZWN0aW9uID4gOTAgJiYgdGhhdC5kaXJlY3Rpb24gPCAxNTApIHtcblx0XHRcdFx0XHRyZXR1cm4gJ2VzRWFzdCc7XG5cdFx0XHRcdH0gZWxzZSBpZiAodGhhdC5kaXJlY3Rpb24gPj0gMTUwICYmIHRoYXQuZGlyZWN0aW9uIDwgMTgwKSB7XG5cdFx0XHRcdFx0cmV0dXJuICdzRWFzdCc7XG5cdFx0XHRcdH0gZWxzZSBpZiAodGhhdC5kaXJlY3Rpb24gPT09IDE4MCkge1xuXHRcdFx0XHRcdHJldHVybiAnc291dGgnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRoYXQuZGlyZWN0aW9uID4gMTgwICYmIHRoYXQuZGlyZWN0aW9uIDw9IDIxMCkge1xuXHRcdFx0XHRcdHJldHVybiAnc1dlc3QnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRoYXQuZGlyZWN0aW9uID4gMjEwICYmIHRoYXQuZGlyZWN0aW9uIDwgMjcwKSB7XG5cdFx0XHRcdFx0cmV0dXJuICd3c1dlc3QnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRoYXQuZGlyZWN0aW9uID49IDI3MCkge1xuXHRcdFx0XHRcdHJldHVybiAnd2VzdCc7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuICdzb3V0aCc7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHZhciB4RGlmZiA9IHRoYXQubW92aW5nVG93YXJkWzBdIC0gdGhhdC5tYXBQb3NpdGlvblswXTtcblx0XHRcdFx0dmFyIHlEaWZmID0gdGhhdC5tb3ZpbmdUb3dhcmRbMV0gLSB0aGF0Lm1hcFBvc2l0aW9uWzFdO1xuXHRcdFx0XHRpZiAoeURpZmYgPD0gMCkge1xuXHRcdFx0XHRcdGlmICh4RGlmZiA+IDApIHtcblx0XHRcdFx0XHRcdHJldHVybiAnZWFzdCc7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHJldHVybiAnd2VzdCc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGRpcmVjdGlvbnMuZXNFYXN0KHhEaWZmKSkge1xuXHRcdFx0XHRcdHJldHVybiAnZXNFYXN0Jztcblx0XHRcdFx0fSBlbHNlIGlmIChkaXJlY3Rpb25zLnNFYXN0KHhEaWZmKSkge1xuXHRcdFx0XHRcdHJldHVybiAnc0Vhc3QnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGRpcmVjdGlvbnMud3NXZXN0KHhEaWZmKSkge1xuXHRcdFx0XHRcdHJldHVybiAnd3NXZXN0Jztcblx0XHRcdFx0fSBlbHNlIGlmIChkaXJlY3Rpb25zLnNXZXN0KHhEaWZmKSkge1xuXHRcdFx0XHRcdHJldHVybiAnc1dlc3QnO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gJ3NvdXRoJztcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBzZXREaXNjcmV0ZURpcmVjdGlvbihkKSB7XG5cdFx0XHRpZiAoZGlzY3JldGVEaXJlY3Rpb25zW2RdKSB7XG5cdFx0XHRcdHRoYXQuc2V0RGlyZWN0aW9uKGRpc2NyZXRlRGlyZWN0aW9uc1tkXSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChkID09PSAnd2VzdCcgfHwgZCA9PT0gJ2Vhc3QnKSB7XG5cdFx0XHRcdHRoYXQuaXNNb3ZpbmcgPSBmYWxzZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoYXQuaXNNb3ZpbmcgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGdldEJlaW5nRWF0ZW5TcHJpdGUoKSB7XG5cdFx0XHRyZXR1cm4gJ2JsYW5rJztcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBnZXRKdW1waW5nU3ByaXRlKCkge1xuXHRcdFx0cmV0dXJuICdqdW1waW5nJztcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBnZXRUcmlja1Nwcml0ZSgpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdUcmljayBzdGVwIGlzJywgdHJpY2tTdGVwKTtcblx0XHRcdGlmICh0cmlja1N0ZXAgPT09IDApIHtcblx0XHRcdFx0cmV0dXJuICdqdW1waW5nJztcblx0XHRcdH0gZWxzZSBpZiAodHJpY2tTdGVwID09PSAxKSB7XG5cdFx0XHRcdHJldHVybiAnc29tZXJzYXVsdDEnO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuICdzb21lcnNhdWx0Mic7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhhdC5zdG9wID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKHRoYXQuZGlyZWN0aW9uID4gMTgwKSB7XG5cdFx0XHRcdHNldERpc2NyZXRlRGlyZWN0aW9uKCd3ZXN0Jyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZXREaXNjcmV0ZURpcmVjdGlvbignZWFzdCcpO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGF0LnR1cm5FYXN0ID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIGRpc2NyZXRlRGlyZWN0aW9uID0gZ2V0RGlzY3JldGVEaXJlY3Rpb24oKTtcblxuXHRcdFx0c3dpdGNoIChkaXNjcmV0ZURpcmVjdGlvbikge1xuXHRcdFx0XHRjYXNlICd3ZXN0Jzpcblx0XHRcdFx0XHRzZXREaXNjcmV0ZURpcmVjdGlvbignd3NXZXN0Jyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ3dzV2VzdCc6XG5cdFx0XHRcdFx0c2V0RGlzY3JldGVEaXJlY3Rpb24oJ3NXZXN0Jyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ3NXZXN0Jzpcblx0XHRcdFx0XHRzZXREaXNjcmV0ZURpcmVjdGlvbignc291dGgnKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnc291dGgnOlxuXHRcdFx0XHRcdHNldERpc2NyZXRlRGlyZWN0aW9uKCdzRWFzdCcpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdzRWFzdCc6XG5cdFx0XHRcdFx0c2V0RGlzY3JldGVEaXJlY3Rpb24oJ2VzRWFzdCcpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdlc0Vhc3QnOlxuXHRcdFx0XHRcdHNldERpc2NyZXRlRGlyZWN0aW9uKCdlYXN0Jyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0c2V0RGlzY3JldGVEaXJlY3Rpb24oJ3NvdXRoJyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoYXQudHVybldlc3QgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgZGlzY3JldGVEaXJlY3Rpb24gPSBnZXREaXNjcmV0ZURpcmVjdGlvbigpO1xuXG5cdFx0XHRzd2l0Y2ggKGRpc2NyZXRlRGlyZWN0aW9uKSB7XG5cdFx0XHRcdGNhc2UgJ2Vhc3QnOlxuXHRcdFx0XHRcdHNldERpc2NyZXRlRGlyZWN0aW9uKCdlc0Vhc3QnKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnZXNFYXN0Jzpcblx0XHRcdFx0XHRzZXREaXNjcmV0ZURpcmVjdGlvbignc0Vhc3QnKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnc0Vhc3QnOlxuXHRcdFx0XHRcdHNldERpc2NyZXRlRGlyZWN0aW9uKCdzb3V0aCcpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdzb3V0aCc6XG5cdFx0XHRcdFx0c2V0RGlzY3JldGVEaXJlY3Rpb24oJ3NXZXN0Jyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ3NXZXN0Jzpcblx0XHRcdFx0XHRzZXREaXNjcmV0ZURpcmVjdGlvbignd3NXZXN0Jyk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ3dzV2VzdCc6XG5cdFx0XHRcdFx0c2V0RGlzY3JldGVEaXJlY3Rpb24oJ3dlc3QnKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRzZXREaXNjcmV0ZURpcmVjdGlvbignc291dGgnKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhhdC5zdGVwV2VzdCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoYXQubWFwUG9zaXRpb25bMF0gLT0gdGhhdC5zcGVlZCAqIDI7XG5cdFx0fTtcblxuXHRcdHRoYXQuc3RlcEVhc3QgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR0aGF0Lm1hcFBvc2l0aW9uWzBdICs9IHRoYXQuc3BlZWQgKiAyO1xuXHRcdH07XG5cblx0XHR0aGF0LnNldE1hcFBvc2l0aW9uVGFyZ2V0ID0gZnVuY3Rpb24gKHgsIHkpIHtcblx0XHRcdGlmICh0aGF0Lmhhc0JlZW5IaXQpIHJldHVybjtcblxuXHRcdFx0aWYgKE1hdGguYWJzKHRoYXQubWFwUG9zaXRpb25bMF0gLSB4KSA8PSA3NSkge1xuXHRcdFx0XHR4ID0gdGhhdC5tYXBQb3NpdGlvblswXTtcblx0XHRcdH1cblxuXHRcdFx0dGhhdC5tb3ZpbmdUb3dhcmQgPSBbIHgsIHkgXTtcblxuXHRcdFx0Ly8gdGhhdC5yZXNldERpcmVjdGlvbigpO1xuXHRcdH07XG5cblx0XHR0aGF0LnN0YXJ0TW92aW5nSWZQb3NzaWJsZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmICghdGhhdC5oYXNCZWVuSGl0ICYmICF0aGF0LmlzQmVpbmdFYXRlbikge1xuXHRcdFx0XHR0aGF0LmlzTW92aW5nID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhhdC5zZXRUdXJuRWFzZUN5Y2xlcyA9IGZ1bmN0aW9uIChjKSB7XG5cdFx0XHR0dXJuRWFzZUN5Y2xlcyA9IGM7XG5cdFx0fTtcblxuXHRcdHRoYXQuZ2V0UGl4ZWxzVHJhdmVsbGVkRG93bk1vdW50YWluID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHBpeGVsc1RyYXZlbGxlZDtcblx0XHR9O1xuXG5cdFx0dGhhdC5yZXNldFNwZWVkID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhhdC5zZXRTcGVlZChzdGFuZGFyZFNwZWVkKTtcblx0XHR9O1xuXG5cdFx0dGhhdC5jeWNsZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmICggdGhhdC5nZXRTcGVlZFgoKSA8PSAwICYmIHRoYXQuZ2V0U3BlZWRZKCkgPD0gMCApIHtcblx0XHRcdFx0XHRcdHRoYXQuaXNNb3ZpbmcgPSBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmICh0aGF0LmlzTW92aW5nKSB7XG5cdFx0XHRcdHBpeGVsc1RyYXZlbGxlZCArPSB0aGF0LnNwZWVkO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhhdC5pc0p1bXBpbmcpIHtcblx0XHRcdFx0dGhhdC5zZXRNYXBQb3NpdGlvblRhcmdldCh1bmRlZmluZWQsIHRoYXQubWFwUG9zaXRpb25bMV0gKyB0aGF0LmdldFNwZWVkKCkpO1xuXHRcdFx0fVxuXG5cdFx0XHRzdXAuY3ljbGUoKTtcblx0XHRcdFxuXHRcdFx0dGhhdC5jaGVja0hpdHRhYmxlT2JqZWN0cygpO1xuXHRcdH07XG5cblx0XHR0aGF0LmRyYXcgPSBmdW5jdGlvbihkQ29udGV4dCkge1xuXHRcdFx0dmFyIHNwcml0ZVBhcnRUb1VzZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0aWYgKHRoYXQuaXNCZWluZ0VhdGVuKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGdldEJlaW5nRWF0ZW5TcHJpdGUoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh0aGF0LmlzSnVtcGluZykge1xuXHRcdFx0XHRcdGlmICh0aGF0LmlzUGVyZm9ybWluZ1RyaWNrKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZ2V0VHJpY2tTcHJpdGUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIGdldEp1bXBpbmdTcHJpdGUoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh0aGF0Lmhhc0JlZW5IaXQpIHtcblx0XHRcdFx0XHRyZXR1cm4gJ2hpdCc7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZ2V0RGlzY3JldGVEaXJlY3Rpb24oKTtcblx0XHRcdH07XG5cblx0XHRcdHJldHVybiBzdXAuZHJhdyhkQ29udGV4dCwgc3ByaXRlUGFydFRvVXNlKCkpO1xuXHRcdH07XG5cblx0XHR0aGF0LmhpdHMgPSBmdW5jdGlvbiAob2JzKSB7XG5cdFx0XHRpZiAob2JzdGFjbGVzSGl0LmluZGV4T2Yob2JzLmlkKSAhPT0gLTEpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIW9icy5vY2N1cGllc1pJbmRleCh0aGF0Lm1hcFBvc2l0aW9uWzJdKSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzdXAuaGl0cyhvYnMpKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblxuXHRcdHRoYXQuc3BlZWRCb29zdCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHZhciBvcmlnaW5hbFNwZWVkID0gdGhhdC5zcGVlZDtcblx0XHRcdGlmIChjYW5TcGVlZEJvb3N0KSB7XG5cdFx0XHRcdGNhblNwZWVkQm9vc3QgPSBmYWxzZTtcblx0XHRcdFx0dGhhdC5zZXRTcGVlZCh0aGF0LnNwZWVkICogYm9vc3RNdWx0aXBsaWVyKTtcblx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dGhhdC5zZXRTcGVlZChvcmlnaW5hbFNwZWVkKTtcblx0XHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdGNhblNwZWVkQm9vc3QgPSB0cnVlO1xuXHRcdFx0XHRcdH0sIDEwMDAwKTtcblx0XHRcdFx0fSwgMjAwMCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoYXQuYXR0ZW1wdFRyaWNrID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKHRoYXQuaXNKdW1waW5nKSB7XG5cdFx0XHRcdHRoYXQuaXNQZXJmb3JtaW5nVHJpY2sgPSB0cnVlO1xuXHRcdFx0XHRjYW5jZWxhYmxlU3RhdGVJbnRlcnZhbCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRpZiAodHJpY2tTdGVwID49IDIpIHtcblx0XHRcdFx0XHRcdHRyaWNrU3RlcCA9IDA7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRyaWNrU3RlcCArPSAxO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSwgMzAwKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhhdC5nZXRTdGFuZGFyZFNwZWVkID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHN0YW5kYXJkU3BlZWQ7XG5cdFx0fTtcblxuXHRcdGZ1bmN0aW9uIGVhc2VTcGVlZFRvVGFyZ2V0VXNpbmdGYWN0b3Ioc3AsIHRhcmdldFNwZWVkLCBmKSB7XG5cdFx0XHRpZiAoZiA9PT0gMCB8fCBmID09PSAxKSB7XG5cdFx0XHRcdHJldHVybiB0YXJnZXRTcGVlZDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNwIDwgdGFyZ2V0U3BlZWQpIHtcblx0XHRcdFx0c3AgKz0gdGhhdC5nZXRTcGVlZCgpICogKGYgLyB0dXJuRWFzZUN5Y2xlcyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzcCA+IHRhcmdldFNwZWVkKSB7XG5cdFx0XHRcdHNwIC09IHRoYXQuZ2V0U3BlZWQoKSAqIChmIC8gdHVybkVhc2VDeWNsZXMpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc3A7XG5cdFx0fVxuXG5cdFx0dGhhdC5nZXRTcGVlZFggPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRpZiAoZ2V0RGlzY3JldGVEaXJlY3Rpb24oKSA9PT0gJ2VzRWFzdCcgfHwgZ2V0RGlzY3JldGVEaXJlY3Rpb24oKSA9PT0gJ3dzV2VzdCcpIHtcblx0XHRcdFx0c3BlZWRYRmFjdG9yID0gMC41O1xuXHRcdFx0XHRzcGVlZFggPSBlYXNlU3BlZWRUb1RhcmdldFVzaW5nRmFjdG9yKHNwZWVkWCwgdGhhdC5nZXRTcGVlZCgpICogc3BlZWRYRmFjdG9yLCBzcGVlZFhGYWN0b3IpO1xuXG5cdFx0XHRcdHJldHVybiBzcGVlZFg7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChnZXREaXNjcmV0ZURpcmVjdGlvbigpID09PSAnc0Vhc3QnIHx8IGdldERpc2NyZXRlRGlyZWN0aW9uKCkgPT09ICdzV2VzdCcpIHtcblx0XHRcdFx0c3BlZWRYRmFjdG9yID0gMC4zMztcblx0XHRcdFx0c3BlZWRYID0gZWFzZVNwZWVkVG9UYXJnZXRVc2luZ0ZhY3RvcihzcGVlZFgsIHRoYXQuZ2V0U3BlZWQoKSAqIHNwZWVkWEZhY3Rvciwgc3BlZWRYRmFjdG9yKTtcblxuXHRcdFx0XHRyZXR1cm4gc3BlZWRYO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTbyBpdCBtdXN0IGJlIHNvdXRoXG5cblx0XHRcdHNwZWVkWCA9IGVhc2VTcGVlZFRvVGFyZ2V0VXNpbmdGYWN0b3Ioc3BlZWRYLCAwLCBzcGVlZFhGYWN0b3IpO1xuXG5cdFx0XHRyZXR1cm4gc3BlZWRYO1xuXHRcdH07XG5cblx0XHR0aGF0LnNldFNwZWVkWSA9IGZ1bmN0aW9uKHN5KSB7XG5cdFx0XHRzcGVlZFkgPSBzeTtcblx0XHR9O1xuXG5cdFx0dGhhdC5nZXRTcGVlZFkgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgdGFyZ2V0U3BlZWQ7XG5cblx0XHRcdGlmICh0aGF0LmlzSnVtcGluZykge1xuXHRcdFx0XHRyZXR1cm4gc3BlZWRZO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoZ2V0RGlzY3JldGVEaXJlY3Rpb24oKSA9PT0gJ2VzRWFzdCcgfHwgZ2V0RGlzY3JldGVEaXJlY3Rpb24oKSA9PT0gJ3dzV2VzdCcpIHtcblx0XHRcdFx0c3BlZWRZRmFjdG9yID0gMC42O1xuXHRcdFx0XHRzcGVlZFkgPSBlYXNlU3BlZWRUb1RhcmdldFVzaW5nRmFjdG9yKHNwZWVkWSwgdGhhdC5nZXRTcGVlZCgpICogMC42LCAwLjYpO1xuXG5cdFx0XHRcdHJldHVybiBzcGVlZFk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChnZXREaXNjcmV0ZURpcmVjdGlvbigpID09PSAnc0Vhc3QnIHx8IGdldERpc2NyZXRlRGlyZWN0aW9uKCkgPT09ICdzV2VzdCcpIHtcblx0XHRcdFx0c3BlZWRZRmFjdG9yID0gMC44NTtcblx0XHRcdFx0c3BlZWRZID0gZWFzZVNwZWVkVG9UYXJnZXRVc2luZ0ZhY3RvcihzcGVlZFksIHRoYXQuZ2V0U3BlZWQoKSAqIDAuODUsIDAuODUpO1xuXG5cdFx0XHRcdHJldHVybiBzcGVlZFk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChnZXREaXNjcmV0ZURpcmVjdGlvbigpID09PSAnZWFzdCcgfHwgZ2V0RGlzY3JldGVEaXJlY3Rpb24oKSA9PT0gJ3dlc3QnKSB7XG5cdFx0XHRcdHNwZWVkWUZhY3RvciA9IDE7XG5cdFx0XHRcdHNwZWVkWSA9IDA7XG5cblx0XHRcdFx0cmV0dXJuIHNwZWVkWTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU28gaXQgbXVzdCBiZSBzb3V0aFxuXG5cdFx0XHRzcGVlZFkgPSBlYXNlU3BlZWRUb1RhcmdldFVzaW5nRmFjdG9yKHNwZWVkWSwgdGhhdC5nZXRTcGVlZCgpLCBzcGVlZFlGYWN0b3IpO1xuXG5cdFx0XHRyZXR1cm4gc3BlZWRZO1xuXHRcdH07XG5cblx0XHR0aGF0Lmhhc0hpdE9ic3RhY2xlID0gZnVuY3Rpb24gKG9icykge1xuXHRcdFx0c2V0Q3Jhc2hlZCgpO1xuXG5cdFx0XHRpZiAobmF2aWdhdG9yLnZpYnJhdGUpIHtcblx0XHRcdFx0bmF2aWdhdG9yLnZpYnJhdGUoNTAwKTtcblx0XHRcdH1cblxuXHRcdFx0b2JzdGFjbGVzSGl0LnB1c2gob2JzLmlkKTtcblxuXHRcdFx0dGhhdC5yZXNldFNwZWVkKCk7XG5cdFx0XHR0aGF0Lm9uSGl0T2JzdGFjbGVDYihvYnMpO1xuXG5cdFx0XHRpZiAoY2FuY2VsYWJsZVN0YXRlVGltZW91dCkge1xuXHRcdFx0XHRjbGVhclRpbWVvdXQoY2FuY2VsYWJsZVN0YXRlVGltZW91dCk7XG5cdFx0XHR9XG5cdFx0XHRjYW5jZWxhYmxlU3RhdGVUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0c2V0Tm9ybWFsKCk7XG5cdFx0XHR9LCAxNTAwKTtcblx0XHR9O1xuXG5cdFx0dGhhdC5oYXNIaXRKdW1wID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0c2V0SnVtcGluZygpO1xuXG5cdFx0XHRpZiAoY2FuY2VsYWJsZVN0YXRlVGltZW91dCkge1xuXHRcdFx0XHRjbGVhclRpbWVvdXQoY2FuY2VsYWJsZVN0YXRlVGltZW91dCk7XG5cdFx0XHR9XG5cdFx0XHRjYW5jZWxhYmxlU3RhdGVUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0c2V0Tm9ybWFsKCk7XG5cdFx0XHR9LCAxMDAwKTtcblx0XHR9O1xuXG5cdFx0dGhhdC5pc0VhdGVuQnkgPSBmdW5jdGlvbiAobW9uc3Rlciwgd2hlbkVhdGVuKSB7XG5cdFx0XHR0aGF0Lmhhc0hpdE9ic3RhY2xlKG1vbnN0ZXIpO1xuXHRcdFx0bW9uc3Rlci5zdGFydEVhdGluZyh3aGVuRWF0ZW4pO1xuXHRcdFx0b2JzdGFjbGVzSGl0LnB1c2gobW9uc3Rlci5pZCk7XG5cdFx0XHR0aGF0LmlzTW92aW5nID0gZmFsc2U7XG5cdFx0XHR0aGF0LmlzQmVpbmdFYXRlbiA9IHRydWU7XG5cdFx0fTtcblxuXHRcdHRoYXQucmVzZXQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRvYnN0YWNsZXNIaXQgPSBbXTtcblx0XHRcdHBpeGVsc1RyYXZlbGxlZCA9IDA7XG5cdFx0XHR0aGF0LmlzTW92aW5nID0gdHJ1ZTtcblx0XHRcdHRoYXQuaXNKdW1waW5nID0gZmFsc2U7XG5cdFx0XHR0aGF0Lmhhc0JlZW5IaXQgPSBmYWxzZTtcblx0XHRcdGNhblNwZWVkQm9vc3QgPSB0cnVlO1xuXHRcdH07XG5cblx0XHR0aGF0LnNldEhpdE9ic3RhY2xlQ2IgPSBmdW5jdGlvbiAoZm4pIHtcblx0XHRcdHRoYXQub25IaXRPYnN0YWNsZUNiID0gZm4gfHwgZnVuY3Rpb24oKSB7fTtcblx0XHR9O1xuXHRcdHJldHVybiB0aGF0O1xuXHR9XG5cblx0Z2xvYmFsLnNraWVyID0gU2tpZXI7XG59KSh0aGlzKTtcblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XG5cdG1vZHVsZS5leHBvcnRzID0gdGhpcy5za2llcjtcbn1cbiIsInZhciBTcHJpdGUgPSByZXF1aXJlKCcuL3Nwcml0ZScpO1xuXG4oZnVuY3Rpb24oZ2xvYmFsKSB7XG5cdGZ1bmN0aW9uIFNub3dib2FyZGVyKGRhdGEpIHtcblx0XHR2YXIgdGhhdCA9IG5ldyBTcHJpdGUoZGF0YSk7XG5cdFx0dmFyIHN1cCA9IHtcblx0XHRcdGRyYXc6IHRoYXQuc3VwZXJpb3IoJ2RyYXcnKSxcblx0XHRcdGN5Y2xlOiB0aGF0LnN1cGVyaW9yKCdjeWNsZScpXG5cdFx0fTtcblx0XHR2YXIgZGlyZWN0aW9ucyA9IHtcblx0XHRcdHNFYXN0OiBmdW5jdGlvbih4RGlmZikgeyByZXR1cm4geERpZmYgPiAwOyB9LFxuXHRcdFx0c1dlc3Q6IGZ1bmN0aW9uKHhEaWZmKSB7IHJldHVybiB4RGlmZiA8PSAwOyB9XG5cdFx0fTtcblx0XHR2YXIgc3RhbmRhcmRTcGVlZCA9IDM7XG5cblx0XHR0aGF0LnNldFNwZWVkKHN0YW5kYXJkU3BlZWQpO1xuXG5cdFx0ZnVuY3Rpb24gZ2V0RGlyZWN0aW9uKCkge1xuXHRcdFx0dmFyIHhEaWZmID0gdGhhdC5tb3ZpbmdUb3dhcmRbMF0gLSB0aGF0Lm1hcFBvc2l0aW9uWzBdO1xuXHRcdFx0dmFyIHlEaWZmID0gdGhhdC5tb3ZpbmdUb3dhcmRbMV0gLSB0aGF0Lm1hcFBvc2l0aW9uWzFdO1xuXG5cdFx0XHRpZiAoZGlyZWN0aW9ucy5zRWFzdCh4RGlmZikpIHtcblx0XHRcdFx0cmV0dXJuICdzRWFzdCc7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gJ3NXZXN0Jztcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGF0LmN5Y2xlID0gZnVuY3Rpb24gKGRDb250ZXh0KSB7XG5cdFx0XHRpZiAoTnVtYmVyLnJhbmRvbSgxMCkgPT09IDEpIHtcblx0XHRcdFx0dGhhdC5zZXRNYXBQb3NpdGlvblRhcmdldChkQ29udGV4dC5nZXRSYW5kb21seUluVGhlQ2VudHJlT2ZNYXAoKSk7XG5cdFx0XHRcdHRoYXQuc2V0U3BlZWQoc3RhbmRhcmRTcGVlZCArIE51bWJlci5yYW5kb20oLTEsIDEpKTtcblx0XHRcdH1cblxuXHRcdFx0dGhhdC5zZXRNYXBQb3NpdGlvblRhcmdldCh1bmRlZmluZWQsIGRDb250ZXh0LmdldE1hcEJlbG93Vmlld3BvcnQoKSArIDYwMCk7XG5cblx0XHRcdHN1cC5jeWNsZSgpO1xuXHRcdH07XG5cblx0XHR0aGF0LmRyYXcgPSBmdW5jdGlvbihkQ29udGV4dCkge1xuXHRcdFx0dmFyIHNwcml0ZVBhcnRUb1VzZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cmV0dXJuIGdldERpcmVjdGlvbigpO1xuXHRcdFx0fTtcblxuXHRcdFx0cmV0dXJuIHN1cC5kcmF3KGRDb250ZXh0LCBzcHJpdGVQYXJ0VG9Vc2UoKSk7XG5cdFx0fTtcblxuXHRcdHJldHVybiB0aGF0O1xuXHR9XG5cblx0Z2xvYmFsLnNub3dib2FyZGVyID0gU25vd2JvYXJkZXI7XG59KSggdGhpcyApO1xuXG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHRoaXMuc25vd2JvYXJkZXI7XG59IiwiKGZ1bmN0aW9uIChnbG9iYWwpIHtcblx0dmFyIEdVSUQgPSByZXF1aXJlKCcuL2d1aWQnKTtcblx0ZnVuY3Rpb24gU3ByaXRlIChkYXRhKSB7XG5cdFx0dmFyIGhpdHRhYmxlT2JqZWN0cyA9IHt9O1xuXHRcdHZhciB6SW5kZXhlc09jY3VwaWVkID0gWyAwIF07XG5cdFx0dmFyIHRoYXQgPSB0aGlzO1xuXHRcdHZhciB0cmFja2VkU3ByaXRlVG9Nb3ZlVG93YXJkO1xuXHRcdHRoYXQuZGlyZWN0aW9uID0gdW5kZWZpbmVkO1xuXHRcdHRoYXQubWFwUG9zaXRpb24gPSBbMCwgMCwgMF07XG5cdFx0dGhhdC5pZCA9IEdVSUQoKTtcblx0XHR0aGF0LmNhbnZhc1ggPSAwO1xuXHRcdHRoYXQuY2FudmFzWSA9IDA7XG5cdFx0dGhhdC5jYW52YXNaID0gMDtcblx0XHR0aGF0LmhlaWdodCA9IDA7XG5cdFx0dGhhdC5zcGVlZCA9IDA7XG5cdFx0dGhhdC5kYXRhID0gZGF0YSB8fCB7IHBhcnRzIDoge30gfTtcblx0XHR0aGF0Lm1vdmluZ1Rvd2FyZCA9IFsgMCwgMCBdO1xuXHRcdHRoYXQubWV0cmVzRG93blRoZU1vdW50YWluID0gMDtcblx0XHR0aGF0Lm1vdmluZ1dpdGhDb252aWN0aW9uID0gZmFsc2U7XG5cdFx0dGhhdC5kZWxldGVkID0gZmFsc2U7XG5cdFx0dGhhdC5tYXhIZWlnaHQgPSAoZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIE9iamVjdC52YWx1ZXModGhhdC5kYXRhLnBhcnRzKS5tYXAoZnVuY3Rpb24gKHApIHsgcmV0dXJuIHBbM107IH0pLm1heCgpO1xuXHRcdH0oKSk7XG5cdFx0dGhhdC5pc01vdmluZyA9IHRydWU7XG5cblx0XHRpZiAoIXRoYXQuZGF0YS5wYXJ0cykge1xuXHRcdFx0dGhhdC5kYXRhLnBhcnRzID0ge307XG5cdFx0fVxuXG5cdFx0aWYgKGRhdGEgJiYgZGF0YS5pZCl7XG5cdFx0XHR0aGF0LmlkID0gZGF0YS5pZDtcblx0XHR9XG5cblx0XHRpZiAoZGF0YSAmJiBkYXRhLnpJbmRleGVzT2NjdXBpZWQpIHtcblx0XHRcdHpJbmRleGVzT2NjdXBpZWQgPSBkYXRhLnpJbmRleGVzT2NjdXBpZWQ7XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gaW5jcmVtZW50WChhbW91bnQpIHtcblx0XHRcdHRoYXQuY2FudmFzWCArPSBhbW91bnQudG9OdW1iZXIoKTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBpbmNyZW1lbnRZKGFtb3VudCkge1xuXHRcdFx0dGhhdC5jYW52YXNZICs9IGFtb3VudC50b051bWJlcigpO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGdldEhpdEJveChmb3JaSW5kZXgpIHtcblx0XHRcdGlmICh0aGF0LmRhdGEuaGl0Qm94ZXMpIHtcblx0XHRcdFx0aWYgKGRhdGEuaGl0Qm94ZXNbZm9yWkluZGV4XSkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhLmhpdEJveGVzW2ZvclpJbmRleF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRmdW5jdGlvbiByb3VuZEhhbGYobnVtKSB7XG5cdFx0XHRudW0gPSBNYXRoLnJvdW5kKG51bSoyKS8yO1xuXHRcdFx0cmV0dXJuIG51bTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBtb3ZlKCkge1xuXHRcdFx0aWYgKCF0aGF0LmlzTW92aW5nKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0dmFyIGN1cnJlbnRYID0gdGhhdC5tYXBQb3NpdGlvblswXTtcblx0XHRcdHZhciBjdXJyZW50WSA9IHRoYXQubWFwUG9zaXRpb25bMV07XG5cblx0XHRcdGlmICh0eXBlb2YgdGhhdC5kaXJlY3Rpb24gIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdC8vIEZvciB0aGlzIHdlIG5lZWQgdG8gbW9kaWZ5IHRoZSB0aGF0LmRpcmVjdGlvbiBzbyBpdCByZWxhdGVzIHRvIHRoZSBob3Jpem9udGFsXG5cdFx0XHRcdHZhciBkID0gdGhhdC5kaXJlY3Rpb24gLSA5MDtcblx0XHRcdFx0aWYgKGQgPCAwKSBkID0gMzYwICsgZDtcblx0XHRcdFx0Y3VycmVudFggKz0gcm91bmRIYWxmKHRoYXQuc3BlZWQgKiBNYXRoLmNvcyhkICogKE1hdGguUEkgLyAxODApKSk7XG5cdFx0XHRcdGN1cnJlbnRZICs9IHJvdW5kSGFsZih0aGF0LnNwZWVkICogTWF0aC5zaW4oZCAqIChNYXRoLlBJIC8gMTgwKSkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKHR5cGVvZiB0aGF0Lm1vdmluZ1Rvd2FyZFswXSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0XHRpZiAoY3VycmVudFggPiB0aGF0Lm1vdmluZ1Rvd2FyZFswXSkge1xuXHRcdFx0XHRcdFx0Y3VycmVudFggLT0gTWF0aC5taW4odGhhdC5nZXRTcGVlZFgoKSwgTWF0aC5hYnMoY3VycmVudFggLSB0aGF0Lm1vdmluZ1Rvd2FyZFswXSkpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoY3VycmVudFggPCB0aGF0Lm1vdmluZ1Rvd2FyZFswXSkge1xuXHRcdFx0XHRcdFx0Y3VycmVudFggKz0gTWF0aC5taW4odGhhdC5nZXRTcGVlZFgoKSwgTWF0aC5hYnMoY3VycmVudFggLSB0aGF0Lm1vdmluZ1Rvd2FyZFswXSkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRcblx0XHRcdFx0aWYgKHR5cGVvZiB0aGF0Lm1vdmluZ1Rvd2FyZFsxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0XHRpZiAoY3VycmVudFkgPiB0aGF0Lm1vdmluZ1Rvd2FyZFsxXSkge1xuXHRcdFx0XHRcdFx0Y3VycmVudFkgLT0gTWF0aC5taW4odGhhdC5nZXRTcGVlZFkoKSwgTWF0aC5hYnMoY3VycmVudFkgLSB0aGF0Lm1vdmluZ1Rvd2FyZFsxXSkpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoY3VycmVudFkgPCB0aGF0Lm1vdmluZ1Rvd2FyZFsxXSkge1xuXHRcdFx0XHRcdFx0Y3VycmVudFkgKz0gTWF0aC5taW4odGhhdC5nZXRTcGVlZFkoKSwgTWF0aC5hYnMoY3VycmVudFkgLSB0aGF0Lm1vdmluZ1Rvd2FyZFsxXSkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR0aGF0LnNldE1hcFBvc2l0aW9uKGN1cnJlbnRYLCBjdXJyZW50WSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5kcmF3ID0gZnVuY3Rpb24gKGRDdHgsIHNwcml0ZUZyYW1lKSB7XG5cdFx0XHR2YXIgZnIgPSB0aGF0LmRhdGEucGFydHNbc3ByaXRlRnJhbWVdO1xuXHRcdFx0dGhhdC5oZWlnaHQgPSBmclszXTtcblx0XHRcdHRoYXQud2lkdGggPSBmclsyXTtcblxuXHRcdFx0dmFyIG5ld0NhbnZhc1Bvc2l0aW9uID0gZEN0eC5tYXBQb3NpdGlvblRvQ2FudmFzUG9zaXRpb24odGhhdC5tYXBQb3NpdGlvbik7XG5cdFx0XHR0aGF0LnNldENhbnZhc1Bvc2l0aW9uKG5ld0NhbnZhc1Bvc2l0aW9uWzBdLCBuZXdDYW52YXNQb3NpdGlvblsxXSk7XG5cblx0XHRcdGRDdHguZHJhd0ltYWdlKGRDdHguZ2V0TG9hZGVkSW1hZ2UodGhhdC5kYXRhLiRpbWFnZUZpbGUpLCBmclswXSwgZnJbMV0sIGZyWzJdLCBmclszXSwgdGhhdC5jYW52YXNYLCB0aGF0LmNhbnZhc1ksIGZyWzJdLCBmclszXSk7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0TWFwUG9zaXRpb24gPSBmdW5jdGlvbiAoeCwgeSwgeikge1xuXHRcdFx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHR4ID0gdGhhdC5tYXBQb3NpdGlvblswXTtcblx0XHRcdH1cblx0XHRcdGlmICh0eXBlb2YgeSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0eSA9IHRoYXQubWFwUG9zaXRpb25bMV07XG5cdFx0XHR9XG5cdFx0XHRpZiAodHlwZW9mIHogPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdHogPSB0aGF0Lm1hcFBvc2l0aW9uWzJdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhhdC56SW5kZXhlc09jY3VwaWVkID0gWyB6IF07XG5cdFx0XHR9XG5cdFx0XHR0aGF0Lm1hcFBvc2l0aW9uID0gW3gsIHksIHpdO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldENhbnZhc1Bvc2l0aW9uID0gZnVuY3Rpb24gKGN4LCBjeSkge1xuXHRcdFx0aWYgKGN4KSB7XG5cdFx0XHRcdGlmIChPYmplY3QuaXNTdHJpbmcoY3gpICYmIChjeC5maXJzdCgpID09PSAnKycgfHwgY3guZmlyc3QoKSA9PT0gJy0nKSkgaW5jcmVtZW50WChjeCk7XG5cdFx0XHRcdGVsc2UgdGhhdC5jYW52YXNYID0gY3g7XG5cdFx0XHR9XG5cdFx0XHRcblx0XHRcdGlmIChjeSkge1xuXHRcdFx0XHRpZiAoT2JqZWN0LmlzU3RyaW5nKGN5KSAmJiAoY3kuZmlyc3QoKSA9PT0gJysnIHx8IGN5LmZpcnN0KCkgPT09ICctJykpIGluY3JlbWVudFkoY3kpO1xuXHRcdFx0XHRlbHNlIHRoYXQuY2FudmFzWSA9IGN5O1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLmdldENhbnZhc1Bvc2l0aW9uWCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHJldHVybiB0aGF0LmNhbnZhc1g7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0Q2FudmFzUG9zaXRpb25ZID0gZnVuY3Rpb24gICgpIHtcblx0XHRcdHJldHVybiB0aGF0LmNhbnZhc1k7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0TGVmdEhpdEJveEVkZ2UgPSBmdW5jdGlvbiAoekluZGV4KSB7XG5cdFx0XHR6SW5kZXggPSB6SW5kZXggfHwgMDtcblx0XHRcdHZhciBsaGJlID0gdGhpcy5nZXRDYW52YXNQb3NpdGlvblgoKTtcblx0XHRcdGlmIChnZXRIaXRCb3goekluZGV4KSkge1xuXHRcdFx0XHRsaGJlICs9IGdldEhpdEJveCh6SW5kZXgpWzBdO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGxoYmU7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0VG9wSGl0Qm94RWRnZSA9IGZ1bmN0aW9uICh6SW5kZXgpIHtcblx0XHRcdHpJbmRleCA9IHpJbmRleCB8fCAwO1xuXHRcdFx0dmFyIHRoYmUgPSB0aGlzLmdldENhbnZhc1Bvc2l0aW9uWSgpO1xuXHRcdFx0aWYgKGdldEhpdEJveCh6SW5kZXgpKSB7XG5cdFx0XHRcdHRoYmUgKz0gZ2V0SGl0Qm94KHpJbmRleClbMV07XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhiZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRSaWdodEhpdEJveEVkZ2UgPSBmdW5jdGlvbiAoekluZGV4KSB7XG5cdFx0XHR6SW5kZXggPSB6SW5kZXggfHwgMDtcblxuXHRcdFx0aWYgKGdldEhpdEJveCh6SW5kZXgpKSB7XG5cdFx0XHRcdHJldHVybiB0aGF0LmNhbnZhc1ggKyBnZXRIaXRCb3goekluZGV4KVsyXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoYXQuY2FudmFzWCArIHRoYXQud2lkdGg7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0Qm90dG9tSGl0Qm94RWRnZSA9IGZ1bmN0aW9uICh6SW5kZXgpIHtcblx0XHRcdHpJbmRleCA9IHpJbmRleCB8fCAwO1xuXG5cdFx0XHRpZiAoZ2V0SGl0Qm94KHpJbmRleCkpIHtcblx0XHRcdFx0cmV0dXJuIHRoYXQuY2FudmFzWSArIGdldEhpdEJveCh6SW5kZXgpWzNdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdGhhdC5jYW52YXNZICsgdGhhdC5oZWlnaHQ7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0UG9zaXRpb25JbkZyb250T2YgPSBmdW5jdGlvbiAgKCkge1xuXHRcdFx0cmV0dXJuIFt0aGF0LmNhbnZhc1gsIHRoYXQuY2FudmFzWSArIHRoYXQuaGVpZ2h0XTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRTcGVlZCA9IGZ1bmN0aW9uIChzKSB7XG5cdFx0XHR0aGF0LnNwZWVkID0gcztcblx0XHRcdHRoYXQuc3BlZWRYID0gcztcblx0XHRcdHRoYXQuc3BlZWRZID0gcztcblx0XHR9O1xuXG5cdFx0dGhpcy5pbmNyZW1lbnRTcGVlZEJ5ID0gZnVuY3Rpb24gKHMpIHtcblx0XHRcdHRoYXQuc3BlZWQgKz0gcztcblx0XHR9O1xuXG5cdFx0dGhhdC5nZXRTcGVlZCA9IGZ1bmN0aW9uIGdldFNwZWVkICgpIHtcblx0XHRcdHJldHVybiB0aGF0LnNwZWVkO1xuXHRcdH07XG5cblx0XHR0aGF0LmdldFNwZWVkWCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHJldHVybiB0aGF0LnNwZWVkO1xuXHRcdH07XG5cblx0XHR0aGF0LmdldFNwZWVkWSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHJldHVybiB0aGF0LnNwZWVkO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEhlaWdodCA9IGZ1bmN0aW9uIChoKSB7XG5cdFx0XHR0aGF0LmhlaWdodCA9IGg7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0V2lkdGggPSBmdW5jdGlvbiAodykge1xuXHRcdFx0dGhhdC53aWR0aCA9IHc7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0TWF4SGVpZ2h0ID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHRoYXQubWF4SGVpZ2h0O1xuXHRcdH07XG5cblx0XHR0aGF0LmdldE1vdmluZ1Rvd2FyZE9wcG9zaXRlID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKCF0aGF0LmlzTW92aW5nKSB7XG5cdFx0XHRcdHJldHVybiBbMCwgMF07XG5cdFx0XHR9XG5cblx0XHRcdHZhciBkeCA9ICh0aGF0Lm1vdmluZ1Rvd2FyZFswXSAtIHRoYXQubWFwUG9zaXRpb25bMF0pO1xuXHRcdFx0dmFyIGR5ID0gKHRoYXQubW92aW5nVG93YXJkWzFdIC0gdGhhdC5tYXBQb3NpdGlvblsxXSk7XG5cblx0XHRcdHZhciBvcHBvc2l0ZVggPSAoTWF0aC5hYnMoZHgpID4gNzUgPyAwIC0gZHggOiAwKTtcblx0XHRcdHZhciBvcHBvc2l0ZVkgPSAtZHk7XG5cblx0XHRcdHJldHVybiBbIG9wcG9zaXRlWCwgb3Bwb3NpdGVZIF07XG5cdFx0fTtcblxuXHRcdHRoaXMuY2hlY2tIaXR0YWJsZU9iamVjdHMgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRPYmplY3Qua2V5cyhoaXR0YWJsZU9iamVjdHMsIGZ1bmN0aW9uIChrLCBvYmplY3REYXRhKSB7XG5cdFx0XHRcdGlmIChvYmplY3REYXRhLm9iamVjdC5kZWxldGVkKSB7XG5cdFx0XHRcdFx0ZGVsZXRlIGhpdHRhYmxlT2JqZWN0c1trXTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAob2JqZWN0RGF0YS5vYmplY3QuaGl0cyh0aGF0KSkge1xuXHRcdFx0XHRcdFx0b2JqZWN0RGF0YS5jYWxsYmFja3MuZWFjaChmdW5jdGlvbiAoY2FsbGJhY2spIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2sodGhhdCwgb2JqZWN0RGF0YS5vYmplY3QpO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9O1xuXG5cdFx0dGhpcy5jeWNsZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoYXQuY2hlY2tIaXR0YWJsZU9iamVjdHMoKTtcblxuXHRcdFx0aWYgKHRyYWNrZWRTcHJpdGVUb01vdmVUb3dhcmQpIHtcblx0XHRcdFx0dGhhdC5zZXRNYXBQb3NpdGlvblRhcmdldCh0cmFja2VkU3ByaXRlVG9Nb3ZlVG93YXJkLm1hcFBvc2l0aW9uWzBdLCB0cmFja2VkU3ByaXRlVG9Nb3ZlVG93YXJkLm1hcFBvc2l0aW9uWzFdLCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdFx0bW92ZSgpO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldE1hcFBvc2l0aW9uVGFyZ2V0ID0gZnVuY3Rpb24gKHgsIHksIG92ZXJyaWRlKSB7XG5cdFx0XHRpZiAob3ZlcnJpZGUpIHtcblx0XHRcdFx0dGhhdC5tb3ZpbmdXaXRoQ29udmljdGlvbiA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIXRoYXQubW92aW5nV2l0aENvbnZpY3Rpb24pIHtcblx0XHRcdFx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdHggPSB0aGF0Lm1vdmluZ1Rvd2FyZFswXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh0eXBlb2YgeSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0XHR5ID0gdGhhdC5tb3ZpbmdUb3dhcmRbMV07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGF0Lm1vdmluZ1Rvd2FyZCA9IFsgeCwgeSBdO1xuXG5cdFx0XHRcdHRoYXQubW92aW5nV2l0aENvbnZpY3Rpb24gPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gdGhhdC5yZXNldERpcmVjdGlvbigpO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldERpcmVjdGlvbiA9IGZ1bmN0aW9uIChhbmdsZSkge1xuXHRcdFx0aWYgKGFuZ2xlID49IDM2MCkge1xuXHRcdFx0XHRhbmdsZSA9IDM2MCAtIGFuZ2xlO1xuXHRcdFx0fVxuXHRcdFx0dGhhdC5kaXJlY3Rpb24gPSBhbmdsZTtcblx0XHRcdHRoYXQubW92aW5nVG93YXJkID0gdW5kZWZpbmVkO1xuXHRcdH07XG5cblx0XHR0aGlzLnJlc2V0RGlyZWN0aW9uID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhhdC5kaXJlY3Rpb24gPSB1bmRlZmluZWQ7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0TWFwUG9zaXRpb25UYXJnZXRXaXRoQ29udmljdGlvbiA9IGZ1bmN0aW9uIChjeCwgY3kpIHtcblx0XHRcdHRoYXQuc2V0TWFwUG9zaXRpb25UYXJnZXQoY3gsIGN5KTtcblx0XHRcdHRoYXQubW92aW5nV2l0aENvbnZpY3Rpb24gPSB0cnVlO1xuXHRcdFx0Ly8gdGhhdC5yZXNldERpcmVjdGlvbigpO1xuXHRcdH07XG5cblx0XHR0aGlzLmZvbGxvdyA9IGZ1bmN0aW9uIChzcHJpdGUpIHtcblx0XHRcdHRyYWNrZWRTcHJpdGVUb01vdmVUb3dhcmQgPSBzcHJpdGU7XG5cdFx0XHQvLyB0aGF0LnJlc2V0RGlyZWN0aW9uKCk7XG5cdFx0fTtcblxuXHRcdHRoaXMuc3RvcEZvbGxvd2luZyA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRyYWNrZWRTcHJpdGVUb01vdmVUb3dhcmQgPSBmYWxzZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5vbkhpdHRpbmcgPSBmdW5jdGlvbiAob2JqZWN0VG9IaXQsIGNhbGxiYWNrKSB7XG5cdFx0XHRpZiAoaGl0dGFibGVPYmplY3RzW29iamVjdFRvSGl0LmlkXSkge1xuXHRcdFx0XHRyZXR1cm4gaGl0dGFibGVPYmplY3RzW29iamVjdFRvSGl0LmlkXS5jYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG5cdFx0XHR9XG5cblx0XHRcdGhpdHRhYmxlT2JqZWN0c1tvYmplY3RUb0hpdC5pZF0gPSB7XG5cdFx0XHRcdG9iamVjdDogb2JqZWN0VG9IaXQsXG5cdFx0XHRcdGNhbGxiYWNrczogWyBjYWxsYmFjayBdXG5cdFx0XHR9O1xuXHRcdH07XG5cblx0XHR0aGlzLmRlbGV0ZU9uTmV4dEN5Y2xlID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhhdC5kZWxldGVkID0gdHJ1ZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5vY2N1cGllc1pJbmRleCA9IGZ1bmN0aW9uICh6KSB7XG5cdFx0XHRyZXR1cm4gekluZGV4ZXNPY2N1cGllZC5pbmRleE9mKHopID49IDA7XG5cdFx0fTtcblxuXHRcdHRoaXMuaGl0cyA9IGZ1bmN0aW9uIChvdGhlcikge1xuXHRcdFx0dmFyIHZlcnRpY2FsSW50ZXJzZWN0ID0gZmFsc2U7XG5cdFx0XHR2YXIgaG9yaXpvbnRhbEludGVyc2VjdCA9IGZhbHNlO1xuXG5cdFx0XHQvLyBUZXN0IHRoYXQgVEhJUyBoYXMgYSBib3R0b20gZWRnZSBpbnNpZGUgb2YgdGhlIG90aGVyIG9iamVjdFxuXHRcdFx0aWYgKG90aGVyLmdldFRvcEhpdEJveEVkZ2UodGhhdC5tYXBQb3NpdGlvblsyXSkgPD0gdGhhdC5nZXRCb3R0b21IaXRCb3hFZGdlKHRoYXQubWFwUG9zaXRpb25bMl0pICYmIG90aGVyLmdldEJvdHRvbUhpdEJveEVkZ2UodGhhdC5tYXBQb3NpdGlvblsyXSkgPj0gdGhhdC5nZXRCb3R0b21IaXRCb3hFZGdlKHRoYXQubWFwUG9zaXRpb25bMl0pKSB7XG5cdFx0XHRcdHZlcnRpY2FsSW50ZXJzZWN0ID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGVzdCB0aGF0IFRISVMgaGFzIGEgdG9wIGVkZ2UgaW5zaWRlIG9mIHRoZSBvdGhlciBvYmplY3Rcblx0XHRcdGlmIChvdGhlci5nZXRUb3BIaXRCb3hFZGdlKHRoYXQubWFwUG9zaXRpb25bMl0pIDw9IHRoYXQuZ2V0VG9wSGl0Qm94RWRnZSh0aGF0Lm1hcFBvc2l0aW9uWzJdKSAmJiBvdGhlci5nZXRCb3R0b21IaXRCb3hFZGdlKHRoYXQubWFwUG9zaXRpb25bMl0pID49IHRoYXQuZ2V0VG9wSGl0Qm94RWRnZSh0aGF0Lm1hcFBvc2l0aW9uWzJdKSkge1xuXHRcdFx0XHR2ZXJ0aWNhbEludGVyc2VjdCA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRlc3QgdGhhdCBUSElTIGhhcyBhIHJpZ2h0IGVkZ2UgaW5zaWRlIG9mIHRoZSBvdGhlciBvYmplY3Rcblx0XHRcdGlmIChvdGhlci5nZXRMZWZ0SGl0Qm94RWRnZSh0aGF0Lm1hcFBvc2l0aW9uWzJdKSA8PSB0aGF0LmdldFJpZ2h0SGl0Qm94RWRnZSh0aGF0Lm1hcFBvc2l0aW9uWzJdKSAmJiBvdGhlci5nZXRSaWdodEhpdEJveEVkZ2UodGhhdC5tYXBQb3NpdGlvblsyXSkgPj0gdGhhdC5nZXRSaWdodEhpdEJveEVkZ2UodGhhdC5tYXBQb3NpdGlvblsyXSkpIHtcblx0XHRcdFx0aG9yaXpvbnRhbEludGVyc2VjdCA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRlc3QgdGhhdCBUSElTIGhhcyBhIGxlZnQgZWRnZSBpbnNpZGUgb2YgdGhlIG90aGVyIG9iamVjdFxuXHRcdFx0aWYgKG90aGVyLmdldExlZnRIaXRCb3hFZGdlKHRoYXQubWFwUG9zaXRpb25bMl0pIDw9IHRoYXQuZ2V0TGVmdEhpdEJveEVkZ2UodGhhdC5tYXBQb3NpdGlvblsyXSkgJiYgb3RoZXIuZ2V0UmlnaHRIaXRCb3hFZGdlKHRoYXQubWFwUG9zaXRpb25bMl0pID49IHRoYXQuZ2V0TGVmdEhpdEJveEVkZ2UodGhhdC5tYXBQb3NpdGlvblsyXSkpIHtcblx0XHRcdFx0aG9yaXpvbnRhbEludGVyc2VjdCA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB2ZXJ0aWNhbEludGVyc2VjdCAmJiBob3Jpem9udGFsSW50ZXJzZWN0O1xuXHRcdH07XG5cblx0XHR0aGlzLmlzQWJvdmVPbkNhbnZhcyA9IGZ1bmN0aW9uIChjeSkge1xuXHRcdFx0cmV0dXJuICh0aGF0LmNhbnZhc1kgKyB0aGF0LmhlaWdodCkgPCBjeTtcblx0XHR9O1xuXG5cdFx0dGhpcy5pc0JlbG93T25DYW52YXMgPSBmdW5jdGlvbiAoY3kpIHtcblx0XHRcdHJldHVybiAodGhhdC5jYW52YXNZKSA+IGN5O1xuXHRcdH07XG5cblx0XHRyZXR1cm4gdGhhdDtcblx0fVxuXG5cdFNwcml0ZS5jcmVhdGVPYmplY3RzID0gZnVuY3Rpb24gY3JlYXRlT2JqZWN0cyhzcHJpdGVJbmZvQXJyYXksIG9wdHMpIHtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkoc3ByaXRlSW5mb0FycmF5KSkgc3ByaXRlSW5mb0FycmF5ID0gWyBzcHJpdGVJbmZvQXJyYXkgXTtcblx0XHRvcHRzID0gT2JqZWN0Lm1lcmdlKG9wdHMsIHtcblx0XHRcdHJhdGVNb2RpZmllcjogMCxcblx0XHRcdGRyb3BSYXRlOiAxLFxuXHRcdFx0cG9zaXRpb246IFswLCAwXVxuXHRcdH0sIGZhbHNlLCBmYWxzZSk7XG5cblx0XHRmdW5jdGlvbiBjcmVhdGVPbmUgKHNwcml0ZUluZm8pIHtcblx0XHRcdHZhciBwb3NpdGlvbiA9IG9wdHMucG9zaXRpb247XG5cdFx0XHRpZiAoTnVtYmVyLnJhbmRvbSgxMDAgKyBvcHRzLnJhdGVNb2RpZmllcikgPD0gc3ByaXRlSW5mby5kcm9wUmF0ZSkge1xuXHRcdFx0XHR2YXIgc3ByaXRlID0gbmV3IFNwcml0ZShzcHJpdGVJbmZvLnNwcml0ZSk7XG5cdFx0XHRcdHNwcml0ZS5zZXRTcGVlZCgwKTtcblxuXHRcdFx0XHRpZiAoT2JqZWN0LmlzRnVuY3Rpb24ocG9zaXRpb24pKSB7XG5cdFx0XHRcdFx0cG9zaXRpb24gPSBwb3NpdGlvbigpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c3ByaXRlLnNldE1hcFBvc2l0aW9uKHBvc2l0aW9uWzBdLCBwb3NpdGlvblsxXSk7XG5cblx0XHRcdFx0aWYgKHNwcml0ZUluZm8uc3ByaXRlLmhpdEJlaGF2aW91ciAmJiBzcHJpdGVJbmZvLnNwcml0ZS5oaXRCZWhhdmlvdXIuc2tpZXIgJiYgb3B0cy5wbGF5ZXIpIHtcblx0XHRcdFx0XHRzcHJpdGUub25IaXR0aW5nKG9wdHMucGxheWVyLCBzcHJpdGVJbmZvLnNwcml0ZS5oaXRCZWhhdmlvdXIuc2tpZXIpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHNwcml0ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgb2JqZWN0cyA9IHNwcml0ZUluZm9BcnJheS5tYXAoY3JlYXRlT25lKS5yZW1vdmUodW5kZWZpbmVkKTtcblxuXHRcdHJldHVybiBvYmplY3RzO1xuXHR9O1xuXG5cdGdsb2JhbC5zcHJpdGUgPSBTcHJpdGU7XG59KSggdGhpcyApO1xuXG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHRoaXMuc3ByaXRlO1xufSIsIihmdW5jdGlvbiAoZ2xvYmFsKSB7XG5cdGZ1bmN0aW9uIFNwcml0ZUFycmF5KCkge1xuXHRcdHRoaXMucHVzaEhhbmRsZXJzID0gW107XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdFNwcml0ZUFycmF5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQXJyYXkucHJvdG90eXBlKTtcblxuXHRTcHJpdGVBcnJheS5wcm90b3R5cGUub25QdXNoID0gZnVuY3Rpb24oZiwgcmV0cm9hY3RpdmUpIHtcblx0XHR0aGlzLnB1c2hIYW5kbGVycy5wdXNoKGYpO1xuXG5cdFx0aWYgKHJldHJvYWN0aXZlKSB7XG5cdFx0XHR0aGlzLmVhY2goZik7XG5cdFx0fVxuXHR9O1xuXG5cdFNwcml0ZUFycmF5LnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24ob2JqKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBvYmopO1xuXHRcdHRoaXMucHVzaEhhbmRsZXJzLmVhY2goZnVuY3Rpb24oaGFuZGxlcikge1xuXHRcdFx0aGFuZGxlcihvYmopO1xuXHRcdH0pO1xuXHR9O1xuXG5cdFNwcml0ZUFycmF5LnByb3RvdHlwZS5jdWxsID0gZnVuY3Rpb24oKSB7XG5cdFx0dGhpcy5lYWNoKGZ1bmN0aW9uIChvYmosIGkpIHtcblx0XHRcdGlmIChvYmouZGVsZXRlZCkge1xuXHRcdFx0XHRyZXR1cm4gKGRlbGV0ZSB0aGlzW2ldKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fTtcblxuXHRnbG9iYWwuc3ByaXRlQXJyYXkgPSBTcHJpdGVBcnJheTtcbn0pKHRoaXMpO1xuXG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHRoaXMuc3ByaXRlQXJyYXk7XG59IiwiLy8gR2xvYmFsIGRlcGVuZGVuY2llcyB3aGljaCByZXR1cm4gbm8gbW9kdWxlc1xucmVxdWlyZSgnLi9saWIvY2FudmFzUmVuZGVyaW5nQ29udGV4dDJERXh0ZW5zaW9ucycpO1xucmVxdWlyZSgnLi9saWIvZXh0ZW5kZXJzJyk7XG5yZXF1aXJlKCcuL2xpYi9wbHVnaW5zJyk7XG5cbi8vIEV4dGVybmFsIGRlcGVuZGVuY2llc1xudmFyIEhhbW1lciA9IHJlcXVpcmUoJ2hhbW1lcmpzJyk7XG52YXIgTW91c2V0cmFwID0gcmVxdWlyZSgnYnItbW91c2V0cmFwJyk7XG5cbi8vIE1ldGhvZCBtb2R1bGVzXG52YXIgaXNNb2JpbGVEZXZpY2UgPSByZXF1aXJlKCcuL2xpYi9pc01vYmlsZURldmljZScpO1xuXG4vLyBHYW1lIE9iamVjdHNcbnZhciBTcHJpdGVBcnJheSA9IHJlcXVpcmUoJy4vbGliL3Nwcml0ZUFycmF5Jyk7XG52YXIgTW9uc3RlciA9IHJlcXVpcmUoJy4vbGliL21vbnN0ZXInKTtcbnZhciBTcHJpdGUgPSByZXF1aXJlKCcuL2xpYi9zcHJpdGUnKTtcbnZhciBTbm93Ym9hcmRlciA9IHJlcXVpcmUoJy4vbGliL3Nub3dib2FyZGVyJyk7XG52YXIgU2tpZXIgPSByZXF1aXJlKCcuL2xpYi9za2llcicpO1xudmFyIEluZm9Cb3ggPSByZXF1aXJlKCcuL2xpYi9pbmZvQm94Jyk7XG52YXIgR2FtZSA9IHJlcXVpcmUoJy4vbGliL2dhbWUnKTtcblxuLy8gTG9jYWwgdmFyaWFibGVzIGZvciBzdGFydGluZyB0aGUgZ2FtZVxudmFyIG1haW5DYW52YXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2tpZnJlZS1jYW52YXMnKTtcbnZhciBkQ29udGV4dCA9IG1haW5DYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbnZhciBpbWFnZVNvdXJjZXMgPSBbICdzcHJpdGUtY2hhcmFjdGVycy5wbmcnLCAnc2tpZnJlZS1vYmplY3RzLnBuZycgXTtcbnZhciBnbG9iYWwgPSB0aGlzO1xudmFyIGluZm9Cb3hDb250cm9scyA9ICdVc2UgdGhlIG1vdXNlIG9yIFdBU0QgdG8gY29udHJvbCB0aGUgcGxheWVyJztcbmlmIChpc01vYmlsZURldmljZSgpKSBpbmZvQm94Q29udHJvbHMgPSAnVGFwIG9yIGRyYWcgb24gdGhlIHBpc3RlIHRvIGNvbnRyb2wgdGhlIHBsYXllcic7XG52YXIgc3ByaXRlcyA9IHJlcXVpcmUoJy4vc3ByaXRlSW5mbycpO1xuXG52YXIgcGl4ZWxzUGVyTWV0cmUgPSAxODtcbnZhciBkaXN0YW5jZVRyYXZlbGxlZEluTWV0cmVzID0gMDtcbnZhciBtb25zdGVyRGlzdGFuY2VUaHJlc2hvbGQgPSAyMDAwO1xudmFyIGxpdmVzTGVmdCA9IDU7XG52YXIgaGlnaFNjb3JlID0gMDtcbnZhciBsb3NlTGlmZU9uT2JzdGFjbGVIaXQgPSBmYWxzZTtcbnZhciBkcm9wUmF0ZXMgPSB7c21hbGxUcmVlOiA0LCB0YWxsVHJlZTogMiwganVtcDogMSwgdGhpY2tTbm93OiAxLCByb2NrOiAxfTtcbmlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnaGlnaFNjb3JlJykpIGhpZ2hTY29yZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdoaWdoU2NvcmUnKTtcblxuZnVuY3Rpb24gbG9hZEltYWdlcyAoc291cmNlcywgbmV4dCkge1xuXHR2YXIgbG9hZGVkID0gMDtcblx0dmFyIGltYWdlcyA9IHt9O1xuXG5cdGZ1bmN0aW9uIGZpbmlzaCAoKSB7XG5cdFx0bG9hZGVkICs9IDE7XG5cdFx0aWYgKGxvYWRlZCA9PT0gc291cmNlcy5sZW5ndGgpIHtcblx0XHRcdG5leHQoaW1hZ2VzKTtcblx0XHR9XG5cdH1cblxuXHRzb3VyY2VzLmVhY2goZnVuY3Rpb24gKHNyYykge1xuXHRcdHZhciBpbSA9IG5ldyBJbWFnZSgpO1xuXHRcdGltLm9ubG9hZCA9IGZpbmlzaDtcblx0XHRpbS5zcmMgPSBzcmM7XG5cdFx0ZENvbnRleHQuc3RvcmVMb2FkZWRJbWFnZShzcmMsIGltKTtcblx0fSk7XG59XG5cbmZ1bmN0aW9uIG1vbnN0ZXJIaXRzU2tpZXJCZWhhdmlvdXIobW9uc3Rlciwgc2tpZXIpIHtcblx0c2tpZXIuaXNFYXRlbkJ5KG1vbnN0ZXIsIGZ1bmN0aW9uICgpIHtcblx0XHRsaXZlc0xlZnQgLT0gMTtcblx0XHRtb25zdGVyLmlzRnVsbCA9IHRydWU7XG5cdFx0bW9uc3Rlci5pc0VhdGluZyA9IGZhbHNlO1xuXHRcdHNraWVyLmlzQmVpbmdFYXRlbiA9IGZhbHNlO1xuXHRcdG1vbnN0ZXIuc2V0U3BlZWQoc2tpZXIuZ2V0U3BlZWQoKSk7XG5cdFx0bW9uc3Rlci5zdG9wRm9sbG93aW5nKCk7XG5cdFx0dmFyIHJhbmRvbVBvc2l0aW9uQWJvdmUgPSBkQ29udGV4dC5nZXRSYW5kb21NYXBQb3NpdGlvbkFib3ZlVmlld3BvcnQoKTtcblx0XHRtb25zdGVyLnNldE1hcFBvc2l0aW9uVGFyZ2V0KHJhbmRvbVBvc2l0aW9uQWJvdmVbMF0sIHJhbmRvbVBvc2l0aW9uQWJvdmVbMV0pO1xuXHR9KTtcbn1cblxuZnVuY3Rpb24gc3RhcnROZXZlckVuZGluZ0dhbWUgKGltYWdlcykge1xuXHR2YXIgcGxheWVyO1xuXHR2YXIgc3RhcnRTaWduO1xuXHR2YXIgaW5mb0JveDtcblx0dmFyIGdhbWU7XG5cblx0ZnVuY3Rpb24gcmVzZXRHYW1lICgpIHtcblx0XHRkaXN0YW5jZVRyYXZlbGxlZEluTWV0cmVzID0gMDtcblx0XHRsaXZlc0xlZnQgPSA1O1xuXHRcdGhpZ2hTY29yZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdoaWdoU2NvcmUnKTtcblx0XHRnYW1lLnJlc2V0KCk7XG5cdFx0Z2FtZS5hZGRTdGF0aWNPYmplY3Qoc3RhcnRTaWduKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGRldGVjdEVuZCAoKSB7XG5cdFx0aWYgKCFnYW1lLmlzUGF1c2VkKCkpIHtcblx0XHRcdGhpZ2hTY29yZSA9IGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdoaWdoU2NvcmUnLCBkaXN0YW5jZVRyYXZlbGxlZEluTWV0cmVzKTtcblx0XHRcdGluZm9Cb3guc2V0TGluZXMoW1xuXHRcdFx0XHQnR2FtZSBvdmVyIScsXG5cdFx0XHRcdCdIaXQgc3BhY2UgdG8gcmVzdGFydCdcblx0XHRcdF0pO1xuXHRcdFx0Z2FtZS5wYXVzZSgpO1xuXHRcdFx0Z2FtZS5jeWNsZSgpO1xuXHRcdH1cblx0fVxuXG5cdGZ1bmN0aW9uIHJhbmRvbWx5U3Bhd25OUEMoc3Bhd25GdW5jdGlvbiwgZHJvcFJhdGUpIHtcblx0XHR2YXIgcmF0ZU1vZGlmaWVyID0gTWF0aC5tYXgoODAwIC0gbWFpbkNhbnZhcy53aWR0aCwgMCk7XG5cdFx0aWYgKE51bWJlci5yYW5kb20oMTAwMCArIHJhdGVNb2RpZmllcikgPD0gZHJvcFJhdGUpIHtcblx0XHRcdHNwYXduRnVuY3Rpb24oKTtcblx0XHR9XG5cdH1cblxuXHRmdW5jdGlvbiBzcGF3bk1vbnN0ZXIgKCkge1xuXHRcdHZhciBuZXdNb25zdGVyID0gbmV3IE1vbnN0ZXIoc3ByaXRlcy5tb25zdGVyKTtcblx0XHR2YXIgcmFuZG9tUG9zaXRpb24gPSBkQ29udGV4dC5nZXRSYW5kb21NYXBQb3NpdGlvbkFib3ZlVmlld3BvcnQoKTtcblx0XHRuZXdNb25zdGVyLnNldE1hcFBvc2l0aW9uKHJhbmRvbVBvc2l0aW9uWzBdLCByYW5kb21Qb3NpdGlvblsxXSk7XG5cdFx0bmV3TW9uc3Rlci5mb2xsb3cocGxheWVyKTtcblx0XHRuZXdNb25zdGVyLnNldFNwZWVkKHBsYXllci5nZXRTdGFuZGFyZFNwZWVkKCkpO1xuXHRcdG5ld01vbnN0ZXIub25IaXR0aW5nKHBsYXllciwgbW9uc3RlckhpdHNTa2llckJlaGF2aW91cik7XG5cblx0XHRnYW1lLmFkZE1vdmluZ09iamVjdChuZXdNb25zdGVyLCAnbW9uc3RlcicpO1xuXHR9XG5cblx0ZnVuY3Rpb24gc3Bhd25Cb2FyZGVyICgpIHtcblx0XHR2YXIgbmV3Qm9hcmRlciA9IG5ldyBTbm93Ym9hcmRlcihzcHJpdGVzLnNub3dib2FyZGVyKTtcblx0XHR2YXIgcmFuZG9tUG9zaXRpb25BYm92ZSA9IGRDb250ZXh0LmdldFJhbmRvbU1hcFBvc2l0aW9uQWJvdmVWaWV3cG9ydCgpO1xuXHRcdHZhciByYW5kb21Qb3NpdGlvbkJlbG93ID0gZENvbnRleHQuZ2V0UmFuZG9tTWFwUG9zaXRpb25CZWxvd1ZpZXdwb3J0KCk7XG5cdFx0bmV3Qm9hcmRlci5zZXRNYXBQb3NpdGlvbihyYW5kb21Qb3NpdGlvbkFib3ZlWzBdLCByYW5kb21Qb3NpdGlvbkFib3ZlWzFdKTtcblx0XHRuZXdCb2FyZGVyLnNldE1hcFBvc2l0aW9uVGFyZ2V0KHJhbmRvbVBvc2l0aW9uQmVsb3dbMF0sIHJhbmRvbVBvc2l0aW9uQmVsb3dbMV0pO1xuXHRcdG5ld0JvYXJkZXIub25IaXR0aW5nKHBsYXllciwgc3ByaXRlcy5zbm93Ym9hcmRlci5oaXRCZWhhdmlvdXIuc2tpZXIpO1xuXG5cdFx0Z2FtZS5hZGRNb3ZpbmdPYmplY3QobmV3Qm9hcmRlcik7XG5cdH1cblxuXHRwbGF5ZXIgPSBuZXcgU2tpZXIoc3ByaXRlcy5za2llcik7XG5cdHBsYXllci5zZXRNYXBQb3NpdGlvbigwLCAwKTtcblx0cGxheWVyLnNldE1hcFBvc2l0aW9uVGFyZ2V0KDAsIC0xMCk7XG5cdGlmICggbG9zZUxpZmVPbk9ic3RhY2xlSGl0ICkge1xuXHRcdHBsYXllci5zZXRIaXRPYnN0YWNsZUNiKGZ1bmN0aW9uKCkge1xuXHRcdFx0bGl2ZXNMZWZ0IC09IDE7XG5cdFx0fSk7XG5cdH1cblxuXHRnYW1lID0gbmV3IEdhbWUobWFpbkNhbnZhcywgcGxheWVyKTtcblxuXHRzdGFydFNpZ24gPSBuZXcgU3ByaXRlKHNwcml0ZXMuc2lnblN0YXJ0KTtcblx0Z2FtZS5hZGRTdGF0aWNPYmplY3Qoc3RhcnRTaWduKTtcblx0c3RhcnRTaWduLnNldE1hcFBvc2l0aW9uKC01MCwgMCk7XG5cdGRDb250ZXh0LmZvbGxvd1Nwcml0ZShwbGF5ZXIpO1xuXG5cdGluZm9Cb3ggPSBuZXcgSW5mb0JveCh7XG5cdFx0aW5pdGlhbExpbmVzIDogW1xuXHRcdFx0J1NraUZyZWUuanMnLFxuXHRcdFx0aW5mb0JveENvbnRyb2xzLFxuXHRcdFx0J1RyYXZlbGxlZCAwbScsXG5cdFx0XHQnSGlnaCBTY29yZTogJyArIGhpZ2hTY29yZSxcblx0XHRcdCdTa2llcnMgbGVmdDogJyArIGxpdmVzTGVmdCxcblx0XHRcdCdDcmVhdGVkIGJ5IERhbiBIb3VnaCAoQGJhc2ljYWxseWRhbiknXG5cdFx0XSxcblx0XHRwb3NpdGlvbjoge1xuXHRcdFx0dG9wOiAxNSxcblx0XHRcdHJpZ2h0OiAxMFxuXHRcdH1cblx0fSk7XG5cblx0Z2FtZS5iZWZvcmVDeWNsZShmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG5ld09iamVjdHMgPSBbXTtcblx0XHRpZiAocGxheWVyLmlzTW92aW5nKSB7XG5cdFx0XHRuZXdPYmplY3RzID0gU3ByaXRlLmNyZWF0ZU9iamVjdHMoW1xuXHRcdFx0XHR7IHNwcml0ZTogc3ByaXRlcy5zbWFsbFRyZWUsIGRyb3BSYXRlOiBkcm9wUmF0ZXMuc21hbGxUcmVlIH0sXG5cdFx0XHRcdHsgc3ByaXRlOiBzcHJpdGVzLnRhbGxUcmVlLCBkcm9wUmF0ZTogZHJvcFJhdGVzLnRhbGxUcmVlIH0sXG5cdFx0XHRcdHsgc3ByaXRlOiBzcHJpdGVzLmp1bXAsIGRyb3BSYXRlOiBkcm9wUmF0ZXMuanVtcCB9LFxuXHRcdFx0XHR7IHNwcml0ZTogc3ByaXRlcy50aGlja1Nub3csIGRyb3BSYXRlOiBkcm9wUmF0ZXMudGhpY2tTbm93IH0sXG5cdFx0XHRcdHsgc3ByaXRlOiBzcHJpdGVzLnJvY2ssIGRyb3BSYXRlOiBkcm9wUmF0ZXMucm9jayB9LFxuXHRcdFx0XSwge1xuXHRcdFx0XHRyYXRlTW9kaWZpZXI6IE1hdGgubWF4KDgwMCAtIG1haW5DYW52YXMud2lkdGgsIDApLFxuXHRcdFx0XHRwb3NpdGlvbjogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHJldHVybiBkQ29udGV4dC5nZXRSYW5kb21NYXBQb3NpdGlvbkJlbG93Vmlld3BvcnQoKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0cGxheWVyOiBwbGF5ZXJcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoIWdhbWUuaXNQYXVzZWQoKSkge1xuXHRcdFx0Z2FtZS5hZGRTdGF0aWNPYmplY3RzKG5ld09iamVjdHMpO1xuXG5cdFx0XHRyYW5kb21seVNwYXduTlBDKHNwYXduQm9hcmRlciwgMC4xKTtcblx0XHRcdGRpc3RhbmNlVHJhdmVsbGVkSW5NZXRyZXMgPSBwYXJzZUZsb2F0KHBsYXllci5nZXRQaXhlbHNUcmF2ZWxsZWREb3duTW91bnRhaW4oKSAvIHBpeGVsc1Blck1ldHJlKS50b0ZpeGVkKDEpO1xuXG5cdFx0XHRpZiAoZGlzdGFuY2VUcmF2ZWxsZWRJbk1ldHJlcyA+IG1vbnN0ZXJEaXN0YW5jZVRocmVzaG9sZCkge1xuXHRcdFx0XHRyYW5kb21seVNwYXduTlBDKHNwYXduTW9uc3RlciwgMC4wMDEpO1xuXHRcdFx0fVxuXG5cdFx0XHRpbmZvQm94LnNldExpbmVzKFtcblx0XHRcdFx0J1NraUZyZWUuanMnLFxuXHRcdFx0XHRpbmZvQm94Q29udHJvbHMsXG5cdFx0XHRcdCdUcmF2ZWxsZWQgJyArIGRpc3RhbmNlVHJhdmVsbGVkSW5NZXRyZXMgKyAnbScsXG5cdFx0XHRcdCdTa2llcnMgbGVmdDogJyArIGxpdmVzTGVmdCxcblx0XHRcdFx0J0hpZ2ggU2NvcmU6ICcgKyBoaWdoU2NvcmUsXG5cdFx0XHRcdCdDcmVhdGVkIGJ5IERhbiBIb3VnaCAoQGJhc2ljYWxseWRhbiknLFxuXHRcdFx0XHQnQ3VycmVudCBTcGVlZDogJyArIHBsYXllci5nZXRTcGVlZCgpLyosXG5cdFx0XHRcdCdTa2llciBNYXAgUG9zaXRpb246ICcgKyBwbGF5ZXIubWFwUG9zaXRpb25bMF0udG9GaXhlZCgxKSArICcsICcgKyBwbGF5ZXIubWFwUG9zaXRpb25bMV0udG9GaXhlZCgxKSxcblx0XHRcdFx0J01vdXNlIE1hcCBQb3NpdGlvbjogJyArIG1vdXNlTWFwUG9zaXRpb25bMF0udG9GaXhlZCgxKSArICcsICcgKyBtb3VzZU1hcFBvc2l0aW9uWzFdLnRvRml4ZWQoMSkqL1xuXHRcdFx0XSk7XG5cdFx0fVxuXHR9KTtcblxuXHRnYW1lLmFmdGVyQ3ljbGUoZnVuY3Rpb24oKSB7XG5cdFx0aWYgKGxpdmVzTGVmdCA9PT0gMCkge1xuXHRcdFx0ZGV0ZWN0RW5kKCk7XG5cdFx0fVxuXHR9KTtcblxuXHRnYW1lLmFkZFVJRWxlbWVudChpbmZvQm94KTtcblx0XG5cdCQobWFpbkNhbnZhcylcblx0Lm1vdXNlbW92ZShmdW5jdGlvbiAoZSkge1xuXHRcdGdhbWUuc2V0TW91c2VYKGUucGFnZVgpO1xuXHRcdGdhbWUuc2V0TW91c2VZKGUucGFnZVkpO1xuXHRcdHBsYXllci5yZXNldERpcmVjdGlvbigpO1xuXHRcdHBsYXllci5zdGFydE1vdmluZ0lmUG9zc2libGUoKTtcblx0fSlcblx0LmJpbmQoJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcblx0XHRnYW1lLnNldE1vdXNlWChlLnBhZ2VYKTtcblx0XHRnYW1lLnNldE1vdXNlWShlLnBhZ2VZKTtcblx0XHRwbGF5ZXIucmVzZXREaXJlY3Rpb24oKTtcblx0XHRwbGF5ZXIuc3RhcnRNb3ZpbmdJZlBvc3NpYmxlKCk7XG5cdH0pXG5cdC5mb2N1cygpOyAvLyBTbyB3ZSBjYW4gbGlzdGVuIHRvIGV2ZW50cyBpbW1lZGlhdGVseVxuXG5cdE1vdXNldHJhcC5iaW5kKCdmJywgcGxheWVyLnNwZWVkQm9vc3QpO1xuXHRNb3VzZXRyYXAuYmluZCgndCcsIHBsYXllci5hdHRlbXB0VHJpY2spO1xuXHRNb3VzZXRyYXAuYmluZChbJ3cnLCAndXAnXSwgZnVuY3Rpb24gKCkge1xuXHRcdHBsYXllci5zdG9wKCk7XG5cdH0pO1xuXHRNb3VzZXRyYXAuYmluZChbJ2EnLCAnbGVmdCddLCBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHBsYXllci5kaXJlY3Rpb24gPT09IDI3MCkge1xuXHRcdFx0cGxheWVyLnN0ZXBXZXN0KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBsYXllci50dXJuV2VzdCgpO1xuXHRcdH1cblx0fSk7XG5cdE1vdXNldHJhcC5iaW5kKFsncycsICdkb3duJ10sIGZ1bmN0aW9uICgpIHtcblx0XHRwbGF5ZXIuc2V0RGlyZWN0aW9uKDE4MCk7XG5cdFx0cGxheWVyLnN0YXJ0TW92aW5nSWZQb3NzaWJsZSgpO1xuXHR9KTtcblx0TW91c2V0cmFwLmJpbmQoWydkJywgJ3JpZ2h0J10sIGZ1bmN0aW9uICgpIHtcblx0XHRpZiAocGxheWVyLmRpcmVjdGlvbiA9PT0gOTApIHtcblx0XHRcdHBsYXllci5zdGVwRWFzdCgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwbGF5ZXIudHVybkVhc3QoKTtcblx0XHR9XG5cdH0pO1xuXHRNb3VzZXRyYXAuYmluZCgnbScsIHNwYXduTW9uc3Rlcik7XG5cdE1vdXNldHJhcC5iaW5kKCdiJywgc3Bhd25Cb2FyZGVyKTtcblx0TW91c2V0cmFwLmJpbmQoJ3NwYWNlJywgcmVzZXRHYW1lKTtcblxuXHR2YXIgaGFtbWVydGltZSA9IEhhbW1lcihtYWluQ2FudmFzKS5vbigncHJlc3MnLCBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRnYW1lLnNldE1vdXNlWChlLmNlbnRlci54KTtcblx0XHRnYW1lLnNldE1vdXNlWShlLmNlbnRlci55KTtcblx0fSkub24oJ3RhcCcsIGZ1bmN0aW9uIChlKSB7XG5cdFx0Z2FtZS5zZXRNb3VzZVgoZS5jZW50ZXIueCk7XG5cdFx0Z2FtZS5zZXRNb3VzZVkoZS5jZW50ZXIueSk7XG5cdH0pLm9uKCdwYW4nLCBmdW5jdGlvbiAoZSkge1xuXHRcdGdhbWUuc2V0TW91c2VYKGUuY2VudGVyLngpO1xuXHRcdGdhbWUuc2V0TW91c2VZKGUuY2VudGVyLnkpO1xuXHRcdHBsYXllci5yZXNldERpcmVjdGlvbigpO1xuXHRcdHBsYXllci5zdGFydE1vdmluZ0lmUG9zc2libGUoKTtcblx0fSkub24oJ2RvdWJsZXRhcCcsIGZ1bmN0aW9uIChlKSB7XG5cdFx0cGxheWVyLnNwZWVkQm9vc3QoKTtcblx0fSk7XG5cblx0cGxheWVyLmlzTW92aW5nID0gZmFsc2U7XG5cdHBsYXllci5zZXREaXJlY3Rpb24oMjcwKTtcblxuXHRnYW1lLnN0YXJ0KCk7XG59XG5cbmZ1bmN0aW9uIHJlc2l6ZUNhbnZhcygpIHtcblx0bWFpbkNhbnZhcy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRtYWluQ2FudmFzLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHJlc2l6ZUNhbnZhcywgZmFsc2UpO1xuXG5yZXNpemVDYW52YXMoKTtcblxubG9hZEltYWdlcyhpbWFnZVNvdXJjZXMsIHN0YXJ0TmV2ZXJFbmRpbmdHYW1lKTtcblxudGhpcy5leHBvcnRzID0gd2luZG93O1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpIHtcblx0dmFyIHNwcml0ZXMgPSB7XG5cdFx0J3NraWVyJyA6IHtcblx0XHRcdCRpbWFnZUZpbGUgOiAnc3ByaXRlLWNoYXJhY3RlcnMucG5nJyxcblx0XHRcdHBhcnRzIDoge1xuXHRcdFx0XHRibGFuayA6IFsgMCwgMCwgMCwgMCBdLFxuXHRcdFx0XHRlYXN0IDogWyAwLCAwLCAyNCwgMzQgXSxcblx0XHRcdFx0ZXNFYXN0IDogWyAyNCwgMCwgMjQsIDM0IF0sXG5cdFx0XHRcdHNFYXN0IDogWyA0OSwgMCwgMTcsIDM0IF0sXG5cdFx0XHRcdHNvdXRoIDogWyA2NSwgMCwgMTcsIDM0IF0sXG5cdFx0XHRcdHNXZXN0IDogWyA0OSwgMzcsIDE3LCAzNCBdLFxuXHRcdFx0XHR3c1dlc3QgOiBbIDI0LCAzNywgMjQsIDM0IF0sXG5cdFx0XHRcdHdlc3QgOiBbIDAsIDM3LCAyNCwgMzQgXSxcblx0XHRcdFx0aGl0IDogWyAwLCA3OCwgMzEsIDMxIF0sXG5cdFx0XHRcdGp1bXBpbmcgOiBbIDg0LCAwLCAzMiwgMzQgXSxcblx0XHRcdFx0c29tZXJzYXVsdDEgOiBbIDExNiwgMCwgMzIsIDM0IF0sXG5cdFx0XHRcdHNvbWVyc2F1bHQyIDogWyAxNDgsIDAsIDMyLCAzNCBdXG5cdFx0XHR9LFxuXHRcdFx0aGl0Qm94ZXM6IHtcblx0XHRcdFx0MDogWyA3LCAyMCwgMjcsIDM0IF1cblx0XHRcdH0sXG5cdFx0XHRpZCA6ICdwbGF5ZXInLFxuXHRcdFx0aGl0QmVoYXZpb3VyOiB7fVxuXHRcdH0sXG5cdFx0J3NtYWxsVHJlZScgOiB7XG5cdFx0XHQkaW1hZ2VGaWxlIDogJ3NraWZyZWUtb2JqZWN0cy5wbmcnLFxuXHRcdFx0cGFydHMgOiB7XG5cdFx0XHRcdG1haW4gOiBbIDAsIDI4LCAzMCwgMzQgXVxuXHRcdFx0fSxcblx0XHRcdGhpdEJveGVzOiB7XG5cdFx0XHRcdDA6IFsgMCwgMTgsIDMwLCAzNCBdXG5cdFx0XHR9LFxuXHRcdFx0aGl0QmVoYXZpb3VyOiB7fVxuXHRcdH0sXG5cdFx0J3RhbGxUcmVlJyA6IHtcblx0XHRcdCRpbWFnZUZpbGUgOiAnc2tpZnJlZS1vYmplY3RzLnBuZycsXG5cdFx0XHRwYXJ0cyA6IHtcblx0XHRcdFx0bWFpbiA6IFsgOTUsIDY2LCAzMiwgNjQgXVxuXHRcdFx0fSxcblx0XHRcdHpJbmRleGVzT2NjdXBpZWQgOiBbMCwgMV0sXG5cdFx0XHRoaXRCb3hlczoge1xuXHRcdFx0XHQwOiBbMCwgNTQsIDMyLCA2NF0sXG5cdFx0XHRcdDE6IFswLCAxMCwgMzIsIDU0XVxuXHRcdFx0fSxcblx0XHRcdGhpdEJlaGF2aW91cjoge31cblx0XHR9LFxuXHRcdCd0aGlja1Nub3cnIDoge1xuXHRcdFx0JGltYWdlRmlsZSA6ICdza2lmcmVlLW9iamVjdHMucG5nJyxcblx0XHRcdHBhcnRzIDoge1xuXHRcdFx0XHRtYWluIDogWyAxNDMsIDUzLCA0MywgMTAgXVxuXHRcdFx0fSxcblx0XHRcdGhpdEJlaGF2aW91cjoge31cblx0XHR9LFxuXHRcdCdyb2NrJyA6IHtcblx0XHRcdCRpbWFnZUZpbGUgOiAnc2tpZnJlZS1vYmplY3RzLnBuZycsXG5cdFx0XHRwYXJ0cyA6IHtcblx0XHRcdFx0bWFpbiA6IFsgMzAsIDUyLCAyMywgMTEgXVxuXHRcdFx0fSxcblx0XHRcdGhpdEJlaGF2aW91cjoge31cblx0XHR9LFxuXHRcdCdtb25zdGVyJyA6IHtcblx0XHRcdCRpbWFnZUZpbGUgOiAnc3ByaXRlLWNoYXJhY3RlcnMucG5nJyxcblx0XHRcdHBhcnRzIDoge1xuXHRcdFx0XHRzRWFzdDEgOiBbIDY0LCAxMTIsIDI2LCA0MyBdLFxuXHRcdFx0XHRzRWFzdDIgOiBbIDkwLCAxMTIsIDMyLCA0MyBdLFxuXHRcdFx0XHRzV2VzdDEgOiBbIDY0LCAxNTgsIDI2LCA0MyBdLFxuXHRcdFx0XHRzV2VzdDIgOiBbIDkwLCAxNTgsIDMyLCA0MyBdLFxuXHRcdFx0XHRlYXRpbmcxIDogWyAxMjIsIDExMiwgMzQsIDQzIF0sXG5cdFx0XHRcdGVhdGluZzIgOiBbIDE1NiwgMTEyLCAzMSwgNDMgXSxcblx0XHRcdFx0ZWF0aW5nMyA6IFsgMTg3LCAxMTIsIDMxLCA0MyBdLFxuXHRcdFx0XHRlYXRpbmc0IDogWyAyMTksIDExMiwgMjUsIDQzIF0sXG5cdFx0XHRcdGVhdGluZzUgOiBbIDI0MywgMTEyLCAyNiwgNDMgXVxuXHRcdFx0fSxcblx0XHRcdGhpdEJlaGF2aW91cjoge31cblx0XHR9LFxuXHRcdCdqdW1wJyA6IHtcblx0XHRcdCRpbWFnZUZpbGUgOiAnc2tpZnJlZS1vYmplY3RzLnBuZycsXG5cdFx0XHRwYXJ0cyA6IHtcblx0XHRcdFx0bWFpbiA6IFsgMTA5LCA1NSwgMzIsIDggXVxuXHRcdFx0fSxcblx0XHRcdGhpdEJlaGF2aW91cjoge31cblx0XHR9LFxuXHRcdCdzaWduU3RhcnQnIDoge1xuXHRcdFx0JGltYWdlRmlsZSA6ICdza2lmcmVlLW9iamVjdHMucG5nJyxcblx0XHRcdHBhcnRzIDoge1xuXHRcdFx0XHRtYWluIDogWyAyNjAsIDEwMywgNDIsIDI3IF1cblx0XHRcdH0sXG5cdFx0XHRoaXRCZWhhdmlvdXI6IHt9XG5cdFx0fSxcblx0XHQnc25vd2JvYXJkZXInIDoge1xuXHRcdFx0JGltYWdlRmlsZSA6ICdzcHJpdGUtY2hhcmFjdGVycy5wbmcnLFxuXHRcdFx0cGFydHMgOiB7XG5cdFx0XHRcdHNFYXN0IDogWyA3MywgMjI5LCAyMCwgMjkgXSxcblx0XHRcdFx0c1dlc3QgOiBbIDk1LCAyMjgsIDI2LCAzMCBdXG5cdFx0XHR9LFxuXHRcdFx0aGl0QmVoYXZpb3VyOiB7fVxuXHRcdH0sXG5cdFx0J2VtcHR5Q2hhaXJMaWZ0Jzoge1xuXHRcdFx0JGltYWdlRmlsZSA6ICdza2lmcmVlLW9iamVjdHMucG5nJyxcblx0XHRcdHBhcnRzOiB7XG5cdFx0XHRcdG1haW4gOiBbIDkyLCAxMzYsIDI2LCAzMCBdXG5cdFx0XHR9LFxuXHRcdFx0ekluZGV4ZXNPY2N1cGllZCA6IFsxXSxcblx0XHR9XG5cdH07XG5cblx0ZnVuY3Rpb24gbW9uc3RlckhpdHNUcmVlQmVoYXZpb3VyKG1vbnN0ZXIpIHtcblx0XHRtb25zdGVyLmRlbGV0ZU9uTmV4dEN5Y2xlKCk7XG5cdH1cblxuXHRzcHJpdGVzLm1vbnN0ZXIuaGl0QmVoYXZpb3VyLnRyZWUgPSBtb25zdGVySGl0c1RyZWVCZWhhdmlvdXI7XG5cblx0ZnVuY3Rpb24gdHJlZUhpdHNNb25zdGVyQmVoYXZpb3VyKHRyZWUsIG1vbnN0ZXIpIHtcblx0XHRtb25zdGVyLmRlbGV0ZU9uTmV4dEN5Y2xlKCk7XG5cdH1cblxuXHRzcHJpdGVzLnNtYWxsVHJlZS5oaXRCZWhhdmlvdXIubW9uc3RlciA9IHRyZWVIaXRzTW9uc3RlckJlaGF2aW91cjtcblx0c3ByaXRlcy50YWxsVHJlZS5oaXRCZWhhdmlvdXIubW9uc3RlciA9IHRyZWVIaXRzTW9uc3RlckJlaGF2aW91cjtcblxuXHRmdW5jdGlvbiBza2llckhpdHNUcmVlQmVoYXZpb3VyKHNraWVyLCB0cmVlKSB7XG5cdFx0c2tpZXIuaGFzSGl0T2JzdGFjbGUodHJlZSk7XG5cdH1cblxuXHRmdW5jdGlvbiB0cmVlSGl0c1NraWVyQmVoYXZpb3VyKHRyZWUsIHNraWVyKSB7XG5cdFx0c2tpZXIuaGFzSGl0T2JzdGFjbGUodHJlZSk7XG5cdH1cblxuXHRzcHJpdGVzLnNtYWxsVHJlZS5oaXRCZWhhdmlvdXIuc2tpZXIgPSB0cmVlSGl0c1NraWVyQmVoYXZpb3VyO1xuXHRzcHJpdGVzLnRhbGxUcmVlLmhpdEJlaGF2aW91ci5za2llciA9IHRyZWVIaXRzU2tpZXJCZWhhdmlvdXI7XG5cblx0ZnVuY3Rpb24gcm9ja0hpdHNTa2llckJlaGF2aW91cihyb2NrLCBza2llcikge1xuXHRcdHNraWVyLmhhc0hpdE9ic3RhY2xlKHJvY2spO1xuXHR9XG5cblx0c3ByaXRlcy5yb2NrLmhpdEJlaGF2aW91ci5za2llciA9IHJvY2tIaXRzU2tpZXJCZWhhdmlvdXI7XG5cblx0ZnVuY3Rpb24gc2tpZXJIaXRzSnVtcEJlaGF2aW91cihza2llciwganVtcCkge1xuXHRcdHNraWVyLmhhc0hpdEp1bXAoanVtcCk7XG5cdH1cblxuXHRmdW5jdGlvbiBqdW1wSGl0c1NraWVyQmVoYXZpb3VyKGp1bXAsIHNraWVyKSB7XG5cdFx0c2tpZXIuaGFzSGl0SnVtcChqdW1wKTtcblx0fVxuXG5cdHNwcml0ZXMuanVtcC5oaXRCZWhhdmlvdXIuc2tpZXIgPSBqdW1wSGl0c1NraWVyQmVoYXZpb3VyO1xuXG4vLyBSZWFsbHkgbm90IGEgZmFuIG9mIHRoaXMgYmVoYXZpb3VyLlxuLypcdGZ1bmN0aW9uIHNraWVySGl0c1RoaWNrU25vd0JlaGF2aW91cihza2llciwgdGhpY2tTbm93KSB7XG5cdFx0Ly8gTmVlZCB0byBpbXBsZW1lbnQgdGhpcyBwcm9wZXJseVxuXHRcdHNraWVyLnNldFNwZWVkKDIpO1xuXHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRza2llci5yZXNldFNwZWVkKCk7XG5cdFx0fSwgNzAwKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHRoaWNrU25vd0hpdHNTa2llckJlaGF2aW91cih0aGlja1Nub3csIHNraWVyKSB7XG5cdFx0Ly8gTmVlZCB0byBpbXBsZW1lbnQgdGhpcyBwcm9wZXJseVxuXHRcdHNraWVyLnNldFNwZWVkKDIpO1xuXHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRza2llci5yZXNldFNwZWVkKCk7XG5cdFx0fSwgMzAwKTtcblx0fSovXG5cblx0Ly8gc3ByaXRlcy50aGlja1Nub3cuaGl0QmVoYXZpb3VyLnNraWVyID0gdGhpY2tTbm93SGl0c1NraWVyQmVoYXZpb3VyO1xuXG5cdGZ1bmN0aW9uIHNub3dib2FyZGVySGl0c1NraWVyQmVoYXZpb3VyKHNub3dib2FyZGVyLCBza2llcikge1xuXHRcdHNraWVyLmhhc0hpdE9ic3RhY2xlKHNub3dib2FyZGVyKTtcblx0fVxuXG5cdHNwcml0ZXMuc25vd2JvYXJkZXIuaGl0QmVoYXZpb3VyLnNraWVyID0gc25vd2JvYXJkZXJIaXRzU2tpZXJCZWhhdmlvdXI7XG5cblx0Z2xvYmFsLnNwcml0ZUluZm8gPSBzcHJpdGVzO1xufSkoIHRoaXMgKTtcblxuXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0bW9kdWxlLmV4cG9ydHMgPSB0aGlzLnNwcml0ZUluZm87XG59IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMiBDcmFpZyBDYW1wYmVsbFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqIE1vdXNldHJhcCBpcyBhIHNpbXBsZSBrZXlib2FyZCBzaG9ydGN1dCBsaWJyYXJ5IGZvciBKYXZhc2NyaXB0IHdpdGhcbiAqIG5vIGV4dGVybmFsIGRlcGVuZGVuY2llc1xuICpcbiAqIEB2ZXJzaW9uIDEuMS4zXG4gKiBAdXJsIGNyYWlnLmlzL2tpbGxpbmcvbWljZVxuICovXG4oZnVuY3Rpb24oKSB7XG5cbiAgICAvKipcbiAgICAgKiBtYXBwaW5nIG9mIHNwZWNpYWwga2V5Y29kZXMgdG8gdGhlaXIgY29ycmVzcG9uZGluZyBrZXlzXG4gICAgICpcbiAgICAgKiBldmVyeXRoaW5nIGluIHRoaXMgZGljdGlvbmFyeSBjYW5ub3QgdXNlIGtleXByZXNzIGV2ZW50c1xuICAgICAqIHNvIGl0IGhhcyB0byBiZSBoZXJlIHRvIG1hcCB0byB0aGUgY29ycmVjdCBrZXljb2RlcyBmb3JcbiAgICAgKiBrZXl1cC9rZXlkb3duIGV2ZW50c1xuICAgICAqXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB2YXIgX01BUCA9IHtcbiAgICAgICAgICAgIDg6ICdiYWNrc3BhY2UnLFxuICAgICAgICAgICAgOTogJ3RhYicsXG4gICAgICAgICAgICAxMzogJ2VudGVyJyxcbiAgICAgICAgICAgIDE2OiAnc2hpZnQnLFxuICAgICAgICAgICAgMTc6ICdjdHJsJyxcbiAgICAgICAgICAgIDE4OiAnYWx0JyxcbiAgICAgICAgICAgIDIwOiAnY2Fwc2xvY2snLFxuICAgICAgICAgICAgMjc6ICdlc2MnLFxuICAgICAgICAgICAgMzI6ICdzcGFjZScsXG4gICAgICAgICAgICAzMzogJ3BhZ2V1cCcsXG4gICAgICAgICAgICAzNDogJ3BhZ2Vkb3duJyxcbiAgICAgICAgICAgIDM1OiAnZW5kJyxcbiAgICAgICAgICAgIDM2OiAnaG9tZScsXG4gICAgICAgICAgICAzNzogJ2xlZnQnLFxuICAgICAgICAgICAgMzg6ICd1cCcsXG4gICAgICAgICAgICAzOTogJ3JpZ2h0JyxcbiAgICAgICAgICAgIDQwOiAnZG93bicsXG4gICAgICAgICAgICA0NTogJ2lucycsXG4gICAgICAgICAgICA0NjogJ2RlbCcsXG4gICAgICAgICAgICA5MTogJ21ldGEnLFxuICAgICAgICAgICAgOTM6ICdtZXRhJyxcbiAgICAgICAgICAgIDIyNDogJ21ldGEnXG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1hcHBpbmcgZm9yIHNwZWNpYWwgY2hhcmFjdGVycyBzbyB0aGV5IGNhbiBzdXBwb3J0XG4gICAgICAgICAqXG4gICAgICAgICAqIHRoaXMgZGljdGlvbmFyeSBpcyBvbmx5IHVzZWQgaW5jYXNlIHlvdSB3YW50IHRvIGJpbmQgYVxuICAgICAgICAgKiBrZXl1cCBvciBrZXlkb3duIGV2ZW50IHRvIG9uZSBvZiB0aGVzZSBrZXlzXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICAgICAqL1xuICAgICAgICBfS0VZQ09ERV9NQVAgPSB7XG4gICAgICAgICAgICAxMDY6ICcqJyxcbiAgICAgICAgICAgIDEwNzogJysnLFxuICAgICAgICAgICAgMTA5OiAnLScsXG4gICAgICAgICAgICAxMTA6ICcuJyxcbiAgICAgICAgICAgIDExMSA6ICcvJyxcbiAgICAgICAgICAgIDE4NjogJzsnLFxuICAgICAgICAgICAgMTg3OiAnPScsXG4gICAgICAgICAgICAxODg6ICcsJyxcbiAgICAgICAgICAgIDE4OTogJy0nLFxuICAgICAgICAgICAgMTkwOiAnLicsXG4gICAgICAgICAgICAxOTE6ICcvJyxcbiAgICAgICAgICAgIDE5MjogJ2AnLFxuICAgICAgICAgICAgMjE5OiAnWycsXG4gICAgICAgICAgICAyMjA6ICdcXFxcJyxcbiAgICAgICAgICAgIDIyMTogJ10nLFxuICAgICAgICAgICAgMjIyOiAnXFwnJ1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGlzIGlzIGEgbWFwcGluZyBvZiBrZXlzIHRoYXQgcmVxdWlyZSBzaGlmdCBvbiBhIFVTIGtleXBhZFxuICAgICAgICAgKiBiYWNrIHRvIHRoZSBub24gc2hpZnQgZXF1aXZlbGVudHNcbiAgICAgICAgICpcbiAgICAgICAgICogdGhpcyBpcyBzbyB5b3UgY2FuIHVzZSBrZXl1cCBldmVudHMgd2l0aCB0aGVzZSBrZXlzXG4gICAgICAgICAqXG4gICAgICAgICAqIG5vdGUgdGhhdCB0aGlzIHdpbGwgb25seSB3b3JrIHJlbGlhYmx5IG9uIFVTIGtleWJvYXJkc1xuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgX1NISUZUX01BUCA9IHtcbiAgICAgICAgICAgICd+JzogJ2AnLFxuICAgICAgICAgICAgJyEnOiAnMScsXG4gICAgICAgICAgICAnQCc6ICcyJyxcbiAgICAgICAgICAgICcjJzogJzMnLFxuICAgICAgICAgICAgJyQnOiAnNCcsXG4gICAgICAgICAgICAnJSc6ICc1JyxcbiAgICAgICAgICAgICdeJzogJzYnLFxuICAgICAgICAgICAgJyYnOiAnNycsXG4gICAgICAgICAgICAnKic6ICc4JyxcbiAgICAgICAgICAgICcoJzogJzknLFxuICAgICAgICAgICAgJyknOiAnMCcsXG4gICAgICAgICAgICAnXyc6ICctJyxcbiAgICAgICAgICAgICcrJzogJz0nLFxuICAgICAgICAgICAgJzonOiAnOycsXG4gICAgICAgICAgICAnXFxcIic6ICdcXCcnLFxuICAgICAgICAgICAgJzwnOiAnLCcsXG4gICAgICAgICAgICAnPic6ICcuJyxcbiAgICAgICAgICAgICc/JzogJy8nLFxuICAgICAgICAgICAgJ3wnOiAnXFxcXCdcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogdGhpcyBpcyBhIGxpc3Qgb2Ygc3BlY2lhbCBzdHJpbmdzIHlvdSBjYW4gdXNlIHRvIG1hcFxuICAgICAgICAgKiB0byBtb2RpZmllciBrZXlzIHdoZW4geW91IHNwZWNpZnkgeW91ciBrZXlib2FyZCBzaG9ydGN1dHNcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAgICovXG4gICAgICAgIF9TUEVDSUFMX0FMSUFTRVMgPSB7XG4gICAgICAgICAgICAnb3B0aW9uJzogJ2FsdCcsXG4gICAgICAgICAgICAnY29tbWFuZCc6ICdtZXRhJyxcbiAgICAgICAgICAgICdyZXR1cm4nOiAnZW50ZXInLFxuICAgICAgICAgICAgJ2VzY2FwZSc6ICdlc2MnXG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHZhcmlhYmxlIHRvIHN0b3JlIHRoZSBmbGlwcGVkIHZlcnNpb24gb2YgX01BUCBmcm9tIGFib3ZlXG4gICAgICAgICAqIG5lZWRlZCB0byBjaGVjayBpZiB3ZSBzaG91bGQgdXNlIGtleXByZXNzIG9yIG5vdCB3aGVuIG5vIGFjdGlvblxuICAgICAgICAgKiBpcyBzcGVjaWZpZWRcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge09iamVjdHx1bmRlZmluZWR9XG4gICAgICAgICAqL1xuICAgICAgICBfUkVWRVJTRV9NQVAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGEgbGlzdCBvZiBhbGwgdGhlIGNhbGxiYWNrcyBzZXR1cCB2aWEgTW91c2V0cmFwLmJpbmQoKVxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgX2NhbGxiYWNrcyA9IHt9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBkaXJlY3QgbWFwIG9mIHN0cmluZyBjb21iaW5hdGlvbnMgdG8gY2FsbGJhY2tzIHVzZWQgZm9yIHRyaWdnZXIoKVxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgX2RpcmVjdF9tYXAgPSB7fSxcblxuICAgICAgICAvKipcbiAgICAgICAgICoga2VlcHMgdHJhY2sgb2Ygd2hhdCBsZXZlbCBlYWNoIHNlcXVlbmNlIGlzIGF0IHNpbmNlIG11bHRpcGxlXG4gICAgICAgICAqIHNlcXVlbmNlcyBjYW4gc3RhcnQgb3V0IHdpdGggdGhlIHNhbWUgc2VxdWVuY2VcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAgICovXG4gICAgICAgIF9zZXF1ZW5jZV9sZXZlbHMgPSB7fSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogdmFyaWFibGUgdG8gc3RvcmUgdGhlIHNldFRpbWVvdXQgY2FsbFxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7bnVsbHxudW1iZXJ9XG4gICAgICAgICAqL1xuICAgICAgICBfcmVzZXRfdGltZXIsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRlbXBvcmFyeSBzdGF0ZSB3aGVyZSB3ZSB3aWxsIGlnbm9yZSB0aGUgbmV4dCBrZXl1cFxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbnxzdHJpbmd9XG4gICAgICAgICAqL1xuICAgICAgICBfaWdub3JlX25leHRfa2V5dXAgPSBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogYXJlIHdlIGN1cnJlbnRseSBpbnNpZGUgb2YgYSBzZXF1ZW5jZT9cbiAgICAgICAgICogdHlwZSBvZiBhY3Rpb24gKFwia2V5dXBcIiBvciBcImtleWRvd25cIiBvciBcImtleXByZXNzXCIpIG9yIGZhbHNlXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0eXBlIHtib29sZWFufHN0cmluZ31cbiAgICAgICAgICovXG4gICAgICAgIF9pbnNpZGVfc2VxdWVuY2UgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIGxvb3AgdGhyb3VnaCB0aGUgZiBrZXlzLCBmMSB0byBmMTkgYW5kIGFkZCB0aGVtIHRvIHRoZSBtYXBcbiAgICAgKiBwcm9ncmFtYXRpY2FsbHlcbiAgICAgKi9cbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IDIwOyArK2kpIHtcbiAgICAgICAgX01BUFsxMTEgKyBpXSA9ICdmJyArIGk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbG9vcCB0aHJvdWdoIHRvIG1hcCBudW1iZXJzIG9uIHRoZSBudW1lcmljIGtleXBhZFxuICAgICAqL1xuICAgIGZvciAoaSA9IDA7IGkgPD0gOTsgKytpKSB7XG4gICAgICAgIF9NQVBbaSArIDk2XSA9IGk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogY3Jvc3MgYnJvd3NlciBhZGQgZXZlbnQgbWV0aG9kXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR8SFRNTERvY3VtZW50fSBvYmplY3RcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIF9hZGRFdmVudChvYmplY3QsIHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChvYmplY3QuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgb2JqZWN0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2ssIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG9iamVjdC5hdHRhY2hFdmVudCgnb24nICsgdHlwZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHRha2VzIHRoZSBldmVudCBhbmQgcmV0dXJucyB0aGUga2V5IGNoYXJhY3RlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtFdmVudH0gZVxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfY2hhcmFjdGVyRnJvbUV2ZW50KGUpIHtcblxuICAgICAgICAvLyBmb3Iga2V5cHJlc3MgZXZlbnRzIHdlIHNob3VsZCByZXR1cm4gdGhlIGNoYXJhY3RlciBhcyBpc1xuICAgICAgICBpZiAoZS50eXBlID09ICdrZXlwcmVzcycpIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGUud2hpY2gpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZm9yIG5vbiBrZXlwcmVzcyBldmVudHMgdGhlIHNwZWNpYWwgbWFwcyBhcmUgbmVlZGVkXG4gICAgICAgIGlmIChfTUFQW2Uud2hpY2hdKSB7XG4gICAgICAgICAgICByZXR1cm4gX01BUFtlLndoaWNoXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfS0VZQ09ERV9NQVBbZS53aGljaF0pIHtcbiAgICAgICAgICAgIHJldHVybiBfS0VZQ09ERV9NQVBbZS53aGljaF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBpdCBpcyBub3QgaW4gdGhlIHNwZWNpYWwgbWFwXG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGUud2hpY2gpLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogY2hlY2tzIGlmIHR3byBhcnJheXMgYXJlIGVxdWFsXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBtb2RpZmllcnMxXG4gICAgICogQHBhcmFtIHtBcnJheX0gbW9kaWZpZXJzMlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIF9tb2RpZmllcnNNYXRjaChtb2RpZmllcnMxLCBtb2RpZmllcnMyKSB7XG4gICAgICAgIHJldHVybiBtb2RpZmllcnMxLnNvcnQoKS5qb2luKCcsJykgPT09IG1vZGlmaWVyczIuc29ydCgpLmpvaW4oJywnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXNldHMgYWxsIHNlcXVlbmNlIGNvdW50ZXJzIGV4Y2VwdCBmb3IgdGhlIG9uZXMgcGFzc2VkIGluXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZG9fbm90X3Jlc2V0XG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIF9yZXNldFNlcXVlbmNlcyhkb19ub3RfcmVzZXQpIHtcbiAgICAgICAgZG9fbm90X3Jlc2V0ID0gZG9fbm90X3Jlc2V0IHx8IHt9O1xuXG4gICAgICAgIHZhciBhY3RpdmVfc2VxdWVuY2VzID0gZmFsc2UsXG4gICAgICAgICAgICBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gX3NlcXVlbmNlX2xldmVscykge1xuICAgICAgICAgICAgaWYgKGRvX25vdF9yZXNldFtrZXldKSB7XG4gICAgICAgICAgICAgICAgYWN0aXZlX3NlcXVlbmNlcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfc2VxdWVuY2VfbGV2ZWxzW2tleV0gPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFhY3RpdmVfc2VxdWVuY2VzKSB7XG4gICAgICAgICAgICBfaW5zaWRlX3NlcXVlbmNlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmaW5kcyBhbGwgY2FsbGJhY2tzIHRoYXQgbWF0Y2ggYmFzZWQgb24gdGhlIGtleWNvZGUsIG1vZGlmaWVycyxcbiAgICAgKiBhbmQgYWN0aW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2hhcmFjdGVyXG4gICAgICogQHBhcmFtIHtBcnJheX0gbW9kaWZpZXJzXG4gICAgICogQHBhcmFtIHtFdmVudHxPYmplY3R9IGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSByZW1vdmUgLSBzaG91bGQgd2UgcmVtb3ZlIGFueSBtYXRjaGVzXG4gICAgICogQHBhcmFtIHtzdHJpbmc9fSBjb21iaW5hdGlvblxuICAgICAqIEByZXR1cm5zIHtBcnJheX1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfZ2V0TWF0Y2hlcyhjaGFyYWN0ZXIsIG1vZGlmaWVycywgZSwgcmVtb3ZlLCBjb21iaW5hdGlvbikge1xuICAgICAgICB2YXIgaSxcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgbWF0Y2hlcyA9IFtdLFxuICAgICAgICAgICAgYWN0aW9uID0gZS50eXBlO1xuXG4gICAgICAgIC8vIGlmIHRoZXJlIGFyZSBubyBldmVudHMgcmVsYXRlZCB0byB0aGlzIGtleWNvZGVcbiAgICAgICAgaWYgKCFfY2FsbGJhY2tzW2NoYXJhY3Rlcl0pIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIGEgbW9kaWZpZXIga2V5IGlzIGNvbWluZyB1cCBvbiBpdHMgb3duIHdlIHNob3VsZCBhbGxvdyBpdFxuICAgICAgICBpZiAoYWN0aW9uID09ICdrZXl1cCcgJiYgX2lzTW9kaWZpZXIoY2hhcmFjdGVyKSkge1xuICAgICAgICAgICAgbW9kaWZpZXJzID0gW2NoYXJhY3Rlcl07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBsb29wIHRocm91Z2ggYWxsIGNhbGxiYWNrcyBmb3IgdGhlIGtleSB0aGF0IHdhcyBwcmVzc2VkXG4gICAgICAgIC8vIGFuZCBzZWUgaWYgYW55IG9mIHRoZW0gbWF0Y2hcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IF9jYWxsYmFja3NbY2hhcmFjdGVyXS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY2FsbGJhY2sgPSBfY2FsbGJhY2tzW2NoYXJhY3Rlcl1baV07XG5cbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBzZXF1ZW5jZSBidXQgaXQgaXMgbm90IGF0IHRoZSByaWdodCBsZXZlbFxuICAgICAgICAgICAgLy8gdGhlbiBtb3ZlIG9udG8gdGhlIG5leHQgbWF0Y2hcbiAgICAgICAgICAgIGlmIChjYWxsYmFjay5zZXEgJiYgX3NlcXVlbmNlX2xldmVsc1tjYWxsYmFjay5zZXFdICE9IGNhbGxiYWNrLmxldmVsKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZSBhY3Rpb24gd2UgYXJlIGxvb2tpbmcgZm9yIGRvZXNuJ3QgbWF0Y2ggdGhlIGFjdGlvbiB3ZSBnb3RcbiAgICAgICAgICAgIC8vIHRoZW4gd2Ugc2hvdWxkIGtlZXAgZ29pbmdcbiAgICAgICAgICAgIGlmIChhY3Rpb24gIT0gY2FsbGJhY2suYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBrZXlwcmVzcyBldmVudCBhbmQgdGhlIG1ldGEga2V5IGFuZCBjb250cm9sIGtleVxuICAgICAgICAgICAgLy8gYXJlIG5vdCBwcmVzc2VkIHRoYXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIG9ubHkgbG9vayBhdCB0aGVcbiAgICAgICAgICAgIC8vIGNoYXJhY3Rlciwgb3RoZXJ3aXNlIGNoZWNrIHRoZSBtb2RpZmllcnMgYXMgd2VsbFxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIGNocm9tZSB3aWxsIG5vdCBmaXJlIGEga2V5cHJlc3MgaWYgbWV0YSBvciBjb250cm9sIGlzIGRvd25cbiAgICAgICAgICAgIC8vIHNhZmFyaSB3aWxsIGZpcmUgYSBrZXlwcmVzcyBpZiBtZXRhIG9yIG1ldGErc2hpZnQgaXMgZG93blxuICAgICAgICAgICAgLy8gZmlyZWZveCB3aWxsIGZpcmUgYSBrZXlwcmVzcyBpZiBtZXRhIG9yIGNvbnRyb2wgaXMgZG93blxuICAgICAgICAgICAgaWYgKChhY3Rpb24gPT0gJ2tleXByZXNzJyAmJiAhZS5tZXRhS2V5ICYmICFlLmN0cmxLZXkpIHx8IF9tb2RpZmllcnNNYXRjaChtb2RpZmllcnMsIGNhbGxiYWNrLm1vZGlmaWVycykpIHtcblxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpcyB1c2VkIHNvIGlmIHlvdSBjaGFuZ2UgeW91ciBtaW5kIGFuZCBjYWxsIGJpbmQgYVxuICAgICAgICAgICAgICAgIC8vIHNlY29uZCB0aW1lIHdpdGggYSBuZXcgZnVuY3Rpb24gdGhlIGZpcnN0IG9uZSBpcyBvdmVyd3JpdHRlblxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmUgJiYgY2FsbGJhY2suY29tYm8gPT0gY29tYmluYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgX2NhbGxiYWNrc1tjaGFyYWN0ZXJdLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBtYXRjaGVzLnB1c2goY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdGFrZXMgYSBrZXkgZXZlbnQgYW5kIGZpZ3VyZXMgb3V0IHdoYXQgdGhlIG1vZGlmaWVycyBhcmVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXZlbnR9IGVcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAgICovXG4gICAgZnVuY3Rpb24gX2V2ZW50TW9kaWZpZXJzKGUpIHtcbiAgICAgICAgdmFyIG1vZGlmaWVycyA9IFtdO1xuXG4gICAgICAgIGlmIChlLnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICBtb2RpZmllcnMucHVzaCgnc2hpZnQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlLmFsdEtleSkge1xuICAgICAgICAgICAgbW9kaWZpZXJzLnB1c2goJ2FsdCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGUuY3RybEtleSkge1xuICAgICAgICAgICAgbW9kaWZpZXJzLnB1c2goJ2N0cmwnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlLm1ldGFLZXkpIHtcbiAgICAgICAgICAgIG1vZGlmaWVycy5wdXNoKCdtZXRhJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbW9kaWZpZXJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGFjdHVhbGx5IGNhbGxzIHRoZSBjYWxsYmFjayBmdW5jdGlvblxuICAgICAqXG4gICAgICogaWYgeW91ciBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5zIGZhbHNlIHRoaXMgd2lsbCB1c2UgdGhlIGpxdWVyeVxuICAgICAqIGNvbnZlbnRpb24gLSBwcmV2ZW50IGRlZmF1bHQgYW5kIHN0b3AgcHJvcG9nYXRpb24gb24gdGhlIGV2ZW50XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEBwYXJhbSB7RXZlbnR9IGVcbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgZnVuY3Rpb24gX2ZpcmVDYWxsYmFjayhjYWxsYmFjaywgZSkge1xuICAgICAgICBpZiAoY2FsbGJhY2soZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGUuc3RvcFByb3BhZ2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICAgICAgZS5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogaGFuZGxlcyBhIGNoYXJhY3RlciBrZXkgZXZlbnRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFyYWN0ZXJcbiAgICAgKiBAcGFyYW0ge0V2ZW50fSBlXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIF9oYW5kbGVDaGFyYWN0ZXIoY2hhcmFjdGVyLCBlKSB7XG5cbiAgICAgICAgLy8gaWYgdGhpcyBldmVudCBzaG91bGQgbm90IGhhcHBlbiBzdG9wIGhlcmVcbiAgICAgICAgaWYgKE1vdXNldHJhcC5zdG9wQ2FsbGJhY2soZSwgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNhbGxiYWNrcyA9IF9nZXRNYXRjaGVzKGNoYXJhY3RlciwgX2V2ZW50TW9kaWZpZXJzKGUpLCBlKSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBkb19ub3RfcmVzZXQgPSB7fSxcbiAgICAgICAgICAgIHByb2Nlc3NlZF9zZXF1ZW5jZV9jYWxsYmFjayA9IGZhbHNlO1xuXG4gICAgICAgIC8vIGxvb3AgdGhyb3VnaCBtYXRjaGluZyBjYWxsYmFja3MgZm9yIHRoaXMga2V5IGV2ZW50XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyArK2kpIHtcblxuICAgICAgICAgICAgLy8gZmlyZSBmb3IgYWxsIHNlcXVlbmNlIGNhbGxiYWNrc1xuICAgICAgICAgICAgLy8gdGhpcyBpcyBiZWNhdXNlIGlmIGZvciBleGFtcGxlIHlvdSBoYXZlIG11bHRpcGxlIHNlcXVlbmNlc1xuICAgICAgICAgICAgLy8gYm91bmQgc3VjaCBhcyBcImcgaVwiIGFuZCBcImcgdFwiIHRoZXkgYm90aCBuZWVkIHRvIGZpcmUgdGhlXG4gICAgICAgICAgICAvLyBjYWxsYmFjayBmb3IgbWF0Y2hpbmcgZyBjYXVzZSBvdGhlcndpc2UgeW91IGNhbiBvbmx5IGV2ZXJcbiAgICAgICAgICAgIC8vIG1hdGNoIHRoZSBmaXJzdCBvbmVcbiAgICAgICAgICAgIGlmIChjYWxsYmFja3NbaV0uc2VxKSB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzc2VkX3NlcXVlbmNlX2NhbGxiYWNrID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIC8vIGtlZXAgYSBsaXN0IG9mIHdoaWNoIHNlcXVlbmNlcyB3ZXJlIG1hdGNoZXMgZm9yIGxhdGVyXG4gICAgICAgICAgICAgICAgZG9fbm90X3Jlc2V0W2NhbGxiYWNrc1tpXS5zZXFdID0gMTtcbiAgICAgICAgICAgICAgICBfZmlyZUNhbGxiYWNrKGNhbGxiYWNrc1tpXS5jYWxsYmFjaywgZSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIHdlcmUgbm8gc2VxdWVuY2UgbWF0Y2hlcyBidXQgd2UgYXJlIHN0aWxsIGhlcmVcbiAgICAgICAgICAgIC8vIHRoYXQgbWVhbnMgdGhpcyBpcyBhIHJlZ3VsYXIgbWF0Y2ggc28gd2Ugc2hvdWxkIGZpcmUgdGhhdFxuICAgICAgICAgICAgaWYgKCFwcm9jZXNzZWRfc2VxdWVuY2VfY2FsbGJhY2sgJiYgIV9pbnNpZGVfc2VxdWVuY2UpIHtcbiAgICAgICAgICAgICAgICBfZmlyZUNhbGxiYWNrKGNhbGxiYWNrc1tpXS5jYWxsYmFjaywgZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB5b3UgYXJlIGluc2lkZSBvZiBhIHNlcXVlbmNlIGFuZCB0aGUga2V5IHlvdSBhcmUgcHJlc3NpbmdcbiAgICAgICAgLy8gaXMgbm90IGEgbW9kaWZpZXIga2V5IHRoZW4gd2Ugc2hvdWxkIHJlc2V0IGFsbCBzZXF1ZW5jZXNcbiAgICAgICAgLy8gdGhhdCB3ZXJlIG5vdCBtYXRjaGVkIGJ5IHRoaXMga2V5IGV2ZW50XG4gICAgICAgIGlmIChlLnR5cGUgPT0gX2luc2lkZV9zZXF1ZW5jZSAmJiAhX2lzTW9kaWZpZXIoY2hhcmFjdGVyKSkge1xuICAgICAgICAgICAgX3Jlc2V0U2VxdWVuY2VzKGRvX25vdF9yZXNldCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBoYW5kbGVzIGEga2V5ZG93biBldmVudFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFdmVudH0gZVxuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfaGFuZGxlS2V5KGUpIHtcblxuICAgICAgICAvLyBub3JtYWxpemUgZS53aGljaCBmb3Iga2V5IGV2ZW50c1xuICAgICAgICAvLyBAc2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDI4NTYyNy9qYXZhc2NyaXB0LWtleWNvZGUtdnMtY2hhcmNvZGUtdXR0ZXItY29uZnVzaW9uXG4gICAgICAgIGUud2hpY2ggPSB0eXBlb2YgZS53aGljaCA9PSBcIm51bWJlclwiID8gZS53aGljaCA6IGUua2V5Q29kZTtcblxuICAgICAgICB2YXIgY2hhcmFjdGVyID0gX2NoYXJhY3RlckZyb21FdmVudChlKTtcblxuICAgICAgICAvLyBubyBjaGFyYWN0ZXIgZm91bmQgdGhlbiBzdG9wXG4gICAgICAgIGlmICghY2hhcmFjdGVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZS50eXBlID09ICdrZXl1cCcgJiYgX2lnbm9yZV9uZXh0X2tleXVwID09IGNoYXJhY3Rlcikge1xuICAgICAgICAgICAgX2lnbm9yZV9uZXh0X2tleXVwID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBfaGFuZGxlQ2hhcmFjdGVyKGNoYXJhY3RlciwgZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZGV0ZXJtaW5lcyBpZiB0aGUga2V5Y29kZSBzcGVjaWZpZWQgaXMgYSBtb2RpZmllciBrZXkgb3Igbm90XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgZnVuY3Rpb24gX2lzTW9kaWZpZXIoa2V5KSB7XG4gICAgICAgIHJldHVybiBrZXkgPT0gJ3NoaWZ0JyB8fCBrZXkgPT0gJ2N0cmwnIHx8IGtleSA9PSAnYWx0JyB8fCBrZXkgPT0gJ21ldGEnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGNhbGxlZCB0byBzZXQgYSAxIHNlY29uZCB0aW1lb3V0IG9uIHRoZSBzcGVjaWZpZWQgc2VxdWVuY2VcbiAgICAgKlxuICAgICAqIHRoaXMgaXMgc28gYWZ0ZXIgZWFjaCBrZXkgcHJlc3MgaW4gdGhlIHNlcXVlbmNlIHlvdSBoYXZlIDEgc2Vjb25kXG4gICAgICogdG8gcHJlc3MgdGhlIG5leHQga2V5IGJlZm9yZSB5b3UgaGF2ZSB0byBzdGFydCBvdmVyXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgZnVuY3Rpb24gX3Jlc2V0U2VxdWVuY2VUaW1lcigpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KF9yZXNldF90aW1lcik7XG4gICAgICAgIF9yZXNldF90aW1lciA9IHNldFRpbWVvdXQoX3Jlc2V0U2VxdWVuY2VzLCAxMDAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXZlcnNlcyB0aGUgbWFwIGxvb2t1cCBzbyB0aGF0IHdlIGNhbiBsb29rIGZvciBzcGVjaWZpYyBrZXlzXG4gICAgICogdG8gc2VlIHdoYXQgY2FuIGFuZCBjYW4ndCB1c2Uga2V5cHJlc3NcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfZ2V0UmV2ZXJzZU1hcCgpIHtcbiAgICAgICAgaWYgKCFfUkVWRVJTRV9NQVApIHtcbiAgICAgICAgICAgIF9SRVZFUlNFX01BUCA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIF9NQVApIHtcblxuICAgICAgICAgICAgICAgIC8vIHB1bGwgb3V0IHRoZSBudW1lcmljIGtleXBhZCBmcm9tIGhlcmUgY2F1c2Uga2V5cHJlc3Mgc2hvdWxkXG4gICAgICAgICAgICAgICAgLy8gYmUgYWJsZSB0byBkZXRlY3QgdGhlIGtleXMgZnJvbSB0aGUgY2hhcmFjdGVyXG4gICAgICAgICAgICAgICAgaWYgKGtleSA+IDk1ICYmIGtleSA8IDExMikge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoX01BUC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIF9SRVZFUlNFX01BUFtfTUFQW2tleV1dID0ga2V5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX1JFVkVSU0VfTUFQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHBpY2tzIHRoZSBiZXN0IGFjdGlvbiBiYXNlZCBvbiB0aGUga2V5IGNvbWJpbmF0aW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gY2hhcmFjdGVyIGZvciBrZXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBtb2RpZmllcnNcbiAgICAgKiBAcGFyYW0ge3N0cmluZz19IGFjdGlvbiBwYXNzZWQgaW5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfcGlja0Jlc3RBY3Rpb24oa2V5LCBtb2RpZmllcnMsIGFjdGlvbikge1xuXG4gICAgICAgIC8vIGlmIG5vIGFjdGlvbiB3YXMgcGlja2VkIGluIHdlIHNob3VsZCB0cnkgdG8gcGljayB0aGUgb25lXG4gICAgICAgIC8vIHRoYXQgd2UgdGhpbmsgd291bGQgd29yayBiZXN0IGZvciB0aGlzIGtleVxuICAgICAgICBpZiAoIWFjdGlvbikge1xuICAgICAgICAgICAgYWN0aW9uID0gX2dldFJldmVyc2VNYXAoKVtrZXldID8gJ2tleWRvd24nIDogJ2tleXByZXNzJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG1vZGlmaWVyIGtleXMgZG9uJ3Qgd29yayBhcyBleHBlY3RlZCB3aXRoIGtleXByZXNzLFxuICAgICAgICAvLyBzd2l0Y2ggdG8ga2V5ZG93blxuICAgICAgICBpZiAoYWN0aW9uID09ICdrZXlwcmVzcycgJiYgbW9kaWZpZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgYWN0aW9uID0gJ2tleWRvd24nO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFjdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBiaW5kcyBhIGtleSBzZXF1ZW5jZSB0byBhbiBldmVudFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvbWJvIC0gY29tYm8gc3BlY2lmaWVkIGluIGJpbmQgY2FsbFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGtleXNcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gYWN0aW9uXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIF9iaW5kU2VxdWVuY2UoY29tYm8sIGtleXMsIGNhbGxiYWNrLCBhY3Rpb24pIHtcblxuICAgICAgICAvLyBzdGFydCBvZmYgYnkgYWRkaW5nIGEgc2VxdWVuY2UgbGV2ZWwgcmVjb3JkIGZvciB0aGlzIGNvbWJpbmF0aW9uXG4gICAgICAgIC8vIGFuZCBzZXR0aW5nIHRoZSBsZXZlbCB0byAwXG4gICAgICAgIF9zZXF1ZW5jZV9sZXZlbHNbY29tYm9dID0gMDtcblxuICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBhY3Rpb24gcGljayB0aGUgYmVzdCBvbmUgZm9yIHRoZSBmaXJzdCBrZXlcbiAgICAgICAgLy8gaW4gdGhlIHNlcXVlbmNlXG4gICAgICAgIGlmICghYWN0aW9uKSB7XG4gICAgICAgICAgICBhY3Rpb24gPSBfcGlja0Jlc3RBY3Rpb24oa2V5c1swXSwgW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNhbGxiYWNrIHRvIGluY3JlYXNlIHRoZSBzZXF1ZW5jZSBsZXZlbCBmb3IgdGhpcyBzZXF1ZW5jZSBhbmQgcmVzZXRcbiAgICAgICAgICogYWxsIG90aGVyIHNlcXVlbmNlcyB0aGF0IHdlcmUgYWN0aXZlXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGVcbiAgICAgICAgICogQHJldHVybnMgdm9pZFxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9pbmNyZWFzZVNlcXVlbmNlID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIF9pbnNpZGVfc2VxdWVuY2UgPSBhY3Rpb247XG4gICAgICAgICAgICAgICAgKytfc2VxdWVuY2VfbGV2ZWxzW2NvbWJvXTtcbiAgICAgICAgICAgICAgICBfcmVzZXRTZXF1ZW5jZVRpbWVyKCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIHdyYXBzIHRoZSBzcGVjaWZpZWQgY2FsbGJhY2sgaW5zaWRlIG9mIGFub3RoZXIgZnVuY3Rpb24gaW4gb3JkZXJcbiAgICAgICAgICAgICAqIHRvIHJlc2V0IGFsbCBzZXF1ZW5jZSBjb3VudGVycyBhcyBzb29uIGFzIHRoaXMgc2VxdWVuY2UgaXMgZG9uZVxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGVcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgX2NhbGxiYWNrQW5kUmVzZXQgPSBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgX2ZpcmVDYWxsYmFjayhjYWxsYmFjaywgZSk7XG5cbiAgICAgICAgICAgICAgICAvLyB3ZSBzaG91bGQgaWdub3JlIHRoZSBuZXh0IGtleSB1cCBpZiB0aGUgYWN0aW9uIGlzIGtleSBkb3duXG4gICAgICAgICAgICAgICAgLy8gb3Iga2V5cHJlc3MuICB0aGlzIGlzIHNvIGlmIHlvdSBmaW5pc2ggYSBzZXF1ZW5jZSBhbmRcbiAgICAgICAgICAgICAgICAvLyByZWxlYXNlIHRoZSBrZXkgdGhlIGZpbmFsIGtleSB3aWxsIG5vdCB0cmlnZ2VyIGEga2V5dXBcbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uICE9PSAna2V5dXAnKSB7XG4gICAgICAgICAgICAgICAgICAgIF9pZ25vcmVfbmV4dF9rZXl1cCA9IF9jaGFyYWN0ZXJGcm9tRXZlbnQoZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gd2VpcmQgcmFjZSBjb25kaXRpb24gaWYgYSBzZXF1ZW5jZSBlbmRzIHdpdGggdGhlIGtleVxuICAgICAgICAgICAgICAgIC8vIGFub3RoZXIgc2VxdWVuY2UgYmVnaW5zIHdpdGhcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KF9yZXNldFNlcXVlbmNlcywgMTApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGk7XG5cbiAgICAgICAgLy8gbG9vcCB0aHJvdWdoIGtleXMgb25lIGF0IGEgdGltZSBhbmQgYmluZCB0aGUgYXBwcm9wcmlhdGUgY2FsbGJhY2tcbiAgICAgICAgLy8gZnVuY3Rpb24uICBmb3IgYW55IGtleSBsZWFkaW5nIHVwIHRvIHRoZSBmaW5hbCBvbmUgaXQgc2hvdWxkXG4gICAgICAgIC8vIGluY3JlYXNlIHRoZSBzZXF1ZW5jZS4gYWZ0ZXIgdGhlIGZpbmFsLCBpdCBzaG91bGQgcmVzZXQgYWxsIHNlcXVlbmNlc1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgX2JpbmRTaW5nbGUoa2V5c1tpXSwgaSA8IGtleXMubGVuZ3RoIC0gMSA/IF9pbmNyZWFzZVNlcXVlbmNlIDogX2NhbGxiYWNrQW5kUmVzZXQsIGFjdGlvbiwgY29tYm8sIGkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogYmluZHMgYSBzaW5nbGUga2V5Ym9hcmQgY29tYmluYXRpb25cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb21iaW5hdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtzdHJpbmc9fSBhY3Rpb25cbiAgICAgKiBAcGFyYW0ge3N0cmluZz19IHNlcXVlbmNlX25hbWUgLSBuYW1lIG9mIHNlcXVlbmNlIGlmIHBhcnQgb2Ygc2VxdWVuY2VcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGxldmVsIC0gd2hhdCBwYXJ0IG9mIHRoZSBzZXF1ZW5jZSB0aGUgY29tbWFuZCBpc1xuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBfYmluZFNpbmdsZShjb21iaW5hdGlvbiwgY2FsbGJhY2ssIGFjdGlvbiwgc2VxdWVuY2VfbmFtZSwgbGV2ZWwpIHtcblxuICAgICAgICAvLyBtYWtlIHN1cmUgbXVsdGlwbGUgc3BhY2VzIGluIGEgcm93IGJlY29tZSBhIHNpbmdsZSBzcGFjZVxuICAgICAgICBjb21iaW5hdGlvbiA9IGNvbWJpbmF0aW9uLnJlcGxhY2UoL1xccysvZywgJyAnKTtcblxuICAgICAgICB2YXIgc2VxdWVuY2UgPSBjb21iaW5hdGlvbi5zcGxpdCgnICcpLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICBtb2RpZmllcnMgPSBbXTtcblxuICAgICAgICAvLyBpZiB0aGlzIHBhdHRlcm4gaXMgYSBzZXF1ZW5jZSBvZiBrZXlzIHRoZW4gcnVuIHRocm91Z2ggdGhpcyBtZXRob2RcbiAgICAgICAgLy8gdG8gcmVwcm9jZXNzIGVhY2ggcGF0dGVybiBvbmUga2V5IGF0IGEgdGltZVxuICAgICAgICBpZiAoc2VxdWVuY2UubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgX2JpbmRTZXF1ZW5jZShjb21iaW5hdGlvbiwgc2VxdWVuY2UsIGNhbGxiYWNrLCBhY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGFrZSB0aGUga2V5cyBmcm9tIHRoaXMgcGF0dGVybiBhbmQgZmlndXJlIG91dCB3aGF0IHRoZSBhY3R1YWxcbiAgICAgICAgLy8gcGF0dGVybiBpcyBhbGwgYWJvdXRcbiAgICAgICAga2V5cyA9IGNvbWJpbmF0aW9uID09PSAnKycgPyBbJysnXSA6IGNvbWJpbmF0aW9uLnNwbGl0KCcrJyk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGtleSA9IGtleXNbaV07XG5cbiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSBrZXkgbmFtZXNcbiAgICAgICAgICAgIGlmIChfU1BFQ0lBTF9BTElBU0VTW2tleV0pIHtcbiAgICAgICAgICAgICAgICBrZXkgPSBfU1BFQ0lBTF9BTElBU0VTW2tleV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgbm90IGEga2V5cHJlc3MgZXZlbnQgdGhlbiB3ZSBzaG91bGRcbiAgICAgICAgICAgIC8vIGJlIHNtYXJ0IGFib3V0IHVzaW5nIHNoaWZ0IGtleXNcbiAgICAgICAgICAgIC8vIHRoaXMgd2lsbCBvbmx5IHdvcmsgZm9yIFVTIGtleWJvYXJkcyBob3dldmVyXG4gICAgICAgICAgICBpZiAoYWN0aW9uICYmIGFjdGlvbiAhPSAna2V5cHJlc3MnICYmIF9TSElGVF9NQVBba2V5XSkge1xuICAgICAgICAgICAgICAgIGtleSA9IF9TSElGVF9NQVBba2V5XTtcbiAgICAgICAgICAgICAgICBtb2RpZmllcnMucHVzaCgnc2hpZnQnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaWYgdGhpcyBrZXkgaXMgYSBtb2RpZmllciB0aGVuIGFkZCBpdCB0byB0aGUgbGlzdCBvZiBtb2RpZmllcnNcbiAgICAgICAgICAgIGlmIChfaXNNb2RpZmllcihrZXkpKSB7XG4gICAgICAgICAgICAgICAgbW9kaWZpZXJzLnB1c2goa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRlcGVuZGluZyBvbiB3aGF0IHRoZSBrZXkgY29tYmluYXRpb24gaXNcbiAgICAgICAgLy8gd2Ugd2lsbCB0cnkgdG8gcGljayB0aGUgYmVzdCBldmVudCBmb3IgaXRcbiAgICAgICAgYWN0aW9uID0gX3BpY2tCZXN0QWN0aW9uKGtleSwgbW9kaWZpZXJzLCBhY3Rpb24pO1xuXG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0byBpbml0aWFsaXplIGFycmF5IGlmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgLy8gYSBjYWxsYmFjayBpcyBhZGRlZCBmb3IgdGhpcyBrZXlcbiAgICAgICAgaWYgKCFfY2FsbGJhY2tzW2tleV0pIHtcbiAgICAgICAgICAgIF9jYWxsYmFja3Nba2V5XSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIGFuIGV4aXN0aW5nIG1hdGNoIGlmIHRoZXJlIGlzIG9uZVxuICAgICAgICBfZ2V0TWF0Y2hlcyhrZXksIG1vZGlmaWVycywge3R5cGU6IGFjdGlvbn0sICFzZXF1ZW5jZV9uYW1lLCBjb21iaW5hdGlvbik7XG5cbiAgICAgICAgLy8gYWRkIHRoaXMgY2FsbCBiYWNrIHRvIHRoZSBhcnJheVxuICAgICAgICAvLyBpZiBpdCBpcyBhIHNlcXVlbmNlIHB1dCBpdCBhdCB0aGUgYmVnaW5uaW5nXG4gICAgICAgIC8vIGlmIG5vdCBwdXQgaXQgYXQgdGhlIGVuZFxuICAgICAgICAvL1xuICAgICAgICAvLyB0aGlzIGlzIGltcG9ydGFudCBiZWNhdXNlIHRoZSB3YXkgdGhlc2UgYXJlIHByb2Nlc3NlZCBleHBlY3RzXG4gICAgICAgIC8vIHRoZSBzZXF1ZW5jZSBvbmVzIHRvIGNvbWUgZmlyc3RcbiAgICAgICAgX2NhbGxiYWNrc1trZXldW3NlcXVlbmNlX25hbWUgPyAndW5zaGlmdCcgOiAncHVzaCddKHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBjYWxsYmFjayxcbiAgICAgICAgICAgIG1vZGlmaWVyczogbW9kaWZpZXJzLFxuICAgICAgICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICAgICAgICBzZXE6IHNlcXVlbmNlX25hbWUsXG4gICAgICAgICAgICBsZXZlbDogbGV2ZWwsXG4gICAgICAgICAgICBjb21ibzogY29tYmluYXRpb25cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogYmluZHMgbXVsdGlwbGUgY29tYmluYXRpb25zIHRvIHRoZSBzYW1lIGNhbGxiYWNrXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBjb21iaW5hdGlvbnNcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gYWN0aW9uXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIF9iaW5kTXVsdGlwbGUoY29tYmluYXRpb25zLCBjYWxsYmFjaywgYWN0aW9uKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29tYmluYXRpb25zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBfYmluZFNpbmdsZShjb21iaW5hdGlvbnNbaV0sIGNhbGxiYWNrLCBhY3Rpb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gc3RhcnQhXG4gICAgX2FkZEV2ZW50KGRvY3VtZW50LCAna2V5cHJlc3MnLCBfaGFuZGxlS2V5KTtcbiAgICBfYWRkRXZlbnQoZG9jdW1lbnQsICdrZXlkb3duJywgX2hhbmRsZUtleSk7XG4gICAgX2FkZEV2ZW50KGRvY3VtZW50LCAna2V5dXAnLCBfaGFuZGxlS2V5KTtcblxuICAgIHZhciBNb3VzZXRyYXAgPSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGJpbmRzIGFuIGV2ZW50IHRvIG1vdXNldHJhcFxuICAgICAgICAgKlxuICAgICAgICAgKiBjYW4gYmUgYSBzaW5nbGUga2V5LCBhIGNvbWJpbmF0aW9uIG9mIGtleXMgc2VwYXJhdGVkIHdpdGggKyxcbiAgICAgICAgICogYW4gYXJyYXkgb2Yga2V5cywgb3IgYSBzZXF1ZW5jZSBvZiBrZXlzIHNlcGFyYXRlZCBieSBzcGFjZXNcbiAgICAgICAgICpcbiAgICAgICAgICogYmUgc3VyZSB0byBsaXN0IHRoZSBtb2RpZmllciBrZXlzIGZpcnN0IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZVxuICAgICAgICAgKiBjb3JyZWN0IGtleSBlbmRzIHVwIGdldHRpbmcgYm91bmQgKHRoZSBsYXN0IGtleSBpbiB0aGUgcGF0dGVybilcbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXl9IGtleXNcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmc9fSBhY3Rpb24gLSAna2V5cHJlc3MnLCAna2V5ZG93bicsIG9yICdrZXl1cCdcbiAgICAgICAgICogQHJldHVybnMgdm9pZFxuICAgICAgICAgKi9cbiAgICAgICAgYmluZDogZnVuY3Rpb24oa2V5cywgY2FsbGJhY2ssIGFjdGlvbikge1xuICAgICAgICAgICAgX2JpbmRNdWx0aXBsZShrZXlzIGluc3RhbmNlb2YgQXJyYXkgPyBrZXlzIDogW2tleXNdLCBjYWxsYmFjaywgYWN0aW9uKTtcbiAgICAgICAgICAgIF9kaXJlY3RfbWFwW2tleXMgKyAnOicgKyBhY3Rpb25dID0gY2FsbGJhY2s7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogdW5iaW5kcyBhbiBldmVudCB0byBtb3VzZXRyYXBcbiAgICAgICAgICpcbiAgICAgICAgICogdGhlIHVuYmluZGluZyBzZXRzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGtleSBjb21ib1xuICAgICAgICAgKiB0byBhbiBlbXB0eSBmdW5jdGlvbiBhbmQgZGVsZXRlcyB0aGUgY29ycmVzcG9uZGluZyBrZXkgaW4gdGhlXG4gICAgICAgICAqIF9kaXJlY3RfbWFwIGRpY3QuXG4gICAgICAgICAqXG4gICAgICAgICAqIHRoZSBrZXljb21ibythY3Rpb24gaGFzIHRvIGJlIGV4YWN0bHkgdGhlIHNhbWUgYXNcbiAgICAgICAgICogaXQgd2FzIGRlZmluZWQgaW4gdGhlIGJpbmQgbWV0aG9kXG4gICAgICAgICAqXG4gICAgICAgICAqIFRPRE86IGFjdHVhbGx5IHJlbW92ZSB0aGlzIGZyb20gdGhlIF9jYWxsYmFja3MgZGljdGlvbmFyeSBpbnN0ZWFkXG4gICAgICAgICAqIG9mIGJpbmRpbmcgYW4gZW1wdHkgZnVuY3Rpb25cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXl9IGtleXNcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblxuICAgICAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICAgICAqL1xuICAgICAgICB1bmJpbmQ6IGZ1bmN0aW9uKGtleXMsIGFjdGlvbikge1xuICAgICAgICAgICAgaWYgKF9kaXJlY3RfbWFwW2tleXMgKyAnOicgKyBhY3Rpb25dKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIF9kaXJlY3RfbWFwW2tleXMgKyAnOicgKyBhY3Rpb25dO1xuICAgICAgICAgICAgICAgIHRoaXMuYmluZChrZXlzLCBmdW5jdGlvbigpIHt9LCBhY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRyaWdnZXJzIGFuIGV2ZW50IHRoYXQgaGFzIGFscmVhZHkgYmVlbiBib3VuZFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5c1xuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZz19IGFjdGlvblxuICAgICAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICAgICAqL1xuICAgICAgICB0cmlnZ2VyOiBmdW5jdGlvbihrZXlzLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIF9kaXJlY3RfbWFwW2tleXMgKyAnOicgKyBhY3Rpb25dKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogcmVzZXRzIHRoZSBsaWJyYXJ5IGJhY2sgdG8gaXRzIGluaXRpYWwgc3RhdGUuICB0aGlzIGlzIHVzZWZ1bFxuICAgICAgICAgKiBpZiB5b3Ugd2FudCB0byBjbGVhciBvdXQgdGhlIGN1cnJlbnQga2V5Ym9hcmQgc2hvcnRjdXRzIGFuZCBiaW5kXG4gICAgICAgICAqIG5ldyBvbmVzIC0gZm9yIGV4YW1wbGUgaWYgeW91IHN3aXRjaCB0byBhbm90aGVyIHBhZ2VcbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybnMgdm9pZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgX2NhbGxiYWNrcyA9IHt9O1xuICAgICAgICAgICAgX2RpcmVjdF9tYXAgPSB7fTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgLyoqXG4gICAgICAgICogc2hvdWxkIHdlIHN0b3AgdGhpcyBldmVudCBiZWZvcmUgZmlyaW5nIG9mZiBjYWxsYmFja3NcbiAgICAgICAgKlxuICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGVcbiAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAgICAqL1xuICAgICAgICBzdG9wQ2FsbGJhY2s6IGZ1bmN0aW9uKGUsIGVsZW1lbnQpIHtcblxuICAgICAgICAgICAgLy8gaWYgdGhlIGVsZW1lbnQgaGFzIHRoZSBjbGFzcyBcIm1vdXNldHJhcFwiIHRoZW4gbm8gbmVlZCB0byBzdG9wXG4gICAgICAgICAgICBpZiAoKCcgJyArIGVsZW1lbnQuY2xhc3NOYW1lICsgJyAnKS5pbmRleE9mKCcgbW91c2V0cmFwICcpID4gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHN0b3AgZm9yIGlucHV0LCBzZWxlY3QsIGFuZCB0ZXh0YXJlYVxuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQudGFnTmFtZSA9PSAnSU5QVVQnIHx8IGVsZW1lbnQudGFnTmFtZSA9PSAnU0VMRUNUJyB8fCBlbGVtZW50LnRhZ05hbWUgPT0gJ1RFWFRBUkVBJyB8fCAoZWxlbWVudC5jb250ZW50RWRpdGFibGUgJiYgZWxlbWVudC5jb250ZW50RWRpdGFibGUgPT0gJ3RydWUnKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBleHBvc2UgbW91c2V0cmFwIHRvIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAgd2luZG93Lk1vdXNldHJhcCA9IE1vdXNldHJhcDtcblxuICAgIC8vIGV4cG9zZSBtb3VzZXRyYXAgYXMgYW4gQU1EIG1vZHVsZVxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoJ21vdXNldHJhcCcsIGZ1bmN0aW9uKCkgeyByZXR1cm4gTW91c2V0cmFwOyB9KTtcbiAgICB9XG4gICAgLy8gYnJvd3NlcmlmeSBzdXBwb3J0XG4gICAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBNb3VzZXRyYXA7XG4gICAgfVxufSkgKCk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG4oZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJvb3QgPSB0aGlzO1xuICAgIHZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG5cdHZhciBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpO1xuXHR2YXIgaW50ZXJ2YWxQYXJzZXIgPSAvKFswLTlcXC5dKykobXN8c3xtfGgpPy87XG5cdHZhciByb290ID0gZ2xvYmFsIHx8IHdpbmRvdztcblxuXHQvLyBMaWwgYml0IG9mIHVzZWZ1bCBwb2x5ZmlsbC4uLlxuXHRpZiAodHlwZW9mKEZ1bmN0aW9uLnByb3RvdHlwZS5pbmhlcml0cykgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0RnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzID0gZnVuY3Rpb24ocGFyZW50KSB7XG5cdFx0XHR0aGlzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUocGFyZW50LnByb3RvdHlwZSk7XG5cdFx0fTtcblx0fVxuXG5cdGlmICh0eXBlb2YoQXJyYXkucHJvdG90eXBlLnJlbW92ZU9uZSkgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnJlbW92ZU9uZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHdoYXQsIGEgPSBhcmd1bWVudHMsIEwgPSBhLmxlbmd0aCwgYXg7XG5cdFx0XHR3aGlsZSAoTCAmJiB0aGlzLmxlbmd0aCkge1xuXHRcdFx0XHR3aGF0ID0gYVstLUxdO1xuXHRcdFx0XHR3aGlsZSAoKGF4ID0gdGhpcy5pbmRleE9mKHdoYXQpKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5zcGxpY2UoYXgsIDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdyZWF0ZXN0Q29tbW9uRmFjdG9yKGludGVydmFscykge1xuXHRcdHZhciBzdW1PZk1vZHVsaSA9IDE7XG5cdFx0dmFyIGludGVydmFsID0gXy5taW4oaW50ZXJ2YWxzKTtcblx0XHR3aGlsZSAoc3VtT2ZNb2R1bGkgIT09IDApIHtcblx0XHRcdHN1bU9mTW9kdWxpID0gXy5yZWR1Y2UoaW50ZXJ2YWxzLCBmdW5jdGlvbihtZW1vLCBpKXsgcmV0dXJuIG1lbW8gKyAoaSAlIGludGVydmFsKTsgfSwgMCk7XG5cdFx0XHRpZiAoc3VtT2ZNb2R1bGkgIT09IDApIHtcblx0XHRcdFx0aW50ZXJ2YWwgLT0gMTA7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBpbnRlcnZhbDtcblx0fVxuXG5cdGZ1bmN0aW9uIHBhcnNlRXZlbnQoZSkge1xuXHRcdHZhciBpbnRlcnZhbEdyb3VwcyA9IGludGVydmFsUGFyc2VyLmV4ZWMoZSk7XG5cdFx0aWYgKCFpbnRlcnZhbEdyb3Vwcykge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJIGRvblxcJ3QgdW5kZXJzdGFuZCB0aGF0IHBhcnRpY3VsYXIgaW50ZXJ2YWwnKTtcblx0XHR9XG5cdFx0dmFyIGludGVydmFsQW1vdW50ID0gK2ludGVydmFsR3JvdXBzWzFdO1xuXHRcdHZhciBpbnRlcnZhbFR5cGUgPSBpbnRlcnZhbEdyb3Vwc1syXSB8fCAnbXMnO1xuXHRcdGlmIChpbnRlcnZhbFR5cGUgPT09ICdzJykge1xuXHRcdFx0aW50ZXJ2YWxBbW91bnQgPSBpbnRlcnZhbEFtb3VudCAqIDEwMDA7XG5cdFx0fSBlbHNlIGlmIChpbnRlcnZhbFR5cGUgPT09ICdtJykge1xuXHRcdFx0aW50ZXJ2YWxBbW91bnQgPSBpbnRlcnZhbEFtb3VudCAqIDEwMDAgKiA2MDtcblx0XHR9IGVsc2UgaWYgKGludGVydmFsVHlwZSA9PT0gJ2gnKSB7XG5cdFx0XHRpbnRlcnZhbEFtb3VudCA9IGludGVydmFsQW1vdW50ICogMTAwMCAqIDYwICogNjA7XG5cdFx0fSBlbHNlIGlmICghIWludGVydmFsVHlwZSAmJiBpbnRlcnZhbFR5cGUgIT09ICdtcycpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignWW91IGNhbiBvbmx5IHNwZWNpZnkgaW50ZXJ2YWxzIG9mIG1zLCBzLCBtLCBvciBoJyk7XG5cdFx0fVxuXHRcdGlmIChpbnRlcnZhbEFtb3VudCA8IDEwIHx8IGludGVydmFsQW1vdW50ICUgMTAgIT09IDApIHtcblx0XHRcdC8vIFdlIG9ubHkgZGVhbCBpbiAxMCdzIG9mIG1pbGxpc2Vjb25kcyBmb3Igc2ltcGxpY2l0eVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdZb3UgY2FuIG9ubHkgc3BlY2lmeSAxMHMgb2YgbWlsbGlzZWNvbmRzLCB0cnVzdCBtZSBvbiB0aGlzIG9uZScpO1xuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0YW1vdW50OmludGVydmFsQW1vdW50LFxuXHRcdFx0dHlwZTppbnRlcnZhbFR5cGVcblx0XHR9O1xuXHR9XG5cblx0ZnVuY3Rpb24gRXZlbnRlZExvb3AoKSB7XG5cdFx0dGhpcy5pbnRlcnZhbElkID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuaW50ZXJ2YWxMZW5ndGggPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5pbnRlcnZhbHNUb0VtaXQgPSB7fTtcblx0XHR0aGlzLmN1cnJlbnRUaWNrID0gMTtcblx0XHR0aGlzLm1heFRpY2tzID0gMDtcblx0XHR0aGlzLmxpc3RlbmluZ0ZvckZvY3VzID0gZmFsc2U7XG5cblx0XHQvLyBQcml2YXRlIG1ldGhvZFxuXHRcdHZhciBkZXRlcm1pbmVJbnRlcnZhbExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHZhciBwb3RlbnRpYWxJbnRlcnZhbExlbmd0aCA9IGdyZWF0ZXN0Q29tbW9uRmFjdG9yKF8ua2V5cyh0aGlzLmludGVydmFsc1RvRW1pdCkpO1xuXHRcdFx0dmFyIGNoYW5nZWQgPSBmYWxzZTtcblxuXHRcdFx0aWYgKHRoaXMuaW50ZXJ2YWxMZW5ndGgpIHtcblx0XHRcdFx0aWYgKHBvdGVudGlhbEludGVydmFsTGVuZ3RoICE9PSB0aGlzLmludGVydmFsTGVuZ3RoKSB7XG5cdFx0XHRcdFx0Ly8gTG9va3MgbGlrZSB3ZSBuZWVkIGEgbmV3IGludGVydmFsXG5cdFx0XHRcdFx0dGhpcy5pbnRlcnZhbExlbmd0aCA9IHBvdGVudGlhbEludGVydmFsTGVuZ3RoO1xuXHRcdFx0XHRcdGNoYW5nZWQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmludGVydmFsTGVuZ3RoID0gcG90ZW50aWFsSW50ZXJ2YWxMZW5ndGg7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubWF4VGlja3MgPSBfLm1heChfLm1hcChfLmtleXModGhpcy5pbnRlcnZhbHNUb0VtaXQpLCBmdW5jdGlvbihhKSB7IHJldHVybiArYTsgfSkpIC8gdGhpcy5pbnRlcnZhbExlbmd0aDtcblx0XHRcdHJldHVybiBjaGFuZ2VkO1xuXHRcdH0uYmluZCh0aGlzKTtcblxuXHRcdHRoaXMub24oJ25ld0xpc3RlbmVyJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdGlmIChlID09PSAncmVtb3ZlTGlzdGVuZXInIHx8IGUgPT09ICduZXdMaXN0ZW5lcicpIHJldHVybjsgLy8gV2UgZG9uJ3QgY2FyZSBhYm91dCB0aGF0IG9uZVxuXHRcdFx0dmFyIGludGVydmFsSW5mbyA9IHBhcnNlRXZlbnQoZSk7XG5cdFx0XHR2YXIgaW50ZXJ2YWxBbW91bnQgPSBpbnRlcnZhbEluZm8uYW1vdW50O1xuXG5cdFx0XHR0aGlzLmludGVydmFsc1RvRW1pdFsraW50ZXJ2YWxBbW91bnRdID0gXy51bmlvbih0aGlzLmludGVydmFsc1RvRW1pdFsraW50ZXJ2YWxBbW91bnRdIHx8IFtdLCBbZV0pO1xuXHRcdFx0XG5cdFx0XHRpZiAoZGV0ZXJtaW5lSW50ZXJ2YWxMZW5ndGgoKSAmJiB0aGlzLmlzU3RhcnRlZCgpKSB7XG5cdFx0XHRcdHRoaXMuc3RvcCgpLnN0YXJ0KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR0aGlzLm9uKCdyZW1vdmVMaXN0ZW5lcicsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRpZiAoRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQodGhpcywgZSkgPiAwKSByZXR1cm47XG5cdFx0XHR2YXIgaW50ZXJ2YWxJbmZvID0gcGFyc2VFdmVudChlKTtcblx0XHRcdHZhciBpbnRlcnZhbEFtb3VudCA9IGludGVydmFsSW5mby5hbW91bnQ7XG5cblx0XHRcdHZhciByZW1vdmVkRXZlbnQgPSB0aGlzLmludGVydmFsc1RvRW1pdFsraW50ZXJ2YWxBbW91bnRdLnJlbW92ZU9uZShlKTtcblx0XHRcdGlmICh0aGlzLmludGVydmFsc1RvRW1pdFsraW50ZXJ2YWxBbW91bnRdLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRkZWxldGUgdGhpcy5pbnRlcnZhbHNUb0VtaXRbK2ludGVydmFsQW1vdW50XTtcblx0XHRcdH1cblx0XHRcdGNvbnNvbGUubG9nKCdEZXRlcm1pbmluZyBpbnRlcnZhbCBsZW5ndGggYWZ0ZXIgcmVtb3ZhbCBvZicsIHJlbW92ZWRFdmVudCk7XG5cdFx0XHRkZXRlcm1pbmVJbnRlcnZhbExlbmd0aCgpO1xuXG5cdFx0XHRpZiAoZGV0ZXJtaW5lSW50ZXJ2YWxMZW5ndGgoKSAmJiB0aGlzLmlzU3RhcnRlZCgpKSB7XG5cdFx0XHRcdHRoaXMuc3RvcCgpLnN0YXJ0KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRFdmVudGVkTG9vcC5pbmhlcml0cyhFdmVudEVtaXR0ZXIpO1xuXG5cdC8vIFB1YmxpYyBtZXRob2RzXG5cdEV2ZW50ZWRMb29wLnByb3RvdHlwZS50aWNrID0gZnVuY3Rpb24gKCkge1xuXHRcdHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLmN1cnJlbnRUaWNrICogdGhpcy5pbnRlcnZhbExlbmd0aDtcblx0XHRfLmVhY2godGhpcy5pbnRlcnZhbHNUb0VtaXQsIGZ1bmN0aW9uIChldmVudHMsIGtleSkge1xuXHRcdFx0aWYgKG1pbGxpc2Vjb25kcyAlIGtleSA9PT0gMCkge1xuXHRcdFx0XHRfLmVhY2goZXZlbnRzLCBmdW5jdGlvbihlKSB7IHRoaXMuZW1pdChlLCBlLCBrZXkpOyB9LmJpbmQodGhpcykpO1xuXHRcdFx0fVxuXHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0dGhpcy5jdXJyZW50VGljayArPSAxO1xuXHRcdGlmICh0aGlzLmN1cnJlbnRUaWNrID4gdGhpcy5tYXhUaWNrcykge1xuXHRcdFx0dGhpcy5jdXJyZW50VGljayA9IDE7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9O1xuXG5cdEV2ZW50ZWRMb29wLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAoIXRoaXMuaW50ZXJ2YWxMZW5ndGgpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignWW91IGhhdmVuXFwndCBzcGVjaWZpZWQgYW55IGludGVydmFsIGNhbGxiYWNrcy4gVXNlIEV2ZW50ZWRMb29wLm9uKFxcJzUwMG1zXFwnLCBmdW5jdGlvbiAoKSB7IC4uLiB9KSB0byBkbyBzbywgYW5kIHRoZW4geW91IGNhbiBzdGFydCcpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5pbnRlcnZhbElkKSB7XG5cdFx0XHRyZXR1cm4gY29uc29sZS5sb2coJ05vIG5lZWQgdG8gc3RhcnQgdGhlIGxvb3AgYWdhaW4sIGl0XFwncyBhbHJlYWR5IHN0YXJ0ZWQuJyk7XG5cdFx0fVxuXG5cdFx0dGhpcy5pbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwodGhpcy50aWNrLmJpbmQodGhpcyksIHRoaXMuaW50ZXJ2YWxMZW5ndGgpO1xuXG5cdFx0aWYgKHJvb3QgJiYgIXRoaXMubGlzdGVuaW5nRm9yRm9jdXMgJiYgcm9vdC5hZGRFdmVudExpc3RlbmVyKSB7XG5cdFx0XHRyb290LmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHRoaXMuc3RhcnQoKTtcblx0XHRcdH0uYmluZCh0aGlzKSk7XG5cblx0XHRcdHJvb3QuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR0aGlzLnN0b3AoKTtcblx0XHRcdH0uYmluZCh0aGlzKSk7XG5cblx0XHRcdHRoaXMubGlzdGVuaW5nRm9yRm9jdXMgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fTtcblxuXHRFdmVudGVkTG9vcC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICgpIHtcblx0XHRjbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWxJZCk7XG5cdFx0dGhpcy5pbnRlcnZhbElkID0gdW5kZWZpbmVkO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9O1xuXG5cdEV2ZW50ZWRMb29wLnByb3RvdHlwZS5pc1N0YXJ0ZWQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuICEhdGhpcy5pbnRlcnZhbElkO1xuXHR9O1xuXG5cdEV2ZW50ZWRMb29wLnByb3RvdHlwZS5ldmVyeSA9IEV2ZW50ZWRMb29wLnByb3RvdHlwZS5vbjtcblxuICAgIC8vIEV4cG9ydCB0aGUgRXZlbnRlZExvb3Agb2JqZWN0IGZvciAqKk5vZGUuanMqKiBvciBvdGhlclxuICAgIC8vIGNvbW1vbmpzIHN5c3RlbXMuIE90aGVyd2lzZSwgYWRkIGl0IGFzIGEgZ2xvYmFsIG9iamVjdCB0byB0aGUgcm9vdFxuICAgIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBFdmVudGVkTG9vcDtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRzLkV2ZW50ZWRMb29wID0gRXZlbnRlZExvb3A7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB3aW5kb3cuRXZlbnRlZExvb3AgPSBFdmVudGVkTG9vcDtcbiAgICB9XG59KS5jYWxsKHRoaXMpO1xufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pIiwiLy8gICAgIFVuZGVyc2NvcmUuanMgMS42LjBcbi8vICAgICBodHRwOi8vdW5kZXJzY29yZWpzLm9yZ1xuLy8gICAgIChjKSAyMDA5LTIwMTQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbi8vICAgICBVbmRlcnNjb3JlIG1heSBiZSBmcmVlbHkgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuXG4oZnVuY3Rpb24oKSB7XG5cbiAgLy8gQmFzZWxpbmUgc2V0dXBcbiAgLy8gLS0tLS0tLS0tLS0tLS1cblxuICAvLyBFc3RhYmxpc2ggdGhlIHJvb3Qgb2JqZWN0LCBgd2luZG93YCBpbiB0aGUgYnJvd3Nlciwgb3IgYGV4cG9ydHNgIG9uIHRoZSBzZXJ2ZXIuXG4gIHZhciByb290ID0gdGhpcztcblxuICAvLyBTYXZlIHRoZSBwcmV2aW91cyB2YWx1ZSBvZiB0aGUgYF9gIHZhcmlhYmxlLlxuICB2YXIgcHJldmlvdXNVbmRlcnNjb3JlID0gcm9vdC5fO1xuXG4gIC8vIEVzdGFibGlzaCB0aGUgb2JqZWN0IHRoYXQgZ2V0cyByZXR1cm5lZCB0byBicmVhayBvdXQgb2YgYSBsb29wIGl0ZXJhdGlvbi5cbiAgdmFyIGJyZWFrZXIgPSB7fTtcblxuICAvLyBTYXZlIGJ5dGVzIGluIHRoZSBtaW5pZmllZCAoYnV0IG5vdCBnemlwcGVkKSB2ZXJzaW9uOlxuICB2YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSwgT2JqUHJvdG8gPSBPYmplY3QucHJvdG90eXBlLCBGdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGU7XG5cbiAgLy8gQ3JlYXRlIHF1aWNrIHJlZmVyZW5jZSB2YXJpYWJsZXMgZm9yIHNwZWVkIGFjY2VzcyB0byBjb3JlIHByb3RvdHlwZXMuXG4gIHZhclxuICAgIHB1c2ggICAgICAgICAgICAgPSBBcnJheVByb3RvLnB1c2gsXG4gICAgc2xpY2UgICAgICAgICAgICA9IEFycmF5UHJvdG8uc2xpY2UsXG4gICAgY29uY2F0ICAgICAgICAgICA9IEFycmF5UHJvdG8uY29uY2F0LFxuICAgIHRvU3RyaW5nICAgICAgICAgPSBPYmpQcm90by50b1N0cmluZyxcbiAgICBoYXNPd25Qcm9wZXJ0eSAgID0gT2JqUHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgLy8gQWxsICoqRUNNQVNjcmlwdCA1KiogbmF0aXZlIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9ucyB0aGF0IHdlIGhvcGUgdG8gdXNlXG4gIC8vIGFyZSBkZWNsYXJlZCBoZXJlLlxuICB2YXJcbiAgICBuYXRpdmVGb3JFYWNoICAgICAgPSBBcnJheVByb3RvLmZvckVhY2gsXG4gICAgbmF0aXZlTWFwICAgICAgICAgID0gQXJyYXlQcm90by5tYXAsXG4gICAgbmF0aXZlUmVkdWNlICAgICAgID0gQXJyYXlQcm90by5yZWR1Y2UsXG4gICAgbmF0aXZlUmVkdWNlUmlnaHQgID0gQXJyYXlQcm90by5yZWR1Y2VSaWdodCxcbiAgICBuYXRpdmVGaWx0ZXIgICAgICAgPSBBcnJheVByb3RvLmZpbHRlcixcbiAgICBuYXRpdmVFdmVyeSAgICAgICAgPSBBcnJheVByb3RvLmV2ZXJ5LFxuICAgIG5hdGl2ZVNvbWUgICAgICAgICA9IEFycmF5UHJvdG8uc29tZSxcbiAgICBuYXRpdmVJbmRleE9mICAgICAgPSBBcnJheVByb3RvLmluZGV4T2YsXG4gICAgbmF0aXZlTGFzdEluZGV4T2YgID0gQXJyYXlQcm90by5sYXN0SW5kZXhPZixcbiAgICBuYXRpdmVJc0FycmF5ICAgICAgPSBBcnJheS5pc0FycmF5LFxuICAgIG5hdGl2ZUtleXMgICAgICAgICA9IE9iamVjdC5rZXlzLFxuICAgIG5hdGl2ZUJpbmQgICAgICAgICA9IEZ1bmNQcm90by5iaW5kO1xuXG4gIC8vIENyZWF0ZSBhIHNhZmUgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgdXNlIGJlbG93LlxuICB2YXIgXyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogaW5zdGFuY2VvZiBfKSByZXR1cm4gb2JqO1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBfKSkgcmV0dXJuIG5ldyBfKG9iaik7XG4gICAgdGhpcy5fd3JhcHBlZCA9IG9iajtcbiAgfTtcblxuICAvLyBFeHBvcnQgdGhlIFVuZGVyc2NvcmUgb2JqZWN0IGZvciAqKk5vZGUuanMqKiwgd2l0aFxuICAvLyBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSBmb3IgdGhlIG9sZCBgcmVxdWlyZSgpYCBBUEkuIElmIHdlJ3JlIGluXG4gIC8vIHRoZSBicm93c2VyLCBhZGQgYF9gIGFzIGEgZ2xvYmFsIG9iamVjdCB2aWEgYSBzdHJpbmcgaWRlbnRpZmllcixcbiAgLy8gZm9yIENsb3N1cmUgQ29tcGlsZXIgXCJhZHZhbmNlZFwiIG1vZGUuXG4gIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF87XG4gICAgfVxuICAgIGV4cG9ydHMuXyA9IF87XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5fID0gXztcbiAgfVxuXG4gIC8vIEN1cnJlbnQgdmVyc2lvbi5cbiAgXy5WRVJTSU9OID0gJzEuNi4wJztcblxuICAvLyBDb2xsZWN0aW9uIEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIFRoZSBjb3JuZXJzdG9uZSwgYW4gYGVhY2hgIGltcGxlbWVudGF0aW9uLCBha2EgYGZvckVhY2hgLlxuICAvLyBIYW5kbGVzIG9iamVjdHMgd2l0aCB0aGUgYnVpbHQtaW4gYGZvckVhY2hgLCBhcnJheXMsIGFuZCByYXcgb2JqZWN0cy5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYGZvckVhY2hgIGlmIGF2YWlsYWJsZS5cbiAgdmFyIGVhY2ggPSBfLmVhY2ggPSBfLmZvckVhY2ggPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gb2JqO1xuICAgIGlmIChuYXRpdmVGb3JFYWNoICYmIG9iai5mb3JFYWNoID09PSBuYXRpdmVGb3JFYWNoKSB7XG4gICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXlzW2ldXSwga2V5c1tpXSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIFJldHVybiB0aGUgcmVzdWx0cyBvZiBhcHBseWluZyB0aGUgaXRlcmF0b3IgdG8gZWFjaCBlbGVtZW50LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgbWFwYCBpZiBhdmFpbGFibGUuXG4gIF8ubWFwID0gXy5jb2xsZWN0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gcmVzdWx0cztcbiAgICBpZiAobmF0aXZlTWFwICYmIG9iai5tYXAgPT09IG5hdGl2ZU1hcCkgcmV0dXJuIG9iai5tYXAoaXRlcmF0b3IsIGNvbnRleHQpO1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJlc3VsdHMucHVzaChpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgbGlzdCkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9O1xuXG4gIHZhciByZWR1Y2VFcnJvciA9ICdSZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJztcblxuICAvLyAqKlJlZHVjZSoqIGJ1aWxkcyB1cCBhIHNpbmdsZSByZXN1bHQgZnJvbSBhIGxpc3Qgb2YgdmFsdWVzLCBha2EgYGluamVjdGAsXG4gIC8vIG9yIGBmb2xkbGAuIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGByZWR1Y2VgIGlmIGF2YWlsYWJsZS5cbiAgXy5yZWR1Y2UgPSBfLmZvbGRsID0gXy5pbmplY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBtZW1vLCBjb250ZXh0KSB7XG4gICAgdmFyIGluaXRpYWwgPSBhcmd1bWVudHMubGVuZ3RoID4gMjtcbiAgICBpZiAob2JqID09IG51bGwpIG9iaiA9IFtdO1xuICAgIGlmIChuYXRpdmVSZWR1Y2UgJiYgb2JqLnJlZHVjZSA9PT0gbmF0aXZlUmVkdWNlKSB7XG4gICAgICBpZiAoY29udGV4dCkgaXRlcmF0b3IgPSBfLmJpbmQoaXRlcmF0b3IsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIGluaXRpYWwgPyBvYmoucmVkdWNlKGl0ZXJhdG9yLCBtZW1vKSA6IG9iai5yZWR1Y2UoaXRlcmF0b3IpO1xuICAgIH1cbiAgICBlYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICBpZiAoIWluaXRpYWwpIHtcbiAgICAgICAgbWVtbyA9IHZhbHVlO1xuICAgICAgICBpbml0aWFsID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1lbW8gPSBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG1lbW8sIHZhbHVlLCBpbmRleCwgbGlzdCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCFpbml0aWFsKSB0aHJvdyBuZXcgVHlwZUVycm9yKHJlZHVjZUVycm9yKTtcbiAgICByZXR1cm4gbWVtbztcbiAgfTtcblxuICAvLyBUaGUgcmlnaHQtYXNzb2NpYXRpdmUgdmVyc2lvbiBvZiByZWR1Y2UsIGFsc28ga25vd24gYXMgYGZvbGRyYC5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYHJlZHVjZVJpZ2h0YCBpZiBhdmFpbGFibGUuXG4gIF8ucmVkdWNlUmlnaHQgPSBfLmZvbGRyID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgbWVtbywgY29udGV4dCkge1xuICAgIHZhciBpbml0aWFsID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgaWYgKG9iaiA9PSBudWxsKSBvYmogPSBbXTtcbiAgICBpZiAobmF0aXZlUmVkdWNlUmlnaHQgJiYgb2JqLnJlZHVjZVJpZ2h0ID09PSBuYXRpdmVSZWR1Y2VSaWdodCkge1xuICAgICAgaWYgKGNvbnRleHQpIGl0ZXJhdG9yID0gXy5iaW5kKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBpbml0aWFsID8gb2JqLnJlZHVjZVJpZ2h0KGl0ZXJhdG9yLCBtZW1vKSA6IG9iai5yZWR1Y2VSaWdodChpdGVyYXRvcik7XG4gICAgfVxuICAgIHZhciBsZW5ndGggPSBvYmoubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggIT09ICtsZW5ndGgpIHtcbiAgICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgICBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB9XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaW5kZXggPSBrZXlzID8ga2V5c1stLWxlbmd0aF0gOiAtLWxlbmd0aDtcbiAgICAgIGlmICghaW5pdGlhbCkge1xuICAgICAgICBtZW1vID0gb2JqW2luZGV4XTtcbiAgICAgICAgaW5pdGlhbCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZW1vID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCBtZW1vLCBvYmpbaW5kZXhdLCBpbmRleCwgbGlzdCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCFpbml0aWFsKSB0aHJvdyBuZXcgVHlwZUVycm9yKHJlZHVjZUVycm9yKTtcbiAgICByZXR1cm4gbWVtbztcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIGZpcnN0IHZhbHVlIHdoaWNoIHBhc3NlcyBhIHRydXRoIHRlc3QuIEFsaWFzZWQgYXMgYGRldGVjdGAuXG4gIF8uZmluZCA9IF8uZGV0ZWN0ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIGFueShvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgbGlzdCkpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgdGhhdCBwYXNzIGEgdHJ1dGggdGVzdC5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYGZpbHRlcmAgaWYgYXZhaWxhYmxlLlxuICAvLyBBbGlhc2VkIGFzIGBzZWxlY3RgLlxuICBfLmZpbHRlciA9IF8uc2VsZWN0ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdHM7XG4gICAgaWYgKG5hdGl2ZUZpbHRlciAmJiBvYmouZmlsdGVyID09PSBuYXRpdmVGaWx0ZXIpIHJldHVybiBvYmouZmlsdGVyKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgbGlzdCkpIHJlc3VsdHMucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgZm9yIHdoaWNoIGEgdHJ1dGggdGVzdCBmYWlscy5cbiAgXy5yZWplY3QgPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgIHJldHVybiBfLmZpbHRlcihvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgcmV0dXJuICFwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgIH0sIGNvbnRleHQpO1xuICB9O1xuXG4gIC8vIERldGVybWluZSB3aGV0aGVyIGFsbCBvZiB0aGUgZWxlbWVudHMgbWF0Y2ggYSB0cnV0aCB0ZXN0LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgZXZlcnlgIGlmIGF2YWlsYWJsZS5cbiAgLy8gQWxpYXNlZCBhcyBgYWxsYC5cbiAgXy5ldmVyeSA9IF8uYWxsID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IF8uaWRlbnRpdHkpO1xuICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDtcbiAgICBpZiAobmF0aXZlRXZlcnkgJiYgb2JqLmV2ZXJ5ID09PSBuYXRpdmVFdmVyeSkgcmV0dXJuIG9iai5ldmVyeShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIGlmICghKHJlc3VsdCA9IHJlc3VsdCAmJiBwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpKSkgcmV0dXJuIGJyZWFrZXI7XG4gICAgfSk7XG4gICAgcmV0dXJuICEhcmVzdWx0O1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiBhdCBsZWFzdCBvbmUgZWxlbWVudCBpbiB0aGUgb2JqZWN0IG1hdGNoZXMgYSB0cnV0aCB0ZXN0LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgc29tZWAgaWYgYXZhaWxhYmxlLlxuICAvLyBBbGlhc2VkIGFzIGBhbnlgLlxuICB2YXIgYW55ID0gXy5zb21lID0gXy5hbnkgPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgIHByZWRpY2F0ZSB8fCAocHJlZGljYXRlID0gXy5pZGVudGl0eSk7XG4gICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDtcbiAgICBpZiAobmF0aXZlU29tZSAmJiBvYmouc29tZSA9PT0gbmF0aXZlU29tZSkgcmV0dXJuIG9iai5zb21lKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKHJlc3VsdCB8fCAocmVzdWx0ID0gcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkpIHJldHVybiBicmVha2VyO1xuICAgIH0pO1xuICAgIHJldHVybiAhIXJlc3VsdDtcbiAgfTtcblxuICAvLyBEZXRlcm1pbmUgaWYgdGhlIGFycmF5IG9yIG9iamVjdCBjb250YWlucyBhIGdpdmVuIHZhbHVlICh1c2luZyBgPT09YCkuXG4gIC8vIEFsaWFzZWQgYXMgYGluY2x1ZGVgLlxuICBfLmNvbnRhaW5zID0gXy5pbmNsdWRlID0gZnVuY3Rpb24ob2JqLCB0YXJnZXQpIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICBpZiAobmF0aXZlSW5kZXhPZiAmJiBvYmouaW5kZXhPZiA9PT0gbmF0aXZlSW5kZXhPZikgcmV0dXJuIG9iai5pbmRleE9mKHRhcmdldCkgIT0gLTE7XG4gICAgcmV0dXJuIGFueShvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHRhcmdldDtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBJbnZva2UgYSBtZXRob2QgKHdpdGggYXJndW1lbnRzKSBvbiBldmVyeSBpdGVtIGluIGEgY29sbGVjdGlvbi5cbiAgXy5pbnZva2UgPSBmdW5jdGlvbihvYmosIG1ldGhvZCkge1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgIHZhciBpc0Z1bmMgPSBfLmlzRnVuY3Rpb24obWV0aG9kKTtcbiAgICByZXR1cm4gXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIChpc0Z1bmMgPyBtZXRob2QgOiB2YWx1ZVttZXRob2RdKS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gQ29udmVuaWVuY2UgdmVyc2lvbiBvZiBhIGNvbW1vbiB1c2UgY2FzZSBvZiBgbWFwYDogZmV0Y2hpbmcgYSBwcm9wZXJ0eS5cbiAgXy5wbHVjayA9IGZ1bmN0aW9uKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIF8ubWFwKG9iaiwgXy5wcm9wZXJ0eShrZXkpKTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBmaWx0ZXJgOiBzZWxlY3Rpbmcgb25seSBvYmplY3RzXG4gIC8vIGNvbnRhaW5pbmcgc3BlY2lmaWMgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8ud2hlcmUgPSBmdW5jdGlvbihvYmosIGF0dHJzKSB7XG4gICAgcmV0dXJuIF8uZmlsdGVyKG9iaiwgXy5tYXRjaGVzKGF0dHJzKSk7XG4gIH07XG5cbiAgLy8gQ29udmVuaWVuY2UgdmVyc2lvbiBvZiBhIGNvbW1vbiB1c2UgY2FzZSBvZiBgZmluZGA6IGdldHRpbmcgdGhlIGZpcnN0IG9iamVjdFxuICAvLyBjb250YWluaW5nIHNwZWNpZmljIGBrZXk6dmFsdWVgIHBhaXJzLlxuICBfLmZpbmRXaGVyZSA9IGZ1bmN0aW9uKG9iaiwgYXR0cnMpIHtcbiAgICByZXR1cm4gXy5maW5kKG9iaiwgXy5tYXRjaGVzKGF0dHJzKSk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBtYXhpbXVtIGVsZW1lbnQgb3IgKGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLlxuICAvLyBDYW4ndCBvcHRpbWl6ZSBhcnJheXMgb2YgaW50ZWdlcnMgbG9uZ2VyIHRoYW4gNjUsNTM1IGVsZW1lbnRzLlxuICAvLyBTZWUgW1dlYktpdCBCdWcgODA3OTddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD04MDc5NylcbiAgXy5tYXggPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKCFpdGVyYXRvciAmJiBfLmlzQXJyYXkob2JqKSAmJiBvYmpbMF0gPT09ICtvYmpbMF0gJiYgb2JqLmxlbmd0aCA8IDY1NTM1KSB7XG4gICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkoTWF0aCwgb2JqKTtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IC1JbmZpbml0eSwgbGFzdENvbXB1dGVkID0gLUluZmluaXR5O1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHZhciBjb21wdXRlZCA9IGl0ZXJhdG9yID8gaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpIDogdmFsdWU7XG4gICAgICBpZiAoY29tcHV0ZWQgPiBsYXN0Q29tcHV0ZWQpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIGxhc3RDb21wdXRlZCA9IGNvbXB1dGVkO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBtaW5pbXVtIGVsZW1lbnQgKG9yIGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLlxuICBfLm1pbiA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpZiAoIWl0ZXJhdG9yICYmIF8uaXNBcnJheShvYmopICYmIG9ialswXSA9PT0gK29ialswXSAmJiBvYmoubGVuZ3RoIDwgNjU1MzUpIHtcbiAgICAgIHJldHVybiBNYXRoLm1pbi5hcHBseShNYXRoLCBvYmopO1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gSW5maW5pdHksIGxhc3RDb21wdXRlZCA9IEluZmluaXR5O1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHZhciBjb21wdXRlZCA9IGl0ZXJhdG9yID8gaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpIDogdmFsdWU7XG4gICAgICBpZiAoY29tcHV0ZWQgPCBsYXN0Q29tcHV0ZWQpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIGxhc3RDb21wdXRlZCA9IGNvbXB1dGVkO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gU2h1ZmZsZSBhbiBhcnJheSwgdXNpbmcgdGhlIG1vZGVybiB2ZXJzaW9uIG9mIHRoZVxuICAvLyBbRmlzaGVyLVlhdGVzIHNodWZmbGVdKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmlzaGVy4oCTWWF0ZXNfc2h1ZmZsZSkuXG4gIF8uc2h1ZmZsZSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciByYW5kO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHNodWZmbGVkID0gW107XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByYW5kID0gXy5yYW5kb20oaW5kZXgrKyk7XG4gICAgICBzaHVmZmxlZFtpbmRleCAtIDFdID0gc2h1ZmZsZWRbcmFuZF07XG4gICAgICBzaHVmZmxlZFtyYW5kXSA9IHZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBzaHVmZmxlZDtcbiAgfTtcblxuICAvLyBTYW1wbGUgKipuKiogcmFuZG9tIHZhbHVlcyBmcm9tIGEgY29sbGVjdGlvbi5cbiAgLy8gSWYgKipuKiogaXMgbm90IHNwZWNpZmllZCwgcmV0dXJucyBhIHNpbmdsZSByYW5kb20gZWxlbWVudC5cbiAgLy8gVGhlIGludGVybmFsIGBndWFyZGAgYXJndW1lbnQgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgbWFwYC5cbiAgXy5zYW1wbGUgPSBmdW5jdGlvbihvYmosIG4sIGd1YXJkKSB7XG4gICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkge1xuICAgICAgaWYgKG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoKSBvYmogPSBfLnZhbHVlcyhvYmopO1xuICAgICAgcmV0dXJuIG9ialtfLnJhbmRvbShvYmoubGVuZ3RoIC0gMSldO1xuICAgIH1cbiAgICByZXR1cm4gXy5zaHVmZmxlKG9iaikuc2xpY2UoMCwgTWF0aC5tYXgoMCwgbikpO1xuICB9O1xuXG4gIC8vIEFuIGludGVybmFsIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIGxvb2t1cCBpdGVyYXRvcnMuXG4gIHZhciBsb29rdXBJdGVyYXRvciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBfLmlkZW50aXR5O1xuICAgIGlmIChfLmlzRnVuY3Rpb24odmFsdWUpKSByZXR1cm4gdmFsdWU7XG4gICAgcmV0dXJuIF8ucHJvcGVydHkodmFsdWUpO1xuICB9O1xuXG4gIC8vIFNvcnQgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbiBwcm9kdWNlZCBieSBhbiBpdGVyYXRvci5cbiAgXy5zb3J0QnkgPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaXRlcmF0b3IgPSBsb29rdXBJdGVyYXRvcihpdGVyYXRvcik7XG4gICAgcmV0dXJuIF8ucGx1Y2soXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICBjcml0ZXJpYTogaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpXG4gICAgICB9O1xuICAgIH0pLnNvcnQoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgIHZhciBhID0gbGVmdC5jcml0ZXJpYTtcbiAgICAgIHZhciBiID0gcmlnaHQuY3JpdGVyaWE7XG4gICAgICBpZiAoYSAhPT0gYikge1xuICAgICAgICBpZiAoYSA+IGIgfHwgYSA9PT0gdm9pZCAwKSByZXR1cm4gMTtcbiAgICAgICAgaWYgKGEgPCBiIHx8IGIgPT09IHZvaWQgMCkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxlZnQuaW5kZXggLSByaWdodC5pbmRleDtcbiAgICB9KSwgJ3ZhbHVlJyk7XG4gIH07XG5cbiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBmb3IgYWdncmVnYXRlIFwiZ3JvdXAgYnlcIiBvcGVyYXRpb25zLlxuICB2YXIgZ3JvdXAgPSBmdW5jdGlvbihiZWhhdmlvcikge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICBpdGVyYXRvciA9IGxvb2t1cEl0ZXJhdG9yKGl0ZXJhdG9yKTtcbiAgICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGtleSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBvYmopO1xuICAgICAgICBiZWhhdmlvcihyZXN1bHQsIGtleSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gR3JvdXBzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24uIFBhc3MgZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZVxuICAvLyB0byBncm91cCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGNyaXRlcmlvbi5cbiAgXy5ncm91cEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCBrZXksIHZhbHVlKSB7XG4gICAgXy5oYXMocmVzdWx0LCBrZXkpID8gcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSkgOiByZXN1bHRba2V5XSA9IFt2YWx1ZV07XG4gIH0pO1xuXG4gIC8vIEluZGV4ZXMgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbiwgc2ltaWxhciB0byBgZ3JvdXBCeWAsIGJ1dCBmb3JcbiAgLy8gd2hlbiB5b3Uga25vdyB0aGF0IHlvdXIgaW5kZXggdmFsdWVzIHdpbGwgYmUgdW5pcXVlLlxuICBfLmluZGV4QnkgPSBncm91cChmdW5jdGlvbihyZXN1bHQsIGtleSwgdmFsdWUpIHtcbiAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICB9KTtcblxuICAvLyBDb3VudHMgaW5zdGFuY2VzIG9mIGFuIG9iamVjdCB0aGF0IGdyb3VwIGJ5IGEgY2VydGFpbiBjcml0ZXJpb24uIFBhc3NcbiAgLy8gZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZSB0byBjb3VudCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlXG4gIC8vIGNyaXRlcmlvbi5cbiAgXy5jb3VudEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCBrZXkpIHtcbiAgICBfLmhhcyhyZXN1bHQsIGtleSkgPyByZXN1bHRba2V5XSsrIDogcmVzdWx0W2tleV0gPSAxO1xuICB9KTtcblxuICAvLyBVc2UgYSBjb21wYXJhdG9yIGZ1bmN0aW9uIHRvIGZpZ3VyZSBvdXQgdGhlIHNtYWxsZXN0IGluZGV4IGF0IHdoaWNoXG4gIC8vIGFuIG9iamVjdCBzaG91bGQgYmUgaW5zZXJ0ZWQgc28gYXMgdG8gbWFpbnRhaW4gb3JkZXIuIFVzZXMgYmluYXJ5IHNlYXJjaC5cbiAgXy5zb3J0ZWRJbmRleCA9IGZ1bmN0aW9uKGFycmF5LCBvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaXRlcmF0b3IgPSBsb29rdXBJdGVyYXRvcihpdGVyYXRvcik7XG4gICAgdmFyIHZhbHVlID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmopO1xuICAgIHZhciBsb3cgPSAwLCBoaWdoID0gYXJyYXkubGVuZ3RoO1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxO1xuICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBhcnJheVttaWRdKSA8IHZhbHVlID8gbG93ID0gbWlkICsgMSA6IGhpZ2ggPSBtaWQ7XG4gICAgfVxuICAgIHJldHVybiBsb3c7XG4gIH07XG5cbiAgLy8gU2FmZWx5IGNyZWF0ZSBhIHJlYWwsIGxpdmUgYXJyYXkgZnJvbSBhbnl0aGluZyBpdGVyYWJsZS5cbiAgXy50b0FycmF5ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFvYmopIHJldHVybiBbXTtcbiAgICBpZiAoXy5pc0FycmF5KG9iaikpIHJldHVybiBzbGljZS5jYWxsKG9iaik7XG4gICAgaWYgKG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoKSByZXR1cm4gXy5tYXAob2JqLCBfLmlkZW50aXR5KTtcbiAgICByZXR1cm4gXy52YWx1ZXMob2JqKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhbiBvYmplY3QuXG4gIF8uc2l6ZSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkgPyBvYmoubGVuZ3RoIDogXy5rZXlzKG9iaikubGVuZ3RoO1xuICB9O1xuXG4gIC8vIEFycmF5IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS1cblxuICAvLyBHZXQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYW4gYXJyYXkuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gdGhlIGZpcnN0IE5cbiAgLy8gdmFsdWVzIGluIHRoZSBhcnJheS4gQWxpYXNlZCBhcyBgaGVhZGAgYW5kIGB0YWtlYC4gVGhlICoqZ3VhcmQqKiBjaGVja1xuICAvLyBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8uZmlyc3QgPSBfLmhlYWQgPSBfLnRha2UgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICBpZiAoKG4gPT0gbnVsbCkgfHwgZ3VhcmQpIHJldHVybiBhcnJheVswXTtcbiAgICBpZiAobiA8IDApIHJldHVybiBbXTtcbiAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgMCwgbik7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBldmVyeXRoaW5nIGJ1dCB0aGUgbGFzdCBlbnRyeSBvZiB0aGUgYXJyYXkuIEVzcGVjaWFsbHkgdXNlZnVsIG9uXG4gIC8vIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIGFsbCB0aGUgdmFsdWVzIGluXG4gIC8vIHRoZSBhcnJheSwgZXhjbHVkaW5nIHRoZSBsYXN0IE4uIFRoZSAqKmd1YXJkKiogY2hlY2sgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aFxuICAvLyBgXy5tYXBgLlxuICBfLmluaXRpYWwgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgMCwgYXJyYXkubGVuZ3RoIC0gKChuID09IG51bGwpIHx8IGd1YXJkID8gMSA6IG4pKTtcbiAgfTtcblxuICAvLyBHZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBhbiBhcnJheS4gUGFzc2luZyAqKm4qKiB3aWxsIHJldHVybiB0aGUgbGFzdCBOXG4gIC8vIHZhbHVlcyBpbiB0aGUgYXJyYXkuIFRoZSAqKmd1YXJkKiogY2hlY2sgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLmxhc3QgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICBpZiAoKG4gPT0gbnVsbCkgfHwgZ3VhcmQpIHJldHVybiBhcnJheVthcnJheS5sZW5ndGggLSAxXTtcbiAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgTWF0aC5tYXgoYXJyYXkubGVuZ3RoIC0gbiwgMCkpO1xuICB9O1xuXG4gIC8vIFJldHVybnMgZXZlcnl0aGluZyBidXQgdGhlIGZpcnN0IGVudHJ5IG9mIHRoZSBhcnJheS4gQWxpYXNlZCBhcyBgdGFpbGAgYW5kIGBkcm9wYC5cbiAgLy8gRXNwZWNpYWxseSB1c2VmdWwgb24gdGhlIGFyZ3VtZW50cyBvYmplY3QuIFBhc3NpbmcgYW4gKipuKiogd2lsbCByZXR1cm5cbiAgLy8gdGhlIHJlc3QgTiB2YWx1ZXMgaW4gdGhlIGFycmF5LiBUaGUgKipndWFyZCoqXG4gIC8vIGNoZWNrIGFsbG93cyBpdCB0byB3b3JrIHdpdGggYF8ubWFwYC5cbiAgXy5yZXN0ID0gXy50YWlsID0gXy5kcm9wID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwoYXJyYXksIChuID09IG51bGwpIHx8IGd1YXJkID8gMSA6IG4pO1xuICB9O1xuXG4gIC8vIFRyaW0gb3V0IGFsbCBmYWxzeSB2YWx1ZXMgZnJvbSBhbiBhcnJheS5cbiAgXy5jb21wYWN0ID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIoYXJyYXksIF8uaWRlbnRpdHkpO1xuICB9O1xuXG4gIC8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIGEgcmVjdXJzaXZlIGBmbGF0dGVuYCBmdW5jdGlvbi5cbiAgdmFyIGZsYXR0ZW4gPSBmdW5jdGlvbihpbnB1dCwgc2hhbGxvdywgb3V0cHV0KSB7XG4gICAgaWYgKHNoYWxsb3cgJiYgXy5ldmVyeShpbnB1dCwgXy5pc0FycmF5KSkge1xuICAgICAgcmV0dXJuIGNvbmNhdC5hcHBseShvdXRwdXQsIGlucHV0KTtcbiAgICB9XG4gICAgZWFjaChpbnB1dCwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkodmFsdWUpIHx8IF8uaXNBcmd1bWVudHModmFsdWUpKSB7XG4gICAgICAgIHNoYWxsb3cgPyBwdXNoLmFwcGx5KG91dHB1dCwgdmFsdWUpIDogZmxhdHRlbih2YWx1ZSwgc2hhbGxvdywgb3V0cHV0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9O1xuXG4gIC8vIEZsYXR0ZW4gb3V0IGFuIGFycmF5LCBlaXRoZXIgcmVjdXJzaXZlbHkgKGJ5IGRlZmF1bHQpLCBvciBqdXN0IG9uZSBsZXZlbC5cbiAgXy5mbGF0dGVuID0gZnVuY3Rpb24oYXJyYXksIHNoYWxsb3cpIHtcbiAgICByZXR1cm4gZmxhdHRlbihhcnJheSwgc2hhbGxvdywgW10pO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHZlcnNpb24gb2YgdGhlIGFycmF5IHRoYXQgZG9lcyBub3QgY29udGFpbiB0aGUgc3BlY2lmaWVkIHZhbHVlKHMpLlxuICBfLndpdGhvdXQgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHJldHVybiBfLmRpZmZlcmVuY2UoYXJyYXksIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gIH07XG5cbiAgLy8gU3BsaXQgYW4gYXJyYXkgaW50byB0d28gYXJyYXlzOiBvbmUgd2hvc2UgZWxlbWVudHMgYWxsIHNhdGlzZnkgdGhlIGdpdmVuXG4gIC8vIHByZWRpY2F0ZSwgYW5kIG9uZSB3aG9zZSBlbGVtZW50cyBhbGwgZG8gbm90IHNhdGlzZnkgdGhlIHByZWRpY2F0ZS5cbiAgXy5wYXJ0aXRpb24gPSBmdW5jdGlvbihhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgdmFyIHBhc3MgPSBbXSwgZmFpbCA9IFtdO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKGVsZW0pIHtcbiAgICAgIChwcmVkaWNhdGUoZWxlbSkgPyBwYXNzIDogZmFpbCkucHVzaChlbGVtKTtcbiAgICB9KTtcbiAgICByZXR1cm4gW3Bhc3MsIGZhaWxdO1xuICB9O1xuXG4gIC8vIFByb2R1Y2UgYSBkdXBsaWNhdGUtZnJlZSB2ZXJzaW9uIG9mIHRoZSBhcnJheS4gSWYgdGhlIGFycmF5IGhhcyBhbHJlYWR5XG4gIC8vIGJlZW4gc29ydGVkLCB5b3UgaGF2ZSB0aGUgb3B0aW9uIG9mIHVzaW5nIGEgZmFzdGVyIGFsZ29yaXRobS5cbiAgLy8gQWxpYXNlZCBhcyBgdW5pcXVlYC5cbiAgXy51bmlxID0gXy51bmlxdWUgPSBmdW5jdGlvbihhcnJheSwgaXNTb3J0ZWQsIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKF8uaXNGdW5jdGlvbihpc1NvcnRlZCkpIHtcbiAgICAgIGNvbnRleHQgPSBpdGVyYXRvcjtcbiAgICAgIGl0ZXJhdG9yID0gaXNTb3J0ZWQ7XG4gICAgICBpc1NvcnRlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB2YXIgaW5pdGlhbCA9IGl0ZXJhdG9yID8gXy5tYXAoYXJyYXksIGl0ZXJhdG9yLCBjb250ZXh0KSA6IGFycmF5O1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdmFyIHNlZW4gPSBbXTtcbiAgICBlYWNoKGluaXRpYWwsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgaWYgKGlzU29ydGVkID8gKCFpbmRleCB8fCBzZWVuW3NlZW4ubGVuZ3RoIC0gMV0gIT09IHZhbHVlKSA6ICFfLmNvbnRhaW5zKHNlZW4sIHZhbHVlKSkge1xuICAgICAgICBzZWVuLnB1c2godmFsdWUpO1xuICAgICAgICByZXN1bHRzLnB1c2goYXJyYXlbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHVuaW9uOiBlYWNoIGRpc3RpbmN0IGVsZW1lbnQgZnJvbSBhbGwgb2ZcbiAgLy8gdGhlIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8udW5pb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXy51bmlxKF8uZmxhdHRlbihhcmd1bWVudHMsIHRydWUpKTtcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgZXZlcnkgaXRlbSBzaGFyZWQgYmV0d2VlbiBhbGwgdGhlXG4gIC8vIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8uaW50ZXJzZWN0aW9uID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgcmVzdCA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gXy5maWx0ZXIoXy51bmlxKGFycmF5KSwgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgcmV0dXJuIF8uZXZlcnkocmVzdCwgZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIF8uY29udGFpbnMob3RoZXIsIGl0ZW0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gVGFrZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG9uZSBhcnJheSBhbmQgYSBudW1iZXIgb2Ygb3RoZXIgYXJyYXlzLlxuICAvLyBPbmx5IHRoZSBlbGVtZW50cyBwcmVzZW50IGluIGp1c3QgdGhlIGZpcnN0IGFycmF5IHdpbGwgcmVtYWluLlxuICBfLmRpZmZlcmVuY2UgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHZhciByZXN0ID0gY29uY2F0LmFwcGx5KEFycmF5UHJvdG8sIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gICAgcmV0dXJuIF8uZmlsdGVyKGFycmF5LCBmdW5jdGlvbih2YWx1ZSl7IHJldHVybiAhXy5jb250YWlucyhyZXN0LCB2YWx1ZSk7IH0pO1xuICB9O1xuXG4gIC8vIFppcCB0b2dldGhlciBtdWx0aXBsZSBsaXN0cyBpbnRvIGEgc2luZ2xlIGFycmF5IC0tIGVsZW1lbnRzIHRoYXQgc2hhcmVcbiAgLy8gYW4gaW5kZXggZ28gdG9nZXRoZXIuXG4gIF8uemlwID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGxlbmd0aCA9IF8ubWF4KF8ucGx1Y2soYXJndW1lbnRzLCAnbGVuZ3RoJykuY29uY2F0KDApKTtcbiAgICB2YXIgcmVzdWx0cyA9IG5ldyBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdHNbaV0gPSBfLnBsdWNrKGFyZ3VtZW50cywgJycgKyBpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH07XG5cbiAgLy8gQ29udmVydHMgbGlzdHMgaW50byBvYmplY3RzLiBQYXNzIGVpdGhlciBhIHNpbmdsZSBhcnJheSBvZiBgW2tleSwgdmFsdWVdYFxuICAvLyBwYWlycywgb3IgdHdvIHBhcmFsbGVsIGFycmF5cyBvZiB0aGUgc2FtZSBsZW5ndGggLS0gb25lIG9mIGtleXMsIGFuZCBvbmUgb2ZcbiAgLy8gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICBfLm9iamVjdCA9IGZ1bmN0aW9uKGxpc3QsIHZhbHVlcykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiB7fTtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGxpc3QubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh2YWx1ZXMpIHtcbiAgICAgICAgcmVzdWx0W2xpc3RbaV1dID0gdmFsdWVzW2ldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W2xpc3RbaV1bMF1dID0gbGlzdFtpXVsxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBJZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBseSB1cyB3aXRoIGluZGV4T2YgKEknbSBsb29raW5nIGF0IHlvdSwgKipNU0lFKiopLFxuICAvLyB3ZSBuZWVkIHRoaXMgZnVuY3Rpb24uIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW5cbiAgLy8gaXRlbSBpbiBhbiBhcnJheSwgb3IgLTEgaWYgdGhlIGl0ZW0gaXMgbm90IGluY2x1ZGVkIGluIHRoZSBhcnJheS5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYGluZGV4T2ZgIGlmIGF2YWlsYWJsZS5cbiAgLy8gSWYgdGhlIGFycmF5IGlzIGxhcmdlIGFuZCBhbHJlYWR5IGluIHNvcnQgb3JkZXIsIHBhc3MgYHRydWVgXG4gIC8vIGZvciAqKmlzU29ydGVkKiogdG8gdXNlIGJpbmFyeSBzZWFyY2guXG4gIF8uaW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBpc1NvcnRlZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gLTE7XG4gICAgdmFyIGkgPSAwLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGlzU29ydGVkKSB7XG4gICAgICBpZiAodHlwZW9mIGlzU29ydGVkID09ICdudW1iZXInKSB7XG4gICAgICAgIGkgPSAoaXNTb3J0ZWQgPCAwID8gTWF0aC5tYXgoMCwgbGVuZ3RoICsgaXNTb3J0ZWQpIDogaXNTb3J0ZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSA9IF8uc29ydGVkSW5kZXgoYXJyYXksIGl0ZW0pO1xuICAgICAgICByZXR1cm4gYXJyYXlbaV0gPT09IGl0ZW0gPyBpIDogLTE7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChuYXRpdmVJbmRleE9mICYmIGFycmF5LmluZGV4T2YgPT09IG5hdGl2ZUluZGV4T2YpIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0sIGlzU29ydGVkKTtcbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgbGFzdEluZGV4T2ZgIGlmIGF2YWlsYWJsZS5cbiAgXy5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBmcm9tKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiAtMTtcbiAgICB2YXIgaGFzSW5kZXggPSBmcm9tICE9IG51bGw7XG4gICAgaWYgKG5hdGl2ZUxhc3RJbmRleE9mICYmIGFycmF5Lmxhc3RJbmRleE9mID09PSBuYXRpdmVMYXN0SW5kZXhPZikge1xuICAgICAgcmV0dXJuIGhhc0luZGV4ID8gYXJyYXkubGFzdEluZGV4T2YoaXRlbSwgZnJvbSkgOiBhcnJheS5sYXN0SW5kZXhPZihpdGVtKTtcbiAgICB9XG4gICAgdmFyIGkgPSAoaGFzSW5kZXggPyBmcm9tIDogYXJyYXkubGVuZ3RoKTtcbiAgICB3aGlsZSAoaS0tKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBHZW5lcmF0ZSBhbiBpbnRlZ2VyIEFycmF5IGNvbnRhaW5pbmcgYW4gYXJpdGhtZXRpYyBwcm9ncmVzc2lvbi4gQSBwb3J0IG9mXG4gIC8vIHRoZSBuYXRpdmUgUHl0aG9uIGByYW5nZSgpYCBmdW5jdGlvbi4gU2VlXG4gIC8vIFt0aGUgUHl0aG9uIGRvY3VtZW50YXRpb25dKGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS9mdW5jdGlvbnMuaHRtbCNyYW5nZSkuXG4gIF8ucmFuZ2UgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgc3RlcCkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDw9IDEpIHtcbiAgICAgIHN0b3AgPSBzdGFydCB8fCAwO1xuICAgICAgc3RhcnQgPSAwO1xuICAgIH1cbiAgICBzdGVwID0gYXJndW1lbnRzWzJdIHx8IDE7XG5cbiAgICB2YXIgbGVuZ3RoID0gTWF0aC5tYXgoTWF0aC5jZWlsKChzdG9wIC0gc3RhcnQpIC8gc3RlcCksIDApO1xuICAgIHZhciBpZHggPSAwO1xuICAgIHZhciByYW5nZSA9IG5ldyBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUoaWR4IDwgbGVuZ3RoKSB7XG4gICAgICByYW5nZVtpZHgrK10gPSBzdGFydDtcbiAgICAgIHN0YXJ0ICs9IHN0ZXA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJhbmdlO1xuICB9O1xuXG4gIC8vIEZ1bmN0aW9uIChhaGVtKSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV1c2FibGUgY29uc3RydWN0b3IgZnVuY3Rpb24gZm9yIHByb3RvdHlwZSBzZXR0aW5nLlxuICB2YXIgY3RvciA9IGZ1bmN0aW9uKCl7fTtcblxuICAvLyBDcmVhdGUgYSBmdW5jdGlvbiBib3VuZCB0byBhIGdpdmVuIG9iamVjdCAoYXNzaWduaW5nIGB0aGlzYCwgYW5kIGFyZ3VtZW50cyxcbiAgLy8gb3B0aW9uYWxseSkuIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBGdW5jdGlvbi5iaW5kYCBpZlxuICAvLyBhdmFpbGFibGUuXG4gIF8uYmluZCA9IGZ1bmN0aW9uKGZ1bmMsIGNvbnRleHQpIHtcbiAgICB2YXIgYXJncywgYm91bmQ7XG4gICAgaWYgKG5hdGl2ZUJpbmQgJiYgZnVuYy5iaW5kID09PSBuYXRpdmVCaW5kKSByZXR1cm4gbmF0aXZlQmluZC5hcHBseShmdW5jLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIGlmICghXy5pc0Z1bmN0aW9uKGZ1bmMpKSB0aHJvdyBuZXcgVHlwZUVycm9yO1xuICAgIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGJvdW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgYm91bmQpKSByZXR1cm4gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgIGN0b3IucHJvdG90eXBlID0gZnVuYy5wcm90b3R5cGU7XG4gICAgICB2YXIgc2VsZiA9IG5ldyBjdG9yO1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBudWxsO1xuICAgICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkoc2VsZiwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICBpZiAoT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUGFydGlhbGx5IGFwcGx5IGEgZnVuY3Rpb24gYnkgY3JlYXRpbmcgYSB2ZXJzaW9uIHRoYXQgaGFzIGhhZCBzb21lIG9mIGl0c1xuICAvLyBhcmd1bWVudHMgcHJlLWZpbGxlZCwgd2l0aG91dCBjaGFuZ2luZyBpdHMgZHluYW1pYyBgdGhpc2AgY29udGV4dC4gXyBhY3RzXG4gIC8vIGFzIGEgcGxhY2Vob2xkZXIsIGFsbG93aW5nIGFueSBjb21iaW5hdGlvbiBvZiBhcmd1bWVudHMgdG8gYmUgcHJlLWZpbGxlZC5cbiAgXy5wYXJ0aWFsID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHZhciBib3VuZEFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHBvc2l0aW9uID0gMDtcbiAgICAgIHZhciBhcmdzID0gYm91bmRBcmdzLnNsaWNlKCk7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJncy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYXJnc1tpXSA9PT0gXykgYXJnc1tpXSA9IGFyZ3VtZW50c1twb3NpdGlvbisrXTtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChwb3NpdGlvbiA8IGFyZ3VtZW50cy5sZW5ndGgpIGFyZ3MucHVzaChhcmd1bWVudHNbcG9zaXRpb24rK10pO1xuICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfTtcbiAgfTtcblxuICAvLyBCaW5kIGEgbnVtYmVyIG9mIGFuIG9iamVjdCdzIG1ldGhvZHMgdG8gdGhhdCBvYmplY3QuIFJlbWFpbmluZyBhcmd1bWVudHNcbiAgLy8gYXJlIHRoZSBtZXRob2QgbmFtZXMgdG8gYmUgYm91bmQuIFVzZWZ1bCBmb3IgZW5zdXJpbmcgdGhhdCBhbGwgY2FsbGJhY2tzXG4gIC8vIGRlZmluZWQgb24gYW4gb2JqZWN0IGJlbG9uZyB0byBpdC5cbiAgXy5iaW5kQWxsID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGZ1bmNzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIGlmIChmdW5jcy5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcignYmluZEFsbCBtdXN0IGJlIHBhc3NlZCBmdW5jdGlvbiBuYW1lcycpO1xuICAgIGVhY2goZnVuY3MsIGZ1bmN0aW9uKGYpIHsgb2JqW2ZdID0gXy5iaW5kKG9ialtmXSwgb2JqKTsgfSk7XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBNZW1vaXplIGFuIGV4cGVuc2l2ZSBmdW5jdGlvbiBieSBzdG9yaW5nIGl0cyByZXN1bHRzLlxuICBfLm1lbW9pemUgPSBmdW5jdGlvbihmdW5jLCBoYXNoZXIpIHtcbiAgICB2YXIgbWVtbyA9IHt9O1xuICAgIGhhc2hlciB8fCAoaGFzaGVyID0gXy5pZGVudGl0eSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGtleSA9IGhhc2hlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIF8uaGFzKG1lbW8sIGtleSkgPyBtZW1vW2tleV0gOiAobWVtb1trZXldID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgICB9O1xuICB9O1xuXG4gIC8vIERlbGF5cyBhIGZ1bmN0aW9uIGZvciB0aGUgZ2l2ZW4gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcywgYW5kIHRoZW4gY2FsbHNcbiAgLy8gaXQgd2l0aCB0aGUgYXJndW1lbnRzIHN1cHBsaWVkLlxuICBfLmRlbGF5ID0gZnVuY3Rpb24oZnVuYywgd2FpdCkge1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IHJldHVybiBmdW5jLmFwcGx5KG51bGwsIGFyZ3MpOyB9LCB3YWl0KTtcbiAgfTtcblxuICAvLyBEZWZlcnMgYSBmdW5jdGlvbiwgc2NoZWR1bGluZyBpdCB0byBydW4gYWZ0ZXIgdGhlIGN1cnJlbnQgY2FsbCBzdGFjayBoYXNcbiAgLy8gY2xlYXJlZC5cbiAgXy5kZWZlciA9IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICByZXR1cm4gXy5kZWxheS5hcHBseShfLCBbZnVuYywgMV0uY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSkpO1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgd2hlbiBpbnZva2VkLCB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGF0IG1vc3Qgb25jZVxuICAvLyBkdXJpbmcgYSBnaXZlbiB3aW5kb3cgb2YgdGltZS4gTm9ybWFsbHksIHRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gd2lsbCBydW5cbiAgLy8gYXMgbXVjaCBhcyBpdCBjYW4sIHdpdGhvdXQgZXZlciBnb2luZyBtb3JlIHRoYW4gb25jZSBwZXIgYHdhaXRgIGR1cmF0aW9uO1xuICAvLyBidXQgaWYgeW91J2QgbGlrZSB0byBkaXNhYmxlIHRoZSBleGVjdXRpb24gb24gdGhlIGxlYWRpbmcgZWRnZSwgcGFzc1xuICAvLyBge2xlYWRpbmc6IGZhbHNlfWAuIFRvIGRpc2FibGUgZXhlY3V0aW9uIG9uIHRoZSB0cmFpbGluZyBlZGdlLCBkaXR0by5cbiAgXy50aHJvdHRsZSA9IGZ1bmN0aW9uKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgICB2YXIgY29udGV4dCwgYXJncywgcmVzdWx0O1xuICAgIHZhciB0aW1lb3V0ID0gbnVsbDtcbiAgICB2YXIgcHJldmlvdXMgPSAwO1xuICAgIG9wdGlvbnMgfHwgKG9wdGlvbnMgPSB7fSk7XG4gICAgdmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICBwcmV2aW91cyA9IG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UgPyAwIDogXy5ub3coKTtcbiAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIGNvbnRleHQgPSBhcmdzID0gbnVsbDtcbiAgICB9O1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBub3cgPSBfLm5vdygpO1xuICAgICAgaWYgKCFwcmV2aW91cyAmJiBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlKSBwcmV2aW91cyA9IG5vdztcbiAgICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdyAtIHByZXZpb3VzKTtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIGlmIChyZW1haW5pbmcgPD0gMCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmICghdGltZW91dCAmJiBvcHRpb25zLnRyYWlsaW5nICE9PSBmYWxzZSkge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIGFzIGxvbmcgYXMgaXQgY29udGludWVzIHRvIGJlIGludm9rZWQsIHdpbGwgbm90XG4gIC8vIGJlIHRyaWdnZXJlZC4gVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGl0IHN0b3BzIGJlaW5nIGNhbGxlZCBmb3JcbiAgLy8gTiBtaWxsaXNlY29uZHMuIElmIGBpbW1lZGlhdGVgIGlzIHBhc3NlZCwgdHJpZ2dlciB0aGUgZnVuY3Rpb24gb24gdGhlXG4gIC8vIGxlYWRpbmcgZWRnZSwgaW5zdGVhZCBvZiB0aGUgdHJhaWxpbmcuXG4gIF8uZGVib3VuY2UgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICB2YXIgdGltZW91dCwgYXJncywgY29udGV4dCwgdGltZXN0YW1wLCByZXN1bHQ7XG5cbiAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBsYXN0ID0gXy5ub3coKSAtIHRpbWVzdGFtcDtcbiAgICAgIGlmIChsYXN0IDwgd2FpdCkge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCAtIGxhc3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgIGlmICghaW1tZWRpYXRlKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgICBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgY29udGV4dCA9IHRoaXM7XG4gICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgdGltZXN0YW1wID0gXy5ub3coKTtcbiAgICAgIHZhciBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuICAgICAgaWYgKCF0aW1lb3V0KSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0KTtcbiAgICAgIH1cbiAgICAgIGlmIChjYWxsTm93KSB7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIGNvbnRleHQgPSBhcmdzID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgZXhlY3V0ZWQgYXQgbW9zdCBvbmUgdGltZSwgbm8gbWF0dGVyIGhvd1xuICAvLyBvZnRlbiB5b3UgY2FsbCBpdC4gVXNlZnVsIGZvciBsYXp5IGluaXRpYWxpemF0aW9uLlxuICBfLm9uY2UgPSBmdW5jdGlvbihmdW5jKSB7XG4gICAgdmFyIHJhbiA9IGZhbHNlLCBtZW1vO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChyYW4pIHJldHVybiBtZW1vO1xuICAgICAgcmFuID0gdHJ1ZTtcbiAgICAgIG1lbW8gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICBmdW5jID0gbnVsbDtcbiAgICAgIHJldHVybiBtZW1vO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyB0aGUgZmlyc3QgZnVuY3Rpb24gcGFzc2VkIGFzIGFuIGFyZ3VtZW50IHRvIHRoZSBzZWNvbmQsXG4gIC8vIGFsbG93aW5nIHlvdSB0byBhZGp1c3QgYXJndW1lbnRzLCBydW4gY29kZSBiZWZvcmUgYW5kIGFmdGVyLCBhbmRcbiAgLy8gY29uZGl0aW9uYWxseSBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbi5cbiAgXy53cmFwID0gZnVuY3Rpb24oZnVuYywgd3JhcHBlcikge1xuICAgIHJldHVybiBfLnBhcnRpYWwod3JhcHBlciwgZnVuYyk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIGEgbGlzdCBvZiBmdW5jdGlvbnMsIGVhY2hcbiAgLy8gY29uc3VtaW5nIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHRoYXQgZm9sbG93cy5cbiAgXy5jb21wb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZ1bmNzID0gYXJndW1lbnRzO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgZm9yICh2YXIgaSA9IGZ1bmNzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGFyZ3MgPSBbZnVuY3NbaV0uYXBwbHkodGhpcywgYXJncyldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFyZ3NbMF07XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIG9ubHkgYmUgZXhlY3V0ZWQgYWZ0ZXIgYmVpbmcgY2FsbGVkIE4gdGltZXMuXG4gIF8uYWZ0ZXIgPSBmdW5jdGlvbih0aW1lcywgZnVuYykge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICgtLXRpbWVzIDwgMSkge1xuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gT2JqZWN0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV0cmlldmUgdGhlIG5hbWVzIG9mIGFuIG9iamVjdCdzIHByb3BlcnRpZXMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBPYmplY3Qua2V5c2BcbiAgXy5rZXlzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBbXTtcbiAgICBpZiAobmF0aXZlS2V5cykgcmV0dXJuIG5hdGl2ZUtleXMob2JqKTtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChfLmhhcyhvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xuICB9O1xuXG4gIC8vIFJldHJpZXZlIHRoZSB2YWx1ZXMgb2YgYW4gb2JqZWN0J3MgcHJvcGVydGllcy5cbiAgXy52YWx1ZXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdmFsdWVzW2ldID0gb2JqW2tleXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9O1xuXG4gIC8vIENvbnZlcnQgYW4gb2JqZWN0IGludG8gYSBsaXN0IG9mIGBba2V5LCB2YWx1ZV1gIHBhaXJzLlxuICBfLnBhaXJzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIHBhaXJzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcGFpcnNbaV0gPSBba2V5c1tpXSwgb2JqW2tleXNbaV1dXTtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXJzO1xuICB9O1xuXG4gIC8vIEludmVydCB0aGUga2V5cyBhbmQgdmFsdWVzIG9mIGFuIG9iamVjdC4gVGhlIHZhbHVlcyBtdXN0IGJlIHNlcmlhbGl6YWJsZS5cbiAgXy5pbnZlcnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0W29ialtrZXlzW2ldXV0gPSBrZXlzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHNvcnRlZCBsaXN0IG9mIHRoZSBmdW5jdGlvbiBuYW1lcyBhdmFpbGFibGUgb24gdGhlIG9iamVjdC5cbiAgLy8gQWxpYXNlZCBhcyBgbWV0aG9kc2BcbiAgXy5mdW5jdGlvbnMgPSBfLm1ldGhvZHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgbmFtZXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKG9ialtrZXldKSkgbmFtZXMucHVzaChrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZXMuc29ydCgpO1xuICB9O1xuXG4gIC8vIEV4dGVuZCBhIGdpdmVuIG9iamVjdCB3aXRoIGFsbCB0aGUgcHJvcGVydGllcyBpbiBwYXNzZWQtaW4gb2JqZWN0KHMpLlxuICBfLmV4dGVuZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBvYmpbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIGNvcHkgb2YgdGhlIG9iamVjdCBvbmx5IGNvbnRhaW5pbmcgdGhlIHdoaXRlbGlzdGVkIHByb3BlcnRpZXMuXG4gIF8ucGljayA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBjb3B5ID0ge307XG4gICAgdmFyIGtleXMgPSBjb25jYXQuYXBwbHkoQXJyYXlQcm90bywgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICBlYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgaWYgKGtleSBpbiBvYmopIGNvcHlba2V5XSA9IG9ialtrZXldO1xuICAgIH0pO1xuICAgIHJldHVybiBjb3B5O1xuICB9O1xuXG4gICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgd2l0aG91dCB0aGUgYmxhY2tsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5vbWl0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGNvcHkgPSB7fTtcbiAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIGlmICghXy5jb250YWlucyhrZXlzLCBrZXkpKSBjb3B5W2tleV0gPSBvYmpba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGNvcHk7XG4gIH07XG5cbiAgLy8gRmlsbCBpbiBhIGdpdmVuIG9iamVjdCB3aXRoIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgXy5kZWZhdWx0cyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBpZiAob2JqW3Byb3BdID09PSB2b2lkIDApIG9ialtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gQ3JlYXRlIGEgKHNoYWxsb3ctY2xvbmVkKSBkdXBsaWNhdGUgb2YgYW4gb2JqZWN0LlxuICBfLmNsb25lID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIF8uaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBfLmV4dGVuZCh7fSwgb2JqKTtcbiAgfTtcblxuICAvLyBJbnZva2VzIGludGVyY2VwdG9yIHdpdGggdGhlIG9iaiwgYW5kIHRoZW4gcmV0dXJucyBvYmouXG4gIC8vIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluLCBpblxuICAvLyBvcmRlciB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaW50ZXJtZWRpYXRlIHJlc3VsdHMgd2l0aGluIHRoZSBjaGFpbi5cbiAgXy50YXAgPSBmdW5jdGlvbihvYmosIGludGVyY2VwdG9yKSB7XG4gICAgaW50ZXJjZXB0b3Iob2JqKTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIEludGVybmFsIHJlY3Vyc2l2ZSBjb21wYXJpc29uIGZ1bmN0aW9uIGZvciBgaXNFcXVhbGAuXG4gIHZhciBlcSA9IGZ1bmN0aW9uKGEsIGIsIGFTdGFjaywgYlN0YWNrKSB7XG4gICAgLy8gSWRlbnRpY2FsIG9iamVjdHMgYXJlIGVxdWFsLiBgMCA9PT0gLTBgLCBidXQgdGhleSBhcmVuJ3QgaWRlbnRpY2FsLlxuICAgIC8vIFNlZSB0aGUgW0hhcm1vbnkgYGVnYWxgIHByb3Bvc2FsXShodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1oYXJtb255OmVnYWwpLlxuICAgIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PSAxIC8gYjtcbiAgICAvLyBBIHN0cmljdCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGBudWxsID09IHVuZGVmaW5lZGAuXG4gICAgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwpIHJldHVybiBhID09PSBiO1xuICAgIC8vIFVud3JhcCBhbnkgd3JhcHBlZCBvYmplY3RzLlxuICAgIGlmIChhIGluc3RhbmNlb2YgXykgYSA9IGEuX3dyYXBwZWQ7XG4gICAgaWYgKGIgaW5zdGFuY2VvZiBfKSBiID0gYi5fd3JhcHBlZDtcbiAgICAvLyBDb21wYXJlIGBbW0NsYXNzXV1gIG5hbWVzLlxuICAgIHZhciBjbGFzc05hbWUgPSB0b1N0cmluZy5jYWxsKGEpO1xuICAgIGlmIChjbGFzc05hbWUgIT0gdG9TdHJpbmcuY2FsbChiKSkgcmV0dXJuIGZhbHNlO1xuICAgIHN3aXRjaCAoY2xhc3NOYW1lKSB7XG4gICAgICAvLyBTdHJpbmdzLCBudW1iZXJzLCBkYXRlcywgYW5kIGJvb2xlYW5zIGFyZSBjb21wYXJlZCBieSB2YWx1ZS5cbiAgICAgIGNhc2UgJ1tvYmplY3QgU3RyaW5nXSc6XG4gICAgICAgIC8vIFByaW1pdGl2ZXMgYW5kIHRoZWlyIGNvcnJlc3BvbmRpbmcgb2JqZWN0IHdyYXBwZXJzIGFyZSBlcXVpdmFsZW50OyB0aHVzLCBgXCI1XCJgIGlzXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gYG5ldyBTdHJpbmcoXCI1XCIpYC5cbiAgICAgICAgcmV0dXJuIGEgPT0gU3RyaW5nKGIpO1xuICAgICAgY2FzZSAnW29iamVjdCBOdW1iZXJdJzpcbiAgICAgICAgLy8gYE5hTmBzIGFyZSBlcXVpdmFsZW50LCBidXQgbm9uLXJlZmxleGl2ZS4gQW4gYGVnYWxgIGNvbXBhcmlzb24gaXMgcGVyZm9ybWVkIGZvclxuICAgICAgICAvLyBvdGhlciBudW1lcmljIHZhbHVlcy5cbiAgICAgICAgcmV0dXJuIGEgIT0gK2EgPyBiICE9ICtiIDogKGEgPT0gMCA/IDEgLyBhID09IDEgLyBiIDogYSA9PSArYik7XG4gICAgICBjYXNlICdbb2JqZWN0IERhdGVdJzpcbiAgICAgIGNhc2UgJ1tvYmplY3QgQm9vbGVhbl0nOlxuICAgICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWVyaWMgcHJpbWl0aXZlIHZhbHVlcy4gRGF0ZXMgYXJlIGNvbXBhcmVkIGJ5IHRoZWlyXG4gICAgICAgIC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcbiAgICAgICAgLy8gb2YgYE5hTmAgYXJlIG5vdCBlcXVpdmFsZW50LlxuICAgICAgICByZXR1cm4gK2EgPT0gK2I7XG4gICAgICAvLyBSZWdFeHBzIGFyZSBjb21wYXJlZCBieSB0aGVpciBzb3VyY2UgcGF0dGVybnMgYW5kIGZsYWdzLlxuICAgICAgY2FzZSAnW29iamVjdCBSZWdFeHBdJzpcbiAgICAgICAgcmV0dXJuIGEuc291cmNlID09IGIuc291cmNlICYmXG4gICAgICAgICAgICAgICBhLmdsb2JhbCA9PSBiLmdsb2JhbCAmJlxuICAgICAgICAgICAgICAgYS5tdWx0aWxpbmUgPT0gYi5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgICAgIGEuaWdub3JlQ2FzZSA9PSBiLmlnbm9yZUNhc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYSAhPSAnb2JqZWN0JyB8fCB0eXBlb2YgYiAhPSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlO1xuICAgIC8vIEFzc3VtZSBlcXVhbGl0eSBmb3IgY3ljbGljIHN0cnVjdHVyZXMuIFRoZSBhbGdvcml0aG0gZm9yIGRldGVjdGluZyBjeWNsaWNcbiAgICAvLyBzdHJ1Y3R1cmVzIGlzIGFkYXB0ZWQgZnJvbSBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLCBhYnN0cmFjdCBvcGVyYXRpb24gYEpPYC5cbiAgICB2YXIgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIC8vIExpbmVhciBzZWFyY2guIFBlcmZvcm1hbmNlIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZlxuICAgICAgLy8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuICAgICAgaWYgKGFTdGFja1tsZW5ndGhdID09IGEpIHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PSBiO1xuICAgIH1cbiAgICAvLyBPYmplY3RzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWl2YWxlbnQsIGJ1dCBgT2JqZWN0YHNcbiAgICAvLyBmcm9tIGRpZmZlcmVudCBmcmFtZXMgYXJlLlxuICAgIHZhciBhQ3RvciA9IGEuY29uc3RydWN0b3IsIGJDdG9yID0gYi5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoYUN0b3IgIT09IGJDdG9yICYmICEoXy5pc0Z1bmN0aW9uKGFDdG9yKSAmJiAoYUN0b3IgaW5zdGFuY2VvZiBhQ3RvcikgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5pc0Z1bmN0aW9uKGJDdG9yKSAmJiAoYkN0b3IgaW5zdGFuY2VvZiBiQ3RvcikpXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiAoJ2NvbnN0cnVjdG9yJyBpbiBhICYmICdjb25zdHJ1Y3RvcicgaW4gYikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gQWRkIHRoZSBmaXJzdCBvYmplY3QgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICAgIGFTdGFjay5wdXNoKGEpO1xuICAgIGJTdGFjay5wdXNoKGIpO1xuICAgIHZhciBzaXplID0gMCwgcmVzdWx0ID0gdHJ1ZTtcbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICBpZiAoY2xhc3NOYW1lID09ICdbb2JqZWN0IEFycmF5XScpIHtcbiAgICAgIC8vIENvbXBhcmUgYXJyYXkgbGVuZ3RocyB0byBkZXRlcm1pbmUgaWYgYSBkZWVwIGNvbXBhcmlzb24gaXMgbmVjZXNzYXJ5LlxuICAgICAgc2l6ZSA9IGEubGVuZ3RoO1xuICAgICAgcmVzdWx0ID0gc2l6ZSA9PSBiLmxlbmd0aDtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgLy8gRGVlcCBjb21wYXJlIHRoZSBjb250ZW50cywgaWdub3Jpbmcgbm9uLW51bWVyaWMgcHJvcGVydGllcy5cbiAgICAgICAgd2hpbGUgKHNpemUtLSkge1xuICAgICAgICAgIGlmICghKHJlc3VsdCA9IGVxKGFbc2l6ZV0sIGJbc2l6ZV0sIGFTdGFjaywgYlN0YWNrKSkpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZXAgY29tcGFyZSBvYmplY3RzLlxuICAgICAgZm9yICh2YXIga2V5IGluIGEpIHtcbiAgICAgICAgaWYgKF8uaGFzKGEsIGtleSkpIHtcbiAgICAgICAgICAvLyBDb3VudCB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIHByb3BlcnRpZXMuXG4gICAgICAgICAgc2l6ZSsrO1xuICAgICAgICAgIC8vIERlZXAgY29tcGFyZSBlYWNoIG1lbWJlci5cbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBfLmhhcyhiLCBrZXkpICYmIGVxKGFba2V5XSwgYltrZXldLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRW5zdXJlIHRoYXQgYm90aCBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUgbnVtYmVyIG9mIHByb3BlcnRpZXMuXG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGZvciAoa2V5IGluIGIpIHtcbiAgICAgICAgICBpZiAoXy5oYXMoYiwga2V5KSAmJiAhKHNpemUtLSkpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9ICFzaXplO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBSZW1vdmUgdGhlIGZpcnN0IG9iamVjdCBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucG9wKCk7XG4gICAgYlN0YWNrLnBvcCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUGVyZm9ybSBhIGRlZXAgY29tcGFyaXNvbiB0byBjaGVjayBpZiB0d28gb2JqZWN0cyBhcmUgZXF1YWwuXG4gIF8uaXNFcXVhbCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gZXEoYSwgYiwgW10sIFtdKTtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIGFycmF5LCBzdHJpbmcsIG9yIG9iamVjdCBlbXB0eT9cbiAgLy8gQW4gXCJlbXB0eVwiIG9iamVjdCBoYXMgbm8gZW51bWVyYWJsZSBvd24tcHJvcGVydGllcy5cbiAgXy5pc0VtcHR5ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoXy5pc0FycmF5KG9iaikgfHwgXy5pc1N0cmluZyhvYmopKSByZXR1cm4gb2JqLmxlbmd0aCA9PT0gMDtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSBpZiAoXy5oYXMob2JqLCBrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhIERPTSBlbGVtZW50P1xuICBfLmlzRWxlbWVudCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiAhIShvYmogJiYgb2JqLm5vZGVUeXBlID09PSAxKTtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGFuIGFycmF5P1xuICAvLyBEZWxlZ2F0ZXMgdG8gRUNNQTUncyBuYXRpdmUgQXJyYXkuaXNBcnJheVxuICBfLmlzQXJyYXkgPSBuYXRpdmVJc0FycmF5IHx8IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT0gJ1tvYmplY3QgQXJyYXldJztcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhcmlhYmxlIGFuIG9iamVjdD9cbiAgXy5pc09iamVjdCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IE9iamVjdChvYmopO1xuICB9O1xuXG4gIC8vIEFkZCBzb21lIGlzVHlwZSBtZXRob2RzOiBpc0FyZ3VtZW50cywgaXNGdW5jdGlvbiwgaXNTdHJpbmcsIGlzTnVtYmVyLCBpc0RhdGUsIGlzUmVnRXhwLlxuICBlYWNoKFsnQXJndW1lbnRzJywgJ0Z1bmN0aW9uJywgJ1N0cmluZycsICdOdW1iZXInLCAnRGF0ZScsICdSZWdFeHAnXSwgZnVuY3Rpb24obmFtZSkge1xuICAgIF9bJ2lzJyArIG5hbWVdID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09ICdbb2JqZWN0ICcgKyBuYW1lICsgJ10nO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIERlZmluZSBhIGZhbGxiYWNrIHZlcnNpb24gb2YgdGhlIG1ldGhvZCBpbiBicm93c2VycyAoYWhlbSwgSUUpLCB3aGVyZVxuICAvLyB0aGVyZSBpc24ndCBhbnkgaW5zcGVjdGFibGUgXCJBcmd1bWVudHNcIiB0eXBlLlxuICBpZiAoIV8uaXNBcmd1bWVudHMoYXJndW1lbnRzKSkge1xuICAgIF8uaXNBcmd1bWVudHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiAhIShvYmogJiYgXy5oYXMob2JqLCAnY2FsbGVlJykpO1xuICAgIH07XG4gIH1cblxuICAvLyBPcHRpbWl6ZSBgaXNGdW5jdGlvbmAgaWYgYXBwcm9wcmlhdGUuXG4gIGlmICh0eXBlb2YgKC8uLykgIT09ICdmdW5jdGlvbicpIHtcbiAgICBfLmlzRnVuY3Rpb24gPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nO1xuICAgIH07XG4gIH1cblxuICAvLyBJcyBhIGdpdmVuIG9iamVjdCBhIGZpbml0ZSBudW1iZXI/XG4gIF8uaXNGaW5pdGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gaXNGaW5pdGUob2JqKSAmJiAhaXNOYU4ocGFyc2VGbG9hdChvYmopKTtcbiAgfTtcblxuICAvLyBJcyB0aGUgZ2l2ZW4gdmFsdWUgYE5hTmA/IChOYU4gaXMgdGhlIG9ubHkgbnVtYmVyIHdoaWNoIGRvZXMgbm90IGVxdWFsIGl0c2VsZikuXG4gIF8uaXNOYU4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gXy5pc051bWJlcihvYmopICYmIG9iaiAhPSArb2JqO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBib29sZWFuP1xuICBfLmlzQm9vbGVhbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IHRydWUgfHwgb2JqID09PSBmYWxzZSB8fCB0b1N0cmluZy5jYWxsKG9iaikgPT0gJ1tvYmplY3QgQm9vbGVhbl0nO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgZXF1YWwgdG8gbnVsbD9cbiAgXy5pc051bGwgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSBudWxsO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFyaWFibGUgdW5kZWZpbmVkP1xuICBfLmlzVW5kZWZpbmVkID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIG9iaiA9PT0gdm9pZCAwO1xuICB9O1xuXG4gIC8vIFNob3J0Y3V0IGZ1bmN0aW9uIGZvciBjaGVja2luZyBpZiBhbiBvYmplY3QgaGFzIGEgZ2l2ZW4gcHJvcGVydHkgZGlyZWN0bHlcbiAgLy8gb24gaXRzZWxmIChpbiBvdGhlciB3b3Jkcywgbm90IG9uIGEgcHJvdG90eXBlKS5cbiAgXy5oYXMgPSBmdW5jdGlvbihvYmosIGtleSkge1xuICAgIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbiAgfTtcblxuICAvLyBVdGlsaXR5IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIFJ1biBVbmRlcnNjb3JlLmpzIGluICpub0NvbmZsaWN0KiBtb2RlLCByZXR1cm5pbmcgdGhlIGBfYCB2YXJpYWJsZSB0byBpdHNcbiAgLy8gcHJldmlvdXMgb3duZXIuIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIFVuZGVyc2NvcmUgb2JqZWN0LlxuICBfLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICByb290Ll8gPSBwcmV2aW91c1VuZGVyc2NvcmU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLy8gS2VlcCB0aGUgaWRlbnRpdHkgZnVuY3Rpb24gYXJvdW5kIGZvciBkZWZhdWx0IGl0ZXJhdG9ycy5cbiAgXy5pZGVudGl0eSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xuXG4gIF8uY29uc3RhbnQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgfTtcblxuICBfLnByb3BlcnR5ID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIG9ialtrZXldO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIHByZWRpY2F0ZSBmb3IgY2hlY2tpbmcgd2hldGhlciBhbiBvYmplY3QgaGFzIGEgZ2l2ZW4gc2V0IG9mIGBrZXk6dmFsdWVgIHBhaXJzLlxuICBfLm1hdGNoZXMgPSBmdW5jdGlvbihhdHRycykge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgIGlmIChvYmogPT09IGF0dHJzKSByZXR1cm4gdHJ1ZTsgLy9hdm9pZCBjb21wYXJpbmcgYW4gb2JqZWN0IHRvIGl0c2VsZi5cbiAgICAgIGZvciAodmFyIGtleSBpbiBhdHRycykge1xuICAgICAgICBpZiAoYXR0cnNba2V5XSAhPT0gb2JqW2tleV0pXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuXG4gIC8vIFJ1biBhIGZ1bmN0aW9uICoqbioqIHRpbWVzLlxuICBfLnRpbWVzID0gZnVuY3Rpb24obiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgYWNjdW0gPSBBcnJheShNYXRoLm1heCgwLCBuKSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIGFjY3VtW2ldID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCBpKTtcbiAgICByZXR1cm4gYWNjdW07XG4gIH07XG5cbiAgLy8gUmV0dXJuIGEgcmFuZG9tIGludGVnZXIgYmV0d2VlbiBtaW4gYW5kIG1heCAoaW5jbHVzaXZlKS5cbiAgXy5yYW5kb20gPSBmdW5jdGlvbihtaW4sIG1heCkge1xuICAgIGlmIChtYXggPT0gbnVsbCkge1xuICAgICAgbWF4ID0gbWluO1xuICAgICAgbWluID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIG1pbiArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSk7XG4gIH07XG5cbiAgLy8gQSAocG9zc2libHkgZmFzdGVyKSB3YXkgdG8gZ2V0IHRoZSBjdXJyZW50IHRpbWVzdGFtcCBhcyBhbiBpbnRlZ2VyLlxuICBfLm5vdyA9IERhdGUubm93IHx8IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7IH07XG5cbiAgLy8gTGlzdCBvZiBIVE1MIGVudGl0aWVzIGZvciBlc2NhcGluZy5cbiAgdmFyIGVudGl0eU1hcCA9IHtcbiAgICBlc2NhcGU6IHtcbiAgICAgICcmJzogJyZhbXA7JyxcbiAgICAgICc8JzogJyZsdDsnLFxuICAgICAgJz4nOiAnJmd0OycsXG4gICAgICAnXCInOiAnJnF1b3Q7JyxcbiAgICAgIFwiJ1wiOiAnJiN4Mjc7J1xuICAgIH1cbiAgfTtcbiAgZW50aXR5TWFwLnVuZXNjYXBlID0gXy5pbnZlcnQoZW50aXR5TWFwLmVzY2FwZSk7XG5cbiAgLy8gUmVnZXhlcyBjb250YWluaW5nIHRoZSBrZXlzIGFuZCB2YWx1ZXMgbGlzdGVkIGltbWVkaWF0ZWx5IGFib3ZlLlxuICB2YXIgZW50aXR5UmVnZXhlcyA9IHtcbiAgICBlc2NhcGU6ICAgbmV3IFJlZ0V4cCgnWycgKyBfLmtleXMoZW50aXR5TWFwLmVzY2FwZSkuam9pbignJykgKyAnXScsICdnJyksXG4gICAgdW5lc2NhcGU6IG5ldyBSZWdFeHAoJygnICsgXy5rZXlzKGVudGl0eU1hcC51bmVzY2FwZSkuam9pbignfCcpICsgJyknLCAnZycpXG4gIH07XG5cbiAgLy8gRnVuY3Rpb25zIGZvciBlc2NhcGluZyBhbmQgdW5lc2NhcGluZyBzdHJpbmdzIHRvL2Zyb20gSFRNTCBpbnRlcnBvbGF0aW9uLlxuICBfLmVhY2goWydlc2NhcGUnLCAndW5lc2NhcGUnXSwgZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgX1ttZXRob2RdID0gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICBpZiAoc3RyaW5nID09IG51bGwpIHJldHVybiAnJztcbiAgICAgIHJldHVybiAoJycgKyBzdHJpbmcpLnJlcGxhY2UoZW50aXR5UmVnZXhlc1ttZXRob2RdLCBmdW5jdGlvbihtYXRjaCkge1xuICAgICAgICByZXR1cm4gZW50aXR5TWFwW21ldGhvZF1bbWF0Y2hdO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gSWYgdGhlIHZhbHVlIG9mIHRoZSBuYW1lZCBgcHJvcGVydHlgIGlzIGEgZnVuY3Rpb24gdGhlbiBpbnZva2UgaXQgd2l0aCB0aGVcbiAgLy8gYG9iamVjdGAgYXMgY29udGV4dDsgb3RoZXJ3aXNlLCByZXR1cm4gaXQuXG4gIF8ucmVzdWx0ID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkge1xuICAgIGlmIChvYmplY3QgPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICB2YXIgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgIHJldHVybiBfLmlzRnVuY3Rpb24odmFsdWUpID8gdmFsdWUuY2FsbChvYmplY3QpIDogdmFsdWU7XG4gIH07XG5cbiAgLy8gQWRkIHlvdXIgb3duIGN1c3RvbSBmdW5jdGlvbnMgdG8gdGhlIFVuZGVyc2NvcmUgb2JqZWN0LlxuICBfLm1peGluID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgZWFjaChfLmZ1bmN0aW9ucyhvYmopLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9IF9bbmFtZV0gPSBvYmpbbmFtZV07XG4gICAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IFt0aGlzLl93cmFwcGVkXTtcbiAgICAgICAgcHVzaC5hcHBseShhcmdzLCBhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgZnVuYy5hcHBseShfLCBhcmdzKSk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGludGVnZXIgaWQgKHVuaXF1ZSB3aXRoaW4gdGhlIGVudGlyZSBjbGllbnQgc2Vzc2lvbikuXG4gIC8vIFVzZWZ1bCBmb3IgdGVtcG9yYXJ5IERPTSBpZHMuXG4gIHZhciBpZENvdW50ZXIgPSAwO1xuICBfLnVuaXF1ZUlkID0gZnVuY3Rpb24ocHJlZml4KSB7XG4gICAgdmFyIGlkID0gKytpZENvdW50ZXIgKyAnJztcbiAgICByZXR1cm4gcHJlZml4ID8gcHJlZml4ICsgaWQgOiBpZDtcbiAgfTtcblxuICAvLyBCeSBkZWZhdWx0LCBVbmRlcnNjb3JlIHVzZXMgRVJCLXN0eWxlIHRlbXBsYXRlIGRlbGltaXRlcnMsIGNoYW5nZSB0aGVcbiAgLy8gZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZSBhbHRlcm5hdGl2ZSBkZWxpbWl0ZXJzLlxuICBfLnRlbXBsYXRlU2V0dGluZ3MgPSB7XG4gICAgZXZhbHVhdGUgICAgOiAvPCUoW1xcc1xcU10rPyklPi9nLFxuICAgIGludGVycG9sYXRlIDogLzwlPShbXFxzXFxTXSs/KSU+L2csXG4gICAgZXNjYXBlICAgICAgOiAvPCUtKFtcXHNcXFNdKz8pJT4vZ1xuICB9O1xuXG4gIC8vIFdoZW4gY3VzdG9taXppbmcgYHRlbXBsYXRlU2V0dGluZ3NgLCBpZiB5b3UgZG9uJ3Qgd2FudCB0byBkZWZpbmUgYW5cbiAgLy8gaW50ZXJwb2xhdGlvbiwgZXZhbHVhdGlvbiBvciBlc2NhcGluZyByZWdleCwgd2UgbmVlZCBvbmUgdGhhdCBpc1xuICAvLyBndWFyYW50ZWVkIG5vdCB0byBtYXRjaC5cbiAgdmFyIG5vTWF0Y2ggPSAvKC4pXi87XG5cbiAgLy8gQ2VydGFpbiBjaGFyYWN0ZXJzIG5lZWQgdG8gYmUgZXNjYXBlZCBzbyB0aGF0IHRoZXkgY2FuIGJlIHB1dCBpbnRvIGFcbiAgLy8gc3RyaW5nIGxpdGVyYWwuXG4gIHZhciBlc2NhcGVzID0ge1xuICAgIFwiJ1wiOiAgICAgIFwiJ1wiLFxuICAgICdcXFxcJzogICAgICdcXFxcJyxcbiAgICAnXFxyJzogICAgICdyJyxcbiAgICAnXFxuJzogICAgICduJyxcbiAgICAnXFx0JzogICAgICd0JyxcbiAgICAnXFx1MjAyOCc6ICd1MjAyOCcsXG4gICAgJ1xcdTIwMjknOiAndTIwMjknXG4gIH07XG5cbiAgdmFyIGVzY2FwZXIgPSAvXFxcXHwnfFxccnxcXG58XFx0fFxcdTIwMjh8XFx1MjAyOS9nO1xuXG4gIC8vIEphdmFTY3JpcHQgbWljcm8tdGVtcGxhdGluZywgc2ltaWxhciB0byBKb2huIFJlc2lnJ3MgaW1wbGVtZW50YXRpb24uXG4gIC8vIFVuZGVyc2NvcmUgdGVtcGxhdGluZyBoYW5kbGVzIGFyYml0cmFyeSBkZWxpbWl0ZXJzLCBwcmVzZXJ2ZXMgd2hpdGVzcGFjZSxcbiAgLy8gYW5kIGNvcnJlY3RseSBlc2NhcGVzIHF1b3RlcyB3aXRoaW4gaW50ZXJwb2xhdGVkIGNvZGUuXG4gIF8udGVtcGxhdGUgPSBmdW5jdGlvbih0ZXh0LCBkYXRhLCBzZXR0aW5ncykge1xuICAgIHZhciByZW5kZXI7XG4gICAgc2V0dGluZ3MgPSBfLmRlZmF1bHRzKHt9LCBzZXR0aW5ncywgXy50ZW1wbGF0ZVNldHRpbmdzKTtcblxuICAgIC8vIENvbWJpbmUgZGVsaW1pdGVycyBpbnRvIG9uZSByZWd1bGFyIGV4cHJlc3Npb24gdmlhIGFsdGVybmF0aW9uLlxuICAgIHZhciBtYXRjaGVyID0gbmV3IFJlZ0V4cChbXG4gICAgICAoc2V0dGluZ3MuZXNjYXBlIHx8IG5vTWF0Y2gpLnNvdXJjZSxcbiAgICAgIChzZXR0aW5ncy5pbnRlcnBvbGF0ZSB8fCBub01hdGNoKS5zb3VyY2UsXG4gICAgICAoc2V0dGluZ3MuZXZhbHVhdGUgfHwgbm9NYXRjaCkuc291cmNlXG4gICAgXS5qb2luKCd8JykgKyAnfCQnLCAnZycpO1xuXG4gICAgLy8gQ29tcGlsZSB0aGUgdGVtcGxhdGUgc291cmNlLCBlc2NhcGluZyBzdHJpbmcgbGl0ZXJhbHMgYXBwcm9wcmlhdGVseS5cbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBzb3VyY2UgPSBcIl9fcCs9J1wiO1xuICAgIHRleHQucmVwbGFjZShtYXRjaGVyLCBmdW5jdGlvbihtYXRjaCwgZXNjYXBlLCBpbnRlcnBvbGF0ZSwgZXZhbHVhdGUsIG9mZnNldCkge1xuICAgICAgc291cmNlICs9IHRleHQuc2xpY2UoaW5kZXgsIG9mZnNldClcbiAgICAgICAgLnJlcGxhY2UoZXNjYXBlciwgZnVuY3Rpb24obWF0Y2gpIHsgcmV0dXJuICdcXFxcJyArIGVzY2FwZXNbbWF0Y2hdOyB9KTtcblxuICAgICAgaWYgKGVzY2FwZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInK1xcbigoX190PShcIiArIGVzY2FwZSArIFwiKSk9PW51bGw/Jyc6Xy5lc2NhcGUoX190KSkrXFxuJ1wiO1xuICAgICAgfVxuICAgICAgaWYgKGludGVycG9sYXRlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIicrXFxuKChfX3Q9KFwiICsgaW50ZXJwb2xhdGUgKyBcIikpPT1udWxsPycnOl9fdCkrXFxuJ1wiO1xuICAgICAgfVxuICAgICAgaWYgKGV2YWx1YXRlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIic7XFxuXCIgKyBldmFsdWF0ZSArIFwiXFxuX19wKz0nXCI7XG4gICAgICB9XG4gICAgICBpbmRleCA9IG9mZnNldCArIG1hdGNoLmxlbmd0aDtcbiAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9KTtcbiAgICBzb3VyY2UgKz0gXCInO1xcblwiO1xuXG4gICAgLy8gSWYgYSB2YXJpYWJsZSBpcyBub3Qgc3BlY2lmaWVkLCBwbGFjZSBkYXRhIHZhbHVlcyBpbiBsb2NhbCBzY29wZS5cbiAgICBpZiAoIXNldHRpbmdzLnZhcmlhYmxlKSBzb3VyY2UgPSAnd2l0aChvYmp8fHt9KXtcXG4nICsgc291cmNlICsgJ31cXG4nO1xuXG4gICAgc291cmNlID0gXCJ2YXIgX190LF9fcD0nJyxfX2o9QXJyYXkucHJvdG90eXBlLmpvaW4sXCIgK1xuICAgICAgXCJwcmludD1mdW5jdGlvbigpe19fcCs9X19qLmNhbGwoYXJndW1lbnRzLCcnKTt9O1xcblwiICtcbiAgICAgIHNvdXJjZSArIFwicmV0dXJuIF9fcDtcXG5cIjtcblxuICAgIHRyeSB7XG4gICAgICByZW5kZXIgPSBuZXcgRnVuY3Rpb24oc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaicsICdfJywgc291cmNlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlLnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgaWYgKGRhdGEpIHJldHVybiByZW5kZXIoZGF0YSwgXyk7XG4gICAgdmFyIHRlbXBsYXRlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgcmV0dXJuIHJlbmRlci5jYWxsKHRoaXMsIGRhdGEsIF8pO1xuICAgIH07XG5cbiAgICAvLyBQcm92aWRlIHRoZSBjb21waWxlZCBmdW5jdGlvbiBzb3VyY2UgYXMgYSBjb252ZW5pZW5jZSBmb3IgcHJlY29tcGlsYXRpb24uXG4gICAgdGVtcGxhdGUuc291cmNlID0gJ2Z1bmN0aW9uKCcgKyAoc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaicpICsgJyl7XFxuJyArIHNvdXJjZSArICd9JztcblxuICAgIHJldHVybiB0ZW1wbGF0ZTtcbiAgfTtcblxuICAvLyBBZGQgYSBcImNoYWluXCIgZnVuY3Rpb24sIHdoaWNoIHdpbGwgZGVsZWdhdGUgdG8gdGhlIHdyYXBwZXIuXG4gIF8uY2hhaW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gXyhvYmopLmNoYWluKCk7XG4gIH07XG5cbiAgLy8gT09QXG4gIC8vIC0tLS0tLS0tLS0tLS0tLVxuICAvLyBJZiBVbmRlcnNjb3JlIGlzIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLCBpdCByZXR1cm5zIGEgd3JhcHBlZCBvYmplY3QgdGhhdFxuICAvLyBjYW4gYmUgdXNlZCBPTy1zdHlsZS4gVGhpcyB3cmFwcGVyIGhvbGRzIGFsdGVyZWQgdmVyc2lvbnMgb2YgYWxsIHRoZVxuICAvLyB1bmRlcnNjb3JlIGZ1bmN0aW9ucy4gV3JhcHBlZCBvYmplY3RzIG1heSBiZSBjaGFpbmVkLlxuXG4gIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjb250aW51ZSBjaGFpbmluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cy5cbiAgdmFyIHJlc3VsdCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiB0aGlzLl9jaGFpbiA/IF8ob2JqKS5jaGFpbigpIDogb2JqO1xuICB9O1xuXG4gIC8vIEFkZCBhbGwgb2YgdGhlIFVuZGVyc2NvcmUgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyIG9iamVjdC5cbiAgXy5taXhpbihfKTtcblxuICAvLyBBZGQgYWxsIG11dGF0b3IgQXJyYXkgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyLlxuICBlYWNoKFsncG9wJywgJ3B1c2gnLCAncmV2ZXJzZScsICdzaGlmdCcsICdzb3J0JywgJ3NwbGljZScsICd1bnNoaWZ0J10sIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgbWV0aG9kID0gQXJyYXlQcm90b1tuYW1lXTtcbiAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG9iaiA9IHRoaXMuX3dyYXBwZWQ7XG4gICAgICBtZXRob2QuYXBwbHkob2JqLCBhcmd1bWVudHMpO1xuICAgICAgaWYgKChuYW1lID09ICdzaGlmdCcgfHwgbmFtZSA9PSAnc3BsaWNlJykgJiYgb2JqLmxlbmd0aCA9PT0gMCkgZGVsZXRlIG9ialswXTtcbiAgICAgIHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCBvYmopO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIEFkZCBhbGwgYWNjZXNzb3IgQXJyYXkgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyLlxuICBlYWNoKFsnY29uY2F0JywgJ2pvaW4nLCAnc2xpY2UnXSwgZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvW25hbWVdO1xuICAgIF8ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgbWV0aG9kLmFwcGx5KHRoaXMuX3dyYXBwZWQsIGFyZ3VtZW50cykpO1xuICAgIH07XG4gIH0pO1xuXG4gIF8uZXh0ZW5kKF8ucHJvdG90eXBlLCB7XG5cbiAgICAvLyBTdGFydCBjaGFpbmluZyBhIHdyYXBwZWQgVW5kZXJzY29yZSBvYmplY3QuXG4gICAgY2hhaW46IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5fY2hhaW4gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8vIEV4dHJhY3RzIHRoZSByZXN1bHQgZnJvbSBhIHdyYXBwZWQgYW5kIGNoYWluZWQgb2JqZWN0LlxuICAgIHZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl93cmFwcGVkO1xuICAgIH1cblxuICB9KTtcblxuICAvLyBBTUQgcmVnaXN0cmF0aW9uIGhhcHBlbnMgYXQgdGhlIGVuZCBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIEFNRCBsb2FkZXJzXG4gIC8vIHRoYXQgbWF5IG5vdCBlbmZvcmNlIG5leHQtdHVybiBzZW1hbnRpY3Mgb24gbW9kdWxlcy4gRXZlbiB0aG91Z2ggZ2VuZXJhbFxuICAvLyBwcmFjdGljZSBmb3IgQU1EIHJlZ2lzdHJhdGlvbiBpcyB0byBiZSBhbm9ueW1vdXMsIHVuZGVyc2NvcmUgcmVnaXN0ZXJzXG4gIC8vIGFzIGEgbmFtZWQgbW9kdWxlIGJlY2F1c2UsIGxpa2UgalF1ZXJ5LCBpdCBpcyBhIGJhc2UgbGlicmFyeSB0aGF0IGlzXG4gIC8vIHBvcHVsYXIgZW5vdWdoIHRvIGJlIGJ1bmRsZWQgaW4gYSB0aGlyZCBwYXJ0eSBsaWIsIGJ1dCBub3QgYmUgcGFydCBvZlxuICAvLyBhbiBBTUQgbG9hZCByZXF1ZXN0LiBUaG9zZSBjYXNlcyBjb3VsZCBnZW5lcmF0ZSBhbiBlcnJvciB3aGVuIGFuXG4gIC8vIGFub255bW91cyBkZWZpbmUoKSBpcyBjYWxsZWQgb3V0c2lkZSBvZiBhIGxvYWRlciByZXF1ZXN0LlxuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKCd1bmRlcnNjb3JlJywgW10sIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF87XG4gICAgfSk7XG4gIH1cbn0pLmNhbGwodGhpcyk7XG4iLCIvKiEgSGFtbWVyLkpTIC0gdjEuMC43ZGV2IC0gMjAxNC0wMi0xOFxuICogaHR0cDovL2VpZ2h0bWVkaWEuZ2l0aHViLmNvbS9oYW1tZXIuanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgSm9yaWsgVGFuZ2VsZGVyIDxqLnRhbmdlbGRlckBnbWFpbC5jb20+O1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlICovXG5cbihmdW5jdGlvbih3aW5kb3csIHVuZGVmaW5lZCkge1xuICAndXNlIHN0cmljdCc7XG5cbi8qKlxuICogSGFtbWVyXG4gKiB1c2UgdGhpcyB0byBjcmVhdGUgaW5zdGFuY2VzXG4gKiBAcGFyYW0gICB7SFRNTEVsZW1lbnR9ICAgZWxlbWVudFxuICogQHBhcmFtICAge09iamVjdH0gICAgICAgIG9wdGlvbnNcbiAqIEByZXR1cm5zIHtIYW1tZXIuSW5zdGFuY2V9XG4gKiBAY29uc3RydWN0b3JcbiAqL1xudmFyIEhhbW1lciA9IGZ1bmN0aW9uKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBIYW1tZXIuSW5zdGFuY2UoZWxlbWVudCwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG4vLyBkZWZhdWx0IHNldHRpbmdzXG5IYW1tZXIuZGVmYXVsdHMgPSB7XG4gIC8vIGFkZCBzdHlsZXMgYW5kIGF0dHJpYnV0ZXMgdG8gdGhlIGVsZW1lbnQgdG8gcHJldmVudCB0aGUgYnJvd3NlciBmcm9tIGRvaW5nXG4gIC8vIGl0cyBuYXRpdmUgYmVoYXZpb3IuIHRoaXMgZG9lc250IHByZXZlbnQgdGhlIHNjcm9sbGluZywgYnV0IGNhbmNlbHNcbiAgLy8gdGhlIGNvbnRleHRtZW51LCB0YXAgaGlnaGxpZ2h0aW5nIGV0Y1xuICAvLyBzZXQgdG8gZmFsc2UgdG8gZGlzYWJsZSB0aGlzXG4gIHN0b3BfYnJvd3Nlcl9iZWhhdmlvcjoge1xuICAgIC8vIHRoaXMgYWxzbyB0cmlnZ2VycyBvbnNlbGVjdHN0YXJ0PWZhbHNlIGZvciBJRVxuICAgIHVzZXJTZWxlY3QgICAgICAgOiAnbm9uZScsXG4gICAgLy8gdGhpcyBtYWtlcyB0aGUgZWxlbWVudCBibG9ja2luZyBpbiBJRTEwID4sIHlvdSBjb3VsZCBleHBlcmltZW50IHdpdGggdGhlIHZhbHVlXG4gICAgLy8gc2VlIGZvciBtb3JlIG9wdGlvbnMgdGhpcyBpc3N1ZTsgaHR0cHM6Ly9naXRodWIuY29tL0VpZ2h0TWVkaWEvaGFtbWVyLmpzL2lzc3Vlcy8yNDFcbiAgICB0b3VjaEFjdGlvbiAgICAgIDogJ25vbmUnLFxuICAgIHRvdWNoQ2FsbG91dCAgICAgOiAnbm9uZScsXG4gICAgY29udGVudFpvb21pbmcgICA6ICdub25lJyxcbiAgICB1c2VyRHJhZyAgICAgICAgIDogJ25vbmUnLFxuICAgIHRhcEhpZ2hsaWdodENvbG9yOiAncmdiYSgwLDAsMCwwKSdcbiAgfVxuXG4gIC8vXG4gIC8vIG1vcmUgc2V0dGluZ3MgYXJlIGRlZmluZWQgcGVyIGdlc3R1cmUgYXQgZ2VzdHVyZXMuanNcbiAgLy9cbn07XG5cbi8vIGRldGVjdCB0b3VjaGV2ZW50c1xuSGFtbWVyLkhBU19QT0lOVEVSRVZFTlRTID0gd2luZG93Lm5hdmlnYXRvci5wb2ludGVyRW5hYmxlZCB8fCB3aW5kb3cubmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQ7XG5IYW1tZXIuSEFTX1RPVUNIRVZFTlRTID0gKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyk7XG5cbi8vIGRvbnQgdXNlIG1vdXNlZXZlbnRzIG9uIG1vYmlsZSBkZXZpY2VzXG5IYW1tZXIuTU9CSUxFX1JFR0VYID0gL21vYmlsZXx0YWJsZXR8aXAoYWR8aG9uZXxvZCl8YW5kcm9pZHxzaWxrL2k7XG5IYW1tZXIuTk9fTU9VU0VFVkVOVFMgPSBIYW1tZXIuSEFTX1RPVUNIRVZFTlRTICYmIHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKEhhbW1lci5NT0JJTEVfUkVHRVgpO1xuXG4vLyBldmVudHR5cGVzIHBlciB0b3VjaGV2ZW50IChzdGFydCwgbW92ZSwgZW5kKVxuLy8gYXJlIGZpbGxlZCBieSBIYW1tZXIuZXZlbnQuZGV0ZXJtaW5lRXZlbnRUeXBlcyBvbiBzZXR1cFxuSGFtbWVyLkVWRU5UX1RZUEVTID0ge307XG5cbi8vIGRpcmVjdGlvbiBkZWZpbmVzXG5IYW1tZXIuRElSRUNUSU9OX0RPV04gPSAnZG93bic7XG5IYW1tZXIuRElSRUNUSU9OX0xFRlQgPSAnbGVmdCc7XG5IYW1tZXIuRElSRUNUSU9OX1VQID0gJ3VwJztcbkhhbW1lci5ESVJFQ1RJT05fUklHSFQgPSAncmlnaHQnO1xuXG4vLyBwb2ludGVyIHR5cGVcbkhhbW1lci5QT0lOVEVSX01PVVNFID0gJ21vdXNlJztcbkhhbW1lci5QT0lOVEVSX1RPVUNIID0gJ3RvdWNoJztcbkhhbW1lci5QT0lOVEVSX1BFTiA9ICdwZW4nO1xuXG4vLyBpbnRlcnZhbCBpbiB3aGljaCBIYW1tZXIgcmVjYWxjdWxhdGVzIGN1cnJlbnQgdmVsb2NpdHkgaW4gbXNcbkhhbW1lci5VUERBVEVfVkVMT0NJVFlfSU5URVJWQUwgPSAyMDtcblxuLy8gdG91Y2ggZXZlbnQgZGVmaW5lc1xuSGFtbWVyLkVWRU5UX1NUQVJUID0gJ3N0YXJ0JztcbkhhbW1lci5FVkVOVF9NT1ZFID0gJ21vdmUnO1xuSGFtbWVyLkVWRU5UX0VORCA9ICdlbmQnO1xuXG4vLyBoYW1tZXIgZG9jdW1lbnQgd2hlcmUgdGhlIGJhc2UgZXZlbnRzIGFyZSBhZGRlZCBhdFxuSGFtbWVyLkRPQ1VNRU5UID0gd2luZG93LmRvY3VtZW50O1xuXG4vLyBwbHVnaW5zIGFuZCBnZXN0dXJlcyBuYW1lc3BhY2VzXG5IYW1tZXIucGx1Z2lucyA9IEhhbW1lci5wbHVnaW5zIHx8IHt9O1xuSGFtbWVyLmdlc3R1cmVzID0gSGFtbWVyLmdlc3R1cmVzIHx8IHt9O1xuXG5cbi8vIGlmIHRoZSB3aW5kb3cgZXZlbnRzIGFyZSBzZXQuLi5cbkhhbW1lci5SRUFEWSA9IGZhbHNlO1xuXG4vKipcbiAqIHNldHVwIGV2ZW50cyB0byBkZXRlY3QgZ2VzdHVyZXMgb24gdGhlIGRvY3VtZW50XG4gKi9cbmZ1bmN0aW9uIHNldHVwKCkge1xuICBpZihIYW1tZXIuUkVBRFkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBmaW5kIHdoYXQgZXZlbnR0eXBlcyB3ZSBhZGQgbGlzdGVuZXJzIHRvXG4gIEhhbW1lci5ldmVudC5kZXRlcm1pbmVFdmVudFR5cGVzKCk7XG5cbiAgLy8gUmVnaXN0ZXIgYWxsIGdlc3R1cmVzIGluc2lkZSBIYW1tZXIuZ2VzdHVyZXNcbiAgSGFtbWVyLnV0aWxzLmVhY2goSGFtbWVyLmdlc3R1cmVzLCBmdW5jdGlvbihnZXN0dXJlKXtcbiAgICBIYW1tZXIuZGV0ZWN0aW9uLnJlZ2lzdGVyKGdlc3R1cmUpO1xuICB9KTtcblxuICAvLyBBZGQgdG91Y2ggZXZlbnRzIG9uIHRoZSBkb2N1bWVudFxuICBIYW1tZXIuZXZlbnQub25Ub3VjaChIYW1tZXIuRE9DVU1FTlQsIEhhbW1lci5FVkVOVF9NT1ZFLCBIYW1tZXIuZGV0ZWN0aW9uLmRldGVjdCk7XG4gIEhhbW1lci5ldmVudC5vblRvdWNoKEhhbW1lci5ET0NVTUVOVCwgSGFtbWVyLkVWRU5UX0VORCwgSGFtbWVyLmRldGVjdGlvbi5kZXRlY3QpO1xuXG4gIC8vIEhhbW1lciBpcyByZWFkeS4uLiFcbiAgSGFtbWVyLlJFQURZID0gdHJ1ZTtcbn1cblxuSGFtbWVyLnV0aWxzID0ge1xuICAvKipcbiAgICogZXh0ZW5kIG1ldGhvZCxcbiAgICogYWxzbyB1c2VkIGZvciBjbG9uaW5nIHdoZW4gZGVzdCBpcyBhbiBlbXB0eSBvYmplY3RcbiAgICogQHBhcmFtICAge09iamVjdH0gICAgZGVzdFxuICAgKiBAcGFyYW0gICB7T2JqZWN0fSAgICBzcmNcbiAgICogQHBhcm0gIHtCb29sZWFufSAgbWVyZ2UgICAgZG8gYSBtZXJnZVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSAgICBkZXN0XG4gICAqL1xuICBleHRlbmQ6IGZ1bmN0aW9uIGV4dGVuZChkZXN0LCBzcmMsIG1lcmdlKSB7XG4gICAgZm9yKHZhciBrZXkgaW4gc3JjKSB7XG4gICAgICBpZihkZXN0W2tleV0gIT09IHVuZGVmaW5lZCAmJiBtZXJnZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGRlc3Rba2V5XSA9IHNyY1trZXldO1xuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBmb3IgZWFjaFxuICAgKiBAcGFyYW0gb2JqXG4gICAqIEBwYXJhbSBpdGVyYXRvclxuICAgKi9cbiAgZWFjaDogZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciBpLCBsZW5ndGg7XG4gICAgLy8gbmF0aXZlIGZvckVhY2ggb24gYXJyYXlzXG4gICAgaWYgKCdmb3JFYWNoJyBpbiBvYmopIHtcbiAgICAgIG9iai5mb3JFYWNoKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICB9XG4gICAgLy8gYXJyYXlzXG4gICAgZWxzZSBpZihvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIG9iamVjdHNcbiAgICBlbHNlIHtcbiAgICAgIGZvciAoaSBpbiBvYmopIHtcbiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSAmJiBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtpXSwgaSwgb2JqKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIGZpbmQgaWYgYSBub2RlIGlzIGluIHRoZSBnaXZlbiBwYXJlbnRcbiAgICogdXNlZCBmb3IgZXZlbnQgZGVsZWdhdGlvbiB0cmlja3NcbiAgICogQHBhcmFtICAge0hUTUxFbGVtZW50fSAgIG5vZGVcbiAgICogQHBhcmFtICAge0hUTUxFbGVtZW50fSAgIHBhcmVudFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gICAgICAgaGFzX3BhcmVudFxuICAgKi9cbiAgaGFzUGFyZW50OiBmdW5jdGlvbihub2RlLCBwYXJlbnQpIHtcbiAgICB3aGlsZShub2RlKSB7XG4gICAgICBpZihub2RlID09IHBhcmVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIGNlbnRlciBvZiBhbGwgdGhlIHRvdWNoZXNcbiAgICogQHBhcmFtICAge0FycmF5fSAgICAgdG91Y2hlc1xuICAgKiBAcmV0dXJucyB7T2JqZWN0fSAgICBjZW50ZXJcbiAgICovXG4gIGdldENlbnRlcjogZnVuY3Rpb24gZ2V0Q2VudGVyKHRvdWNoZXMpIHtcbiAgICB2YXIgdmFsdWVzWCA9IFtdLCB2YWx1ZXNZID0gW107XG5cbiAgICBIYW1tZXIudXRpbHMuZWFjaCh0b3VjaGVzLCBmdW5jdGlvbih0b3VjaCkge1xuICAgICAgLy8gSSBwcmVmZXIgY2xpZW50WCBiZWNhdXNlIGl0IGlnbm9yZSB0aGUgc2Nyb2xsaW5nIHBvc2l0aW9uXG4gICAgICB2YWx1ZXNYLnB1c2godHlwZW9mIHRvdWNoLmNsaWVudFggIT09ICd1bmRlZmluZWQnID8gdG91Y2guY2xpZW50WCA6IHRvdWNoLnBhZ2VYICk7XG4gICAgICB2YWx1ZXNZLnB1c2godHlwZW9mIHRvdWNoLmNsaWVudFkgIT09ICd1bmRlZmluZWQnID8gdG91Y2guY2xpZW50WSA6IHRvdWNoLnBhZ2VZICk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGFnZVg6ICgoTWF0aC5taW4uYXBwbHkoTWF0aCwgdmFsdWVzWCkgKyBNYXRoLm1heC5hcHBseShNYXRoLCB2YWx1ZXNYKSkgLyAyKSxcbiAgICAgIHBhZ2VZOiAoKE1hdGgubWluLmFwcGx5KE1hdGgsIHZhbHVlc1kpICsgTWF0aC5tYXguYXBwbHkoTWF0aCwgdmFsdWVzWSkpIC8gMilcbiAgICB9O1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB0aGUgdmVsb2NpdHkgYmV0d2VlbiB0d28gcG9pbnRzXG4gICAqIEBwYXJhbSAgIHtOdW1iZXJ9ICAgIGRlbHRhX3RpbWVcbiAgICogQHBhcmFtICAge051bWJlcn0gICAgZGVsdGFfeFxuICAgKiBAcGFyYW0gICB7TnVtYmVyfSAgICBkZWx0YV95XG4gICAqIEByZXR1cm5zIHtPYmplY3R9ICAgIHZlbG9jaXR5XG4gICAqL1xuICBnZXRWZWxvY2l0eTogZnVuY3Rpb24gZ2V0VmVsb2NpdHkoZGVsdGFfdGltZSwgZGVsdGFfeCwgZGVsdGFfeSkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiBNYXRoLmFicyhkZWx0YV94IC8gZGVsdGFfdGltZSkgfHwgMCxcbiAgICAgIHk6IE1hdGguYWJzKGRlbHRhX3kgLyBkZWx0YV90aW1lKSB8fCAwXG4gICAgfTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIGFuZ2xlIGJldHdlZW4gdHdvIGNvb3JkaW5hdGVzXG4gICAqIEBwYXJhbSAgIHtUb3VjaH0gICAgIHRvdWNoMVxuICAgKiBAcGFyYW0gICB7VG91Y2h9ICAgICB0b3VjaDJcbiAgICogQHJldHVybnMge051bWJlcn0gICAgYW5nbGVcbiAgICovXG4gIGdldEFuZ2xlOiBmdW5jdGlvbiBnZXRBbmdsZSh0b3VjaDEsIHRvdWNoMikge1xuICAgIHZhciB5ID0gdG91Y2gyLnBhZ2VZIC0gdG91Y2gxLnBhZ2VZLFxuICAgICAgeCA9IHRvdWNoMi5wYWdlWCAtIHRvdWNoMS5wYWdlWDtcbiAgICByZXR1cm4gTWF0aC5hdGFuMih5LCB4KSAqIDE4MCAvIE1hdGguUEk7XG4gIH0sXG5cblxuICAvKipcbiAgICogYW5nbGUgdG8gZGlyZWN0aW9uIGRlZmluZVxuICAgKiBAcGFyYW0gICB7VG91Y2h9ICAgICB0b3VjaDFcbiAgICogQHBhcmFtICAge1RvdWNofSAgICAgdG91Y2gyXG4gICAqIEByZXR1cm5zIHtTdHJpbmd9ICAgIGRpcmVjdGlvbiBjb25zdGFudCwgbGlrZSBIYW1tZXIuRElSRUNUSU9OX0xFRlRcbiAgICovXG4gIGdldERpcmVjdGlvbjogZnVuY3Rpb24gZ2V0RGlyZWN0aW9uKHRvdWNoMSwgdG91Y2gyKSB7XG4gICAgdmFyIHggPSBNYXRoLmFicyh0b3VjaDEucGFnZVggLSB0b3VjaDIucGFnZVgpLFxuICAgICAgeSA9IE1hdGguYWJzKHRvdWNoMS5wYWdlWSAtIHRvdWNoMi5wYWdlWSk7XG5cbiAgICBpZih4ID49IHkpIHtcbiAgICAgIHJldHVybiB0b3VjaDEucGFnZVggLSB0b3VjaDIucGFnZVggPiAwID8gSGFtbWVyLkRJUkVDVElPTl9MRUZUIDogSGFtbWVyLkRJUkVDVElPTl9SSUdIVDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4gdG91Y2gxLnBhZ2VZIC0gdG91Y2gyLnBhZ2VZID4gMCA/IEhhbW1lci5ESVJFQ1RJT05fVVAgOiBIYW1tZXIuRElSRUNUSU9OX0RPV047XG4gICAgfVxuICB9LFxuXG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28gdG91Y2hlc1xuICAgKiBAcGFyYW0gICB7VG91Y2h9ICAgICB0b3VjaDFcbiAgICogQHBhcmFtICAge1RvdWNofSAgICAgdG91Y2gyXG4gICAqIEByZXR1cm5zIHtOdW1iZXJ9ICAgIGRpc3RhbmNlXG4gICAqL1xuICBnZXREaXN0YW5jZTogZnVuY3Rpb24gZ2V0RGlzdGFuY2UodG91Y2gxLCB0b3VjaDIpIHtcbiAgICB2YXIgeCA9IHRvdWNoMi5wYWdlWCAtIHRvdWNoMS5wYWdlWCxcbiAgICAgIHkgPSB0b3VjaDIucGFnZVkgLSB0b3VjaDEucGFnZVk7XG4gICAgcmV0dXJuIE1hdGguc3FydCgoeCAqIHgpICsgKHkgKiB5KSk7XG4gIH0sXG5cblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzY2FsZSBmYWN0b3IgYmV0d2VlbiB0d28gdG91Y2hMaXN0cyAoZmluZ2VycylcbiAgICogbm8gc2NhbGUgaXMgMSwgYW5kIGdvZXMgZG93biB0byAwIHdoZW4gcGluY2hlZCB0b2dldGhlciwgYW5kIGJpZ2dlciB3aGVuIHBpbmNoZWQgb3V0XG4gICAqIEBwYXJhbSAgIHtBcnJheX0gICAgIHN0YXJ0XG4gICAqIEBwYXJhbSAgIHtBcnJheX0gICAgIGVuZFxuICAgKiBAcmV0dXJucyB7TnVtYmVyfSAgICBzY2FsZVxuICAgKi9cbiAgZ2V0U2NhbGU6IGZ1bmN0aW9uIGdldFNjYWxlKHN0YXJ0LCBlbmQpIHtcbiAgICAvLyBuZWVkIHR3byBmaW5nZXJzLi4uXG4gICAgaWYoc3RhcnQubGVuZ3RoID49IDIgJiYgZW5kLmxlbmd0aCA+PSAyKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXREaXN0YW5jZShlbmRbMF0sIGVuZFsxXSkgL1xuICAgICAgICB0aGlzLmdldERpc3RhbmNlKHN0YXJ0WzBdLCBzdGFydFsxXSk7XG4gICAgfVxuICAgIHJldHVybiAxO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB0aGUgcm90YXRpb24gZGVncmVlcyBiZXR3ZWVuIHR3byB0b3VjaExpc3RzIChmaW5nZXJzKVxuICAgKiBAcGFyYW0gICB7QXJyYXl9ICAgICBzdGFydFxuICAgKiBAcGFyYW0gICB7QXJyYXl9ICAgICBlbmRcbiAgICogQHJldHVybnMge051bWJlcn0gICAgcm90YXRpb25cbiAgICovXG4gIGdldFJvdGF0aW9uOiBmdW5jdGlvbiBnZXRSb3RhdGlvbihzdGFydCwgZW5kKSB7XG4gICAgLy8gbmVlZCB0d28gZmluZ2Vyc1xuICAgIGlmKHN0YXJ0Lmxlbmd0aCA+PSAyICYmIGVuZC5sZW5ndGggPj0gMikge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0QW5nbGUoZW5kWzFdLCBlbmRbMF0pIC1cbiAgICAgICAgdGhpcy5nZXRBbmdsZShzdGFydFsxXSwgc3RhcnRbMF0pO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBib29sZWFuIGlmIHRoZSBkaXJlY3Rpb24gaXMgdmVydGljYWxcbiAgICogQHBhcmFtICAgIHtTdHJpbmd9ICAgIGRpcmVjdGlvblxuICAgKiBAcmV0dXJucyAge0Jvb2xlYW59ICAgaXNfdmVydGljYWxcbiAgICovXG4gIGlzVmVydGljYWw6IGZ1bmN0aW9uIGlzVmVydGljYWwoZGlyZWN0aW9uKSB7XG4gICAgcmV0dXJuIChkaXJlY3Rpb24gPT0gSGFtbWVyLkRJUkVDVElPTl9VUCB8fCBkaXJlY3Rpb24gPT0gSGFtbWVyLkRJUkVDVElPTl9ET1dOKTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBzdG9wIGJyb3dzZXIgZGVmYXVsdCBiZWhhdmlvciB3aXRoIGNzcyBwcm9wc1xuICAgKiBAcGFyYW0gICB7SHRtbEVsZW1lbnR9ICAgZWxlbWVudFxuICAgKiBAcGFyYW0gICB7T2JqZWN0fSAgICAgICAgY3NzX3Byb3BzXG4gICAqL1xuICBzdG9wRGVmYXVsdEJyb3dzZXJCZWhhdmlvcjogZnVuY3Rpb24gc3RvcERlZmF1bHRCcm93c2VyQmVoYXZpb3IoZWxlbWVudCwgY3NzX3Byb3BzKSB7XG4gICAgaWYoIWNzc19wcm9wcyB8fCAhZWxlbWVudCB8fCAhZWxlbWVudC5zdHlsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHdpdGggY3NzIHByb3BlcnRpZXMgZm9yIG1vZGVybiBicm93c2Vyc1xuICAgIEhhbW1lci51dGlscy5lYWNoKFsnd2Via2l0JywgJ2todG1sJywgJ21veicsICdNb3onLCAnbXMnLCAnbycsICcnXSwgZnVuY3Rpb24odmVuZG9yKSB7XG4gICAgICBIYW1tZXIudXRpbHMuZWFjaChjc3NfcHJvcHMsIGZ1bmN0aW9uKHZhbHVlLCBwcm9wKSB7XG4gICAgICAgICAgLy8gdmVuZGVyIHByZWZpeCBhdCB0aGUgcHJvcGVydHlcbiAgICAgICAgICBpZih2ZW5kb3IpIHtcbiAgICAgICAgICAgIHByb3AgPSB2ZW5kb3IgKyBwcm9wLnN1YnN0cmluZygwLCAxKS50b1VwcGVyQ2FzZSgpICsgcHJvcC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHNldCB0aGUgc3R5bGVcbiAgICAgICAgICBpZihwcm9wIGluIGVsZW1lbnQuc3R5bGUpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbcHJvcF0gPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIGFsc28gdGhlIGRpc2FibGUgb25zZWxlY3RzdGFydFxuICAgIGlmKGNzc19wcm9wcy51c2VyU2VsZWN0ID09ICdub25lJykge1xuICAgICAgZWxlbWVudC5vbnNlbGVjdHN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gYW5kIGRpc2FibGUgb25kcmFnc3RhcnRcbiAgICBpZihjc3NfcHJvcHMudXNlckRyYWcgPT0gJ25vbmUnKSB7XG4gICAgICBlbGVtZW50Lm9uZHJhZ3N0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH07XG4gICAgfVxuICB9LFxuXG5cbiAgLyoqXG4gICAqIHJldmVydHMgYWxsIGNoYW5nZXMgbWFkZSBieSAnc3RvcERlZmF1bHRCcm93c2VyQmVoYXZpb3InXG4gICAqIEBwYXJhbSAgIHtIdG1sRWxlbWVudH0gICBlbGVtZW50XG4gICAqIEBwYXJhbSAgIHtPYmplY3R9ICAgICAgICBjc3NfcHJvcHNcbiAgICovXG4gIHN0YXJ0RGVmYXVsdEJyb3dzZXJCZWhhdmlvcjogZnVuY3Rpb24gc3RhcnREZWZhdWx0QnJvd3NlckJlaGF2aW9yKGVsZW1lbnQsIGNzc19wcm9wcykge1xuICAgIGlmKCFjc3NfcHJvcHMgfHwgIWVsZW1lbnQgfHwgIWVsZW1lbnQuc3R5bGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB3aXRoIGNzcyBwcm9wZXJ0aWVzIGZvciBtb2Rlcm4gYnJvd3NlcnNcbiAgICBIYW1tZXIudXRpbHMuZWFjaChbJ3dlYmtpdCcsICdraHRtbCcsICdtb3onLCAnTW96JywgJ21zJywgJ28nLCAnJ10sIGZ1bmN0aW9uKHZlbmRvcikge1xuICAgICAgSGFtbWVyLnV0aWxzLmVhY2goY3NzX3Byb3BzLCBmdW5jdGlvbih2YWx1ZSwgcHJvcCkge1xuICAgICAgICAgIC8vIHZlbmRlciBwcmVmaXggYXQgdGhlIHByb3BlcnR5XG4gICAgICAgICAgaWYodmVuZG9yKSB7XG4gICAgICAgICAgICBwcm9wID0gdmVuZG9yICsgcHJvcC5zdWJzdHJpbmcoMCwgMSkudG9VcHBlckNhc2UoKSArIHByb3Auc3Vic3RyaW5nKDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyByZXNldCB0aGUgc3R5bGVcbiAgICAgICAgICBpZihwcm9wIGluIGVsZW1lbnQuc3R5bGUpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbcHJvcF0gPSAnJztcbiAgICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIGFsc28gdGhlIGVuYWJsZSBvbnNlbGVjdHN0YXJ0XG4gICAgaWYoY3NzX3Byb3BzLnVzZXJTZWxlY3QgPT0gJ25vbmUnKSB7XG4gICAgICBlbGVtZW50Lm9uc2VsZWN0c3RhcnQgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIGFuZCBlbmFibGUgb25kcmFnc3RhcnRcbiAgICBpZihjc3NfcHJvcHMudXNlckRyYWcgPT0gJ25vbmUnKSB7XG4gICAgICBlbGVtZW50Lm9uZHJhZ3N0YXJ0ID0gbnVsbDtcbiAgICB9XG4gIH1cbn07XG5cblxuLyoqXG4gKiBjcmVhdGUgbmV3IGhhbW1lciBpbnN0YW5jZVxuICogYWxsIG1ldGhvZHMgc2hvdWxkIHJldHVybiB0aGUgaW5zdGFuY2UgaXRzZWxmLCBzbyBpdCBpcyBjaGFpbmFibGUuXG4gKiBAcGFyYW0gICB7SFRNTEVsZW1lbnR9ICAgICAgIGVsZW1lbnRcbiAqIEBwYXJhbSAgIHtPYmplY3R9ICAgICAgICAgICAgW29wdGlvbnM9e31dXG4gKiBAcmV0dXJucyB7SGFtbWVyLkluc3RhbmNlfVxuICogQGNvbnN0cnVjdG9yXG4gKi9cbkhhbW1lci5JbnN0YW5jZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIHNldHVwIEhhbW1lckpTIHdpbmRvdyBldmVudHMgYW5kIHJlZ2lzdGVyIGFsbCBnZXN0dXJlc1xuICAvLyB0aGlzIGFsc28gc2V0cyB1cCB0aGUgZGVmYXVsdCBvcHRpb25zXG4gIHNldHVwKCk7XG5cbiAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAvLyBzdGFydC9zdG9wIGRldGVjdGlvbiBvcHRpb25cbiAgdGhpcy5lbmFibGVkID0gdHJ1ZTtcblxuICAvLyBtZXJnZSBvcHRpb25zXG4gIHRoaXMub3B0aW9ucyA9IEhhbW1lci51dGlscy5leHRlbmQoXG4gICAgSGFtbWVyLnV0aWxzLmV4dGVuZCh7fSwgSGFtbWVyLmRlZmF1bHRzKSxcbiAgICBvcHRpb25zIHx8IHt9KTtcblxuICAvLyBhZGQgc29tZSBjc3MgdG8gdGhlIGVsZW1lbnQgdG8gcHJldmVudCB0aGUgYnJvd3NlciBmcm9tIGRvaW5nIGl0cyBuYXRpdmUgYmVoYXZvaXJcbiAgaWYodGhpcy5vcHRpb25zLnN0b3BfYnJvd3Nlcl9iZWhhdmlvcikge1xuICAgIEhhbW1lci51dGlscy5zdG9wRGVmYXVsdEJyb3dzZXJCZWhhdmlvcih0aGlzLmVsZW1lbnQsIHRoaXMub3B0aW9ucy5zdG9wX2Jyb3dzZXJfYmVoYXZpb3IpO1xuICB9XG5cbiAgLy8gc3RhcnQgZGV0ZWN0aW9uIG9uIHRvdWNoc3RhcnRcbiAgdGhpcy5fZXZlbnRTdGFydEhhbmRsZXIgPSBIYW1tZXIuZXZlbnQub25Ub3VjaChlbGVtZW50LCBIYW1tZXIuRVZFTlRfU1RBUlQsIGZ1bmN0aW9uKGV2KSB7XG4gICAgaWYoc2VsZi5lbmFibGVkKSB7XG4gICAgICBIYW1tZXIuZGV0ZWN0aW9uLnN0YXJ0RGV0ZWN0KHNlbGYsIGV2KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGtlZXAgYSBsaXN0IG9mIHVzZXIgZXZlbnQgaGFuZGxlcnMgd2hpY2ggbmVlZHMgdG8gYmUgcmVtb3ZlZCB3aGVuIGNhbGxpbmcgJ2Rpc3Bvc2UnXG4gIHRoaXMuX2V2ZW50SGFuZGxlciA9IFtdO1xuXG4gIC8vIHJldHVybiBpbnN0YW5jZVxuICByZXR1cm4gdGhpcztcbn07XG5cblxuSGFtbWVyLkluc3RhbmNlLnByb3RvdHlwZSA9IHtcbiAgLyoqXG4gICAqIGJpbmQgZXZlbnRzIHRvIHRoZSBpbnN0YW5jZVxuICAgKiBAcGFyYW0gICB7U3RyaW5nfSAgICAgIGdlc3R1cmVcbiAgICogQHBhcmFtICAge0Z1bmN0aW9ufSAgICBoYW5kbGVyXG4gICAqIEByZXR1cm5zIHtIYW1tZXIuSW5zdGFuY2V9XG4gICAqL1xuICBvbjogZnVuY3Rpb24gb25FdmVudChnZXN0dXJlLCBoYW5kbGVyKSB7XG4gICAgdmFyIGdlc3R1cmVzID0gZ2VzdHVyZS5zcGxpdCgnICcpO1xuICAgIEhhbW1lci51dGlscy5lYWNoKGdlc3R1cmVzLCBmdW5jdGlvbihnZXN0dXJlKSB7XG4gICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihnZXN0dXJlLCBoYW5kbGVyLCBmYWxzZSk7XG4gICAgICB0aGlzLl9ldmVudEhhbmRsZXIucHVzaCh7IGdlc3R1cmU6IGdlc3R1cmUsIGhhbmRsZXI6IGhhbmRsZXIgfSk7XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cblxuICAvKipcbiAgICogdW5iaW5kIGV2ZW50cyB0byB0aGUgaW5zdGFuY2VcbiAgICogQHBhcmFtICAge1N0cmluZ30gICAgICBnZXN0dXJlXG4gICAqIEBwYXJhbSAgIHtGdW5jdGlvbn0gICAgaGFuZGxlclxuICAgKiBAcmV0dXJucyB7SGFtbWVyLkluc3RhbmNlfVxuICAgKi9cbiAgb2ZmOiBmdW5jdGlvbiBvZmZFdmVudChnZXN0dXJlLCBoYW5kbGVyKSB7XG4gICAgdmFyIGdlc3R1cmVzID0gZ2VzdHVyZS5zcGxpdCgnICcpO1xuICAgIEhhbW1lci51dGlscy5lYWNoKGdlc3R1cmVzLCBmdW5jdGlvbihnZXN0dXJlKSB7XG4gICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihnZXN0dXJlLCBoYW5kbGVyLCBmYWxzZSk7XG5cbiAgICAgIC8vIHJlbW92ZSB0aGUgZXZlbnQgaGFuZGxlciBmcm9tIHRoZSBpbnRlcm5hbCBsaXN0XG4gICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgIEhhbW1lci51dGlscy5lYWNoKHRoaXMuX2V2ZW50SGFuZGxlciwgZnVuY3Rpb24oZXZlbnRIYW5kbGVyLCBpKSB7XG4gICAgICAgIGlmIChpbmRleCA9PT0gLTEgJiYgZXZlbnRIYW5kbGVyLmdlc3R1cmUgPT09IGdlc3R1cmUgJiYgZXZlbnRIYW5kbGVyLmhhbmRsZXIgPT09IGhhbmRsZXIpIHtcbiAgICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMpO1xuXG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICB0aGlzLl9ldmVudEhhbmRsZXIuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyIGdlc3R1cmUgZXZlbnRcbiAgICogQHBhcmFtICAge1N0cmluZ30gICAgICBnZXN0dXJlXG4gICAqIEBwYXJhbSAgIHtPYmplY3R9ICAgICAgW2V2ZW50RGF0YV1cbiAgICogQHJldHVybnMge0hhbW1lci5JbnN0YW5jZX1cbiAgICovXG4gIHRyaWdnZXI6IGZ1bmN0aW9uIHRyaWdnZXJFdmVudChnZXN0dXJlLCBldmVudERhdGEpIHtcbiAgICAvLyBvcHRpb25hbFxuICAgIGlmKCFldmVudERhdGEpIHtcbiAgICAgIGV2ZW50RGF0YSA9IHt9O1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSBET00gZXZlbnRcbiAgICB2YXIgZXZlbnQgPSBIYW1tZXIuRE9DVU1FTlQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgZXZlbnQuaW5pdEV2ZW50KGdlc3R1cmUsIHRydWUsIHRydWUpO1xuICAgIGV2ZW50Lmdlc3R1cmUgPSBldmVudERhdGE7XG5cbiAgICAvLyB0cmlnZ2VyIG9uIHRoZSB0YXJnZXQgaWYgaXQgaXMgaW4gdGhlIGluc3RhbmNlIGVsZW1lbnQsXG4gICAgLy8gdGhpcyBpcyBmb3IgZXZlbnQgZGVsZWdhdGlvbiB0cmlja3NcbiAgICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcbiAgICBpZihIYW1tZXIudXRpbHMuaGFzUGFyZW50KGV2ZW50RGF0YS50YXJnZXQsIGVsZW1lbnQpKSB7XG4gICAgICBlbGVtZW50ID0gZXZlbnREYXRhLnRhcmdldDtcbiAgICB9XG5cbiAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGVuYWJsZSBvZiBkaXNhYmxlIGhhbW1lci5qcyBkZXRlY3Rpb25cbiAgICogQHBhcmFtICAge0Jvb2xlYW59ICAgc3RhdGVcbiAgICogQHJldHVybnMge0hhbW1lci5JbnN0YW5jZX1cbiAgICovXG4gIGVuYWJsZTogZnVuY3Rpb24gZW5hYmxlKHN0YXRlKSB7XG4gICAgdGhpcy5lbmFibGVkID0gc3RhdGU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cblxuICAvKipcbiAgICogZGlzcG9zZSB0aGlzIGhhbW1lciBpbnN0YW5jZVxuICAgKiBAcmV0dXJucyB7SGFtbWVyLkluc3RhbmNlfVxuICAgKi9cbiAgZGlzcG9zZTogZnVuY3Rpb24gZGlzcG9zZSgpIHtcblxuICAgIC8vIHVuZG8gYWxsIGNoYW5nZXMgbWFkZSBieSBzdG9wX2Jyb3dzZXJfYmVoYXZpb3JcbiAgICBpZih0aGlzLm9wdGlvbnMuc3RvcF9icm93c2VyX2JlaGF2aW9yKSB7XG4gICAgICBIYW1tZXIudXRpbHMuc3RhcnREZWZhdWx0QnJvd3NlckJlaGF2aW9yKHRoaXMuZWxlbWVudCwgdGhpcy5vcHRpb25zLnN0b3BfYnJvd3Nlcl9iZWhhdmlvcik7XG4gICAgfVxuXG4gICAgLy8gdW5iaW5kIGFsbCBjdXN0b20gZXZlbnQgaGFuZGxlcnNcbiAgICBIYW1tZXIudXRpbHMuZWFjaCh0aGlzLl9ldmVudEhhbmRsZXIsIGZ1bmN0aW9uKGV2ZW50SGFuZGxlcikge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnRIYW5kbGVyLmdlc3R1cmUsIGV2ZW50SGFuZGxlci5oYW5kbGVyLCBmYWxzZSk7XG4gICAgfSwgdGhpcyk7XG4gICAgdGhpcy5fZXZlbnRIYW5kbGVyLmxlbmd0aCA9IDA7XG5cbiAgICAvLyB1bmJpbmQgdGhlIHN0YXJ0IGV2ZW50IGxpc3RlbmVyXG4gICAgSGFtbWVyLmV2ZW50LnVuYmluZERvbSh0aGlzLmVsZW1lbnQsIEhhbW1lci5FVkVOVF9UWVBFU1tIYW1tZXIuRVZFTlRfU1RBUlRdLCB0aGlzLl9ldmVudFN0YXJ0SGFuZGxlcik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn07XG5cblxuLyoqXG4gKiB0aGlzIGhvbGRzIHRoZSBsYXN0IG1vdmUgZXZlbnQsXG4gKiB1c2VkIHRvIGZpeCBlbXB0eSB0b3VjaGVuZCBpc3N1ZVxuICogc2VlIHRoZSBvblRvdWNoIGV2ZW50IGZvciBhbiBleHBsYW5hdGlvblxuICogQHR5cGUge09iamVjdH1cbiAqL1xudmFyIGxhc3RfbW92ZV9ldmVudCA9IG51bGw7XG5cblxuLyoqXG4gKiB3aGVuIHRoZSBtb3VzZSBpcyBob2xkIGRvd24sIHRoaXMgaXMgdHJ1ZVxuICogQHR5cGUge0Jvb2xlYW59XG4gKi9cbnZhciBlbmFibGVfZGV0ZWN0ID0gZmFsc2U7XG5cblxuLyoqXG4gKiB3aGVuIHRvdWNoIGV2ZW50cyBoYXZlIGJlZW4gZmlyZWQsIHRoaXMgaXMgdHJ1ZVxuICogQHR5cGUge0Jvb2xlYW59XG4gKi9cbnZhciB0b3VjaF90cmlnZ2VyZWQgPSBmYWxzZTtcblxuXG5IYW1tZXIuZXZlbnQgPSB7XG4gIC8qKlxuICAgKiBzaW1wbGUgYWRkRXZlbnRMaXN0ZW5lclxuICAgKiBAcGFyYW0gICB7SFRNTEVsZW1lbnR9ICAgZWxlbWVudFxuICAgKiBAcGFyYW0gICB7U3RyaW5nfSAgICAgICAgdHlwZVxuICAgKiBAcGFyYW0gICB7RnVuY3Rpb259ICAgICAgaGFuZGxlclxuICAgKi9cbiAgYmluZERvbTogZnVuY3Rpb24oZWxlbWVudCwgdHlwZSwgaGFuZGxlcikge1xuICAgIHZhciB0eXBlcyA9IHR5cGUuc3BsaXQoJyAnKTtcbiAgICBIYW1tZXIudXRpbHMuZWFjaCh0eXBlcywgZnVuY3Rpb24odHlwZSl7XG4gICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlciwgZmFsc2UpO1xuICAgIH0pO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIHNpbXBsZSByZW1vdmVFdmVudExpc3RlbmVyXG4gICAqIEBwYXJhbSAgIHtIVE1MRWxlbWVudH0gICBlbGVtZW50XG4gICAqIEBwYXJhbSAgIHtTdHJpbmd9ICAgICAgICB0eXBlXG4gICAqIEBwYXJhbSAgIHtGdW5jdGlvbn0gICAgICBoYW5kbGVyXG4gICAqL1xuICB1bmJpbmREb206IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIpIHtcbiAgICB2YXIgdHlwZXMgPSB0eXBlLnNwbGl0KCcgJyk7XG4gICAgSGFtbWVyLnV0aWxzLmVhY2godHlwZXMsIGZ1bmN0aW9uKHR5cGUpe1xuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgICB9KTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiB0b3VjaCBldmVudHMgd2l0aCBtb3VzZSBmYWxsYmFja1xuICAgKiBAcGFyYW0gICB7SFRNTEVsZW1lbnR9ICAgZWxlbWVudFxuICAgKiBAcGFyYW0gICB7U3RyaW5nfSAgICAgICAgZXZlbnRUeXBlICAgICAgICBsaWtlIEhhbW1lci5FVkVOVF9NT1ZFXG4gICAqIEBwYXJhbSAgIHtGdW5jdGlvbn0gICAgICBoYW5kbGVyXG4gICAqL1xuICBvblRvdWNoOiBmdW5jdGlvbiBvblRvdWNoKGVsZW1lbnQsIGV2ZW50VHlwZSwgaGFuZGxlcikge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBmbiA9IGZ1bmN0aW9uIGJpbmREb21PblRvdWNoKGV2KSB7XG4gICAgICB2YXIgc291cmNlRXZlbnRUeXBlID0gZXYudHlwZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAvLyBvbm1vdXNldXAsIGJ1dCB3aGVuIHRvdWNoZW5kIGhhcyBiZWVuIGZpcmVkIHdlIGRvIG5vdGhpbmcuXG4gICAgICAvLyB0aGlzIGlzIGZvciB0b3VjaGRldmljZXMgd2hpY2ggYWxzbyBmaXJlIGEgbW91c2V1cCBvbiB0b3VjaGVuZFxuICAgICAgaWYoc291cmNlRXZlbnRUeXBlLm1hdGNoKC9tb3VzZS8pICYmIHRvdWNoX3RyaWdnZXJlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG1vdXNlYnV0dG9uIG11c3QgYmUgZG93biBvciBhIHRvdWNoIGV2ZW50XG4gICAgICBlbHNlIGlmKHNvdXJjZUV2ZW50VHlwZS5tYXRjaCgvdG91Y2gvKSB8fCAgIC8vIHRvdWNoIGV2ZW50cyBhcmUgYWx3YXlzIG9uIHNjcmVlblxuICAgICAgICBzb3VyY2VFdmVudFR5cGUubWF0Y2goL3BvaW50ZXJkb3duLykgfHwgLy8gcG9pbnRlcmV2ZW50cyB0b3VjaFxuICAgICAgICAoc291cmNlRXZlbnRUeXBlLm1hdGNoKC9tb3VzZS8pICYmIGV2LndoaWNoID09PSAxKSAgIC8vIG1vdXNlIGlzIHByZXNzZWRcbiAgICAgICAgKSB7XG4gICAgICAgIGVuYWJsZV9kZXRlY3QgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBtb3VzZSBpc24ndCBwcmVzc2VkXG4gICAgICBlbHNlIGlmKHNvdXJjZUV2ZW50VHlwZS5tYXRjaCgvbW91c2UvKSAmJiAhZXYud2hpY2gpIHtcbiAgICAgICAgZW5hYmxlX2RldGVjdCA9IGZhbHNlO1xuICAgICAgfVxuXG5cbiAgICAgIC8vIHdlIGFyZSBpbiBhIHRvdWNoIGV2ZW50LCBzZXQgdGhlIHRvdWNoIHRyaWdnZXJlZCBib29sIHRvIHRydWUsXG4gICAgICAvLyB0aGlzIGZvciB0aGUgY29uZmxpY3RzIHRoYXQgbWF5IG9jY3VyIG9uIGlvcyBhbmQgYW5kcm9pZFxuICAgICAgaWYoc291cmNlRXZlbnRUeXBlLm1hdGNoKC90b3VjaHxwb2ludGVyLykpIHtcbiAgICAgICAgdG91Y2hfdHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gY291bnQgdGhlIHRvdGFsIHRvdWNoZXMgb24gdGhlIHNjcmVlblxuICAgICAgdmFyIGNvdW50X3RvdWNoZXMgPSAwO1xuXG4gICAgICAvLyB3aGVuIHRvdWNoIGhhcyBiZWVuIHRyaWdnZXJlZCBpbiB0aGlzIGRldGVjdGlvbiBzZXNzaW9uXG4gICAgICAvLyBhbmQgd2UgYXJlIG5vdyBoYW5kbGluZyBhIG1vdXNlIGV2ZW50LCB3ZSBzdG9wIHRoYXQgdG8gcHJldmVudCBjb25mbGljdHNcbiAgICAgIGlmKGVuYWJsZV9kZXRlY3QpIHtcbiAgICAgICAgLy8gdXBkYXRlIHBvaW50ZXJldmVudFxuICAgICAgICBpZihIYW1tZXIuSEFTX1BPSU5URVJFVkVOVFMgJiYgZXZlbnRUeXBlICE9IEhhbW1lci5FVkVOVF9FTkQpIHtcbiAgICAgICAgICBjb3VudF90b3VjaGVzID0gSGFtbWVyLlBvaW50ZXJFdmVudC51cGRhdGVQb2ludGVyKGV2ZW50VHlwZSwgZXYpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRvdWNoXG4gICAgICAgIGVsc2UgaWYoc291cmNlRXZlbnRUeXBlLm1hdGNoKC90b3VjaC8pKSB7XG4gICAgICAgICAgY291bnRfdG91Y2hlcyA9IGV2LnRvdWNoZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIC8vIG1vdXNlXG4gICAgICAgIGVsc2UgaWYoIXRvdWNoX3RyaWdnZXJlZCkge1xuICAgICAgICAgIGNvdW50X3RvdWNoZXMgPSBzb3VyY2VFdmVudFR5cGUubWF0Y2goL3VwLykgPyAwIDogMTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHdlIGFyZSBpbiBhIGVuZCBldmVudCwgYnV0IHdoZW4gd2UgcmVtb3ZlIG9uZSB0b3VjaCBhbmRcbiAgICAgICAgLy8gd2Ugc3RpbGwgaGF2ZSBlbm91Z2gsIHNldCBldmVudFR5cGUgdG8gbW92ZVxuICAgICAgICBpZihjb3VudF90b3VjaGVzID4gMCAmJiBldmVudFR5cGUgPT0gSGFtbWVyLkVWRU5UX0VORCkge1xuICAgICAgICAgIGV2ZW50VHlwZSA9IEhhbW1lci5FVkVOVF9NT1ZFO1xuICAgICAgICB9XG4gICAgICAgIC8vIG5vIHRvdWNoZXMsIGZvcmNlIHRoZSBlbmQgZXZlbnRcbiAgICAgICAgZWxzZSBpZighY291bnRfdG91Y2hlcykge1xuICAgICAgICAgIGV2ZW50VHlwZSA9IEhhbW1lci5FVkVOVF9FTkQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdG9yZSB0aGUgbGFzdCBtb3ZlIGV2ZW50XG4gICAgICAgIGlmKGNvdW50X3RvdWNoZXMgfHwgbGFzdF9tb3ZlX2V2ZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgbGFzdF9tb3ZlX2V2ZW50ID0gZXY7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0cmlnZ2VyIHRoZSBoYW5kbGVyXG4gICAgICAgIGhhbmRsZXIuY2FsbChIYW1tZXIuZGV0ZWN0aW9uLCBzZWxmLmNvbGxlY3RFdmVudERhdGEoZWxlbWVudCwgZXZlbnRUeXBlLCBzZWxmLmdldFRvdWNoTGlzdChsYXN0X21vdmVfZXZlbnQsIGV2ZW50VHlwZSksIGV2KSk7XG5cbiAgICAgICAgLy8gcmVtb3ZlIHBvaW50ZXJldmVudCBmcm9tIGxpc3RcbiAgICAgICAgaWYoSGFtbWVyLkhBU19QT0lOVEVSRVZFTlRTICYmIGV2ZW50VHlwZSA9PSBIYW1tZXIuRVZFTlRfRU5EKSB7XG4gICAgICAgICAgY291bnRfdG91Y2hlcyA9IEhhbW1lci5Qb2ludGVyRXZlbnQudXBkYXRlUG9pbnRlcihldmVudFR5cGUsIGV2KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBvbiB0aGUgZW5kIHdlIHJlc2V0IGV2ZXJ5dGhpbmdcbiAgICAgIGlmKCFjb3VudF90b3VjaGVzKSB7XG4gICAgICAgIGxhc3RfbW92ZV9ldmVudCA9IG51bGw7XG4gICAgICAgIGVuYWJsZV9kZXRlY3QgPSBmYWxzZTtcbiAgICAgICAgdG91Y2hfdHJpZ2dlcmVkID0gZmFsc2U7XG4gICAgICAgIEhhbW1lci5Qb2ludGVyRXZlbnQucmVzZXQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5iaW5kRG9tKGVsZW1lbnQsIEhhbW1lci5FVkVOVF9UWVBFU1tldmVudFR5cGVdLCBmbik7XG5cbiAgICAvLyByZXR1cm4gdGhlIGJvdW5kIGZ1bmN0aW9uIHRvIGJlIGFibGUgdG8gdW5iaW5kIGl0IGxhdGVyXG4gICAgcmV0dXJuIGZuO1xuICAgIH0sXG5cblxuICAvKipcbiAgICogd2UgaGF2ZSBkaWZmZXJlbnQgZXZlbnRzIGZvciBlYWNoIGRldmljZS9icm93c2VyXG4gICAqIGRldGVybWluZSB3aGF0IHdlIG5lZWQgYW5kIHNldCB0aGVtIGluIHRoZSBIYW1tZXIuRVZFTlRfVFlQRVMgY29uc3RhbnRcbiAgICovXG4gIGRldGVybWluZUV2ZW50VHlwZXM6IGZ1bmN0aW9uIGRldGVybWluZUV2ZW50VHlwZXMoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIHRoZSBldmVudHR5cGUgd2Ugd2FudCB0byBzZXRcbiAgICB2YXIgdHlwZXM7XG5cbiAgICAvLyBwb2ludGVyRXZlbnRzIG1hZ2ljXG4gICAgaWYoSGFtbWVyLkhBU19QT0lOVEVSRVZFTlRTKSB7XG4gICAgICB0eXBlcyA9IEhhbW1lci5Qb2ludGVyRXZlbnQuZ2V0RXZlbnRzKCk7XG4gICAgfVxuICAgIC8vIG9uIEFuZHJvaWQsIGlPUywgYmxhY2tiZXJyeSwgd2luZG93cyBtb2JpbGUgd2UgZG9udCB3YW50IGFueSBtb3VzZWV2ZW50c1xuICAgIGVsc2UgaWYoSGFtbWVyLk5PX01PVVNFRVZFTlRTKSB7XG4gICAgICB0eXBlcyA9IFtcbiAgICAgICAgJ3RvdWNoc3RhcnQnLFxuICAgICAgICAndG91Y2htb3ZlJyxcbiAgICAgICAgJ3RvdWNoZW5kIHRvdWNoY2FuY2VsJ107XG4gICAgfVxuICAgIC8vIGZvciBub24gcG9pbnRlciBldmVudHMgYnJvd3NlcnMgYW5kIG1peGVkIGJyb3dzZXJzLFxuICAgIC8vIGxpa2UgY2hyb21lIG9uIHdpbmRvd3M4IHRvdWNoIGxhcHRvcFxuICAgIGVsc2Uge1xuICAgICAgdHlwZXMgPSBbXG4gICAgICAgICd0b3VjaHN0YXJ0IG1vdXNlZG93bicsXG4gICAgICAgICd0b3VjaG1vdmUgbW91c2Vtb3ZlJyxcbiAgICAgICAgJ3RvdWNoZW5kIHRvdWNoY2FuY2VsIG1vdXNldXAnXTtcbiAgICB9XG5cbiAgICBIYW1tZXIuRVZFTlRfVFlQRVNbSGFtbWVyLkVWRU5UX1NUQVJUXSA9IHR5cGVzWzBdO1xuICAgIEhhbW1lci5FVkVOVF9UWVBFU1tIYW1tZXIuRVZFTlRfTU9WRV0gPSB0eXBlc1sxXTtcbiAgICBIYW1tZXIuRVZFTlRfVFlQRVNbSGFtbWVyLkVWRU5UX0VORF0gPSB0eXBlc1syXTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBjcmVhdGUgdG91Y2hsaXN0IGRlcGVuZGluZyBvbiB0aGUgZXZlbnRcbiAgICogQHBhcmFtICAge09iamVjdH0gICAgZXZcbiAgICogQHBhcmFtICAge1N0cmluZ30gICAgZXZlbnRUeXBlICAgdXNlZCBieSB0aGUgZmFrZW11bHRpdG91Y2ggcGx1Z2luXG4gICAqL1xuICBnZXRUb3VjaExpc3Q6IGZ1bmN0aW9uIGdldFRvdWNoTGlzdChldi8qLCBldmVudFR5cGUqLykge1xuICAgIC8vIGdldCB0aGUgZmFrZSBwb2ludGVyRXZlbnQgdG91Y2hsaXN0XG4gICAgaWYoSGFtbWVyLkhBU19QT0lOVEVSRVZFTlRTKSB7XG4gICAgICByZXR1cm4gSGFtbWVyLlBvaW50ZXJFdmVudC5nZXRUb3VjaExpc3QoKTtcbiAgICB9XG4gICAgLy8gZ2V0IHRoZSB0b3VjaGxpc3RcbiAgICBlbHNlIGlmKGV2LnRvdWNoZXMpIHtcbiAgICAgIHJldHVybiBldi50b3VjaGVzO1xuICAgIH1cbiAgICAvLyBtYWtlIGZha2UgdG91Y2hsaXN0IGZyb20gbW91c2UgcG9zaXRpb25cbiAgICBlbHNlIHtcbiAgICAgIGV2LmlkZW50aWZpZXIgPSAxO1xuICAgICAgcmV0dXJuIFtldl07XG4gICAgfVxuICB9LFxuXG5cbiAgLyoqXG4gICAqIGNvbGxlY3QgZXZlbnQgZGF0YSBmb3IgSGFtbWVyIGpzXG4gICAqIEBwYXJhbSAgIHtIVE1MRWxlbWVudH0gICBlbGVtZW50XG4gICAqIEBwYXJhbSAgIHtTdHJpbmd9ICAgICAgICBldmVudFR5cGUgICAgICAgIGxpa2UgSGFtbWVyLkVWRU5UX01PVkVcbiAgICogQHBhcmFtICAge09iamVjdH0gICAgICAgIGV2ZW50RGF0YVxuICAgKi9cbiAgY29sbGVjdEV2ZW50RGF0YTogZnVuY3Rpb24gY29sbGVjdEV2ZW50RGF0YShlbGVtZW50LCBldmVudFR5cGUsIHRvdWNoZXMsIGV2KSB7XG4gICAgLy8gZmluZCBvdXQgcG9pbnRlclR5cGVcbiAgICB2YXIgcG9pbnRlclR5cGUgPSBIYW1tZXIuUE9JTlRFUl9UT1VDSDtcbiAgICBpZihldi50eXBlLm1hdGNoKC9tb3VzZS8pIHx8IEhhbW1lci5Qb2ludGVyRXZlbnQubWF0Y2hUeXBlKEhhbW1lci5QT0lOVEVSX01PVVNFLCBldikpIHtcbiAgICAgIHBvaW50ZXJUeXBlID0gSGFtbWVyLlBPSU5URVJfTU9VU0U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNlbnRlciAgICAgOiBIYW1tZXIudXRpbHMuZ2V0Q2VudGVyKHRvdWNoZXMpLFxuICAgICAgdGltZVN0YW1wICA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpLFxuICAgICAgdGFyZ2V0ICAgICA6IGV2LnRhcmdldCxcbiAgICAgIHRvdWNoZXMgICAgOiB0b3VjaGVzLFxuICAgICAgZXZlbnRUeXBlICA6IGV2ZW50VHlwZSxcbiAgICAgIHBvaW50ZXJUeXBlOiBwb2ludGVyVHlwZSxcbiAgICAgIHNyY0V2ZW50ICAgOiBldixcblxuICAgICAgLyoqXG4gICAgICAgKiBwcmV2ZW50IHRoZSBicm93c2VyIGRlZmF1bHQgYWN0aW9uc1xuICAgICAgICogbW9zdGx5IHVzZWQgdG8gZGlzYWJsZSBzY3JvbGxpbmcgb2YgdGhlIGJyb3dzZXJcbiAgICAgICAqL1xuICAgICAgcHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZih0aGlzLnNyY0V2ZW50LnByZXZlbnRNYW5pcHVsYXRpb24pIHtcbiAgICAgICAgICB0aGlzLnNyY0V2ZW50LnByZXZlbnRNYW5pcHVsYXRpb24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHRoaXMuc3JjRXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgICB0aGlzLnNyY0V2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogc3RvcCBidWJibGluZyB0aGUgZXZlbnQgdXAgdG8gaXRzIHBhcmVudHNcbiAgICAgICAqL1xuICAgICAgc3RvcFByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5zcmNFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogaW1tZWRpYXRlbHkgc3RvcCBnZXN0dXJlIGRldGVjdGlvblxuICAgICAgICogbWlnaHQgYmUgdXNlZnVsIGFmdGVyIGEgc3dpcGUgd2FzIGRldGVjdGVkXG4gICAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAgICovXG4gICAgICBzdG9wRGV0ZWN0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEhhbW1lci5kZXRlY3Rpb24uc3RvcERldGVjdCgpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn07XG5cbkhhbW1lci5Qb2ludGVyRXZlbnQgPSB7XG4gIC8qKlxuICAgKiBob2xkcyBhbGwgcG9pbnRlcnNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHBvaW50ZXJzOiB7fSxcblxuICAvKipcbiAgICogZ2V0IGEgbGlzdCBvZiBwb2ludGVyc1xuICAgKiBAcmV0dXJucyB7QXJyYXl9ICAgICB0b3VjaGxpc3RcbiAgICovXG4gIGdldFRvdWNoTGlzdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciB0b3VjaGxpc3QgPSBbXTtcblxuICAgIC8vIHdlIGNhbiB1c2UgZm9yRWFjaCBzaW5jZSBwb2ludGVyRXZlbnRzIG9ubHkgaXMgaW4gSUUxMFxuICAgIEhhbW1lci51dGlscy5lYWNoKHNlbGYucG9pbnRlcnMsIGZ1bmN0aW9uKHBvaW50ZXIpe1xuICAgICAgdG91Y2hsaXN0LnB1c2gocG9pbnRlcik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdG91Y2hsaXN0O1xuICB9LFxuXG4gIC8qKlxuICAgKiB1cGRhdGUgdGhlIHBvc2l0aW9uIG9mIGEgcG9pbnRlclxuICAgKiBAcGFyYW0gICB7U3RyaW5nfSAgIHR5cGUgICAgICAgICAgICAgSGFtbWVyLkVWRU5UX0VORFxuICAgKiBAcGFyYW0gICB7T2JqZWN0fSAgIHBvaW50ZXJFdmVudFxuICAgKi9cbiAgdXBkYXRlUG9pbnRlcjogZnVuY3Rpb24odHlwZSwgcG9pbnRlckV2ZW50KSB7XG4gICAgaWYodHlwZSA9PSBIYW1tZXIuRVZFTlRfRU5EKSB7XG4gICAgICBkZWxldGUgdGhpcy5wb2ludGVyc1twb2ludGVyRXZlbnQucG9pbnRlcklkXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBwb2ludGVyRXZlbnQuaWRlbnRpZmllciA9IHBvaW50ZXJFdmVudC5wb2ludGVySWQ7XG4gICAgICB0aGlzLnBvaW50ZXJzW3BvaW50ZXJFdmVudC5wb2ludGVySWRdID0gcG9pbnRlckV2ZW50O1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnBvaW50ZXJzKS5sZW5ndGg7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNoZWNrIGlmIGV2IG1hdGNoZXMgcG9pbnRlcnR5cGVcbiAgICogQHBhcmFtICAge1N0cmluZ30gICAgICAgIHBvaW50ZXJUeXBlICAgICBIYW1tZXIuUE9JTlRFUl9NT1VTRVxuICAgKiBAcGFyYW0gICB7UG9pbnRlckV2ZW50fSAgZXZcbiAgICovXG4gIG1hdGNoVHlwZTogZnVuY3Rpb24ocG9pbnRlclR5cGUsIGV2KSB7XG4gICAgaWYoIWV2LnBvaW50ZXJUeXBlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHB0ID0gZXYucG9pbnRlclR5cGUsXG4gICAgICB0eXBlcyA9IHt9O1xuICAgIHR5cGVzW0hhbW1lci5QT0lOVEVSX01PVVNFXSA9IChwdCA9PT0gZXYuTVNQT0lOVEVSX1RZUEVfTU9VU0UgfHwgcHQgPT09IEhhbW1lci5QT0lOVEVSX01PVVNFKTtcbiAgICB0eXBlc1tIYW1tZXIuUE9JTlRFUl9UT1VDSF0gPSAocHQgPT09IGV2Lk1TUE9JTlRFUl9UWVBFX1RPVUNIIHx8IHB0ID09PSBIYW1tZXIuUE9JTlRFUl9UT1VDSCk7XG4gICAgdHlwZXNbSGFtbWVyLlBPSU5URVJfUEVOXSA9IChwdCA9PT0gZXYuTVNQT0lOVEVSX1RZUEVfUEVOIHx8IHB0ID09PSBIYW1tZXIuUE9JTlRFUl9QRU4pO1xuICAgIHJldHVybiB0eXBlc1twb2ludGVyVHlwZV07XG4gIH0sXG5cblxuICAvKipcbiAgICogZ2V0IGV2ZW50c1xuICAgKi9cbiAgZ2V0RXZlbnRzOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gW1xuICAgICAgJ3BvaW50ZXJkb3duIE1TUG9pbnRlckRvd24nLFxuICAgICAgJ3BvaW50ZXJtb3ZlIE1TUG9pbnRlck1vdmUnLFxuICAgICAgJ3BvaW50ZXJ1cCBwb2ludGVyY2FuY2VsIE1TUG9pbnRlclVwIE1TUG9pbnRlckNhbmNlbCdcbiAgICBdO1xuICB9LFxuXG4gIC8qKlxuICAgKiByZXNldCB0aGUgbGlzdFxuICAgKi9cbiAgcmVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucG9pbnRlcnMgPSB7fTtcbiAgfVxufTtcblxuXG5IYW1tZXIuZGV0ZWN0aW9uID0ge1xuICAvLyBjb250YWlucyBhbGwgcmVnaXN0cmVkIEhhbW1lci5nZXN0dXJlcyBpbiB0aGUgY29ycmVjdCBvcmRlclxuICBnZXN0dXJlczogW10sXG5cbiAgLy8gZGF0YSBvZiB0aGUgY3VycmVudCBIYW1tZXIuZ2VzdHVyZSBkZXRlY3Rpb24gc2Vzc2lvblxuICBjdXJyZW50IDogbnVsbCxcblxuICAvLyB0aGUgcHJldmlvdXMgSGFtbWVyLmdlc3R1cmUgc2Vzc2lvbiBkYXRhXG4gIC8vIGlzIGEgZnVsbCBjbG9uZSBvZiB0aGUgcHJldmlvdXMgZ2VzdHVyZS5jdXJyZW50IG9iamVjdFxuICBwcmV2aW91czogbnVsbCxcblxuICAvLyB3aGVuIHRoaXMgYmVjb21lcyB0cnVlLCBubyBnZXN0dXJlcyBhcmUgZmlyZWRcbiAgc3RvcHBlZCA6IGZhbHNlLFxuXG5cbiAgLyoqXG4gICAqIHN0YXJ0IEhhbW1lci5nZXN0dXJlIGRldGVjdGlvblxuICAgKiBAcGFyYW0gICB7SGFtbWVyLkluc3RhbmNlfSAgIGluc3RcbiAgICogQHBhcmFtICAge09iamVjdH0gICAgICAgICAgICBldmVudERhdGFcbiAgICovXG4gIHN0YXJ0RGV0ZWN0OiBmdW5jdGlvbiBzdGFydERldGVjdChpbnN0LCBldmVudERhdGEpIHtcbiAgICAvLyBhbHJlYWR5IGJ1c3kgd2l0aCBhIEhhbW1lci5nZXN0dXJlIGRldGVjdGlvbiBvbiBhbiBlbGVtZW50XG4gICAgaWYodGhpcy5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wcGVkID0gZmFsc2U7XG5cbiAgICB0aGlzLmN1cnJlbnQgPSB7XG4gICAgICBpbnN0ICAgICAgOiBpbnN0LCAvLyByZWZlcmVuY2UgdG8gSGFtbWVySW5zdGFuY2Ugd2UncmUgd29ya2luZyBmb3JcbiAgICAgIHN0YXJ0RXZlbnQ6IEhhbW1lci51dGlscy5leHRlbmQoe30sIGV2ZW50RGF0YSksIC8vIHN0YXJ0IGV2ZW50RGF0YSBmb3IgZGlzdGFuY2VzLCB0aW1pbmcgZXRjXG4gICAgICBsYXN0RXZlbnQgOiBmYWxzZSwgLy8gbGFzdCBldmVudERhdGFcbiAgICAgIGxhc3RWRXZlbnQ6IGZhbHNlLCAvLyBsYXN0IGV2ZW50RGF0YSBmb3IgdmVsb2NpdHkuXG4gICAgICB2ZWxvY2l0eSAgOiBmYWxzZSwgLy8gY3VycmVudCB2ZWxvY2l0eVxuICAgICAgbmFtZSAgICAgIDogJycgLy8gY3VycmVudCBnZXN0dXJlIHdlJ3JlIGluL2RldGVjdGVkLCBjYW4gYmUgJ3RhcCcsICdob2xkJyBldGNcbiAgICB9O1xuXG4gICAgdGhpcy5kZXRlY3QoZXZlbnREYXRhKTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBIYW1tZXIuZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICogQHBhcmFtICAge09iamVjdH0gICAgZXZlbnREYXRhXG4gICAqL1xuICBkZXRlY3Q6IGZ1bmN0aW9uIGRldGVjdChldmVudERhdGEpIHtcbiAgICBpZighdGhpcy5jdXJyZW50IHx8IHRoaXMuc3RvcHBlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGV4dGVuZCBldmVudCBkYXRhIHdpdGggY2FsY3VsYXRpb25zIGFib3V0IHNjYWxlLCBkaXN0YW5jZSBldGNcbiAgICBldmVudERhdGEgPSB0aGlzLmV4dGVuZEV2ZW50RGF0YShldmVudERhdGEpO1xuXG4gICAgLy8gaW5zdGFuY2Ugb3B0aW9uc1xuICAgIHZhciBpbnN0X29wdGlvbnMgPSB0aGlzLmN1cnJlbnQuaW5zdC5vcHRpb25zO1xuXG4gICAgLy8gY2FsbCBIYW1tZXIuZ2VzdHVyZSBoYW5kbGVyc1xuICAgIEhhbW1lci51dGlscy5lYWNoKHRoaXMuZ2VzdHVyZXMsIGZ1bmN0aW9uKGdlc3R1cmUpIHtcbiAgICAgIC8vIG9ubHkgd2hlbiB0aGUgaW5zdGFuY2Ugb3B0aW9ucyBoYXZlIGVuYWJsZWQgdGhpcyBnZXN0dXJlXG4gICAgICBpZighdGhpcy5zdG9wcGVkICYmIGluc3Rfb3B0aW9uc1tnZXN0dXJlLm5hbWVdICE9PSBmYWxzZSkge1xuICAgICAgICAvLyBpZiBhIGhhbmRsZXIgcmV0dXJucyBmYWxzZSwgd2Ugc3RvcCB3aXRoIHRoZSBkZXRlY3Rpb25cbiAgICAgICAgaWYoZ2VzdHVyZS5oYW5kbGVyLmNhbGwoZ2VzdHVyZSwgZXZlbnREYXRhLCB0aGlzLmN1cnJlbnQuaW5zdCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgdGhpcy5zdG9wRGV0ZWN0KCk7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG5cbiAgICAvLyBzdG9yZSBhcyBwcmV2aW91cyBldmVudCBldmVudFxuICAgIGlmKHRoaXMuY3VycmVudCkge1xuICAgICAgdGhpcy5jdXJyZW50Lmxhc3RFdmVudCA9IGV2ZW50RGF0YTtcbiAgICB9XG5cbiAgICAvLyBlbmRldmVudCwgYnV0IG5vdCB0aGUgbGFzdCB0b3VjaCwgc28gZG9udCBzdG9wXG4gICAgaWYoZXZlbnREYXRhLmV2ZW50VHlwZSA9PSBIYW1tZXIuRVZFTlRfRU5EICYmICFldmVudERhdGEudG91Y2hlcy5sZW5ndGggLSAxKSB7XG4gICAgICB0aGlzLnN0b3BEZXRlY3QoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXZlbnREYXRhO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGNsZWFyIHRoZSBIYW1tZXIuZ2VzdHVyZSB2YXJzXG4gICAqIHRoaXMgaXMgY2FsbGVkIG9uIGVuZERldGVjdCwgYnV0IGNhbiBhbHNvIGJlIHVzZWQgd2hlbiBhIGZpbmFsIEhhbW1lci5nZXN0dXJlIGhhcyBiZWVuIGRldGVjdGVkXG4gICAqIHRvIHN0b3Agb3RoZXIgSGFtbWVyLmdlc3R1cmVzIGZyb20gYmVpbmcgZmlyZWRcbiAgICovXG4gIHN0b3BEZXRlY3Q6IGZ1bmN0aW9uIHN0b3BEZXRlY3QoKSB7XG4gICAgLy8gY2xvbmUgY3VycmVudCBkYXRhIHRvIHRoZSBzdG9yZSBhcyB0aGUgcHJldmlvdXMgZ2VzdHVyZVxuICAgIC8vIHVzZWQgZm9yIHRoZSBkb3VibGUgdGFwIGdlc3R1cmUsIHNpbmNlIHRoaXMgaXMgYW4gb3RoZXIgZ2VzdHVyZSBkZXRlY3Qgc2Vzc2lvblxuICAgIHRoaXMucHJldmlvdXMgPSBIYW1tZXIudXRpbHMuZXh0ZW5kKHt9LCB0aGlzLmN1cnJlbnQpO1xuXG4gICAgLy8gcmVzZXQgdGhlIGN1cnJlbnRcbiAgICB0aGlzLmN1cnJlbnQgPSBudWxsO1xuXG4gICAgLy8gc3RvcHBlZCFcbiAgICB0aGlzLnN0b3BwZWQgPSB0cnVlO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGV4dGVuZCBldmVudERhdGEgZm9yIEhhbW1lci5nZXN0dXJlc1xuICAgKiBAcGFyYW0gICB7T2JqZWN0fSAgIGV2XG4gICAqIEByZXR1cm5zIHtPYmplY3R9ICAgZXZcbiAgICovXG4gIGV4dGVuZEV2ZW50RGF0YTogZnVuY3Rpb24gZXh0ZW5kRXZlbnREYXRhKGV2KSB7XG4gICAgdmFyIHN0YXJ0RXYgPSB0aGlzLmN1cnJlbnQuc3RhcnRFdmVudCxcbiAgICAgICAgbGFzdFZFdiA9IHRoaXMuY3VycmVudC5sYXN0VkV2ZW50O1xuXG4gICAgLy8gaWYgdGhlIHRvdWNoZXMgY2hhbmdlLCBzZXQgdGhlIG5ldyB0b3VjaGVzIG92ZXIgdGhlIHN0YXJ0RXZlbnQgdG91Y2hlc1xuICAgIC8vIHRoaXMgYmVjYXVzZSB0b3VjaGV2ZW50cyBkb24ndCBoYXZlIGFsbCB0aGUgdG91Y2hlcyBvbiB0b3VjaHN0YXJ0LCBvciB0aGVcbiAgICAvLyB1c2VyIG11c3QgcGxhY2UgaGlzIGZpbmdlcnMgYXQgdGhlIEVYQUNUIHNhbWUgdGltZSBvbiB0aGUgc2NyZWVuLCB3aGljaCBpcyBub3QgcmVhbGlzdGljXG4gICAgLy8gYnV0LCBzb21ldGltZXMgaXQgaGFwcGVucyB0aGF0IGJvdGggZmluZ2VycyBhcmUgdG91Y2hpbmcgYXQgdGhlIEVYQUNUIHNhbWUgdGltZVxuICAgIGlmKHN0YXJ0RXYgJiYgKGV2LnRvdWNoZXMubGVuZ3RoICE9IHN0YXJ0RXYudG91Y2hlcy5sZW5ndGggfHwgZXYudG91Y2hlcyA9PT0gc3RhcnRFdi50b3VjaGVzKSkge1xuICAgICAgLy8gZXh0ZW5kIDEgbGV2ZWwgZGVlcCB0byBnZXQgdGhlIHRvdWNobGlzdCB3aXRoIHRoZSB0b3VjaCBvYmplY3RzXG4gICAgICBzdGFydEV2LnRvdWNoZXMgPSBbXTtcbiAgICAgIEhhbW1lci51dGlscy5lYWNoKGV2LnRvdWNoZXMsIGZ1bmN0aW9uKHRvdWNoKSB7XG4gICAgICAgIHN0YXJ0RXYudG91Y2hlcy5wdXNoKEhhbW1lci51dGlscy5leHRlbmQoe30sIHRvdWNoKSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgZGVsdGFfdGltZSA9IGV2LnRpbWVTdGFtcCAtIHN0YXJ0RXYudGltZVN0YW1wXG4gICAgICAsIGRlbHRhX3ggPSBldi5jZW50ZXIucGFnZVggLSBzdGFydEV2LmNlbnRlci5wYWdlWFxuICAgICAgLCBkZWx0YV95ID0gZXYuY2VudGVyLnBhZ2VZIC0gc3RhcnRFdi5jZW50ZXIucGFnZVlcbiAgICAgICwgaW50ZXJpbUFuZ2xlXG4gICAgICAsIGludGVyaW1EaXJlY3Rpb25cbiAgICAgICwgdmVsb2NpdHkgPSB0aGlzLmN1cnJlbnQudmVsb2NpdHk7XG4gIFxuICAgIGlmIChsYXN0VkV2ICE9PSBmYWxzZSAmJiBldi50aW1lU3RhbXAgLSBsYXN0VkV2LnRpbWVTdGFtcCA+IEhhbW1lci5VUERBVEVfVkVMT0NJVFlfSU5URVJWQUwpIHtcbiAgXG4gICAgICAgIHZlbG9jaXR5ID0gIEhhbW1lci51dGlscy5nZXRWZWxvY2l0eShldi50aW1lU3RhbXAgLSBsYXN0VkV2LnRpbWVTdGFtcCwgZXYuY2VudGVyLnBhZ2VYIC0gbGFzdFZFdi5jZW50ZXIucGFnZVgsIGV2LmNlbnRlci5wYWdlWSAtIGxhc3RWRXYuY2VudGVyLnBhZ2VZKTtcbiAgICAgICAgdGhpcy5jdXJyZW50Lmxhc3RWRXZlbnQgPSBldjtcbiAgXG4gICAgICAgIGlmICh2ZWxvY2l0eS54ID4gMCAmJiB2ZWxvY2l0eS55ID4gMCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50LnZlbG9jaXR5ID0gdmVsb2NpdHk7XG4gICAgICAgIH1cbiAgXG4gICAgfSBlbHNlIGlmKHRoaXMuY3VycmVudC52ZWxvY2l0eSA9PT0gZmFsc2UpIHtcbiAgICAgICAgdmVsb2NpdHkgPSBIYW1tZXIudXRpbHMuZ2V0VmVsb2NpdHkoZGVsdGFfdGltZSwgZGVsdGFfeCwgZGVsdGFfeSk7XG4gICAgICAgIHRoaXMuY3VycmVudC52ZWxvY2l0eSA9IHZlbG9jaXR5O1xuICAgICAgICB0aGlzLmN1cnJlbnQubGFzdFZFdmVudCA9IGV2O1xuICAgIH1cblxuICAgIC8vIGVuZCBldmVudHMgKGUuZy4gZHJhZ2VuZCkgZG9uJ3QgaGF2ZSB1c2VmdWwgdmFsdWVzIGZvciBpbnRlcmltRGlyZWN0aW9uICYgaW50ZXJpbUFuZ2xlXG4gICAgLy8gYmVjYXVzZSB0aGUgcHJldmlvdXMgZXZlbnQgaGFzIGV4YWN0bHkgdGhlIHNhbWUgY29vcmRpbmF0ZXNcbiAgICAvLyBzbyBmb3IgZW5kIGV2ZW50cywgdGFrZSB0aGUgcHJldmlvdXMgdmFsdWVzIG9mIGludGVyaW1EaXJlY3Rpb24gJiBpbnRlcmltQW5nbGVcbiAgICAvLyBpbnN0ZWFkIG9mIHJlY2FsY3VsYXRpbmcgdGhlbSBhbmQgZ2V0dGluZyBhIHNwdXJpb3VzICcwJ1xuICAgIGlmKGV2LmV2ZW50VHlwZSA9PT0gJ2VuZCcpIHtcbiAgICAgIGludGVyaW1BbmdsZSA9IHRoaXMuY3VycmVudC5sYXN0RXZlbnQgJiYgdGhpcy5jdXJyZW50Lmxhc3RFdmVudC5pbnRlcmltQW5nbGU7XG4gICAgICBpbnRlcmltRGlyZWN0aW9uID0gdGhpcy5jdXJyZW50Lmxhc3RFdmVudCAmJiB0aGlzLmN1cnJlbnQubGFzdEV2ZW50LmludGVyaW1EaXJlY3Rpb247XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaW50ZXJpbUFuZ2xlID0gdGhpcy5jdXJyZW50Lmxhc3RFdmVudCAmJiBIYW1tZXIudXRpbHMuZ2V0QW5nbGUodGhpcy5jdXJyZW50Lmxhc3RFdmVudC5jZW50ZXIsIGV2LmNlbnRlcik7XG4gICAgICBpbnRlcmltRGlyZWN0aW9uID0gdGhpcy5jdXJyZW50Lmxhc3RFdmVudCAmJiBIYW1tZXIudXRpbHMuZ2V0RGlyZWN0aW9uKHRoaXMuY3VycmVudC5sYXN0RXZlbnQuY2VudGVyLCBldi5jZW50ZXIpO1xuICAgIH1cblxuICAgIEhhbW1lci51dGlscy5leHRlbmQoZXYsIHtcbiAgICAgIGRlbHRhVGltZTogZGVsdGFfdGltZSxcblxuICAgICAgZGVsdGFYOiBkZWx0YV94LFxuICAgICAgZGVsdGFZOiBkZWx0YV95LFxuXG4gICAgICB2ZWxvY2l0eVg6IHZlbG9jaXR5LngsXG4gICAgICB2ZWxvY2l0eVk6IHZlbG9jaXR5LnksXG5cbiAgICAgIGRpc3RhbmNlOiBIYW1tZXIudXRpbHMuZ2V0RGlzdGFuY2Uoc3RhcnRFdi5jZW50ZXIsIGV2LmNlbnRlciksXG5cbiAgICAgIGFuZ2xlOiBIYW1tZXIudXRpbHMuZ2V0QW5nbGUoc3RhcnRFdi5jZW50ZXIsIGV2LmNlbnRlciksXG4gICAgICBpbnRlcmltQW5nbGU6IGludGVyaW1BbmdsZSxcblxuICAgICAgZGlyZWN0aW9uOiBIYW1tZXIudXRpbHMuZ2V0RGlyZWN0aW9uKHN0YXJ0RXYuY2VudGVyLCBldi5jZW50ZXIpLFxuICAgICAgaW50ZXJpbURpcmVjdGlvbjogaW50ZXJpbURpcmVjdGlvbixcblxuICAgICAgc2NhbGU6IEhhbW1lci51dGlscy5nZXRTY2FsZShzdGFydEV2LnRvdWNoZXMsIGV2LnRvdWNoZXMpLFxuICAgICAgcm90YXRpb246IEhhbW1lci51dGlscy5nZXRSb3RhdGlvbihzdGFydEV2LnRvdWNoZXMsIGV2LnRvdWNoZXMpLFxuXG4gICAgICBzdGFydEV2ZW50OiBzdGFydEV2XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZXY7XG4gIH0sXG5cblxuICAvKipcbiAgICogcmVnaXN0ZXIgbmV3IGdlc3R1cmVcbiAgICogQHBhcmFtICAge09iamVjdH0gICAgZ2VzdHVyZSBvYmplY3QsIHNlZSBnZXN0dXJlcy5qcyBmb3IgZG9jdW1lbnRhdGlvblxuICAgKiBAcmV0dXJucyB7QXJyYXl9ICAgICBnZXN0dXJlc1xuICAgKi9cbiAgcmVnaXN0ZXI6IGZ1bmN0aW9uIHJlZ2lzdGVyKGdlc3R1cmUpIHtcbiAgICAvLyBhZGQgYW4gZW5hYmxlIGdlc3R1cmUgb3B0aW9ucyBpZiB0aGVyZSBpcyBubyBnaXZlblxuICAgIHZhciBvcHRpb25zID0gZ2VzdHVyZS5kZWZhdWx0cyB8fCB7fTtcbiAgICBpZihvcHRpb25zW2dlc3R1cmUubmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9uc1tnZXN0dXJlLm5hbWVdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBleHRlbmQgSGFtbWVyIGRlZmF1bHQgb3B0aW9ucyB3aXRoIHRoZSBIYW1tZXIuZ2VzdHVyZSBvcHRpb25zXG4gICAgSGFtbWVyLnV0aWxzLmV4dGVuZChIYW1tZXIuZGVmYXVsdHMsIG9wdGlvbnMsIHRydWUpO1xuXG4gICAgLy8gc2V0IGl0cyBpbmRleFxuICAgIGdlc3R1cmUuaW5kZXggPSBnZXN0dXJlLmluZGV4IHx8IDEwMDA7XG5cbiAgICAvLyBhZGQgSGFtbWVyLmdlc3R1cmUgdG8gdGhlIGxpc3RcbiAgICB0aGlzLmdlc3R1cmVzLnB1c2goZ2VzdHVyZSk7XG5cbiAgICAvLyBzb3J0IHRoZSBsaXN0IGJ5IGluZGV4XG4gICAgdGhpcy5nZXN0dXJlcy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIGlmKGEuaW5kZXggPCBiLmluZGV4KSB7IHJldHVybiAtMTsgfVxuICAgICAgaWYoYS5pbmRleCA+IGIuaW5kZXgpIHsgcmV0dXJuIDE7IH1cbiAgICAgIHJldHVybiAwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2VzdHVyZXM7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBEcmFnXG4gKiBNb3ZlIHdpdGggeCBmaW5nZXJzIChkZWZhdWx0IDEpIGFyb3VuZCBvbiB0aGUgcGFnZS4gQmxvY2tpbmcgdGhlIHNjcm9sbGluZyB3aGVuXG4gKiBtb3ZpbmcgbGVmdCBhbmQgcmlnaHQgaXMgYSBnb29kIHByYWN0aWNlLiBXaGVuIGFsbCB0aGUgZHJhZyBldmVudHMgYXJlIGJsb2NraW5nXG4gKiB5b3UgZGlzYWJsZSBzY3JvbGxpbmcgb24gdGhhdCBhcmVhLlxuICogQGV2ZW50cyAgZHJhZywgZHJhcGxlZnQsIGRyYWdyaWdodCwgZHJhZ3VwLCBkcmFnZG93blxuICovXG5IYW1tZXIuZ2VzdHVyZXMuRHJhZyA9IHtcbiAgbmFtZSAgICAgOiAnZHJhZycsXG4gIGluZGV4ICAgIDogNTAsXG4gIGRlZmF1bHRzIDoge1xuICAgIGRyYWdfbWluX2Rpc3RhbmNlICAgICAgICAgICAgOiAxMCxcblxuICAgIC8vIFNldCBjb3JyZWN0X2Zvcl9kcmFnX21pbl9kaXN0YW5jZSB0byB0cnVlIHRvIG1ha2UgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBkcmFnXG4gICAgLy8gYmUgY2FsY3VsYXRlZCBmcm9tIHdoZXJlIHRoZSBkcmFnIHdhcyB0cmlnZ2VyZWQsIG5vdCBmcm9tIHdoZXJlIHRoZSB0b3VjaCBzdGFydGVkLlxuICAgIC8vIFVzZWZ1bCB0byBhdm9pZCBhIGplcmstc3RhcnRpbmcgZHJhZywgd2hpY2ggY2FuIG1ha2UgZmluZS1hZGp1c3RtZW50c1xuICAgIC8vIHRocm91Z2ggZHJhZ2dpbmcgZGlmZmljdWx0LCBhbmQgYmUgdmlzdWFsbHkgdW5hcHBlYWxpbmcuXG4gICAgY29ycmVjdF9mb3JfZHJhZ19taW5fZGlzdGFuY2U6IHRydWUsXG5cbiAgICAvLyBzZXQgMCBmb3IgdW5saW1pdGVkLCBidXQgdGhpcyBjYW4gY29uZmxpY3Qgd2l0aCB0cmFuc2Zvcm1cbiAgICBkcmFnX21heF90b3VjaGVzICAgICAgICAgICAgIDogMSxcblxuICAgIC8vIHByZXZlbnQgZGVmYXVsdCBicm93c2VyIGJlaGF2aW9yIHdoZW4gZHJhZ2dpbmcgb2NjdXJzXG4gICAgLy8gYmUgY2FyZWZ1bCB3aXRoIGl0LCBpdCBtYWtlcyB0aGUgZWxlbWVudCBhIGJsb2NraW5nIGVsZW1lbnRcbiAgICAvLyB3aGVuIHlvdSBhcmUgdXNpbmcgdGhlIGRyYWcgZ2VzdHVyZSwgaXQgaXMgYSBnb29kIHByYWN0aWNlIHRvIHNldCB0aGlzIHRydWVcbiAgICBkcmFnX2Jsb2NrX2hvcml6b250YWwgICAgICAgIDogZmFsc2UsXG4gICAgZHJhZ19ibG9ja192ZXJ0aWNhbCAgICAgICAgICA6IGZhbHNlLFxuXG4gICAgLy8gZHJhZ19sb2NrX3RvX2F4aXMga2VlcHMgdGhlIGRyYWcgZ2VzdHVyZSBvbiB0aGUgYXhpcyB0aGF0IGl0IHN0YXJ0ZWQgb24sXG4gICAgLy8gSXQgZGlzYWxsb3dzIHZlcnRpY2FsIGRpcmVjdGlvbnMgaWYgdGhlIGluaXRpYWwgZGlyZWN0aW9uIHdhcyBob3Jpem9udGFsLCBhbmQgdmljZSB2ZXJzYS5cbiAgICBkcmFnX2xvY2tfdG9fYXhpcyAgICAgICAgICAgIDogZmFsc2UsXG5cbiAgICAvLyBkcmFnIGxvY2sgb25seSBraWNrcyBpbiB3aGVuIGRpc3RhbmNlID4gZHJhZ19sb2NrX21pbl9kaXN0YW5jZVxuICAgIC8vIFRoaXMgd2F5LCBsb2NraW5nIG9jY3VycyBvbmx5IHdoZW4gdGhlIGRpc3RhbmNlIGhhcyBiZWNvbWUgbGFyZ2UgZW5vdWdoIHRvIHJlbGlhYmx5IGRldGVybWluZSB0aGUgZGlyZWN0aW9uXG4gICAgZHJhZ19sb2NrX21pbl9kaXN0YW5jZSAgICAgICA6IDI1XG4gIH0sXG5cbiAgdHJpZ2dlcmVkOiBmYWxzZSxcbiAgaGFuZGxlciAgOiBmdW5jdGlvbiBkcmFnR2VzdHVyZShldiwgaW5zdCkge1xuICAgIC8vIGN1cnJlbnQgZ2VzdHVyZSBpc250IGRyYWcsIGJ1dCBkcmFnZ2VkIGlzIHRydWVcbiAgICAvLyB0aGlzIG1lYW5zIGFuIG90aGVyIGdlc3R1cmUgaXMgYnVzeS4gbm93IGNhbGwgZHJhZ2VuZFxuICAgIGlmKEhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5uYW1lICE9IHRoaXMubmFtZSAmJiB0aGlzLnRyaWdnZXJlZCkge1xuICAgICAgaW5zdC50cmlnZ2VyKHRoaXMubmFtZSArICdlbmQnLCBldik7XG4gICAgICB0aGlzLnRyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG1heCB0b3VjaGVzXG4gICAgaWYoaW5zdC5vcHRpb25zLmRyYWdfbWF4X3RvdWNoZXMgPiAwICYmXG4gICAgICBldi50b3VjaGVzLmxlbmd0aCA+IGluc3Qub3B0aW9ucy5kcmFnX21heF90b3VjaGVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoKGV2LmV2ZW50VHlwZSkge1xuICAgICAgY2FzZSBIYW1tZXIuRVZFTlRfU1RBUlQ6XG4gICAgICAgIHRoaXMudHJpZ2dlcmVkID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEhhbW1lci5FVkVOVF9NT1ZFOlxuICAgICAgICAvLyB3aGVuIHRoZSBkaXN0YW5jZSB3ZSBtb3ZlZCBpcyB0b28gc21hbGwgd2Ugc2tpcCB0aGlzIGdlc3R1cmVcbiAgICAgICAgLy8gb3Igd2UgY2FuIGJlIGFscmVhZHkgaW4gZHJhZ2dpbmdcbiAgICAgICAgaWYoZXYuZGlzdGFuY2UgPCBpbnN0Lm9wdGlvbnMuZHJhZ19taW5fZGlzdGFuY2UgJiZcbiAgICAgICAgICBIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQubmFtZSAhPSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3ZSBhcmUgZHJhZ2dpbmchXG4gICAgICAgIGlmKEhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5uYW1lICE9IHRoaXMubmFtZSkge1xuICAgICAgICAgIEhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5uYW1lID0gdGhpcy5uYW1lO1xuICAgICAgICAgIGlmKGluc3Qub3B0aW9ucy5jb3JyZWN0X2Zvcl9kcmFnX21pbl9kaXN0YW5jZSAmJiBldi5kaXN0YW5jZSA+IDApIHtcbiAgICAgICAgICAgIC8vIFdoZW4gYSBkcmFnIGlzIHRyaWdnZXJlZCwgc2V0IHRoZSBldmVudCBjZW50ZXIgdG8gZHJhZ19taW5fZGlzdGFuY2UgcGl4ZWxzIGZyb20gdGhlIG9yaWdpbmFsIGV2ZW50IGNlbnRlci5cbiAgICAgICAgICAgIC8vIFdpdGhvdXQgdGhpcyBjb3JyZWN0aW9uLCB0aGUgZHJhZ2dlZCBkaXN0YW5jZSB3b3VsZCBqdW1wc3RhcnQgYXQgZHJhZ19taW5fZGlzdGFuY2UgcGl4ZWxzIGluc3RlYWQgb2YgYXQgMC5cbiAgICAgICAgICAgIC8vIEl0IG1pZ2h0IGJlIHVzZWZ1bCB0byBzYXZlIHRoZSBvcmlnaW5hbCBzdGFydCBwb2ludCBzb21ld2hlcmVcbiAgICAgICAgICAgIHZhciBmYWN0b3IgPSBNYXRoLmFicyhpbnN0Lm9wdGlvbnMuZHJhZ19taW5fZGlzdGFuY2UgLyBldi5kaXN0YW5jZSk7XG4gICAgICAgICAgICBIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQuc3RhcnRFdmVudC5jZW50ZXIucGFnZVggKz0gZXYuZGVsdGFYICogZmFjdG9yO1xuICAgICAgICAgICAgSGFtbWVyLmRldGVjdGlvbi5jdXJyZW50LnN0YXJ0RXZlbnQuY2VudGVyLnBhZ2VZICs9IGV2LmRlbHRhWSAqIGZhY3RvcjtcblxuICAgICAgICAgICAgLy8gcmVjYWxjdWxhdGUgZXZlbnQgZGF0YSB1c2luZyBuZXcgc3RhcnQgcG9pbnRcbiAgICAgICAgICAgIGV2ID0gSGFtbWVyLmRldGVjdGlvbi5leHRlbmRFdmVudERhdGEoZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGxvY2sgZHJhZyB0byBheGlzP1xuICAgICAgICBpZihIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQubGFzdEV2ZW50LmRyYWdfbG9ja2VkX3RvX2F4aXMgfHwgKGluc3Qub3B0aW9ucy5kcmFnX2xvY2tfdG9fYXhpcyAmJiBpbnN0Lm9wdGlvbnMuZHJhZ19sb2NrX21pbl9kaXN0YW5jZSA8PSBldi5kaXN0YW5jZSkpIHtcbiAgICAgICAgICBldi5kcmFnX2xvY2tlZF90b19heGlzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFzdF9kaXJlY3Rpb24gPSBIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQubGFzdEV2ZW50LmRpcmVjdGlvbjtcbiAgICAgICAgaWYoZXYuZHJhZ19sb2NrZWRfdG9fYXhpcyAmJiBsYXN0X2RpcmVjdGlvbiAhPT0gZXYuZGlyZWN0aW9uKSB7XG4gICAgICAgICAgLy8ga2VlcCBkaXJlY3Rpb24gb24gdGhlIGF4aXMgdGhhdCB0aGUgZHJhZyBnZXN0dXJlIHN0YXJ0ZWQgb25cbiAgICAgICAgICBpZihIYW1tZXIudXRpbHMuaXNWZXJ0aWNhbChsYXN0X2RpcmVjdGlvbikpIHtcbiAgICAgICAgICAgIGV2LmRpcmVjdGlvbiA9IChldi5kZWx0YVkgPCAwKSA/IEhhbW1lci5ESVJFQ1RJT05fVVAgOiBIYW1tZXIuRElSRUNUSU9OX0RPV047XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZXYuZGlyZWN0aW9uID0gKGV2LmRlbHRhWCA8IDApID8gSGFtbWVyLkRJUkVDVElPTl9MRUZUIDogSGFtbWVyLkRJUkVDVElPTl9SSUdIVDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaXJzdCB0aW1lLCB0cmlnZ2VyIGRyYWdzdGFydCBldmVudFxuICAgICAgICBpZighdGhpcy50cmlnZ2VyZWQpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIodGhpcy5uYW1lICsgJ3N0YXJ0JywgZXYpO1xuICAgICAgICAgIHRoaXMudHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHRyaWdnZXIgbm9ybWFsIGV2ZW50XG4gICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcblxuICAgICAgICAvLyBkaXJlY3Rpb24gZXZlbnQsIGxpa2UgZHJhZ2Rvd25cbiAgICAgICAgaW5zdC50cmlnZ2VyKHRoaXMubmFtZSArIGV2LmRpcmVjdGlvbiwgZXYpO1xuXG4gICAgICAgIC8vIGJsb2NrIHRoZSBicm93c2VyIGV2ZW50c1xuICAgICAgICBpZigoaW5zdC5vcHRpb25zLmRyYWdfYmxvY2tfdmVydGljYWwgJiYgSGFtbWVyLnV0aWxzLmlzVmVydGljYWwoZXYuZGlyZWN0aW9uKSkgfHxcbiAgICAgICAgICAoaW5zdC5vcHRpb25zLmRyYWdfYmxvY2tfaG9yaXpvbnRhbCAmJiAhSGFtbWVyLnV0aWxzLmlzVmVydGljYWwoZXYuZGlyZWN0aW9uKSkpIHtcbiAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEhhbW1lci5FVkVOVF9FTkQ6XG4gICAgICAgIC8vIHRyaWdnZXIgZHJhZ2VuZFxuICAgICAgICBpZih0aGlzLnRyaWdnZXJlZCkge1xuICAgICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUgKyAnZW5kJywgZXYpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEhvbGRcbiAqIFRvdWNoIHN0YXlzIGF0IHRoZSBzYW1lIHBsYWNlIGZvciB4IHRpbWVcbiAqIEBldmVudHMgIGhvbGRcbiAqL1xuSGFtbWVyLmdlc3R1cmVzLkhvbGQgPSB7XG4gIG5hbWUgICAgOiAnaG9sZCcsXG4gIGluZGV4ICAgOiAxMCxcbiAgZGVmYXVsdHM6IHtcbiAgICBob2xkX3RpbWVvdXQgIDogNTAwLFxuICAgIGhvbGRfdGhyZXNob2xkOiAxXG4gIH0sXG4gIHRpbWVyICAgOiBudWxsLFxuICBoYW5kbGVyIDogZnVuY3Rpb24gaG9sZEdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICBzd2l0Y2goZXYuZXZlbnRUeXBlKSB7XG4gICAgICBjYXNlIEhhbW1lci5FVkVOVF9TVEFSVDpcbiAgICAgICAgLy8gY2xlYXIgYW55IHJ1bm5pbmcgdGltZXJzXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcblxuICAgICAgICAvLyBzZXQgdGhlIGdlc3R1cmUgc28gd2UgY2FuIGNoZWNrIGluIHRoZSB0aW1lb3V0IGlmIGl0IHN0aWxsIGlzXG4gICAgICAgIEhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5uYW1lID0gdGhpcy5uYW1lO1xuXG4gICAgICAgIC8vIHNldCB0aW1lciBhbmQgaWYgYWZ0ZXIgdGhlIHRpbWVvdXQgaXQgc3RpbGwgaXMgaG9sZCxcbiAgICAgICAgLy8gd2UgdHJpZ2dlciB0aGUgaG9sZCBldmVudFxuICAgICAgICB0aGlzLnRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZihIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQubmFtZSA9PSAnaG9sZCcpIHtcbiAgICAgICAgICAgIGluc3QudHJpZ2dlcignaG9sZCcsIGV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIGluc3Qub3B0aW9ucy5ob2xkX3RpbWVvdXQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gd2hlbiB5b3UgbW92ZSBvciBlbmQgd2UgY2xlYXIgdGhlIHRpbWVyXG4gICAgICBjYXNlIEhhbW1lci5FVkVOVF9NT1ZFOlxuICAgICAgICBpZihldi5kaXN0YW5jZSA+IGluc3Qub3B0aW9ucy5ob2xkX3RocmVzaG9sZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBIYW1tZXIuRVZFTlRfRU5EOlxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBSZWxlYXNlXG4gKiBDYWxsZWQgYXMgbGFzdCwgdGVsbHMgdGhlIHVzZXIgaGFzIHJlbGVhc2VkIHRoZSBzY3JlZW5cbiAqIEBldmVudHMgIHJlbGVhc2VcbiAqL1xuSGFtbWVyLmdlc3R1cmVzLlJlbGVhc2UgPSB7XG4gIG5hbWUgICA6ICdyZWxlYXNlJyxcbiAgaW5kZXggIDogSW5maW5pdHksXG4gIGhhbmRsZXI6IGZ1bmN0aW9uIHJlbGVhc2VHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgaWYoZXYuZXZlbnRUeXBlID09IEhhbW1lci5FVkVOVF9FTkQpIHtcbiAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogU3dpcGVcbiAqIHRyaWdnZXJzIHN3aXBlIGV2ZW50cyB3aGVuIHRoZSBlbmQgdmVsb2NpdHkgaXMgYWJvdmUgdGhlIHRocmVzaG9sZFxuICogQGV2ZW50cyAgc3dpcGUsIHN3aXBlbGVmdCwgc3dpcGVyaWdodCwgc3dpcGV1cCwgc3dpcGVkb3duXG4gKi9cbkhhbW1lci5nZXN0dXJlcy5Td2lwZSA9IHtcbiAgbmFtZSAgICA6ICdzd2lwZScsXG4gIGluZGV4ICAgOiA0MCxcbiAgZGVmYXVsdHM6IHtcbiAgICAvLyBzZXQgMCBmb3IgdW5saW1pdGVkLCBidXQgdGhpcyBjYW4gY29uZmxpY3Qgd2l0aCB0cmFuc2Zvcm1cbiAgICBzd2lwZV9taW5fdG91Y2hlczogMSxcbiAgICBzd2lwZV9tYXhfdG91Y2hlczogMSxcbiAgICBzd2lwZV92ZWxvY2l0eSAgIDogMC43XG4gIH0sXG4gIGhhbmRsZXIgOiBmdW5jdGlvbiBzd2lwZUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICBpZihldi5ldmVudFR5cGUgPT0gSGFtbWVyLkVWRU5UX0VORCkge1xuICAgICAgLy8gbWF4IHRvdWNoZXNcbiAgICAgIGlmKGluc3Qub3B0aW9ucy5zd2lwZV9tYXhfdG91Y2hlcyA+IDAgJiZcbiAgICAgICAgZXYudG91Y2hlcy5sZW5ndGggPCBpbnN0Lm9wdGlvbnMuc3dpcGVfbWluX3RvdWNoZXMgJiZcbiAgICAgICAgZXYudG91Y2hlcy5sZW5ndGggPiBpbnN0Lm9wdGlvbnMuc3dpcGVfbWF4X3RvdWNoZXMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyB3aGVuIHRoZSBkaXN0YW5jZSB3ZSBtb3ZlZCBpcyB0b28gc21hbGwgd2Ugc2tpcCB0aGlzIGdlc3R1cmVcbiAgICAgIC8vIG9yIHdlIGNhbiBiZSBhbHJlYWR5IGluIGRyYWdnaW5nXG4gICAgICBpZihldi52ZWxvY2l0eVggPiBpbnN0Lm9wdGlvbnMuc3dpcGVfdmVsb2NpdHkgfHxcbiAgICAgICAgZXYudmVsb2NpdHlZID4gaW5zdC5vcHRpb25zLnN3aXBlX3ZlbG9jaXR5KSB7XG4gICAgICAgIC8vIHRyaWdnZXIgc3dpcGUgZXZlbnRzXG4gICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcbiAgICAgICAgaW5zdC50cmlnZ2VyKHRoaXMubmFtZSArIGV2LmRpcmVjdGlvbiwgZXYpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBUYXAvRG91YmxlVGFwXG4gKiBRdWljayB0b3VjaCBhdCBhIHBsYWNlIG9yIGRvdWJsZSBhdCB0aGUgc2FtZSBwbGFjZVxuICogQGV2ZW50cyAgdGFwLCBkb3VibGV0YXBcbiAqL1xuSGFtbWVyLmdlc3R1cmVzLlRhcCA9IHtcbiAgbmFtZSAgICA6ICd0YXAnLFxuICBpbmRleCAgIDogMTAwLFxuICBkZWZhdWx0czoge1xuICAgIHRhcF9tYXhfdG91Y2h0aW1lIDogMjUwLFxuICAgIHRhcF9tYXhfZGlzdGFuY2UgIDogMTAsXG4gICAgdGFwX2Fsd2F5cyAgICAgICAgOiB0cnVlLFxuICAgIGRvdWJsZXRhcF9kaXN0YW5jZTogMjAsXG4gICAgZG91YmxldGFwX2ludGVydmFsOiAzMDBcbiAgfSxcbiAgaGFuZGxlciA6IGZ1bmN0aW9uIHRhcEdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICBpZihldi5ldmVudFR5cGUgPT0gSGFtbWVyLkVWRU5UX01PVkUgJiYgIUhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5yZWFjaGVkVGFwTWF4RGlzdGFuY2UpIHtcbiAgICAgIC8vVHJhY2sgdGhlIGRpc3RhbmNlIHdlJ3ZlIG1vdmVkLiBJZiBpdCdzIGFib3ZlIHRoZSBtYXggT05DRSwgcmVtZW1iZXIgdGhhdCAoZml4ZXMgIzQwNikuXG4gICAgICBIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQucmVhY2hlZFRhcE1heERpc3RhbmNlID0gKGV2LmRpc3RhbmNlID4gaW5zdC5vcHRpb25zLnRhcF9tYXhfZGlzdGFuY2UpO1xuICAgIH0gZWxzZSBpZihldi5ldmVudFR5cGUgPT0gSGFtbWVyLkVWRU5UX0VORCAmJiBldi5zcmNFdmVudC50eXBlICE9ICd0b3VjaGNhbmNlbCcpIHtcbiAgICAgIC8vIHByZXZpb3VzIGdlc3R1cmUsIGZvciB0aGUgZG91YmxlIHRhcCBzaW5jZSB0aGVzZSBhcmUgdHdvIGRpZmZlcmVudCBnZXN0dXJlIGRldGVjdGlvbnNcbiAgICAgIHZhciBwcmV2ID0gSGFtbWVyLmRldGVjdGlvbi5wcmV2aW91cyxcbiAgICAgICAgZGlkX2RvdWJsZXRhcCA9IGZhbHNlO1xuXG4gICAgICAvLyB3aGVuIHRoZSB0b3VjaHRpbWUgaXMgaGlnaGVyIHRoZW4gdGhlIG1heCB0b3VjaCB0aW1lXG4gICAgICAvLyBvciB3aGVuIHRoZSBtb3ZpbmcgZGlzdGFuY2UgaXMgdG9vIG11Y2hcbiAgICAgIGlmKEhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5yZWFjaGVkVGFwTWF4RGlzdGFuY2UgfHwgZXYuZGVsdGFUaW1lID4gaW5zdC5vcHRpb25zLnRhcF9tYXhfdG91Y2h0aW1lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gY2hlY2sgaWYgZG91YmxlIHRhcFxuICAgICAgaWYocHJldiAmJiBwcmV2Lm5hbWUgPT0gJ3RhcCcgJiZcbiAgICAgICAgKGV2LnRpbWVTdGFtcCAtIHByZXYubGFzdEV2ZW50LnRpbWVTdGFtcCkgPCBpbnN0Lm9wdGlvbnMuZG91YmxldGFwX2ludGVydmFsICYmXG4gICAgICAgIGV2LmRpc3RhbmNlIDwgaW5zdC5vcHRpb25zLmRvdWJsZXRhcF9kaXN0YW5jZSkge1xuICAgICAgICBpbnN0LnRyaWdnZXIoJ2RvdWJsZXRhcCcsIGV2KTtcbiAgICAgICAgZGlkX2RvdWJsZXRhcCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGRvIGEgc2luZ2xlIHRhcFxuICAgICAgaWYoIWRpZF9kb3VibGV0YXAgfHwgaW5zdC5vcHRpb25zLnRhcF9hbHdheXMpIHtcbiAgICAgICAgSGFtbWVyLmRldGVjdGlvbi5jdXJyZW50Lm5hbWUgPSAndGFwJztcbiAgICAgICAgaW5zdC50cmlnZ2VyKEhhbW1lci5kZXRlY3Rpb24uY3VycmVudC5uYW1lLCBldik7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFRvdWNoXG4gKiBDYWxsZWQgYXMgZmlyc3QsIHRlbGxzIHRoZSB1c2VyIGhhcyB0b3VjaGVkIHRoZSBzY3JlZW5cbiAqIEBldmVudHMgIHRvdWNoXG4gKi9cbkhhbW1lci5nZXN0dXJlcy5Ub3VjaCA9IHtcbiAgbmFtZSAgICA6ICd0b3VjaCcsXG4gIGluZGV4ICAgOiAtSW5maW5pdHksXG4gIGRlZmF1bHRzOiB7XG4gICAgLy8gY2FsbCBwcmV2ZW50RGVmYXVsdCBhdCB0b3VjaHN0YXJ0LCBhbmQgbWFrZXMgdGhlIGVsZW1lbnQgYmxvY2tpbmcgYnlcbiAgICAvLyBkaXNhYmxpbmcgdGhlIHNjcm9sbGluZyBvZiB0aGUgcGFnZSwgYnV0IGl0IGltcHJvdmVzIGdlc3R1cmVzIGxpa2VcbiAgICAvLyB0cmFuc2Zvcm1pbmcgYW5kIGRyYWdnaW5nLlxuICAgIC8vIGJlIGNhcmVmdWwgd2l0aCB1c2luZyB0aGlzLCBpdCBjYW4gYmUgdmVyeSBhbm5veWluZyBmb3IgdXNlcnMgdG8gYmUgc3R1Y2tcbiAgICAvLyBvbiB0aGUgcGFnZVxuICAgIHByZXZlbnRfZGVmYXVsdCAgICA6IGZhbHNlLFxuXG4gICAgLy8gZGlzYWJsZSBtb3VzZSBldmVudHMsIHNvIG9ubHkgdG91Y2ggKG9yIHBlbiEpIGlucHV0IHRyaWdnZXJzIGV2ZW50c1xuICAgIHByZXZlbnRfbW91c2VldmVudHM6IGZhbHNlXG4gIH0sXG4gIGhhbmRsZXIgOiBmdW5jdGlvbiB0b3VjaEdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICBpZihpbnN0Lm9wdGlvbnMucHJldmVudF9tb3VzZWV2ZW50cyAmJiBldi5wb2ludGVyVHlwZSA9PSBIYW1tZXIuUE9JTlRFUl9NT1VTRSkge1xuICAgICAgZXYuc3RvcERldGVjdCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmKGluc3Qub3B0aW9ucy5wcmV2ZW50X2RlZmF1bHQpIHtcbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYoZXYuZXZlbnRUeXBlID09IEhhbW1lci5FVkVOVF9TVEFSVCkge1xuICAgICAgaW5zdC50cmlnZ2VyKHRoaXMubmFtZSwgZXYpO1xuICAgIH1cbiAgfVxufTtcblxuXG4vKipcbiAqIFRyYW5zZm9ybVxuICogVXNlciB3YW50IHRvIHNjYWxlIG9yIHJvdGF0ZSB3aXRoIDIgZmluZ2Vyc1xuICogQGV2ZW50cyAgdHJhbnNmb3JtLCBwaW5jaCwgcGluY2hpbiwgcGluY2hvdXQsIHJvdGF0ZVxuICovXG5IYW1tZXIuZ2VzdHVyZXMuVHJhbnNmb3JtID0ge1xuICBuYW1lICAgICA6ICd0cmFuc2Zvcm0nLFxuICBpbmRleCAgICA6IDQ1LFxuICBkZWZhdWx0cyA6IHtcbiAgICAvLyBmYWN0b3IsIG5vIHNjYWxlIGlzIDEsIHpvb21pbiBpcyB0byAwIGFuZCB6b29tb3V0IHVudGlsIGhpZ2hlciB0aGVuIDFcbiAgICB0cmFuc2Zvcm1fbWluX3NjYWxlICAgOiAwLjAxLFxuICAgIC8vIHJvdGF0aW9uIGluIGRlZ3JlZXNcbiAgICB0cmFuc2Zvcm1fbWluX3JvdGF0aW9uOiAxLFxuICAgIC8vIHByZXZlbnQgZGVmYXVsdCBicm93c2VyIGJlaGF2aW9yIHdoZW4gdHdvIHRvdWNoZXMgYXJlIG9uIHRoZSBzY3JlZW5cbiAgICAvLyBidXQgaXQgbWFrZXMgdGhlIGVsZW1lbnQgYSBibG9ja2luZyBlbGVtZW50XG4gICAgLy8gd2hlbiB5b3UgYXJlIHVzaW5nIHRoZSB0cmFuc2Zvcm0gZ2VzdHVyZSwgaXQgaXMgYSBnb29kIHByYWN0aWNlIHRvIHNldCB0aGlzIHRydWVcbiAgICB0cmFuc2Zvcm1fYWx3YXlzX2Jsb2NrOiBmYWxzZVxuICB9LFxuICB0cmlnZ2VyZWQ6IGZhbHNlLFxuICBoYW5kbGVyICA6IGZ1bmN0aW9uIHRyYW5zZm9ybUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAvLyBjdXJyZW50IGdlc3R1cmUgaXNudCBkcmFnLCBidXQgZHJhZ2dlZCBpcyB0cnVlXG4gICAgLy8gdGhpcyBtZWFucyBhbiBvdGhlciBnZXN0dXJlIGlzIGJ1c3kuIG5vdyBjYWxsIGRyYWdlbmRcbiAgICBpZihIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQubmFtZSAhPSB0aGlzLm5hbWUgJiYgdGhpcy50cmlnZ2VyZWQpIHtcbiAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUgKyAnZW5kJywgZXYpO1xuICAgICAgdGhpcy50cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhdGxlYXN0IG11bHRpdG91Y2hcbiAgICBpZihldi50b3VjaGVzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBwcmV2ZW50IGRlZmF1bHQgd2hlbiB0d28gZmluZ2VycyBhcmUgb24gdGhlIHNjcmVlblxuICAgIGlmKGluc3Qub3B0aW9ucy50cmFuc2Zvcm1fYWx3YXlzX2Jsb2NrKSB7XG4gICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIHN3aXRjaChldi5ldmVudFR5cGUpIHtcbiAgICAgIGNhc2UgSGFtbWVyLkVWRU5UX1NUQVJUOlxuICAgICAgICB0aGlzLnRyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBIYW1tZXIuRVZFTlRfTU9WRTpcbiAgICAgICAgdmFyIHNjYWxlX3RocmVzaG9sZCA9IE1hdGguYWJzKDEgLSBldi5zY2FsZSk7XG4gICAgICAgIHZhciByb3RhdGlvbl90aHJlc2hvbGQgPSBNYXRoLmFicyhldi5yb3RhdGlvbik7XG5cbiAgICAgICAgLy8gd2hlbiB0aGUgZGlzdGFuY2Ugd2UgbW92ZWQgaXMgdG9vIHNtYWxsIHdlIHNraXAgdGhpcyBnZXN0dXJlXG4gICAgICAgIC8vIG9yIHdlIGNhbiBiZSBhbHJlYWR5IGluIGRyYWdnaW5nXG4gICAgICAgIGlmKHNjYWxlX3RocmVzaG9sZCA8IGluc3Qub3B0aW9ucy50cmFuc2Zvcm1fbWluX3NjYWxlICYmXG4gICAgICAgICAgcm90YXRpb25fdGhyZXNob2xkIDwgaW5zdC5vcHRpb25zLnRyYW5zZm9ybV9taW5fcm90YXRpb24pIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3ZSBhcmUgdHJhbnNmb3JtaW5nIVxuICAgICAgICBIYW1tZXIuZGV0ZWN0aW9uLmN1cnJlbnQubmFtZSA9IHRoaXMubmFtZTtcblxuICAgICAgICAvLyBmaXJzdCB0aW1lLCB0cmlnZ2VyIGRyYWdzdGFydCBldmVudFxuICAgICAgICBpZighdGhpcy50cmlnZ2VyZWQpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIodGhpcy5uYW1lICsgJ3N0YXJ0JywgZXYpO1xuICAgICAgICAgIHRoaXMudHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTsgLy8gYmFzaWMgdHJhbnNmb3JtIGV2ZW50XG5cbiAgICAgICAgLy8gdHJpZ2dlciByb3RhdGUgZXZlbnRcbiAgICAgICAgaWYocm90YXRpb25fdGhyZXNob2xkID4gaW5zdC5vcHRpb25zLnRyYW5zZm9ybV9taW5fcm90YXRpb24pIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIoJ3JvdGF0ZScsIGV2KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHRyaWdnZXIgcGluY2ggZXZlbnRcbiAgICAgICAgaWYoc2NhbGVfdGhyZXNob2xkID4gaW5zdC5vcHRpb25zLnRyYW5zZm9ybV9taW5fc2NhbGUpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIoJ3BpbmNoJywgZXYpO1xuICAgICAgICAgIGluc3QudHJpZ2dlcigncGluY2gnICsgKChldi5zY2FsZSA8IDEpID8gJ2luJyA6ICdvdXQnKSwgZXYpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEhhbW1lci5FVkVOVF9FTkQ6XG4gICAgICAgIC8vIHRyaWdnZXIgZHJhZ2VuZFxuICAgICAgICBpZih0aGlzLnRyaWdnZXJlZCkge1xuICAgICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUgKyAnZW5kJywgZXYpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuXG4gIC8vIEJhc2VkIG9mZiBMby1EYXNoJ3MgZXhjZWxsZW50IFVNRCB3cmFwcGVyIChzbGlnaHRseSBtb2RpZmllZCkgLSBodHRwczovL2dpdGh1Yi5jb20vYmVzdGllanMvbG9kYXNoL2Jsb2IvbWFzdGVyL2xvZGFzaC5qcyNMNTUxNS1MNTU0M1xuICAvLyBzb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBzcGVjaWZpYyBjb25kaXRpb24gcGF0dGVybnMgbGlrZSB0aGUgZm9sbG93aW5nOlxuICBpZih0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIGRlZmluZSBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkgeyByZXR1cm4gSGFtbWVyOyB9KTtcbiAgfVxuXG4gIC8vIGNoZWNrIGZvciBgZXhwb3J0c2AgYWZ0ZXIgYGRlZmluZWAgaW4gY2FzZSBhIGJ1aWxkIG9wdGltaXplciBhZGRzIGFuIGBleHBvcnRzYCBvYmplY3RcbiAgZWxzZSBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gSGFtbWVyO1xuICB9XG5cbiAgZWxzZSB7XG4gICAgd2luZG93LkhhbW1lciA9IEhhbW1lcjtcbiAgfVxuXG59KSh3aW5kb3cpO1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH1cbiAgICAgIHRocm93IFR5cGVFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4nKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIHZhciBtO1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gMDtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbihlbWl0dGVyLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IDE7XG4gIGVsc2VcbiAgICByZXQgPSBlbWl0dGVyLl9ldmVudHNbdHlwZV0ubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuIl19 diff --git a/SinglePlayer - Games/Skii Game/dist/skifree.min.js b/SinglePlayer - Games/Skii Game/dist/skifree.min.js new file mode 100644 index 00000000..e2e70f7d --- /dev/null +++ b/SinglePlayer - Games/Skii Game/dist/skifree.min.js @@ -0,0 +1,2 @@ +(function e(t,n,r){function i(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(s)return s(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 i(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var s=typeof require=="function"&&require;for(var o=0;o2?i=.1:i+=.1;if(e>=0)return"sEast"+Math.ceil(i);if(e<0)return"sWest"+Math.ceil(i)};return n(e,r())},t.startEating=u,t}e.monster=t})(this),typeof t!="undefined"&&(t.exports=this.monster)},{"./sprite":11}],8:[function(e,t,n){(function(){var e,t=function(){},n=["assert","clear","count","debug","dir","dirxml","error","exception","group","groupCollapsed","groupEnd","info","log","markTimeline","profile","profileEnd","table","time","timeEnd","timeStamp","trace","warn"],r=n.length,i=window.console=window.console||{};while(r--)e=n[r],i[e]||(i[e]=t)})()},{}],9:[function(e,t,n){var r=e("./sprite");typeof navigator!="undefined"?navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate:navigator={vibrate:!1},function(e){function t(e){function b(){n.setSpeed(c),n.isMoving=!0,n.hasBeenHit=!1,n.isJumping=!1,n.isPerformingTrick=!1,u&&clearInterval(u),n.setMapPosition(undefined,undefined,0)}function w(){n.isMoving=!1,n.hasBeenHit=!0,n.isJumping=!1,n.isPerformingTrick=!1,u&&clearInterval(u),n.setMapPosition(undefined,undefined,0)}function E(){var e=n.getSpeed();n.setSpeed(e+2),n.setSpeedY(e+2),n.isMoving=!0,n.hasBeenHit=!1,n.isJumping=!0,n.setMapPosition(undefined,undefined,1)}function S(){if(n.direction)return n.direction<=90?"east":n.direction>90&&n.direction<150?"esEast":n.direction>=150&&n.direction<180?"sEast":n.direction===180?"south":n.direction>180&&n.direction<=210?"sWest":n.direction>210&&n.direction<270?"wsWest":n.direction>=270?"west":"south";var e=n.movingToward[0]-n.mapPosition[0],t=n.movingToward[1]-n.mapPosition[1];return t<=0?e>0?"east":"west":s.esEast(e)?"esEast":s.sEast(e)?"sEast":s.wsWest(e)?"wsWest":s.sWest(e)?"sWest":"south"}function x(e){t[e]&&n.setDirection(t[e]),e==="west"||e==="east"?n.isMoving=!1:n.isMoving=!0}function T(){return"blank"}function N(){return"jumping"}function C(){return console.log("Trick step is",y),y===0?"jumping":y===1?"somersault1":"somersault2"}function k(e,t,r){return r===0||r===1?t:(et&&(e-=n.getSpeed()*(r/p)),e)}var t={west:270,wsWest:240,sWest:195,south:180,sEast:165,esEast:120,east:90},n=new r(e),i={draw:n.superior("draw"),cycle:n.superior("cycle"),getSpeedX:n.superior("getSpeedX"),getSpeedY:n.superior("getSpeedY"),hits:n.superior("hits")},s={esEast:function(e){return e>300},sEast:function(e){return e>75},wsWest:function(e){return e<-300},sWest:function(e){return e<-75}},o,u,a=!0,f=[],l=0,c=5,h=2,p=70,d=0,v=0,m=0,g=1,y=0;return n.isMoving=!0,n.hasBeenHit=!1,n.isJumping=!1,n.isPerformingTrick=!1,n.onHitObstacleCb=function(){},n.setSpeed(c),n.reset=function(){f=[],l=0,n.isMoving=!0,n.hasBeenHit=!1,a=!0,b()},n.stop=function(){n.direction>180?x("west"):x("east")},n.turnEast=function(){var e=S();switch(e){case"west":x("wsWest");break;case"wsWest":x("sWest");break;case"sWest":x("south");break;case"south":x("sEast");break;case"sEast":x("esEast");break;case"esEast":x("east");break;default:x("south")}},n.turnWest=function(){var e=S();switch(e){case"east":x("esEast");break;case"esEast":x("sEast");break;case"sEast":x("south");break;case"south":x("sWest");break;case"sWest":x("wsWest");break;case"wsWest":x("west");break;default:x("south")}},n.stepWest=function(){n.mapPosition[0]-=n.speed*2},n.stepEast=function(){n.mapPosition[0]+=n.speed*2},n.setMapPositionTarget=function(e,t){if(n.hasBeenHit)return;Math.abs(n.mapPosition[0]-e)<=75&&(e=n.mapPosition[0]),n.movingToward=[e,t]},n.startMovingIfPossible=function(){!n.hasBeenHit&&!n.isBeingEaten&&(n.isMoving=!0)},n.setTurnEaseCycles=function(e){p=e},n.getPixelsTravelledDownMountain=function(){return l},n.resetSpeed=function(){n.setSpeed(c)},n.cycle=function(){n.getSpeedX()<=0&&n.getSpeedY()<=0&&(n.isMoving=!1),n.isMoving&&(l+=n.speed),n.isJumping&&n.setMapPositionTarget(undefined,n.mapPosition[1]+n.getSpeed()),i.cycle(),n.checkHittableObjects()},n.draw=function(e){var t=function(){return n.isBeingEaten?T():n.isJumping?n.isPerformingTrick?C():N():n.hasBeenHit?"hit":S()};return i.draw(e,t())},n.hits=function(e){return f.indexOf(e.id)!==-1?!1:e.occupiesZIndex(n.mapPosition[2])?i.hits(e)?!0:!1:!1},n.speedBoost=function(){var e=n.speed;a&&(a=!1,n.setSpeed(n.speed*h),setTimeout(function(){n.setSpeed(e),setTimeout(function(){a=!0},1e4)},2e3))},n.attemptTrick=function(){n.isJumping&&(n.isPerformingTrick=!0,u=setInterval(function(){y>=2?y=0:y+=1},300))},n.getStandardSpeed=function(){return c},n.getSpeedX=function(){return S()==="esEast"||S()==="wsWest"?(v=.5,d=k(d,n.getSpeed()*v,v),d):S()==="sEast"||S()==="sWest"?(v=.33,d=k(d,n.getSpeed()*v,v),d):(d=k(d,0,v),d)},n.setSpeedY=function(e){m=e},n.getSpeedY=function(){var e;return n.isJumping?m:S()==="esEast"||S()==="wsWest"?(g=.6,m=k(m,n.getSpeed()*.6,.6),m):S()==="sEast"||S()==="sWest"?(g=.85,m=k(m,n.getSpeed()*.85,.85),m):S()==="east"||S()==="west"?(g=1,m=0,m):(m=k(m,n.getSpeed(),g),m)},n.hasHitObstacle=function(e){w(),navigator.vibrate&&navigator.vibrate(500),f.push(e.id),n.resetSpeed(),n.onHitObstacleCb(e),o&&clearTimeout(o),o=setTimeout(function(){b()},1500)},n.hasHitJump=function(){E(),o&&clearTimeout(o),o=setTimeout(function(){b()},1e3)},n.isEatenBy=function(e,t){n.hasHitObstacle(e),e.startEating(t),f.push(e.id),n.isMoving=!1,n.isBeingEaten=!0},n.reset=function(){f=[],l=0,n.isMoving=!0,n.isJumping=!1,n.hasBeenHit=!1,a=!0},n.setHitObstacleCb=function(e){n.onHitObstacleCb=e||function(){}},n}e.skier=t}(this),typeof t!="undefined"&&(t.exports=this.skier)},{"./sprite":11}],10:[function(e,t,n){var r=e("./sprite");(function(e){function t(e){function o(){var e=t.movingToward[0]-t.mapPosition[0],n=t.movingToward[1]-t.mapPosition[1];return i.sEast(e)?"sEast":"sWest"}var t=new r(e),n={draw:t.superior("draw"),cycle:t.superior("cycle")},i={sEast:function(e){return e>0},sWest:function(e){return e<=0}},s=3;return t.setSpeed(s),t.cycle=function(e){Number.random(10)===1&&(t.setMapPositionTarget(e.getRandomlyInTheCentreOfMap()),t.setSpeed(s+Number.random(-1,1))),t.setMapPositionTarget(undefined,e.getMapBelowViewport()+600),n.cycle()},t.draw=function(e){var t=function(){return o()};return n.draw(e,t())},t}e.snowboarder=t})(this),typeof t!="undefined"&&(t.exports=this.snowboarder)},{"./sprite":11}],11:[function(e,t,n){(function(t){function r(e){function o(e){i.canvasX+=e.toNumber()}function u(e){i.canvasY+=e.toNumber()}function a(t){if(i.data.hitBoxes&&e.hitBoxes[t])return e.hitBoxes[t]}function f(e){return e=Math.round(e*2)/2,e}function l(){if(!i.isMoving)return;var e=i.mapPosition[0],t=i.mapPosition[1];if(typeof i.direction!="undefined"){var n=i.direction-90;n<0&&(n=360+n),e+=f(i.speed*Math.cos(n*(Math.PI/180))),t+=f(i.speed*Math.sin(n*(Math.PI/180)))}else typeof i.movingToward[0]!="undefined"&&(e>i.movingToward[0]?e-=Math.min(i.getSpeedX(),Math.abs(e-i.movingToward[0])):ei.movingToward[1]?t-=Math.min(i.getSpeedY(),Math.abs(t-i.movingToward[1])):t75?0-e:0,r=-t;return[n,r]},this.checkHittableObjects=function(){Object.keys(t,function(e,n){n.object.deleted?delete t[e]:n.object.hits(i)&&n.callbacks.each(function(e){e(i,n.object)})})},this.cycle=function(){i.checkHittableObjects(),s&&i.setMapPositionTarget(s.mapPosition[0],s.mapPosition[1],!0),l()},this.setMapPositionTarget=function(e,t,n){n&&(i.movingWithConviction=!1),i.movingWithConviction||(typeof e=="undefined"&&(e=i.movingToward[0]),typeof t=="undefined"&&(t=i.movingToward[1]),i.movingToward=[e,t],i.movingWithConviction=!1)},this.setDirection=function(e){e>=360&&(e=360-e),i.direction=e,i.movingToward=undefined},this.resetDirection=function(){i.direction=undefined},this.setMapPositionTargetWithConviction=function(e,t){i.setMapPositionTarget(e,t),i.movingWithConviction=!0},this.follow=function(e){s=e},this.stopFollowing=function(){s=!1},this.onHitting=function(e,n){if(t[e.id])return t[e.id].callbacks.push(n);t[e.id]={object:e,callbacks:[n]}},this.deleteOnNextCycle=function(){i.deleted=!0},this.occupiesZIndex=function(e){return r.indexOf(e)>=0},this.hits=function(e){var t=!1,n=!1;return e.getTopHitBoxEdge(i.mapPosition[2])<=i.getBottomHitBoxEdge(i.mapPosition[2])&&e.getBottomHitBoxEdge(i.mapPosition[2])>=i.getBottomHitBoxEdge(i.mapPosition[2])&&(t=!0),e.getTopHitBoxEdge(i.mapPosition[2])<=i.getTopHitBoxEdge(i.mapPosition[2])&&e.getBottomHitBoxEdge(i.mapPosition[2])>=i.getTopHitBoxEdge(i.mapPosition[2])&&(t=!0),e.getLeftHitBoxEdge(i.mapPosition[2])<=i.getRightHitBoxEdge(i.mapPosition[2])&&e.getRightHitBoxEdge(i.mapPosition[2])>=i.getRightHitBoxEdge(i.mapPosition[2])&&(n=!0),e.getLeftHitBoxEdge(i.mapPosition[2])<=i.getLeftHitBoxEdge(i.mapPosition[2])&&e.getRightHitBoxEdge(i.mapPosition[2])>=i.getLeftHitBoxEdge(i.mapPosition[2])&&(n=!0),t&&n},this.isAboveOnCanvas=function(e){return i.canvasY+i.heighte},i}var n=e("./guid");r.createObjects=function(t,n){function i(e){var t=n.position;if(Number.random(100+n.rateModifier)<=e.dropRate){var i=new r(e.sprite);return i.setSpeed(0),Object.isFunction(t)&&(t=t()),i.setMapPosition(t[0],t[1]),e.sprite.hitBehaviour&&e.sprite.hitBehaviour.skier&&n.player&&i.onHitting(n.player,e.sprite.hitBehaviour.skier),i}}Array.isArray(t)||(t=[t]),n=Object.merge(n,{rateModifier:0,dropRate:1,position:[0,0]},!1,!1);var s=t.map(i).remove(undefined);return s},t.sprite=r})(this),typeof t!="undefined"&&(t.exports=this.sprite)},{"./guid":4}],12:[function(e,t,n){(function(e){function t(){return this.pushHandlers=[],this}t.prototype=Object.create(Array.prototype),t.prototype.onPush=function(e,t){this.pushHandlers.push(e),t&&this.each(e)},t.prototype.push=function(e){Array.prototype.push.call(this,e),this.pushHandlers.each(function(t){t(e)})},t.prototype.cull=function(){this.each(function(e,t){if(e.deleted)return delete this[t]})},e.spriteArray=t})(this),typeof t!="undefined"&&(t.exports=this.spriteArray)},{}],13:[function(e,t,n){function C(e,t){function i(){n+=1,n===e.length&&t(r)}var n=0,r={};e.each(function(e){var t=new Image;t.onload=i,t.src=e,d.storeLoadedImage(e,t)})}function k(e,t){t.isEatenBy(e,function(){S-=1,e.isFull=!0,e.isEating=!1,t.isBeingEaten=!1,e.setSpeed(t.getSpeed()),e.stopFollowing();var n=d.getRandomMapPositionAboveViewport();e.setMapPositionTarget(n[0],n[1])})}function L(e){function v(){w=0,S=5,x=localStorage.getItem("highScore"),o.reset(),o.addStaticObject(n)}function m(){o.isPaused()||(x=localStorage.setItem("highScore",w),s.setLines(["Game over!","Hit space to restart"]),o.pause(),o.cycle())}function C(e,t){var n=Math.max(800-p.width,0);Number.random(1e3+n)<=t&&e()}function L(){var e=new u(y.monster),n=d.getRandomMapPositionAboveViewport();e.setMapPosition(n[0],n[1]),e.follow(t),e.setSpeed(t.getStandardSpeed()),e.onHitting(t,k),o.addMovingObject(e,"monster")}function A(){var e=new f(y.snowboarder),n=d.getRandomMapPositionAboveViewport(),r=d.getRandomMapPositionBelowViewport();e.setMapPosition(n[0],n[1]),e.setMapPositionTarget(r[0],r[1]),e.onHitting(t,y.snowboarder.hitBehaviour.skier),o.addMovingObject(e)}var t,n,s,o;t=new l(y.skier),t.setMapPosition(0,0),t.setMapPositionTarget(0,-10),T&&t.setHitObstacleCb(function(){S-=1}),o=new h(p,t),n=new a(y.signStart),o.addStaticObject(n),n.setMapPosition(-50,0),d.followSprite(t),s=new c({initialLines:["SkiFree.js",g,"Travelled 0m","High Score: "+x,"Skiers left: "+S,"Created by Dan Hough (@basicallydan)"],position:{top:15,right:10}}),o.beforeCycle(function(){var e=[];t.isMoving&&(e=a.createObjects([{sprite:y.smallTree,dropRate:N.smallTree},{sprite:y.tallTree,dropRate:N.tallTree},{sprite:y.jump,dropRate:N.jump},{sprite:y.thickSnow,dropRate:N.thickSnow},{sprite:y.rock,dropRate:N.rock}],{rateModifier:Math.max(800-p.width,0),position:function(){return d.getRandomMapPositionBelowViewport()},player:t})),o.isPaused()||(o.addStaticObjects(e),C(A,.1),w=parseFloat(t.getPixelsTravelledDownMountain()/b).toFixed(1),w>E&&C(L,.001),s.setLines(["SkiFree.js",g,"Travelled "+w+"m","Skiers left: "+S,"High Score: "+x,"Created by Dan Hough (@basicallydan)","Current Speed: "+t.getSpeed()]))}),o.afterCycle(function(){S===0&&m()}),o.addUIElement(s),$(p).mousemove(function(e){o.setMouseX(e.pageX),o.setMouseY(e.pageY),t.resetDirection(),t.startMovingIfPossible()}).bind("click",function(e){o.setMouseX(e.pageX),o.setMouseY(e.pageY),t.resetDirection(),t.startMovingIfPossible()}).focus(),i.bind("f",t.speedBoost),i.bind("t",t.attemptTrick),i.bind(["w","up"],function(){t.stop()}),i.bind(["a","left"],function(){t.direction===270?t.stepWest():t.turnWest()}),i.bind(["s","down"],function(){t.setDirection(180),t.startMovingIfPossible()}),i.bind(["d","right"],function(){t.direction===90?t.stepEast():t.turnEast()}),i.bind("m",L),i.bind("b",A),i.bind("space",v);var O=r(p).on("press",function(e){e.preventDefault(),o.setMouseX(e.center.x),o.setMouseY(e.center.y)}).on("tap",function(e){o.setMouseX(e.center.x),o.setMouseY(e.center.y)}).on("pan",function(e){o.setMouseX(e.center.x),o.setMouseY(e.center.y),t.resetDirection(),t.startMovingIfPossible()}).on("doubletap",function(e){t.speedBoost()});t.isMoving=!1,t.setDirection(270),o.start()}function A(){p.width=window.innerWidth,p.height=window.innerHeight}e("./lib/canvasRenderingContext2DExtensions"),e("./lib/extenders"),e("./lib/plugins");var r=e("hammerjs"),i=e("br-mousetrap"),s=e("./lib/isMobileDevice"),o=e("./lib/spriteArray"),u=e("./lib/monster"),a=e("./lib/sprite"),f=e("./lib/snowboarder"),l=e("./lib/skier"),c=e("./lib/infoBox"),h=e("./lib/game"),p=document.getElementById("skifree-canvas"),d=p.getContext("2d"),v=["sprite-characters.png","skifree-objects.png"],m=this,g="Use the mouse or WASD to control the player";s()&&(g="Tap or drag on the piste to control the player");var y=e("./spriteInfo"),b=18,w=0,E=2e3,S=5,x=0,T=!1,N={smallTree:4,tallTree:2,jump:1,thickSnow:1,rock:1};localStorage.getItem("highScore")&&(x=localStorage.getItem("highScore")),window.addEventListener("resize",A,!1),A(),C(v,L),this.exports=window},{"./lib/canvasRenderingContext2DExtensions":1,"./lib/extenders":2,"./lib/game":3,"./lib/infoBox":5,"./lib/isMobileDevice":6,"./lib/monster":7,"./lib/plugins":8,"./lib/skier":9,"./lib/snowboarder":10,"./lib/sprite":11,"./lib/spriteArray":12,"./spriteInfo":14,"br-mousetrap":15,hammerjs:18}],14:[function(e,t,n){(function(e){function n(e){e.deleteOnNextCycle()}function r(e,t){t.deleteOnNextCycle()}function i(e,t){e.hasHitObstacle(t)}function s(e,t){t.hasHitObstacle(e)}function o(e,t){t.hasHitObstacle(e)}function u(e,t){e.hasHitJump(t)}function a(e,t){t.hasHitJump(e)}function f(e,t){t.hasHitObstacle(e)}var t={skier:{$imageFile:"sprite-characters.png",parts:{blank:[0,0,0,0],east:[0,0,24,34],esEast:[24,0,24,34],sEast:[49,0,17,34],south:[65,0,17,34],sWest:[49,37,17,34],wsWest:[24,37,24,34],west:[0,37,24,34],hit:[0,78,31,31],jumping:[84,0,32,34],somersault1:[116,0,32,34],somersault2:[148,0,32,34]},hitBoxes:{0:[7,20,27,34]},id:"player",hitBehaviour:{}},smallTree:{$imageFile:"skifree-objects.png",parts:{main:[0,28,30,34]},hitBoxes:{0:[0,18,30,34]},hitBehaviour:{}},tallTree:{$imageFile:"skifree-objects.png",parts:{main:[95,66,32,64]},zIndexesOccupied:[0,1],hitBoxes:{0:[0,54,32,64],1:[0,10,32,54]},hitBehaviour:{}},thickSnow:{$imageFile:"skifree-objects.png",parts:{main:[143,53,43,10]},hitBehaviour:{}},rock:{$imageFile:"skifree-objects.png",parts:{main:[30,52,23,11]},hitBehaviour:{}},monster:{$imageFile:"sprite-characters.png",parts:{sEast1:[64,112,26,43],sEast2:[90,112,32,43],sWest1:[64,158,26,43],sWest2:[90,158,32,43],eating1:[122,112,34,43],eating2:[156,112,31,43],eating3:[187,112,31,43],eating4:[219,112,25,43],eating5:[243,112,26,43]},hitBehaviour:{}},jump:{$imageFile:"skifree-objects.png",parts:{main:[109,55,32,8]},hitBehaviour:{}},signStart:{$imageFile:"skifree-objects.png",parts:{main:[260,103,42,27]},hitBehaviour:{}},snowboarder:{$imageFile:"sprite-characters.png",parts:{sEast:[73,229,20,29],sWest:[95,228,26,30]},hitBehaviour:{}},emptyChairLift:{$imageFile:"skifree-objects.png",parts:{main:[92,136,26,30]},zIndexesOccupied:[1]}};t.monster.hitBehaviour.tree=n,t.smallTree.hitBehaviour.monster=r,t.tallTree.hitBehaviour.monster=r,t.smallTree.hitBehaviour.skier=s,t.tallTree.hitBehaviour.skier=s,t.rock.hitBehaviour.skier=o,t.jump.hitBehaviour.skier=a,t.snowboarder.hitBehaviour.skier=f,e.spriteInfo=t})(this),typeof t!="undefined"&&(t.exports=this.spriteInfo)},{}],15:[function(e,t,n){(function(){function p(e,t,n){if(e.addEventListener){e.addEventListener(t,n,!1);return}e.attachEvent("on"+t,n)}function d(t){return t.type=="keypress"?String.fromCharCode(t.which):e[t.which]?e[t.which]:n[t.which]?n[t.which]:String.fromCharCode(t.which).toLowerCase()}function v(e,t){return e.sort().join(",")===t.sort().join(",")}function m(e){e=e||{};var t=!1,n;for(n in a){if(e[n]){t=!0;continue}a[n]=0}t||(c=!1)}function g(e,t,n,r,i){var s,u,f=[],l=n.type;if(!o[e])return[];l=="keyup"&&S(e)&&(t=[e]);for(s=0;s95&&t<112)continue;e.hasOwnProperty(t)&&(s[e[t]]=t)}}return s}function N(e,t,n){return n||(n=T()[e]?"keydown":"keypress"),n=="keypress"&&t.length&&(n="keydown"),n}function C(e,t,n,r){a[e]=0,r||(r=N(t[0],[]));var i=function(t){c=r,++a[e],x()},s=function(e){b(n,e),r!=="keyup"&&(l=d(e)),setTimeout(m,10)},o;for(o=0;o1){C(e,a,t,n);return}c=e==="+"?["+"]:e.split("+");for(f=0;f":".","?":"/","|":"\\"},i={option:"alt",command:"meta","return":"enter",escape:"esc"},s,o={},u={},a={},f,l=!1,c=!1;for(var h=1;h<20;++h)e[111+h]="f"+h;for(h=0;h<=9;++h)e[h+96]=h;p(document,"keypress",E),p(document,"keydown",E),p(document,"keyup",E);var A={bind:function(e,t,n){return L(e instanceof Array?e:[e],t,n),u[e+":"+n]=t,this},unbind:function(e,t){return u[e+":"+t]&&(delete u[e+":"+t],this.bind(e,function(){},t)),this},trigger:function(e,t){return u[e+":"+t](),this},reset:function(){return o={},u={},this},stopCallback:function(e,t){return(" "+t.className+" ").indexOf(" mousetrap ")>-1?!1:t.tagName=="INPUT"||t.tagName=="SELECT"||t.tagName=="TEXTAREA"||t.contentEditable&&t.contentEditable=="true"}};window.Mousetrap=A,typeof define=="function"&&define.amd&&define("mousetrap",function(){return A}),typeof t=="object"&&t.exports&&(t.exports=A)})()},{}],16:[function(e,t,n){(function(r){(function(){function a(e){var t=1,n=o.min(e);while(t!==0)t=o.reduce(e,function(e,t){return e+t%n},0),t!==0&&(n-=10);return n}function f(e){var t=u.exec(e);if(!t)throw new Error("I don't understand that particular interval");var n=+t[1],r=t[2]||"ms";if(r==="s")n*=1e3;else if(r==="m")n=n*1e3*60;else if(r==="h")n=n*1e3*60*60;else if(!!r&&r!=="ms")throw new Error("You can only specify intervals of ms, s, m, or h");if(n<10||n%10!==0)throw new Error("You can only specify 10s of milliseconds, trust me on this one");return{amount:n,type:r}}function l(){this.intervalId=undefined,this.intervalLength=undefined,this.intervalsToEmit={},this.currentTick=1,this.maxTicks=0,this.listeningForFocus=!1;var e=function(){var e=a(o.keys(this.intervalsToEmit)),t=!1;return this.intervalLength?e!==this.intervalLength&&(this.intervalLength=e,t=!0):this.intervalLength=e,this.maxTicks=o.max(o.map(o.keys(this.intervalsToEmit),function(e){return+e}))/this.intervalLength,t}.bind(this);this.on("newListener",function(t){if(t==="removeListener"||t==="newListener")return;var n=f(t),r=n.amount;this.intervalsToEmit[+r]=o.union(this.intervalsToEmit[+r]||[],[t]),e()&&this.isStarted()&&this.stop().start()}),this.on("removeListener",function(t){if(s.listenerCount(this,t)>0)return;var n=f(t),r=n.amount,i=this.intervalsToEmit[+r].removeOne(t);this.intervalsToEmit[+r].length===0&&delete this.intervalsToEmit[+r],console.log("Determining interval length after removal of",i),e(),e()&&this.isStarted()&&this.stop().start()})}var i=this,s=e("events").EventEmitter,o=e("underscore"),u=/([0-9\.]+)(ms|s|m|h)?/,i=r||window;typeof Function.prototype.inherits=="undefined"&&(Function.prototype.inherits=function(e){this.prototype=Object.create(e.prototype)}),typeof Array.prototype.removeOne=="undefined"&&(Array.prototype.removeOne=function(){var e,t=arguments,n=t.length,r;while(n&&this.length){e=t[--n];while((r=this.indexOf(e))!==-1)return this.splice(r,1)}}),l.inherits(s),l.prototype.tick=function(){var e=this.currentTick*this.intervalLength;return o.each(this.intervalsToEmit,function(t,n){e%n===0&&o.each(t,function(e){this.emit(e,e,n)}.bind(this))}.bind(this)),this.currentTick+=1,this.currentTick>this.maxTicks&&(this.currentTick=1),this},l.prototype.start=function(){if(!this.intervalLength)throw new Error("You haven't specified any interval callbacks. Use EventedLoop.on('500ms', function () { ... }) to do so, and then you can start");return this.intervalId?console.log("No need to start the loop again, it's already started."):(this.intervalId=setInterval(this.tick.bind(this),this.intervalLength),i&&!this.listeningForFocus&&i.addEventListener&&(i.addEventListener("focus",function(){this.start()}.bind(this)),i.addEventListener("blur",function(){this.stop()}.bind(this)),this.listeningForFocus=!0),this)},l.prototype.stop=function(){return clearInterval(this.intervalId),this.intervalId=undefined,this},l.prototype.isStarted=function(){return!!this.intervalId},l.prototype.every=l.prototype.on,typeof n!="undefined"&&(typeof t!="undefined"&&t.exports&&(n=t.exports=l),n.EventedLoop=l),typeof window!="undefined"&&(window.EventedLoop=l)}).call(this)}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{events:19,underscore:17}],17:[function(e,t,n){(function(){var e=this,r=e._,i={},s=Array.prototype,o=Object.prototype,u=Function.prototype,a=s.push,f=s.slice,l=s.concat,c=o.toString,h=o.hasOwnProperty,p=s.forEach,d=s.map,v=s.reduce,m=s.reduceRight,g=s.filter,y=s.every,b=s.some,w=s.indexOf,E=s.lastIndexOf,S=Array.isArray,x=Object.keys,T=u.bind,N=function(e){if(e instanceof N)return e;if(!(this instanceof N))return new N(e);this._wrapped=e};typeof n!="undefined"?(typeof t!="undefined"&&t.exports&&(n=t.exports=N),n._=N):e._=N,N.VERSION="1.6.0";var C=N.each=N.forEach=function(e,t,n){if(e==null)return e;if(p&&e.forEach===p)e.forEach(t,n);else if(e.length===+e.length){for(var r=0,s=e.length;r2;e==null&&(e=[]);if(v&&e.reduce===v)return r&&(t=N.bind(t,r)),i?e.reduce(t,n +):e.reduce(t);C(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(k);return n},N.reduceRight=N.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(m&&e.reduceRight===m)return r&&(t=N.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=N.keys(e);s=o.length}C(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(k);return n},N.find=N.detect=function(e,t,n){var r;return L(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},N.filter=N.select=function(e,t,n){var r=[];return e==null?r:g&&e.filter===g?e.filter(t,n):(C(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},N.reject=function(e,t,n){return N.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},N.every=N.all=function(e,t,n){t||(t=N.identity);var r=!0;return e==null?r:y&&e.every===y?e.every(t,n):(C(e,function(e,s,o){if(!(r=r&&t.call(n,e,s,o)))return i}),!!r)};var L=N.some=N.any=function(e,t,n){t||(t=N.identity);var r=!1;return e==null?r:b&&e.some===b?e.some(t,n):(C(e,function(e,s,o){if(r||(r=t.call(n,e,s,o)))return i}),!!r)};N.contains=N.include=function(e,t){return e==null?!1:w&&e.indexOf===w?e.indexOf(t)!=-1:L(e,function(e){return e===t})},N.invoke=function(e,t){var n=f.call(arguments,2),r=N.isFunction(t);return N.map(e,function(e){return(r?t:e[t]).apply(e,n)})},N.pluck=function(e,t){return N.map(e,N.property(t))},N.where=function(e,t){return N.filter(e,N.matches(t))},N.findWhere=function(e,t){return N.find(e,N.matches(t))},N.max=function(e,t,n){if(!t&&N.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);var r=-Infinity,i=-Infinity;return C(e,function(e,s,o){var u=t?t.call(n,e,s,o):e;u>i&&(r=e,i=u)}),r},N.min=function(e,t,n){if(!t&&N.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);var r=Infinity,i=Infinity;return C(e,function(e,s,o){var u=t?t.call(n,e,s,o):e;ur||n===void 0)return 1;if(n>>1;n.call(r,e[u])=0;n--)t=[e[n].apply(this,t)];return t[0]}},N.after=function(e,t){return function(){if(--e<1)return t.apply(this,arguments)}},N.keys=function(e){if(!N.isObject(e))return[];if(x)return x(e);var t=[];for(var n in e)N.has(e,n)&&t.push(n);return t},N.values=function(e){var t=N.keys(e),n=t.length,r=new Array(n);for(var i=0;i":">",'"':""","'":"'"}};P.unescape=N.invert(P.escape);var H={escape:new RegExp("["+N.keys(P.escape).join("")+"]","g"),unescape:new RegExp("("+N.keys(P.unescape).join("|")+")","g")};N.each(["escape","unescape"],function(e){N[e]=function(t){return t==null?"":(""+t).replace(H[e],function(t){return P[e][t]})}}),N.result=function(e,t){if(e==null)return void 0;var n=e[t];return N.isFunction(n)?n.call(e):n},N.mixin=function(e){C(N.functions(e),function(t){var n=N[t]=e[t];N.prototype[t]=function(){var e=[this._wrapped];return a.apply(e,arguments),q.call(this,n.apply(N,e))}})};var B=0;N.uniqueId=function(e){var t=++B+"";return e?e+t:t},N.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var j=/(.)^/,F={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},I=/\\|'|\r|\n|\t|\u2028|\u2029/g;N.template=function(e,t,n){var r;n=N.defaults({},n,N.templateSettings);var i=new RegExp([(n.escape||j).source,(n.interpolate||j).source,(n.evaluate||j).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(I,function(e){return"\\"+F[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,N);var a=function(e){return r.call(this,e,N)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},N.chain=function(e){return N(e).chain()};var q=function(e){return this._chain?N(e).chain():e};N.mixin(N),C(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=s[e];N.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],q.call(this,n)}}),C(["concat","join","slice"],function(e){var t=s[e];N.prototype[e]=function(){return q.call(this,t.apply(this._wrapped,arguments))}}),N.extend(N.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}}),typeof define=="function"&&define.amd&&define("underscore",[],function(){return N})}).call(this)},{}],18:[function(e,t,n){(function(e,n){"use strict";function i(){if(r.READY)return;r.event.determineEventTypes(),r.utils.each(r.gestures,function(e){r.detection.register(e)}),r.event.onTouch(r.DOCUMENT,r.EVENT_MOVE,r.detection.detect),r.event.onTouch(r.DOCUMENT,r.EVENT_END,r.detection.detect),r.READY=!0}var r=function(e,t){return new r.Instance(e,t||{})};r.defaults={stop_browser_behavior:{userSelect:"none",touchAction:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},r.HAS_POINTEREVENTS=e.navigator.pointerEnabled||e.navigator.msPointerEnabled,r.HAS_TOUCHEVENTS="ontouchstart"in e,r.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android|silk/i,r.NO_MOUSEEVENTS=r.HAS_TOUCHEVENTS&&e.navigator.userAgent.match(r.MOBILE_REGEX),r.EVENT_TYPES={},r.DIRECTION_DOWN="down",r.DIRECTION_LEFT="left",r.DIRECTION_UP="up",r.DIRECTION_RIGHT="right",r.POINTER_MOUSE="mouse",r.POINTER_TOUCH="touch",r.POINTER_PEN="pen",r.UPDATE_VELOCITY_INTERVAL=20,r.EVENT_START="start",r.EVENT_MOVE="move",r.EVENT_END="end",r.DOCUMENT=e.document,r.plugins=r.plugins||{},r.gestures=r.gestures||{},r.READY=!1,r.utils={extend:function(t,r,i){for(var s in r){if(t[s]!==n&&i)continue;t[s]=r[s]}return t},each:function(e,t,r){var i,s;if("forEach"in e)e.forEach(t,r);else if(e.length!==n){for(i=0,s=e.length;i=s?t.pageX-n.pageX>0?r.DIRECTION_LEFT:r.DIRECTION_RIGHT:t.pageY-n.pageY>0?r.DIRECTION_UP:r.DIRECTION_DOWN},getDistance:function(t,n){var r=n.pageX-t.pageX,i=n.pageY-t.pageY;return Math.sqrt(r*r+i*i)},getScale:function(t,n){return t.length>=2&&n.length>=2?this.getDistance(n[0],n[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,n){return t.length>=2&&n.length>=2?this.getAngle(n[1],n[0])-this.getAngle(t[1],t[0]):0},isVertical:function(t){return t==r.DIRECTION_UP||t==r.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,n){if(!n||!t||!t.style)return;r.utils.each(["webkit","khtml","moz","Moz","ms","o",""],function(e){r.utils.each(n,function(n,r){e&&(r=e+r.substring(0,1).toUpperCase()+r.substring(1)),r in t.style&&(t.style[r]=n)})}),n.userSelect=="none"&&(t.onselectstart=function(){return!1}),n.userDrag=="none"&&(t.ondragstart=function(){return!1})},startDefaultBrowserBehavior:function(t,n){if(!n||!t||!t.style)return;r.utils.each(["webkit","khtml","moz","Moz","ms","o",""],function(e){r.utils.each(n,function(n,r){e&&(r=e+r.substring(0,1).toUpperCase()+r.substring(1)),r in t.style&&(t.style[r]="")})}),n.userSelect=="none"&&(t.onselectstart=null),n.userDrag=="none"&&(t.ondragstart=null)}},r.Instance=function(e,t){var n=this;return i(),this.element=e,this.enabled=!0,this.options=r.utils.extend(r.utils.extend({},r.defaults),t||{}),this.options.stop_browser_behavior&&r.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),this._eventStartHandler=r.event.onTouch(e,r.EVENT_START,function(e){n.enabled&&r.detection.startDetect(n,e)}),this._eventHandler=[],this},r.Instance.prototype={on:function(t,n){var i=t.split(" ");return r.utils.each(i,function(e){this.element.addEventListener(e,n,!1),this._eventHandler.push({gesture:e,handler:n})},this),this},off:function(t,n){var i=t.split(" ");return r.utils.each(i,function(e){this.element.removeEventListener(e,n,!1);var t=-1;r.utils.each(this._eventHandler,function(r,i){t===-1&&r.gesture===e&&r.handler===n&&(t=i)},this),t>-1&&this._eventHandler.splice(t,1)},this),this},trigger:function(t,n){n||(n={});var i=r.DOCUMENT.createEvent("Event");i.initEvent(t,!0,!0),i.gesture=n;var s=this.element;return r.utils.hasParent(n.target,s)&&(s=n.target),s.dispatchEvent(i),this},enable:function(t){return this.enabled=t,this},dispose:function(){return this.options.stop_browser_behavior&&r.utils.startDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),r.utils.each(this._eventHandler,function(e){this.element.removeEventListener(e.gesture,e.handler,!1)},this),this._eventHandler.length=0,r.event.unbindDom(this.element,r.EVENT_TYPES[r.EVENT_START],this._eventStartHandler),this}};var s=null,o=!1,u=!1;r.event={bindDom:function(e,t,n){var i=t.split(" ");r.utils.each(i,function(t){e.addEventListener(t,n,!1)})},unbindDom:function(e,t,n){var i=t.split(" ");r.utils.each(i,function(t){e.removeEventListener(t,n,!1)})},onTouch:function(t,n,i){var a=this,f=function(f){var l=f.type.toLowerCase();if(l.match(/mouse/)&&u)return;l.match(/touch/)||l.match(/pointerdown/)||l.match(/mouse/)&&f.which===1?o=!0:l.match(/mouse/)&&!f.which&&(o=!1),l.match(/touch|pointer/)&&(u=!0);var c=0;if(o){r.HAS_POINTEREVENTS&&n!=r.EVENT_END?c=r.PointerEvent.updatePointer(n,f):l.match(/touch/)?c=f.touches.length:u||(c=l.match(/up/)?0:1),c>0&&n==r.EVENT_END?n=r.EVENT_MOVE:c||(n=r.EVENT_END);if(c||s===null)s=f;i.call(r.detection,a.collectEventData(t,n,a.getTouchList(s,n),f)),r.HAS_POINTEREVENTS&&n==r.EVENT_END&&(c=r.PointerEvent.updatePointer(n,f))}c||(s=null,o=!1,u=!1,r.PointerEvent.reset())};return this.bindDom(t,r.EVENT_TYPES[n],f),f},determineEventTypes:function(){var t;r.HAS_POINTEREVENTS?t=r.PointerEvent.getEvents():r.NO_MOUSEEVENTS?t=["touchstart","touchmove","touchend touchcancel"]:t=["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],r.EVENT_TYPES[r.EVENT_START]=t[0],r.EVENT_TYPES[r.EVENT_MOVE]=t[1],r.EVENT_TYPES[r.EVENT_END]=t[2]},getTouchList:function(t){return r.HAS_POINTEREVENTS?r.PointerEvent.getTouchList():t.touches?t.touches:(t.identifier=1,[t])},collectEventData:function(t,n,i,s){var o=r.POINTER_TOUCH;if(s.type.match(/mouse/)||r.PointerEvent.matchType(r.POINTER_MOUSE,s))o=r.POINTER_MOUSE;return{center:r.utils.getCenter(i),timeStamp:(new Date).getTime(),target:s.target,touches:i,eventType:n,pointerType:o,srcEvent:s,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault&&this.srcEvent.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return r.detection.stopDetect()}}}},r.PointerEvent={pointers:{},getTouchList:function(){var e=this,t=[];return r.utils.each(e.pointers,function(e){t.push(e)}),t},updatePointer:function(e,t){return e==r.EVENT_END?delete this.pointers[t.pointerId]:(t.identifier=t.pointerId,this.pointers[t.pointerId]=t),Object.keys(this.pointers).length},matchType:function(e,t){if(!t.pointerType)return!1;var n=t.pointerType,i={};return i[r.POINTER_MOUSE]=n===t.MSPOINTER_TYPE_MOUSE||n===r.POINTER_MOUSE,i[r.POINTER_TOUCH]=n===t.MSPOINTER_TYPE_TOUCH||n===r.POINTER_TOUCH,i[r.POINTER_PEN]=n===t.MSPOINTER_TYPE_PEN||n===r.POINTER_PEN,i[e]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},r.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(t,n){if(this.current)return;this.stopped=!1,this.current={inst:t,startEvent:r.utils.extend({},n),lastEvent:!1,lastVEvent:!1,velocity:!1,name:""},this.detect(n)},detect:function(t){if(!this.current||this.stopped)return;t=this.extendEventData(t);var n=this.current.inst.options;return r.utils.each(this.gestures,function(e){if(!this.stopped&&n[e.name]!==!1&&e.handler.call(e,t,this.current.inst)===!1)return this.stopDetect(),!1},this),this.current&&(this.current.lastEvent=t),t.eventType==r.EVENT_END&&!t.touches.length-1&&this.stopDetect(),t},stopDetect:function(){this.previous=r.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(t){var n=this.current.startEvent,i=this.current.lastVEvent;n&&(t.touches.length!=n.touches.length||t.touches===n.touches)&&(n.touches=[],r.utils.each(t.touches,function(e){n.touches.push(r.utils.extend({},e))}));var s=t.timeStamp-n.timeStamp,o=t.center.pageX-n.center.pageX,u=t.center.pageY-n.center.pageY,a,f,l=this.current.velocity;return i!==!1&&t.timeStamp-i.timeStamp>r.UPDATE_VELOCITY_INTERVAL?(l=r.utils.getVelocity(t.timeStamp-i.timeStamp,t.center.pageX-i.center.pageX,t.center.pageY-i.center.pageY),this.current.lastVEvent=t,l.x>0&&l.y>0&&(this.current.velocity=l)):this.current.velocity===!1&&(l=r.utils.getVelocity(s,o,u),this.current.velocity=l,this.current.lastVEvent=t),t.eventType==="end"?(a=this.current.lastEvent&&this.current.lastEvent.interimAngle,f=this.current.lastEvent&&this.current.lastEvent.interimDirection):(a=this.current.lastEvent&&r.utils.getAngle(this.current.lastEvent.center,t.center),f=this.current.lastEvent&&r.utils.getDirection(this.current.lastEvent.center,t.center)),r.utils.extend(t,{deltaTime:s,deltaX:o,deltaY:u,velocityX:l.x,velocityY:l.y,distance:r.utils.getDistance(n.center,t.center),angle:r.utils.getAngle(n.center,t.center),interimAngle:a,direction:r.utils.getDirection(n.center,t.center),interimDirection:f,scale:r.utils.getScale(n.touches,t.touches),rotation:r.utils.getRotation(n.touches,t.touches),startEvent:n}),t},register:function(t){var i=t.defaults||{};return i[t.name]===n&&(i[t.name]=!0),r.utils.extend(r.defaults,i,!0),t.index=t.index||1e3,this.gestures.push(t),this.gestures.sort(function(e,t){return e.indext.index?1:0}),this.gestures}},r.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,correct_for_drag_min_distance:!0,drag_max_touches:1,drag_block_horizontal:!1,drag_block_vertical:!1,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(t,n){if(r.detection.current.name!=this.name&&this.triggered){n.trigger(this.name+"end",t),this.triggered=!1;return}if(n.options.drag_max_touches>0&&t.touches.length>n.options.drag_max_touches)return;switch(t.eventType){case r.EVENT_START:this.triggered=!1;break;case r.EVENT_MOVE:if(t.distance0){var i=Math.abs(n.options.drag_min_distance/t.distance);r.detection.current.startEvent.center.pageX+=t.deltaX*i,r.detection.current.startEvent.center.pageY+=t.deltaY*i,t=r.detection.extendEventData(t)}}if(r.detection.current.lastEvent.drag_locked_to_axis||n.options.drag_lock_to_axis&&n.options.drag_lock_min_distance<=t.distance)t.drag_locked_to_axis=!0;var s=r.detection.current.lastEvent.direction;t.drag_locked_to_axis&&s!==t.direction&&(r.utils.isVertical(s)?t.direction=t.deltaY<0?r.DIRECTION_UP:r.DIRECTION_DOWN:t.direction=t.deltaX<0?r.DIRECTION_LEFT:r.DIRECTION_RIGHT),this.triggered||(n.trigger(this.name+"start",t),this.triggered=!0),n.trigger(this.name,t),n.trigger(this.name+t.direction,t),(n.options.drag_block_vertical&&r.utils.isVertical(t.direction)||n.options.drag_block_horizontal&&!r.utils.isVertical(t.direction))&&t.preventDefault();break;case r.EVENT_END:this.triggered&&n.trigger(this.name+"end",t),this.triggered=!1}}},r.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(t,n){switch(t.eventType){case r.EVENT_START:clearTimeout(this.timer),r.detection.current.name=this.name,this.timer=setTimeout(function(){r.detection.current.name=="hold"&&n.trigger("hold",t)},n.options.hold_timeout);break;case r.EVENT_MOVE:t.distance>n.options.hold_threshold&&clearTimeout(this.timer);break;case r.EVENT_END:clearTimeout(this.timer)}}},r.gestures.Release={name:"release",index:Infinity,handler:function(t,n){t.eventType==r.EVENT_END&&n.trigger(this.name,t)}},r.gestures.Swipe={name:"swipe",index:40,defaults:{swipe_min_touches:1,swipe_max_touches:1,swipe_velocity:.7},handler:function(t,n){if(t.eventType==r.EVENT_END){if(n.options.swipe_max_touches>0&&t.touches.lengthn.options.swipe_max_touches)return;if(t.velocityX>n.options.swipe_velocity||t.velocityY>n.options.swipe_velocity)n.trigger(this.name,t),n.trigger(this.name+t.direction,t)}}},r.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(t,n){if(t.eventType==r.EVENT_MOVE&&!r.detection.current.reachedTapMaxDistance)r.detection.current.reachedTapMaxDistance=t.distance>n.options.tap_max_distance;else if(t.eventType==r.EVENT_END&&t.srcEvent.type!="touchcancel"){var i=r.detection.previous,s=!1;if(r.detection.current.reachedTapMaxDistance||t.deltaTime>n.options.tap_max_touchtime)return;i&&i.name=="tap"&&t.timeStamp-i.lastEvent.timeStampn.options.transform_min_rotation&&n.trigger("rotate",t),i>n.options.transform_min_scale&&(n.trigger("pinch",t),n.trigger("pinch"+(t.scale<1?"in":"out"),t));break;case r.EVENT_END:this.triggered&&n.trigger(this.name+"end",t),this.triggered=!1}}},typeof define=="function"&&define.amd?define(function(){return r}):typeof t=="object"&&t.exports?t.exports=r:e.Hammer=r})(window)},{}],19:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||undefined}function i(e){return typeof e=="function"}function s(e){return typeof e=="number"}function o(e){return typeof e=="object"&&e!==null}function u(e){return e===void 0}t.exports=r,r.EventEmitter=r,r.prototype._events=undefined,r.prototype._maxListeners=undefined,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,s,a,f;this._events||(this._events={});if(e==="error")if(!this._events.error||o(this._events.error)&&!this._events.error.length)throw t=arguments[1],t instanceof Error?t:TypeError('Uncaught, unspecified "error" event.');n=this._events[e];if(u(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:r=arguments.length,s=new Array(r-1);for(a=1;a0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),typeof console.trace=="function"&&console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}]},{},[13]); \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/index.html b/SinglePlayer - Games/Skii Game/index.html new file mode 100644 index 00000000..553afd7a --- /dev/null +++ b/SinglePlayer - Games/Skii Game/index.html @@ -0,0 +1,52 @@ + + + + + + Skii Game + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fork SkiFree.js on GitHub + A blog post about this game + + + + + + + diff --git a/SinglePlayer - Games/Skii Game/js/lib/canvasRenderingContext2DExtensions.js b/SinglePlayer - Games/Skii Game/js/lib/canvasRenderingContext2DExtensions.js new file mode 100644 index 00000000..e042ddf4 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/canvasRenderingContext2DExtensions.js @@ -0,0 +1,97 @@ +CanvasRenderingContext2D.prototype.storeLoadedImage = function (key, image) { + if (!this.images) { + this.images = {}; + } + + this.images[key] = image; +}; + +CanvasRenderingContext2D.prototype.getLoadedImage = function (key) { + if (this.images[key]) { + return this.images[key]; + } +}; + +CanvasRenderingContext2D.prototype.followSprite = function (sprite) { + this.centralSprite = sprite; +}; + +CanvasRenderingContext2D.prototype.getCentralPosition = function () { + return { + map: this.centralSprite.mapPosition, + canvas: [ Math.round(this.canvas.width * 0.5), Math.round(this.canvas.height * 0.5), 0] + }; +}; + +CanvasRenderingContext2D.prototype.mapPositionToCanvasPosition = function (position) { + var central = this.getCentralPosition(); + var centralMapPosition = central.map; + var centralCanvasPosition = central.canvas; + var mapDifferenceX = centralMapPosition[0] - position[0]; + var mapDifferenceY = centralMapPosition[1] - position[1]; + return [ centralCanvasPosition[0] - mapDifferenceX, centralCanvasPosition[1] - mapDifferenceY ]; +}; + +CanvasRenderingContext2D.prototype.canvasPositionToMapPosition = function (position) { + var central = this.getCentralPosition(); + var centralMapPosition = central.map; + var centralCanvasPosition = central.canvas; + var mapDifferenceX = centralCanvasPosition[0] - position[0]; + var mapDifferenceY = centralCanvasPosition[1] - position[1]; + return [ centralMapPosition[0] - mapDifferenceX, centralMapPosition[1] - mapDifferenceY ]; +}; + +CanvasRenderingContext2D.prototype.getCentreOfViewport = function () { + return (this.canvas.width / 2).floor(); +}; + +// Y-pos canvas functions +CanvasRenderingContext2D.prototype.getMiddleOfViewport = function () { + return (this.canvas.height / 2).floor(); +}; + +CanvasRenderingContext2D.prototype.getBelowViewport = function () { + return this.canvas.height.floor(); +}; + +CanvasRenderingContext2D.prototype.getMapBelowViewport = function () { + var below = this.getBelowViewport(); + return this.canvasPositionToMapPosition([ 0, below ])[1]; +}; + +CanvasRenderingContext2D.prototype.getRandomlyInTheCentreOfCanvas = function (buffer) { + var min = 0; + var max = this.canvas.width; + + if (buffer) { + min -= buffer; + max += buffer; + } + + return Number.random(min, max); +}; + +CanvasRenderingContext2D.prototype.getRandomlyInTheCentreOfMap = function (buffer) { + var random = this.getRandomlyInTheCentreOfCanvas(buffer); + return this.canvasPositionToMapPosition([ random, 0 ])[0]; +}; + +CanvasRenderingContext2D.prototype.getRandomMapPositionBelowViewport = function () { + var xCanvas = this.getRandomlyInTheCentreOfCanvas(); + var yCanvas = this.getBelowViewport(); + return this.canvasPositionToMapPosition([ xCanvas, yCanvas ]); +}; + +CanvasRenderingContext2D.prototype.getRandomMapPositionAboveViewport = function () { + var xCanvas = this.getRandomlyInTheCentreOfCanvas(); + var yCanvas = this.getAboveViewport(); + return this.canvasPositionToMapPosition([ xCanvas, yCanvas ]); +}; + +CanvasRenderingContext2D.prototype.getTopOfViewport = function () { + return this.canvasPositionToMapPosition([ 0, 0 ])[1]; +}; + +CanvasRenderingContext2D.prototype.getAboveViewport = function () { + return 0 - (this.canvas.height / 4).floor(); +}; \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/commonjs-require.js b/SinglePlayer - Games/Skii Game/js/lib/commonjs-require.js new file mode 100644 index 00000000..1f28c667 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/commonjs-require.js @@ -0,0 +1,13 @@ +/* + * + * For the browser ONLY + * + */ + +var global = this; + +function require (name) { + var indexToGoFrom = name.lastIndexOf('/'); + name = name.substring(indexToGoFrom + 1); + return global[name]; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/extenders.js b/SinglePlayer - Games/Skii Game/js/lib/extenders.js new file mode 100644 index 00000000..fcade91c --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/extenders.js @@ -0,0 +1,14 @@ +// Extends function so that new-able objects can be given new methods easily +Function.prototype.method = function (name, func) { + this.prototype[name] = func; + return this; +}; + +// Will return the original method of an object when inheriting from another +Object.method('superior', function (name) { + var that = this; + var method = that[name]; + return function() { + return method.apply(that, arguments); + }; +}); \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/game.js b/SinglePlayer - Games/Skii Game/js/lib/game.js new file mode 100644 index 00000000..26bb5399 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/game.js @@ -0,0 +1,161 @@ +var SpriteArray = require('./spriteArray'); +var EventedLoop = require('eventedloop'); + +(function (global) { + function Game (mainCanvas, player) { + var staticObjects = new SpriteArray(); + var movingObjects = new SpriteArray(); + var uiElements = new SpriteArray(); + var dContext = mainCanvas.getContext('2d'); + var mouseX = dContext.getCentreOfViewport(); + var mouseY = 0; + var paused = false; + var that = this; + var beforeCycleCallbacks = []; + var afterCycleCallbacks = []; + var gameLoop = new EventedLoop(); + + this.addStaticObject = function (sprite) { + staticObjects.push(sprite); + }; + + this.addStaticObjects = function (sprites) { + sprites.forEach(this.addStaticObject.bind(this)); + }; + + this.addMovingObject = function (movingObject, movingObjectType) { + if (movingObjectType) { + staticObjects.onPush(function (obj) { + if (obj.data && obj.data.hitBehaviour[movingObjectType]) { + obj.onHitting(movingObject, obj.data.hitBehaviour[movingObjectType]); + } + }, true); + } + + movingObjects.push(movingObject); + }; + + this.addUIElement = function (element) { + uiElements.push(element); + }; + + this.beforeCycle = function (callback) { + beforeCycleCallbacks.push(callback); + }; + + this.afterCycle = function (callback) { + afterCycleCallbacks.push(callback); + }; + + this.setMouseX = function (x) { + mouseX = x; + }; + + this.setMouseY = function (y) { + mouseY = y; + }; + + player.setMapPosition(0, 0); + player.setMapPositionTarget(0, -10); + dContext.followSprite(player); + + var intervalNum = 0; + + this.cycle = function () { + beforeCycleCallbacks.each(function(c) { + c(); + }); + + // Clear canvas + var mouseMapPosition = dContext.canvasPositionToMapPosition([mouseX, mouseY]); + + if (!player.isJumping) { + player.setMapPositionTarget(mouseMapPosition[0], mouseMapPosition[1]); + } + + intervalNum++; + + player.cycle(); + + movingObjects.each(function (movingObject, i) { + movingObject.cycle(dContext); + }); + + staticObjects.cull(); + staticObjects.each(function (staticObject, i) { + if (staticObject.cycle) { + staticObject.cycle(); + } + }); + + uiElements.each(function (uiElement, i) { + if (uiElement.cycle) { + uiElement.cycle(); + } + }); + + afterCycleCallbacks.each(function(c) { + c(); + }); + }; + + that.draw = function () { + // Clear canvas + mainCanvas.width = mainCanvas.width; + + player.draw(dContext); + + player.cycle(); + + movingObjects.each(function (movingObject, i) { + movingObject.draw(dContext); + }); + + staticObjects.each(function (staticObject, i) { + if (staticObject.draw) { + staticObject.draw(dContext, 'main'); + } + }); + + uiElements.each(function (uiElement, i) { + if (uiElement.draw) { + uiElement.draw(dContext, 'main'); + } + }); + }; + + this.start = function () { + gameLoop.start(); + }; + + this.pause = function () { + paused = true; + gameLoop.stop(); + }; + + this.isPaused = function () { + return paused; + }; + + this.reset = function () { + paused = false; + staticObjects = new SpriteArray(); + movingObjects = new SpriteArray(); + mouseX = dContext.getCentreOfViewport(); + mouseY = 0; + player.reset(); + player.setMapPosition(0, 0, 0); + this.start(); + }.bind(this); + + gameLoop.on('20', this.cycle); + gameLoop.on('20', this.draw); + } + + global.game = Game; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.game; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/guid.js b/SinglePlayer - Games/Skii Game/js/lib/guid.js new file mode 100644 index 00000000..cbe5a0b6 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/guid.js @@ -0,0 +1,25 @@ +// Creates a random ID string +(function(global) { + function guid () + { + var S4 = function () + { + return Math.floor( + Math.random() * 0x10000 /* 65536 */ + ).toString(16); + }; + + return ( + S4() + S4() + "-" + + S4() + "-" + + S4() + "-" + + S4() + "-" + + S4() + S4() + S4() + ); + } + global.guid = guid; +})(this); + +if (typeof module !== 'undefined') { + module.exports = this.guid; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/infoBox.js b/SinglePlayer - Games/Skii Game/js/lib/infoBox.js new file mode 100644 index 00000000..363a3c9d --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/infoBox.js @@ -0,0 +1,50 @@ +function InfoBox(data) { + var that = this; + + that.lines = data.initialLines; + + that.top = data.position.top; + that.right = data.position.right; + that.bottom = data.position.bottom; + that.left = data.position.left; + + that.width = data.width; + that.height = data.height; + + that.setLines = function (lines) { + that.lines = lines; + }; + + that.draw = function (dContext) { + dContext.font = '11px monospace'; + var yOffset = 0; + that.lines.each(function (line) { + var fontSize = +dContext.font.slice(0,2); + var textWidth = dContext.measureText(line).width; + var textHeight = fontSize * 1.5; + var xPos, yPos; + if (that.top) { + yPos = that.top + yOffset; + } else if (that.bottom) { + yPos = dContext.canvas.height - that.top - textHeight + yOffset; + } + + if (that.right) { + xPos = dContext.canvas.width - that.right - textWidth; + } else if (that.left) { + xPos = that.left; + } + + yOffset += textHeight; + + + dContext.fillText(line, xPos, yPos); + }); + }; + + return that; +} + +if (typeof module !== 'undefined') { + module.exports = InfoBox; +} diff --git a/SinglePlayer - Games/Skii Game/js/lib/input.js b/SinglePlayer - Games/Skii Game/js/lib/input.js new file mode 100644 index 00000000..637444f9 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/input.js @@ -0,0 +1,11 @@ +(function(global) { + global.inputControl = { + on: function (event, callback) { + var eventInfo = event.split('.').map(String.prototype.toLowerCase.apply); + } + }; +})(this); + +if (typeof module !== 'undefined') { + module.exports = this.inputControl; +} diff --git a/SinglePlayer - Games/Skii Game/js/lib/isMobileDevice.js b/SinglePlayer - Games/Skii Game/js/lib/isMobileDevice.js new file mode 100644 index 00000000..dc654456 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/isMobileDevice.js @@ -0,0 +1,17 @@ +function isMobileDevice() { + if(navigator.userAgent.match(/Android/i) || + navigator.userAgent.match(/webOS/i) || + navigator.userAgent.match(/iPhone/i) || + navigator.userAgent.match(/iPad/i) || + navigator.userAgent.match(/iPod/i) || + navigator.userAgent.match(/BlackBerry/i) || + navigator.userAgent.match(/Windows Phone/i) + ) { + return true; + } + else { + return false; + } +} + +module.exports = isMobileDevice; \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/monster.js b/SinglePlayer - Games/Skii Game/js/lib/monster.js new file mode 100644 index 00000000..235d7711 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/monster.js @@ -0,0 +1,65 @@ +var Sprite = require('./sprite'); + +(function(global) { + function Monster(data) { + var that = new Sprite(data); + var super_draw = that.superior('draw'); + var spriteVersion = 1; + var eatingStage = 0; + var standardSpeed = 6; + + that.isEating = false; + that.isFull = false; + that.setSpeed(standardSpeed); + + that.draw = function(dContext) { + var spritePartToUse = function () { + var xDiff = that.movingToward[0] - that.canvasX; + + if (that.isEating) { + return 'eating' + eatingStage; + } + + if (spriteVersion + 0.1 > 2) { + spriteVersion = 0.1; + } else { + spriteVersion += 0.1; + } + if (xDiff >= 0) { + return 'sEast' + Math.ceil(spriteVersion); + } else if (xDiff < 0) { + return 'sWest' + Math.ceil(spriteVersion); + } + }; + + return super_draw(dContext, spritePartToUse()); + }; + + function startEating (whenDone) { + eatingStage += 1; + that.isEating = true; + that.isMoving = false; + if (eatingStage < 6) { + setTimeout(function () { + startEating(whenDone); + }, 300); + } else { + eatingStage = 0; + that.isEating = false; + that.isMoving = true; + whenDone(); + } + } + + that.startEating = startEating; + + return that; + } + + global.monster = Monster; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.monster; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/plugins.js b/SinglePlayer - Games/Skii Game/js/lib/plugins.js new file mode 100644 index 00000000..ba113ac2 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/plugins.js @@ -0,0 +1,22 @@ +// Avoid `console` errors in browsers that lack a console. +(function() { + var method; + var noop = function noop() {}; + var methods = [ + 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', + 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', + 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', + 'timeStamp', 'trace', 'warn' + ]; + var length = methods.length; + var console = (window.console = window.console || {}); + + while (length--) { + method = methods[length]; + + // Only stub undefined methods. + if (!console[method]) { + console[method] = noop; + } + } +}()); \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/skiLift.js b/SinglePlayer - Games/Skii Game/js/lib/skiLift.js new file mode 100644 index 00000000..aeeb4127 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/skiLift.js @@ -0,0 +1,24 @@ +var Sprite = require('./sprite'); + +function SkiLift(data) { + var that = new Sprite(data); + var super_draw = that.superior('draw'); + var super_cycle = that.superior('cycle'); + var standardSpeed = 6; + that.setSpeed(standardSpeed); + + that.draw = function(dContext) { + return super_draw(dContext, 'main'); + }; + + that.cycle = function() { + return super_cycle.apply(arguments); + }; + + return that; +} + + +if (typeof module !== 'undefined') { + module.exports = SkiLift; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/skier.js b/SinglePlayer - Games/Skii Game/js/lib/skier.js new file mode 100644 index 00000000..1f90a70e --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/skier.js @@ -0,0 +1,503 @@ +var Sprite = require('./sprite'); +if (typeof navigator !== 'undefined') { + navigator.vibrate = navigator.vibrate || + navigator.webkitVibrate || + navigator.mozVibrate || + navigator.msVibrate; +} else { + navigator = { + vibrate: false + }; +} + +(function(global) { + function Skier(data) { + var discreteDirections = { + 'west': 270, + 'wsWest': 240, + 'sWest': 195, + 'south': 180, + 'sEast': 165, + 'esEast': 120, + 'east': 90 + }; + var that = new Sprite(data); + var sup = { + draw: that.superior('draw'), + cycle: that.superior('cycle'), + getSpeedX: that.superior('getSpeedX'), + getSpeedY: that.superior('getSpeedY'), + hits: that.superior('hits') + }; + var directions = { + esEast: function(xDiff) { return xDiff > 300; }, + sEast: function(xDiff) { return xDiff > 75; }, + wsWest: function(xDiff) { return xDiff < -300; }, + sWest: function(xDiff) { return xDiff < -75; } + }; + + var cancelableStateTimeout; + var cancelableStateInterval; + + var canSpeedBoost = true; + + var obstaclesHit = []; + var pixelsTravelled = 0; + var standardSpeed = 5; + var boostMultiplier = 2; + var turnEaseCycles = 70; + var speedX = 0; + var speedXFactor = 0; + var speedY = 0; + var speedYFactor = 1; + var trickStep = 0; // There are three of these + + that.isMoving = true; + that.hasBeenHit = false; + that.isJumping = false; + that.isPerformingTrick = false; + that.onHitObstacleCb = function() {}; + that.setSpeed(standardSpeed); + + that.reset = function () { + obstaclesHit = []; + pixelsTravelled = 0; + that.isMoving = true; + that.hasBeenHit = false; + canSpeedBoost = true; + setNormal(); + }; + + function setNormal() { + that.setSpeed(standardSpeed); + that.isMoving = true; + that.hasBeenHit = false; + that.isJumping = false; + that.isPerformingTrick = false; + if (cancelableStateInterval) { + clearInterval(cancelableStateInterval); + } + that.setMapPosition(undefined, undefined, 0); + } + + function setCrashed() { + that.isMoving = false; + that.hasBeenHit = true; + that.isJumping = false; + that.isPerformingTrick = false; + if (cancelableStateInterval) { + clearInterval(cancelableStateInterval); + } + that.setMapPosition(undefined, undefined, 0); + } + + function setJumping() { + var currentSpeed = that.getSpeed(); + that.setSpeed(currentSpeed + 2); + that.setSpeedY(currentSpeed + 2); + that.isMoving = true; + that.hasBeenHit = false; + that.isJumping = true; + that.setMapPosition(undefined, undefined, 1); + } + + function getDiscreteDirection() { + if (that.direction) { + if (that.direction <= 90) { + return 'east'; + } else if (that.direction > 90 && that.direction < 150) { + return 'esEast'; + } else if (that.direction >= 150 && that.direction < 180) { + return 'sEast'; + } else if (that.direction === 180) { + return 'south'; + } else if (that.direction > 180 && that.direction <= 210) { + return 'sWest'; + } else if (that.direction > 210 && that.direction < 270) { + return 'wsWest'; + } else if (that.direction >= 270) { + return 'west'; + } else { + return 'south'; + } + } else { + var xDiff = that.movingToward[0] - that.mapPosition[0]; + var yDiff = that.movingToward[1] - that.mapPosition[1]; + if (yDiff <= 0) { + if (xDiff > 0) { + return 'east'; + } else { + return 'west'; + } + } + + if (directions.esEast(xDiff)) { + return 'esEast'; + } else if (directions.sEast(xDiff)) { + return 'sEast'; + } else if (directions.wsWest(xDiff)) { + return 'wsWest'; + } else if (directions.sWest(xDiff)) { + return 'sWest'; + } + } + return 'south'; + } + + function setDiscreteDirection(d) { + if (discreteDirections[d]) { + that.setDirection(discreteDirections[d]); + } + + if (d === 'west' || d === 'east') { + that.isMoving = false; + } else { + that.isMoving = true; + } + } + + function getBeingEatenSprite() { + return 'blank'; + } + + function getJumpingSprite() { + return 'jumping'; + } + + function getTrickSprite() { + console.log('Trick step is', trickStep); + if (trickStep === 0) { + return 'jumping'; + } else if (trickStep === 1) { + return 'somersault1'; + } else { + return 'somersault2'; + } + } + + that.stop = function () { + if (that.direction > 180) { + setDiscreteDirection('west'); + } else { + setDiscreteDirection('east'); + } + }; + + that.turnEast = function () { + var discreteDirection = getDiscreteDirection(); + + switch (discreteDirection) { + case 'west': + setDiscreteDirection('wsWest'); + break; + case 'wsWest': + setDiscreteDirection('sWest'); + break; + case 'sWest': + setDiscreteDirection('south'); + break; + case 'south': + setDiscreteDirection('sEast'); + break; + case 'sEast': + setDiscreteDirection('esEast'); + break; + case 'esEast': + setDiscreteDirection('east'); + break; + default: + setDiscreteDirection('south'); + break; + } + }; + + that.turnWest = function () { + var discreteDirection = getDiscreteDirection(); + + switch (discreteDirection) { + case 'east': + setDiscreteDirection('esEast'); + break; + case 'esEast': + setDiscreteDirection('sEast'); + break; + case 'sEast': + setDiscreteDirection('south'); + break; + case 'south': + setDiscreteDirection('sWest'); + break; + case 'sWest': + setDiscreteDirection('wsWest'); + break; + case 'wsWest': + setDiscreteDirection('west'); + break; + default: + setDiscreteDirection('south'); + break; + } + }; + + that.stepWest = function () { + that.mapPosition[0] -= that.speed * 2; + }; + + that.stepEast = function () { + that.mapPosition[0] += that.speed * 2; + }; + + that.setMapPositionTarget = function (x, y) { + if (that.hasBeenHit) return; + + if (Math.abs(that.mapPosition[0] - x) <= 75) { + x = that.mapPosition[0]; + } + + that.movingToward = [ x, y ]; + + // that.resetDirection(); + }; + + that.startMovingIfPossible = function () { + if (!that.hasBeenHit && !that.isBeingEaten) { + that.isMoving = true; + } + }; + + that.setTurnEaseCycles = function (c) { + turnEaseCycles = c; + }; + + that.getPixelsTravelledDownMountain = function () { + return pixelsTravelled; + }; + + that.resetSpeed = function () { + that.setSpeed(standardSpeed); + }; + + that.cycle = function () { + if ( that.getSpeedX() <= 0 && that.getSpeedY() <= 0 ) { + that.isMoving = false; + } + if (that.isMoving) { + pixelsTravelled += that.speed; + } + + if (that.isJumping) { + that.setMapPositionTarget(undefined, that.mapPosition[1] + that.getSpeed()); + } + + sup.cycle(); + + that.checkHittableObjects(); + }; + + that.draw = function(dContext) { + var spritePartToUse = function () { + if (that.isBeingEaten) { + return getBeingEatenSprite(); + } + + if (that.isJumping) { + if (that.isPerformingTrick) { + return getTrickSprite(); + } + return getJumpingSprite(); + } + + if (that.hasBeenHit) { + return 'hit'; + } + + return getDiscreteDirection(); + }; + + return sup.draw(dContext, spritePartToUse()); + }; + + that.hits = function (obs) { + if (obstaclesHit.indexOf(obs.id) !== -1) { + return false; + } + + if (!obs.occupiesZIndex(that.mapPosition[2])) { + return false; + } + + if (sup.hits(obs)) { + return true; + } + + return false; + }; + + that.speedBoost = function () { + var originalSpeed = that.speed; + if (canSpeedBoost) { + canSpeedBoost = false; + that.setSpeed(that.speed * boostMultiplier); + setTimeout(function () { + that.setSpeed(originalSpeed); + setTimeout(function () { + canSpeedBoost = true; + }, 10000); + }, 2000); + } + }; + + that.attemptTrick = function () { + if (that.isJumping) { + that.isPerformingTrick = true; + cancelableStateInterval = setInterval(function () { + if (trickStep >= 2) { + trickStep = 0; + } else { + trickStep += 1; + } + }, 300); + } + }; + + that.getStandardSpeed = function () { + return standardSpeed; + }; + + function easeSpeedToTargetUsingFactor(sp, targetSpeed, f) { + if (f === 0 || f === 1) { + return targetSpeed; + } + + if (sp < targetSpeed) { + sp += that.getSpeed() * (f / turnEaseCycles); + } + + if (sp > targetSpeed) { + sp -= that.getSpeed() * (f / turnEaseCycles); + } + + return sp; + } + + that.getSpeedX = function () { + if (getDiscreteDirection() === 'esEast' || getDiscreteDirection() === 'wsWest') { + speedXFactor = 0.5; + speedX = easeSpeedToTargetUsingFactor(speedX, that.getSpeed() * speedXFactor, speedXFactor); + + return speedX; + } + + if (getDiscreteDirection() === 'sEast' || getDiscreteDirection() === 'sWest') { + speedXFactor = 0.33; + speedX = easeSpeedToTargetUsingFactor(speedX, that.getSpeed() * speedXFactor, speedXFactor); + + return speedX; + } + + // So it must be south + + speedX = easeSpeedToTargetUsingFactor(speedX, 0, speedXFactor); + + return speedX; + }; + + that.setSpeedY = function(sy) { + speedY = sy; + }; + + that.getSpeedY = function () { + var targetSpeed; + + if (that.isJumping) { + return speedY; + } + + if (getDiscreteDirection() === 'esEast' || getDiscreteDirection() === 'wsWest') { + speedYFactor = 0.6; + speedY = easeSpeedToTargetUsingFactor(speedY, that.getSpeed() * 0.6, 0.6); + + return speedY; + } + + if (getDiscreteDirection() === 'sEast' || getDiscreteDirection() === 'sWest') { + speedYFactor = 0.85; + speedY = easeSpeedToTargetUsingFactor(speedY, that.getSpeed() * 0.85, 0.85); + + return speedY; + } + + if (getDiscreteDirection() === 'east' || getDiscreteDirection() === 'west') { + speedYFactor = 1; + speedY = 0; + + return speedY; + } + + // So it must be south + + speedY = easeSpeedToTargetUsingFactor(speedY, that.getSpeed(), speedYFactor); + + return speedY; + }; + + that.hasHitObstacle = function (obs) { + setCrashed(); + + if (navigator.vibrate) { + navigator.vibrate(500); + } + + obstaclesHit.push(obs.id); + + that.resetSpeed(); + that.onHitObstacleCb(obs); + + if (cancelableStateTimeout) { + clearTimeout(cancelableStateTimeout); + } + cancelableStateTimeout = setTimeout(function() { + setNormal(); + }, 1500); + }; + + that.hasHitJump = function () { + setJumping(); + + if (cancelableStateTimeout) { + clearTimeout(cancelableStateTimeout); + } + cancelableStateTimeout = setTimeout(function() { + setNormal(); + }, 1000); + }; + + that.isEatenBy = function (monster, whenEaten) { + that.hasHitObstacle(monster); + monster.startEating(whenEaten); + obstaclesHit.push(monster.id); + that.isMoving = false; + that.isBeingEaten = true; + }; + + that.reset = function () { + obstaclesHit = []; + pixelsTravelled = 0; + that.isMoving = true; + that.isJumping = false; + that.hasBeenHit = false; + canSpeedBoost = true; + }; + + that.setHitObstacleCb = function (fn) { + that.onHitObstacleCb = fn || function() {}; + }; + return that; + } + + global.skier = Skier; +})(this); + +if (typeof module !== 'undefined') { + module.exports = this.skier; +} diff --git a/SinglePlayer - Games/Skii Game/js/lib/snowboarder.js b/SinglePlayer - Games/Skii Game/js/lib/snowboarder.js new file mode 100644 index 00000000..372b40fd --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/snowboarder.js @@ -0,0 +1,57 @@ +var Sprite = require('./sprite'); + +(function(global) { + function Snowboarder(data) { + var that = new Sprite(data); + var sup = { + draw: that.superior('draw'), + cycle: that.superior('cycle') + }; + var directions = { + sEast: function(xDiff) { return xDiff > 0; }, + sWest: function(xDiff) { return xDiff <= 0; } + }; + var standardSpeed = 3; + + that.setSpeed(standardSpeed); + + function getDirection() { + var xDiff = that.movingToward[0] - that.mapPosition[0]; + var yDiff = that.movingToward[1] - that.mapPosition[1]; + + if (directions.sEast(xDiff)) { + return 'sEast'; + } else { + return 'sWest'; + } + } + + that.cycle = function (dContext) { + if (Number.random(10) === 1) { + that.setMapPositionTarget(dContext.getRandomlyInTheCentreOfMap()); + that.setSpeed(standardSpeed + Number.random(-1, 1)); + } + + that.setMapPositionTarget(undefined, dContext.getMapBelowViewport() + 600); + + sup.cycle(); + }; + + that.draw = function(dContext) { + var spritePartToUse = function () { + return getDirection(); + }; + + return sup.draw(dContext, spritePartToUse()); + }; + + return that; + } + + global.snowboarder = Snowboarder; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.snowboarder; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/sprite.js b/SinglePlayer - Games/Skii Game/js/lib/sprite.js new file mode 100644 index 00000000..16b2683f --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/sprite.js @@ -0,0 +1,399 @@ +(function (global) { + var GUID = require('./guid'); + function Sprite (data) { + var hittableObjects = {}; + var zIndexesOccupied = [ 0 ]; + var that = this; + var trackedSpriteToMoveToward; + that.direction = undefined; + that.mapPosition = [0, 0, 0]; + that.id = GUID(); + that.canvasX = 0; + that.canvasY = 0; + that.canvasZ = 0; + that.height = 0; + that.speed = 0; + that.data = data || { parts : {} }; + that.movingToward = [ 0, 0 ]; + that.metresDownTheMountain = 0; + that.movingWithConviction = false; + that.deleted = false; + that.maxHeight = (function () { + return Object.values(that.data.parts).map(function (p) { return p[3]; }).max(); + }()); + that.isMoving = true; + + if (!that.data.parts) { + that.data.parts = {}; + } + + if (data && data.id){ + that.id = data.id; + } + + if (data && data.zIndexesOccupied) { + zIndexesOccupied = data.zIndexesOccupied; + } + + function incrementX(amount) { + that.canvasX += amount.toNumber(); + } + + function incrementY(amount) { + that.canvasY += amount.toNumber(); + } + + function getHitBox(forZIndex) { + if (that.data.hitBoxes) { + if (data.hitBoxes[forZIndex]) { + return data.hitBoxes[forZIndex]; + } + } + } + + function roundHalf(num) { + num = Math.round(num*2)/2; + return num; + } + + function move() { + if (!that.isMoving) { + return; + } + + var currentX = that.mapPosition[0]; + var currentY = that.mapPosition[1]; + + if (typeof that.direction !== 'undefined') { + // For this we need to modify the that.direction so it relates to the horizontal + var d = that.direction - 90; + if (d < 0) d = 360 + d; + currentX += roundHalf(that.speed * Math.cos(d * (Math.PI / 180))); + currentY += roundHalf(that.speed * Math.sin(d * (Math.PI / 180))); + } else { + if (typeof that.movingToward[0] !== 'undefined') { + if (currentX > that.movingToward[0]) { + currentX -= Math.min(that.getSpeedX(), Math.abs(currentX - that.movingToward[0])); + } else if (currentX < that.movingToward[0]) { + currentX += Math.min(that.getSpeedX(), Math.abs(currentX - that.movingToward[0])); + } + } + + if (typeof that.movingToward[1] !== 'undefined') { + if (currentY > that.movingToward[1]) { + currentY -= Math.min(that.getSpeedY(), Math.abs(currentY - that.movingToward[1])); + } else if (currentY < that.movingToward[1]) { + currentY += Math.min(that.getSpeedY(), Math.abs(currentY - that.movingToward[1])); + } + } + } + + that.setMapPosition(currentX, currentY); + } + + this.draw = function (dCtx, spriteFrame) { + var fr = that.data.parts[spriteFrame]; + that.height = fr[3]; + that.width = fr[2]; + + var newCanvasPosition = dCtx.mapPositionToCanvasPosition(that.mapPosition); + that.setCanvasPosition(newCanvasPosition[0], newCanvasPosition[1]); + + dCtx.drawImage(dCtx.getLoadedImage(that.data.$imageFile), fr[0], fr[1], fr[2], fr[3], that.canvasX, that.canvasY, fr[2], fr[3]); + }; + + this.setMapPosition = function (x, y, z) { + if (typeof x === 'undefined') { + x = that.mapPosition[0]; + } + if (typeof y === 'undefined') { + y = that.mapPosition[1]; + } + if (typeof z === 'undefined') { + z = that.mapPosition[2]; + } else { + that.zIndexesOccupied = [ z ]; + } + that.mapPosition = [x, y, z]; + }; + + this.setCanvasPosition = function (cx, cy) { + if (cx) { + if (Object.isString(cx) && (cx.first() === '+' || cx.first() === '-')) incrementX(cx); + else that.canvasX = cx; + } + + if (cy) { + if (Object.isString(cy) && (cy.first() === '+' || cy.first() === '-')) incrementY(cy); + else that.canvasY = cy; + } + }; + + this.getCanvasPositionX = function () { + return that.canvasX; + }; + + this.getCanvasPositionY = function () { + return that.canvasY; + }; + + this.getLeftHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + var lhbe = this.getCanvasPositionX(); + if (getHitBox(zIndex)) { + lhbe += getHitBox(zIndex)[0]; + } + return lhbe; + }; + + this.getTopHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + var thbe = this.getCanvasPositionY(); + if (getHitBox(zIndex)) { + thbe += getHitBox(zIndex)[1]; + } + return thbe; + }; + + this.getRightHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + + if (getHitBox(zIndex)) { + return that.canvasX + getHitBox(zIndex)[2]; + } + + return that.canvasX + that.width; + }; + + this.getBottomHitBoxEdge = function (zIndex) { + zIndex = zIndex || 0; + + if (getHitBox(zIndex)) { + return that.canvasY + getHitBox(zIndex)[3]; + } + + return that.canvasY + that.height; + }; + + this.getPositionInFrontOf = function () { + return [that.canvasX, that.canvasY + that.height]; + }; + + this.setSpeed = function (s) { + that.speed = s; + that.speedX = s; + that.speedY = s; + }; + + this.incrementSpeedBy = function (s) { + that.speed += s; + }; + + that.getSpeed = function getSpeed () { + return that.speed; + }; + + that.getSpeedX = function () { + return that.speed; + }; + + that.getSpeedY = function () { + return that.speed; + }; + + this.setHeight = function (h) { + that.height = h; + }; + + this.setWidth = function (w) { + that.width = w; + }; + + this.getMaxHeight = function () { + return that.maxHeight; + }; + + that.getMovingTowardOpposite = function () { + if (!that.isMoving) { + return [0, 0]; + } + + var dx = (that.movingToward[0] - that.mapPosition[0]); + var dy = (that.movingToward[1] - that.mapPosition[1]); + + var oppositeX = (Math.abs(dx) > 75 ? 0 - dx : 0); + var oppositeY = -dy; + + return [ oppositeX, oppositeY ]; + }; + + this.checkHittableObjects = function () { + Object.keys(hittableObjects, function (k, objectData) { + if (objectData.object.deleted) { + delete hittableObjects[k]; + } else { + if (objectData.object.hits(that)) { + objectData.callbacks.each(function (callback) { + callback(that, objectData.object); + }); + } + } + }); + }; + + this.cycle = function () { + that.checkHittableObjects(); + + if (trackedSpriteToMoveToward) { + that.setMapPositionTarget(trackedSpriteToMoveToward.mapPosition[0], trackedSpriteToMoveToward.mapPosition[1], true); + } + + move(); + }; + + this.setMapPositionTarget = function (x, y, override) { + if (override) { + that.movingWithConviction = false; + } + + if (!that.movingWithConviction) { + if (typeof x === 'undefined') { + x = that.movingToward[0]; + } + + if (typeof y === 'undefined') { + y = that.movingToward[1]; + } + + that.movingToward = [ x, y ]; + + that.movingWithConviction = false; + } + + // that.resetDirection(); + }; + + this.setDirection = function (angle) { + if (angle >= 360) { + angle = 360 - angle; + } + that.direction = angle; + that.movingToward = undefined; + }; + + this.resetDirection = function () { + that.direction = undefined; + }; + + this.setMapPositionTargetWithConviction = function (cx, cy) { + that.setMapPositionTarget(cx, cy); + that.movingWithConviction = true; + // that.resetDirection(); + }; + + this.follow = function (sprite) { + trackedSpriteToMoveToward = sprite; + // that.resetDirection(); + }; + + this.stopFollowing = function () { + trackedSpriteToMoveToward = false; + }; + + this.onHitting = function (objectToHit, callback) { + if (hittableObjects[objectToHit.id]) { + return hittableObjects[objectToHit.id].callbacks.push(callback); + } + + hittableObjects[objectToHit.id] = { + object: objectToHit, + callbacks: [ callback ] + }; + }; + + this.deleteOnNextCycle = function () { + that.deleted = true; + }; + + this.occupiesZIndex = function (z) { + return zIndexesOccupied.indexOf(z) >= 0; + }; + + this.hits = function (other) { + var verticalIntersect = false; + var horizontalIntersect = false; + + // Test that THIS has a bottom edge inside of the other object + if (other.getTopHitBoxEdge(that.mapPosition[2]) <= that.getBottomHitBoxEdge(that.mapPosition[2]) && other.getBottomHitBoxEdge(that.mapPosition[2]) >= that.getBottomHitBoxEdge(that.mapPosition[2])) { + verticalIntersect = true; + } + + // Test that THIS has a top edge inside of the other object + if (other.getTopHitBoxEdge(that.mapPosition[2]) <= that.getTopHitBoxEdge(that.mapPosition[2]) && other.getBottomHitBoxEdge(that.mapPosition[2]) >= that.getTopHitBoxEdge(that.mapPosition[2])) { + verticalIntersect = true; + } + + // Test that THIS has a right edge inside of the other object + if (other.getLeftHitBoxEdge(that.mapPosition[2]) <= that.getRightHitBoxEdge(that.mapPosition[2]) && other.getRightHitBoxEdge(that.mapPosition[2]) >= that.getRightHitBoxEdge(that.mapPosition[2])) { + horizontalIntersect = true; + } + + // Test that THIS has a left edge inside of the other object + if (other.getLeftHitBoxEdge(that.mapPosition[2]) <= that.getLeftHitBoxEdge(that.mapPosition[2]) && other.getRightHitBoxEdge(that.mapPosition[2]) >= that.getLeftHitBoxEdge(that.mapPosition[2])) { + horizontalIntersect = true; + } + + return verticalIntersect && horizontalIntersect; + }; + + this.isAboveOnCanvas = function (cy) { + return (that.canvasY + that.height) < cy; + }; + + this.isBelowOnCanvas = function (cy) { + return (that.canvasY) > cy; + }; + + return that; + } + + Sprite.createObjects = function createObjects(spriteInfoArray, opts) { + if (!Array.isArray(spriteInfoArray)) spriteInfoArray = [ spriteInfoArray ]; + opts = Object.merge(opts, { + rateModifier: 0, + dropRate: 1, + position: [0, 0] + }, false, false); + + function createOne (spriteInfo) { + var position = opts.position; + if (Number.random(100 + opts.rateModifier) <= spriteInfo.dropRate) { + var sprite = new Sprite(spriteInfo.sprite); + sprite.setSpeed(0); + + if (Object.isFunction(position)) { + position = position(); + } + + sprite.setMapPosition(position[0], position[1]); + + if (spriteInfo.sprite.hitBehaviour && spriteInfo.sprite.hitBehaviour.skier && opts.player) { + sprite.onHitting(opts.player, spriteInfo.sprite.hitBehaviour.skier); + } + + return sprite; + } + } + + var objects = spriteInfoArray.map(createOne).remove(undefined); + + return objects; + }; + + global.sprite = Sprite; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.sprite; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/lib/spriteArray.js b/SinglePlayer - Games/Skii Game/js/lib/spriteArray.js new file mode 100644 index 00000000..cce2e5aa --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/lib/spriteArray.js @@ -0,0 +1,39 @@ +(function (global) { + function SpriteArray() { + this.pushHandlers = []; + + return this; + } + + SpriteArray.prototype = Object.create(Array.prototype); + + SpriteArray.prototype.onPush = function(f, retroactive) { + this.pushHandlers.push(f); + + if (retroactive) { + this.each(f); + } + }; + + SpriteArray.prototype.push = function(obj) { + Array.prototype.push.call(this, obj); + this.pushHandlers.each(function(handler) { + handler(obj); + }); + }; + + SpriteArray.prototype.cull = function() { + this.each(function (obj, i) { + if (obj.deleted) { + return (delete this[i]); + } + }); + }; + + global.spriteArray = SpriteArray; +})(this); + + +if (typeof module !== 'undefined') { + module.exports = this.spriteArray; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/main.js b/SinglePlayer - Games/Skii Game/js/main.js new file mode 100644 index 00000000..57512139 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/main.js @@ -0,0 +1,282 @@ +// Global dependencies which return no modules +require('./lib/canvasRenderingContext2DExtensions'); +require('./lib/extenders'); +require('./lib/plugins'); + +// External dependencies +var Hammer = require('hammerjs'); +var Mousetrap = require('br-mousetrap'); + +// Method modules +var isMobileDevice = require('./lib/isMobileDevice'); + +// Game Objects +var SpriteArray = require('./lib/spriteArray'); +var Monster = require('./lib/monster'); +var Sprite = require('./lib/sprite'); +var Snowboarder = require('./lib/snowboarder'); +var Skier = require('./lib/skier'); +var InfoBox = require('./lib/infoBox'); +var Game = require('./lib/game'); + +// Local variables for starting the game +var mainCanvas = document.getElementById('skifree-canvas'); +var dContext = mainCanvas.getContext('2d'); +var imageSources = [ 'sprite-characters.png', 'skifree-objects.png' ]; +var global = this; +var infoBoxControls = 'Use the mouse or WASD to control the player'; +if (isMobileDevice()) infoBoxControls = 'Tap or drag on the piste to control the player'; +var sprites = require('./spriteInfo'); + +var pixelsPerMetre = 18; +var distanceTravelledInMetres = 0; +var monsterDistanceThreshold = 2000; +var livesLeft = 5; +var highScore = 0; +var loseLifeOnObstacleHit = false; +var dropRates = {smallTree: 4, tallTree: 2, jump: 1, thickSnow: 1, rock: 1}; +if (localStorage.getItem('highScore')) highScore = localStorage.getItem('highScore'); + +function loadImages (sources, next) { + var loaded = 0; + var images = {}; + + function finish () { + loaded += 1; + if (loaded === sources.length) { + next(images); + } + } + + sources.each(function (src) { + var im = new Image(); + im.onload = finish; + im.src = src; + dContext.storeLoadedImage(src, im); + }); +} + +function monsterHitsSkierBehaviour(monster, skier) { + skier.isEatenBy(monster, function () { + livesLeft -= 1; + monster.isFull = true; + monster.isEating = false; + skier.isBeingEaten = false; + monster.setSpeed(skier.getSpeed()); + monster.stopFollowing(); + var randomPositionAbove = dContext.getRandomMapPositionAboveViewport(); + monster.setMapPositionTarget(randomPositionAbove[0], randomPositionAbove[1]); + }); +} + +function startNeverEndingGame (images) { + var player; + var startSign; + var infoBox; + var game; + + function resetGame () { + distanceTravelledInMetres = 0; + livesLeft = 5; + highScore = localStorage.getItem('highScore'); + game.reset(); + game.addStaticObject(startSign); + } + + function detectEnd () { + if (!game.isPaused()) { + highScore = localStorage.setItem('highScore', distanceTravelledInMetres); + infoBox.setLines([ + 'Game over!', + 'Hit space to restart' + ]); + game.pause(); + game.cycle(); + } + } + + function randomlySpawnNPC(spawnFunction, dropRate) { + var rateModifier = Math.max(800 - mainCanvas.width, 0); + if (Number.random(1000 + rateModifier) <= dropRate) { + spawnFunction(); + } + } + + function spawnMonster () { + var newMonster = new Monster(sprites.monster); + var randomPosition = dContext.getRandomMapPositionAboveViewport(); + newMonster.setMapPosition(randomPosition[0], randomPosition[1]); + newMonster.follow(player); + newMonster.setSpeed(player.getStandardSpeed()); + newMonster.onHitting(player, monsterHitsSkierBehaviour); + + game.addMovingObject(newMonster, 'monster'); + } + + function spawnBoarder () { + var newBoarder = new Snowboarder(sprites.snowboarder); + var randomPositionAbove = dContext.getRandomMapPositionAboveViewport(); + var randomPositionBelow = dContext.getRandomMapPositionBelowViewport(); + newBoarder.setMapPosition(randomPositionAbove[0], randomPositionAbove[1]); + newBoarder.setMapPositionTarget(randomPositionBelow[0], randomPositionBelow[1]); + newBoarder.onHitting(player, sprites.snowboarder.hitBehaviour.skier); + + game.addMovingObject(newBoarder); + } + + player = new Skier(sprites.skier); + player.setMapPosition(0, 0); + player.setMapPositionTarget(0, -10); + if ( loseLifeOnObstacleHit ) { + player.setHitObstacleCb(function() { + livesLeft -= 1; + }); + } + + game = new Game(mainCanvas, player); + + startSign = new Sprite(sprites.signStart); + game.addStaticObject(startSign); + startSign.setMapPosition(-50, 0); + dContext.followSprite(player); + + infoBox = new InfoBox({ + initialLines : [ + 'SkiFree.js', + infoBoxControls, + 'Travelled 0m', + 'High Score: ' + highScore, + 'Skiers left: ' + livesLeft, + 'Created by Dan Hough (@basicallydan)' + ], + position: { + top: 15, + right: 10 + } + }); + + game.beforeCycle(function () { + var newObjects = []; + if (player.isMoving) { + newObjects = Sprite.createObjects([ + { sprite: sprites.smallTree, dropRate: dropRates.smallTree }, + { sprite: sprites.tallTree, dropRate: dropRates.tallTree }, + { sprite: sprites.jump, dropRate: dropRates.jump }, + { sprite: sprites.thickSnow, dropRate: dropRates.thickSnow }, + { sprite: sprites.rock, dropRate: dropRates.rock }, + ], { + rateModifier: Math.max(800 - mainCanvas.width, 0), + position: function () { + return dContext.getRandomMapPositionBelowViewport(); + }, + player: player + }); + } + if (!game.isPaused()) { + game.addStaticObjects(newObjects); + + randomlySpawnNPC(spawnBoarder, 0.1); + distanceTravelledInMetres = parseFloat(player.getPixelsTravelledDownMountain() / pixelsPerMetre).toFixed(1); + + if (distanceTravelledInMetres > monsterDistanceThreshold) { + randomlySpawnNPC(spawnMonster, 0.001); + } + + infoBox.setLines([ + 'SkiFree.js', + infoBoxControls, + 'Travelled ' + distanceTravelledInMetres + 'm', + 'Skiers left: ' + livesLeft, + 'High Score: ' + highScore, + 'Created by Dan Hough (@basicallydan)', + 'Current Speed: ' + player.getSpeed()/*, + 'Skier Map Position: ' + player.mapPosition[0].toFixed(1) + ', ' + player.mapPosition[1].toFixed(1), + 'Mouse Map Position: ' + mouseMapPosition[0].toFixed(1) + ', ' + mouseMapPosition[1].toFixed(1)*/ + ]); + } + }); + + game.afterCycle(function() { + if (livesLeft === 0) { + detectEnd(); + } + }); + + game.addUIElement(infoBox); + + $(mainCanvas) + .mousemove(function (e) { + game.setMouseX(e.pageX); + game.setMouseY(e.pageY); + player.resetDirection(); + player.startMovingIfPossible(); + }) + .bind('click', function (e) { + game.setMouseX(e.pageX); + game.setMouseY(e.pageY); + player.resetDirection(); + player.startMovingIfPossible(); + }) + .focus(); // So we can listen to events immediately + + Mousetrap.bind('f', player.speedBoost); + Mousetrap.bind('t', player.attemptTrick); + Mousetrap.bind(['w', 'up'], function () { + player.stop(); + }); + Mousetrap.bind(['a', 'left'], function () { + if (player.direction === 270) { + player.stepWest(); + } else { + player.turnWest(); + } + }); + Mousetrap.bind(['s', 'down'], function () { + player.setDirection(180); + player.startMovingIfPossible(); + }); + Mousetrap.bind(['d', 'right'], function () { + if (player.direction === 90) { + player.stepEast(); + } else { + player.turnEast(); + } + }); + Mousetrap.bind('m', spawnMonster); + Mousetrap.bind('b', spawnBoarder); + Mousetrap.bind('space', resetGame); + + var hammertime = Hammer(mainCanvas).on('press', function (e) { + e.preventDefault(); + game.setMouseX(e.gesture.center.x); + game.setMouseY(e.gesture.center.y); + }).on('tap', function (e) { + game.setMouseX(e.gesture.center.x); + game.setMouseY(e.gesture.center.y); + }).on('pan', function (e) { + game.setMouseX(e.gesture.center.x); + game.setMouseY(e.gesture.center.y); + player.resetDirection(); + player.startMovingIfPossible(); + }).on('doubletap', function (e) { + player.speedBoost(); + }); + + player.isMoving = false; + player.setDirection(270); + + game.start(); +} + +function resizeCanvas() { + mainCanvas.width = window.innerWidth; + mainCanvas.height = window.innerHeight; +} + +window.addEventListener('resize', resizeCanvas, false); + +resizeCanvas(); + +loadImages(imageSources, startNeverEndingGame); + +this.exports = window; diff --git a/SinglePlayer - Games/Skii Game/js/spriteInfo.js b/SinglePlayer - Games/Skii Game/js/spriteInfo.js new file mode 100644 index 00000000..0686e1a3 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/spriteInfo.js @@ -0,0 +1,178 @@ +(function (global) { + var sprites = { + 'skier' : { + $imageFile : 'sprite-characters.png', + parts : { + blank : [ 0, 0, 0, 0 ], + east : [ 0, 0, 24, 34 ], + esEast : [ 24, 0, 24, 34 ], + sEast : [ 49, 0, 17, 34 ], + south : [ 65, 0, 17, 34 ], + sWest : [ 49, 37, 17, 34 ], + wsWest : [ 24, 37, 24, 34 ], + west : [ 0, 37, 24, 34 ], + hit : [ 0, 78, 31, 31 ], + jumping : [ 84, 0, 32, 34 ], + somersault1 : [ 116, 0, 32, 34 ], + somersault2 : [ 148, 0, 32, 34 ] + }, + hitBoxes: { + 0: [ 7, 20, 27, 34 ] + }, + id : 'player', + hitBehaviour: {} + }, + 'smallTree' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 0, 28, 30, 34 ] + }, + hitBoxes: { + 0: [ 0, 18, 30, 34 ] + }, + hitBehaviour: {} + }, + 'tallTree' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 95, 66, 32, 64 ] + }, + zIndexesOccupied : [0, 1], + hitBoxes: { + 0: [0, 54, 32, 64], + 1: [0, 10, 32, 54] + }, + hitBehaviour: {} + }, + 'thickSnow' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 143, 53, 43, 10 ] + }, + hitBehaviour: {} + }, + 'rock' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 30, 52, 23, 11 ] + }, + hitBehaviour: {} + }, + 'monster' : { + $imageFile : 'sprite-characters.png', + parts : { + sEast1 : [ 64, 112, 26, 43 ], + sEast2 : [ 90, 112, 32, 43 ], + sWest1 : [ 64, 158, 26, 43 ], + sWest2 : [ 90, 158, 32, 43 ], + eating1 : [ 122, 112, 34, 43 ], + eating2 : [ 156, 112, 31, 43 ], + eating3 : [ 187, 112, 31, 43 ], + eating4 : [ 219, 112, 25, 43 ], + eating5 : [ 243, 112, 26, 43 ] + }, + hitBehaviour: {} + }, + 'jump' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 109, 55, 32, 8 ] + }, + hitBehaviour: {} + }, + 'signStart' : { + $imageFile : 'skifree-objects.png', + parts : { + main : [ 260, 103, 42, 27 ] + }, + hitBehaviour: {} + }, + 'snowboarder' : { + $imageFile : 'sprite-characters.png', + parts : { + sEast : [ 73, 229, 20, 29 ], + sWest : [ 95, 228, 26, 30 ] + }, + hitBehaviour: {} + }, + 'emptyChairLift': { + $imageFile : 'skifree-objects.png', + parts: { + main : [ 92, 136, 26, 30 ] + }, + zIndexesOccupied : [1], + } + }; + + function monsterHitsTreeBehaviour(monster) { + monster.deleteOnNextCycle(); + } + + sprites.monster.hitBehaviour.tree = monsterHitsTreeBehaviour; + + function treeHitsMonsterBehaviour(tree, monster) { + monster.deleteOnNextCycle(); + } + + sprites.smallTree.hitBehaviour.monster = treeHitsMonsterBehaviour; + sprites.tallTree.hitBehaviour.monster = treeHitsMonsterBehaviour; + + function skierHitsTreeBehaviour(skier, tree) { + skier.hasHitObstacle(tree); + } + + function treeHitsSkierBehaviour(tree, skier) { + skier.hasHitObstacle(tree); + } + + sprites.smallTree.hitBehaviour.skier = treeHitsSkierBehaviour; + sprites.tallTree.hitBehaviour.skier = treeHitsSkierBehaviour; + + function rockHitsSkierBehaviour(rock, skier) { + skier.hasHitObstacle(rock); + } + + sprites.rock.hitBehaviour.skier = rockHitsSkierBehaviour; + + function skierHitsJumpBehaviour(skier, jump) { + skier.hasHitJump(jump); + } + + function jumpHitsSkierBehaviour(jump, skier) { + skier.hasHitJump(jump); + } + + sprites.jump.hitBehaviour.skier = jumpHitsSkierBehaviour; + +// Really not a fan of this behaviour. +/* function skierHitsThickSnowBehaviour(skier, thickSnow) { + // Need to implement this properly + skier.setSpeed(2); + setTimeout(function() { + skier.resetSpeed(); + }, 700); + } + + function thickSnowHitsSkierBehaviour(thickSnow, skier) { + // Need to implement this properly + skier.setSpeed(2); + setTimeout(function() { + skier.resetSpeed(); + }, 300); + }*/ + + // sprites.thickSnow.hitBehaviour.skier = thickSnowHitsSkierBehaviour; + + function snowboarderHitsSkierBehaviour(snowboarder, skier) { + skier.hasHitObstacle(snowboarder); + } + + sprites.snowboarder.hitBehaviour.skier = snowboarderHitsSkierBehaviour; + + global.spriteInfo = sprites; +})( this ); + + +if (typeof module !== 'undefined') { + module.exports = this.spriteInfo; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/vendor/jquery-1.8.3.min.js b/SinglePlayer - Games/Skii Game/js/vendor/jquery-1.8.3.min.js new file mode 100644 index 00000000..38837795 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/vendor/jquery-1.8.3.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/js/vendor/modernizr-2.6.2.min.js b/SinglePlayer - Games/Skii Game/js/vendor/modernizr-2.6.2.min.js new file mode 100644 index 00000000..f65d4797 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/js/vendor/modernizr-2.6.2.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.6.2 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load + */ +;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f-1)ha(e.wa?a.prototype:a,d,e.method)})},extend:function(b,c,d){E(a,d!==n,c,b)}})}}function E(a,b,c,d){var e=b?a.prototype:a,f;ga(a);G(d,function(h,i){f=e[h];if(typeof c==="function")i=ia(e[h],i,c);if(c!==n||!e[h])ha(e,h,i);a.SugarMethods[h]={wa:b,method:i,Da:f}})} +function H(a,b,c,d,e){var f={};d=C(d)?d.split(","):d;d.forEach(function(h,i){e(f,h,i)});E(a,b,c,f)}function ia(a,b,c){return function(){return a&&(c===k||!c.apply(this,arguments))?a.apply(this,arguments):b.apply(this,arguments)}}function ha(a,b,c){if(ca)p.defineProperty(a,b,{value:c,configurable:k,enumerable:n,writable:k});else a[b]=c}function F(a,b){var c=[],d;for(d=0;d=b;){e.push(a);c&&c.call(this,a);a+=d||1}return e}function N(a,b,c){c=v[c||"round"];var d=v.pow(10,v.abs(b||0));if(b<0)d=1/d;return c(a*d)/d}function qa(a,b){return N(a,b,"floor")}function O(a,b,c,d){d=v.abs(a).toString(d||10);d=ra(b-d.replace(/\.\d+/,"").length,"0")+d;if(c||a<0)d=(a<0?"-":"+")+d;return d} +function sa(a){if(a>=11&&a<=13)return"th";else switch(a%10){case 1:return"st";case 2:return"nd";case 3:return"rd";default:return"th"}}function ta(){return"\t\n\u000b\u000c\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u2028\u2029\u3000\ufeff"}function ra(a,b){return q(v.max(0,I(a)?a:1)+1).join(b||"")}function ua(a,b){var c=a.toString().match(/[^/]*$/)[0];if(b)c=(c+b).split("").sort().join("").replace(/([gimy])\1+/g,"$1");return c} +function P(a){C(a)||(a=t(a));return a.replace(/([\\/'*+?|()\[\]{}.^$])/g,"\\$1")}function va(a,b){var c=typeof a,d,e,f,h,i,j;if(c==="string")return a;f=p.prototype.toString.call(a);d=ma(a);e=f==="[object Array]";if(a!=l&&d||e){b||(b=[]);if(b.length>1)for(j=b.length;j--;)if(b[j]===a)return"CYC";b.push(a);d=t(a.constructor);h=e?a:p.keys(a).sort();for(j=0;j>0);if(c<0)c=e+c;if(!f&&c<0||f&&c>=e)c=h;for(;f&&c>=0||!f&&c>>0==e&&e!=4294967295&&e>=c&&d.push(parseInt(e));d.sort().each(function(f){return b.call(a,a[f],f,a)});return a}function Fa(a,b,c,d,e){var f,h;S(a,function(i,j,g){if(Ca(i,b,g,[i,j,g])){f=i;h=j;return n}},c,d);return e?h:f} +function Ga(a,b){var c=[],d={},e;S(a,function(f,h){e=b?R(f,b,a,[f,h,a]):f;Ha(d,e)||c.push(f)});return c}function Ia(a,b,c){var d=[],e={};b.each(function(f){Ha(e,f)});a.each(function(f){var h=va(f),i=!wa(f);if(Ja(e,h,f,i)!=c){var j=0;if(i)for(h=e[h];je||i&&g0)c=b}catch(d){}a=a.concat(c)});return a}}); +E(q,k,n,{find:function(a,b,c){return Fa(this,a,b,c)},findAll:function(a,b,c){var d=[];S(this,function(e,f,h){Ca(e,a,h,[e,f,h])&&d.push(e)},b,c);return d},findIndex:function(a,b,c){a=Fa(this,a,b,c,k);return K(a)?-1:a},count:function(a){if(K(a))return this.length;return this.findAll(a).length},removeAt:function(a,b){if(K(a))return this;if(K(b))b=a;for(var c=0;c<=b-a;c++)this.splice(a,1);return this},include:function(a,b){return this.clone().add(a,b)},exclude:function(){return q.prototype.remove.apply(this.clone(), +arguments)},clone:function(){return na([],this)},unique:function(a){return Ga(this,a)},flatten:function(a){return Ka(this,a)},union:function(){return Ga(this.concat(La(arguments)))},intersect:function(){return Ia(this,La(arguments),n)},subtract:function(){return Ia(this,La(arguments),k)},at:function(){return xa(this,arguments)},first:function(a){if(K(a))return this[0];if(a<0)a=0;return this.slice(0,a)},last:function(a){if(K(a))return this[this.length-1];return this.slice(this.length-a<0?0:this.length- +a)},from:function(a){return this.slice(a)},to:function(a){if(K(a))a=this.length;return this.slice(0,a)},min:function(a,b){return Ma(this,a,"min",b)},max:function(a,b){return Ma(this,a,"max",b)},least:function(a,b){return Ma(this.groupBy.apply(this,[a]),"length","min",b)},most:function(a,b){return Ma(this.groupBy.apply(this,[a]),"length","max",b)},sum:function(a){a=a?this.map(a):this;return a.length>0?a.reduce(function(b,c){return b+c}):0},average:function(a){a=a?this.map(a):this;return a.length>0? +a.sum()/a.length:0},inGroups:function(a,b){var c=arguments.length>1,d=this,e=[],f=N(this.length/a,void 0,"ceil");pa(0,a-1,function(h){h=h*f;var i=d.slice(h,h+f);c&&i.lengthh?1:0;return f*(b?-1:1)});return c},randomize:function(){for(var a=this.concat(),b,c,d=a.length;d;b=parseInt(v.random()* +d),c=a[--d],a[d]=a[b],a[b]=c);return a},zip:function(){var a=F(arguments);return this.map(function(b,c){return[b].concat(a.map(function(d){return c in d?d[c]:l}))})},sample:function(a){var b=this.randomize();return arguments.length>0?b.slice(0,a):b[0]},each:function(a,b,c){S(this,a,b,c);return this},add:function(a,b){if(!B(u(b))||isNaN(b))b=this.length;q.prototype.splice.apply(this,[b,0].concat(a));return this},remove:function(){var a,b=this;F(arguments,function(c){for(a=0;a0&&!A(a[0])},"map,every,all,some,any,none,filter",function(a,b){a[b]=function(c){return this[b](function(d,e){return b==="map"?R(d,c,this,[d,e,this]):Ca(d,c,this,[d,e,this])})}})})(); +(function(){q[Ta]="A\u00c1\u00c0\u00c2\u00c3\u0104BC\u0106\u010c\u00c7D\u010e\u00d0E\u00c9\u00c8\u011a\u00ca\u00cb\u0118FG\u011eH\u0131I\u00cd\u00cc\u0130\u00ce\u00cfJKL\u0141MN\u0143\u0147\u00d1O\u00d3\u00d2\u00d4PQR\u0158S\u015a\u0160\u015eT\u0164U\u00da\u00d9\u016e\u00db\u00dcVWXY\u00ddZ\u0179\u017b\u017d\u00de\u00c6\u0152\u00d8\u00d5\u00c5\u00c4\u00d6".split("").map(function(b){return b+b.toLowerCase()}).join("");var a={};S("A\u00c1\u00c0\u00c2\u00c3\u00c4,C\u00c7,E\u00c9\u00c8\u00ca\u00cb,I\u00cd\u00cc\u0130\u00ce\u00cf,O\u00d3\u00d2\u00d4\u00d5\u00d6,S\u00df,U\u00da\u00d9\u00db\u00dc".split(","), +function(b){var c=b.charAt(0);S(b.slice(1).split(""),function(d){a[d]=c;a[d.toLowerCase()]=c.toLowerCase()})});q[Oa]=k;q[Ra]=a})();Va(Wa);Va(Xa,k);ya(Ya,oa); +var T,$a,ab=["ampm","hour","minute","second","ampm","utc","offset_sign","offset_hours","offset_minutes","ampm"],bb="({t})?\\s*(\\d{1,2}(?:[,.]\\d+)?)(?:{h}([0-5]\\d(?:[,.]\\d+)?)?{m}(?::?([0-5]\\d(?:[,.]\\d+)?){s})?\\s*(?:({t})|(Z)|(?:([+-])(\\d{2,2})(?::?(\\d{2,2}))?)?)?|\\s*({t}))",cb={},db,eb,fb,gb=[],hb=[{ba:"f{1,4}|ms|milliseconds",format:function(a){return V(a,"Milliseconds")}},{ba:"ss?|seconds",format:function(a){return V(a,"Seconds")}},{ba:"mm?|minutes",format:function(a){return V(a,"Minutes")}}, +{ba:"hh?|hours|12hr",format:function(a){a=V(a,"Hours");return a===0?12:a-qa(a/13)*12}},{ba:"HH?|24hr",format:function(a){return V(a,"Hours")}},{ba:"dd?|date|day",format:function(a){return V(a,"Date")}},{ba:"dow|weekday",la:k,format:function(a,b,c){a=V(a,"Day");return b.weekdays[a+(c-1)*7]}},{ba:"MM?",format:function(a){return V(a,"Month")+1}},{ba:"mon|month",la:k,format:function(a,b,c){a=V(a,"Month");return b.months[a+(c-1)*12]}},{ba:"y{2,4}|year",format:function(a){return V(a,"FullYear")}},{ba:"[Tt]{1,2}", +format:function(a,b,c,d){if(b.ampm.length==0)return"";a=V(a,"Hours");b=b.ampm[qa(a/12)];if(d.length===1)b=b.slice(0,1);if(d.slice(0,1)==="T")b=b.toUpperCase();return b}},{ba:"z{1,4}|tz|timezone",text:k,format:function(a,b,c,d){a=a.getUTCOffset();if(d=="z"||d=="zz")a=a.replace(/(\d{2})(\d{2})/,function(e,f){return O(f,d.length)});return a}},{ba:"iso(tz|timezone)",format:function(a){return a.getUTCOffset(k)}},{ba:"ord",format:function(a){a=V(a,"Date");return a+sa(a)}}],ib=[{$:"year",method:"FullYear", +ja:k,da:function(a){return(365+(a?a.isLeapYear()?1:0:0.25))*24*60*60*1E3}},{$:"month",method:"Month",ja:k,da:function(a,b){var c=30.4375,d;if(a){d=a.daysInMonth();if(b<=d.days())c=d}return c*24*60*60*1E3},error:0.919},{$:"week",method:"Week",da:aa(6048E5)},{$:"day",method:"Date",ja:k,da:aa(864E5)},{$:"hour",method:"Hours",da:aa(36E5)},{$:"minute",method:"Minutes",da:aa(6E4)},{$:"second",method:"Seconds",da:aa(1E3)},{$:"millisecond",method:"Milliseconds",da:aa(1)}],jb={}; +function kb(a){na(this,a);this.ga=gb.concat()} +kb.prototype={getMonth:function(a){return B(a)?a-1:this.months.indexOf(a)%12},getWeekday:function(a){return this.weekdays.indexOf(a)%7},oa:function(a){var b;return B(a)?a:a&&(b=this.numbers.indexOf(a))!==-1?(b+1)%10:1},ta:function(a){var b=this;return a.replace(r(this.num,"g"),function(c){return b.oa(c)||""})},ra:function(a){return T.units[this.units.indexOf(a)%8]},ua:function(a){return this.na(a,a[2]>0?"future":"past")},qa:function(a){return this.na(lb(a),"duration")},va:function(a){a=a||this.code; +return a==="en"||a==="en-US"?k:this.variant},ya:function(a){return a===this.ampm[0]},za:function(a){return a&&a===this.ampm[1]},na:function(a,b){var c,d,e=a[0],f=a[1],h=a[2],i=this[b]||this.relative;if(A(i))return i.call(this,e,f,h,b);d=this.units[(this.plural&&e>1?1:0)*8+f]||this.units[f];if(this.capitalizeUnit)d=mb(d);c=this.modifiers.filter(function(j){return j.name=="sign"&&j.value==(h>0?1:-1)})[0];return i.replace(/\{(.*?)\}/g,function(j,g){switch(g){case "num":return e;case "unit":return d; +case "sign":return c.src}})},sa:function(){return this.ma?[this.ma].concat(this.ga):this.ga},addFormat:function(a,b,c,d,e){var f=c||[],h=this,i;a=a.replace(/\s+/g,"[-,. ]*");a=a.replace(/\{([^,]+?)\}/g,function(j,g){var m,o,w,z=g.match(/\?$/);w=g.match(/^(\d+)\??$/);var J=g.match(/(\d)(?:-(\d))?/),M=g.replace(/[^a-z]+$/,"");if(w)m=h.tokens[w[1]];else if(h[M])m=h[M];else if(h[M+"s"]){m=h[M+"s"];if(J){o=[];m.forEach(function(Q,Da){var U=Da%(h.units?8:m.length);if(U>=J[1]&&U<=(J[2]||J[1]))o.push(Q)}); +m=o}m=nb(m)}if(w)w="(?:"+m+")";else{c||f.push(M);w="("+m+")"}if(z)w+="?";return w});if(b){b=ob(bb,h,e);e=["t","[\\s\\u3000]"].concat(h.timeMarker);i=a.match(/\\d\{\d,\d\}\)+\??$/);pb(h,"(?:"+b+")[,\\s\\u3000]+?"+a,ab.concat(f),d);pb(h,a+"(?:[,\\s]*(?:"+e.join("|")+(i?"+":"*")+")"+b+")?",f.concat(ab),d)}else pb(h,a,f,d)}};function qb(a,b){var c;C(a)||(a="");c=jb[a]||jb[a.slice(0,2)];if(b===n&&!c)throw Error("Invalid locale.");return c||$a} +function rb(a,b){function c(g){var m=i[g];if(C(m))i[g]=m.split(",");else m||(i[g]=[])}function d(g,m){g=g.split("+").map(function(o){return o.replace(/(.+):(.+)$/,function(w,z,J){return J.split("|").map(function(M){return z+M}).join("|")})}).join("|");return g.split("|").forEach(m)}function e(g,m,o){var w=[];i[g].forEach(function(z,J){if(m)z+="+"+z.slice(0,3);d(z,function(M,Q){w[Q*o+J]=M.toLowerCase()})});i[g]=w}function f(g,m,o){g="\\d{"+g+","+m+"}";if(o)g+="|(?:"+nb(i.numbers)+")+";return g}function h(g, +m){i[g]=i[g]||m}var i,j;i=new kb(b);c("modifiers");"months,weekdays,units,numbers,articles,tokens,timeMarker,ampm,timeSuffixes,dateParse,timeParse".split(",").forEach(c);j=!i.monthSuffix;e("months",j,12);e("weekdays",j,7);e("units",n,8);e("numbers",n,10);h("code",a);h("date",f(1,2,i.digitDate));h("year","'\\d{2}|"+f(4,4));h("num",function(){var g=["\\d+"].concat(i.articles);if(i.numbers)g=g.concat(i.numbers);return nb(g)}());(function(){var g=[];i.ha={};i.modifiers.forEach(function(m){var o=m.name; +d(m.src,function(w){var z=i[o];i.ha[w]=m;g.push({name:o,src:w,value:m.value});i[o]=z?z+"|"+w:w})});i.day+="|"+nb(i.weekdays);i.modifiers=g})();if(i.monthSuffix){i.month=f(1,2);i.months=pa(1,12).map(function(g){return g+i.monthSuffix})}i.full_month=f(1,2)+"|"+nb(i.months);i.timeSuffixes.length>0&&i.addFormat(ob(bb,i),n,ab);i.addFormat("{day}",k);i.addFormat("{month}"+(i.monthSuffix||""));i.addFormat("{year}"+(i.yearSuffix||""));i.timeParse.forEach(function(g){i.addFormat(g,k)});i.dateParse.forEach(function(g){i.addFormat(g)}); +return jb[a]=i}function pb(a,b,c,d){a.ga.unshift({Ba:d,xa:a,Aa:r("^"+b+"$","i"),to:c})}function mb(a){return a.slice(0,1).toUpperCase()+a.slice(1)}function nb(a){return a.filter(function(b){return!!b}).join("|")}function sb(a,b){var c;if(ma(a[0]))return a;else if(B(a[0])&&!B(a[1]))return[a[0]];else if(C(a[0])&&b)return[tb(a[0]),a[1]];c={};eb.forEach(function(d,e){c[d.$]=a[e]});return[c]} +function tb(a,b){var c={};if(match=a.match(/^(\d+)?\s?(\w+?)s?$/i)){if(K(b))b=parseInt(match[1])||1;c[match[2].toLowerCase()]=b}return c}function ub(a,b){var c={},d,e;b.forEach(function(f,h){d=a[h+1];if(!(K(d)||d==="")){if(f==="year")c.Ca=d.replace(/'/,"");e=parseFloat(d.replace(/'/,"").replace(/,/,"."));c[f]=!isNaN(e)?e:d.toLowerCase()}});return c}function vb(a){a=a.trim().replace(/^(just )?now|\.+$/i,"");return wb(a)} +function wb(a){return a.replace(db,function(b,c,d){var e=0,f=1,h,i;if(c)return b;d.split("").reverse().forEach(function(j){j=cb[j];var g=j>9;if(g){if(h)e+=f;f*=j/(i||1);i=j}else{if(h===n)f*=10;e+=f*j}h=g});if(h)e+=f;return e})} +function xb(a,b,c,d){var e=new s,f=n,h,i,j,g,m,o,w,z,J;e.utc(d);if(fa(a))e.utc(a.isUTC()).setTime(a.getTime());else if(B(a))e.setTime(a);else if(ma(a)){e.set(a,k);g=a}else if(C(a)){h=qb(b);a=vb(a);h&&G(h.sa(),function(M,Q){var Da=a.match(Q.Aa);if(Da){j=Q;i=j.xa;g=ub(Da,j.to,i);g.utc&&e.utc();i.ma=j;if(g.timestamp){g=g.timestamp;return n}if(j.Ba&&!C(g.month)&&(C(g.date)||h.va(b))){z=g.month;g.month=g.date;g.date=z}if(g.year&&g.Ca.length===2)g.year=N(V(new s,"FullYear")/100)*100-N(g.year/100)*100+g.year; +if(g.month){g.month=i.getMonth(g.month);if(g.shift&&!g.unit)g.unit=i.units[7]}if(g.weekday&&g.date)delete g.weekday;else if(g.weekday){g.weekday=i.getWeekday(g.weekday);if(g.shift&&!g.unit)g.unit=i.units[5]}if(g.day&&(z=i.ha[g.day])){g.day=z.value;e.reset();f=k}else if(g.day&&(o=i.getWeekday(g.day))>-1){delete g.day;if(g.num&&g.month){J=function(){var U=e.getWeekday();e.setWeekday(7*(g.num-1)+(U>o?o+7:o))};g.day=1}else g.weekday=o}if(g.date&&!B(g.date))g.date=i.ta(g.date);if(i.za(g.ampm)&&g.hour< +12)g.hour+=12;else if(i.ya(g.ampm)&&g.hour===12)g.hour=0;if("offset_hours"in g||"offset_minutes"in g){e.utc();g.offset_minutes=g.offset_minutes||0;g.offset_minutes+=g.offset_hours*60;if(g.offset_sign==="-")g.offset_minutes*=-1;g.minute-=g.offset_minutes}if(g.unit){f=k;w=i.oa(g.num);m=i.ra(g.unit);if(g.shift||g.edge){w*=(z=i.ha[g.shift])?z.value:0;if(m==="month"&&I(g.date)){e.set({day:g.date},k);delete g.date}if(m==="year"&&I(g.month)){e.set({month:g.month,day:g.date},k);delete g.month;delete g.date}}if(g.sign&& +(z=i.ha[g.sign]))w*=z.value;if(I(g.weekday)){e.set({weekday:g.weekday},k);delete g.weekday}g[m]=(g[m]||0)+w}if(g.year_sign==="-")g.year*=-1;fb.slice(1,4).forEach(function(U,$b){var Eb=g[U.$],Fb=Eb%1;if(Fb){g[fb[$b].$]=N(Fb*(U.$==="second"?1E3:60));g[U.$]=qa(Eb)}});return n}});if(j)if(f)e.advance(g);else{e._utc&&e.reset();yb(e,g,k,n,c)}else{e=a?new s(a):new s;d&&e.addMinutes(e.getTimezoneOffset())}if(g&&g.edge){z=i.ha[g.edge];G(fb.slice(4),function(M,Q){if(I(g[Q.$])){m=Q.$;return n}});if(m==="year")g.fa= +"month";else if(m==="month"||m==="week")g.fa="day";e[(z.value<0?"endOf":"beginningOf")+mb(m)]();z.value===-2&&e.reset()}J&&J();e.utc(n)}return{ea:e,set:g}}function lb(a){var b,c=v.abs(a),d=c,e=0;fb.slice(1).forEach(function(f,h){b=qa(N(c/f.da()*10)/10);if(b>=1){d=b;e=h+1}});return[d,e,a]} +function zb(a,b,c,d){var e,f=qb(d),h=r(/^[A-Z]/);if(a.isValid())if(Date[b])b=Date[b];else{if(A(b)){e=lb(a.millisecondsFromNow());b=b.apply(a,e.concat(f))}}else return"Invalid Date";if(!b&&c){e=e||lb(a.millisecondsFromNow());if(e[1]===0){e[1]=1;e[0]=1}return f.ua(e)}b=b||"long";b=f[b]||b;hb.forEach(function(i){b=b.replace(r("\\{("+i.ba+")(\\d)?\\}",i.la?"i":""),function(j,g,m){j=i.format(a,f,m||1,g);m=g.length;var o=g.match(/^(.)\1+$/);if(i.la){if(m===3)j=j.slice(0,3);if(o||g.match(h))j=mb(j)}else if(o&& +!i.text)j=(B(j)?O(j,m):j.toString()).slice(-m);return j})});return b} +function Ab(a,b,c,d){var e,f,h,i=0,j=0,g=0;e=xb(b,l,l,d);if(c>0){j=g=c;f=k}if(!e.ea.isValid())return n;if(e.set&&e.set.fa){ib.forEach(function(m){if(m.$===e.set.fa)i=m.da(e.ea,a-e.ea)-1});b=mb(e.set.fa);if(e.set.edge||e.set.shift)e.ea["beginningOf"+b]();if(e.set.fa==="month")h=e.ea.clone()["endOf"+b]().getTime();if(!f&&e.set.sign&&e.set.fa!="millisecond"){j=50;g=-50}}f=a.getTime();b=e.ea.getTime();h=h||b+i;h=Bb(a,b,h);return f>=b-j&&f<=h+g} +function Bb(a,b,c){b=new Date(b);a=(new Date(c)).utc(a.isUTC());if(V(a,"Hours")!==23){b=b.getTimezoneOffset();a=a.getTimezoneOffset();if(b!==a)c+=(a-b).minutes()}return c} +function yb(a,b,c,d,e){function f(g){return I(b[g])?b[g]:b[g+"s"]}function h(g){return I(f(g))}var i,j;if(B(b)&&d)b={milliseconds:b};else if(B(b)){a.setTime(b);return a}if(I(b.date))b.day=b.date;G(fb,function(g,m){var o=m.$==="day";if(h(m.$)||o&&h("weekday")){b.fa=m.$;j=+g;return n}else if(c&&m.$!=="week"&&(!o||!h("week")))W(a,m.method,o?1:0)});ib.forEach(function(g){var m=g.$;g=g.method;var o;o=f(m);if(!K(o)){if(d){if(m==="week"){o=(b.day||0)+o*7;g="Date"}o=o*d+V(a,g)}else m==="month"&&h("day")&& +W(a,"Date",15);W(a,g,o);if(d&&m==="month"){m=o;if(m<0)m=m%12+12;m%12!=V(a,"Month")&&W(a,"Date",0)}}});if(!d&&!h("day")&&h("weekday")){i=f("weekday");a.setWeekday(i)}(function(){var g=new s;return e===-1&&a>g||e===1&&as.create(a).getTime()-(b||0)},isBefore:function(a,b){return this.getTime()d},isLeapYear:function(){var a=V(this,"FullYear");return a%4===0&&a%100!==0||a%400===0},daysInMonth:function(){return 32-V(new s(V(this,"FullYear"),V(this,"Month"),32),"Date")},format:function(a,b){return zb(this,a,n,b)},relative:function(a,b){if(C(a)){b=a;a=l}return zb(this,a,k,b)},is:function(a,b,c){var d,e;if(this.isValid()){if(C(a)){a=a.trim().toLowerCase(); +e=this.clone().utc(c);switch(k){case a==="future":return this.getTime()>(new s).getTime();case a==="past":return this.getTime()<(new s).getTime();case a==="weekday":return V(e,"Day")>0&&V(e,"Day")<6;case a==="weekend":return V(e,"Day")===0||V(e,"Day")===6;case (d=T.weekdays.indexOf(a)%7)>-1:return V(e,"Day")===d;case (d=T.months.indexOf(a)%12)>-1:return V(e,"Month")===d}}return Ab(this,a,b,c)}},reset:function(a){var b={},c;a=a||"hours";if(a==="date")a="days";c=ib.some(function(d){return a===d.$|| +a===d.$+"s"});b[a]=a.match(/^days?/)?1:0;return c?this.set(b,k):this},clone:function(){var a=new s(this.getTime());a.utc(this.isUTC());return a}});s.extend({iso:function(){return this.toISOString()},getWeekday:s.prototype.getDay,getUTCWeekday:s.prototype.getUTCDay}); +function Cb(a,b){function c(){return N(this*b)}function d(){return X(arguments)[a.ia](this)}function e(){return X(arguments)[a.ia](-this)}var f=a.$,h={};h[f]=c;h[f+"s"]=c;h[f+"Before"]=e;h[f+"sBefore"]=e;h[f+"Ago"]=e;h[f+"sAgo"]=e;h[f+"After"]=d;h[f+"sAfter"]=d;h[f+"FromNow"]=d;h[f+"sFromNow"]=d;u.extend(h)}u.extend({duration:function(a){return qb(a).qa(this)}}); +T=$a=s.addLocale("en",{plural:k,timeMarker:"at",ampm:"am,pm",months:"January,February,March,April,May,June,July,August,September,October,November,December",weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday",units:"millisecond:|s,second:|s,minute:|s,hour:|s,day:|s,week:|s,month:|s,year:|s",numbers:"one,two,three,four,five,six,seven,eight,nine,ten",articles:"a,an,the",tokens:"the,st|nd|rd|th,of","short":"{Month} {d}, {yyyy}","long":"{Month} {d}, {yyyy} {h}:{mm}{tt}",full:"{Weekday} {Month} {d}, {yyyy} {h}:{mm}:{ss}{tt}", +past:"{num} {unit} {sign}",future:"{num} {unit} {sign}",duration:"{num} {unit}",modifiers:[{name:"day",src:"yesterday",value:-1},{name:"day",src:"today",value:0},{name:"day",src:"tomorrow",value:1},{name:"sign",src:"ago|before",value:-1},{name:"sign",src:"from now|after|from|in|later",value:1},{name:"edge",src:"last day",value:-2},{name:"edge",src:"end",value:-1},{name:"edge",src:"first day|beginning",value:1},{name:"shift",src:"last",value:-1},{name:"shift",src:"the|this",value:0},{name:"shift", +src:"next",value:1}],dateParse:["{num} {unit} {sign}","{sign} {num} {unit}","{month} {year}","{shift} {unit=5-7}","{0?} {date}{1}","{0?} {edge} of {shift?} {unit=4-7?}{month?}{year?}"],timeParse:["{0} {num}{1} {day} of {month} {year?}","{weekday?} {month} {date}{1?} {year?}","{date} {month} {year}","{date} {month}","{shift} {weekday}","{shift} week {weekday}","{weekday} {2?} {shift} week","{num} {unit=4-5} {sign} {day}","{0?} {date}{1} of {month}","{0?}{month?} {date?}{1?} of {shift} {unit=6-7}"]}); +fb=ib.concat().reverse();eb=ib.concat();eb.splice(2,1); +H(s,k,n,ib,function(a,b,c){function d(g){g=g/h;var m=g%1,o=b.error||0.999;if(m&&v.abs(m%1)>o)g=N(g);return parseInt(g)}var e=b.$,f=mb(e),h=b.da(),i,j;b.ia="add"+f+"s";i=function(g,m){return d(this.getTime()-s.create(g,m).getTime())};j=function(g,m){return d(s.create(g,m).getTime()-this.getTime())};a[e+"sAgo"]=j;a[e+"sUntil"]=j;a[e+"sSince"]=i;a[e+"sFromNow"]=i;a[b.ia]=function(g,m){var o={};o[e]=g;return this.advance(o,m)};Cb(b,h);c<3&&["Last","This","Next"].forEach(function(g){a["is"+g+f]=function(){return this.is(g+ +" "+e)}});if(c<4){a["beginningOf"+f]=function(){var g={};switch(e){case "year":g.year=V(this,"FullYear");break;case "month":g.month=V(this,"Month");break;case "day":g.day=V(this,"Date");break;case "week":g.weekday=0}return this.set(g,k)};a["endOf"+f]=function(){var g={hours:23,minutes:59,seconds:59,milliseconds:999};switch(e){case "year":g.month=11;g.day=31;break;case "month":g.day=this.daysInMonth();break;case "week":g.weekday=6}return this.set(g,k)}}}); +T.addFormat("([+-])?(\\d{4,4})[-.]?{full_month}[-.]?(\\d{1,2})?",k,["year_sign","year","month","date"],n,k);T.addFormat("(\\d{1,2})[-.\\/]{full_month}(?:[-.\\/](\\d{2,4}))?",k,["date","month","year"],k);T.addFormat("{full_month}[-.](\\d{4,4})",n,["month","year"]);T.addFormat("\\/Date\\((\\d+(?:\\+\\d{4,4})?)\\)\\/",n,["timestamp"]);T.addFormat(ob(bb,T),n,ab);gb=T.ga.slice(0,7).reverse();T.ga=T.ga.slice(7).concat(gb);H(s,k,n,"short,long,full",function(a,b){a[b]=function(c){return zb(this,b,n,c)}}); +"\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u767e\u5343\u4e07".split("").forEach(function(a,b){if(b>9)b=v.pow(10,b-9);cb[a]=b});"\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19".split("").forEach(function(a,b){cb[a]=b});db=r("([\u671f\u9031\u5468])?([\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u767e\u5343\u4e07\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19]+)(?!\u6628)","g"); +(function(){var a="today,yesterday,tomorrow,weekday,weekend,future,past".split(","),b=T.weekdays.slice(0,7),c=T.months.slice(0,12);H(s,k,n,a.concat(b).concat(c),function(d,e){d["is"+mb(e)]=function(f){return this.is(e,0,f)}})})();(function(){s.extend({utc:{create:function(){return X(arguments,0,k)},past:function(){return X(arguments,-1,k)},future:function(){return X(arguments,1,k)}}},n,n)})(); +s.extend({RFC1123:"{Dow}, {dd} {Mon} {yyyy} {HH}:{mm}:{ss} {tz}",RFC1036:"{Weekday}, {dd}-{Mon}-{yy} {HH}:{mm}:{ss} {tz}",ISO8601_DATE:"{yyyy}-{MM}-{dd}",ISO8601_DATETIME:"{yyyy}-{MM}-{dd}T{HH}:{mm}:{ss}.{fff}{isotz}"},n,n); +DateRange=function(a,b){this.start=s.create(a);this.end=s.create(b)};DateRange.prototype.toString=function(){return this.isValid()?this.start.full()+".."+this.end.full():"Invalid DateRange"}; +E(DateRange,k,n,{isValid:function(){return this.start=b.start&&c<=b.end})},every:function(a,b){var c=this.start.clone(),d=[],e=0,f,h;if(C(a)){c.advance(tb(a,0),k);f=tb(a);h=a.toLowerCase()==="day"}else f={milliseconds:a};for(;c<=this.end;){d.push(c);b&&b(c,e);if(h&&V(c,"Hours")===23){c=c.clone();W(c, +"Hours",48)}else c=c.clone().advance(f,k);e++}return d},union:function(a){return new DateRange(this.starta.end?this.end:a.end)},intersect:function(a){return new DateRange(this.start>a.start?this.start:a.start,this.endb-2)){e.push([this,arguments]);h()}}var d=this,e=[],f=n,h,i,j;a=a||1;b=b||Infinity;i=N(a,void 0,"ceil");j=N(i/a);h=function(){if(!(f||e.length==0)){for(var g=v.max(e.length-j,0);e.length>g;)Function.prototype.apply.apply(d,e.shift());Db(c,i,function(){f=n;h()});f=k}};return c},delay:function(a){var b=F(arguments).slice(1);Db(this,a,this,this,b);return this},throttle:function(a){return this.lazy(a,1)},debounce:function(a){function b(){b.cancel(); +Db(b,a,c,this,arguments)}var c=this;return b},cancel:function(){if(da(this.timers))for(;this.timers.length>0;)clearTimeout(this.timers.shift());return this},after:function(a){var b=this,c=0,d=[];if(B(a)){if(a===0){b.call();return b}}else a=1;return function(){var e;d.push(F(arguments));c++;if(c==a){e=b.call(this,d);c=0;d=[];return e}}},once:function(){var a=this;return function(){return L(a,"memo")?a.memo:a.memo=a.apply(this,arguments)}},fill:function(){var a=this,b=F(arguments);return function(){var c= +F(arguments);b.forEach(function(d,e){if(d!=l||e>=c.length)c.splice(e,0,d)});return a.apply(this,c)}}}); +function Gb(a,b,c,d,e,f){var h=a.toFixed(20),i=h.search(/\./);h=h.search(/[1-9]/);i=i-h;if(i>0)i-=1;e=v.max(v.min((i/3).floor(),e===n?c.length:e),-d);d=c.charAt(e+d-1);if(i<-9){e=-3;b=i.abs()-9;d=c.slice(0,1)}return(a/(f?(2).pow(10*e):(10).pow(e*3))).round(b||0).format()+d.trim()} +E(u,n,n,{random:function(a,b){var c,d;if(arguments.length==1){b=a;a=0}c=v.min(a||0,K(b)?1:b);d=v.max(a||0,K(b)?1:b)+1;return qa(v.random()*(d-c)+c)}}); +E(u,k,n,{log:function(a){return v.log(this)/(a?v.log(a):1)},abbr:function(a){return Gb(this,a,"kmbt",0,4)},metric:function(a,b){return Gb(this,a,"n\u03bcm kMGTPE",4,K(b)?1:b)},bytes:function(a,b){return Gb(this,a,"kMGTPE",0,K(b)?4:b,k)+"B"},isInteger:function(){return this%1==0},isOdd:function(){return!isNaN(this)&&!this.isMultipleOf(2)},isEven:function(){return this.isMultipleOf(2)},isMultipleOf:function(a){return this%a===0},format:function(a,b,c){var d,e,f,h="";if(K(b))b=",";if(K(c))c=".";d=(B(a)? +N(this,a||0).toFixed(v.max(a,0)):this.toString()).replace(/^-/,"").split(".");e=d[0];f=d[1];for(d=e.length;d>0;d-=3){if(d2},{startsWith:function(a,b,c){var d=this;if(b)d=d.slice(b);if(K(c))c=k;a=D(a)?a.source.replace("^",""):P(a);return r("^"+a,c?"":"i").test(d)},endsWith:function(a,b,c){var d=this;if(I(b))d=d.slice(0,b);if(K(c))c=k;a=D(a)?a.source.replace("$",""):P(a);return r(a+"$",c?"":"i").test(d)}}); +E(t,k,n,{escapeRegExp:function(){return P(this)},escapeURL:function(a){return a?encodeURIComponent(this):encodeURI(this)},unescapeURL:function(a){return a?decodeURI(this):decodeURIComponent(this)},escapeHTML:function(){return this.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},unescapeHTML:function(){return this.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g, +"'").replace(///g,"/")},encodeBase64:function(){return Lb(this)},decodeBase64:function(){return Mb(this)},each:function(a,b){var c,d;if(A(a)){b=a;a=/[\s\S]/g}else if(a)if(C(a))a=r(P(a),"gi");else{if(D(a))a=r(a.source,ua(a,"g"))}else a=/[\s\S]/g;c=this.match(a)||[];if(b)for(d=0;d +0?"_":"")+a.toLowerCase()}).replace(/([A-Z\d]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").toLowerCase()},camelize:function(a){return this.underscore().replace(/(^|_)([^_]+)/g,function(b,c,d,e){b=d;b=(c=t.Inflector)&&c.acronyms[b];b=C(b)?b:void 0;e=a!==n||e>0;if(b)return e?b:b.toLowerCase();return e?d.capitalize():d})},spacify:function(){return this.underscore().replace(/_/g," ")},stripTags:function(){var a=this;ja(arguments.length>0?arguments:[""],function(b){a=a.replace(r("]*>","gi"),"")});return a},removeTags:function(){var a=this;ja(arguments.length>0?arguments:["\\S+"],function(b){b=r("<("+b+")[^<>]*(?:\\/>|>.*?<\\/\\1>)","gi");a=a.replace(b,"")});return a},truncate:function(a,b,c,d){var e="",f="",h=this.toString(),i="["+ta()+"]+",j="[^"+ta()+"]*",g=r(i+j+"$");d=K(d)?"...":t(d);if(h.length<=a)return h;switch(c){case "left":a=h.length-a;e=d;h=h.slice(a);g=r("^"+j+i);break;case "middle":a=qa(a/2);f=d+h.slice(h.length-a).trimLeft();h=h.slice(0,a);break;default:a= +a;f=d;h=h.slice(0,a)}if(b===n&&this.slice(a,a+1).match(/\S/))h=h.remove(g);return e+h+f},pad:function(a,b){return ra(b,a)+this+ra(b,a)},padLeft:function(a,b){return ra(b,a)+this},padRight:function(a,b){return this+ra(b,a)},first:function(a){if(K(a))a=1;return this.substr(0,a)},last:function(a){if(K(a))a=1;return this.substr(this.length-a<0?0:this.length-a)},repeat:function(a){var b="",c=this;if(!B(a)||a<1)return"";for(;a;){if(a&1)b+=c;if(a>>=1)c+=c}return b},toNumber:function(a){var b=this.replace(/,/g, +"");return b.match(/\./)?parseFloat(b):parseInt(b,a||10)},capitalize:function(a){var b;return this.toLowerCase().replace(a?/[\s\S]/g:/^\S/,function(c){var d=c.toUpperCase(),e;e=b?c:d;b=d!==c;return e})},assign:function(){var a={};F(arguments,function(b,c){if(ma(b))na(a,b);else a[c+1]=b});return this.replace(/\{([^{]+?)\}/g,function(b,c){return L(a,c)?a[c]:b})},namespace:function(a){a=a||ba;G(this.split("."),function(b,c){return!!(a=a[c])});return a}});E(t,k,n,{insert:t.prototype.add}); +(function(a){if(this.btoa){Lb=this.btoa;Mb=this.atob}else{var b=/[^A-Za-z0-9\+\/\=]/g;Lb=function(c){var d="",e,f,h,i,j,g,m=0;do{e=c.charCodeAt(m++);f=c.charCodeAt(m++);h=c.charCodeAt(m++);i=e>>2;e=(e&3)<<4|f>>4;j=(f&15)<<2|h>>6;g=h&63;if(isNaN(f))j=g=64;else if(isNaN(h))g=64;d=d+a.charAt(i)+a.charAt(e)+a.charAt(j)+a.charAt(g)}while(m>4;f=(f&15)<<4|i>>2;h=(i&3)<<6|j;d+=t.fromCharCode(e);if(i!=64)d+=t.fromCharCode(f);if(j!=64)d+=t.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 Ef@;phUH||9 literal 0 HcmV?d00001 diff --git a/SinglePlayer - Games/Skii Game/skifree-objects.png b/SinglePlayer - Games/Skii Game/skifree-objects.png new file mode 100644 index 0000000000000000000000000000000000000000..5a9e1723c4ebec4bbc866d2ad6932f455109befa GIT binary patch literal 10203 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 literal 0 HcmV?d00001 diff --git a/SinglePlayer - Games/Skii Game/sprite-characters.png b/SinglePlayer - Games/Skii Game/sprite-characters.png new file mode 100644 index 0000000000000000000000000000000000000000..3509bf09a9fd76852f9d6edead031bd2420a31de GIT binary patch literal 24664 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

@_XFAKJTeoi$1-^s1@olhqp*PFH(one{{ zK9oFY+?9)GlT^j!*!tPagh^?h=w)VctIo_|uQHSHn!5=p_;t{{0EWNaQp zjexK}HRXv3rRn%daa@>8KR*398QRTrp(TjsQxiAjvnlTwEB>TnH=n}$Ohb87eB$OV z7^UPkSBm>dTSy}Gcs3ADiZ&7pt7n=c|I;a4{Um9Zw?z)6Av5YDfa>07qLCubQaVDJ zDZFbeqPYVRkX~f^IK>mryQ~>WTH>@Oha0(mqUD-;z0GVrH=^;{0)@N0@l8Pwllze!Lw&MU3L! zO^FLlnT4Ye-`YxP5?|xCi~1ijRC8;Kw5o7c~LMYuZY%02AzVE>!2}QRJ6jD zsJCE;WBc}ye-IGNNAO)QUrlkIupWv2C^-D*YthzUGO7R^dC-84$OjS6>DQY|Ri6-= zQoq;1WG_Ze)@EKEC*$tHV<#gx4#g32pg&h2Pc9@8xfKc@*{VL&_F0rS-z^V zY|FO9sg6>76w3(_Hy>fi1pf?cs!@`|s~SR9ID`TszB>t^=5;zJhj92T7^~ch!9AvI0=$R%%$46&mm|7@RtDY243Rni+G3RbILF5qM6ZjJI|s<--;Foc<{ZH-j2}i%RT2kqQoV`XK(00&Bz+ zo+2Y7P^w&S1uvv9ug9yZJ?mDPSx2t26LI=JTv_LFX}kp2NqZK!@@%BRdI*i1tfEqZ z;2yEDHo3Q`G=5OV>ePUq5^@qkdo&7pnF4x1Ad<5sr+28~chxOSG8KZj@8YylYl(x! zDxAtdA+c5uQK=(W=iS`a`gvi6~WCB!utmf0SU&BV0U0IJp&q%;>e3mnIvPuM1n_g&P9>3B#L zX8*NPj8bj!3&Wm6aK`3KQ{m88vp+|HWl=MI;qdn zQbu%?o;!&T#(-s^j4LQY*|GTT%fJDWh=#3)TxQ&M@~(lfhks_!y5QtRtckXf86!k<8&e zyN4qVPC7ZB?Vxwj5%ow*&XsA_nksTHMdgEw5Y&b&9swuK^A=Hd~NoCqK^rE?Tq z@oFuAh3sh^#fJ83*FaJd9*p-E*7!a&Iw=#8~ePiL88*K=D zC5mUQpCwdrDJJF;mu?puH1lxtG^>Pgo&6Z3hLqyq6#C9tsqV z0w*qCvAN9r{c;}#KAgE62DsE)W~hr~NP^VRR46hZ?bT|+H3PWs3Fh(rYKgs1Z65_O z)=mmk_GK#^uMOxG>|WUpST3S7sWAKI2tImG#xuD3nfhGE*8?4!Fs|*UfbW^Y{W$EW zfTXA3`pufR$9pQ==bj2tBQ#BnpJIVo!xMjWyDF@qe}wxgApF~l%W?8vryV+UU?Xda zYrx_El)u9{Iism(@KV?!F4R1BHT+fZ zs}O_^rw{?t^}+C=@2h}yoLnxf_6{G>z6yAolgl=Jd%KVKRX8)vxJdPr(nS@m#moT~a0-~PQbPNpy-{xYTtnFDPJ0KauDpwsgBbdPMs1K_IC$5WGeXb%^{;LkcoLn6V*_c-g}H3I)@) z<>;*RYu%VkR1J)pQC&xu6MTgX&l$qMxmf-6WUl4v(OYE2D?V*KfKcvhMZ3ceCkOQl z;+q(Q^t<`%DBg+d-Fwuk;_l4KiP8CAZqVki*DgfHw_wzX3*!r-?P}j*o)B%n3phy6 z()m@-$3W@oC^(jP^78q0*vF&kg=!jw)bjwcP*ym+Lot2T1p6A@Q=U z7wKXRgB&T8qZ<#rroU=Jxk7E89v5HOYk(6D!qO)$%S%TDW$FVg{&#i-4Zcs~q;=Uz zc8pay%!^ASD}pU*jqGkeF}9Hm`Y~;k_rbRZaD=tSd-kG0(1UC7YnfwhG4bw_GaDcN zMgnbfC@kG%Z?M3dq48?q4`H8y))GN_fbu*VE3e|rPEd@oZciWDE(FVU_;%iBLq*0o z&5(*d`cfU3RVELA&w>me!03~rJ1IDkxE{Lyc|bc=TiW;i z?5rR}RbKh7o1yv=&NnL&A(E|JEVE%LYG+3OQq8fA8@nzz<3ZMwLhwHa)O&BpP+L@y zS@~>X_5UBaPMF+CFj#FL)c^i4?h|GdCyG6Q`1=j>jxV(>e%@}^*W2}v`HC|^I?O$P zaToc^%piXY3Ub0dU1Bysrd)0*cqKI$$#fwF@8oCkBU^09<0@lca@;==;t(Aj|9| z!@=6Wx|0W}06^${%>kEf)<`jDOXa!4{(|zRK&`ZEA^p!!J#-oN_S z<5mCG-HHtJRyw`5x(n?zz?Rq&uonZHOCM&RYePhT7*seQm~|#dYBSpduGr*2@v4u; zxHN9JppumO$*Yt}6sEIWcNv3wm!G>L*$MZZbAztpTF=hk;o={&F)z1mFh&RD=QDJ959C&c1wgtXm_mm-#&^&hR|NZ z(9Wb17P*q$NZ8qzNy|&@uzG1T_kx`6^P51$iiB_Pv}{Xcgnls@AWM``b1Hxg^j0(F`E-F0P&{cMVmc4IpbY23kvI(?kX){~@y#-h+qvoWr9UXgRKNxR8<{c(HZf$>y?2;*FN%yC}50%+fH**0_~`99jCD_1!y#m^i>4QAfT#dU zzelP)vX7B^ubOHon)4bt2awC3Yr9zi$p@b;T=B+OC+FR2L{A60?ue*^iwgjoq5?v>Eqmk-kt&HAVa~C#i|(_iDa=Uy4Rl0@dF7 zS2UdvK|7i1-=?qXwh&Nth@dv@B>UUZXo35^daaLuXo36vI*DqZo?eUD@0ZrNXR@3p z+hd}*E~5y{%C81T)b=Qu43rcZb+2*mX$oECRYUdnODo+0sI4Ab>N1D#>2W-^)Q>Io zV@v&)%~B_v+NFKzWq&cf;A|z>*3Nz@Z;b8ft4Y7Vc3)r9J-^6YhyVJ5RyPQ#UC`Fw zR)!ia%Pvk#b}&7qTTamD$?uCOd+^wt$;CpG(SkSe(2l?TLP)MJj``{hx`^oLn}Q2Y z{$(q?q1KF7>XYAB9;3|dly%rfRIWc)Dh(e8P%r{j|4iXhqoePNCzZNJMJiR@*H zA=Z5_I8&@Y@21R^$}z9SvkbA+uu>&G^0Lx9M0J==)}*lNY0QFy<8Qx18E*uOLqwi9 zKO5j2Bd*zFW9|7xpbEKGvg1D>6VAm=oLO9Ob^psFuU;hoyMdlP^c*E8p=-(dc1qtR zlRUDFMTcE9_sglF6}t&OdFAK`U8|(uOiPq)#!KupZ`c&DY9XUAt@ z=ytobq88tF82U=-MXy0}mDWk=^rgf%qai3$%DE$obpBI@O~~LPbxjra^vZZT4jBWl z^p5|z^NrodR%o|BSdpNvf69aRAj!>0S`_4nr@k`G4;WFCL-(iK;Xyf^L5 zQ<-H7JMAg}?`7@HWd$fO4)8h>VSilp!_mskPy`RGPT2e-M zd26@V9<|NUfn?X8*e7+O#2zJ@yY>(0860%5pWHLxYLl^~Q1p?Gpr{U^W6!P6>jhTY zS;dKu7I7@NFQKoIdW*yeK&=;{9B@AC`Py5Rh3m`OW-%*lGCJe8eye^fw6{0e9G3(( zfkL-Tt{&J-KC-^dRhll}?*qM$?;msEF$YfLz;Dt1X;8zPX)(XeooeJIo|cDTs?!!( zc7o>R?)OQQy$)F>O8lSaVSWt-HPC4^JrHrSBN;RgYVTnx*{S98s zb{r8@(aKY;#u^e?m-9743`0OWbX|5F9?TFUSG6!62yfkVujWXPmFjuEgPbH~ogAy5 z?PvpgTzV;eMst>{Nt^(Fm$jR0Wd*YqAcYtZip%jzDBh8{Iz~p6Ss%$~is<7D+_Gwn z%sV?$80~)mBEsgXi$UPm}4I}A(0Ko@{OS9T{E3(0>dec54O?c6Ok;uq!%2`O$H*OMUp00w)?Q zzQd?64kBf!iRY|iR@P_)-^mdbTt+?P%GHx!(l+=4 z3jVeeJSm|^v|0Oli`KQID4H|stCO%<{s$()DtCJTxD92?6Fl8e$LIp}ig=xBK}L4Y z(wIUmb)bQ$TD}KX;oFq6`CN-QNG3GB3@A;m=NZ8wrAqrQm2A~ZfWm2Ene~jds0orH z%J;65REJo{5@ov;Y7Tq~Mtk1JkLlE)iC0y51BuIiGnS+f-)>|dU_tJJK!kV0m5$67 zA~Lrg0t3Qpfy`|%D^RUUe+eZjbnb1yF$W>fwl`;&wO!>(noHMkG$)DHQ62=Xw2BUM z1H`3z4;FfAV2aN^(4Y&wkt2mK2kcUXyYfpsF6FmDDVQ3+#ZItCVc+pvu8>F06=R57!9L&|RUZ?@98^QDU(gHd$I7l|{p<=(^FpCUcga{}StKkm3=3kTY2Jjt%h{ z+KHUJ9T3zY%!!;b1Ps!_4Z1b=yW?0rCaYNkR#Shn#PNzF81;+VshqHVg`TYSGvj&nqaqabYMK1SxbjEp_o^S83GJkGmPlqeFK<@A7~vgyo;QKZhsrXamVn zoRTI?D{S1g$3Lem#b{oh1t*08dTYCg`Wy^yRq{&1z<>p$b}Uruph7uv6eqyJ)GCQ4 zw+kj>6I%iv^p-#>YR?vg$^7G-vS`+$cq8kO^wN$$%3B zqy@jyO4TCNV#~uhRTZ{@vy)wlZhN5Rk)dr`in9(Zm&bc(PRZY5SM{;jT~)6VBW}k4 zV08}YB+>5fVk%;0-mKaVvkkihnfhXPmjXu0S&2?^7JkYg6^&k__uA zsO>iaxt5oqY5q2qfoRNj_ejsFoj~J@JAi}?i&uqgdaCVsXUJvTJZk|z)15(P_$@O9 z#}asQXK`7NWbNe6U5!j;<6%>ZKc%?U3Y)5Og$YFDyiHukxLP}^H74GJgWDiURASIP zzzLp#Xh&oJq!T>fed^tJ_^tgtHkz@6TwNQVhHJ)Pet{AgFn$l*N*Wc<;f@ks-?Ifn^5{iVNjshds%@q1rF&vJ+A=WsjK-PmFs?}s zF(PT~u*B=dj(1eIsj0{Yu_PWLB+tQQAcwNAXHd`zHcn9>o2%sOE*$uD&H&ZsDP4^U zAeBJ%p4MHs@2+dz`SyfP8Vr!+fngW8ibzFbmw{EOyK7hHc^a{8S{+GcT;D~vp(xl) z>;4mZHOi=Z%u;<344e?E&d6D%+DbxF_*z{xDaImz+mw1kiv6=tDvi2l9{(7P1(ewH z<;k8T?@9FtcmQoo3HN7qdGOsTxvjV&CGMgLDk;?NMhPsB0bN3sWC?H+3(2f!6ewV* z%}%kq=o%_i>Lfc}R072jQBk$PE<|{lP}A*L#YMECBp%cW%G_c?c=u`MfDT(~g(A~Z zyx%2{g$Nr2T}cnpGU6EuccehlTL*y#s9Im3JtdY?b?-zvA5x2$gQsRV?m=EE4k7+!$Yu$Cm##COnl0* zpzA8I?vE+L8shyGh#4oJfJzpPfsUp=@wm@lg%KjJCzg8A8(HkMLqd0Wtswmx3BN@` zXZgM~p4pk0$|mAzbkEa7s2jY#92~kc&p3l$UVtC$K!nc}OF@D*4&X<<4VGe2d2|D+ z3!J-_m<<(o&Y^Z86#i9)!#I9QO7+;Q=iQ&2;E9Ad@=k$T2i&aIu#j})s>5x2;eMw# z*k(690j-7`KACK#6f2uOW`lM$05wt|Fco7;XVzM3XI4$7I>_<9>e%aPDTHdhot>^`-CT={JHkPN0O9e-lk*epz;_Y|{BD z@L`Ew#bmb|0mu7V=W-pM?AM`nIIghXz)}R#-3TTw3F<)bs=zjdq6M&;dYP&cSHo6P zZ*Oo7js;V5NxPZr=uwoEu!@S`ObN4R6bY-_&faTOfc<65s5@m^JdJ7b$IhY_2?_Q9 zfnENELxoG zH-xz0RnEHtwM-Q_Py=7$r2%32F2DyK4&4ZlCJ|z>Bs(SJBHlbkR3YmyY&W{wn&SnG zglxMpK)wSpFd<-Atw2t6$~8$;XOnUFiOVd+k`!W47)O5WWXER#fYy0$2XM-skb6 z48~I>^4#qrSNHBDkH%#&XmDDaROUPmqgdEa>M{UI@8^xwr2Dr!ozOD2A{!bV^FQ;fUHSowB7SJrb?{TNVimqEL?!f!PsgChiY%N8e zXB3(ZO-;kVAT)0tDq1bRN+~||7hQ%F)MqEAtlKz6mN#9QLBduAwmwffTD1AK9sfd( zQmq~=+N(icBV!JpI|0P)_0I1xs68k`vgxshx%eR9E{u%9^?y)M+fmn1qP`y@YZ}mD zvPYy+J4%#K#%I-0qLtsxd)au7bmKc<&y9WXlJ0(VXwnMCjc4Us&Hu(sI*4S^W0q8OaI8zLr-P9i8!?C4}wup%$q)wA4EBukh|z%mekAU%x3LLIkA@n}viz4-)Z=SjgCDv~tzatY|Qij(w zR5vP}1Dutj&DzbL<&g4_4hc0>tiT$J>6Bqv8fGO+ALw;OZSz^|rO5XO<&0vnG>QC{ zxkBlR@50&-yeJKwrZfm^!L~Z#zuHJdkIS?-!gk?A;`PyZ|Dm1?S~KP|P##2>s^~=m z{^nBTEKC_XIiR4;DLVsg7KLxU;LfQIRH^AR>~21Oc8-_Mh*D&E?*x3^t7!@p9fOAW z!#NSut=l^V>sWQDcUujpF z1H~<lP|*_(B1C7&*7cW@T{$mM z5&P@U)yu9{Xu;msfuIn^G%?0Qk67IMKoJs%PYP9y(uQa& ziQ=LK=@#-*pClUw>sq&NbZ6Y3$CE;jjU@dJ&hj5;=Hz!NF%EP)xb63l3jMkVIVqGr z1n%62b5f}M_uqY-6iTv1bf<={mH>6LckHClBDp784UK%3de{9M@X5V93h4e%3hjii zaP&9FP6`d-J>7zi#^aMhWApZ5zs^l-f15{s%FV|oh3d`j#MHy8Hh-nN&{_BRq);4U zB3f+6I$)VwZ94w(NujW0^Q6#YX5u-Lv|z#tTd$!gdlu=g^_Q5;e(>jy`AMPrj&uST zRhmB7IiWR8H9hT=P~@y;^A4xFsc?v^{Y0|{-OBFqOWaz?1rp*bVe zn|q!S>e@D1`&8$?t{X>wI?&b52aOgr>P{LA)AG8JSV*h$K{>u^suA_b_quz4(?OvM zk9?|M-imuar-P#0>Bem2`U!CZW$N|u>7cN}8qqIsGRAv^2wode=Jo3p0CTMEo_sp! zEdrgi6-Q47-Pu7N8RbMC`>CLI4_%r00*M{AWO*+7qV5Giq#b~6BUOhRM}k_V2}mKY z%ei+*WnhrQn&$3rY>38{xQJshW!@Xyo&`!g4t?Pw(BNkc8pHf4e9i=QmKSI`Jw-Zn+8D4L<4aIZp%b)(yv3}b;GMh^yt#i623eZNH1Qh9DA`Xipn;49d!1=9JVPm#DWB@`y2-3VG3gz@NOCc<&OG>fB=XdVoADQ(amZ=2slH5WfqTwX`yT(cb-?NX$+K7&>%g z&tND2SE4M^3I*h-_y@M|fq?4>xsxb0&>&Z>u%k$oQ)R?)6Fd8y^a)m~su*W&gO7he zI?Q^yu$Q`J@~J1vsQjJrWiWC$x!$E&b|UZ*)K)_K1xiu{%)m_s-C!%DI6ya8z||OF zl7A&r=*1MGICXb?39;A@$E|PKvku=zc#ArgS2VK07T$-mWJ)u<8G->m?l=Y428SM_no zE9cq8BGgh09*pU8#WpIZPEJ(xGE6ENaRro_jU21|Qe3S_nSJyGv4<6-8*T3`~+U5r{Q>_C{=>a*}vD@PfL<^%!4f%N?Oy{Sq?I42h^kF6T}Xo! zI)PCuMg$ZC3o+P)E_?NPl>BADvB;Nd78ow2It(K{3Dm`K%c1Q;si^C8C{uIgis#-S zEV4psOwq=2 zUd}?9Ws2>R!g8zYT+dRlbFFDI_dhCCIi;nCsEBn>%DG_dq}5b>+>oL-pW*0a;W1yoO20WG4X>Ng#gz>ISZ}^ zZh0UlfO8&%K9!1 zv^ii=G+PpXEh!d>7O9ItZwca10awaHJA#_N1A8@GL7D9A0L8p|MB>7qCt^51AFCfz zdo`d*$fE743HkVwWLFrD@7O@+jZ#w;)Z+)T=`!~RsGgrcGjZyED$!i0pmu-ymj7T-sVL zJ(4{f@bps1AMq{@Dg9CdJl@BFhP}Rz1A66(x}_o$AJJY89qA+8&mmeHiL7lTKHNPW z&`Pr_WpW*Ae#AREG|V-uV6h*`jt;^4NOyEt!}w@+bQsZ{lPe$gt`7PHh2;_N>|o(U zT}y9%R69IK0q$%3h)fG<0Chkf;Vut!gTo0&>Kye*>=u6?@Akk-9sR98SGzs98rktm z*K)a&!&Bq8v4I)w=Z*Hzy%?U#;$#PL`dTY@E9h_W_J_%Q(9_({HU>|PY*3;5nFUSw zw6f(O2^iPpxpHqDJ(?bdX2G;Z&#$jb>gide0u%#@?zMcVr#2Fdke`J?w*>LFy3(*<)-%Ps&tw!v=cY6XTvat@N2 zR*7(h-){0aV&iB|!p>oom3-2A3UjV6U}q<1`aiXV-Thqpx{1CD!6gvpIkL2!{lb^s zrc9DqGa&8R+Tw+;kn=s(y|W}9NUN3a4j>t$%ic3#gF>XtIxkS*-q)&lL-voZF%X>S z?1LqmI=#Ehs^`wxaXZ>=mFH@$d=G$CBI$M>UpnyRKvv3DknO$*+j+6pdy`)drDmvX zwVuAfTj--J19pLHN%~5As7wE(ViPY;t~kDMkG1yekT;|Mg>0YK@(NuEtkE_*TXwrV z<%8RMEyZ8)<&Y%}_WfoQ!a)BzR#dg&SW8S}hVc4gd$$d6SpB4h`i(z_fSL`*0{IJa zE#1e^mGO7RkbfPzgC1GbM5DEQsxF79Yw3N1Z=1PSxV{|9*-j1?T$ItYaR;W+pS2#| zxY3M4oS%Z6lD@~9|KfLP-1i9AFXReTN&pAXGQLu!d9W=49Nu=ofztMfd>*Z<^;ZgT zP57;ksmQwr-$)?an!ykz#KPhf`_veHje?Tkr~#7*jGm*OKG3!U8%LBLiOOF-s;p~X z=V9$l(ApYBIT$iWax7q9y;?XQ*6sz%W&LSs7(;6eIm`6=P zfWePuDGWXe+QDPi#q(%_heuT3dh3F>;!)79L^_&a9-1C6lc=B zt_~wj42aXMsHMafV2vJhmjmH~eD4ovL^q39M$=b-X! zJd~UKuJdz8E$di7mt2pKMpFl$!-fCumv7%_5g|UgfOmWEhO& zV4JPGBFT4+DCrZWSLMa)(Q=5$_bNB9?F6>|VEfO?mWUCwp@u% z0KCBq2H6nW#Jhg%Yn`9SId_!yMsy7tgc57~P+~^@nD~JGIe-P`y58jaBJyXSTg~^L z0BmA*`fP4q4LPvMbN~W(Ux~Wb{F#*aY`}yRrItdHcYBm23NaUhA8Vt&n*BCVWYwh2 zZ)lYP6Py!@S~<*E?0Sw(CD3ySqr>6+)ioRy$l>OMZed8hGah5rs2m&jDmq44Q;6JG zY(EV|eYUCXaN;p-Z^Hs>8^${ys!%HwhK11uXAzxD@GZ#}z} z?w;Ko-OJ;k$wlArzrrI)q= zsLPKfmL_eQ=3g4LpesN$9vE26)-bsTpI0`>l_KX)d4j+8N6PdHNFMksAcIHTPfkF6 z%O|+fHh(g1)zLDqOQ8LupsN)XI6+%z=`GOiU5n!8?_!tIP+Q)w?l^CiXY31q>z-|f zupvFACm-zs)4!_yUGVwWu@TwBBjv z>TXps4SBuOkk{SPf#{EZ&{Ed;k_Nfomr1YpYxpIH%>F`hr@{A~ilas8l=!~WvhG$C ztn?b*+p*~M>00!At$iOO)4k~T>*Y}y_w;%K{eJ0Y^h|tlui0||NTcszDIeheKC$290je5)>X2I^nhqhu$8 zv!2?z9Ba$)XB{!SdjEcolEsbBKkccTws@56`n&r-O4bfS!Kj`Yd#`5cU>O=Z3bmG{ zBg$zzt5-*lkCg@rtVzw1uR1<<{q1+?1k|<$HKxN<=D>Fb!`WyR-Z)OPdiNr z<7D-tR%1GH)I377b~X={tx=vCheW)0Dt(}y&Mu!@U~V1)TTYAPH$9!bHzzJnN>_&f z%%IJQEuEa|`MXT#Xb!{stq=AxYpM0woaZ8phWa{sxGbX}z;r^+9^pv`%idHiIF0Kj zVRfb~H{;1?${wWPrZ(K$)W!mwa-uBVJ=opSx>eXPK*L9veD)uPQt^>h2f#6Ozuyac zMqxZQRQK-{#Iv@?RJV;tNy z;3eK>H1xC+WnVxgyu3{Gl|W`bX~^#09-lazbeQZ{z~(fpGf(KU!H5kHlPy$!m6q5D zl$Cn1Qk`^)?3Wox$ZC00PSuWLX+SfhaJ4$7>o7hrC^f1k#R6N1D$wI5-1oS-rwG z+2VOip6ln9e-(jT5?86EfqDUZiiUu>llWhuEO0cX2S1cfbV8Vk(r=9#fYaz}g|x%-yLmO3!@Fyt0< zE04q%Yn%k~T+Ov3VniF)mngi;kRwiVN)^Klumzi?9PZY z6t_A#wvM486k)+kfZSQ&O(PYvYk1V*w!4<_`b4yU5`q-=;_Ny)N)zF9s)wm7PmVR_ zE;|oG&l029(!h|D@miV_A9cx8gkGz-`t06`Q~A*elo_frefh~R#V_OD_nD{SUMhGq zu<{j*#pnujTM(TA;kI&;H6bm;M~l3PdP2@4s6lT%8_f!DVQ@PqmhsPpOLnXduAq|B zB3vwb1uxQ$nB%;rdOKcL`$~q2^lEHENQo@D?SVnW!0#$397Tj&;SMrEvVR(Pq~gb8 z*!#T#?0X2L!RGCYypx<`*dUT?$U=uc{Hr|p(HM_0H`|tDH#PMD7$V9Bl zU^zP;^fK_-oMIsIgDd;#pkVZWo$Xv~K}#UYi9ZPjIc4tRhg!P!sWQ4%A+yWsH{@fm zn@cbju=(Fnb9JFIYo^-YK!v%)@B;VNR7I|u$TyuYp5o~|Bn^|l#U%kcSL=)@+zmAJ zHV|HhhHsF=nvfov$w0p^gdmzSbg$9FLW->fz-~z;kT`2i5U=p`tlD33E+}vC3TXTl z-XZ`r66eUeWyvI=lA>X^Y$O(l#n#kc&>R}gd1yih z@^TCD2Z_p@(gF}pP|g`E16CA*4lcR5IdwK5dyr3_EkMX9;i^?v+jvN^#aSRmi!G{e z3p#_j5Eyz)MK+7K&~8os6wtjbTItX~Sdo|jo;WzT5V}>vf&%P=&W0&-8Bd%xY*1qP z`D;lR6bRm-BP{I7!Zw#hA>VRIzm-Xn0Zjp33mct?;GG4P)XTpF3n0DektDYiltTsp^Ib3sAke zBJCUqQ4Mp1)aF!&rm8QZ=(SXUf(~nXs~?(L_$(hou>4hwp-3ll%Og|WgGOIs6*f>V zS;E5j5~mGYrr@h>@tUl6#Xw4p%CkV);I%_ix71he+K>WHDNq%{hU`&{?~bpGXG+hz zXFPRPP^Cq%Mi>Ydp#<=q@lD3e^kI~}+7ZvcQssJYp{dRk=vS5`y&Rp+n7~gz_0#Y0 zTlKwR2rK49ZG|HnZr;I+fk@| zS{Qx91*dd*6lxsQ^`lS$yKo=~QAxUX9BQ6)WsPvQ%yuGfvNe@1E_n>u@g!3{W5;4N zh_wPoSuwF~d%Who@qM0-iUMd>SsN|jySRxBAgK-iaft2@+X<=ym3RLaGZPD(p3 z6AtyGE3^4Ooeh9BXhA5JxR;itnMg17k!)rE$esHP`)5M%rL0Lp3mOlWf<4`r2jAsa)9gS)6Ae6f9dC2buz5f}zvM&$ns@9k}E|VCw|c zXl2`W^x0ynQCn;!a)FW>8JmMlW$c#8a**kk+v_Ov`%z}=N0>%8RzmA`hV6Byzw9FR zshmSzA*!YBOnA!irR(ad?vE+0r}E}kED)vg0MlQgyeg|Yvh-i@luF5QroU|Uvr$t0_|j5+syCswV@!!;SBxh)deku%JADpHcs2Uibc%wS z=GQ@BjMwWMozj~dPv${TRBdPxDxxy=)mwtK4;_6rhm*{6}MHc<=u z8!cb-+U#0ebF`M5RQ5%+?|0x<`D56mYx@h@)7StQZrFVYyRd~+B*pS^abcY5$*K}@ z2DdzYQSO&Ngu}lM4Zjuwv;1MvK1y^Vrpze7gi5NsJ+E@=fu@>HBvC>6jNb-@{# zY|-sa2m{y+2Br~GWOMDYNF%Kgj>Y6R!x?4eJa2__p1;hfwOg^sd2U{XOT9xBBs%PQ!< zY&6no0wn%q11DYj%}V&0Yg526e31OL*JY321qv=>ktj^tvLavu!9ANITtKAAI9ieO z*c<%9t?4xxFGU40{rgl#b<}#nJ4E=eo}Vs$35b@N@@TvKVXn8%Os`oB@&NbpnsZzg zSnHYzd{(qCpE`}*g$K*De$`h>oPJ8KkEypVK#erc1uURkfzj5~tR4JGGS#}?kEA2; zbU(^fjkYc3({O;)21VxFruv~3945E4zJyvZR{`icYrps@wzsS)kYoZ$$6m(a=trW( zyaHtJyMwW*sP8e2;{v0F&Ie3Y^1g+GhJDmanq)0{QJ1N@)e8EDUULYky%MCz?DPbv zT<`Q1NA!+}RMb|6>>3UbsJRYRRvYdHx zL1#RN?YJF4ddyn=0j2s8A3zFoWP-n&u;5}kZxdAa1@Gjplf1S9Tf+epnqOtX&Faum z*S@D$&0KdofE4bVR&XD}0i+Q829RyjALIbiYXV5IC=w=R<5@w1c)M>8?Eq4`5w%hj zyltKT(O22zPle%12hB2`_;42b9Fx(Q+}A0jd+=vYi;r#l%Fk z8DD?|l;RNF4|eLP1eB<>ZN~;4i4bs)+-x+UwO_l{&9qr=AiZGp!7yRkKneh0OH};& zh;*%%Qq&6iDJP8r7Uj{fsp6Nnyv77aou~jTHL~EMYd~Ht?d5cY|QLRbTSKcRk?9cZ`cc`w2&n(z!0QIwZ9XFsReD z$f%D6wtW|>Rf$V4?vbUGmq-m7wM~Zzs*({##uVH~PFsp7$xM3My@15O0JxPlmJU|q zP=Rhi>OzT>!;+3ptKxp3Zruq7@M#9nSyp9W&pjqkFqdB&kfk7I5Q`X+_@fIH|u&O-O+9pFa!)%d5y{%0E!qoiCW4E3$C!UHE`<&=1 zexcdWapb~*5A}%AIRrSm*UPB5OQc=7B1AH}Fj}yT&zUMQYjgNO-=n4OOfZ0PKyXa& z+7Jb4kDtEZ(&~O%$TrDGSb#oTLn&1F%IZdI&Y|4CzXXl0I? zk~l4%rq@Qsr@}EZ5*6hpM>|>uDYj&}07dGrKi3$psBQ7E0@K$~3sl!uJf_I>1q!?i zozo{^-Y4693yIPZ7H_>k;I577JAPQ_j)Jp#?Zr6?W=HH=bqIZDfm57zZ)*5BkvF+&_OXyctz zc1phe1*Nv`ZANvVh0Ir9cvU&F;})gSFyZ^vhF#U#t%XFRr|s8MWie~bDjWwZAg8&V zD_a9fzc}LwW?St=Qcw2_be=$xMkOsPpsFD2_ZI3j3Y~m%ptv@udVK1ra;v7I4N*S{ z8M7J7{_oRqn&!#8TaS$)X`(ZN54ZO`SCw>bPrv)8jq;eA_r@4K1-)gZK+Y~ zU+d|SpEJ6*Bw&vnbkr;MI|tsbfB8bbwDU9Bo!-uBjnX&{s5-YtT+?S?tpSE*Vhbk3 zS}EbU>kt)hXZh=7ROe~D%3?FVkC_m5584;Dotc_i|0cN1q59~#GOGIWZO9+}Ek1%qnJfeag)@LOiw6j|hEyuBg!|(~YR`WZKK`^H`DzY+CL1R|Rj+(kuj=&Ez?@>MHXf_OKemD)783nr zL2jUHGOA;1kL5v7QXxU|`QkE>w`tJ6j6 z*{K^rSbFP)tW&VR!fWR^1=F{ja>0n@|1&0+>R8c3y!7UI;Fjd2euz`8_HxIm`nnhl zQ3cTtu1FE8hC`^lBA(lRp=(N22u@+?Y1KRX0u|b#7GX>uA+Y=HQ3o~iZ9mt}p;MLX z$A{h|pS5T(i*o@ic}W>`dq4#b78o6ApGNUK;Ax=@(V3lpY9bN2cH9DqunOqcyY3t6 zKTE;fd+Z?>D^9UE>9Ei`hSENxQE?1fFdlj48i3#BclJq3Z0U^&rVb*%JbZ)?jT}-K zm;%Qrp8d{R!7Y{43+%88)V;Eu9ovW=stD(I73{GWQtr`Sg| zFL61+q>U3>f_n_Kb)ur9umj#s1--^tQyUBelUNKmT%8K~WXT0yuQm6iFiO(pALWfX z>D}oXQ2pOA~V=v9qjeFL<*{(Y{Qtch4HZ`5d||k+Pk3a@<`qg zU~CC_AD-G|EV!Vo2V+fL#U?8k<85cnm^`Yh zI)74%+62IY!+*IqQ(;x!J*mwKbff8j6|oq&Xw8!fVf`xUbTXSVNfUzX%5y?Tk_5o(i?gVJKfvi&Db*@lMn>(?y|< z$U(VKMa_^Jl|l2?w$7kJ-5*LW`j!VLm|6EkorJ_gSp*Z_883*&VYZqYV?rw-G0bcw z^3^@i__Ux}oP=pVlNGT^5zaI@Hn$VVExO23n{#ZanZK{8*Zs_R8l!j6{SeW&C1tm5syf|9V z?!)IAK4)YU8Pt#U;;J<73z<9_(Sl%0AOg^e8#U5)ek%MK$!!Xy7gv}mCGZ_|vTdMb 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 Z?D|)!`e4X&_#w8t`#TEUQQ#&8{uhb&CJX=o literal 0 HcmV?d00001 diff --git a/SinglePlayer - Games/Skii Game/test/skier.test.js b/SinglePlayer - Games/Skii Game/test/skier.test.js new file mode 100644 index 00000000..4e0d5f7e --- /dev/null +++ b/SinglePlayer - Games/Skii Game/test/skier.test.js @@ -0,0 +1,357 @@ +var extenders = require(__dirname + '/../js/lib/extenders'); +var Sprite = require(__dirname + '/../js/lib/sprite'); +var Skier = require(__dirname + '/../js/lib/skier'); +var should = require('should'); +var sugar = require('sugar'); + +describe('Skier', function() { + describe('#getMovingTowardOpposite()', function() { + it('should return the point relative to the skier, rotated 180 degrees around the skier if the skier is going right', function() { + var skier = new Skier(); + skier.setSpeed(3); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(100, 36); + + skier.getMovingTowardOpposite()[0].should.equal(-90); + skier.getMovingTowardOpposite()[1].should.equal(-6); + }); + + it('should return the point relative to the skier, rotated 180 degrees around the skier if the skier is going left', function() { + var skier = new Skier(); + skier.setSpeed(3); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(-100, 36); + + skier.getMovingTowardOpposite()[0].should.equal(110); + skier.getMovingTowardOpposite()[1].should.equal(-6); + }); + }); + + describe('#hits()', function() { + it('should still hit taller objects if jumping', function() { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.hasHitJump(); + + var tallSprite = new Sprite({ + zIndexesOccupied : [0, 1] + }); + + tallSprite.setHeight(10); + tallSprite.setWidth(10); + tallSprite.setMapPosition(10, 30); + + skier.hits(tallSprite).should.equal(true); + }); + + it('should still hit taller objects with a high-up z-index if jumping', function() { + var skier = new Skier(); + skier.setMapPosition(30, 25); + skier.setHeight(10); + skier.setWidth(10); + skier.hasHitJump(); + + var tallSprite = new Sprite({ + zIndexesOccupied : [0, 1], + hitBoxes: { + 0: [0, 15, 10, 20], + 1: [0, 5, 10, 15] + } + }); + + tallSprite.setHeight(20); + tallSprite.setWidth(10); + tallSprite.setMapPosition(30, 30); + + skier.hits(tallSprite).should.equal(true); + }); + + it('should not hit shorter objects if jumping', function() { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.hasHitJump(); + + var shortSprite = new Sprite({ + zIndexesOccupied : [0] + }); + + shortSprite.setHeight(10); + shortSprite.setWidth(10); + shortSprite.setMapPosition(10, 30); + + skier.hits(shortSprite).should.equal(false); + }); + }); + + describe('#getSpeedX()', function() { + it('should ease on the x-axis when the skier turns south-east', function () { + var skier = new Skier(); + skier.setTurnEaseCycles(5); + skier.setSpeed(4); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(10, 30); + skier.getSpeedX().should.equal(0); + skier.setMapPositionTarget(150, 35); + skier.getSpeedX().should.equal(4 * (0.33 / 5)); + skier.getSpeedX().should.equal(4 * (0.33 / 5) * 2); + skier.getSpeedX().should.equal(4 * (0.33 / 5) * 3); + skier.getSpeedX().should.equal(4 * (0.33 / 5) * 4); + skier.getSpeedX().should.equal(4 * 0.33); + }); + + it('should ease on the x-axis when the skier turns east-south-east', function () { + var skier = new Skier(); + skier.setTurnEaseCycles(5); + skier.setSpeed(4); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(10, 30); + skier.getSpeedX().should.equal(0); + skier.setMapPositionTarget(450, 35); + skier.getSpeedX().should.equal(4 * (0.5 / 5)); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 2); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 3); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 4); + skier.getSpeedX().should.equal(4 * 0.5); + }); + + it('should ease on the x-axis back down when the skier turns from east-south-east to south', function () { + var skier = new Skier(); + skier.setTurnEaseCycles(5); + skier.setSpeed(4); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(10, 30); + skier.getSpeedX().should.equal(0); + skier.setMapPositionTarget(450, 35); + skier.getSpeedX().should.equal(4 * (0.5 / 5)); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 2); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 3); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 4); + skier.getSpeedX().should.equal(4 * 0.5); + skier.setMapPositionTarget(10, 35); + skier.getSpeedX().should.equal(4 * (0.5 / 5) * 4); + }); + }); + + describe('#getSpeedY()', function() { + it('should ease on the y-axis when the skier turns from east (stationary) to south-east', function () { + var skier = new Skier(); + skier.setTurnEaseCycles(5); + skier.setSpeed(4); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(15, 30); + skier.getSpeedY().should.equal(0); + skier.setMapPositionTarget(150, 35); + skier.getSpeedY().should.equal(4 * (0.85 / 5)); + skier.getSpeedY().should.equal(4 * (0.85 / 5) * 2); + skier.getSpeedY().should.equal(4 * (0.85 / 5) * 3); + skier.getSpeedY().should.equal(4 * (0.85 / 5) * 4); + skier.getSpeedY().should.equal(4 * (0.85 / 5) * 5); + }); + + it('should ease on the y-axis when the skier turns from east (stationary) to east-south-east from', function () { + var skier = new Skier(); + skier.setTurnEaseCycles(5); + skier.setSpeed(4); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(10, 30); + skier.getSpeedY().should.equal(0); + skier.setMapPositionTarget(450, 35); + skier.getSpeedY().should.equal(4 * (0.6 / 5)); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 2); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 3); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 4); + skier.getSpeedY().should.equal(4 * 0.6); + }); + + it('should ease on the y-axis when the skier turns from east (stationary) to east-south-east to south', function () { + var skier = new Skier(); + skier.setTurnEaseCycles(5); + skier.setSpeed(4); + skier.setMapPosition(10, 30); + skier.setMapPositionTarget(10, 30); + skier.getSpeedY().should.equal(0); + skier.setMapPositionTarget(450, 35); + skier.getSpeedY().should.equal(4 * (0.6 / 5)); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 2); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 3); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 4); + skier.getSpeedY().should.equal(4 * 0.6); + skier.setMapPositionTarget(10, 45); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 6); + skier.getSpeedY().should.equal(4 * (0.6 / 5) * 7); + }); + }); + + describe('#setMapPositionTarget()', function() { + it('should not allow setting the map position target whilst jumping', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setSpeed(4); + skier.setSpeedY(4); + skier.setMapPositionTarget(10, 70); + skier.getSpeedY().should.equal(4); + skier.hasHitJump(); + skier.cycle(); + skier.setMapPositionTarget(80, -40); + skier.getSpeedY().should.equal(6); + }); + }); + + describe('#turnEast()', function() { + it('should go one discrete direction from stopping west', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(270); + skier.turnEast(); + skier.direction.should.equal(240); + }); + + it('should go two discrete directions from stopping west', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(270); + skier.turnEast(); + skier.turnEast(); + skier.direction.should.equal(195); + }); + + it('should go three discrete directions from stopping west', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(270); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.direction.should.equal(180); + }); + + it('should go four discrete directions from stopping west', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(270); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.direction.should.equal(165); + }); + + it('should go five discrete directions from stopping west', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(270); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.direction.should.equal(120); + }); + + it('should go six discrete directions from stopping west', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(270); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.turnEast(); + skier.direction.should.equal(90); + }); + + it('should go to next discrete direction from arbitrary direction', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(255); + skier.turnEast(); + skier.direction.should.equal(195); + }); + }); + + describe('#turnWest()', function() { + it('should go one discrete directions from stopping east', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(90); + skier.turnWest(); + skier.direction.should.equal(120); + }); + + it('should go two discrete directions from stopping east', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(90); + skier.turnWest(); + skier.turnWest(); + skier.direction.should.equal(165); + }); + + it('should go three discrete directions from stopping east', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(90); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.direction.should.equal(180); + }); + + it('should go four discrete directions from stopping east', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(90); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.direction.should.equal(195); + }); + + it('should go five discrete direction from stopping east', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(90); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.direction.should.equal(240); + }); + + it('should go six discrete direction from stopping east', function () { + var skier = new Skier(); + skier.setMapPosition(10, 30); + skier.setDirection(90); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.turnWest(); + skier.direction.should.equal(270); + }); + }); + + describe('#stepWest()', function() { + it('should go twice the speed steps to the west', function () { + var skier = new Skier(); + skier.setSpeed(3); + skier.setMapPosition(10, 30); + skier.stepWest(); + skier.mapPosition[0].should.equal(4); + }); + }); + + describe('#stepEast()', function() { + it('should go twice the speed steps to the east', function () { + var skier = new Skier(); + skier.setSpeed(3); + skier.setMapPosition(10, 30); + skier.stepEast(); + skier.mapPosition[0].should.equal(16); + }); + }); +}); \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/test/sprite.test.js b/SinglePlayer - Games/Skii Game/test/sprite.test.js new file mode 100644 index 00000000..28ff0465 --- /dev/null +++ b/SinglePlayer - Games/Skii Game/test/sprite.test.js @@ -0,0 +1,370 @@ +var Sprite = require(__dirname + '/../js/lib/sprite'); +var assert = require('assert'); +var should = require('should'); +var sugar = require('sugar'); + +describe('Sprite', function() { + describe('#setSpeed()', function() { + it('should set the correct speed', function() { + var sprite = new Sprite(); + + sprite.setSpeed(5); + + sprite.getSpeed().should.equal(5); + }); + }); + + describe('#setCanvasPosition()', function() { + it('should set the correct position', function() { + var sprite = new Sprite(); + + sprite.setMapPosition(5, 10); + + sprite.mapPosition[0].should.equal(5); + sprite.mapPosition[1].should.equal(10); + }); + }); + + describe('#cycle()', function() { + it('should move the sprite along at the given speed', function() { + var sprite = new Sprite(); + + sprite.setSpeed(3); + + sprite.setMapPosition(5, 10); + + sprite.setMapPositionTarget(10, 18); + + sprite.cycle(); + + sprite.mapPosition[0].should.equal(8); + sprite.mapPosition[1].should.equal(13); + }); + + it('should not move the sprite along if it is not moving', function() { + var sprite = new Sprite(); + + sprite.setSpeed(3); + + sprite.isMoving = false; + + sprite.setMapPosition(5, 10); + + sprite.setMapPositionTarget(10, 18); + + sprite.cycle(); + + sprite.mapPosition[0].should.equal(5); + sprite.mapPosition[1].should.equal(10); + }); + + it('should allow the sprite to move in in opposite directions on either axis', function() { + var sprite = new Sprite(); + + sprite.setSpeed(3); + + sprite.setMapPosition(5, 10); + + sprite.setMapPositionTarget(1, 18); + + sprite.cycle(); + + sprite.mapPosition[0].should.equal(2); + sprite.mapPosition[1].should.equal(13); + }); + + it('should be able to decrease in both dimensions', function() { + var sprite = new Sprite(); + + sprite.setSpeed(3); + + sprite.setMapPosition(5, 10); + + sprite.setMapPositionTarget(1, 1); + + sprite.cycle(); + + sprite.mapPosition[0].should.equal(2); + sprite.mapPosition[1].should.equal(7); + }); + + it('should move the sprite to the target position if it is nearer than the speed', function() { + var sprite = new Sprite(); + + sprite.setSpeed(3); + + sprite.setMapPosition(5, 10); + + sprite.setMapPositionTarget(7, 11); + + sprite.cycle(); + + assert.equal(7, sprite.mapPosition[0]); + assert.equal(11, sprite.mapPosition[1]); + }); + + it('should move up if the y-difference is absolutely greater than the y-position', function() { + var sprite = new Sprite(); + + sprite.setSpeed(3); + + sprite.setMapPosition(6, 20); + + sprite.setMapPositionTarget(-50, -10); + + sprite.cycle(); + + sprite.mapPosition[0].should.equal(3); + sprite.mapPosition[1].should.equal(17); + }); + }); + + describe('#hit()', function() { + it('should not register two objects as having hit if they do intersect in any dimension', function() { + var object1 = new Sprite(); + var object2 = new Sprite(); + + object1.setCanvasPosition(1, 1); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(15, 15); + object2.setHeight(10); + object2.setWidth(10); + + object1.hits(object2).should.equal(false); + }); + + it('should not register two objects as having hit if they intersect in the X dimension', function() { + var object1 = new Sprite(); + var object2 = new Sprite(); + + object1.setCanvasPosition(1, 1); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(3, 15); + object2.setHeight(10); + object2.setWidth(10); + + object1.hits(object2).should.equal(false); + object2.hits(object1).should.equal(false); + }); + + it('should not register two objects as having hit if they intersect in the Y dimension', function() { + var object1 = new Sprite(); + var object2 = new Sprite(); + + object1.setCanvasPosition(1, 1); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(15, 2); + object2.setHeight(10); + object2.setWidth(10); + + object1.hits(object2).should.equal(false); + object2.hits(object1).should.equal(false); + }); + + it('should register two objects as having hit if they intersect in both dimensions', function() { + var object1 = new Sprite(); + var object2 = new Sprite(); + + object1.setCanvasPosition(1, 1); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(3, 3); + object2.setHeight(10); + object2.setWidth(10); + + object1.hits(object2).should.not.equal(false); + object2.hits(object1).should.not.equal(false); + }); + + it('should not register two objects with hitboxes as having hit if they intersect in both dimensions but their hitboxes do not', function() { + var object1 = new Sprite({ + hitBoxes: { + 0: [ 0, 5, 10, 10 ] + } + }); + var object2 = new Sprite({ + hitBoxes: { + 0: [ 0, 5, 10, 10 ] + } + }); + var object3 = new Sprite({ + hitBoxes: { + 0: [ 0, 0, 5, 5 ] + } + }); + var object4 = new Sprite({ + hitBoxes: { + 0: [ 0, 0, 10, 10 ] + } + }); + + object1.setCanvasPosition(0, 0); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(0, 9); + object2.setHeight(10); + object2.setWidth(10); + + object3.setCanvasPosition(20, 0); + object3.setHeight(10); + object3.setWidth(10); + + object4.setCanvasPosition(20, 9); + object4.setHeight(10); + object4.setWidth(10); + + object1.hits(object2).should.equal(false); + object2.hits(object1).should.equal(false); + + object3.hits(object4).should.equal(false); + object4.hits(object3).should.equal(false); + }); + }); + + describe('#onHitting()', function () { + it('should run the appropriate callback when two things hit in a cycle', function() { + var object1 = new Sprite(); + var object2 = new Sprite(); + var testString = 'not hit'; + + object1.setCanvasPosition(1, 1); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(3, 3); + object2.setHeight(10); + object2.setWidth(10); + + object1.onHitting(object2, function () { + testString = 'hit'; + }); + + object1.cycle(); + + testString.should.equal('hit'); + }); + + it('should not register the hit if a hittable object has been deleted', function() { + var object1 = new Sprite(); + var object2 = new Sprite(); + var testString = 'not hit'; + + object1.setCanvasPosition(1, 1); + object1.setHeight(10); + object1.setWidth(10); + + object2.setCanvasPosition(3, 3); + object2.setHeight(10); + object2.setWidth(10); + + object1.onHitting(object2, function () { + testString = 'hit'; + }); + + object2.deleteOnNextCycle(); + object1.cycle(); + + testString.should.equal('not hit'); + }); + }); + + describe('#follow()', function () { + it('should move toward the a stationary sprite it is following', function () { + var hunter = new Sprite(); + hunter.isMoving = true; + hunter.setSpeed(1); + hunter.setMapPosition(5, 20); + + var prey = new Sprite(); + prey.isMoving = false; + prey.setMapPosition(10, 20); + + hunter.follow(prey); + + hunter.cycle(); + prey.cycle(); + + hunter.mapPosition[0].should.equal(6); + hunter.mapPosition[1].should.equal(20); + + prey.mapPosition[0].should.equal(10); + prey.mapPosition[1].should.equal(20); + }); + }); + + describe('#setDirection()', function () { + it('should move down by the speed if the direction is 180 degrees', function () { + var sprite = new Sprite(); + sprite.isMoving = true; + sprite.setSpeed(1); + sprite.setDirection(180); + sprite.setMapPosition(10, 20); + sprite.cycle(); + sprite.mapPosition[0].should.equal(10); + sprite.mapPosition[1].should.equal(21); + }); + + it('should move right by the speed if the direction is 90 degrees', function () { + var sprite = new Sprite(); + sprite.isMoving = true; + sprite.setSpeed(1); + sprite.setDirection(90); + sprite.setMapPosition(10, 20); + sprite.cycle(); + sprite.mapPosition[0].should.equal(11); + sprite.mapPosition[1].should.equal(20); + }); + + it('should move left by the speed if the direction is 270 degrees', function () { + var sprite = new Sprite(); + sprite.isMoving = true; + sprite.setSpeed(1); + sprite.setDirection(270); + sprite.setMapPosition(10, 20); + sprite.cycle(); + sprite.mapPosition[0].should.equal(9); + sprite.mapPosition[1].should.equal(20); + }); + + it('should move right and down by half by the speed if the direction is 135 degrees', function () { + var sprite = new Sprite(); + sprite.isMoving = true; + sprite.setSpeed(1); + sprite.setDirection(135); + sprite.setMapPosition(10, 20); + sprite.cycle(); + sprite.mapPosition[0].should.equal(10.5); + sprite.mapPosition[1].should.equal(20.5); + }); + + it('should move left and down by half by the speed if the direction is 225 degrees', function () { + var sprite = new Sprite(); + sprite.isMoving = true; + sprite.setSpeed(1); + sprite.setDirection(225); + sprite.setMapPosition(10, 20); + sprite.cycle(); + sprite.mapPosition[0].should.equal(9.5); + sprite.mapPosition[1].should.equal(20.5); + }); + + it('should move up by half by the speed if the direction is 0 degrees', function () { + var sprite = new Sprite(); + sprite.isMoving = true; + sprite.setSpeed(1); + sprite.setDirection(0); + sprite.setMapPosition(10, 20); + sprite.cycle(); + sprite.mapPosition[0].should.equal(10); + sprite.mapPosition[1].should.equal(19); + }); + }); +}); \ No newline at end of file diff --git a/SinglePlayer - Games/Skii Game/yeti-big.png b/SinglePlayer - Games/Skii Game/yeti-big.png new file mode 100644 index 0000000000000000000000000000000000000000..02ec9b1d5a6c8d2012a6a59cb116550b69c6f6db GIT binary patch literal 59015 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¨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