diff --git a/app/Chat.js b/app/Chat.js new file mode 100644 index 0000000..52b96be --- /dev/null +++ b/app/Chat.js @@ -0,0 +1,14 @@ +var socket = io(); +var scroll = 0; + +$('#form').submit(function(){ + console.log("Hallo"); + socket.emit('chat message', localStorage.getItem('player') + ': ' + $('#m').val()); + $('#m').val(''); + return false; +}); +socket.on('chat message', function(msg) { + var message = $('#messages'); + var list = document.getElementById("messages"); + message.append($('
  • ').text(msg)); +}); \ No newline at end of file diff --git a/app/Collision.js b/app/Collision.js index eedccf0..35a4049 100644 --- a/app/Collision.js +++ b/app/Collision.js @@ -1,6 +1,12 @@ var Collision = function () { - + var x,y,z; + var globalXs = []; + var globalYs = []; + var globalZs = []; + var globalMXs = []; + var globalMYs = []; + var globalMZs = []; /************************* MIN AND MAX FUNCTIONS *************************/ @@ -10,7 +16,7 @@ var Collision = function () { function minX(box) { // array for x values - var globalXs = []; + globalXs = []; // get the position of each vertex for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { // get the local position of the vertex @@ -27,19 +33,19 @@ var Collision = function () { // Calculates the max X value of the vertices of a box function maxX(box) { - var globalXs = []; + globalMXs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { var localVertex = box.geometry.vertices[vertexIndex].clone(); var globalVertex = localVertex.applyMatrix4(box.matrix); - globalXs.push(globalVertex.x); + globalMXs.push(globalVertex.x); } - return Math.max.apply(Math, globalXs); + return Math.max.apply(Math, globalMXs); } // Calculates the min Y value of the vertices of a box function minY(box) { - var globalYs = []; + globalYs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { var localVertex = box.geometry.vertices[vertexIndex].clone(); var globalVertex = localVertex.applyMatrix4(box.matrix); @@ -51,19 +57,19 @@ var Collision = function () { // Calculates the max Y value of the vertices of a box function maxY(box) { - var globalYs = []; + globalMYs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { var localVertex = box.geometry.vertices[vertexIndex].clone(); var globalVertex = localVertex.applyMatrix4(box.matrix); - globalYs.push(globalVertex.y); + globalMYs.push(globalVertex.y); } - return Math.max.apply(Math, globalYs); + return Math.max.apply(Math, globalMYs); } // Calculates the min Z value of the vertices of a box function minZ(box) { - var globalZs = []; + globalZs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { var localVertex = box.geometry.vertices[vertexIndex].clone(); var globalVertex = localVertex.applyMatrix4(box.matrix); @@ -75,20 +81,20 @@ var Collision = function () { // Calculates the max Z value of the vertices of a box function maxZ(box) { - var globalZs = []; + globalMZs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { var localVertex = box.geometry.vertices[vertexIndex].clone(); var globalVertex = localVertex.applyMatrix4(box.matrix); - globalZs.push(globalVertex.z); + globalMZs.push(globalVertex.z); } - return Math.max.apply(Math, globalZs); + return Math.max.apply(Math, globalMZs); } // Calculates the min x value of the vertices of a box function minXship(box) { // array for x values - var globalXs = []; + globalXs = []; // get the position of each vertex for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { globalXs.push(box.geometry.vertices[vertexIndex].x + ship.position.x); @@ -100,17 +106,17 @@ var Collision = function () { // Calculates the max X value of the vertices of a box function maxXship(box) { - var globalXs = []; + globalMXs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { - globalXs.push(box.geometry.vertices[vertexIndex].x + ship.position.x); + globalMXs.push(box.geometry.vertices[vertexIndex].x + ship.position.x); } - return Math.max.apply(Math, globalXs); + return Math.max.apply(Math, globalMXs); } // Calculates the min Y value of the vertices of a box function minYship(box) { - var globalYs = []; + globalYs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { globalYs.push(box.geometry.vertices[vertexIndex].y + ship.position.y); } @@ -120,17 +126,17 @@ var Collision = function () { // Calculates the max Y value of the vertices of a box function maxYship(box) { - var globalYs = []; + globalMYs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { - globalYs.push(box.geometry.vertices[vertexIndex].y + ship.position.y); + globalMYs.push(box.geometry.vertices[vertexIndex].y + ship.position.y); } - return Math.max.apply(Math, globalYs); + return Math.max.apply(Math, globalMYs); } // Calculates the min Z value of the vertices of a box function minZship(box) { - var globalZs = []; + globalZs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { globalZs.push(box.geometry.vertices[vertexIndex].z + ship.position.z); } @@ -140,11 +146,11 @@ var Collision = function () { // Calculates the max Z value of the vertices of a box function maxZship(box) { - var globalZs = []; + globalMZs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { - globalZs.push(box.geometry.vertices[vertexIndex].z + ship.position.z); + globalMZs.push(box.geometry.vertices[vertexIndex].z + ship.position.z); } - return Math.max.apply(Math, globalZs); + return Math.max.apply(Math, globalMZs); } @@ -152,7 +158,7 @@ var Collision = function () { function minXenemy(box, i) { // array for x values - var globalXs = []; + globalXs = []; // get the position of each vertex for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { globalXs.push(box.geometry.vertices[vertexIndex].x + enemies[i].position.x); @@ -164,37 +170,37 @@ var Collision = function () { // Calculates the max X value of the vertices of a box function maxXenemy(box, i) { - var globalXs = []; + globalMXs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { - globalXs.push(box.geometry.vertices[vertexIndex].x + enemies[i].position.x); + globalMXs.push(box.geometry.vertices[vertexIndex].x + enemies[i].position.x); } - return Math.max.apply(Math, globalXs); + return Math.max.apply(Math, globalMXs); } // Calculates the min Y value of the vertices of a box function minYenemy(box, i) { - var globalYs = []; + globalYs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { globalYs.push(box.geometry.vertices[vertexIndex].y + enemies[i].position.y); } - return Math.min.apply(Math, globalYs); + return Math.min.apply(Math, globalMYs); } // Calculates the max Y value of the vertices of a box function maxYenemy(box, i) { - var globalYs = []; + globalYs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { - globalYs.push(box.geometry.vertices[vertexIndex].y + enemies[i].position.y); + globalMYs.push(box.geometry.vertices[vertexIndex].y + enemies[i].position.y); } - return Math.max.apply(Math, globalYs); + return Math.max.apply(Math, globalMYs); } // Calculates the min Z value of the vertices of a box function minZenemy(box, i) { - var globalZs = []; + globalZs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { globalZs.push(box.geometry.vertices[vertexIndex].z + enemies[i].position.z); } @@ -204,11 +210,11 @@ var Collision = function () { // Calculates the max Z value of the vertices of a box function maxZenemy(box, i) { - var globalZs = []; + globalMZs = []; for (var vertexIndex = 0; vertexIndex < box.geometry.vertices.length; vertexIndex++) { - globalZs.push(box.geometry.vertices[vertexIndex].z + enemies[i].position.z); + globalMZs.push(box.geometry.vertices[vertexIndex].z + enemies[i].position.z); } - return Math.max.apply(Math, globalZs); + return Math.max.apply(Math, globalMZs); } /************************* INTERSECTION FUNCTIONS *************************/ @@ -239,9 +245,9 @@ var Collision = function () { // Checks if there is an intersection between a sphere and a box function intersectSphereBox(sphere, box) { // get box closest point to sphere center by clamping - var x = Math.max(minX(box), Math.min(sphere.position.x, maxX(box))); - var y = Math.max(minY(box), Math.min(sphere.position.y, maxY(box))); - var z = Math.max(minZ(box), Math.min(sphere.position.z, maxZ(box))); + x = Math.max(minX(box), Math.min(sphere.position.x, maxX(box))); + y = Math.max(minY(box), Math.min(sphere.position.y, maxY(box))); + z = Math.max(minZ(box), Math.min(sphere.position.z, maxZ(box))); // distance between the sphere and the closest box-point to the spehere var distance = Math.sqrt((x - sphere.position.x) * (x - sphere.position.x) + @@ -285,9 +291,9 @@ var Collision = function () { function cylinderAsBox(cylinder) { // parameters for the box - var x = cylinder.geometry.parameters.radiusTop * 2; - var y = cylinder.geometry.parameters.height; - var z = cylinder.geometry.parameters.radiusTop * 2; + x = cylinder.geometry.parameters.radiusTop * 2; + y = cylinder.geometry.parameters.height; + z = cylinder.geometry.parameters.radiusTop * 2; // initialize box var boxGeometry = new THREE.BoxGeometry(x, y, z); @@ -322,10 +328,16 @@ var Collision = function () { // Checks if there is an intersection between a ShipHitbox and another box function intersectShipHitBoxBox(a, b) { + var x1Pruef = minXship(a) <= maxX(b); + var x2Pruef = maxXship(a) >= minX(b); + var y1Pruef = minYship(a) <= maxY(b); + var y2Pruef = maxYship(a) >= minY(b); + var z1Pruef = minZship(a) <= maxZ(b); + var z2Pruef = maxZship(a) >= minZ(b); // if there is an intersection in every dimension the two boxes intersect - return (minXship(a) <= maxX(b) && maxXship(a) >= minX(b) && - (minYship(a) <= maxY(b) && maxYship(a) >= minY(b)) && - (minZship(a) <= maxZ(b) && maxZship(a) >= minZ(b))); + return (x1Pruef && x2Pruef && + (y1Pruef && y2Pruef) && + (z1Pruef && z2Pruef)); } // Checks if there is an intersection between a point and box diff --git a/app/Crosshairs.js b/app/Crosshairs.js index af86c5e..a84223e 100644 --- a/app/Crosshairs.js +++ b/app/Crosshairs.js @@ -2,6 +2,9 @@ var cross1, cross2, cross3, cross4, cross5, cross6, cross7, cross8, cross9, cros var crosses = []; var pos = 0; var old = 0; +var crossx = 0; +var crossy = 5; +var crossz = -40; function Crosshairs() { return { @@ -13,7 +16,7 @@ function Crosshairs() { var materialA = new THREE.SpriteMaterial({ map: mapA }); cross1 = new THREE.Sprite(materialA); - cross1.position.set(0, 10, -40); + cross1.position.set(crossx, crossy, crossz); cross1.scale.set(6.0, 6.0, 1.0); cross1.visible = false; crosses.push(cross1); @@ -24,7 +27,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross2 = new THREE.Sprite(materialA); - cross2.position.set(0, 10, -40); + cross2.position.set(crossx, crossy, crossz); cross2.scale.set(6.0, 6.0, 1.0); cross2.visible = false; crosses.push(cross2); @@ -34,7 +37,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross3 = new THREE.Sprite(materialA); - cross3.position.set(0, 10, -40); + cross3.position.set(crossx, crossy, crossz); cross3.scale.set(6.0, 6.0, 1.0); cross3.visible = false; crosses.push(cross3); @@ -44,7 +47,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross4 = new THREE.Sprite(materialA); - cross4.position.set(0, 10, -40); + cross4.position.set(crossx, crossy, crossz); cross4.scale.set(6.0, 6.0, 1.0); cross4.visible = false; crosses.push(cross4); @@ -54,7 +57,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross5 = new THREE.Sprite(materialA); - cross5.position.set(0, 10, -40); + cross5.position.set(crossx, crossy, crossz); cross5.scale.set(6.0, 6.0, 1.0); cross5.visible = false; crosses.push(cross5); @@ -64,7 +67,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross6 = new THREE.Sprite(materialA); - cross6.position.set(0, 10, -40); + cross6.position.set(crossx, crossy, crossz); cross6.scale.set(6.0, 6.0, 1.0); cross6.visible = false; crosses.push(cross6); @@ -74,7 +77,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross7 = new THREE.Sprite(materialA); - cross7.position.set(0, 10, -40); + cross7.position.set(crossx, crossy, crossz); cross7.scale.set(6.0, 6.0, 1.0); cross7.visible = false; crosses.push(cross7); @@ -84,7 +87,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross8 = new THREE.Sprite(materialA); - cross8.position.set(0, 10, -40); + cross8.position.set(crossx, crossy, crossz); cross8.scale.set(6.0, 6.0, 1.0); cross8.visible = false; crosses.push(cross8); @@ -94,7 +97,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross9 = new THREE.Sprite(materialA); - cross9.position.set(0, 10, -40); + cross9.position.set(crossx, crossy, crossz); cross9.scale.set(6.0, 6.0, 1.0); cross9.visible = false; crosses.push(cross9); @@ -104,7 +107,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross10 = new THREE.Sprite(materialA); - cross10.position.set(0, 10, -40); + cross10.position.set(crossx, crossy, crossz); cross10.scale.set(6.0, 6.0, 1.0); cross10.visible = false; crosses.push(cross10); @@ -114,7 +117,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross11 = new THREE.Sprite(materialA); - cross11.position.set(0, 10, -40); + cross11.position.set(crossx, crossy, crossz); cross11.scale.set(6.0, 6.0, 1.0); cross11.visible = false; crosses.push(cross11); @@ -124,7 +127,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross12 = new THREE.Sprite(materialA); - cross12.position.set(0, 10, -40); + cross12.position.set(crossx, crossy, crossz); cross12.scale.set(6.0, 6.0, 1.0); cross12.visible = false; crosses.push(cross12); @@ -134,7 +137,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross13 = new THREE.Sprite(materialA); - cross13.position.set(0, 10, -40); + cross13.position.set(crossx, crossy, crossz); cross13.scale.set(6.0, 6.0, 1.0); cross13.visible = false; crosses.push(cross13); @@ -144,7 +147,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross14 = new THREE.Sprite(materialA); - cross14.position.set(0, 10, -40); + cross14.position.set(crossx, crossy, crossz); cross14.scale.set(6.0, 6.0, 1.0); cross14.visible = false; crosses.push(cross14); @@ -154,17 +157,18 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross15 = new THREE.Sprite(materialA); - cross15.position.set(0, 10, -40); + cross15.position.set(crossx, crossy, crossz); cross15.scale.set(6.0, 6.0, 1.0); cross15.visible = false; crosses.push(cross15); + mapA = fileLoader.get("Crosshair16"); - materialA = new THREE.SpriteMaterial({ map: mapA }); + materialA = new THREE.SpriteMaterial({map: mapA}); cross16 = new THREE.Sprite(materialA); - cross16.position.set(0, 10, -40); + cross16.position.set(crossx, crossy, crossz); cross16.scale.set(6.0, 6.0, 1.0); cross16.visible = false; crosses.push(cross16); @@ -174,7 +178,7 @@ function Crosshairs() { materialA = new THREE.SpriteMaterial({ map: mapA }); cross17 = new THREE.Sprite(materialA); - cross17.position.set(0, 10, -40); + cross17.position.set(crossx, crossy, crossz); cross17.scale.set(6.0, 6.0, 1.0); cross17.visible = false; crosses.push(cross17); @@ -197,7 +201,7 @@ function Crosshairs() { crosses[pos].position.set(0, 0, -40); } else { - crosses[pos].position.set(0, 10, -40); + crosses[pos].position.set(crossx, crossy, crossz); } crosses[old].visible = false; ship.remove(crosses[old]); @@ -214,7 +218,7 @@ function switchCross(neuPos){ old=pos; pos=neuPos; - crosses[pos].position.set(0,10,-40); + crosses[pos].position.set(crossx, crossy, crossz); crosses[old].visible = false; ship.remove(crosses[old]); ship.add(crosses[pos]); diff --git a/app/Enemy.js b/app/Enemy.js index 1525ee6..0740c0e 100644 --- a/app/Enemy.js +++ b/app/Enemy.js @@ -345,7 +345,6 @@ Enemy.prototype.collectObstacles = function(optimalDir, delta) { var possibleObstacle = false; var obstacles = []; - var bot = Bot(); var asteroids = bot.getAsteroids(); //console.log("Asteroids:" + asteroids.length); var enemies = bot.getEnemies(); @@ -365,7 +364,8 @@ Enemy.prototype.collectObstacles = function(optimalDir, delta) { var shipDistance = distanceToNext + delta * this.speed; // Kontrolliere, ob sich im guardingRadius andere Gegenstaende befinden - for(asteroid of asteroids) { // Asteroiden schon geupdatet + for(var j = 0; j < asteroids.length; j++) { // Asteroiden schon geupdatet + var asteroid = asteroids[j]; d = Math.abs(shipDistance - asteroid.position.distanceTo(ship.position)); // Teste, ob im richtigen Ring um den Spieler @@ -383,7 +383,8 @@ Enemy.prototype.collectObstacles = function(optimalDir, delta) { } - for(enemy of enemies) { + for(var i = 0; i < enemies.length; i++) { + var enemy = enemies[i]; d = enemy.position.distanceTo(ship.position) - shipDistance; if(d <= 0 && d <= minObstacleDistance) { // nahe und vor einem distanceToShip = enemy.position.distanceTo(shipPosition); diff --git a/app/Interface.js b/app/Interface.js index 5fae027..126c707 100644 --- a/app/Interface.js +++ b/app/Interface.js @@ -571,6 +571,8 @@ function gameOver() { glitchScreen(500); document.getElementById('gameOverText3').innerHTML = getScore(); $('#gameOverBox').animate({top: '20%'}, 500); + + network.postNewScore({'player':localStorage.getItem('player'), 'score': getScore(), 'level': level}); Pause = true; PauseScreen = true; movement.unlockPointer(); diff --git a/app/Movement.js b/app/Movement.js index e90553b..0cf02bd 100644 --- a/app/Movement.js +++ b/app/Movement.js @@ -209,13 +209,7 @@ function Movement() { stop(); break; case 80: - if (Pause) { - PauseScreen = false; - interface.toggleMenuOverlay(); - movement.lockPointer(); - - } else { - + if(!Pause) { interface.toggleMenuOverlay(); movement.unlockPointer(); PauseScreen = true; @@ -295,6 +289,7 @@ function Movement() { lat = Math.max(-85, Math.min(70, lat)); phi = THREE.Math.degToRad(90 - lat); theta = THREE.Math.degToRad(lon); + cameraWatcher(); cameraWatcher(); @@ -305,6 +300,7 @@ function Movement() { targetPosition.y = position.y + 100 * Math.cos(phi); targetPosition.z = position.z + 100 * Math.sin(phi) * Math.sin(theta); ship.lookAt(targetPosition); + //turret.move(); // Animation vom Raumschiff function animation(){ @@ -395,7 +391,7 @@ function changeCam() { function stop() { xAxis = 0.0; - yAxis = -0.0; + yAxis = 0.0; zAxis = 0.0; setSpeed(-yAxis); mouseX = 0.0; @@ -424,16 +420,16 @@ function cameraWatcher (){ if(!isFirstPerson){ if(lat> 57 && yAxis ==0){ - camera.setTarget('fTarget'); + //camera.setTarget('fTarget'); }else if(lat>65 &&yAxis ==-1){ - camera.setTarget ('fTarget'); + //camera.setTarget ('fTarget'); }else { - camera.setTarget('Target'); + //camera.setTarget('Target'); } diff --git a/app/Multiplayer.js b/app/Multiplayer.js new file mode 100644 index 0000000..5d68e60 --- /dev/null +++ b/app/Multiplayer.js @@ -0,0 +1,11 @@ +var socket = io(); + +socket.emit('connecton'); + +socket.on('host',function(){ + +}); + +socket.on('client',function(){ + +}); \ No newline at end of file diff --git a/app/Network.js b/app/Network.js index dd6294f..b9f65d9 100644 --- a/app/Network.js +++ b/app/Network.js @@ -1,6 +1,6 @@ -var HIGHSCORE_SERVER_BASE_URL = "http://localhost:8000"; +var HIGHSCORE_SERVER_BASE_URL = "http://localhost:3000"; -var OFFLINE_TEST_MODE = true; // TODO +var OFFLINE_TEST_MODE = false; // TODO var Network = function() { var data = [ @@ -40,7 +40,7 @@ var Network = function() { type: "POST", url: HIGHSCORE_SERVER_BASE_URL + "/api/1/highscore", contentType: "application/json; charset=utf-8", - data: score, + data: JSON.stringify(score), dataType: "json", success: function(data) { // TODO diff --git a/app/Player.js b/app/Player.js index 2224470..5a82827 100644 --- a/app/Player.js +++ b/app/Player.js @@ -338,7 +338,7 @@ function Player() { } -}; +} function doubleMgDmg(value){ diff --git a/app/RayParticleRenderer.js b/app/RayParticleRenderer.js index e3c787d..50d3e2e 100644 --- a/app/RayParticleRenderer.js +++ b/app/RayParticleRenderer.js @@ -60,7 +60,9 @@ function RayParticleRenderer(particleColor, nParticles, particleTexture, startVe }; this.reset = function () { - + + this.particleSystem.geometry.dispose(); + this.particleSystem.material.dispose(); scene.remove(this.particleSystem); this.particleSystem = undefined; diff --git a/app/Turret.js b/app/Turret.js new file mode 100644 index 0000000..852fecc --- /dev/null +++ b/app/Turret.js @@ -0,0 +1,127 @@ + +var rotupdn = 0; +var leftrgt = 0; + +var up = false; +var down = false; +var left = false; +var right = false; +var weaponTurret; +var refPoint; + +var rotX = 1; +var rotY = 1; + +function Turret(){ + + return{ + + init:function(){ + var tur = new THREE.BoxGeometry(2,5,2); + tur.translate(0,-7,0); + var material = new THREE.MeshBasicMaterial({color: 0xffffff}); + weaponTurret = new THREE.Mesh(tur,material); + weaponTurret.position.set(0,0,0); + ship.add(weaponTurret); + + var refe = new THREE.SphereGeometry(0.1,10,10); + var smaterial = new THREE.MeshBasicMaterial({ + + transparent: true, + color: 0xffffff + }); + refPoint = new THREE.Mesh(refe,smaterial); + refPoint.position.set(0,-5,0); + weaponTurret.add(refPoint); + + + + + var tkdown = function(event) { + + switch (event.keyCode) { + case 73: + down = true; + break; + case 74: + right = true; + break; + case 75: + up = true; + break; + case 76: + left = true; + } + }; + + var tkup = function(event) { + + switch (event.keyCode) { + case 73: + down = false; + break; + case 74: + right = false; + break; + case 75: + up = false; + break; + case 76: + left = false; + } + }; + + window.addEventListener('keydown', tkdown); + window.addEventListener('keyup', tkup); + }, + move:function() { + + if (up == true && rotupdn > -5) { + rotupdn--; + + } + if (down == true && rotupdn < 5) { + rotupdn++; + + } + if (left == true && leftrgt < 5) { + leftrgt++; + } + if (right == true && leftrgt > -5) { + leftrgt--; + } + if (rotupdn > 0) { + rotupdn -= 0.5; + } else if (rotupdn < 0) { + rotupdn += 0.5; + } + + if (leftrgt > 0) { + leftrgt -= 0.5; + } else if (leftrgt < 0) { + leftrgt += 0.5; + } + + if (weaponTurret.rotation.x < rotX && weaponTurret.rotation.x > -rotX) { + weaponTurret.rotateX(rotupdn / 30); + }else if(weaponTurret.rotation.x <= -rotX && rotupdn > 0){ + weaponTurret.rotateX(rotupdn / 30); + }else if(weaponTurret.rotation.x >= rotX && rotupdn < 0){ + weaponTurret.rotateX(rotupdn / 30); + } + + if (weaponTurret.rotation.z < rotY && weaponTurret.rotation.z > -rotY) { + weaponTurret.rotateZ(leftrgt / 30); + }else if(weaponTurret.rotation.z <= -rotY && leftrgt > 0){ + weaponTurret.rotateZ(leftrgt / 30); + }else if(weaponTurret.rotation.z >= rotY && leftrgt < 0){ + weaponTurret.rotateZ(leftrgt / 30); + } + weaponTurret.rotation.set(weaponTurret.rotation.x,0,weaponTurret.rotation.z); + + } + + } +} + + diff --git a/app/Weapon.js b/app/Weapon.js index da3d489..c31e9df 100644 --- a/app/Weapon.js +++ b/app/Weapon.js @@ -118,6 +118,7 @@ function initializeWeapons() { //initialize clock for time-control weaponClock = new THREE.Clock(); + //add Listener for left and rigth mouseclick document.body.addEventListener('click', shoot, false); @@ -227,6 +228,7 @@ function shoot(e) { if (weaponsActive == true){ if (e.button === 0) { shootLaser(); + //shoott(); //enemyShootLaser(dummyEnemy, ship.position); } else if (activeSecWeapon == 0) { @@ -292,8 +294,6 @@ function shootLaser() { //play lazer-sound laserAudio.play(); - //reset timer - timeSinceShoot = 0; //create mesh var laser = new THREE.Mesh(shootGeometry, shootMaterial); @@ -334,33 +334,75 @@ function shootLaser() { } +function shoott() { + if (timeSinceShoot > 0.4) { + timeSinceShoot = 0; + + //play lazer-sound + laserAudio.play(); + + //create mesh + var tlaser = new THREE.Mesh(shootGeometry, shootMaterial); + + tlaser.name = "Laser"; + //translate to ship position + tlaser.position.x = ship.position.x; + tlaser.position.y = ship.position.y; + tlaser.position.z = ship.position.z; + + //set orientation of the bullet according to ship orientation + var tempvec = new THREE.Vector3(refPoint.matrixWorld.elements[12], refPoint.matrixWorld.elements[13], refPoint.matrixWorld.elements[14]); + + tlaser.lookAt(tempvec); + + //rotate: laser beam would be pointing up otherwise + tlaser.rotateX(1.57); + tlaser.rotateX(Math.PI); + + tlaser.translateY(-85); + + + for (var i = -50; i <= 50; i++) { + var dummyDot = new THREE.Object3D(); + dummyDot.position.y = tlaser.geometry.parameters.height / 100 * i; + dummyDot.name = "BoxPoint" + i; + tlaser.add(dummyDot); + } + //add bullet to scene + scene.add(tlaser); + //add bullet to bullet list so it will be moved + + projectiles.push(tlaser); + + + //console.log(bullet1.name); + + //collidableMeshList.push(bullet1); + } +} + //Firering main-laser function enemyShootLaser(laserShootingBotPosition, laserShootingTarget) { - //play lazer-sound - laserAudio.play(); + //play lazer-sound + laserAudio.play(); - //create mesh - var laser = new THREE.Mesh(shootGeometry, shootMaterial); + //create mesh + var laser = new THREE.Mesh(shootGeometry, shootMaterial); - //set name for recognition in render-function - laser.name = "Laser"; + //set name for recognition in render-function + laser.name = "Laser"; //translate bullet to ship position laser.position.x = laserShootingBotPosition.x; laser.position.y = laserShootingBotPosition.y; laser.position.z = laserShootingBotPosition.z; - //set orientation of the bullet according to ship orientation - laser.lookAt(laserShootingTarget); + //set orientation of the bullet according to ship orientation + laser.lookAt(laserShootingTarget); - //rotate: laser beam would be pointing up otherwise - laser.rotateX(-1.57); - - //translate so that laser starts in front of ship - laser.translateY(-200); - - laser.translateZ(20); + //rotate: laser beam would be pointing up otherwise + laser.rotateX(-1.57); var numberDummyDots = 100; for (var i = 0; i <= numberDummyDots; i++) { @@ -369,17 +411,32 @@ function enemyShootLaser(laserShootingBotPosition, laserShootingTarget) { dummyDot.name = "BoxPoint" + i; laser.add(dummyDot); } + for (var i = -50; i <= 50; i++) { + var dummyDot = new THREE.Object3D(); + dummyDot.position.y = laser.geometry.parameters.height / 100 * i; + dummyDot.name = "BoxPoint" + i; + laser.add(dummyDot); + } - //add bullet to scene - scene.add(laser); - - //add laser to projectiles list so it will be moved - projectiles.push(laser); } + function successRocket(projectileIndex) { + + //get to hitbox belonging rocket + var rocket = projectiles[projectileIndex].userData; + //add bullet to scene + scene.add(laser); + + //add laser to projectiles list so it will be moved + projectiles.push(laser); + + } + + //projectileIndex: Index in projectile list of laser hitbox + function successLaser(projectileIndex) { //remove laser and laserbeam from scene for(var i = 0; i<=projectiles[projectileIndex].children.length; i++){ @@ -416,15 +473,16 @@ function successMachineGunBullet(projectileIndex) { } //Shooting Rocket -function shootRocket() { + function shootRocket() { - //if for limiting rocket-shooting frequence - if (timeSinceRocket > rocketReloadTime && rocketAmmo > 0) { - rocketAmmo -= 1; - updateWeaponInterface(); + //if for limiting rocket-shooting frequence + if (timeSinceRocket > rocketReloadTime && rocketAmmo > 0) { + rocketAmmo -= 1; + updateWeaponInterface(); + + //play rocket-sound + rocketAudio.play(); - //play rocket-sound - rocketAudio.play(); // create rocket var rocket = new THREE.Mesh(rocketGeometry, rocketMaterial); @@ -462,8 +520,7 @@ function shootRocket() { //reset timer timeSinceRocket = 0; } - -} + } //Shooting Rocket function shootGuidedMissile() { @@ -540,13 +597,18 @@ function shootGuidedMissile() { } //Explosion of the rocket at specific distance -function rocketExplode(rocket) { + function rocketExplode(rocket) { //play explosion time explosionAudio.play(); - //the explosion is a big sphere (dummy) - var explosion = new THREE.Mesh(explosionGeometry, explosionMaterial); + //play explosion time + explosionAudio.play(); + + + //the explosion is a big sphere (dummy) + var explosion = new THREE.Mesh(explosionGeometry, explosionMaterial); + //set rocket back for realistic detonation point rocket.translateZ(-40); @@ -555,47 +617,48 @@ function rocketExplode(rocket) { explosion.position.y = rocket.position.y; explosion.position.z = rocket.position.z; - var particleAnimationPosition = new THREE.Vector3(explosion.position.x, - explosion.position.y, - explosion.position.z); + var particleAnimationPosition = new THREE.Vector3(explosion.position.x, + explosion.position.y, + explosion.position.z); - //name for identification in rendering - explosion.name = "Explosion"; - explosion.visible = false; - //add explosion to scene - scene.add(explosion); + //name for identification in rendering + explosion.name = "Explosion"; + explosion.visible = false; + //add explosion to scene + scene.add(explosion); - //reset explosion timer for ending explosion after specific time - explosionTime = 0; + //reset explosion timer for ending explosion after specific time + explosionTime = 0; - //add explision to projetiles list for rendering and collision - projectiles.push(explosion); + //add explision to projetiles list for rendering and collision + projectiles.push(explosion); - // starte Particle: Implosion -> Explosion -> Halo - particleHandler.addImplosion(particleAnimationPosition); + // starte Particle: Implosion -> Explosion -> Halo + particleHandler.addImplosion(particleAnimationPosition); -} + } //calculates the distance between an Object and the spaceship -function calculateDistanceToShip(obj) { + function calculateDistanceToShip(obj) { - var dx = obj.position.x - ship.position.x; - var dy = obj.position.y - ship.position.y; - var dz = obj.position.z - ship.position.z; + var dx = obj.position.x - ship.position.x; + var dy = obj.position.y - ship.position.y; + var dz = obj.position.z - ship.position.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz); - -} + return Math.sqrt(dx * dx + dy * dy + dz * dz); + } //funtion for mooving weapons and destruction of rocket/explosion -function renderWeapons(){ + +function renderWeapons() { //Variable for adding the past time since last call to all Weapon-Time-Counters var add = weaponClock.getDelta(); //increment time counters for limiting shooting frequence + timeSinceShoot += add; timeSinceMG += add; timeSinceRocket += add; @@ -607,6 +670,7 @@ function renderWeapons(){ shockwaveTime += add; //function for limiting single shootings while MG-shooting + if(mgCounter > 0){ if(timeSinceMG >0.05){ timeSinceMG = 0; @@ -681,8 +745,93 @@ function renderWeapons(){ } } - -} +//funtion for mooving weapons and destruction of rocket/explosion + function renderWeapons() { + + + //Variable for adding the past time since last call to all Weapon-Time-Counters + var add = weaponClock.getDelta(); + + //increment time counters for limiting shooting frequence + timeSinceShoot += add; + timeSinceMG += add; + timeSinceRocket += add; + timeSinceShockwave += add; + //variable for limiting explosion lifespan + explosionTime += add; + shockwaveTime += add; + + //function for limiting single shootings while MG-shooting + if (mgCounter > 0) { + if (timeSinceMG > 0.05) { + timeSinceMG = 0; + MGShoot(); + mgCounter -= 1; + } + } + + //Translate all projectiles and check for end of existance + for (var bul in projectiles) { + + //calculate distance between projectile and spaceship + var dis = calculateDistanceToShip(projectiles[bul]); + + //check name and proceed accordingly + + //if projectile is a laser hitbox: + if (projectiles[bul].name == "Laser") { + + //translate in mooving direction + projectiles[bul].translateY(-4000 * add); + + //translate to hitbox belonging laser-beam + if (dis > biggerSphereRadius) { + successLaser(bul); + } + } + + //if projectile is a rocket Hitbox: + else if (projectiles[bul].name == "Rocket") { + //translate in mooving direction (translateZ becouse of different orientation then laser) + projectiles[bul].translateZ(2000 * add); + + //translate to hitbox belonging rocket + var rkt = projectiles[bul]; + rkt.translateZ(2000 * add); + //console.log(rkt); + + if (dis > 1500) { + successRocket(bul); + } + } + //if projectile is an Explosion: + else if (projectiles[bul].name == "Explosion") { + //Check if Explosion + if (explosionTime > 0.15) { + scene.remove(projectiles[bul]); + projectiles.splice(bul, 1); + } + } + else if (projectiles[bul].name == "MachineGun") { + //translate in mooving direction + projectiles[bul].translateZ(-1000 * add); + + if (dis > 800) { + successMachineGunBullet(bul); + } + } + else if (projectiles[bul].name == "Shockwave") { + //Check if Explosion + if (shockwaveTime > 0.15) { + scene.remove(projectiles[bul]); + projectiles.splice(bul, 1); + } + } + + } + + } + } function inRange(rkt, enemy) { if (rkt.position.x < enemy.position.x + 10 @@ -699,12 +848,12 @@ function inRange(rkt, enemy) { function toggleWeapons() { - if (weaponsActive === true) { - document.removeEventListener('click', shoot, false); - weaponsActive = false; - } else { - document.addEventListener('click', shoot, false); - weaponsActive = true; - } + if (weaponsActive === true) { + document.removeEventListener('click', shoot, false); + weaponsActive = false; + } else { + document.addEventListener('click', shoot, false); + weaponsActive = true; + } -} + } diff --git a/app/World.js b/app/World.js new file mode 100644 index 0000000..0d26d1d --- /dev/null +++ b/app/World.js @@ -0,0 +1,358 @@ +/*var sphere = new THREE.Object3D(); +var biggerSphere = new THREE.Object3D(); +var stars = []; + +/*var asteroids = []; +>>>>>>> 106e7f639ff0f7197b7976b29414f702ecf4f6fb +var asteroidsHP = []; +var asteroidSpeedVecs = []; +var asteroidRotVecs = []; +//var asteroidHitBoxes = []; +var smallSphereRadius = 1000; +var biggerSphereRadius = 5000; +var asteroidRadius = 3.5; +var defaultAsteroidHP = 10; +var destroyedAsteroids = 0; //für die milestones +var asteroidRadius = 4.2; +var defaultAsteroidHP = 10;*/ + + +//starStuff +/*function createStars() { + + var star, material, alpha; + + for (var count = 0; count < 300; count++) { + + material = new THREE.MeshBasicMaterial({ + transparent: true, + combine: THREE.MixOperation, + blending: THREE.AdditiveBlending, + + color: 0xffffff + }); + + var sphereGeometry = new THREE.SphereGeometry(1, 32, 32); + + // make the star + star = new THREE.Mesh(sphereGeometry, material); + + star.position.x = ship.position.x + Math.floor(Math.random() * (smallSphereRadius - (-smallSphereRadius)) - smallSphereRadius); + star.position.y = ship.position.y + Math.floor(Math.random() * (smallSphereRadius - (-smallSphereRadius)) - smallSphereRadius); + star.position.z = ship.position.z + Math.floor(Math.random() * (smallSphereRadius - (-smallSphereRadius)) - smallSphereRadius); + star.scale.x = star.scale.y = star.scale.z = Math.random() * 3 - 2; + + scene.add(star); + stars.push(star); + } + +}*/ + + +//AsteroidStuff +/* +function createAsteroids() { + + var rndSpeedX, rndSpeedY, rndSpeedZ, rotSpeed, rndScale; + + var materialAst, astHitBox, hitGeometry; + var astTexture, astOriginal;*/ +/* + astGeometry = fileLoader.get("AsteroidV2"); + astTexture = fileLoader.get("AsteroidTex"); + + for (countAst = 0; countAst < 150; countAst++) {*/ + +/* rndSpeedX = Math.random() * 15 - 11; + rndSpeedY = Math.random() * 15 - 11; + rndSpeedZ = Math.random() * 15 - 11;*/ + /*rotSpeed = Math.random() * 0.05 - 0.01;*/ + /*rndScale = Math.random() * 30;*/ +/* + var vecSpeed = new THREE.Vector3(rndSpeedX, rndSpeedY, rndSpeedZ); + var vecRot = new THREE.Vector3(rotSpeed * (Math.random() * (2 - 0) - 0), rotSpeed * (Math.random() * (2 - 0) - 0), rotSpeed * (Math.random() * 2 - 0)); + asteroidSpeedVecs.push(vecSpeed); + asteroidRotVecs.push(vecRot);*/ + + /* astOriginal = new THREE.Mesh(astGeometry, new THREE.MeshPhongMaterial({ map: astTexture })); +*/ +/* astOriginal.position.x = ship.position.x + Math.floor(Math.random() * (biggerSphereRadius - (-biggerSphereRadius)) - biggerSphereRadius); + astOriginal.position.y = ship.position.y + Math.floor(Math.random() * (biggerSphereRadius - (-biggerSphereRadius)) - biggerSphereRadius); + astOriginal.position.z = ship.position.z + Math.floor(Math.random() * (biggerSphereRadius - (-biggerSphereRadius)) - biggerSphereRadius);*/ + +/* astOriginal.scale.x = astOriginal.scale.y = astOriginal.scale.z = rndScale; +*//* hitGeometry = new THREE.SphereGeometry(asteroidRadius * rndScale, 32, 32); + + var colSphereMaterial = new THREE.MeshBasicMaterial({ + transparent: true, + opacity: 0.5, + color: 0xffffff + });*/ + +/* astHitBox = new THREE.Mesh(hitGeometry, colSphereMaterial); + astHitBox.position.set(astOriginal.position.x, astOriginal.position.y, astOriginal.position.z); +*/ +/* asteroidsHP.push(defaultAsteroidHP); + asteroids.push(astOriginal); + asteroidHitBoxes.push(astHitBox); + scene.add(astOriginal);*/ + /* } + +}*/ + + +//Update asteroid-position and their hitboxes with randomized speed and rotation; +/*function updateAsteroids() { + + var tmpAsteroid, newVec, rndAngle2; + var tmpHitBox; + + for (countAst = 0; countAst < asteroids.length; countAst++) { + + tmpAsteroid = asteroids[countAst]; + tmpHitBox = asteroidHitBoxes[countAst];*/ + //Update RotationValue +/* tmpAsteroid.rotation.x += asteroidRotVecs[countAst].x; + tmpAsteroid.rotation.y -= asteroidRotVecs[countAst].y; + tmpAsteroid.rotation.z -= asteroidRotVecs[countAst].z; +*/ + //Update SpeedValue +/* tmpAsteroid.position.x += asteroidSpeedVecs[countAst].x; + tmpAsteroid.position.y += asteroidSpeedVecs[countAst].y; + tmpAsteroid.position.z += asteroidSpeedVecs[countAst].z; +*/ + //Update SpeedValue Hitbox +/* tmpHitBox.position.x += asteroidSpeedVecs[countAst].x; + tmpHitBox.position.y += asteroidSpeedVecs[countAst].y; + tmpHitBox.position.z += asteroidSpeedVecs[countAst].z; + + if ((tmpAsteroid.position.x < biggerSphere.position.x - biggerSphereRadius || tmpAsteroid.position.x > biggerSphere.position.x + biggerSphereRadius || tmpAsteroid.position.y < biggerSphere.position.y - biggerSphereRadius || tmpAsteroid.position.y > biggerSphere.position.y + biggerSphereRadius || tmpAsteroid.position.z < biggerSphere.position.z - biggerSphereRadius || tmpAsteroid.position.z > biggerSphere.position.z + biggerSphereRadius)) { + + newVec = new THREE.Vector3(Math.random(), Math.random(), Math.random()); + newVec.normalize(); + + var rnd1, rnd2, rnd3; + + rnd1 = Math.sign(Math.sign(Math.random() - 0.5) + 0.1); + rnd2 = Math.sign(Math.sign(Math.random() - 0.5) + 0.1); + rnd3 = Math.sign(Math.sign(Math.random() - 0.5) + 0.1); + + tmpAsteroid.position.x = ship.position.x + rnd1 * biggerSphereRadius * newVec.x; + tmpAsteroid.position.y = ship.position.y + rnd2 * biggerSphereRadius * newVec.y; + tmpAsteroid.position.z = ship.position.z + rnd3 * biggerSphereRadius * newVec.z; + + tmpHitBox.position.x = ship.position.x + rnd1 * biggerSphereRadius * newVec.x; + tmpHitBox.position.y = ship.position.y + rnd2 * biggerSphereRadius * newVec.y; + tmpHitBox.position.z = ship.position.z + rnd3 * biggerSphereRadius * newVec.z; + }*/ +/* } + +}*/ + + +//Function to trigger if asteroids collide +/*function asteroidCollision(ast1Index, ast2Index) { + + var ast1 = asteroids[ast1Index]; + var ast2 = asteroids[ast2Index]; + var ast1Dir = asteroidSpeedVecs[ast1Index]; + var ast2Dir = asteroidSpeedVecs[ast2Index]; + + if (asteroidHitBoxes[ast1Index].geometry.parameters.radius > 55 && asteroidHitBoxes[ast2Index].geometry.parameters.radius > 55) { + var axis = ast2.position.clone(); + axis.sub(ast1.position); + + var negAxis = ast1.position.clone(); + negAxis.sub(ast2.position); + + axis.normalize(); + negAxis.normalize(); + + ast1Dir = ast1Dir.sub(axis.multiplyScalar(2 * ast1Dir.dot(axis))); + ast2Dir = ast2Dir.sub(negAxis.multiplyScalar(2 * ast2Dir.dot(negAxis))); + + asteroidSpeedVecs[ast1Index] = ast1Dir; + asteroidSpeedVecs[ast2Index] = ast2Dir; + } + + else if (asteroidHitBoxes[ast1Index].geometry.parameters.radius < 55 && asteroidHitBoxes[ast2Index].geometry.parameters.radius > 55) { + destroyAsteroid(ast1Index, "AsteroidAsteroidCollision"); + } else if (asteroidHitBoxes[ast1Index].geometry.parameters.radius > 55 && asteroidHitBoxes[ast2Index].geometry.parameters.radius < 55) { + destroyAsteroid(ast2Index, "AsteroidAsteroidCollision"); + } else if (asteroidHitBoxes[ast1Index].geometry.parameters.radius < 55 && asteroidHitBoxes[ast2Index].geometry.parameters.radius < 55) { + destroyAsteroid(ast1Index, "AsteroidAsteroidCollision"); + destroyAsteroid(ast2Index, "AsteroidAsteroidCollision"); + } + +}*/ + + +/*function hitAsteroid(asteroidNumber, collisionType) { + + switch (collisionType) { + + case "Laser": + asteroidsHP[asteroidNumber] -= laserDamage; + + // particleHandler.addShockwave(asteroids[asteroidNumber].position, 0xff6611); + particleHandler.addLittleExplosion(asteroids[asteroidNumber].position, 3, 0xff0000, 1, 1); + particleHandler.addLittleExplosion(asteroids[asteroidNumber].position, 3, 0xffffff, 1, 1); + + break; + + case "Rocket": + + asteroidsHP[asteroidNumber] -= rocketDamage; + + break; + + case "Explosion": + + asteroidsHP[asteroidNumber] -= explosionDamage; + break; + + case "MachineGun": + + asteroidsHP[asteroidNumber] -= MGDamage; + break; + + case "ShockWave": + + asteroidsHP[asteroidNumber] -= shockWaveDamage; + break; + + default: + + break; + + } + + if (asteroidsHP[asteroidNumber] <= 0) { + destroyAsteroid(asteroidNumber, collisionType); + } + +}*/ + + + +/*function changeAsteroidDirection (asteroidNumber){ + + var newRotVal = Math.random() * (2 +1) - 1; + + asteroidSpeedVecs[asteroidNumber] = asteroidSpeedVecs[asteroidNumber].multiplyScalar(-1) ; + asteroidSpeedVecs[asteroidNumber] = asteroidSpeedVecs[asteroidNumber].add(3) ; + + asteroidRotVecs[asteroidNumber] = asteroidRotVecs[asteroidNumber].multiplyScalar(newRotVal); + + + +}*/ + + +/*//Function to trigger if Asteroid get destroyed +function destroyAsteroid(asteroidNumber, collisionType) { + + //für die Milestones + destroyedAsteroids++; + checkMilestones(); + + asteroidAudio.play(); + + // update Highscore + switch (collisionType) { + + case "Laser": + case "Rocket": + case "Explosion": + changeScore(scoreValues["asteroidDestroyed"]); + + break; + + default: + + break; + + } + + newVec = new THREE.Vector3(Math.random(), Math.random(), Math.random()); + newVec.normalize(); + + var rnd1, rnd2, rnd3; + + rnd1 = Math.sign(Math.sign(Math.random() - 0.5) + 0.1); + rnd2 = Math.sign(Math.sign(Math.random() - 0.5) + 0.1); + rnd3 = Math.sign(Math.sign(Math.random() - 0.5) + 0.1); + + particleHandler.addExplosion(asteroids[asteroidNumber].position, 2, 0xcccccc, 1, asteroidHitBoxes[asteroidNumber].geometry.parameters.radius / 45); + + var newScale = Math.random() * 30; + + spawnPowerUp(asteroids[asteroidNumber].position.x, asteroids[asteroidNumber].position.y, asteroids[asteroidNumber].position.z); + asteroids[asteroidNumber].position.x = ship.position.x + rnd1 * biggerSphereRadius * newVec.x; + asteroids[asteroidNumber].position.y = ship.position.y + rnd2 * biggerSphereRadius * newVec.y; + asteroids[asteroidNumber].position.z = ship.position.z + rnd3 * biggerSphereRadius * newVec.z; + + asteroidHitBoxes[asteroidNumber].position.x = ship.position.x + rnd1 * biggerSphereRadius * newVec.x; + asteroidHitBoxes[asteroidNumber].position.y = ship.position.y + rnd2 * biggerSphereRadius * newVec.y; + asteroidHitBoxes[asteroidNumber].position.z = ship.position.z + rnd3 * biggerSphereRadius * newVec.z; + + asteroidsHP[asteroidNumber] = defaultAsteroidHP; + +}*/ +/* +//Function to create the Spheres around the player +function World() { + + return { + init: function () { + + var geometry = new THREE.SphereGeometry(smallSphereRadius, 200, 200); + var biggerGeometry = new THREE.SphereGeometry(biggerSphereRadius, 200, 200); + + var material = new THREE.MeshBasicMaterial({ + transparent: true + + }); + + sphere = new THREE.Mesh(geometry, material); + biggerSphere = new THREE.Mesh(biggerGeometry, material); + biggerSphere.position.set(0, 0, 0); + sphere.position.set(0, 0, 0); + } + } + +} + +//Update stars- check if they are inside Sphere. Else randomize Position +function updateStars() { + + // iterate through every star + for (var i = 0; i < stars.length; i++) { + star = stars[i]; + + var temp = Math.sin(clock.getElapsedTime()); + temp = temp == 0 ? 0.00001 : temp; + + star.scale.x = star.scale.y = star.scale.z = temp; + + if ((star.position.x < sphere.position.x - smallSphereRadius || star.position.x > sphere.position.x + smallSphereRadius || star.position.y < sphere.position.y - smallSphereRadius || star.position.y > sphere.position.y + smallSphereRadius || star.position.z < sphere.position.z - smallSphereRadius || star.position.z > sphere.position.z + smallSphereRadius)) { + + star.position.x = ship.position.x + Math.floor(Math.random() * (smallSphereRadius - (-smallSphereRadius)) - smallSphereRadius); + star.position.y = ship.position.y + Math.floor(Math.random() * (smallSphereRadius - (-smallSphereRadius)) - smallSphereRadius); + star.position.z = ship.position.z + Math.floor(Math.random() * (smallSphereRadius - (-smallSphereRadius)) - smallSphereRadius); + } + + } +} + +//function to get the directionVector of a Mesh +function getMeshDirection(mesh) { + + //Default Front-Facing + var dir = new THREE.Vector3(0, 0, 1); + //Apply rotation of Mesh + dir.applyQuaternion(mesh.quaternion); + + return dir; +}*/ + diff --git a/app/core.js b/app/core.js index 2db10d2..4bb60b1 100644 --- a/app/core.js +++ b/app/core.js @@ -16,7 +16,11 @@ var crosshair; var ship; var player; var movement; +//var turret; +var explosionParticleHandler; +var frames = 0; var particleHandler; + var collision; var stats; var network; @@ -79,7 +83,7 @@ function init() { scene = new THREE.Scene(); clock = new THREE.Clock(); - + /********** Szene füllen **********/ var light, object; @@ -107,6 +111,9 @@ function init() { crosshair = new Crosshairs(); crosshair.init(); + //turret = new Turret(); + //turret.init(); + initializeWeapons(); stats = new Stats(); @@ -121,7 +128,7 @@ function init() { cameraPosition: new THREE.Vector3(0, 15, 30), fixed: false, stiffness: 0.15, - matchRotation: false + matchRotation: true }); camera.addTarget({ @@ -133,6 +140,7 @@ function init() { matchRotation: true }); + camera.addTarget({ name: 'fTarget', targetObject: ship, @@ -151,7 +159,6 @@ function init() { matchRotation: false }); - var cam = Camera(); cam.init(); @@ -201,7 +208,6 @@ function cameraAnimate() { frames++; requestAnimationFrame(cameraAnimate); } else { - requestAnimationFrame(animate); } @@ -266,7 +272,7 @@ function render() { camera.update(); if (glitchPassEnabled) { - composer.render(); + composer.render(); } else { renderer.render(scene, camera); } diff --git a/app/game.html b/app/game.html index 7b60846..fe2d28f 100644 --- a/app/game.html +++ b/app/game.html @@ -679,10 +679,13 @@ + +
    + +
    - + + @@ -795,6 +798,8 @@ + + @@ -809,6 +814,7 @@ + diff --git a/index.html b/index.html index 2f77e2b..98c4b22 100644 --- a/index.html +++ b/index.html @@ -12,12 +12,15 @@ + + + diff --git a/node_modules/.bin/mime b/node_modules/.bin/mime new file mode 100644 index 0000000..0dbddf0 --- /dev/null +++ b/node_modules/.bin/mime @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../mime/cli.js" "$@" + ret=$? +else + node "$basedir/../mime/cli.js" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/.bin/mime.cmd b/node_modules/.bin/mime.cmd new file mode 100644 index 0000000..8169562 --- /dev/null +++ b/node_modules/.bin/mime.cmd @@ -0,0 +1,7 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\mime\cli.js" %* +) ELSE ( + @SETLOCAL + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\mime\cli.js" %* +) \ No newline at end of file diff --git a/node_modules/accepts/HISTORY.md b/node_modules/accepts/HISTORY.md new file mode 100644 index 0000000..0508481 --- /dev/null +++ b/node_modules/accepts/HISTORY.md @@ -0,0 +1,74 @@ +1.1.4 / 2014-12-10 +================== + + * deps: mime-types@~2.0.4 + - deps: mime-db@~1.3.0 + +1.1.3 / 2014-11-09 +================== + + * deps: mime-types@~2.0.3 + - deps: mime-db@~1.2.0 + +1.1.2 / 2014-10-14 +================== + + * deps: negotiator@0.4.9 + - Fix error when media type has invalid parameter + +1.1.1 / 2014-09-28 +================== + + * deps: mime-types@~2.0.2 + - deps: mime-db@~1.1.0 + * deps: negotiator@0.4.8 + - Fix all negotiations to be case-insensitive + - Stable sort preferences of same quality according to client order + +1.1.0 / 2014-09-02 +================== + + * update `mime-types` + +1.0.7 / 2014-07-04 +================== + + * Fix wrong type returned from `type` when match after unknown extension + +1.0.6 / 2014-06-24 +================== + + * deps: negotiator@0.4.7 + +1.0.5 / 2014-06-20 +================== + + * fix crash when unknown extension given + +1.0.4 / 2014-06-19 +================== + + * use `mime-types` + +1.0.3 / 2014-06-11 +================== + + * deps: negotiator@0.4.6 + - Order by specificity when quality is the same + +1.0.2 / 2014-05-29 +================== + + * Fix interpretation when header not in request + * deps: pin negotiator@0.4.5 + +1.0.1 / 2014-01-18 +================== + + * Identity encoding isn't always acceptable + * deps: negotiator@~0.4.0 + +1.0.0 / 2013-12-27 +================== + + * Genesis diff --git a/node_modules/accepts/LICENSE b/node_modules/accepts/LICENSE new file mode 100644 index 0000000..f23dca8 --- /dev/null +++ b/node_modules/accepts/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014 Jonathan Ong + +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. diff --git a/node_modules/accepts/README.md b/node_modules/accepts/README.md new file mode 100644 index 0000000..a9bc28a --- /dev/null +++ b/node_modules/accepts/README.md @@ -0,0 +1,94 @@ +# accepts + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +Higher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use. + +In addition to negotatior, it allows: + +- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`. +- Allows type shorthands such as `json`. +- Returns `false` when no types match +- Treats non-existent headers as `*` + +## API + +### var accept = new Accepts(req) + +```js +var accepts = require('accepts') + +http.createServer(function (req, res) { + var accept = accepts(req) +}) +``` + +### accept\[property\]\(\) + +Returns all the explicitly accepted content property as an array in descending priority. + +- `accept.types()` +- `accept.encodings()` +- `accept.charsets()` +- `accept.languages()` + +They are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc. + +Note: you should almost never do this in a real app as it defeats the purpose of content negotiation. + +Example: + +```js +// in Google Chrome +var encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate'] +``` + +Since you probably don't support `sdch`, you should just supply the encodings you support: + +```js +var encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably +``` + +### accept\[property\]\(values, ...\) + +You can either have `values` be an array or have an argument list of values. + +If the client does not accept any `values`, `false` will be returned. +If the client accepts any `values`, the preferred `value` will be return. + +For `accept.types()`, shorthand mime types are allowed. + +Example: + +```js +// req.headers.accept = 'application/json' + +accept.types('json') // -> 'json' +accept.types('html', 'json') // -> 'json' +accept.types('html') // -> false + +// req.headers.accept = '' +// which is equivalent to `*` + +accept.types() // -> [], no explicit types +accept.types('text/html', 'text/json') // -> 'text/html', since it was first +``` + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/accepts.svg?style=flat +[npm-url]: https://npmjs.org/package/accepts +[node-version-image]: https://img.shields.io/node/v/accepts.svg?style=flat +[node-version-url]: http://nodejs.org/download/ +[travis-image]: https://img.shields.io/travis/jshttp/accepts.svg?style=flat +[travis-url]: https://travis-ci.org/jshttp/accepts +[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts.svg?style=flat +[coveralls-url]: https://coveralls.io/r/jshttp/accepts +[downloads-image]: https://img.shields.io/npm/dm/accepts.svg?style=flat +[downloads-url]: https://npmjs.org/package/accepts diff --git a/node_modules/accepts/index.js b/node_modules/accepts/index.js new file mode 100644 index 0000000..805e33a --- /dev/null +++ b/node_modules/accepts/index.js @@ -0,0 +1,160 @@ +var Negotiator = require('negotiator') +var mime = require('mime-types') + +var slice = [].slice + +module.exports = Accepts + +function Accepts(req) { + if (!(this instanceof Accepts)) + return new Accepts(req) + + this.headers = req.headers + this.negotiator = Negotiator(req) +} + +/** + * Check if the given `type(s)` is acceptable, returning + * the best match when true, otherwise `undefined`, in which + * case you should respond with 406 "Not Acceptable". + * + * The `type` value may be a single mime type string + * such as "application/json", the extension name + * such as "json" or an array `["json", "html", "text/plain"]`. When a list + * or array is given the _best_ match, if any is returned. + * + * Examples: + * + * // Accept: text/html + * this.types('html'); + * // => "html" + * + * // Accept: text/*, application/json + * this.types('html'); + * // => "html" + * this.types('text/html'); + * // => "text/html" + * this.types('json', 'text'); + * // => "json" + * this.types('application/json'); + * // => "application/json" + * + * // Accept: text/*, application/json + * this.types('image/png'); + * this.types('png'); + * // => undefined + * + * // Accept: text/*;q=.5, application/json + * this.types(['html', 'json']); + * this.types('html', 'json'); + * // => "json" + * + * @param {String|Array} type(s)... + * @return {String|Array|Boolean} + * @api public + */ + +Accepts.prototype.type = +Accepts.prototype.types = function (types) { + if (!Array.isArray(types)) types = slice.call(arguments); + var n = this.negotiator; + if (!types.length) return n.mediaTypes(); + if (!this.headers.accept) return types[0]; + var mimes = types.map(extToMime); + var accepts = n.mediaTypes(mimes.filter(validMime)); + var first = accepts[0]; + if (!first) return false; + return types[mimes.indexOf(first)]; +} + +/** + * Return accepted encodings or best fit based on `encodings`. + * + * Given `Accept-Encoding: gzip, deflate` + * an array sorted by quality is returned: + * + * ['gzip', 'deflate'] + * + * @param {String|Array} encoding(s)... + * @return {String|Array} + * @api public + */ + +Accepts.prototype.encoding = +Accepts.prototype.encodings = function (encodings) { + if (!Array.isArray(encodings)) encodings = slice.call(arguments); + var n = this.negotiator; + if (!encodings.length) return n.encodings(); + return n.encodings(encodings)[0] || false; +} + +/** + * Return accepted charsets or best fit based on `charsets`. + * + * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` + * an array sorted by quality is returned: + * + * ['utf-8', 'utf-7', 'iso-8859-1'] + * + * @param {String|Array} charset(s)... + * @return {String|Array} + * @api public + */ + +Accepts.prototype.charset = +Accepts.prototype.charsets = function (charsets) { + if (!Array.isArray(charsets)) charsets = [].slice.call(arguments); + var n = this.negotiator; + if (!charsets.length) return n.charsets(); + if (!this.headers['accept-charset']) return charsets[0]; + return n.charsets(charsets)[0] || false; +} + +/** + * Return accepted languages or best fit based on `langs`. + * + * Given `Accept-Language: en;q=0.8, es, pt` + * an array sorted by quality is returned: + * + * ['es', 'pt', 'en'] + * + * @param {String|Array} lang(s)... + * @return {Array|String} + * @api public + */ + +Accepts.prototype.lang = +Accepts.prototype.langs = +Accepts.prototype.language = +Accepts.prototype.languages = function (langs) { + if (!Array.isArray(langs)) langs = slice.call(arguments); + var n = this.negotiator; + if (!langs.length) return n.languages(); + if (!this.headers['accept-language']) return langs[0]; + return n.languages(langs)[0] || false; +} + +/** + * Convert extnames to mime. + * + * @param {String} type + * @return {String} + * @api private + */ + +function extToMime(type) { + if (~type.indexOf('/')) return type; + return mime.lookup(type); +} + +/** + * Check if mime is valid. + * + * @param {String} type + * @return {String} + * @api private + */ + +function validMime(type) { + return typeof type === 'string'; +} diff --git a/node_modules/accepts/package.json b/node_modules/accepts/package.json new file mode 100644 index 0000000..57539d1 --- /dev/null +++ b/node_modules/accepts/package.json @@ -0,0 +1,126 @@ +{ + "_args": [ + [ + { + "raw": "accepts@~1.1.3", + "scope": null, + "escapedName": "accepts", + "name": "accepts", + "rawSpec": "~1.1.3", + "spec": ">=1.1.3 <1.2.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "accepts@>=1.1.3 <1.2.0", + "_id": "accepts@1.1.4", + "_inCache": true, + "_installable": true, + "_location": "/accepts", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "accepts@~1.1.3", + "scope": null, + "escapedName": "accepts", + "name": "accepts", + "rawSpec": "~1.1.3", + "spec": ">=1.1.3 <1.2.0", + "type": "range" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", + "_shasum": "d71c96f7d41d0feda2c38cd14e8a27c04158df4a", + "_shrinkwrap": null, + "_spec": "accepts@~1.1.3", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "bugs": { + "url": "https://github.com/jshttp/accepts/issues" + }, + "dependencies": { + "mime-types": "~2.0.4", + "negotiator": "0.4.9" + }, + "description": "Higher-level content negotiation", + "devDependencies": { + "istanbul": "~0.3.4", + "mocha": "~2.0.1" + }, + "directories": {}, + "dist": { + "shasum": "d71c96f7d41d0feda2c38cd14e8a27c04158df4a", + "tarball": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "files": [ + "LICENSE", + "HISTORY.md", + "index.js" + ], + "gitHead": "df66414d80f096627b28f137127fce0a851d7900", + "homepage": "https://github.com/jshttp/accepts", + "keywords": [ + "content", + "negotiation", + "accept", + "accepts" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "federomero", + "email": "federomero@gmail.com" + }, + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "shtylman", + "email": "shtylman@gmail.com" + }, + { + "name": "mscdex", + "email": "mscdex@mscdex.net" + }, + { + "name": "fishrock123", + "email": "fishrock123@rocketmail.com" + } + ], + "name": "accepts", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jshttp/accepts.git" + }, + "scripts": { + "test": "mocha --reporter spec --check-leaks --bail test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" + }, + "version": "1.1.4" +} diff --git a/node_modules/after/.npmignore b/node_modules/after/.npmignore new file mode 100644 index 0000000..6c78602 --- /dev/null +++ b/node_modules/after/.npmignore @@ -0,0 +1,2 @@ +node_modules +.monitor diff --git a/node_modules/after/.travis.yml b/node_modules/after/.travis.yml new file mode 100644 index 0000000..84fd7ca --- /dev/null +++ b/node_modules/after/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - 0.9 diff --git a/node_modules/after/LICENCE b/node_modules/after/LICENCE new file mode 100644 index 0000000..7c35130 --- /dev/null +++ b/node_modules/after/LICENCE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Raynos. + +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. \ No newline at end of file diff --git a/node_modules/after/README.md b/node_modules/after/README.md new file mode 100644 index 0000000..0012d35 --- /dev/null +++ b/node_modules/after/README.md @@ -0,0 +1,75 @@ +# After [![Build Status][1]][2] + +Invoke callback after n calls + +## Status: production ready + +## Example + + var after = require("after") + , next = after(3, logItWorks) + + next() + next() + next() // it works + + function logItWorks() { + console.log("it works!") + } + +## Example with error handling + + var after = require("after") + , next = after(3, logError) + + next() + next(new Error("oops")) // logs oops + next() // does nothing + + function logError(err) { + console.log(err) + } + +## After < 0.6.0 + +Older versions of after had iterators and flows in them. + +These have been replaced with seperate modules + + - [iterators][8] + - [composite][9] + +## Installation + +`npm install after` + +## Tests + +`npm test` + +## Blog post + + - [Flow control in node.js][3] + +## Examples : + + - [Determining the end of asynchronous operations][4] + - [In javascript what are best practices for executing multiple asynchronous functions][5] + - [JavaScript performance long running tasks][6] + - [Synchronous database queries with node.js][7] + +## Contributors + + - Raynos + +## MIT Licenced + + [1]: https://secure.travis-ci.org/Raynos/after.png + [2]: http://travis-ci.org/Raynos/after + [3]: http://raynos.org/blog/2/Flow-control-in-node.js + [4]: http://stackoverflow.com/questions/6852059/determining-the-end-of-asynchronous-operations-javascript/6852307#6852307 + [5]: http://stackoverflow.com/questions/6869872/in-javascript-what-are-best-practices-for-executing-multiple-asynchronous-functi/6870031#6870031 + [6]: http://stackoverflow.com/questions/6864397/javascript-performance-long-running-tasks/6889419#6889419 + [7]: http://stackoverflow.com/questions/6597493/synchronous-database-queries-with-node-js/6620091#6620091 + [8]: http://github.com/Raynos/iterators + [9]: http://github.com/Raynos/composite diff --git a/node_modules/after/index.js b/node_modules/after/index.js new file mode 100644 index 0000000..ec24879 --- /dev/null +++ b/node_modules/after/index.js @@ -0,0 +1,28 @@ +module.exports = after + +function after(count, callback, err_cb) { + var bail = false + err_cb = err_cb || noop + proxy.count = count + + return (count === 0) ? callback() : proxy + + function proxy(err, result) { + if (proxy.count <= 0) { + throw new Error('after called too many times') + } + --proxy.count + + // after first error, rest are passed to err_cb + if (err) { + bail = true + callback(err) + // future error callbacks will go to error handler + callback = err_cb + } else if (proxy.count === 0 && !bail) { + callback(null, result) + } + } +} + +function noop() {} diff --git a/node_modules/after/package.json b/node_modules/after/package.json new file mode 100644 index 0000000..2dce351 --- /dev/null +++ b/node_modules/after/package.json @@ -0,0 +1,97 @@ +{ + "_args": [ + [ + { + "raw": "after@0.8.1", + "scope": null, + "escapedName": "after", + "name": "after", + "rawSpec": "0.8.1", + "spec": "0.8.1", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser" + ] + ], + "_from": "after@0.8.1", + "_id": "after@0.8.1", + "_inCache": true, + "_installable": true, + "_location": "/after", + "_npmUser": { + "name": "raynos", + "email": "raynos2@gmail.com" + }, + "_npmVersion": "1.2.25", + "_phantomChildren": {}, + "_requested": { + "raw": "after@0.8.1", + "scope": null, + "escapedName": "after", + "name": "after", + "rawSpec": "0.8.1", + "spec": "0.8.1", + "type": "version" + }, + "_requiredBy": [ + "/engine.io-parser" + ], + "_resolved": "https://registry.npmjs.org/after/-/after-0.8.1.tgz", + "_shasum": "ab5d4fb883f596816d3515f8f791c0af486dd627", + "_shrinkwrap": null, + "_spec": "after@0.8.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser", + "author": { + "name": "Raynos", + "email": "raynos2@gmail.com" + }, + "bugs": { + "url": "https://github.com/Raynos/after/issues" + }, + "contributors": [ + { + "name": "Raynos", + "email": "raynos2@gmail.com", + "url": "http://raynos.org" + } + ], + "dependencies": {}, + "description": "after - tiny flow control", + "devDependencies": { + "mocha": "~1.8.1" + }, + "directories": {}, + "dist": { + "shasum": "ab5d4fb883f596816d3515f8f791c0af486dd627", + "tarball": "https://registry.npmjs.org/after/-/after-0.8.1.tgz" + }, + "homepage": "https://github.com/Raynos/after#readme", + "keywords": [ + "flowcontrol", + "after", + "flow", + "control", + "arch" + ], + "maintainers": [ + { + "name": "raynos", + "email": "raynos2@gmail.com" + }, + { + "name": "shtylman", + "email": "shtylman@gmail.com" + } + ], + "name": "after", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/Raynos/after.git" + }, + "scripts": { + "test": "mocha --ui tdd --reporter spec test/*.js" + }, + "version": "0.8.1" +} diff --git a/node_modules/after/test/after-test.js b/node_modules/after/test/after-test.js new file mode 100644 index 0000000..0d63f4c --- /dev/null +++ b/node_modules/after/test/after-test.js @@ -0,0 +1,120 @@ +/*global suite, test*/ + +var assert = require("assert") + , after = require("../") + +test("exists", function () { + assert(typeof after === "function", "after is not a function") +}) + +test("after when called with 0 invokes", function (done) { + after(0, done) +}); + +test("after 1", function (done) { + var next = after(1, done) + next() +}) + +test("after 5", function (done) { + var next = after(5, done) + , i = 5 + + while (i--) { + next() + } +}) + +test("manipulate count", function (done) { + var next = after(1, done) + , i = 5 + + next.count = i + while (i--) { + next() + } +}) + +test("after terminates on error", function (done) { + var next = after(2, function(err) { + assert.equal(err.message, 'test'); + done(); + }) + next(new Error('test')) + next(new Error('test2')) +}) + +test('gee', function(done) { + done = after(2, done) + + function cb(err) { + assert.equal(err.message, 1); + done() + } + + var next = after(3, cb, function(err) { + assert.equal(err.message, 2) + done() + }); + + next() + next(new Error(1)) + next(new Error(2)) +}) + +test('eee', function(done) { + done = after(3, done) + + function cb(err) { + assert.equal(err.message, 1); + done() + } + + var next = after(3, cb, function(err) { + assert.equal(err.message, 2) + done() + }); + + next(new Error(1)) + next(new Error(2)) + next(new Error(2)) +}) + +test('gge', function(done) { + function cb(err) { + assert.equal(err.message, 1); + done() + } + + var next = after(3, cb, function(err) { + // should not happen + assert.ok(false); + }); + + next() + next() + next(new Error(1)) +}) + +test('egg', function(done) { + function cb(err) { + assert.equal(err.message, 1); + done() + } + + var next = after(3, cb, function(err) { + // should not happen + assert.ok(false); + }); + + next(new Error(1)) + next() + next() +}) + +test('throws on too many calls', function(done) { + var next = after(1, done); + next() + assert.throws(next, /after called too many times/); +}); + diff --git a/node_modules/array-flatten/LICENSE b/node_modules/array-flatten/LICENSE new file mode 100644 index 0000000..983fbe8 --- /dev/null +++ b/node_modules/array-flatten/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + +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. diff --git a/node_modules/array-flatten/README.md b/node_modules/array-flatten/README.md new file mode 100644 index 0000000..91fa5b6 --- /dev/null +++ b/node_modules/array-flatten/README.md @@ -0,0 +1,43 @@ +# Array Flatten + +[![NPM version][npm-image]][npm-url] +[![NPM downloads][downloads-image]][downloads-url] +[![Build status][travis-image]][travis-url] +[![Test coverage][coveralls-image]][coveralls-url] + +> Flatten an array of nested arrays into a single flat array. Accepts an optional depth. + +## Installation + +``` +npm install array-flatten --save +``` + +## Usage + +```javascript +var flatten = require('array-flatten') + +flatten([1, [2, [3, [4, [5], 6], 7], 8], 9]) +//=> [1, 2, 3, 4, 5, 6, 7, 8, 9] + +flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2) +//=> [1, 2, 3, [4, [5], 6], 7, 8, 9] + +(function () { + flatten(arguments) //=> [1, 2, 3] +})(1, [2, 3]) +``` + +## License + +MIT + +[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat +[npm-url]: https://npmjs.org/package/array-flatten +[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat +[downloads-url]: https://npmjs.org/package/array-flatten +[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat +[travis-url]: https://travis-ci.org/blakeembrey/array-flatten +[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat +[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master diff --git a/node_modules/array-flatten/array-flatten.js b/node_modules/array-flatten/array-flatten.js new file mode 100644 index 0000000..089117b --- /dev/null +++ b/node_modules/array-flatten/array-flatten.js @@ -0,0 +1,64 @@ +'use strict' + +/** + * Expose `arrayFlatten`. + */ +module.exports = arrayFlatten + +/** + * Recursive flatten function with depth. + * + * @param {Array} array + * @param {Array} result + * @param {Number} depth + * @return {Array} + */ +function flattenWithDepth (array, result, depth) { + for (var i = 0; i < array.length; i++) { + var value = array[i] + + if (depth > 0 && Array.isArray(value)) { + flattenWithDepth(value, result, depth - 1) + } else { + result.push(value) + } + } + + return result +} + +/** + * Recursive flatten function. Omitting depth is slightly faster. + * + * @param {Array} array + * @param {Array} result + * @return {Array} + */ +function flattenForever (array, result) { + for (var i = 0; i < array.length; i++) { + var value = array[i] + + if (Array.isArray(value)) { + flattenForever(value, result) + } else { + result.push(value) + } + } + + return result +} + +/** + * Flatten an array, with the ability to define a depth. + * + * @param {Array} array + * @param {Number} depth + * @return {Array} + */ +function arrayFlatten (array, depth) { + if (depth == null) { + return flattenForever(array, []) + } + + return flattenWithDepth(array, [], depth) +} diff --git a/node_modules/array-flatten/package.json b/node_modules/array-flatten/package.json new file mode 100644 index 0000000..24dcabe --- /dev/null +++ b/node_modules/array-flatten/package.json @@ -0,0 +1,97 @@ +{ + "_args": [ + [ + { + "raw": "array-flatten@1.1.1", + "scope": null, + "escapedName": "array-flatten", + "name": "array-flatten", + "rawSpec": "1.1.1", + "spec": "1.1.1", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "array-flatten@1.1.1", + "_id": "array-flatten@1.1.1", + "_inCache": true, + "_installable": true, + "_location": "/array-flatten", + "_nodeVersion": "2.3.3", + "_npmUser": { + "name": "blakeembrey", + "email": "hello@blakeembrey.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "array-flatten@1.1.1", + "scope": null, + "escapedName": "array-flatten", + "name": "array-flatten", + "rawSpec": "1.1.1", + "spec": "1.1.1", + "type": "version" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "_shasum": "9a5f699051b1e7073328f2a008968b64ea2955d2", + "_shrinkwrap": null, + "_spec": "array-flatten@1.1.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "Blake Embrey", + "email": "hello@blakeembrey.com", + "url": "http://blakeembrey.me" + }, + "bugs": { + "url": "https://github.com/blakeembrey/array-flatten/issues" + }, + "dependencies": {}, + "description": "Flatten an array of nested arrays into a single flat array", + "devDependencies": { + "istanbul": "^0.3.13", + "mocha": "^2.2.4", + "pre-commit": "^1.0.7", + "standard": "^3.7.3" + }, + "directories": {}, + "dist": { + "shasum": "9a5f699051b1e7073328f2a008968b64ea2955d2", + "tarball": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + }, + "files": [ + "array-flatten.js", + "LICENSE" + ], + "gitHead": "1963a9189229d408e1e8f585a00c8be9edbd1803", + "homepage": "https://github.com/blakeembrey/array-flatten", + "keywords": [ + "array", + "flatten", + "arguments", + "depth" + ], + "license": "MIT", + "main": "array-flatten.js", + "maintainers": [ + { + "name": "blakeembrey", + "email": "hello@blakeembrey.com" + } + ], + "name": "array-flatten", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/blakeembrey/array-flatten.git" + }, + "scripts": { + "test": "istanbul cover _mocha -- -R spec" + }, + "version": "1.1.1" +} diff --git a/node_modules/arraybuffer.slice/.npmignore b/node_modules/arraybuffer.slice/.npmignore new file mode 100644 index 0000000..cfbee8d --- /dev/null +++ b/node_modules/arraybuffer.slice/.npmignore @@ -0,0 +1,17 @@ +lib-cov +lcov.info +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results +build +.grunt + +node_modules diff --git a/node_modules/arraybuffer.slice/Makefile b/node_modules/arraybuffer.slice/Makefile new file mode 100644 index 0000000..849887f --- /dev/null +++ b/node_modules/arraybuffer.slice/Makefile @@ -0,0 +1,8 @@ + +REPORTER = dot + +test: + @./node_modules/.bin/mocha \ + --reporter $(REPORTER) + +.PHONY: test diff --git a/node_modules/arraybuffer.slice/README.md b/node_modules/arraybuffer.slice/README.md new file mode 100644 index 0000000..15e465e --- /dev/null +++ b/node_modules/arraybuffer.slice/README.md @@ -0,0 +1,17 @@ +# How to +```javascript +var sliceBuffer = require('arraybuffer.slice'); +var ab = (new Int8Array(5)).buffer; +var sliced = sliceBuffer(ab, 1, 3); +sliced = sliceBuffer(ab, 1); +``` + +# Licence (MIT) +Copyright (C) 2013 Rase- + + +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. diff --git a/node_modules/arraybuffer.slice/index.js b/node_modules/arraybuffer.slice/index.js new file mode 100644 index 0000000..11ac556 --- /dev/null +++ b/node_modules/arraybuffer.slice/index.js @@ -0,0 +1,29 @@ +/** + * An abstraction for slicing an arraybuffer even when + * ArrayBuffer.prototype.slice is not supported + * + * @api public + */ + +module.exports = function(arraybuffer, start, end) { + var bytes = arraybuffer.byteLength; + start = start || 0; + end = end || bytes; + + if (arraybuffer.slice) { return arraybuffer.slice(start, end); } + + if (start < 0) { start += bytes; } + if (end < 0) { end += bytes; } + if (end > bytes) { end = bytes; } + + if (start >= bytes || start >= end || bytes === 0) { + return new ArrayBuffer(0); + } + + var abv = new Uint8Array(arraybuffer); + var result = new Uint8Array(end - start); + for (var i = start, ii = 0; i < end; i++, ii++) { + result[ii] = abv[i]; + } + return result.buffer; +}; diff --git a/node_modules/arraybuffer.slice/package.json b/node_modules/arraybuffer.slice/package.json new file mode 100644 index 0000000..9c78f80 --- /dev/null +++ b/node_modules/arraybuffer.slice/package.json @@ -0,0 +1,73 @@ +{ + "_args": [ + [ + { + "raw": "arraybuffer.slice@0.0.6", + "scope": null, + "escapedName": "arraybuffer.slice", + "name": "arraybuffer.slice", + "rawSpec": "0.0.6", + "spec": "0.0.6", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser" + ] + ], + "_from": "arraybuffer.slice@0.0.6", + "_id": "arraybuffer.slice@0.0.6", + "_inCache": true, + "_installable": true, + "_location": "/arraybuffer.slice", + "_npmUser": { + "name": "rase-", + "email": "tonykovanen@hotmail.com" + }, + "_npmVersion": "1.3.5", + "_phantomChildren": {}, + "_requested": { + "raw": "arraybuffer.slice@0.0.6", + "scope": null, + "escapedName": "arraybuffer.slice", + "name": "arraybuffer.slice", + "rawSpec": "0.0.6", + "spec": "0.0.6", + "type": "version" + }, + "_requiredBy": [ + "/engine.io-parser" + ], + "_resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "_shasum": "f33b2159f0532a3f3107a272c0ccfbd1ad2979ca", + "_shrinkwrap": null, + "_spec": "arraybuffer.slice@0.0.6", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser", + "bugs": { + "url": "https://github.com/rase-/arraybuffer.slice/issues" + }, + "dependencies": {}, + "description": "Exports a function for slicing ArrayBuffers (no polyfilling)", + "devDependencies": { + "expect.js": "0.2.0", + "mocha": "1.17.1" + }, + "directories": {}, + "dist": { + "shasum": "f33b2159f0532a3f3107a272c0ccfbd1ad2979ca", + "tarball": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz" + }, + "homepage": "https://github.com/rase-/arraybuffer.slice", + "maintainers": [ + { + "name": "rase-", + "email": "tonykovanen@hotmail.com" + } + ], + "name": "arraybuffer.slice", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/rase-/arraybuffer.slice.git" + }, + "version": "0.0.6" +} diff --git a/node_modules/arraybuffer.slice/test/slice-buffer.js b/node_modules/arraybuffer.slice/test/slice-buffer.js new file mode 100644 index 0000000..4778da6 --- /dev/null +++ b/node_modules/arraybuffer.slice/test/slice-buffer.js @@ -0,0 +1,227 @@ +/* + * Test dependencies + */ + +var sliceBuffer = require('../index.js'); +var expect = require('expect.js'); + +/** + * Tests + */ + +describe('sliceBuffer', function() { + describe('using standard slice', function() { + it('should slice correctly with only start provided', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, 3); + var sabv = new Uint8Array(sliced); + for (var i = 3, ii = 0; i < abv.length; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with start and end provided', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, 3, 8); + var sabv = new Uint8Array(sliced); + for (var i = 3, ii = 0; i < 8; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with negative start', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, -3); + var sabv = new Uint8Array(sliced); + for (var i = abv.length - 3, ii = 0; i < abv.length; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with negative end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, 0, -3); + var sabv = new Uint8Array(sliced); + for (var i = 0, ii = 0; i < abv.length - 3; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with negative start and end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, -6, -3); + var sabv = new Uint8Array(sliced); + for (var i = abv.length - 6, ii = 0; i < abv.length - 3; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with equal start and end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, 1, 1); + expect(sliced.byteLength).to.equal(0); + }); + + it('should slice correctly when end larger than buffer', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, 0, 100); + expect(new Uint8Array(sliced)).to.eql(abv); + }); + + it('shoud slice correctly when start larger than end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + + var sliced = sliceBuffer(abv.buffer, 6, 5); + expect(sliced.byteLength).to.equal(0); + }); + }); + + describe('using fallback', function() { + it('should slice correctly with only start provided', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + var sliced = sliceBuffer(ab, 3); + var sabv = new Uint8Array(sliced); + for (var i = 3, ii = 0; i < abv.length; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with start and end provided', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + + var sliced = sliceBuffer(ab, 3, 8); + var sabv = new Uint8Array(sliced); + for (var i = 3, ii = 0; i < 8; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with negative start', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + + var sliced = sliceBuffer(ab, -3); + var sabv = new Uint8Array(sliced); + for (var i = abv.length - 3, ii = 0; i < abv.length; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with negative end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + var sliced = sliceBuffer(ab, 0, -3); + var sabv = new Uint8Array(sliced); + for (var i = 0, ii = 0; i < abv.length - 3; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with negative start and end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + var sliced = sliceBuffer(ab, -6, -3); + var sabv = new Uint8Array(sliced); + for (var i = abv.length - 6, ii = 0; i < abv.length - 3; i++, ii++) { + expect(abv[i]).to.equal(sabv[ii]); + } + }); + + it('should slice correctly with equal start and end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + var sliced = sliceBuffer(ab, 1, 1); + expect(sliced.byteLength).to.equal(0); + }); + + it('should slice correctly when end larger than buffer', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + var sliced = sliceBuffer(ab, 0, 100); + var sabv = new Uint8Array(sliced); + for (var i = 0; i < abv.length; i++) { + expect(abv[i]).to.equal(sabv[i]); + } + }); + + it('shoud slice correctly when start larger than end', function() { + var abv = new Uint8Array(10); + for (var i = 0; i < abv.length; i++) { + abv[i] = i; + } + var ab = abv.buffer; + ab.slice = undefined; + + var sliced = sliceBuffer(ab, 6, 5); + expect(sliced.byteLength).to.equal(0); + }); + }); +}); diff --git a/node_modules/backo2/.npmignore b/node_modules/backo2/.npmignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/node_modules/backo2/.npmignore @@ -0,0 +1 @@ +node_modules/ diff --git a/node_modules/backo2/History.md b/node_modules/backo2/History.md new file mode 100644 index 0000000..8eb28b8 --- /dev/null +++ b/node_modules/backo2/History.md @@ -0,0 +1,12 @@ + +1.0.1 / 2014-02-17 +================== + + * go away decimal point + * history + +1.0.0 / 2014-02-17 +================== + + * add jitter option + * Initial commit diff --git a/node_modules/backo2/Makefile b/node_modules/backo2/Makefile new file mode 100644 index 0000000..9987df8 --- /dev/null +++ b/node_modules/backo2/Makefile @@ -0,0 +1,8 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter dot \ + --bail + +.PHONY: test \ No newline at end of file diff --git a/node_modules/backo2/Readme.md b/node_modules/backo2/Readme.md new file mode 100644 index 0000000..0df2a39 --- /dev/null +++ b/node_modules/backo2/Readme.md @@ -0,0 +1,34 @@ +# backo + + Simple exponential backoff because the others seem to have weird abstractions. + +## Installation + +``` +$ npm install backo +``` + +## Options + + - `min` initial timeout in milliseconds [100] + - `max` max timeout [10000] + - `jitter` [0] + - `factor` [2] + +## Example + +```js +var Backoff = require('backo'); +var backoff = new Backoff({ min: 100, max: 20000 }); + +setTimeout(function(){ + something.reconnect(); +}, backoff.duration()); + +// later when something works +backoff.reset() +``` + +# License + + MIT diff --git a/node_modules/backo2/component.json b/node_modules/backo2/component.json new file mode 100644 index 0000000..994845a --- /dev/null +++ b/node_modules/backo2/component.json @@ -0,0 +1,11 @@ +{ + "name": "backo", + "repo": "segmentio/backo", + "dependencies": {}, + "version": "1.0.1", + "description": "simple backoff without the weird abstractions", + "keywords": ["backoff"], + "license": "MIT", + "scripts": ["index.js"], + "main": "index.js" +} diff --git a/node_modules/backo2/index.js b/node_modules/backo2/index.js new file mode 100644 index 0000000..fac4429 --- /dev/null +++ b/node_modules/backo2/index.js @@ -0,0 +1,85 @@ + +/** + * Expose `Backoff`. + */ + +module.exports = Backoff; + +/** + * Initialize backoff timer with `opts`. + * + * - `min` initial timeout in milliseconds [100] + * - `max` max timeout [10000] + * - `jitter` [0] + * - `factor` [2] + * + * @param {Object} opts + * @api public + */ + +function Backoff(opts) { + opts = opts || {}; + this.ms = opts.min || 100; + this.max = opts.max || 10000; + this.factor = opts.factor || 2; + this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; + this.attempts = 0; +} + +/** + * Return the backoff duration. + * + * @return {Number} + * @api public + */ + +Backoff.prototype.duration = function(){ + var ms = this.ms * Math.pow(this.factor, this.attempts++); + if (this.jitter) { + var rand = Math.random(); + var deviation = Math.floor(rand * this.jitter * ms); + ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; + } + return Math.min(ms, this.max) | 0; +}; + +/** + * Reset the number of attempts. + * + * @api public + */ + +Backoff.prototype.reset = function(){ + this.attempts = 0; +}; + +/** + * Set the minimum duration + * + * @api public + */ + +Backoff.prototype.setMin = function(min){ + this.ms = min; +}; + +/** + * Set the maximum duration + * + * @api public + */ + +Backoff.prototype.setMax = function(max){ + this.max = max; +}; + +/** + * Set the jitter + * + * @api public + */ + +Backoff.prototype.setJitter = function(jitter){ + this.jitter = jitter; +}; + diff --git a/node_modules/backo2/package.json b/node_modules/backo2/package.json new file mode 100644 index 0000000..c47dc53 --- /dev/null +++ b/node_modules/backo2/package.json @@ -0,0 +1,79 @@ +{ + "_args": [ + [ + { + "raw": "backo2@1.0.2", + "scope": null, + "escapedName": "backo2", + "name": "backo2", + "rawSpec": "1.0.2", + "spec": "1.0.2", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-client" + ] + ], + "_from": "backo2@1.0.2", + "_id": "backo2@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/backo2", + "_npmUser": { + "name": "mokesmokes", + "email": "mokesmokes@gmail.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "backo2@1.0.2", + "scope": null, + "escapedName": "backo2", + "name": "backo2", + "rawSpec": "1.0.2", + "spec": "1.0.2", + "type": "version" + }, + "_requiredBy": [ + "/socket.io-client" + ], + "_resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "_shasum": "31ab1ac8b129363463e35b3ebb69f4dfcfba7947", + "_shrinkwrap": null, + "_spec": "backo2@1.0.2", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-client", + "bugs": { + "url": "https://github.com/mokesmokes/backo/issues" + }, + "dependencies": {}, + "description": "simple backoff based on segmentio/backo", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "31ab1ac8b129363463e35b3ebb69f4dfcfba7947", + "tarball": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz" + }, + "gitHead": "3e695bade7756fef2295e8883bf3570a06e5d9ec", + "homepage": "https://github.com/mokesmokes/backo", + "keywords": [ + "backoff" + ], + "license": "MIT", + "maintainers": [ + { + "name": "mokesmokes", + "email": "mokesmokes@gmail.com" + } + ], + "name": "backo2", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mokesmokes/backo.git" + }, + "scripts": {}, + "version": "1.0.2" +} diff --git a/node_modules/backo2/test/index.js b/node_modules/backo2/test/index.js new file mode 100644 index 0000000..ea1f6de --- /dev/null +++ b/node_modules/backo2/test/index.js @@ -0,0 +1,18 @@ + +var Backoff = require('..'); +var assert = require('assert'); + +describe('.duration()', function(){ + it('should increase the backoff', function(){ + var b = new Backoff; + + assert(100 == b.duration()); + assert(200 == b.duration()); + assert(400 == b.duration()); + assert(800 == b.duration()); + + b.reset(); + assert(100 == b.duration()); + assert(200 == b.duration()); + }) +}) \ No newline at end of file diff --git a/node_modules/base64-arraybuffer/.npmignore b/node_modules/base64-arraybuffer/.npmignore new file mode 100644 index 0000000..2ccbe46 --- /dev/null +++ b/node_modules/base64-arraybuffer/.npmignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/node_modules/base64-arraybuffer/.travis.yml b/node_modules/base64-arraybuffer/.travis.yml new file mode 100644 index 0000000..e2eeb99 --- /dev/null +++ b/node_modules/base64-arraybuffer/.travis.yml @@ -0,0 +1,6 @@ +--- +language: node_js +node_js: +- '0.10' +before_script: +- npm install diff --git a/node_modules/base64-arraybuffer/LICENSE-MIT b/node_modules/base64-arraybuffer/LICENSE-MIT new file mode 100644 index 0000000..ed27b41 --- /dev/null +++ b/node_modules/base64-arraybuffer/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2012 Niklas von Hertzen + +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. diff --git a/node_modules/base64-arraybuffer/README.md b/node_modules/base64-arraybuffer/README.md new file mode 100644 index 0000000..b841154 --- /dev/null +++ b/node_modules/base64-arraybuffer/README.md @@ -0,0 +1,23 @@ +# base64-arraybuffer + +[![Build Status](https://travis-ci.org/niklasvh/base64-arraybuffer.png)](https://travis-ci.org/niklasvh/base64-arraybuffer) + +Encode/decode base64 data into ArrayBuffers + +## Getting Started +Install the module with: `npm install base64-arraybuffer` + +## API +The library encodes and decodes base64 to and from ArrayBuffers + + - __encode(buffer)__ - Encodes `ArrayBuffer` into base64 string + - __decode(str)__ - Decodes base64 string to `ArrayBuffer` + +## Release History + + - 0.1.2 - Fix old format of typed arrays + - 0.1.0 - Initial version, basic decode/encode base64 to and from ArrayBuffer + +## License +Copyright (c) 2012 Niklas von Hertzen +Licensed under the MIT license. diff --git a/node_modules/base64-arraybuffer/grunt.js b/node_modules/base64-arraybuffer/grunt.js new file mode 100644 index 0000000..73c4e7a --- /dev/null +++ b/node_modules/base64-arraybuffer/grunt.js @@ -0,0 +1,39 @@ +module.exports = function(grunt) { + "use strict"; + // Project configuration. + grunt.initConfig({ + pkg: '', + test: { + files: ['test/**/*.js'] + }, + lint: { + files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js'] + }, + watch: { + files: '', + tasks: 'default' + }, + jshint: { + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + boss: true, + eqnull: true, + node: true + }, + globals: { + exports: true + } + } + }); + + // Default task. + grunt.registerTask('default', 'test'); + +}; \ No newline at end of file diff --git a/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js b/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js new file mode 100644 index 0000000..362fbfa --- /dev/null +++ b/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js @@ -0,0 +1,59 @@ +/* + * base64-arraybuffer + * https://github.com/niklasvh/base64-arraybuffer + * + * Copyright (c) 2012 Niklas von Hertzen + * Licensed under the MIT license. + */ +(function(chars){ + "use strict"; + + exports.encode = function(arraybuffer) { + var bytes = new Uint8Array(arraybuffer), + i, len = bytes.length, base64 = ""; + + for (i = 0; i < len; i+=3) { + base64 += chars[bytes[i] >> 2]; + base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; + base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; + base64 += chars[bytes[i + 2] & 63]; + } + + if ((len % 3) === 2) { + base64 = base64.substring(0, base64.length - 1) + "="; + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + "=="; + } + + return base64; + }; + + exports.decode = function(base64) { + var bufferLength = base64.length * 0.75, + len = base64.length, i, p = 0, + encoded1, encoded2, encoded3, encoded4; + + if (base64[base64.length - 1] === "=") { + bufferLength--; + if (base64[base64.length - 2] === "=") { + bufferLength--; + } + } + + var arraybuffer = new ArrayBuffer(bufferLength), + bytes = new Uint8Array(arraybuffer); + + for (i = 0; i < len; i+=4) { + encoded1 = chars.indexOf(base64[i]); + encoded2 = chars.indexOf(base64[i+1]); + encoded3 = chars.indexOf(base64[i+2]); + encoded4 = chars.indexOf(base64[i+3]); + + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); + } + + return arraybuffer; + }; +})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); diff --git a/node_modules/base64-arraybuffer/package.json b/node_modules/base64-arraybuffer/package.json new file mode 100644 index 0000000..299224c --- /dev/null +++ b/node_modules/base64-arraybuffer/package.json @@ -0,0 +1,91 @@ +{ + "_args": [ + [ + { + "raw": "base64-arraybuffer@0.1.2", + "scope": null, + "escapedName": "base64-arraybuffer", + "name": "base64-arraybuffer", + "rawSpec": "0.1.2", + "spec": "0.1.2", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser" + ] + ], + "_from": "base64-arraybuffer@0.1.2", + "_id": "base64-arraybuffer@0.1.2", + "_inCache": true, + "_installable": true, + "_location": "/base64-arraybuffer", + "_npmUser": { + "name": "niklasvh", + "email": "niklasvh@gmail.com" + }, + "_npmVersion": "1.3.21", + "_phantomChildren": {}, + "_requested": { + "raw": "base64-arraybuffer@0.1.2", + "scope": null, + "escapedName": "base64-arraybuffer", + "name": "base64-arraybuffer", + "rawSpec": "0.1.2", + "spec": "0.1.2", + "type": "version" + }, + "_requiredBy": [ + "/engine.io-parser" + ], + "_resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz", + "_shasum": "474df4a9f2da24e05df3158c3b1db3c3cd46a154", + "_shrinkwrap": null, + "_spec": "base64-arraybuffer@0.1.2", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser", + "author": { + "name": "Niklas von Hertzen", + "email": "niklasvh@gmail.com", + "url": "http://hertzen.com" + }, + "bugs": { + "url": "https://github.com/niklasvh/base64-arraybuffer/issues" + }, + "dependencies": {}, + "description": "Encode/decode base64 data into ArrayBuffers", + "devDependencies": { + "grunt": "~0.3.17" + }, + "directories": {}, + "dist": { + "shasum": "474df4a9f2da24e05df3158c3b1db3c3cd46a154", + "tarball": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz" + }, + "engines": { + "node": ">= 0.6.0" + }, + "homepage": "https://github.com/niklasvh/base64-arraybuffer", + "keywords": [], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/niklasvh/base64-arraybuffer/blob/master/LICENSE-MIT" + } + ], + "main": "lib/base64-arraybuffer", + "maintainers": [ + { + "name": "niklasvh", + "email": "niklasvh@gmail.com" + } + ], + "name": "base64-arraybuffer", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/niklasvh/base64-arraybuffer.git" + }, + "scripts": { + "test": "grunt test" + }, + "version": "0.1.2" +} diff --git a/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js b/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js new file mode 100644 index 0000000..fe89c22 --- /dev/null +++ b/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js @@ -0,0 +1,72 @@ +(function(){ + "use strict"; + var base64_arraybuffer = require('../lib/base64-arraybuffer.js'); + + /* + ======== A Handy Little Nodeunit Reference ======== + https://github.com/caolan/nodeunit + + Test methods: + test.expect(numAssertions) + test.done() + Test assertions: + test.ok(value, [message]) + test.equal(actual, expected, [message]) + test.notEqual(actual, expected, [message]) + test.deepEqual(actual, expected, [message]) + test.notDeepEqual(actual, expected, [message]) + test.strictEqual(actual, expected, [message]) + test.notStrictEqual(actual, expected, [message]) + test.throws(block, [error], [message]) + test.doesNotThrow(block, [error], [message]) + test.ifError(value) +*/ + + + function stringArrayBuffer(str) { + var buffer = new ArrayBuffer(str.length); + var bytes = new Uint8Array(buffer); + + str.split('').forEach(function(str, i) { + bytes[i] = str.charCodeAt(0); + }); + + return buffer; + } + + function testArrayBuffers(buffer1, buffer2) { + var len1 = buffer1.byteLength, + len2 = buffer2.byteLength; + if (len1 !== len2) { + console.log(buffer1, buffer2); + return false; + } + + for (var i = 0; i < len1; i++) { + if (buffer1[i] !== buffer1[i]) { + console.log(i, buffer1, buffer2); + return false; + } + } + return true; + } + + exports['base64tests'] = { + 'encode': function(test) { + test.expect(4); + + test.equal(base64_arraybuffer.encode(stringArrayBuffer("Hello world")), "SGVsbG8gd29ybGQ=", 'encode "Hello world"'); + test.equal(base64_arraybuffer.encode(stringArrayBuffer("Man")), 'TWFu', 'encode "Man"'); + test.equal(base64_arraybuffer.encode(stringArrayBuffer("Ma")), "TWE=", 'encode "Ma"'); + test.equal(base64_arraybuffer.encode(stringArrayBuffer("Hello worlds!")), "SGVsbG8gd29ybGRzIQ==", 'encode "Hello worlds!"'); + test.done(); + }, + 'decode': function(test) { + test.expect(3); + test.ok(testArrayBuffers(base64_arraybuffer.decode("TWFu"), stringArrayBuffer("Man")), 'decode "Man"'); + test.ok(testArrayBuffers(base64_arraybuffer.decode("SGVsbG8gd29ybGQ="), stringArrayBuffer("Hello world")), 'decode "Hello world"'); + test.ok(testArrayBuffers(base64_arraybuffer.decode("SGVsbG8gd29ybGRzIQ=="), stringArrayBuffer("Hello worlds!")), 'decode "Hello worlds!"'); + test.done(); + } + }; +})(); diff --git a/node_modules/base64id/.npmignore b/node_modules/base64id/.npmignore new file mode 100644 index 0000000..39e9864 --- /dev/null +++ b/node_modules/base64id/.npmignore @@ -0,0 +1,3 @@ +support +test +examples diff --git a/node_modules/base64id/README.md b/node_modules/base64id/README.md new file mode 100644 index 0000000..b4361c1 --- /dev/null +++ b/node_modules/base64id/README.md @@ -0,0 +1,18 @@ +base64id +======== + +Node.js module that generates a base64 id. + +Uses crypto.randomBytes when available, falls back to unsafe methods for node.js <= 0.4. + +To increase performance, random bytes are buffered to minimize the number of synchronous calls to crypto.randomBytes. + +## Installation + + $ npm install mongoose + +## Usage + + var base64id = require('base64id'); + + var id = base64id.generateId(); diff --git a/node_modules/base64id/lib/base64id.js b/node_modules/base64id/lib/base64id.js new file mode 100644 index 0000000..f688159 --- /dev/null +++ b/node_modules/base64id/lib/base64id.js @@ -0,0 +1,103 @@ +/*! + * base64id v0.1.0 + */ + +/** + * Module dependencies + */ + +var crypto = require('crypto'); + +/** + * Constructor + */ + +var Base64Id = function() { }; + +/** + * Get random bytes + * + * Uses a buffer if available, falls back to crypto.randomBytes + */ + +Base64Id.prototype.getRandomBytes = function(bytes) { + + var BUFFER_SIZE = 4096 + var self = this; + + bytes = bytes || 12; + + if (bytes > BUFFER_SIZE) { + return crypto.randomBytes(bytes); + } + + var bytesInBuffer = parseInt(BUFFER_SIZE/bytes); + var threshold = parseInt(bytesInBuffer*0.85); + + if (!threshold) { + return crypto.randomBytes(bytes); + } + + if (this.bytesBufferIndex == null) { + this.bytesBufferIndex = -1; + } + + if (this.bytesBufferIndex == bytesInBuffer) { + this.bytesBuffer = null; + this.bytesBufferIndex = -1; + } + + // No buffered bytes available or index above threshold + if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) { + + if (!this.isGeneratingBytes) { + this.isGeneratingBytes = true; + crypto.randomBytes(BUFFER_SIZE, function(err, bytes) { + self.bytesBuffer = bytes; + self.bytesBufferIndex = 0; + self.isGeneratingBytes = false; + }); + } + + // Fall back to sync call when no buffered bytes are available + if (this.bytesBufferIndex == -1) { + return crypto.randomBytes(bytes); + } + } + + var result = this.bytesBuffer.slice(bytes*this.bytesBufferIndex, bytes*(this.bytesBufferIndex+1)); + this.bytesBufferIndex++; + + return result; +} + +/** + * Generates a base64 id + * + * (Original version from socket.io ) + */ + +Base64Id.prototype.generateId = function () { + var rand = new Buffer(15); // multiple of 3 for base64 + if (!rand.writeInt32BE) { + return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString() + + Math.abs(Math.random() * Math.random() * Date.now() | 0).toString(); + } + this.sequenceNumber = (this.sequenceNumber + 1) | 0; + rand.writeInt32BE(this.sequenceNumber, 11); + if (crypto.randomBytes) { + this.getRandomBytes(12).copy(rand); + } else { + // not secure for node 0.4 + [0, 4, 8].forEach(function(i) { + rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i); + }); + } + return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-'); +}; + +/** + * Export + */ + +exports = module.exports = new Base64Id(); diff --git a/node_modules/base64id/package.json b/node_modules/base64id/package.json new file mode 100644 index 0000000..676aa92 --- /dev/null +++ b/node_modules/base64id/package.json @@ -0,0 +1,81 @@ +{ + "_args": [ + [ + { + "raw": "base64id@0.1.0", + "scope": null, + "escapedName": "base64id", + "name": "base64id", + "rawSpec": "0.1.0", + "spec": "0.1.0", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io" + ] + ], + "_defaultsLoaded": true, + "_engineSupported": true, + "_from": "base64id@0.1.0", + "_id": "base64id@0.1.0", + "_inCache": true, + "_installable": true, + "_location": "/base64id", + "_nodeVersion": "v0.6.15", + "_npmUser": { + "name": "faeldt_kristian", + "email": "faeldt_kristian@cyberagent.co.jp" + }, + "_npmVersion": "1.1.16", + "_phantomChildren": {}, + "_requested": { + "raw": "base64id@0.1.0", + "scope": null, + "escapedName": "base64id", + "name": "base64id", + "rawSpec": "0.1.0", + "spec": "0.1.0", + "type": "version" + }, + "_requiredBy": [ + "/engine.io" + ], + "_resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz", + "_shasum": "02ce0fdeee0cef4f40080e1e73e834f0b1bfce3f", + "_shrinkwrap": null, + "_spec": "base64id@0.1.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io", + "author": { + "name": "Kristian Faeldt", + "email": "faeldt_kristian@cyberagent.co.jp" + }, + "bugs": { + "url": "https://github.com/faeldt/base64id/issues" + }, + "dependencies": {}, + "description": "Generates a base64 id", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "02ce0fdeee0cef4f40080e1e73e834f0b1bfce3f", + "tarball": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz" + }, + "engines": { + "node": ">= 0.4.0" + }, + "homepage": "https://github.com/faeldt/base64id#readme", + "main": "./lib/base64id.js", + "maintainers": [ + { + "name": "faeldt_kristian", + "email": "faeldt_kristian@cyberagent.co.jp" + } + ], + "name": "base64id", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/faeldt/base64id.git" + }, + "version": "0.1.0" +} diff --git a/node_modules/benchmark/LICENSE.txt b/node_modules/benchmark/LICENSE.txt new file mode 100644 index 0000000..e33e63f --- /dev/null +++ b/node_modules/benchmark/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2010-2012 Mathias Bynens +Based on JSLitmus.js, copyright Robert Kieffer +Modified by John-David Dalton + +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. diff --git a/node_modules/benchmark/README.md b/node_modules/benchmark/README.md new file mode 100644 index 0000000..a3ab3f8 --- /dev/null +++ b/node_modules/benchmark/README.md @@ -0,0 +1,131 @@ +# Benchmark.js v1.0.0 + +A [robust](http://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/ "Bulletproof JavaScript benchmarks") benchmarking library that works on nearly all JavaScript platforms1, supports high-resolution timers, and returns statistically significant results. As seen on [jsPerf](http://jsperf.com/). + +## BestieJS + +Benchmark.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation. + +## Documentation + +The documentation for Benchmark.js can be viewed here: + +For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/benchmark.js/wiki/Roadmap). + +## Support + +Benchmark.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5. + +## Installation and usage + +In a browser or Adobe AIR: + +~~~ html + +~~~ + +Optionally, expose Java’s nanosecond timer by adding the `nano` applet to the ``: + +~~~ html + +~~~ + +Or enable Chrome’s microsecond timer by using the [command line switch](http://peter.sh/experiments/chromium-command-line-switches/#enable-benchmarking): + + --enable-benchmarking + +Via [npm](http://npmjs.org/): + +~~~ bash +npm install benchmark +~~~ + +In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): + +~~~ js +var Benchmark = require('benchmark'); +~~~ + +Optionally, use the [microtime module](https://github.com/wadey/node-microtime) by Wade Simmons: + +~~~ bash +npm install microtime +~~~ + +In [RingoJS v0.7.0-](http://ringojs.org/): + +~~~ js +var Benchmark = require('benchmark').Benchmark; +~~~ + +In [Rhino](http://www.mozilla.org/rhino/): + +~~~ js +load('benchmark.js'); +~~~ + +In an AMD loader like [RequireJS](http://requirejs.org/): + +~~~ js +require({ + 'paths': { + 'benchmark': 'path/to/benchmark' + } +}, +['benchmark'], function(Benchmark) { + console.log(Benchmark.version); +}); + +// or with platform.js +// https://github.com/bestiejs/platform.js +require({ + 'paths': { + 'benchmark': 'path/to/benchmark', + 'platform': 'path/to/platform' + } +}, +['benchmark', 'platform'], function(Benchmark, platform) { + Benchmark.platform = platform; + console.log(Benchmark.platform.name); +}); +~~~ + +Usage example: + +~~~ js +var suite = new Benchmark.Suite; + +// add tests +suite.add('RegExp#test', function() { + /o/.test('Hello World!'); +}) +.add('String#indexOf', function() { + 'Hello World!'.indexOf('o') > -1; +}) +// add listeners +.on('cycle', function(event) { + console.log(String(event.target)); +}) +.on('complete', function() { + console.log('Fastest is ' + this.filter('fastest').pluck('name')); +}) +// run async +.run({ 'async': true }); + +// logs: +// > RegExp#test x 4,161,532 +-0.99% (59 cycles) +// > String#indexOf x 6,139,623 +-1.00% (131 cycles) +// > Fastest is String#indexOf +~~~ + +## Authors + +* [Mathias Bynens](http://mathiasbynens.be/) + [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") +* [John-David Dalton](http://allyoucanleet.com/) + [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") + +## Contributors + +* [Kit Cambridge](http://kitcambridge.github.com/) + [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") diff --git a/node_modules/benchmark/benchmark.js b/node_modules/benchmark/benchmark.js new file mode 100644 index 0000000..d8eb309 --- /dev/null +++ b/node_modules/benchmark/benchmark.js @@ -0,0 +1,3918 @@ +/*! + * Benchmark.js v1.0.0 + * Copyright 2010-2012 Mathias Bynens + * Based on JSLitmus.js, copyright Robert Kieffer + * Modified by John-David Dalton + * Available under MIT license + */ +;(function(window, undefined) { + 'use strict'; + + /** Used to assign each benchmark an incrimented id */ + var counter = 0; + + /** Detect DOM document object */ + var doc = isHostType(window, 'document') && document; + + /** Detect free variable `define` */ + var freeDefine = typeof define == 'function' && + typeof define.amd == 'object' && define.amd && define; + + /** Detect free variable `exports` */ + var freeExports = typeof exports == 'object' && exports && + (typeof global == 'object' && global && global == global.global && (window = global), exports); + + /** Detect free variable `require` */ + var freeRequire = typeof require == 'function' && require; + + /** Used to crawl all properties regardless of enumerability */ + var getAllKeys = Object.getOwnPropertyNames; + + /** Used to get property descriptors */ + var getDescriptor = Object.getOwnPropertyDescriptor; + + /** Used in case an object doesn't have its own method */ + var hasOwnProperty = {}.hasOwnProperty; + + /** Used to check if an object is extensible */ + var isExtensible = Object.isExtensible || function() { return true; }; + + /** Used to access Wade Simmons' Node microtime module */ + var microtimeObject = req('microtime'); + + /** Used to access the browser's high resolution timer */ + var perfObject = isHostType(window, 'performance') && performance; + + /** Used to call the browser's high resolution timer */ + var perfName = perfObject && ( + perfObject.now && 'now' || + perfObject.webkitNow && 'webkitNow' + ); + + /** Used to access Node's high resolution timer */ + var processObject = isHostType(window, 'process') && process; + + /** Used to check if an own property is enumerable */ + var propertyIsEnumerable = {}.propertyIsEnumerable; + + /** Used to set property descriptors */ + var setDescriptor = Object.defineProperty; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** Used to prevent a `removeChild` memory leak in IE < 9 */ + var trash = doc && doc.createElement('div'); + + /** Used to integrity check compiled tests */ + var uid = 'uid' + (+new Date); + + /** Used to avoid infinite recursion when methods call each other */ + var calledBy = {}; + + /** Used to avoid hz of Infinity */ + var divisors = { + '1': 4096, + '2': 512, + '3': 64, + '4': 8, + '5': 0 + }; + + /** + * T-Distribution two-tailed critical values for 95% confidence + * http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm + */ + var tTable = { + '1': 12.706,'2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447, + '7': 2.365, '8': 2.306, '9': 2.262, '10': 2.228, '11': 2.201, '12': 2.179, + '13': 2.16, '14': 2.145, '15': 2.131, '16': 2.12, '17': 2.11, '18': 2.101, + '19': 2.093, '20': 2.086, '21': 2.08, '22': 2.074, '23': 2.069, '24': 2.064, + '25': 2.06, '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042, + 'infinity': 1.96 + }; + + /** + * Critical Mann-Whitney U-values for 95% confidence + * http://www.saburchill.com/IBbiology/stats/003.html + */ + var uTable = { + '5': [0, 1, 2], + '6': [1, 2, 3, 5], + '7': [1, 3, 5, 6, 8], + '8': [2, 4, 6, 8, 10, 13], + '9': [2, 4, 7, 10, 12, 15, 17], + '10': [3, 5, 8, 11, 14, 17, 20, 23], + '11': [3, 6, 9, 13, 16, 19, 23, 26, 30], + '12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37], + '13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45], + '14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55], + '15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64], + '16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75], + '17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87], + '18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99], + '19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113], + '20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127], + '21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142], + '22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158], + '23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175], + '24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192], + '25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211], + '26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230], + '27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250], + '28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272], + '29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294], + '30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317] + }; + + /** + * An object used to flag environments/features. + * + * @static + * @memberOf Benchmark + * @type Object + */ + var support = {}; + + (function() { + + /** + * Detect Adobe AIR. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.air = isClassOf(window.runtime, 'ScriptBridgingProxyObject'); + + /** + * Detect if `arguments` objects have the correct internal [[Class]] value. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.argumentsClass = isClassOf(arguments, 'Arguments'); + + /** + * Detect if in a browser environment. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.browser = doc && isHostType(window, 'navigator'); + + /** + * Detect if strings support accessing characters by index. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.charByIndex = + // IE 8 supports indexes on string literals but not string objects + ('x'[0] + Object('x')[0]) == 'xx'; + + /** + * Detect if strings have indexes as own properties. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.charByOwnIndex = + // Narwhal, Rhino, RingoJS, IE 8, and Opera < 10.52 support indexes on + // strings but don't detect them as own properties + support.charByIndex && hasKey('x', '0'); + + /** + * Detect if Java is enabled/exposed. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.java = isClassOf(window.java, 'JavaPackage'); + + /** + * Detect if the Timers API exists. + * + * @memberOf Benchmark.support + * @type Boolean + */ + support.timeout = isHostType(window, 'setTimeout') && isHostType(window, 'clearTimeout'); + + /** + * Detect if functions support decompilation. + * + * @name decompilation + * @memberOf Benchmark.support + * @type Boolean + */ + try { + // Safari 2.x removes commas in object literals + // from Function#toString results + // http://webk.it/11609 + // Firefox 3.6 and Opera 9.25 strip grouping + // parentheses from Function#toString results + // http://bugzil.la/559438 + support.decompilation = Function( + 'return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')' + )()(0).x === '1'; + } catch(e) { + support.decompilation = false; + } + + /** + * Detect ES5+ property descriptor API. + * + * @name descriptors + * @memberOf Benchmark.support + * @type Boolean + */ + try { + var o = {}; + support.descriptors = (setDescriptor(o, o, o), 'value' in getDescriptor(o, o)); + } catch(e) { + support.descriptors = false; + } + + /** + * Detect ES5+ Object.getOwnPropertyNames(). + * + * @name getAllKeys + * @memberOf Benchmark.support + * @type Boolean + */ + try { + support.getAllKeys = /\bvalueOf\b/.test(getAllKeys(Object.prototype)); + } catch(e) { + support.getAllKeys = false; + } + + /** + * Detect if own properties are iterated before inherited properties (all but IE < 9). + * + * @name iteratesOwnLast + * @memberOf Benchmark.support + * @type Boolean + */ + support.iteratesOwnFirst = (function() { + var props = []; + function ctor() { this.x = 1; } + ctor.prototype = { 'y': 1 }; + for (var prop in new ctor) { props.push(prop); } + return props[0] == 'x'; + }()); + + /** + * Detect if a node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to a + * string without a `toString` property value of `typeof` "function". + * + * @name nodeClass + * @memberOf Benchmark.support + * @type Boolean + */ + try { + support.nodeClass = ({ 'toString': 0 } + '', toString.call(doc || 0) != '[object Object]'); + } catch(e) { + support.nodeClass = true; + } + }()); + + /** + * Timer object used by `clock()` and `Deferred#resolve`. + * + * @private + * @type Object + */ + var timer = { + + /** + * The timer namespace object or constructor. + * + * @private + * @memberOf timer + * @type Function|Object + */ + 'ns': Date, + + /** + * Starts the deferred timer. + * + * @private + * @memberOf timer + * @param {Object} deferred The deferred instance. + */ + 'start': null, // lazy defined in `clock()` + + /** + * Stops the deferred timer. + * + * @private + * @memberOf timer + * @param {Object} deferred The deferred instance. + */ + 'stop': null // lazy defined in `clock()` + }; + + /** Shortcut for inverse results */ + var noArgumentsClass = !support.argumentsClass, + noCharByIndex = !support.charByIndex, + noCharByOwnIndex = !support.charByOwnIndex; + + /** Math shortcuts */ + var abs = Math.abs, + floor = Math.floor, + max = Math.max, + min = Math.min, + pow = Math.pow, + sqrt = Math.sqrt; + + /*--------------------------------------------------------------------------*/ + + /** + * The Benchmark constructor. + * + * @constructor + * @param {String} name A name to identify the benchmark. + * @param {Function|String} fn The test to benchmark. + * @param {Object} [options={}] Options object. + * @example + * + * // basic usage (the `new` operator is optional) + * var bench = new Benchmark(fn); + * + * // or using a name first + * var bench = new Benchmark('foo', fn); + * + * // or with options + * var bench = new Benchmark('foo', fn, { + * + * // displayed by Benchmark#toString if `name` is not available + * 'id': 'xyz', + * + * // called when the benchmark starts running + * 'onStart': onStart, + * + * // called after each run cycle + * 'onCycle': onCycle, + * + * // called when aborted + * 'onAbort': onAbort, + * + * // called when a test errors + * 'onError': onError, + * + * // called when reset + * 'onReset': onReset, + * + * // called when the benchmark completes running + * 'onComplete': onComplete, + * + * // compiled/called before the test loop + * 'setup': setup, + * + * // compiled/called after the test loop + * 'teardown': teardown + * }); + * + * // or name and options + * var bench = new Benchmark('foo', { + * + * // a flag to indicate the benchmark is deferred + * 'defer': true, + * + * // benchmark test function + * 'fn': function(deferred) { + * // call resolve() when the deferred test is finished + * deferred.resolve(); + * } + * }); + * + * // or options only + * var bench = new Benchmark({ + * + * // benchmark name + * 'name': 'foo', + * + * // benchmark test as a string + * 'fn': '[1,2,3,4].sort()' + * }); + * + * // a test's `this` binding is set to the benchmark instance + * var bench = new Benchmark('foo', function() { + * 'My name is '.concat(this.name); // My name is foo + * }); + */ + function Benchmark(name, fn, options) { + var me = this; + + // allow instance creation without the `new` operator + if (me == null || me.constructor != Benchmark) { + return new Benchmark(name, fn, options); + } + // juggle arguments + if (isClassOf(name, 'Object')) { + // 1 argument (options) + options = name; + } + else if (isClassOf(name, 'Function')) { + // 2 arguments (fn, options) + options = fn; + fn = name; + } + else if (isClassOf(fn, 'Object')) { + // 2 arguments (name, options) + options = fn; + fn = null; + me.name = name; + } + else { + // 3 arguments (name, fn [, options]) + me.name = name; + } + setOptions(me, options); + me.id || (me.id = ++counter); + me.fn == null && (me.fn = fn); + me.stats = deepClone(me.stats); + me.times = deepClone(me.times); + } + + /** + * The Deferred constructor. + * + * @constructor + * @memberOf Benchmark + * @param {Object} clone The cloned benchmark instance. + */ + function Deferred(clone) { + var me = this; + if (me == null || me.constructor != Deferred) { + return new Deferred(clone); + } + me.benchmark = clone; + clock(me); + } + + /** + * The Event constructor. + * + * @constructor + * @memberOf Benchmark + * @param {String|Object} type The event type. + */ + function Event(type) { + var me = this; + return (me == null || me.constructor != Event) + ? new Event(type) + : (type instanceof Event) + ? type + : extend(me, { 'timeStamp': +new Date }, typeof type == 'string' ? { 'type': type } : type); + } + + /** + * The Suite constructor. + * + * @constructor + * @memberOf Benchmark + * @param {String} name A name to identify the suite. + * @param {Object} [options={}] Options object. + * @example + * + * // basic usage (the `new` operator is optional) + * var suite = new Benchmark.Suite; + * + * // or using a name first + * var suite = new Benchmark.Suite('foo'); + * + * // or with options + * var suite = new Benchmark.Suite('foo', { + * + * // called when the suite starts running + * 'onStart': onStart, + * + * // called between running benchmarks + * 'onCycle': onCycle, + * + * // called when aborted + * 'onAbort': onAbort, + * + * // called when a test errors + * 'onError': onError, + * + * // called when reset + * 'onReset': onReset, + * + * // called when the suite completes running + * 'onComplete': onComplete + * }); + */ + function Suite(name, options) { + var me = this; + + // allow instance creation without the `new` operator + if (me == null || me.constructor != Suite) { + return new Suite(name, options); + } + // juggle arguments + if (isClassOf(name, 'Object')) { + // 1 argument (options) + options = name; + } else { + // 2 arguments (name [, options]) + me.name = name; + } + setOptions(me, options); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Note: Some array methods have been implemented in plain JavaScript to avoid + * bugs in IE, Opera, Rhino, and Mobile Safari. + * + * IE compatibility mode and IE < 9 have buggy Array `shift()` and `splice()` + * functions that fail to remove the last element, `object[0]`, of + * array-like-objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * In Opera < 9.50 and some older/beta Mobile Safari versions using `unshift()` + * generically to augment the `arguments` object will pave the value at index 0 + * without incrimenting the other values's indexes. + * https://github.com/documentcloud/underscore/issues/9 + * + * Rhino and environments it powers, like Narwhal and RingoJS, may have + * buggy Array `concat()`, `reverse()`, `shift()`, `slice()`, `splice()` and + * `unshift()` functions that make sparse arrays non-sparse by assigning the + * undefined indexes a value of undefined. + * https://github.com/mozilla/rhino/commit/702abfed3f8ca043b2636efd31c14ba7552603dd + */ + + /** + * Creates an array containing the elements of the host array followed by the + * elements of each argument in order. + * + * @memberOf Benchmark.Suite + * @returns {Array} The new array. + */ + function concat() { + var value, + j = -1, + length = arguments.length, + result = slice.call(this), + index = result.length; + + while (++j < length) { + value = arguments[j]; + if (isClassOf(value, 'Array')) { + for (var k = 0, l = value.length; k < l; k++, index++) { + if (k in value) { + result[index] = value[k]; + } + } + } else { + result[index++] = value; + } + } + return result; + } + + /** + * Utility function used by `shift()`, `splice()`, and `unshift()`. + * + * @private + * @param {Number} start The index to start inserting elements. + * @param {Number} deleteCount The number of elements to delete from the insert point. + * @param {Array} elements The elements to insert. + * @returns {Array} An array of deleted elements. + */ + function insert(start, deleteCount, elements) { + // `result` should have its length set to the `deleteCount` + // see https://bugs.ecmascript.org/show_bug.cgi?id=332 + var deleteEnd = start + deleteCount, + elementCount = elements ? elements.length : 0, + index = start - 1, + length = start + elementCount, + object = this, + result = Array(deleteCount), + tail = slice.call(object, deleteEnd); + + // delete elements from the array + while (++index < deleteEnd) { + if (index in object) { + result[index - start] = object[index]; + delete object[index]; + } + } + // insert elements + index = start - 1; + while (++index < length) { + object[index] = elements[index - start]; + } + // append tail elements + start = index--; + length = max(0, (object.length >>> 0) - deleteCount + elementCount); + while (++index < length) { + if ((index - start) in tail) { + object[index] = tail[index - start]; + } else if (index in object) { + delete object[index]; + } + } + // delete excess elements + deleteCount = deleteCount > elementCount ? deleteCount - elementCount : 0; + while (deleteCount--) { + index = length + deleteCount; + if (index in object) { + delete object[index]; + } + } + object.length = length; + return result; + } + + /** + * Rearrange the host array's elements in reverse order. + * + * @memberOf Benchmark.Suite + * @returns {Array} The reversed array. + */ + function reverse() { + var upperIndex, + value, + index = -1, + object = Object(this), + length = object.length >>> 0, + middle = floor(length / 2); + + if (length > 1) { + while (++index < middle) { + upperIndex = length - index - 1; + value = upperIndex in object ? object[upperIndex] : uid; + if (index in object) { + object[upperIndex] = object[index]; + } else { + delete object[upperIndex]; + } + if (value != uid) { + object[index] = value; + } else { + delete object[index]; + } + } + } + return object; + } + + /** + * Removes the first element of the host array and returns it. + * + * @memberOf Benchmark.Suite + * @returns {Mixed} The first element of the array. + */ + function shift() { + return insert.call(this, 0, 1)[0]; + } + + /** + * Creates an array of the host array's elements from the start index up to, + * but not including, the end index. + * + * @memberOf Benchmark.Suite + * @param {Number} start The starting index. + * @param {Number} end The end index. + * @returns {Array} The new array. + */ + function slice(start, end) { + var index = -1, + object = Object(this), + length = object.length >>> 0, + result = []; + + start = toInteger(start); + start = start < 0 ? max(length + start, 0) : min(start, length); + start--; + end = end == null ? length : toInteger(end); + end = end < 0 ? max(length + end, 0) : min(end, length); + + while ((++index, ++start) < end) { + if (start in object) { + result[index] = object[start]; + } + } + return result; + } + + /** + * Allows removing a range of elements and/or inserting elements into the + * host array. + * + * @memberOf Benchmark.Suite + * @param {Number} start The start index. + * @param {Number} deleteCount The number of elements to delete. + * @param {Mixed} [val1, val2, ...] values to insert at the `start` index. + * @returns {Array} An array of removed elements. + */ + function splice(start, deleteCount) { + var object = Object(this), + length = object.length >>> 0; + + start = toInteger(start); + start = start < 0 ? max(length + start, 0) : min(start, length); + + // support the de-facto SpiderMonkey extension + // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice#Parameters + // https://bugs.ecmascript.org/show_bug.cgi?id=429 + deleteCount = arguments.length == 1 + ? length - start + : min(max(toInteger(deleteCount), 0), length - start); + + return insert.call(object, start, deleteCount, slice.call(arguments, 2)); + } + + /** + * Converts the specified `value` to an integer. + * + * @private + * @param {Mixed} value The value to convert. + * @returns {Number} The resulting integer. + */ + function toInteger(value) { + value = +value; + return value === 0 || !isFinite(value) ? value || 0 : value - (value % 1); + } + + /** + * Appends arguments to the host array. + * + * @memberOf Benchmark.Suite + * @returns {Number} The new length. + */ + function unshift() { + var object = Object(this); + insert.call(object, 0, 0, arguments); + return object.length; + } + + /*--------------------------------------------------------------------------*/ + + /** + * A generic `Function#bind` like method. + * + * @private + * @param {Function} fn The function to be bound to `thisArg`. + * @param {Mixed} thisArg The `this` binding for the given function. + * @returns {Function} The bound function. + */ + function bind(fn, thisArg) { + return function() { fn.apply(thisArg, arguments); }; + } + + /** + * Creates a function from the given arguments string and body. + * + * @private + * @param {String} args The comma separated function arguments. + * @param {String} body The function body. + * @returns {Function} The new function. + */ + function createFunction() { + // lazy define + createFunction = function(args, body) { + var result, + anchor = freeDefine ? define.amd : Benchmark, + prop = uid + 'createFunction'; + + runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}'); + result = anchor[prop]; + delete anchor[prop]; + return result; + }; + // fix JaegerMonkey bug + // http://bugzil.la/639720 + createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || noop)() == uid ? createFunction : Function; + return createFunction.apply(null, arguments); + } + + /** + * Delay the execution of a function based on the benchmark's `delay` property. + * + * @private + * @param {Object} bench The benchmark instance. + * @param {Object} fn The function to execute. + */ + function delay(bench, fn) { + bench._timerId = setTimeout(fn, bench.delay * 1e3); + } + + /** + * Destroys the given element. + * + * @private + * @param {Element} element The element to destroy. + */ + function destroyElement(element) { + trash.appendChild(element); + trash.innerHTML = ''; + } + + /** + * Iterates over an object's properties, executing the `callback` for each. + * Callbacks may terminate the loop by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + * @param {Object} options The options object. + * @returns {Object} Returns the object iterated over. + */ + function forProps() { + var forShadowed, + skipSeen, + forArgs = true, + shadowed = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']; + + (function(enumFlag, key) { + // must use a non-native constructor to catch the Safari 2 issue + function Klass() { this.valueOf = 0; }; + Klass.prototype.valueOf = 0; + // check various for-in bugs + for (key in new Klass) { + enumFlag += key == 'valueOf' ? 1 : 0; + } + // check if `arguments` objects have non-enumerable indexes + for (key in arguments) { + key == '0' && (forArgs = false); + } + // Safari 2 iterates over shadowed properties twice + // http://replay.waybackmachine.org/20090428222941/http://tobielangel.com/2007/1/29/for-in-loop-broken-in-safari/ + skipSeen = enumFlag == 2; + // IE < 9 incorrectly makes an object's properties non-enumerable if they have + // the same name as other non-enumerable properties in its prototype chain. + forShadowed = !enumFlag; + }(0)); + + // lazy define + forProps = function(object, callback, options) { + options || (options = {}); + + var result = object; + object = Object(object); + + var ctor, + key, + keys, + skipCtor, + done = !result, + which = options.which, + allFlag = which == 'all', + index = -1, + iteratee = object, + length = object.length, + ownFlag = allFlag || which == 'own', + seen = {}, + skipProto = isClassOf(object, 'Function'), + thisArg = options.bind; + + if (thisArg !== undefined) { + callback = bind(callback, thisArg); + } + // iterate all properties + if (allFlag && support.getAllKeys) { + for (index = 0, keys = getAllKeys(object), length = keys.length; index < length; index++) { + key = keys[index]; + if (callback(object[key], key, object) === false) { + break; + } + } + } + // else iterate only enumerable properties + else { + for (key in object) { + // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + // (if the prototype or a property on the prototype has been set) + // incorrectly set a function's `prototype` property [[Enumerable]] value + // to `true`. Because of this we standardize on skipping the `prototype` + // property of functions regardless of their [[Enumerable]] value. + if ((done = + !(skipProto && key == 'prototype') && + !(skipSeen && (hasKey(seen, key) || !(seen[key] = true))) && + (!ownFlag || ownFlag && hasKey(object, key)) && + callback(object[key], key, object) === false)) { + break; + } + } + // in IE < 9 strings don't support accessing characters by index + if (!done && (forArgs && isArguments(object) || + ((noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String') && + (iteratee = noCharByIndex ? object.split('') : object)))) { + while (++index < length) { + if ((done = + callback(iteratee[index], String(index), object) === false)) { + break; + } + } + } + if (!done && forShadowed) { + // Because IE < 9 can't set the `[[Enumerable]]` attribute of an existing + // property and the `constructor` property of a prototype defaults to + // non-enumerable, we manually skip the `constructor` property when we + // think we are iterating over a `prototype` object. + ctor = object.constructor; + skipCtor = ctor && ctor.prototype && ctor.prototype.constructor === ctor; + for (index = 0; index < 7; index++) { + key = shadowed[index]; + if (!(skipCtor && key == 'constructor') && + hasKey(object, key) && + callback(object[key], key, object) === false) { + break; + } + } + } + } + return result; + }; + return forProps.apply(null, arguments); + } + + /** + * Gets the name of the first argument from a function's source. + * + * @private + * @param {Function} fn The function. + * @returns {String} The argument name. + */ + function getFirstArgument(fn) { + return (!hasKey(fn, 'toString') && + (/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || ''; + } + + /** + * Computes the arithmetic mean of a sample. + * + * @private + * @param {Array} sample The sample. + * @returns {Number} The mean. + */ + function getMean(sample) { + return reduce(sample, function(sum, x) { + return sum + x; + }) / sample.length || 0; + } + + /** + * Gets the source code of a function. + * + * @private + * @param {Function} fn The function. + * @param {String} altSource A string used when a function's source code is unretrievable. + * @returns {String} The function's source code. + */ + function getSource(fn, altSource) { + var result = altSource; + if (isStringable(fn)) { + result = String(fn); + } else if (support.decompilation) { + // escape the `{` for Firefox 1 + result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1]; + } + // trim string + result = (result || '').replace(/^\s+|\s+$/g, ''); + + // detect strings containing only the "use strict" directive + return /^(?:\/\*+[\w|\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result) + ? '' + : result; + } + + /** + * Checks if a value is an `arguments` object. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the value is an `arguments` object, else `false`. + */ + function isArguments() { + // lazy define + isArguments = function(value) { + return toString.call(value) == '[object Arguments]'; + }; + if (noArgumentsClass) { + isArguments = function(value) { + return hasKey(value, 'callee') && + !(propertyIsEnumerable && propertyIsEnumerable.call(value, 'callee')); + }; + } + return isArguments(arguments[0]); + } + + /** + * Checks if an object is of the specified class. + * + * @private + * @param {Mixed} value The value to check. + * @param {String} name The name of the class. + * @returns {Boolean} Returns `true` if the value is of the specified class, else `false`. + */ + function isClassOf(value, name) { + return value != null && toString.call(value) == '[object ' + name + ']'; + } + + /** + * Host objects can return type values that are different from their actual + * data type. The objects we are concerned with usually return non-primitive + * types of object, function, or unknown. + * + * @private + * @param {Mixed} object The owner of the property. + * @param {String} property The property to check. + * @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`. + */ + function isHostType(object, property) { + var type = object != null ? typeof object[property] : 'number'; + return !/^(?:boolean|number|string|undefined)$/.test(type) && + (type == 'object' ? !!object[property] : true); + } + + /** + * Checks if a given `value` is an object created by the `Object` constructor + * assuming objects created by the `Object` constructor have no inherited + * enumerable properties and that there are no `Object.prototype` extensions. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a plain `Object` object, else `false`. + */ + function isPlainObject(value) { + // avoid non-objects and false positives for `arguments` objects in IE < 9 + var result = false; + if (!(value && typeof value == 'object') || (noArgumentsClass && isArguments(value))) { + return result; + } + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings. + // Also check that the constructor is `Object` (i.e. `Object instanceof Object`) + var ctor = value.constructor; + if ((support.nodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) && + (!isClassOf(ctor, 'Function') || ctor instanceof ctor)) { + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + if (support.iteratesOwnFirst) { + forProps(value, function(subValue, subKey) { + result = subKey; + }); + return result === false || hasKey(value, result); + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + forProps(value, function(subValue, subKey) { + result = !hasKey(value, subKey); + return false; + }); + return result === false; + } + return result; + } + + /** + * Checks if a value can be safely coerced to a string. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the value can be coerced, else `false`. + */ + function isStringable(value) { + return hasKey(value, 'toString') || isClassOf(value, 'String'); + } + + /** + * Wraps a function and passes `this` to the original function as the + * first argument. + * + * @private + * @param {Function} fn The function to be wrapped. + * @returns {Function} The new function. + */ + function methodize(fn) { + return function() { + var args = [this]; + args.push.apply(args, arguments); + return fn.apply(null, args); + }; + } + + /** + * A no-operation function. + * + * @private + */ + function noop() { + // no operation performed + } + + /** + * A wrapper around require() to suppress `module missing` errors. + * + * @private + * @param {String} id The module id. + * @returns {Mixed} The exported module or `null`. + */ + function req(id) { + try { + var result = freeExports && freeRequire(id); + } catch(e) { } + return result || null; + } + + /** + * Runs a snippet of JavaScript via script injection. + * + * @private + * @param {String} code The code to run. + */ + function runScript(code) { + var anchor = freeDefine ? define.amd : Benchmark, + script = doc.createElement('script'), + sibling = doc.getElementsByTagName('script')[0], + parent = sibling.parentNode, + prop = uid + 'runScript', + prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();'; + + // Firefox 2.0.0.2 cannot use script injection as intended because it executes + // asynchronously, but that's OK because script injection is only used to avoid + // the previously commented JaegerMonkey bug. + try { + // remove the inserted script *before* running the code to avoid differences + // in the expected script element count/order of the document. + script.appendChild(doc.createTextNode(prefix + code)); + anchor[prop] = function() { destroyElement(script); }; + } catch(e) { + parent = parent.cloneNode(false); + sibling = null; + script.text = code; + } + parent.insertBefore(script, sibling); + delete anchor[prop]; + } + + /** + * A helper function for setting options/event handlers. + * + * @private + * @param {Object} bench The benchmark instance. + * @param {Object} [options={}] Options object. + */ + function setOptions(bench, options) { + options = extend({}, bench.constructor.options, options); + bench.options = forOwn(options, function(value, key) { + if (value != null) { + // add event listeners + if (/^on[A-Z]/.test(key)) { + forEach(key.split(' '), function(key) { + bench.on(key.slice(2).toLowerCase(), value); + }); + } else if (!hasKey(bench, key)) { + bench[key] = deepClone(value); + } + } + }); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Handles cycling/completing the deferred benchmark. + * + * @memberOf Benchmark.Deferred + */ + function resolve() { + var me = this, + clone = me.benchmark, + bench = clone._original; + + if (bench.aborted) { + // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete + me.teardown(); + clone.running = false; + cycle(me); + } + else if (++me.cycles < clone.count) { + // continue the test loop + if (support.timeout) { + // use setTimeout to avoid a call stack overflow if called recursively + setTimeout(function() { clone.compiled.call(me, timer); }, 0); + } else { + clone.compiled.call(me, timer); + } + } + else { + timer.stop(me); + me.teardown(); + delay(clone, function() { cycle(me); }); + } + } + + /*--------------------------------------------------------------------------*/ + + /** + * A deep clone utility. + * + * @static + * @memberOf Benchmark + * @param {Mixed} value The value to clone. + * @returns {Mixed} The cloned value. + */ + function deepClone(value) { + var accessor, + circular, + clone, + ctor, + descriptor, + extensible, + key, + length, + markerKey, + parent, + result, + source, + subIndex, + data = { 'value': value }, + index = 0, + marked = [], + queue = { 'length': 0 }, + unmarked = []; + + /** + * An easily detectable decorator for cloned values. + */ + function Marker(object) { + this.raw = object; + } + + /** + * The callback used by `forProps()`. + */ + function forPropsCallback(subValue, subKey) { + // exit early to avoid cloning the marker + if (subValue && subValue.constructor == Marker) { + return; + } + // add objects to the queue + if (subValue === Object(subValue)) { + queue[queue.length++] = { 'key': subKey, 'parent': clone, 'source': value }; + } + // assign non-objects + else { + try { + // will throw an error in strict mode if the property is read-only + clone[subKey] = subValue; + } catch(e) { } + } + } + + /** + * Gets an available marker key for the given object. + */ + function getMarkerKey(object) { + // avoid collisions with existing keys + var result = uid; + while (object[result] && object[result].constructor != Marker) { + result += 1; + } + return result; + } + + do { + key = data.key; + parent = data.parent; + source = data.source; + clone = value = source ? source[key] : data.value; + accessor = circular = descriptor = false; + + // create a basic clone to filter out functions, DOM elements, and + // other non `Object` objects + if (value === Object(value)) { + // use custom deep clone function if available + if (isClassOf(value.deepClone, 'Function')) { + clone = value.deepClone(); + } else { + ctor = value.constructor; + switch (toString.call(value)) { + case '[object Array]': + clone = new ctor(value.length); + break; + + case '[object Boolean]': + clone = new ctor(value == true); + break; + + case '[object Date]': + clone = new ctor(+value); + break; + + case '[object Object]': + isPlainObject(value) && (clone = {}); + break; + + case '[object Number]': + case '[object String]': + clone = new ctor(value); + break; + + case '[object RegExp]': + clone = ctor(value.source, + (value.global ? 'g' : '') + + (value.ignoreCase ? 'i' : '') + + (value.multiline ? 'm' : '')); + } + } + // continue clone if `value` doesn't have an accessor descriptor + // http://es5.github.com/#x8.10.1 + if (clone && clone != value && + !(descriptor = source && support.descriptors && getDescriptor(source, key), + accessor = descriptor && (descriptor.get || descriptor.set))) { + // use an existing clone (circular reference) + if ((extensible = isExtensible(value))) { + markerKey = getMarkerKey(value); + if (value[markerKey]) { + circular = clone = value[markerKey].raw; + } + } else { + // for frozen/sealed objects + for (subIndex = 0, length = unmarked.length; subIndex < length; subIndex++) { + data = unmarked[subIndex]; + if (data.object === value) { + circular = clone = data.clone; + break; + } + } + } + if (!circular) { + // mark object to allow quickly detecting circular references and tie it to its clone + if (extensible) { + value[markerKey] = new Marker(clone); + marked.push({ 'key': markerKey, 'object': value }); + } else { + // for frozen/sealed objects + unmarked.push({ 'clone': clone, 'object': value }); + } + // iterate over object properties + forProps(value, forPropsCallback, { 'which': 'all' }); + } + } + } + if (parent) { + // for custom property descriptors + if (accessor || (descriptor && !(descriptor.configurable && descriptor.enumerable && descriptor.writable))) { + if ('value' in descriptor) { + descriptor.value = clone; + } + setDescriptor(parent, key, descriptor); + } + // for default property descriptors + else { + parent[key] = clone; + } + } else { + result = clone; + } + } while ((data = queue[index++])); + + // remove markers + for (index = 0, length = marked.length; index < length; index++) { + data = marked[index]; + delete data.object[data.key]; + } + return result; + } + + /** + * An iteration utility for arrays and objects. + * Callbacks may terminate the loop by explicitly returning `false`. + * + * @static + * @memberOf Benchmark + * @param {Array|Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} thisArg The `this` binding for the callback. + * @returns {Array|Object} Returns the object iterated over. + */ + function each(object, callback, thisArg) { + var result = object; + object = Object(object); + + var fn = callback, + index = -1, + length = object.length, + isSnapshot = !!(object.snapshotItem && (length = object.snapshotLength)), + isSplittable = (noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String'), + isConvertable = isSnapshot || isSplittable || 'item' in object, + origObject = object; + + // in Opera < 10.5 `hasKey(object, 'length')` returns `false` for NodeLists + if (length === length >>> 0) { + if (isConvertable) { + // the third argument of the callback is the original non-array object + callback = function(value, index) { + return fn.call(this, value, index, origObject); + }; + // in IE < 9 strings don't support accessing characters by index + if (isSplittable) { + object = object.split(''); + } else { + object = []; + while (++index < length) { + // in Safari 2 `index in object` is always `false` for NodeLists + object[index] = isSnapshot ? result.snapshotItem(index) : result[index]; + } + } + } + forEach(object, callback, thisArg); + } else { + forOwn(object, callback, thisArg); + } + return result; + } + + /** + * Copies enumerable properties from the source(s) object to the destination object. + * + * @static + * @memberOf Benchmark + * @param {Object} destination The destination object. + * @param {Object} [source={}] The source object. + * @returns {Object} The destination object. + */ + function extend(destination, source) { + // Chrome < 14 incorrectly sets `destination` to `undefined` when we `delete arguments[0]` + // http://code.google.com/p/v8/issues/detail?id=839 + var result = destination; + delete arguments[0]; + + forEach(arguments, function(source) { + forProps(source, function(value, key) { + result[key] = value; + }); + }); + return result; + } + + /** + * A generic `Array#filter` like method. + * + * @static + * @memberOf Benchmark + * @param {Array} array The array to iterate over. + * @param {Function|String} callback The function/alias called per iteration. + * @param {Mixed} thisArg The `this` binding for the callback. + * @returns {Array} A new array of values that passed callback filter. + * @example + * + * // get odd numbers + * Benchmark.filter([1, 2, 3, 4, 5], function(n) { + * return n % 2; + * }); // -> [1, 3, 5]; + * + * // get fastest benchmarks + * Benchmark.filter(benches, 'fastest'); + * + * // get slowest benchmarks + * Benchmark.filter(benches, 'slowest'); + * + * // get benchmarks that completed without erroring + * Benchmark.filter(benches, 'successful'); + */ + function filter(array, callback, thisArg) { + var result; + + if (callback == 'successful') { + // callback to exclude those that are errored, unrun, or have hz of Infinity + callback = function(bench) { return bench.cycles && isFinite(bench.hz); }; + } + else if (callback == 'fastest' || callback == 'slowest') { + // get successful, sort by period + margin of error, and filter fastest/slowest + result = filter(array, 'successful').sort(function(a, b) { + a = a.stats; b = b.stats; + return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback == 'fastest' ? 1 : -1); + }); + result = filter(result, function(bench) { + return result[0].compare(bench) == 0; + }); + } + return result || reduce(array, function(result, value, index) { + return callback.call(thisArg, value, index, array) ? (result.push(value), result) : result; + }, []); + } + + /** + * A generic `Array#forEach` like method. + * Callbacks may terminate the loop by explicitly returning `false`. + * + * @static + * @memberOf Benchmark + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} thisArg The `this` binding for the callback. + * @returns {Array} Returns the array iterated over. + */ + function forEach(array, callback, thisArg) { + var index = -1, + length = (array = Object(array)).length >>> 0; + + if (thisArg !== undefined) { + callback = bind(callback, thisArg); + } + while (++index < length) { + if (index in array && + callback(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Iterates over an object's own properties, executing the `callback` for each. + * Callbacks may terminate the loop by explicitly returning `false`. + * + * @static + * @memberOf Benchmark + * @param {Object} object The object to iterate over. + * @param {Function} callback The function executed per own property. + * @param {Mixed} thisArg The `this` binding for the callback. + * @returns {Object} Returns the object iterated over. + */ + function forOwn(object, callback, thisArg) { + return forProps(object, callback, { 'bind': thisArg, 'which': 'own' }); + } + + /** + * Converts a number to a more readable comma-separated string representation. + * + * @static + * @memberOf Benchmark + * @param {Number} number The number to convert. + * @returns {String} The more readable string representation. + */ + function formatNumber(number) { + number = String(number).split('.'); + return number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') + + (number[1] ? '.' + number[1] : ''); + } + + /** + * Checks if an object has the specified key as a direct property. + * + * @static + * @memberOf Benchmark + * @param {Object} object The object to check. + * @param {String} key The key to check for. + * @returns {Boolean} Returns `true` if key is a direct property, else `false`. + */ + function hasKey() { + // lazy define for worst case fallback (not as accurate) + hasKey = function(object, key) { + var parent = object != null && (object.constructor || Object).prototype; + return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]); + }; + // for modern browsers + if (isClassOf(hasOwnProperty, 'Function')) { + hasKey = function(object, key) { + return object != null && hasOwnProperty.call(object, key); + }; + } + // for Safari 2 + else if ({}.__proto__ == Object.prototype) { + hasKey = function(object, key) { + var result = false; + if (object != null) { + object = Object(object); + object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0]; + } + return result; + }; + } + return hasKey.apply(this, arguments); + } + + /** + * A generic `Array#indexOf` like method. + * + * @static + * @memberOf Benchmark + * @param {Array} array The array to iterate over. + * @param {Mixed} value The value to search for. + * @param {Number} [fromIndex=0] The index to start searching from. + * @returns {Number} The index of the matched value or `-1`. + */ + function indexOf(array, value, fromIndex) { + var index = toInteger(fromIndex), + length = (array = Object(array)).length >>> 0; + + index = (index < 0 ? max(0, length + index) : index) - 1; + while (++index < length) { + if (index in array && value === array[index]) { + return index; + } + } + return -1; + } + + /** + * Modify a string by replacing named tokens with matching object property values. + * + * @static + * @memberOf Benchmark + * @param {String} string The string to modify. + * @param {Object} object The template object. + * @returns {String} The modified string. + */ + function interpolate(string, object) { + forOwn(object, function(value, key) { + // escape regexp special characters in `key` + string = string.replace(RegExp('#\\{' + key.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + '\\}', 'g'), value); + }); + return string; + } + + /** + * Invokes a method on all items in an array. + * + * @static + * @memberOf Benchmark + * @param {Array} benches Array of benchmarks to iterate over. + * @param {String|Object} name The name of the method to invoke OR options object. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. + * @returns {Array} A new array of values returned from each method invoked. + * @example + * + * // invoke `reset` on all benchmarks + * Benchmark.invoke(benches, 'reset'); + * + * // invoke `emit` with arguments + * Benchmark.invoke(benches, 'emit', 'complete', listener); + * + * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks + * Benchmark.invoke(benches, { + * + * // invoke the `run` method + * 'name': 'run', + * + * // pass a single argument + * 'args': true, + * + * // treat as queue, removing benchmarks from front of `benches` until empty + * 'queued': true, + * + * // called before any benchmarks have been invoked. + * 'onStart': onStart, + * + * // called between invoking benchmarks + * 'onCycle': onCycle, + * + * // called after all benchmarks have been invoked. + * 'onComplete': onComplete + * }); + */ + function invoke(benches, name) { + var args, + bench, + queued, + index = -1, + eventProps = { 'currentTarget': benches }, + options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop }, + result = map(benches, function(bench) { return bench; }); + + /** + * Invokes the method of the current object and if synchronous, fetches the next. + */ + function execute() { + var listeners, + async = isAsync(bench); + + if (async) { + // use `getNext` as the first listener + bench.on('complete', getNext); + listeners = bench.events.complete; + listeners.splice(0, 0, listeners.pop()); + } + // execute method + result[index] = isClassOf(bench && bench[name], 'Function') ? bench[name].apply(bench, args) : undefined; + // if synchronous return true until finished + return !async && getNext(); + } + + /** + * Fetches the next bench or executes `onComplete` callback. + */ + function getNext(event) { + var cycleEvent, + last = bench, + async = isAsync(last); + + if (async) { + last.off('complete', getNext); + last.emit('complete'); + } + // emit "cycle" event + eventProps.type = 'cycle'; + eventProps.target = last; + cycleEvent = Event(eventProps); + options.onCycle.call(benches, cycleEvent); + + // choose next benchmark if not exiting early + if (!cycleEvent.aborted && raiseIndex() !== false) { + bench = queued ? benches[0] : result[index]; + if (isAsync(bench)) { + delay(bench, execute); + } + else if (async) { + // resume execution if previously asynchronous but now synchronous + while (execute()) { } + } + else { + // continue synchronous execution + return true; + } + } else { + // emit "complete" event + eventProps.type = 'complete'; + options.onComplete.call(benches, Event(eventProps)); + } + // When used as a listener `event.aborted = true` will cancel the rest of + // the "complete" listeners because they were already called above and when + // used as part of `getNext` the `return false` will exit the execution while-loop. + if (event) { + event.aborted = true; + } else { + return false; + } + } + + /** + * Checks if invoking `Benchmark#run` with asynchronous cycles. + */ + function isAsync(object) { + // avoid using `instanceof` here because of IE memory leak issues with host objects + var async = args[0] && args[0].async; + return Object(object).constructor == Benchmark && name == 'run' && + ((async == null ? object.options.async : async) && support.timeout || object.defer); + } + + /** + * Raises `index` to the next defined index or returns `false`. + */ + function raiseIndex() { + var length = result.length; + if (queued) { + // if queued remove the previous bench and subsequent skipped non-entries + do { + ++index > 0 && shift.call(benches); + } while ((length = benches.length) && !('0' in benches)); + } + else { + while (++index < length && !(index in result)) { } + } + // if we reached the last index then return `false` + return (queued ? length : index < length) ? index : (index = false); + } + + // juggle arguments + if (isClassOf(name, 'String')) { + // 2 arguments (array, name) + args = slice.call(arguments, 2); + } else { + // 2 arguments (array, options) + options = extend(options, name); + name = options.name; + args = isClassOf(args = 'args' in options ? options.args : [], 'Array') ? args : [args]; + queued = options.queued; + } + + // start iterating over the array + if (raiseIndex() !== false) { + // emit "start" event + bench = result[index]; + eventProps.type = 'start'; + eventProps.target = bench; + options.onStart.call(benches, Event(eventProps)); + + // end early if the suite was aborted in an "onStart" listener + if (benches.aborted && benches.constructor == Suite && name == 'run') { + // emit "cycle" event + eventProps.type = 'cycle'; + options.onCycle.call(benches, Event(eventProps)); + // emit "complete" event + eventProps.type = 'complete'; + options.onComplete.call(benches, Event(eventProps)); + } + // else start + else { + if (isAsync(bench)) { + delay(bench, execute); + } else { + while (execute()) { } + } + } + } + return result; + } + + /** + * Creates a string of joined array values or object key-value pairs. + * + * @static + * @memberOf Benchmark + * @param {Array|Object} object The object to operate on. + * @param {String} [separator1=','] The separator used between key-value pairs. + * @param {String} [separator2=': '] The separator used between keys and values. + * @returns {String} The joined result. + */ + function join(object, separator1, separator2) { + var result = [], + length = (object = Object(object)).length, + arrayLike = length === length >>> 0; + + separator2 || (separator2 = ': '); + each(object, function(value, key) { + result.push(arrayLike ? value : key + separator2 + value); + }); + return result.join(separator1 || ','); + } + + /** + * A generic `Array#map` like method. + * + * @static + * @memberOf Benchmark + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} thisArg The `this` binding for the callback. + * @returns {Array} A new array of values returned by the callback. + */ + function map(array, callback, thisArg) { + return reduce(array, function(result, value, index) { + result[index] = callback.call(thisArg, value, index, array); + return result; + }, Array(Object(array).length >>> 0)); + } + + /** + * Retrieves the value of a specified property from all items in an array. + * + * @static + * @memberOf Benchmark + * @param {Array} array The array to iterate over. + * @param {String} property The property to pluck. + * @returns {Array} A new array of property values. + */ + function pluck(array, property) { + return map(array, function(object) { + return object == null ? undefined : object[property]; + }); + } + + /** + * A generic `Array#reduce` like method. + * + * @static + * @memberOf Benchmark + * @param {Array} array The array to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} accumulator Initial value of the accumulator. + * @returns {Mixed} The accumulator. + */ + function reduce(array, callback, accumulator) { + var noaccum = arguments.length < 3; + forEach(array, function(value, index) { + accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, array); + }); + return accumulator; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Aborts all benchmarks in the suite. + * + * @name abort + * @memberOf Benchmark.Suite + * @returns {Object} The suite instance. + */ + function abortSuite() { + var event, + me = this, + resetting = calledBy.resetSuite; + + if (me.running) { + event = Event('abort'); + me.emit(event); + if (!event.cancelled || resetting) { + // avoid infinite recursion + calledBy.abortSuite = true; + me.reset(); + delete calledBy.abortSuite; + + if (!resetting) { + me.aborted = true; + invoke(me, 'abort'); + } + } + } + return me; + } + + /** + * Adds a test to the benchmark suite. + * + * @memberOf Benchmark.Suite + * @param {String} name A name to identify the benchmark. + * @param {Function|String} fn The test to benchmark. + * @param {Object} [options={}] Options object. + * @returns {Object} The benchmark instance. + * @example + * + * // basic usage + * suite.add(fn); + * + * // or using a name first + * suite.add('foo', fn); + * + * // or with options + * suite.add('foo', fn, { + * 'onCycle': onCycle, + * 'onComplete': onComplete + * }); + * + * // or name and options + * suite.add('foo', { + * 'fn': fn, + * 'onCycle': onCycle, + * 'onComplete': onComplete + * }); + * + * // or options only + * suite.add({ + * 'name': 'foo', + * 'fn': fn, + * 'onCycle': onCycle, + * 'onComplete': onComplete + * }); + */ + function add(name, fn, options) { + var me = this, + bench = Benchmark(name, fn, options), + event = Event({ 'type': 'add', 'target': bench }); + + if (me.emit(event), !event.cancelled) { + me.push(bench); + } + return me; + } + + /** + * Creates a new suite with cloned benchmarks. + * + * @name clone + * @memberOf Benchmark.Suite + * @param {Object} options Options object to overwrite cloned options. + * @returns {Object} The new suite instance. + */ + function cloneSuite(options) { + var me = this, + result = new me.constructor(extend({}, me.options, options)); + + // copy own properties + forOwn(me, function(value, key) { + if (!hasKey(result, key)) { + result[key] = value && isClassOf(value.clone, 'Function') + ? value.clone() + : deepClone(value); + } + }); + return result; + } + + /** + * An `Array#filter` like method. + * + * @name filter + * @memberOf Benchmark.Suite + * @param {Function|String} callback The function/alias called per iteration. + * @returns {Object} A new suite of benchmarks that passed callback filter. + */ + function filterSuite(callback) { + var me = this, + result = new me.constructor; + + result.push.apply(result, filter(me, callback)); + return result; + } + + /** + * Resets all benchmarks in the suite. + * + * @name reset + * @memberOf Benchmark.Suite + * @returns {Object} The suite instance. + */ + function resetSuite() { + var event, + me = this, + aborting = calledBy.abortSuite; + + if (me.running && !aborting) { + // no worries, `resetSuite()` is called within `abortSuite()` + calledBy.resetSuite = true; + me.abort(); + delete calledBy.resetSuite; + } + // reset if the state has changed + else if ((me.aborted || me.running) && + (me.emit(event = Event('reset')), !event.cancelled)) { + me.running = false; + if (!aborting) { + invoke(me, 'reset'); + } + } + return me; + } + + /** + * Runs the suite. + * + * @name run + * @memberOf Benchmark.Suite + * @param {Object} [options={}] Options object. + * @returns {Object} The suite instance. + * @example + * + * // basic usage + * suite.run(); + * + * // or with options + * suite.run({ 'async': true, 'queued': true }); + */ + function runSuite(options) { + var me = this; + + me.reset(); + me.running = true; + options || (options = {}); + + invoke(me, { + 'name': 'run', + 'args': options, + 'queued': options.queued, + 'onStart': function(event) { + me.emit(event); + }, + 'onCycle': function(event) { + var bench = event.target; + if (bench.error) { + me.emit({ 'type': 'error', 'target': bench }); + } + me.emit(event); + event.aborted = me.aborted; + }, + 'onComplete': function(event) { + me.running = false; + me.emit(event); + } + }); + return me; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Executes all registered listeners of the specified event type. + * + * @memberOf Benchmark, Benchmark.Suite + * @param {String|Object} type The event type or object. + * @returns {Mixed} Returns the return value of the last listener executed. + */ + function emit(type) { + var listeners, + me = this, + event = Event(type), + events = me.events, + args = (arguments[0] = event, arguments); + + event.currentTarget || (event.currentTarget = me); + event.target || (event.target = me); + delete event.result; + + if (events && (listeners = hasKey(events, event.type) && events[event.type])) { + forEach(listeners.slice(), function(listener) { + if ((event.result = listener.apply(me, args)) === false) { + event.cancelled = true; + } + return !event.aborted; + }); + } + return event.result; + } + + /** + * Returns an array of event listeners for a given type that can be manipulated + * to add or remove listeners. + * + * @memberOf Benchmark, Benchmark.Suite + * @param {String} type The event type. + * @returns {Array} The listeners array. + */ + function listeners(type) { + var me = this, + events = me.events || (me.events = {}); + + return hasKey(events, type) ? events[type] : (events[type] = []); + } + + /** + * Unregisters a listener for the specified event type(s), + * or unregisters all listeners for the specified event type(s), + * or unregisters all listeners for all event types. + * + * @memberOf Benchmark, Benchmark.Suite + * @param {String} [type] The event type. + * @param {Function} [listener] The function to unregister. + * @returns {Object} The benchmark instance. + * @example + * + * // unregister a listener for an event type + * bench.off('cycle', listener); + * + * // unregister a listener for multiple event types + * bench.off('start cycle', listener); + * + * // unregister all listeners for an event type + * bench.off('cycle'); + * + * // unregister all listeners for multiple event types + * bench.off('start cycle complete'); + * + * // unregister all listeners for all event types + * bench.off(); + */ + function off(type, listener) { + var me = this, + events = me.events; + + events && each(type ? type.split(' ') : events, function(listeners, type) { + var index; + if (typeof listeners == 'string') { + type = listeners; + listeners = hasKey(events, type) && events[type]; + } + if (listeners) { + if (listener) { + index = indexOf(listeners, listener); + if (index > -1) { + listeners.splice(index, 1); + } + } else { + listeners.length = 0; + } + } + }); + return me; + } + + /** + * Registers a listener for the specified event type(s). + * + * @memberOf Benchmark, Benchmark.Suite + * @param {String} type The event type. + * @param {Function} listener The function to register. + * @returns {Object} The benchmark instance. + * @example + * + * // register a listener for an event type + * bench.on('cycle', listener); + * + * // register a listener for multiple event types + * bench.on('start cycle', listener); + */ + function on(type, listener) { + var me = this, + events = me.events || (me.events = {}); + + forEach(type.split(' '), function(type) { + (hasKey(events, type) + ? events[type] + : (events[type] = []) + ).push(listener); + }); + return me; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Aborts the benchmark without recording times. + * + * @memberOf Benchmark + * @returns {Object} The benchmark instance. + */ + function abort() { + var event, + me = this, + resetting = calledBy.reset; + + if (me.running) { + event = Event('abort'); + me.emit(event); + if (!event.cancelled || resetting) { + // avoid infinite recursion + calledBy.abort = true; + me.reset(); + delete calledBy.abort; + + if (support.timeout) { + clearTimeout(me._timerId); + delete me._timerId; + } + if (!resetting) { + me.aborted = true; + me.running = false; + } + } + } + return me; + } + + /** + * Creates a new benchmark using the same test and options. + * + * @memberOf Benchmark + * @param {Object} options Options object to overwrite cloned options. + * @returns {Object} The new benchmark instance. + * @example + * + * var bizarro = bench.clone({ + * 'name': 'doppelganger' + * }); + */ + function clone(options) { + var me = this, + result = new me.constructor(extend({}, me, options)); + + // correct the `options` object + result.options = extend({}, me.options, options); + + // copy own custom properties + forOwn(me, function(value, key) { + if (!hasKey(result, key)) { + result[key] = deepClone(value); + } + }); + return result; + } + + /** + * Determines if a benchmark is faster than another. + * + * @memberOf Benchmark + * @param {Object} other The benchmark to compare. + * @returns {Number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate. + */ + function compare(other) { + var critical, + zStat, + me = this, + sample1 = me.stats.sample, + sample2 = other.stats.sample, + size1 = sample1.length, + size2 = sample2.length, + maxSize = max(size1, size2), + minSize = min(size1, size2), + u1 = getU(sample1, sample2), + u2 = getU(sample2, sample1), + u = min(u1, u2); + + function getScore(xA, sampleB) { + return reduce(sampleB, function(total, xB) { + return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5); + }, 0); + } + + function getU(sampleA, sampleB) { + return reduce(sampleA, function(total, xA) { + return total + getScore(xA, sampleB); + }, 0); + } + + function getZ(u) { + return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12); + } + + // exit early if comparing the same benchmark + if (me == other) { + return 0; + } + // reject the null hyphothesis the two samples come from the + // same population (i.e. have the same median) if... + if (size1 + size2 > 30) { + // ...the z-stat is greater than 1.96 or less than -1.96 + // http://www.statisticslectures.com/topics/mannwhitneyu/ + zStat = getZ(u); + return abs(zStat) > 1.96 ? (zStat > 0 ? -1 : 1) : 0; + } + // ...the U value is less than or equal the critical U value + // http://www.geoib.com/mann-whitney-u-test.html + critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3]; + return u <= critical ? (u == u1 ? 1 : -1) : 0; + } + + /** + * Reset properties and abort if running. + * + * @memberOf Benchmark + * @returns {Object} The benchmark instance. + */ + function reset() { + var data, + event, + me = this, + index = 0, + changes = { 'length': 0 }, + queue = { 'length': 0 }; + + if (me.running && !calledBy.abort) { + // no worries, `reset()` is called within `abort()` + calledBy.reset = true; + me.abort(); + delete calledBy.reset; + } + else { + // a non-recursive solution to check if properties have changed + // http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4 + data = { 'destination': me, 'source': extend({}, me.constructor.prototype, me.options) }; + do { + forOwn(data.source, function(value, key) { + var changed, + destination = data.destination, + currValue = destination[key]; + + if (value && typeof value == 'object') { + if (isClassOf(value, 'Array')) { + // check if an array value has changed to a non-array value + if (!isClassOf(currValue, 'Array')) { + changed = currValue = []; + } + // or has changed its length + if (currValue.length != value.length) { + changed = currValue = currValue.slice(0, value.length); + currValue.length = value.length; + } + } + // check if an object has changed to a non-object value + else if (!currValue || typeof currValue != 'object') { + changed = currValue = {}; + } + // register a changed object + if (changed) { + changes[changes.length++] = { 'destination': destination, 'key': key, 'value': currValue }; + } + queue[queue.length++] = { 'destination': currValue, 'source': value }; + } + // register a changed primitive + else if (value !== currValue && !(value == null || isClassOf(value, 'Function'))) { + changes[changes.length++] = { 'destination': destination, 'key': key, 'value': value }; + } + }); + } + while ((data = queue[index++])); + + // if changed emit the `reset` event and if it isn't cancelled reset the benchmark + if (changes.length && (me.emit(event = Event('reset')), !event.cancelled)) { + forEach(changes, function(data) { + data.destination[data.key] = data.value; + }); + } + } + return me; + } + + /** + * Displays relevant benchmark information when coerced to a string. + * + * @name toString + * @memberOf Benchmark + * @returns {String} A string representation of the benchmark instance. + */ + function toStringBench() { + var me = this, + error = me.error, + hz = me.hz, + id = me.id, + stats = me.stats, + size = stats.sample.length, + pm = support.java ? '+/-' : '\xb1', + result = me.name || (isNaN(id) ? id : ''); + + if (error) { + result += ': ' + join(error); + } else { + result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm + + stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)'; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Clocks the time taken to execute a test per cycle (secs). + * + * @private + * @param {Object} bench The benchmark instance. + * @returns {Number} The time taken. + */ + function clock() { + var applet, + options = Benchmark.options, + template = { 'begin': 's$=new n$', 'end': 'r$=(new n$-s$)/1e3', 'uid': uid }, + timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }]; + + // lazy define for hi-res timers + clock = function(clone) { + var deferred; + if (clone instanceof Deferred) { + deferred = clone; + clone = deferred.benchmark; + } + + var bench = clone._original, + fn = bench.fn, + fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '', + stringable = isStringable(fn); + + var source = { + 'setup': getSource(bench.setup, preprocess('m$.setup()')), + 'fn': getSource(fn, preprocess('m$.fn(' + fnArg + ')')), + 'fnArg': fnArg, + 'teardown': getSource(bench.teardown, preprocess('m$.teardown()')) + }; + + var count = bench.count = clone.count, + decompilable = support.decompilation || stringable, + id = bench.id, + isEmpty = !(source.fn || stringable), + name = bench.name || (typeof id == 'number' ? '' : id), + ns = timer.ns, + result = 0; + + // init `minTime` if needed + clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime); + + // repair nanosecond timer + // (some Chrome builds erase the `ns` variable after millions of executions) + if (applet) { + try { + ns.nanoTime(); + } catch(e) { + // use non-element to avoid issues with libs that augment them + ns = timer.ns = new applet.Packages.nano; + } + } + + // Compile in setup/teardown functions and the test loop. + // Create a new compiled test, instead of using the cached `bench.compiled`, + // to avoid potential engine optimizations enabled over the life of the test. + var compiled = bench.compiled = createFunction(preprocess('t$'), interpolate( + preprocess(deferred + ? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' + + // when `deferred.cycles` is `0` then... + 'if(!d$.cycles){' + + // set `deferred.fn` + 'd$.fn=function(){var #{fnArg}=d$;if(typeof f$=="function"){try{#{fn}\n}catch(e$){f$(d$)}}else{#{fn}\n}};' + + // set `deferred.teardown` + 'd$.teardown=function(){d$.cycles=0;if(typeof td$=="function"){try{#{teardown}\n}catch(e$){td$()}}else{#{teardown}\n}};' + + // execute the benchmark's `setup` + 'if(typeof su$=="function"){try{#{setup}\n}catch(e$){su$()}}else{#{setup}\n};' + + // start timer + 't$.start(d$);' + + // execute `deferred.fn` and return a dummy object + '}d$.fn();return{}' + + : 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\n#{begin};' + + 'while(i$--){#{fn}\n}#{end};#{teardown}\nreturn{elapsed:r$,uid:"#{uid}"}'), + source + )); + + try { + if (isEmpty) { + // Firefox may remove dead code from Function#toString results + // http://bugzil.la/536085 + throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.'); + } + else if (!deferred) { + // pretest to determine if compiled code is exits early, usually by a + // rogue `return` statement, by checking for a return object with the uid + bench.count = 1; + compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled; + bench.count = count; + } + } catch(e) { + compiled = null; + clone.error = e || new Error(String(e)); + bench.count = count; + } + // fallback when a test exits early or errors during pretest + if (decompilable && !compiled && !deferred && !isEmpty) { + compiled = createFunction(preprocess('t$'), interpolate( + preprocess( + (clone.error && !stringable + ? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count' + : 'function f$(){#{fn}\n}var r$,s$,m$=this,i$=m$.count' + ) + + ',n$=t$.ns;#{setup}\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' + + 'delete m$.f$;#{teardown}\nreturn{elapsed:r$}' + ), + source + )); + + try { + // pretest one more time to check for errors + bench.count = 1; + compiled.call(bench, timer); + bench.compiled = compiled; + bench.count = count; + delete clone.error; + } + catch(e) { + bench.count = count; + if (clone.error) { + compiled = null; + } else { + bench.compiled = compiled; + clone.error = e || new Error(String(e)); + } + } + } + // assign `compiled` to `clone` before calling in case a deferred benchmark + // immediately calls `deferred.resolve()` + clone.compiled = compiled; + // if no errors run the full test loop + if (!clone.error) { + result = compiled.call(deferred || bench, timer).elapsed; + } + return result; + }; + + /*------------------------------------------------------------------------*/ + + /** + * Gets the current timer's minimum resolution (secs). + */ + function getRes(unit) { + var measured, + begin, + count = 30, + divisor = 1e3, + ns = timer.ns, + sample = []; + + // get average smallest measurable time + while (count--) { + if (unit == 'us') { + divisor = 1e6; + if (ns.stop) { + ns.start(); + while (!(measured = ns.microseconds())) { } + } else if (ns[perfName]) { + divisor = 1e3; + measured = Function('n', 'var r,s=n.' + perfName + '();while(!(r=n.' + perfName + '()-s)){};return r')(ns); + } else { + begin = ns(); + while (!(measured = ns() - begin)) { } + } + } + else if (unit == 'ns') { + divisor = 1e9; + if (ns.nanoTime) { + begin = ns.nanoTime(); + while (!(measured = ns.nanoTime() - begin)) { } + } else { + begin = (begin = ns())[0] + (begin[1] / divisor); + while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) { } + divisor = 1; + } + } + else { + begin = new ns; + while (!(measured = new ns - begin)) { } + } + // check for broken timers (nanoTime may have issues) + // http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/ + if (measured > 0) { + sample.push(measured); + } else { + sample.push(Infinity); + break; + } + } + // convert to seconds + return getMean(sample) / divisor; + } + + /** + * Replaces all occurrences of `$` with a unique number and + * template tokens with content. + */ + function preprocess(code) { + return interpolate(code, template).replace(/\$/g, /\d+/.exec(uid)); + } + + /*------------------------------------------------------------------------*/ + + // detect nanosecond support from a Java applet + each(doc && doc.applets || [], function(element) { + return !(timer.ns = applet = 'nanoTime' in element && element); + }); + + // check type in case Safari returns an object instead of a number + try { + if (typeof timer.ns.nanoTime() == 'number') { + timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); + } + } catch(e) { } + + // detect Chrome's microsecond timer: + // enable benchmarking via the --enable-benchmarking command + // line switch in at least Chrome 7 to use chrome.Interval + try { + if ((timer.ns = new (window.chrome || window.chromium).Interval)) { + timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); + } + } catch(e) { } + + // detect `performance.now` microsecond resolution timer + if ((timer.ns = perfName && perfObject)) { + timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); + } + + // detect Node's nanosecond resolution timer available in Node >= 0.8 + if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') { + timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); + } + + // detect Wade Simmons' Node microtime module + if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') { + timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); + } + + // pick timer with highest resolution + timer = reduce(timers, function(timer, other) { + return other.res < timer.res ? other : timer; + }); + + // remove unused applet + if (timer.unit != 'ns' && applet) { + applet = destroyElement(applet); + } + // error if there are no working timers + if (timer.res == Infinity) { + throw new Error('Benchmark.js was unable to find a working timer.'); + } + // use API of chosen timer + if (timer.unit == 'ns') { + if (timer.ns.nanoTime) { + extend(template, { + 'begin': 's$=n$.nanoTime()', + 'end': 'r$=(n$.nanoTime()-s$)/1e9' + }); + } else { + extend(template, { + 'begin': 's$=n$()', + 'end': 'r$=n$(s$);r$=r$[0]+(r$[1]/1e9)' + }); + } + } + else if (timer.unit == 'us') { + if (timer.ns.stop) { + extend(template, { + 'begin': 's$=n$.start()', + 'end': 'r$=n$.microseconds()/1e6' + }); + } else if (perfName) { + extend(template, { + 'begin': 's$=n$.' + perfName + '()', + 'end': 'r$=(n$.' + perfName + '()-s$)/1e3' + }); + } else { + extend(template, { + 'begin': 's$=n$()', + 'end': 'r$=(n$()-s$)/1e6' + }); + } + } + + // define `timer` methods + timer.start = createFunction(preprocess('o$'), + preprocess('var n$=this.ns,#{begin};o$.elapsed=0;o$.timeStamp=s$')); + + timer.stop = createFunction(preprocess('o$'), + preprocess('var n$=this.ns,s$=o$.timeStamp,#{end};o$.elapsed=r$')); + + // resolve time span required to achieve a percent uncertainty of at most 1% + // http://spiff.rit.edu/classes/phys273/uncert/uncert.html + options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05)); + return clock.apply(null, arguments); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Computes stats on benchmark results. + * + * @private + * @param {Object} bench The benchmark instance. + * @param {Object} options The options object. + */ + function compute(bench, options) { + options || (options = {}); + + var async = options.async, + elapsed = 0, + initCount = bench.initCount, + minSamples = bench.minSamples, + queue = [], + sample = bench.stats.sample; + + /** + * Adds a clone to the queue. + */ + function enqueue() { + queue.push(bench.clone({ + '_original': bench, + 'events': { + 'abort': [update], + 'cycle': [update], + 'error': [update], + 'start': [update] + } + })); + } + + /** + * Updates the clone/original benchmarks to keep their data in sync. + */ + function update(event) { + var clone = this, + type = event.type; + + if (bench.running) { + if (type == 'start') { + // Note: `clone.minTime` prop is inited in `clock()` + clone.count = bench.initCount; + } + else { + if (type == 'error') { + bench.error = clone.error; + } + if (type == 'abort') { + bench.abort(); + bench.emit('cycle'); + } else { + event.currentTarget = event.target = bench; + bench.emit(event); + } + } + } else if (bench.aborted) { + // clear abort listeners to avoid triggering bench's abort/cycle again + clone.events.abort.length = 0; + clone.abort(); + } + } + + /** + * Determines if more clones should be queued or if cycling should stop. + */ + function evaluate(event) { + var critical, + df, + mean, + moe, + rme, + sd, + sem, + variance, + clone = event.target, + done = bench.aborted, + now = +new Date, + size = sample.push(clone.times.period), + maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime, + times = bench.times, + varOf = function(sum, x) { return sum + pow(x - mean, 2); }; + + // exit early for aborted or unclockable tests + if (done || clone.hz == Infinity) { + maxedOut = !(size = sample.length = queue.length = 0); + } + + if (!done) { + // sample mean (estimate of the population mean) + mean = getMean(sample); + // sample variance (estimate of the population variance) + variance = reduce(sample, varOf, 0) / (size - 1) || 0; + // sample standard deviation (estimate of the population standard deviation) + sd = sqrt(variance); + // standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean) + sem = sd / sqrt(size); + // degrees of freedom + df = size - 1; + // critical value + critical = tTable[Math.round(df) || 1] || tTable.infinity; + // margin of error + moe = sem * critical; + // relative margin of error + rme = (moe / mean) * 100 || 0; + + extend(bench.stats, { + 'deviation': sd, + 'mean': mean, + 'moe': moe, + 'rme': rme, + 'sem': sem, + 'variance': variance + }); + + // Abort the cycle loop when the minimum sample size has been collected + // and the elapsed time exceeds the maximum time allowed per benchmark. + // We don't count cycle delays toward the max time because delays may be + // increased by browsers that clamp timeouts for inactive tabs. + // https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs + if (maxedOut) { + // reset the `initCount` in case the benchmark is rerun + bench.initCount = initCount; + bench.running = false; + done = true; + times.elapsed = (now - times.timeStamp) / 1e3; + } + if (bench.hz != Infinity) { + bench.hz = 1 / mean; + times.cycle = mean * bench.count; + times.period = mean; + } + } + // if time permits, increase sample size to reduce the margin of error + if (queue.length < 2 && !maxedOut) { + enqueue(); + } + // abort the invoke cycle when done + event.aborted = done; + } + + // init queue and begin + enqueue(); + invoke(queue, { + 'name': 'run', + 'args': { 'async': async }, + 'queued': true, + 'onCycle': evaluate, + 'onComplete': function() { bench.emit('complete'); } + }); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Cycles a benchmark until a run `count` can be established. + * + * @private + * @param {Object} clone The cloned benchmark instance. + * @param {Object} options The options object. + */ + function cycle(clone, options) { + options || (options = {}); + + var deferred; + if (clone instanceof Deferred) { + deferred = clone; + clone = clone.benchmark; + } + + var clocked, + cycles, + divisor, + event, + minTime, + period, + async = options.async, + bench = clone._original, + count = clone.count, + times = clone.times; + + // continue, if not aborted between cycles + if (clone.running) { + // `minTime` is set to `Benchmark.options.minTime` in `clock()` + cycles = ++clone.cycles; + clocked = deferred ? deferred.elapsed : clock(clone); + minTime = clone.minTime; + + if (cycles > bench.cycles) { + bench.cycles = cycles; + } + if (clone.error) { + event = Event('error'); + event.message = clone.error; + clone.emit(event); + if (!event.cancelled) { + clone.abort(); + } + } + } + + // continue, if not errored + if (clone.running) { + // time taken to complete last test cycle + bench.times.cycle = times.cycle = clocked; + // seconds per operation + period = bench.times.period = times.period = clocked / count; + // ops per second + bench.hz = clone.hz = 1 / period; + // avoid working our way up to this next time + bench.initCount = clone.initCount = count; + // do we need to do another cycle? + clone.running = clocked < minTime; + + if (clone.running) { + // tests may clock at `0` when `initCount` is a small number, + // to avoid that we set its count to something a bit higher + if (!clocked && (divisor = divisors[clone.cycles]) != null) { + count = floor(4e6 / divisor); + } + // calculate how many more iterations it will take to achive the `minTime` + if (count <= clone.count) { + count += Math.ceil((minTime - clocked) / period); + } + clone.running = count != Infinity; + } + } + // should we exit early? + event = Event('cycle'); + clone.emit(event); + if (event.aborted) { + clone.abort(); + } + // figure out what to do next + if (clone.running) { + // start a new cycle + clone.count = count; + if (deferred) { + clone.compiled.call(deferred, timer); + } else if (async) { + delay(clone, function() { cycle(clone, options); }); + } else { + cycle(clone); + } + } + else { + // fix TraceMonkey bug associated with clock fallbacks + // http://bugzil.la/509069 + if (support.browser) { + runScript(uid + '=1;delete ' + uid); + } + // done + clone.emit('complete'); + } + } + + /*--------------------------------------------------------------------------*/ + + /** + * Runs the benchmark. + * + * @memberOf Benchmark + * @param {Object} [options={}] Options object. + * @returns {Object} The benchmark instance. + * @example + * + * // basic usage + * bench.run(); + * + * // or with options + * bench.run({ 'async': true }); + */ + function run(options) { + var me = this, + event = Event('start'); + + // set `running` to `false` so `reset()` won't call `abort()` + me.running = false; + me.reset(); + me.running = true; + + me.count = me.initCount; + me.times.timeStamp = +new Date; + me.emit(event); + + if (!event.cancelled) { + options = { 'async': ((options = options && options.async) == null ? me.async : options) && support.timeout }; + + // for clones created within `compute()` + if (me._original) { + if (me.defer) { + Deferred(me); + } else { + cycle(me, options); + } + } + // for original benchmarks + else { + compute(me, options); + } + } + return me; + } + + /*--------------------------------------------------------------------------*/ + + // Firefox 1 erroneously defines variable and argument names of functions on + // the function itself as non-configurable properties with `undefined` values. + // The bugginess continues as the `Benchmark` constructor has an argument + // named `options` and Firefox 1 will not assign a value to `Benchmark.options`, + // making it non-writable in the process, unless it is the first property + // assigned by for-in loop of `extend()`. + extend(Benchmark, { + + /** + * The default options copied by benchmark instances. + * + * @static + * @memberOf Benchmark + * @type Object + */ + 'options': { + + /** + * A flag to indicate that benchmark cycles will execute asynchronously + * by default. + * + * @memberOf Benchmark.options + * @type Boolean + */ + 'async': false, + + /** + * A flag to indicate that the benchmark clock is deferred. + * + * @memberOf Benchmark.options + * @type Boolean + */ + 'defer': false, + + /** + * The delay between test cycles (secs). + * @memberOf Benchmark.options + * @type Number + */ + 'delay': 0.005, + + /** + * Displayed by Benchmark#toString when a `name` is not available + * (auto-generated if absent). + * + * @memberOf Benchmark.options + * @type String + */ + 'id': undefined, + + /** + * The default number of times to execute a test on a benchmark's first cycle. + * + * @memberOf Benchmark.options + * @type Number + */ + 'initCount': 1, + + /** + * The maximum time a benchmark is allowed to run before finishing (secs). + * Note: Cycle delays aren't counted toward the maximum time. + * + * @memberOf Benchmark.options + * @type Number + */ + 'maxTime': 5, + + /** + * The minimum sample size required to perform statistical analysis. + * + * @memberOf Benchmark.options + * @type Number + */ + 'minSamples': 5, + + /** + * The time needed to reduce the percent uncertainty of measurement to 1% (secs). + * + * @memberOf Benchmark.options + * @type Number + */ + 'minTime': 0, + + /** + * The name of the benchmark. + * + * @memberOf Benchmark.options + * @type String + */ + 'name': undefined, + + /** + * An event listener called when the benchmark is aborted. + * + * @memberOf Benchmark.options + * @type Function + */ + 'onAbort': undefined, + + /** + * An event listener called when the benchmark completes running. + * + * @memberOf Benchmark.options + * @type Function + */ + 'onComplete': undefined, + + /** + * An event listener called after each run cycle. + * + * @memberOf Benchmark.options + * @type Function + */ + 'onCycle': undefined, + + /** + * An event listener called when a test errors. + * + * @memberOf Benchmark.options + * @type Function + */ + 'onError': undefined, + + /** + * An event listener called when the benchmark is reset. + * + * @memberOf Benchmark.options + * @type Function + */ + 'onReset': undefined, + + /** + * An event listener called when the benchmark starts running. + * + * @memberOf Benchmark.options + * @type Function + */ + 'onStart': undefined + }, + + /** + * Platform object with properties describing things like browser name, + * version, and operating system. + * + * @static + * @memberOf Benchmark + * @type Object + */ + 'platform': req('platform') || window.platform || { + + /** + * The platform description. + * + * @memberOf Benchmark.platform + * @type String + */ + 'description': window.navigator && navigator.userAgent || null, + + /** + * The name of the browser layout engine. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'layout': null, + + /** + * The name of the product hosting the browser. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'product': null, + + /** + * The name of the browser/environment. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'name': null, + + /** + * The name of the product's manufacturer. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'manufacturer': null, + + /** + * The name of the operating system. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'os': null, + + /** + * The alpha/beta release indicator. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'prerelease': null, + + /** + * The browser/environment version. + * + * @memberOf Benchmark.platform + * @type String|Null + */ + 'version': null, + + /** + * Return platform description when the platform object is coerced to a string. + * + * @memberOf Benchmark.platform + * @type Function + * @returns {String} The platform description. + */ + 'toString': function() { + return this.description || ''; + } + }, + + /** + * The semantic version number. + * + * @static + * @memberOf Benchmark + * @type String + */ + 'version': '1.0.0', + + // an object of environment/feature detection flags + 'support': support, + + // clone objects + 'deepClone': deepClone, + + // iteration utility + 'each': each, + + // augment objects + 'extend': extend, + + // generic Array#filter + 'filter': filter, + + // generic Array#forEach + 'forEach': forEach, + + // generic own property iteration utility + 'forOwn': forOwn, + + // converts a number to a comma-separated string + 'formatNumber': formatNumber, + + // generic Object#hasOwnProperty + // (trigger hasKey's lazy define before assigning it to Benchmark) + 'hasKey': (hasKey(Benchmark, ''), hasKey), + + // generic Array#indexOf + 'indexOf': indexOf, + + // template utility + 'interpolate': interpolate, + + // invokes a method on each item in an array + 'invoke': invoke, + + // generic Array#join for arrays and objects + 'join': join, + + // generic Array#map + 'map': map, + + // retrieves a property value from each item in an array + 'pluck': pluck, + + // generic Array#reduce + 'reduce': reduce + }); + + /*--------------------------------------------------------------------------*/ + + extend(Benchmark.prototype, { + + /** + * The number of times a test was executed. + * + * @memberOf Benchmark + * @type Number + */ + 'count': 0, + + /** + * The number of cycles performed while benchmarking. + * + * @memberOf Benchmark + * @type Number + */ + 'cycles': 0, + + /** + * The number of executions per second. + * + * @memberOf Benchmark + * @type Number + */ + 'hz': 0, + + /** + * The compiled test function. + * + * @memberOf Benchmark + * @type Function|String + */ + 'compiled': undefined, + + /** + * The error object if the test failed. + * + * @memberOf Benchmark + * @type Object + */ + 'error': undefined, + + /** + * The test to benchmark. + * + * @memberOf Benchmark + * @type Function|String + */ + 'fn': undefined, + + /** + * A flag to indicate if the benchmark is aborted. + * + * @memberOf Benchmark + * @type Boolean + */ + 'aborted': false, + + /** + * A flag to indicate if the benchmark is running. + * + * @memberOf Benchmark + * @type Boolean + */ + 'running': false, + + /** + * Compiled into the test and executed immediately **before** the test loop. + * + * @memberOf Benchmark + * @type Function|String + * @example + * + * // basic usage + * var bench = Benchmark({ + * 'setup': function() { + * var c = this.count, + * element = document.getElementById('container'); + * while (c--) { + * element.appendChild(document.createElement('div')); + * } + * }, + * 'fn': function() { + * element.removeChild(element.lastChild); + * } + * }); + * + * // compiles to something like: + * var c = this.count, + * element = document.getElementById('container'); + * while (c--) { + * element.appendChild(document.createElement('div')); + * } + * var start = new Date; + * while (count--) { + * element.removeChild(element.lastChild); + * } + * var end = new Date - start; + * + * // or using strings + * var bench = Benchmark({ + * 'setup': '\ + * var a = 0;\n\ + * (function() {\n\ + * (function() {\n\ + * (function() {', + * 'fn': 'a += 1;', + * 'teardown': '\ + * }())\n\ + * }())\n\ + * }())' + * }); + * + * // compiles to something like: + * var a = 0; + * (function() { + * (function() { + * (function() { + * var start = new Date; + * while (count--) { + * a += 1; + * } + * var end = new Date - start; + * }()) + * }()) + * }()) + */ + 'setup': noop, + + /** + * Compiled into the test and executed immediately **after** the test loop. + * + * @memberOf Benchmark + * @type Function|String + */ + 'teardown': noop, + + /** + * An object of stats including mean, margin or error, and standard deviation. + * + * @memberOf Benchmark + * @type Object + */ + 'stats': { + + /** + * The margin of error. + * + * @memberOf Benchmark#stats + * @type Number + */ + 'moe': 0, + + /** + * The relative margin of error (expressed as a percentage of the mean). + * + * @memberOf Benchmark#stats + * @type Number + */ + 'rme': 0, + + /** + * The standard error of the mean. + * + * @memberOf Benchmark#stats + * @type Number + */ + 'sem': 0, + + /** + * The sample standard deviation. + * + * @memberOf Benchmark#stats + * @type Number + */ + 'deviation': 0, + + /** + * The sample arithmetic mean. + * + * @memberOf Benchmark#stats + * @type Number + */ + 'mean': 0, + + /** + * The array of sampled periods. + * + * @memberOf Benchmark#stats + * @type Array + */ + 'sample': [], + + /** + * The sample variance. + * + * @memberOf Benchmark#stats + * @type Number + */ + 'variance': 0 + }, + + /** + * An object of timing data including cycle, elapsed, period, start, and stop. + * + * @memberOf Benchmark + * @type Object + */ + 'times': { + + /** + * The time taken to complete the last cycle (secs). + * + * @memberOf Benchmark#times + * @type Number + */ + 'cycle': 0, + + /** + * The time taken to complete the benchmark (secs). + * + * @memberOf Benchmark#times + * @type Number + */ + 'elapsed': 0, + + /** + * The time taken to execute the test once (secs). + * + * @memberOf Benchmark#times + * @type Number + */ + 'period': 0, + + /** + * A timestamp of when the benchmark started (ms). + * + * @memberOf Benchmark#times + * @type Number + */ + 'timeStamp': 0 + }, + + // aborts benchmark (does not record times) + 'abort': abort, + + // creates a new benchmark using the same test and options + 'clone': clone, + + // compares benchmark's hertz with another + 'compare': compare, + + // executes listeners + 'emit': emit, + + // get listeners + 'listeners': listeners, + + // unregister listeners + 'off': off, + + // register listeners + 'on': on, + + // reset benchmark properties + 'reset': reset, + + // runs the benchmark + 'run': run, + + // pretty print benchmark info + 'toString': toStringBench + }); + + /*--------------------------------------------------------------------------*/ + + extend(Deferred.prototype, { + + /** + * The deferred benchmark instance. + * + * @memberOf Benchmark.Deferred + * @type Object + */ + 'benchmark': null, + + /** + * The number of deferred cycles performed while benchmarking. + * + * @memberOf Benchmark.Deferred + * @type Number + */ + 'cycles': 0, + + /** + * The time taken to complete the deferred benchmark (secs). + * + * @memberOf Benchmark.Deferred + * @type Number + */ + 'elapsed': 0, + + /** + * A timestamp of when the deferred benchmark started (ms). + * + * @memberOf Benchmark.Deferred + * @type Number + */ + 'timeStamp': 0, + + // cycles/completes the deferred benchmark + 'resolve': resolve + }); + + /*--------------------------------------------------------------------------*/ + + extend(Event.prototype, { + + /** + * A flag to indicate if the emitters listener iteration is aborted. + * + * @memberOf Benchmark.Event + * @type Boolean + */ + 'aborted': false, + + /** + * A flag to indicate if the default action is cancelled. + * + * @memberOf Benchmark.Event + * @type Boolean + */ + 'cancelled': false, + + /** + * The object whose listeners are currently being processed. + * + * @memberOf Benchmark.Event + * @type Object + */ + 'currentTarget': undefined, + + /** + * The return value of the last executed listener. + * + * @memberOf Benchmark.Event + * @type Mixed + */ + 'result': undefined, + + /** + * The object to which the event was originally emitted. + * + * @memberOf Benchmark.Event + * @type Object + */ + 'target': undefined, + + /** + * A timestamp of when the event was created (ms). + * + * @memberOf Benchmark.Event + * @type Number + */ + 'timeStamp': 0, + + /** + * The event type. + * + * @memberOf Benchmark.Event + * @type String + */ + 'type': '' + }); + + /*--------------------------------------------------------------------------*/ + + /** + * The default options copied by suite instances. + * + * @static + * @memberOf Benchmark.Suite + * @type Object + */ + Suite.options = { + + /** + * The name of the suite. + * + * @memberOf Benchmark.Suite.options + * @type String + */ + 'name': undefined + }; + + /*--------------------------------------------------------------------------*/ + + extend(Suite.prototype, { + + /** + * The number of benchmarks in the suite. + * + * @memberOf Benchmark.Suite + * @type Number + */ + 'length': 0, + + /** + * A flag to indicate if the suite is aborted. + * + * @memberOf Benchmark.Suite + * @type Boolean + */ + 'aborted': false, + + /** + * A flag to indicate if the suite is running. + * + * @memberOf Benchmark.Suite + * @type Boolean + */ + 'running': false, + + /** + * An `Array#forEach` like method. + * Callbacks may terminate the loop by explicitly returning `false`. + * + * @memberOf Benchmark.Suite + * @param {Function} callback The function called per iteration. + * @returns {Object} The suite iterated over. + */ + 'forEach': methodize(forEach), + + /** + * An `Array#indexOf` like method. + * + * @memberOf Benchmark.Suite + * @param {Mixed} value The value to search for. + * @returns {Number} The index of the matched value or `-1`. + */ + 'indexOf': methodize(indexOf), + + /** + * Invokes a method on all benchmarks in the suite. + * + * @memberOf Benchmark.Suite + * @param {String|Object} name The name of the method to invoke OR options object. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. + * @returns {Array} A new array of values returned from each method invoked. + */ + 'invoke': methodize(invoke), + + /** + * Converts the suite of benchmarks to a string. + * + * @memberOf Benchmark.Suite + * @param {String} [separator=','] A string to separate each element of the array. + * @returns {String} The string. + */ + 'join': [].join, + + /** + * An `Array#map` like method. + * + * @memberOf Benchmark.Suite + * @param {Function} callback The function called per iteration. + * @returns {Array} A new array of values returned by the callback. + */ + 'map': methodize(map), + + /** + * Retrieves the value of a specified property from all benchmarks in the suite. + * + * @memberOf Benchmark.Suite + * @param {String} property The property to pluck. + * @returns {Array} A new array of property values. + */ + 'pluck': methodize(pluck), + + /** + * Removes the last benchmark from the suite and returns it. + * + * @memberOf Benchmark.Suite + * @returns {Mixed} The removed benchmark. + */ + 'pop': [].pop, + + /** + * Appends benchmarks to the suite. + * + * @memberOf Benchmark.Suite + * @returns {Number} The suite's new length. + */ + 'push': [].push, + + /** + * Sorts the benchmarks of the suite. + * + * @memberOf Benchmark.Suite + * @param {Function} [compareFn=null] A function that defines the sort order. + * @returns {Object} The sorted suite. + */ + 'sort': [].sort, + + /** + * An `Array#reduce` like method. + * + * @memberOf Benchmark.Suite + * @param {Function} callback The function called per iteration. + * @param {Mixed} accumulator Initial value of the accumulator. + * @returns {Mixed} The accumulator. + */ + 'reduce': methodize(reduce), + + // aborts all benchmarks in the suite + 'abort': abortSuite, + + // adds a benchmark to the suite + 'add': add, + + // creates a new suite with cloned benchmarks + 'clone': cloneSuite, + + // executes listeners of a specified type + 'emit': emit, + + // creates a new suite of filtered benchmarks + 'filter': filterSuite, + + // get listeners + 'listeners': listeners, + + // unregister listeners + 'off': off, + + // register listeners + 'on': on, + + // resets all benchmarks in the suite + 'reset': resetSuite, + + // runs all benchmarks in the suite + 'run': runSuite, + + // array methods + 'concat': concat, + + 'reverse': reverse, + + 'shift': shift, + + 'slice': slice, + + 'splice': splice, + + 'unshift': unshift + }); + + /*--------------------------------------------------------------------------*/ + + // expose Deferred, Event and Suite + extend(Benchmark, { + 'Deferred': Deferred, + 'Event': Event, + 'Suite': Suite + }); + + // expose Benchmark + // some AMD build optimizers, like r.js, check for specific condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // define as an anonymous module so, through path mapping, it can be aliased + define(function() { + return Benchmark; + }); + } + // check for `exports` after `define` in case a build optimizer adds an `exports` object + else if (freeExports) { + // in Node.js or RingoJS v0.8.0+ + if (typeof module == 'object' && module && module.exports == freeExports) { + (module.exports = Benchmark).Benchmark = Benchmark; + } + // in Narwhal or RingoJS v0.7.0- + else { + freeExports.Benchmark = Benchmark; + } + } + // in a browser or Rhino + else { + // use square bracket notation so Closure Compiler won't munge `Benchmark` + // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export + window['Benchmark'] = Benchmark; + } + + // trigger clock's lazy define early to avoid a security error + if (support.air) { + clock({ '_original': { 'fn': noop, 'count': 1, 'options': {} } }); + } +}(this)); diff --git a/node_modules/benchmark/doc/README.md b/node_modules/benchmark/doc/README.md new file mode 100644 index 0000000..5b8960a --- /dev/null +++ b/node_modules/benchmark/doc/README.md @@ -0,0 +1,2629 @@ +# Benchmark.js v1.0.0 + + + + + + +## `Benchmark` +* [`Benchmark`](#benchmarkname-fn--options) +* [`Benchmark.version`](#benchmarkversion) +* [`Benchmark.deepClone`](#benchmarkdeepclonevalue) +* [`Benchmark.each`](#benchmarkeachobject-callback-thisarg) +* [`Benchmark.extend`](#benchmarkextenddestination--source) +* [`Benchmark.filter`](#benchmarkfilterarray-callback-thisarg) +* [`Benchmark.forEach`](#benchmarkforeacharray-callback-thisarg) +* [`Benchmark.formatNumber`](#benchmarkformatnumbernumber) +* [`Benchmark.forOwn`](#benchmarkforownobject-callback-thisarg) +* [`Benchmark.hasKey`](#benchmarkhaskeyobject-key) +* [`Benchmark.indexOf`](#benchmarkindexofarray-value--fromindex0) +* [`Benchmark.interpolate`](#benchmarkinterpolatestring-object) +* [`Benchmark.invoke`](#benchmarkinvokebenches-name--arg1-arg2-) +* [`Benchmark.join`](#benchmarkjoinobject--separator1--separator2:) +* [`Benchmark.map`](#benchmarkmaparray-callback-thisarg) +* [`Benchmark.pluck`](#benchmarkpluckarray-property) +* [`Benchmark.reduce`](#benchmarkreducearray-callback-accumulator) + + + + + + +## `Benchmark.prototype` +* [`Benchmark.prototype.aborted`](#benchmarkprototypeaborted) +* [`Benchmark.prototype.compiled`](#benchmarkprototypecompiled) +* [`Benchmark.prototype.count`](#benchmarkprototypecount) +* [`Benchmark.prototype.cycles`](#benchmarkprototypecycles) +* [`Benchmark.prototype.fn`](#benchmarkprototypefn) +* [`Benchmark.prototype.hz`](#benchmarkprototypehz) +* [`Benchmark.prototype.running`](#benchmarkprototyperunning) +* [`Benchmark.prototype.setup`](#benchmarkprototypesetup) +* [`Benchmark.prototype.teardown`](#benchmarkprototypeteardown) +* [`Benchmark.prototype.abort`](#benchmarkprototypeabort) +* [`Benchmark.prototype.clone`](#benchmarkprototypecloneoptions) +* [`Benchmark.prototype.compare`](#benchmarkprototypecompareother) +* [`Benchmark.prototype.emit`](#benchmarkprototypeemittype) +* [`Benchmark.prototype.listeners`](#benchmarkprototypelistenerstype) +* [`Benchmark.prototype.off`](#benchmarkprototypeofftype-listener) +* [`Benchmark.prototype.on`](#benchmarkprototypeontype-listener) +* [`Benchmark.prototype.reset`](#benchmarkprototypereset) +* [`Benchmark.prototype.run`](#benchmarkprototyperunoptions) +* [`Benchmark.prototype.toString`](#benchmarkprototypetostring) + + + + + + +## `Benchmark.options` +* [`Benchmark.options`](#benchmarkoptions) +* [`Benchmark.options.async`](#benchmarkoptionsasync) +* [`Benchmark.options.defer`](#benchmarkoptionsdefer) +* [`Benchmark.options.delay`](#benchmarkoptionsdelay) +* [`Benchmark.options.id`](#benchmarkoptionsid) +* [`Benchmark.options.initCount`](#benchmarkoptionsinitcount) +* [`Benchmark.options.maxTime`](#benchmarkoptionsmaxtime) +* [`Benchmark.options.minSamples`](#benchmarkoptionsminsamples) +* [`Benchmark.options.minTime`](#benchmarkoptionsmintime) +* [`Benchmark.options.name`](#benchmarkoptionsname) +* [`Benchmark.options.onAbort`](#benchmarkoptionsonabort) +* [`Benchmark.options.onComplete`](#benchmarkoptionsoncomplete) +* [`Benchmark.options.onCycle`](#benchmarkoptionsoncycle) +* [`Benchmark.options.onError`](#benchmarkoptionsonerror) +* [`Benchmark.options.onReset`](#benchmarkoptionsonreset) +* [`Benchmark.options.onStart`](#benchmarkoptionsonstart) + + + + + + +## `Benchmark.platform` +* [`Benchmark.platform`](#benchmarkplatform) +* [`Benchmark.platform.description`](#benchmarkplatformdescription) +* [`Benchmark.platform.layout`](#benchmarkplatformlayout) +* [`Benchmark.platform.manufacturer`](#benchmarkplatformmanufacturer) +* [`Benchmark.platform.name`](#benchmarkplatformname) +* [`Benchmark.platform.os`](#benchmarkplatformos) +* [`Benchmark.platform.prerelease`](#benchmarkplatformprerelease) +* [`Benchmark.platform.product`](#benchmarkplatformproduct) +* [`Benchmark.platform.version`](#benchmarkplatformversion) +* [`Benchmark.platform.toString`](#benchmarkplatformtostring) + + + + + + +## `Benchmark.support` +* [`Benchmark.support`](#benchmarksupport) +* [`Benchmark.support.air`](#benchmarksupportair) +* [`Benchmark.support.argumentsClass`](#benchmarksupportargumentsclass) +* [`Benchmark.support.browser`](#benchmarksupportbrowser) +* [`Benchmark.support.charByIndex`](#benchmarksupportcharbyindex) +* [`Benchmark.support.charByOwnIndex`](#benchmarksupportcharbyownindex) +* [`Benchmark.support.decompilation`](#benchmarksupportdecompilation) +* [`Benchmark.support.descriptors`](#benchmarksupportdescriptors) +* [`Benchmark.support.getAllKeys`](#benchmarksupportgetallkeys) +* [`Benchmark.support.iteratesOwnLast`](#benchmarksupportiteratesownfirst) +* [`Benchmark.support.java`](#benchmarksupportjava) +* [`Benchmark.support.nodeClass`](#benchmarksupportnodeclass) +* [`Benchmark.support.timeout`](#benchmarksupporttimeout) + + + + + + +## `Benchmark.prototype.error` +* [`Benchmark.prototype.error`](#benchmarkprototypeerror) + + + + + + +## `Benchmark.prototype.stats` +* [`Benchmark.prototype.stats`](#benchmarkprototypestats) +* [`Benchmark.prototype.stats.deviation`](#benchmark-statsdeviation) +* [`Benchmark.prototype.stats.mean`](#benchmark-statsmean) +* [`Benchmark.prototype.stats.moe`](#benchmark-statsmoe) +* [`Benchmark.prototype.stats.rme`](#benchmark-statsrme) +* [`Benchmark.prototype.stats.sample`](#benchmark-statssample) +* [`Benchmark.prototype.stats.sem`](#benchmark-statssem) +* [`Benchmark.prototype.stats.variance`](#benchmark-statsvariance) + + + + + + +## `Benchmark.prototype.times` +* [`Benchmark.prototype.times`](#benchmarkprototypetimes) +* [`Benchmark.prototype.times.cycle`](#benchmark-timescycle) +* [`Benchmark.prototype.times.elapsed`](#benchmark-timeselapsed) +* [`Benchmark.prototype.times.period`](#benchmark-timesperiod) +* [`Benchmark.prototype.times.timeStamp`](#benchmark-timestimestamp) + + + + + + +## `Benchmark.Deferred` +* [`Benchmark.Deferred`](#benchmarkdeferredclone) + + + + + + +## `Benchmark.Deferred.prototype` +* [`Benchmark.Deferred.prototype.benchmark`](#benchmarkdeferredprototypebenchmark) +* [`Benchmark.Deferred.prototype.cycles`](#benchmarkdeferredprototypecycles) +* [`Benchmark.Deferred.prototype.elapsed`](#benchmarkdeferredprototypeelapsed) +* [`Benchmark.Deferred.prototype.resolve`](#benchmarkdeferredprototyperesolve) +* [`Benchmark.Deferred.prototype.timeStamp`](#benchmarkdeferredprototypetimestamp) + + + + + + +## `Benchmark.Event` +* [`Benchmark.Event`](#benchmarkeventtype) + + + + + + +## `Benchmark.Event.prototype` +* [`Benchmark.Event.prototype.aborted`](#benchmarkeventprototypeaborted) +* [`Benchmark.Event.prototype.cancelled`](#benchmarkeventprototypecancelled) +* [`Benchmark.Event.prototype.result`](#benchmarkeventprototyperesult) +* [`Benchmark.Event.prototype.timeStamp`](#benchmarkeventprototypetimestamp) +* [`Benchmark.Event.prototype.type`](#benchmarkeventprototypetype) + + + + + + +## `Benchmark.Event.prototype.currentTarget` +* [`Benchmark.Event.prototype.currentTarget`](#benchmarkeventprototypecurrenttarget) + + + + + + +## `Benchmark.Event.prototype.target` +* [`Benchmark.Event.prototype.target`](#benchmarkeventprototypetarget) + + + + + + +## `Benchmark.Suite` +* [`Benchmark.Suite`](#benchmarksuitename--options) + + + + + + +## `Benchmark.Suite.prototype` +* [`Benchmark.Suite.prototype.aborted`](#benchmarksuiteprototypeaborted) +* [`Benchmark.Suite.prototype.length`](#benchmarksuiteprototypelength) +* [`Benchmark.Suite.prototype.running`](#benchmarksuiteprototyperunning) +* [`Benchmark.Suite.prototype.abort`](#benchmarksuiteprototypeabort) +* [`Benchmark.Suite.prototype.add`](#benchmarksuiteprototypeaddname-fn--options) +* [`Benchmark.Suite.prototype.clone`](#benchmarksuiteprototypecloneoptions) +* [`Benchmark.Suite.prototype.emit`](#benchmarkprototypeemittype) +* [`Benchmark.Suite.prototype.filter`](#benchmarksuiteprototypefiltercallback) +* [`Benchmark.Suite.prototype.forEach`](#benchmarksuiteprototypeforeachcallback) +* [`Benchmark.Suite.prototype.indexOf`](#benchmarksuiteprototypeindexofvalue) +* [`Benchmark.Suite.prototype.invoke`](#benchmarksuiteprototypeinvokename--arg1-arg2-) +* [`Benchmark.Suite.prototype.join`](#benchmarksuiteprototypejoinseparator-) +* [`Benchmark.Suite.prototype.listeners`](#benchmarkprototypelistenerstype) +* [`Benchmark.Suite.prototype.map`](#benchmarksuiteprototypemapcallback) +* [`Benchmark.Suite.prototype.off`](#benchmarkprototypeofftype-listener) +* [`Benchmark.Suite.prototype.on`](#benchmarkprototypeontype-listener) +* [`Benchmark.Suite.prototype.pluck`](#benchmarksuiteprototypepluckproperty) +* [`Benchmark.Suite.prototype.pop`](#benchmarksuiteprototypepop) +* [`Benchmark.Suite.prototype.push`](#benchmarksuiteprototypepush) +* [`Benchmark.Suite.prototype.reduce`](#benchmarksuiteprototypereducecallback-accumulator) +* [`Benchmark.Suite.prototype.reset`](#benchmarksuiteprototypereset) +* [`Benchmark.Suite.prototype.reverse`](#benchmarksuiteprototypereverse) +* [`Benchmark.Suite.prototype.run`](#benchmarksuiteprototyperunoptions) +* [`Benchmark.Suite.prototype.shift`](#benchmarksuiteprototypeshift) +* [`Benchmark.Suite.prototype.slice`](#benchmarksuiteprototypeslicestart-end) +* [`Benchmark.Suite.prototype.sort`](#benchmarksuiteprototypesortcomparefnnull) +* [`Benchmark.Suite.prototype.splice`](#benchmarksuiteprototypesplicestart-deletecount--val1-val2-) +* [`Benchmark.Suite.prototype.unshift`](#benchmarksuiteprototypeunshift) + + + + + + +## `Benchmark.Suite.options` +* [`Benchmark.Suite.options`](#benchmarksuiteoptions) +* [`Benchmark.Suite.options.name`](#benchmarksuiteoptionsname) + + + + + + + + + + + + +## `Benchmark` + + + +### `Benchmark(name, fn [, options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L404 "View in source") [Ⓣ][1] + +The Benchmark constructor. + +#### Arguments +1. `name` *(String)*: A name to identify the benchmark. +2. `fn` *(Function|String)*: The test to benchmark. +3. `[options={}]` *(Object)*: Options object. + +#### Example +~~~ js +// basic usage (the `new` operator is optional) +var bench = new Benchmark(fn); + +// or using a name first +var bench = new Benchmark('foo', fn); + +// or with options +var bench = new Benchmark('foo', fn, { + + // displayed by Benchmark#toString if `name` is not available + 'id': 'xyz', + + // called when the benchmark starts running + 'onStart': onStart, + + // called after each run cycle + 'onCycle': onCycle, + + // called when aborted + 'onAbort': onAbort, + + // called when a test errors + 'onError': onError, + + // called when reset + 'onReset': onReset, + + // called when the benchmark completes running + 'onComplete': onComplete, + + // compiled/called before the test loop + 'setup': setup, + + // compiled/called after the test loop + 'teardown': teardown +}); + +// or name and options +var bench = new Benchmark('foo', { + + // a flag to indicate the benchmark is deferred + 'defer': true, + + // benchmark test function + 'fn': function(deferred) { + // call resolve() when the deferred test is finished + deferred.resolve(); + } +}); + +// or options only +var bench = new Benchmark({ + + // benchmark name + 'name': 'foo', + + // benchmark test as a string + 'fn': '[1,2,3,4].sort()' +}); + +// a test's `this` binding is set to the benchmark instance +var bench = new Benchmark('foo', function() { + 'My name is '.concat(this.name); // My name is foo +}); +~~~ + +* * * + + + + + + +### `Benchmark.version` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3267 "View in source") [Ⓣ][1] + +*(String)*: The semantic version number. + +* * * + + + + + + +### `Benchmark.deepClone(value)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1225 "View in source") [Ⓣ][1] + +A deep clone utility. + +#### Arguments +1. `value` *(Mixed)*: The value to clone. + +#### Returns +*(Mixed)*: The cloned value. + +* * * + + + + + + +### `Benchmark.each(object, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1400 "View in source") [Ⓣ][1] + +An iteration utility for arrays and objects. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `object` *(Array|Object)*: The object to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array, Object)*: Returns the object iterated over. + +* * * + + + + + + +### `Benchmark.extend(destination [, source={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1446 "View in source") [Ⓣ][1] + +Copies enumerable properties from the source(s) object to the destination object. + +#### Arguments +1. `destination` *(Object)*: The destination object. +2. `[source={}]` *(Object)*: The source object. + +#### Returns +*(Object)*: The destination object. + +* * * + + + + + + +### `Benchmark.filter(array, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1485 "View in source") [Ⓣ][1] + +A generic `Array#filter` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function|String)*: The function/alias called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array)*: A new array of values that passed callback filter. + +#### Example +~~~ js +// get odd numbers +Benchmark.filter([1, 2, 3, 4, 5], function(n) { + return n % 2; +}); // -> [1, 3, 5]; + +// get fastest benchmarks +Benchmark.filter(benches, 'fastest'); + +// get slowest benchmarks +Benchmark.filter(benches, 'slowest'); + +// get benchmarks that completed without erroring +Benchmark.filter(benches, 'successful'); +~~~ + +* * * + + + + + + +### `Benchmark.forEach(array, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1518 "View in source") [Ⓣ][1] + +A generic `Array#forEach` like method. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array)*: Returns the array iterated over. + +* * * + + + + + + +### `Benchmark.formatNumber(number)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1557 "View in source") [Ⓣ][1] + +Converts a number to a more readable comma-separated string representation. + +#### Arguments +1. `number` *(Number)*: The number to convert. + +#### Returns +*(String)*: The more readable string representation. + +* * * + + + + + + +### `Benchmark.forOwn(object, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1545 "View in source") [Ⓣ][1] + +Iterates over an object's own properties, executing the `callback` for each. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `object` *(Object)*: The object to iterate over. +2. `callback` *(Function)*: The function executed per own property. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Object)*: Returns the object iterated over. + +* * * + + + + + + +### `Benchmark.hasKey(object, key)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1572 "View in source") [Ⓣ][1] + +Checks if an object has the specified key as a direct property. + +#### Arguments +1. `object` *(Object)*: The object to check. +2. `key` *(String)*: The key to check for. + +#### Returns +*(Boolean)*: Returns `true` if key is a direct property, else `false`. + +* * * + + + + + + +### `Benchmark.indexOf(array, value [, fromIndex=0])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1608 "View in source") [Ⓣ][1] + +A generic `Array#indexOf` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `value` *(Mixed)*: The value to search for. +3. `[fromIndex=0]` *(Number)*: The index to start searching from. + +#### Returns +*(Number)*: The index of the matched value or `-1`. + +* * * + + + + + + +### `Benchmark.interpolate(string, object)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1630 "View in source") [Ⓣ][1] + +Modify a string by replacing named tokens with matching object property values. + +#### Arguments +1. `string` *(String)*: The string to modify. +2. `object` *(Object)*: The template object. + +#### Returns +*(String)*: The modified string. + +* * * + + + + + + +### `Benchmark.invoke(benches, name [, arg1, arg2, ...])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1677 "View in source") [Ⓣ][1] + +Invokes a method on all items in an array. + +#### Arguments +1. `benches` *(Array)*: Array of benchmarks to iterate over. +2. `name` *(String|Object)*: The name of the method to invoke OR options object. +3. `[arg1, arg2, ...]` *(Mixed)*: Arguments to invoke the method with. + +#### Returns +*(Array)*: A new array of values returned from each method invoked. + +#### Example +~~~ js +// invoke `reset` on all benchmarks +Benchmark.invoke(benches, 'reset'); + +// invoke `emit` with arguments +Benchmark.invoke(benches, 'emit', 'complete', listener); + +// invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks +Benchmark.invoke(benches, { + + // invoke the `run` method + 'name': 'run', + + // pass a single argument + 'args': true, + + // treat as queue, removing benchmarks from front of `benches` until empty + 'queued': true, + + // called before any benchmarks have been invoked. + 'onStart': onStart, + + // called between invoking benchmarks + 'onCycle': onCycle, + + // called after all benchmarks have been invoked. + 'onComplete': onComplete +}); +~~~ + +* * * + + + + + + +### `Benchmark.join(object [, separator1=',', separator2=': '])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1831 "View in source") [Ⓣ][1] + +Creates a string of joined array values or object key-value pairs. + +#### Arguments +1. `object` *(Array|Object)*: The object to operate on. +2. `[separator1=',']` *(String)*: The separator used between key-value pairs. +3. `[separator2=': ']` *(String)*: The separator used between keys and values. + +#### Returns +*(String)*: The joined result. + +* * * + + + + + + +### `Benchmark.map(array, callback, thisArg)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1853 "View in source") [Ⓣ][1] + +A generic `Array#map` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `thisArg` *(Mixed)*: The `this` binding for the callback. + +#### Returns +*(Array)*: A new array of values returned by the callback. + +* * * + + + + + + +### `Benchmark.pluck(array, property)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1869 "View in source") [Ⓣ][1] + +Retrieves the value of a specified property from all items in an array. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `property` *(String)*: The property to pluck. + +#### Returns +*(Array)*: A new array of property values. + +* * * + + + + + + +### `Benchmark.reduce(array, callback, accumulator)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1885 "View in source") [Ⓣ][1] + +A generic `Array#reduce` like method. + +#### Arguments +1. `array` *(Array)*: The array to iterate over. +2. `callback` *(Function)*: The function called per iteration. +3. `accumulator` *(Mixed)*: Initial value of the accumulator. + +#### Returns +*(Mixed)*: The accumulator. + +* * * + + + + + + + + + +## `Benchmark.prototype` + + + +### `Benchmark.prototype.aborted` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3377 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the benchmark is aborted. + +* * * + + + + + + +### `Benchmark.prototype.compiled` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3353 "View in source") [Ⓣ][1] + +*(Function, String)*: The compiled test function. + +* * * + + + + + + +### `Benchmark.prototype.count` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3329 "View in source") [Ⓣ][1] + +*(Number)*: The number of times a test was executed. + +* * * + + + + + + +### `Benchmark.prototype.cycles` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3337 "View in source") [Ⓣ][1] + +*(Number)*: The number of cycles performed while benchmarking. + +* * * + + + + + + +### `Benchmark.prototype.fn` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3369 "View in source") [Ⓣ][1] + +*(Function, String)*: The test to benchmark. + +* * * + + + + + + +### `Benchmark.prototype.hz` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3345 "View in source") [Ⓣ][1] + +*(Number)*: The number of executions per second. + +* * * + + + + + + +### `Benchmark.prototype.running` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3385 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the benchmark is running. + +* * * + + + + + + +### `Benchmark.prototype.setup` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3448 "View in source") [Ⓣ][1] + +*(Function, String)*: Compiled into the test and executed immediately **before** the test loop. + +#### Example +~~~ js +// basic usage +var bench = Benchmark({ + 'setup': function() { + var c = this.count, + element = document.getElementById('container'); + while (c--) { + element.appendChild(document.createElement('div')); + } + }, + 'fn': function() { + element.removeChild(element.lastChild); + } +}); + +// compiles to something like: +var c = this.count, + element = document.getElementById('container'); +while (c--) { + element.appendChild(document.createElement('div')); +} +var start = new Date; +while (count--) { + element.removeChild(element.lastChild); +} +var end = new Date - start; + +// or using strings +var bench = Benchmark({ + 'setup': '\ + var a = 0;\n\ + (function() {\n\ + (function() {\n\ + (function() {', + 'fn': 'a += 1;', + 'teardown': '\ + }())\n\ + }())\n\ + }())' +}); + +// compiles to something like: +var a = 0; +(function() { + (function() { + (function() { + var start = new Date; + while (count--) { + a += 1; + } + var end = new Date - start; + }()) + }()) +}()) +~~~ + +* * * + + + + + + +### `Benchmark.prototype.teardown` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3456 "View in source") [Ⓣ][1] + +*(Function, String)*: Compiled into the test and executed immediately **after** the test loop. + +* * * + + + + + + +### `Benchmark.prototype.abort()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2218 "View in source") [Ⓣ][1] + +Aborts the benchmark without recording times. + +#### Returns +*(Object)*: The benchmark instance. + +* * * + + + + + + +### `Benchmark.prototype.clone(options)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2257 "View in source") [Ⓣ][1] + +Creates a new benchmark using the same test and options. + +#### Arguments +1. `options` *(Object)*: Options object to overwrite cloned options. + +#### Returns +*(Object)*: The new benchmark instance. + +#### Example +~~~ js +var bizarro = bench.clone({ + 'name': 'doppelganger' +}); +~~~ + +* * * + + + + + + +### `Benchmark.prototype.compare(other)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2280 "View in source") [Ⓣ][1] + +Determines if a benchmark is faster than another. + +#### Arguments +1. `other` *(Object)*: The benchmark to compare. + +#### Returns +*(Number)*: Returns `-1` if slower, `1` if faster, and `0` if indeterminate. + +* * * + + + + + + +### `Benchmark.Suite.prototype.emit(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2095 "View in source") [Ⓣ][1] + +Executes all registered listeners of the specified event type. + +#### Arguments +1. `type` *(String|Object)*: The event type or object. + +#### Returns +*(Mixed)*: Returns the return value of the last listener executed. + +* * * + + + + + + +### `Benchmark.Suite.prototype.listeners(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2125 "View in source") [Ⓣ][1] + +Returns an array of event listeners for a given type that can be manipulated to add or remove listeners. + +#### Arguments +1. `type` *(String)*: The event type. + +#### Returns +*(Array)*: The listeners array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.off([type, listener])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2158 "View in source") [Ⓣ][1] + +Unregisters a listener for the specified event type(s), or unregisters all listeners for the specified event type(s), or unregisters all listeners for all event types. + +#### Arguments +1. `[type]` *(String)*: The event type. +2. `[listener]` *(Function)*: The function to unregister. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +~~~ js +// unregister a listener for an event type +bench.off('cycle', listener); + +// unregister a listener for multiple event types +bench.off('start cycle', listener); + +// unregister all listeners for an event type +bench.off('cycle'); + +// unregister all listeners for multiple event types +bench.off('start cycle complete'); + +// unregister all listeners for all event types +bench.off(); +~~~ + +* * * + + + + + + +### `Benchmark.Suite.prototype.on(type, listener)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2197 "View in source") [Ⓣ][1] + +Registers a listener for the specified event type(s). + +#### Arguments +1. `type` *(String)*: The event type. +2. `listener` *(Function)*: The function to register. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +~~~ js +// register a listener for an event type +bench.on('cycle', listener); + +// register a listener for multiple event types +bench.on('start cycle', listener); +~~~ + +* * * + + + + + + +### `Benchmark.prototype.reset()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2334 "View in source") [Ⓣ][1] + +Reset properties and abort if running. + +#### Returns +*(Object)*: The benchmark instance. + +* * * + + + + + + +### `Benchmark.prototype.run([options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3000 "View in source") [Ⓣ][1] + +Runs the benchmark. + +#### Arguments +1. `[options={}]` *(Object)*: Options object. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +~~~ js +// basic usage +bench.run(); + +// or with options +bench.run({ 'async': true }); +~~~ + +* * * + + + + + + +### `Benchmark.prototype.toString()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2405 "View in source") [Ⓣ][1] + +Displays relevant benchmark information when coerced to a string. + +#### Returns +*(String)*: A string representation of the benchmark instance. + +* * * + + + + + + + + + +## `Benchmark.options` + + + +### `Benchmark.options` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3049 "View in source") [Ⓣ][1] + +*(Object)*: The default options copied by benchmark instances. + +* * * + + + + + + +### `Benchmark.options.async` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3058 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate that benchmark cycles will execute asynchronously by default. + +* * * + + + + + + +### `Benchmark.options.defer` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3066 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate that the benchmark clock is deferred. + +* * * + + + + + + +### `Benchmark.options.delay` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3073 "View in source") [Ⓣ][1] + +*(Number)*: The delay between test cycles *(secs)*. + +* * * + + + + + + +### `Benchmark.options.id` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3082 "View in source") [Ⓣ][1] + +*(String)*: Displayed by Benchmark#toString when a `name` is not available *(auto-generated if absent)*. + +* * * + + + + + + +### `Benchmark.options.initCount` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3090 "View in source") [Ⓣ][1] + +*(Number)*: The default number of times to execute a test on a benchmark's first cycle. + +* * * + + + + + + +### `Benchmark.options.maxTime` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3099 "View in source") [Ⓣ][1] + +*(Number)*: The maximum time a benchmark is allowed to run before finishing *(secs)*. Note: Cycle delays aren't counted toward the maximum time. + +* * * + + + + + + +### `Benchmark.options.minSamples` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3107 "View in source") [Ⓣ][1] + +*(Number)*: The minimum sample size required to perform statistical analysis. + +* * * + + + + + + +### `Benchmark.options.minTime` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3115 "View in source") [Ⓣ][1] + +*(Number)*: The time needed to reduce the percent uncertainty of measurement to `1`% *(secs)*. + +* * * + + + + + + +### `Benchmark.options.name` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3123 "View in source") [Ⓣ][1] + +*(String)*: The name of the benchmark. + +* * * + + + + + + +### `Benchmark.options.onAbort` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3131 "View in source") [Ⓣ][1] + +An event listener called when the benchmark is aborted. + +* * * + + + + + + +### `Benchmark.options.onComplete` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3139 "View in source") [Ⓣ][1] + +An event listener called when the benchmark completes running. + +* * * + + + + + + +### `Benchmark.options.onCycle` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3147 "View in source") [Ⓣ][1] + +An event listener called after each run cycle. + +* * * + + + + + + +### `Benchmark.options.onError` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3155 "View in source") [Ⓣ][1] + +An event listener called when a test errors. + +* * * + + + + + + +### `Benchmark.options.onReset` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3163 "View in source") [Ⓣ][1] + +An event listener called when the benchmark is reset. + +* * * + + + + + + +### `Benchmark.options.onStart` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3171 "View in source") [Ⓣ][1] + +An event listener called when the benchmark starts running. + +* * * + + + + + + + + + +## `Benchmark.platform` + + + +### `Benchmark.platform` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3182 "View in source") [Ⓣ][1] + +*(Object)*: Platform object with properties describing things like browser name, version, and operating system. + +* * * + + + + + + +### `Benchmark.platform.description` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3190 "View in source") [Ⓣ][1] + +*(String)*: The platform description. + +* * * + + + + + + +### `Benchmark.platform.layout` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3198 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the browser layout engine. + +* * * + + + + + + +### `Benchmark.platform.manufacturer` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3222 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the product's manufacturer. + +* * * + + + + + + +### `Benchmark.platform.name` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3214 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the browser/environment. + +* * * + + + + + + +### `Benchmark.platform.os` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3230 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the operating system. + +* * * + + + + + + +### `Benchmark.platform.prerelease` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3238 "View in source") [Ⓣ][1] + +*(String, Null)*: The alpha/beta release indicator. + +* * * + + + + + + +### `Benchmark.platform.product` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3206 "View in source") [Ⓣ][1] + +*(String, Null)*: The name of the product hosting the browser. + +* * * + + + + + + +### `Benchmark.platform.version` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3246 "View in source") [Ⓣ][1] + +*(String, Null)*: The browser/environment version. + +* * * + + + + + + +### `Benchmark.platform.toString()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3255 "View in source") [Ⓣ][1] + +Return platform description when the platform object is coerced to a string. + +#### Returns +*(String)*: The platform description. + +* * * + + + + + + + + + +## `Benchmark.support` + + + +### `Benchmark.support` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L135 "View in source") [Ⓣ][1] + +*(Object)*: An object used to flag environments/features. + +* * * + + + + + + +### `Benchmark.support.air` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L145 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect Adobe AIR. + +* * * + + + + + + +### `Benchmark.support.argumentsClass` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L153 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if `arguments` objects have the correct internal [[Class]] value. + +* * * + + + + + + +### `Benchmark.support.browser` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L161 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if in a browser environment. + +* * * + + + + + + +### `Benchmark.support.charByIndex` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L169 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if strings support accessing characters by index. + +* * * + + + + + + +### `Benchmark.support.charByOwnIndex` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L179 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if strings have indexes as own properties. + +* * * + + + + + + +### `Benchmark.support.decompilation` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L207 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if functions support decompilation. + +* * * + + + + + + +### `Benchmark.support.descriptors` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L228 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect ES5+ property descriptor API. + +* * * + + + + + + +### `Benchmark.support.getAllKeys` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L242 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect ES5+ Object.getOwnPropertyNames(). + +* * * + + + + + + +### `Benchmark.support.iteratesOwnFirst` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L255 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if own properties are iterated before inherited properties *(all but IE < `9`)*. + +* * * + + + + + + +### `Benchmark.support.java` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L190 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if Java is enabled/exposed. + +* * * + + + + + + +### `Benchmark.support.nodeClass` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L272 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if a node's [[Class]] is resolvable *(all but IE < `9`)* and that the JS engine errors when attempting to coerce an object to a string without a `toString` property value of `typeof` "function". + +* * * + + + + + + +### `Benchmark.support.timeout` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L198 "View in source") [Ⓣ][1] + +*(Boolean)*: Detect if the Timers API exists. + +* * * + + + + + + + + + +## `Benchmark.prototype.error` + + + +### `Benchmark.prototype.error` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3361 "View in source") [Ⓣ][1] + +*(Object)*: The error object if the test failed. + +* * * + + + + + + + + + +## `Benchmark.prototype.stats` + + + +### `Benchmark.prototype.stats` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3464 "View in source") [Ⓣ][1] + +*(Object)*: An object of stats including mean, margin or error, and standard deviation. + +* * * + + + + + + +### `Benchmark.prototype.stats.deviation` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3496 "View in source") [Ⓣ][1] + +*(Number)*: The sample standard deviation. + +* * * + + + + + + +### `Benchmark.prototype.stats.mean` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3504 "View in source") [Ⓣ][1] + +*(Number)*: The sample arithmetic mean. + +* * * + + + + + + +### `Benchmark.prototype.stats.moe` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3472 "View in source") [Ⓣ][1] + +*(Number)*: The margin of error. + +* * * + + + + + + +### `Benchmark.prototype.stats.rme` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3480 "View in source") [Ⓣ][1] + +*(Number)*: The relative margin of error *(expressed as a percentage of the mean)*. + +* * * + + + + + + +### `Benchmark.prototype.stats.sample` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3512 "View in source") [Ⓣ][1] + +*(Array)*: The array of sampled periods. + +* * * + + + + + + +### `Benchmark.prototype.stats.sem` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3488 "View in source") [Ⓣ][1] + +*(Number)*: The standard error of the mean. + +* * * + + + + + + +### `Benchmark.prototype.stats.variance` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3520 "View in source") [Ⓣ][1] + +*(Number)*: The sample variance. + +* * * + + + + + + + + + +## `Benchmark.prototype.times` + + + +### `Benchmark.prototype.times` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3529 "View in source") [Ⓣ][1] + +*(Object)*: An object of timing data including cycle, elapsed, period, start, and stop. + +* * * + + + + + + +### `Benchmark.prototype.times.cycle` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3537 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to complete the last cycle *(secs)*. + +* * * + + + + + + +### `Benchmark.prototype.times.elapsed` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3545 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to complete the benchmark *(secs)*. + +* * * + + + + + + +### `Benchmark.prototype.times.period` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3553 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to execute the test once *(secs)*. + +* * * + + + + + + +### `Benchmark.prototype.times.timeStamp` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3561 "View in source") [Ⓣ][1] + +*(Number)*: A timestamp of when the benchmark started *(ms)*. + +* * * + + + + + + + + + +## `Benchmark.Deferred` + + + +### `Benchmark.Deferred(clone)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L445 "View in source") [Ⓣ][1] + +The Deferred constructor. + +#### Arguments +1. `clone` *(Object)*: The cloned benchmark instance. + +* * * + + + + + + + + + +## `Benchmark.Deferred.prototype` + + + +### `Benchmark.Deferred.prototype.benchmark` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3605 "View in source") [Ⓣ][1] + +*(Object)*: The deferred benchmark instance. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.cycles` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3613 "View in source") [Ⓣ][1] + +*(Number)*: The number of deferred cycles performed while benchmarking. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.elapsed` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3621 "View in source") [Ⓣ][1] + +*(Number)*: The time taken to complete the deferred benchmark *(secs)*. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.resolve` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1188 "View in source") [Ⓣ][1] + +*(Unknown)*: Handles cycling/completing the deferred benchmark. + +* * * + + + + + + +### `Benchmark.Deferred.prototype.timeStamp` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3629 "View in source") [Ⓣ][1] + +*(Number)*: A timestamp of when the deferred benchmark started *(ms)*. + +* * * + + + + + + + + + +## `Benchmark.Event` + + + +### `Benchmark.Event(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L461 "View in source") [Ⓣ][1] + +The Event constructor. + +#### Arguments +1. `type` *(String|Object)*: The event type. + +* * * + + + + + + + + + +## `Benchmark.Event.prototype` + + + +### `Benchmark.Event.prototype.aborted` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3645 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the emitters listener iteration is aborted. + +* * * + + + + + + +### `Benchmark.Event.prototype.cancelled` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3653 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the default action is cancelled. + +* * * + + + + + + +### `Benchmark.Event.prototype.result` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3669 "View in source") [Ⓣ][1] + +*(Mixed)*: The return value of the last executed listener. + +* * * + + + + + + +### `Benchmark.Event.prototype.timeStamp` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3685 "View in source") [Ⓣ][1] + +*(Number)*: A timestamp of when the event was created *(ms)*. + +* * * + + + + + + +### `Benchmark.Event.prototype.type` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3693 "View in source") [Ⓣ][1] + +*(String)*: The event type. + +* * * + + + + + + + + + +## `Benchmark.Event.prototype.currentTarget` + + + +### `Benchmark.Event.prototype.currentTarget` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3661 "View in source") [Ⓣ][1] + +*(Object)*: The object whose listeners are currently being processed. + +* * * + + + + + + + + + +## `Benchmark.Event.prototype.target` + + + +### `Benchmark.Event.prototype.target` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3677 "View in source") [Ⓣ][1] + +*(Object)*: The object to which the event was originally emitted. + +* * * + + + + + + + + + +## `Benchmark.Suite` + + + +### `Benchmark.Suite(name [, options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L507 "View in source") [Ⓣ][1] + +The Suite constructor. + +#### Arguments +1. `name` *(String)*: A name to identify the suite. +2. `[options={}]` *(Object)*: Options object. + +#### Example +~~~ js +// basic usage (the `new` operator is optional) +var suite = new Benchmark.Suite; + +// or using a name first +var suite = new Benchmark.Suite('foo'); + +// or with options +var suite = new Benchmark.Suite('foo', { + + // called when the suite starts running + 'onStart': onStart, + + // called between running benchmarks + 'onCycle': onCycle, + + // called when aborted + 'onAbort': onAbort, + + // called when a test errors + 'onError': onError, + + // called when reset + 'onReset': onReset, + + // called when the suite completes running + 'onComplete': onComplete +}); +~~~ + +* * * + + + + + + + + + +## `Benchmark.Suite.prototype` + + + +### `Benchmark.Suite.prototype.aborted` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3734 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the suite is aborted. + +* * * + + + + + + +### `Benchmark.Suite.prototype.length` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3726 "View in source") [Ⓣ][1] + +*(Number)*: The number of benchmarks in the suite. + +* * * + + + + + + +### `Benchmark.Suite.prototype.running` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3742 "View in source") [Ⓣ][1] + +*(Boolean)*: A flag to indicate if the suite is running. + +* * * + + + + + + +### `Benchmark.Suite.prototype.abort()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1902 "View in source") [Ⓣ][1] + +Aborts all benchmarks in the suite. + +#### Returns +*(Object)*: The suite instance. + +* * * + + + + + + +### `Benchmark.Suite.prototype.add(name, fn [, options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1962 "View in source") [Ⓣ][1] + +Adds a test to the benchmark suite. + +#### Arguments +1. `name` *(String)*: A name to identify the benchmark. +2. `fn` *(Function|String)*: The test to benchmark. +3. `[options={}]` *(Object)*: Options object. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +~~~ js +// basic usage +suite.add(fn); + +// or using a name first +suite.add('foo', fn); + +// or with options +suite.add('foo', fn, { + 'onCycle': onCycle, + 'onComplete': onComplete +}); + +// or name and options +suite.add('foo', { + 'fn': fn, + 'onCycle': onCycle, + 'onComplete': onComplete +}); + +// or options only +suite.add({ + 'name': 'foo', + 'fn': fn, + 'onCycle': onCycle, + 'onComplete': onComplete +}); +~~~ + +* * * + + + + + + +### `Benchmark.Suite.prototype.clone(options)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1981 "View in source") [Ⓣ][1] + +Creates a new suite with cloned benchmarks. + +#### Arguments +1. `options` *(Object)*: Options object to overwrite cloned options. + +#### Returns +*(Object)*: The new suite instance. + +* * * + + + + + + +### `Benchmark.Suite.prototype.emit(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2095 "View in source") [Ⓣ][1] + +Executes all registered listeners of the specified event type. + +#### Arguments +1. `type` *(String|Object)*: The event type or object. + +#### Returns +*(Mixed)*: Returns the return value of the last listener executed. + +* * * + + + + + + +### `Benchmark.Suite.prototype.filter(callback)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2004 "View in source") [Ⓣ][1] + +An `Array#filter` like method. + +#### Arguments +1. `callback` *(Function|String)*: The function/alias called per iteration. + +#### Returns +*(Object)*: A new suite of benchmarks that passed callback filter. + +* * * + + + + + + +### `Benchmark.Suite.prototype.forEach(callback)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3752 "View in source") [Ⓣ][1] + +An `Array#forEach` like method. Callbacks may terminate the loop by explicitly returning `false`. + +#### Arguments +1. `callback` *(Function)*: The function called per iteration. + +#### Returns +*(Object)*: The suite iterated over. + +* * * + + + + + + +### `Benchmark.Suite.prototype.indexOf(value)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3761 "View in source") [Ⓣ][1] + +An `Array#indexOf` like method. + +#### Arguments +1. `value` *(Mixed)*: The value to search for. + +#### Returns +*(Number)*: The index of the matched value or `-1`. + +* * * + + + + + + +### `Benchmark.Suite.prototype.invoke(name [, arg1, arg2, ...])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3771 "View in source") [Ⓣ][1] + +Invokes a method on all benchmarks in the suite. + +#### Arguments +1. `name` *(String|Object)*: The name of the method to invoke OR options object. +2. `[arg1, arg2, ...]` *(Mixed)*: Arguments to invoke the method with. + +#### Returns +*(Array)*: A new array of values returned from each method invoked. + +* * * + + + + + + +### `Benchmark.Suite.prototype.join([separator=','])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3780 "View in source") [Ⓣ][1] + +Converts the suite of benchmarks to a string. + +#### Arguments +1. `[separator=',']` *(String)*: A string to separate each element of the array. + +#### Returns +*(String)*: The string. + +* * * + + + + + + +### `Benchmark.Suite.prototype.listeners(type)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2125 "View in source") [Ⓣ][1] + +Returns an array of event listeners for a given type that can be manipulated to add or remove listeners. + +#### Arguments +1. `type` *(String)*: The event type. + +#### Returns +*(Array)*: The listeners array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.map(callback)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3789 "View in source") [Ⓣ][1] + +An `Array#map` like method. + +#### Arguments +1. `callback` *(Function)*: The function called per iteration. + +#### Returns +*(Array)*: A new array of values returned by the callback. + +* * * + + + + + + +### `Benchmark.Suite.prototype.off([type, listener])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2158 "View in source") [Ⓣ][1] + +Unregisters a listener for the specified event type(s), or unregisters all listeners for the specified event type(s), or unregisters all listeners for all event types. + +#### Arguments +1. `[type]` *(String)*: The event type. +2. `[listener]` *(Function)*: The function to unregister. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +~~~ js +// unregister a listener for an event type +bench.off('cycle', listener); + +// unregister a listener for multiple event types +bench.off('start cycle', listener); + +// unregister all listeners for an event type +bench.off('cycle'); + +// unregister all listeners for multiple event types +bench.off('start cycle complete'); + +// unregister all listeners for all event types +bench.off(); +~~~ + +* * * + + + + + + +### `Benchmark.Suite.prototype.on(type, listener)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2197 "View in source") [Ⓣ][1] + +Registers a listener for the specified event type(s). + +#### Arguments +1. `type` *(String)*: The event type. +2. `listener` *(Function)*: The function to register. + +#### Returns +*(Object)*: The benchmark instance. + +#### Example +~~~ js +// register a listener for an event type +bench.on('cycle', listener); + +// register a listener for multiple event types +bench.on('start cycle', listener); +~~~ + +* * * + + + + + + +### `Benchmark.Suite.prototype.pluck(property)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3798 "View in source") [Ⓣ][1] + +Retrieves the value of a specified property from all benchmarks in the suite. + +#### Arguments +1. `property` *(String)*: The property to pluck. + +#### Returns +*(Array)*: A new array of property values. + +* * * + + + + + + +### `Benchmark.Suite.prototype.pop()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3806 "View in source") [Ⓣ][1] + +Removes the last benchmark from the suite and returns it. + +#### Returns +*(Mixed)*: The removed benchmark. + +* * * + + + + + + +### `Benchmark.Suite.prototype.push()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3814 "View in source") [Ⓣ][1] + +Appends benchmarks to the suite. + +#### Returns +*(Number)*: The suite's new length. + +* * * + + + + + + +### `Benchmark.Suite.prototype.reduce(callback, accumulator)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3833 "View in source") [Ⓣ][1] + +An `Array#reduce` like method. + +#### Arguments +1. `callback` *(Function)*: The function called per iteration. +2. `accumulator` *(Mixed)*: Initial value of the accumulator. + +#### Returns +*(Mixed)*: The accumulator. + +* * * + + + + + + +### `Benchmark.Suite.prototype.reset()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2019 "View in source") [Ⓣ][1] + +Resets all benchmarks in the suite. + +#### Returns +*(Object)*: The suite instance. + +* * * + + + + + + +### `Benchmark.Suite.prototype.reverse()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L638 "View in source") [Ⓣ][1] + +Rearrange the host array's elements in reverse order. + +#### Returns +*(Array)*: The reversed array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.run([options={}])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L2056 "View in source") [Ⓣ][1] + +Runs the suite. + +#### Arguments +1. `[options={}]` *(Object)*: Options object. + +#### Returns +*(Object)*: The suite instance. + +#### Example +~~~ js +// basic usage +suite.run(); + +// or with options +suite.run({ 'async': true, 'queued': true }); +~~~ + +* * * + + + + + + +### `Benchmark.Suite.prototype.shift()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L671 "View in source") [Ⓣ][1] + +Removes the first element of the host array and returns it. + +#### Returns +*(Mixed)*: The first element of the array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.slice(start, end)` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L684 "View in source") [Ⓣ][1] + +Creates an array of the host array's elements from the start index up to, but not including, the end index. + +#### Arguments +1. `start` *(Number)*: The starting index. +2. `end` *(Number)*: The end index. + +#### Returns +*(Array)*: The new array. + +* * * + + + + + + +### `Benchmark.Suite.prototype.sort([compareFn=null])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3823 "View in source") [Ⓣ][1] + +Sorts the benchmarks of the suite. + +#### Arguments +1. `[compareFn=null]` *(Function)*: A function that defines the sort order. + +#### Returns +*(Object)*: The sorted suite. + +* * * + + + + + + +### `Benchmark.Suite.prototype.splice(start, deleteCount [, val1, val2, ...])` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L714 "View in source") [Ⓣ][1] + +Allows removing a range of elements and/or inserting elements into the host array. + +#### Arguments +1. `start` *(Number)*: The start index. +2. `deleteCount` *(Number)*: The number of elements to delete. +3. `[val1, val2, ...]` *(Mixed)*: values to insert at the `start` index. + +#### Returns +*(Array)*: An array of removed elements. + +* * * + + + + + + +### `Benchmark.Suite.prototype.unshift()` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L749 "View in source") [Ⓣ][1] + +Appends arguments to the host array. + +#### Returns +*(Number)*: The new length. + +* * * + + + + + + + + + +## `Benchmark.Suite.options` + + + +### `Benchmark.Suite.options` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3705 "View in source") [Ⓣ][1] + +*(Object)*: The default options copied by suite instances. + +* * * + + + + + + +### `Benchmark.Suite.options.name` +# [Ⓢ](https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L3713 "View in source") [Ⓣ][1] + +*(String)*: The name of the suite. + +* * * + + + + + + + + + + + [1]: #Benchmark "Jump back to the TOC." \ No newline at end of file diff --git a/node_modules/benchmark/package.json b/node_modules/benchmark/package.json new file mode 100644 index 0000000..013f7e9 --- /dev/null +++ b/node_modules/benchmark/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "benchmark@1.0.0", + "scope": null, + "escapedName": "benchmark", + "name": "benchmark", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-adapter\\node_modules\\socket.io-parser" + ] + ], + "_from": "benchmark@1.0.0", + "_id": "benchmark@1.0.0", + "_inCache": true, + "_installable": true, + "_location": "/benchmark", + "_phantomChildren": {}, + "_requested": { + "raw": "benchmark@1.0.0", + "scope": null, + "escapedName": "benchmark", + "name": "benchmark", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "_requiredBy": [ + "/socket.io-adapter/socket.io-parser", + "/socket.io-parser" + ], + "_resolved": "https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz", + "_shasum": "2f1e2fa4c359f11122aa183082218e957e390c73", + "_shrinkwrap": null, + "_spec": "benchmark@1.0.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-adapter\\node_modules\\socket.io-parser", + "author": { + "name": "Mathias Bynens", + "email": "mathias@benchmarkjs.com", + "url": "http://mathiasbynens.be/" + }, + "bugs": { + "url": "https://github.com/bestiejs/benchmark.js/issues", + "email": "bugs@benchmarkjs.com" + }, + "dependencies": {}, + "description": "A benchmarking library that works on nearly all JavaScript platforms, supports high-resolution timers, and returns statistically significant results.", + "devDependencies": {}, + "directories": { + "doc": "./doc", + "test": "./test" + }, + "dist": { + "shasum": "2f1e2fa4c359f11122aa183082218e957e390c73", + "tarball": "https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz" + }, + "engines": [ + "node", + "rhino" + ], + "homepage": "http://benchmarkjs.com/", + "keywords": [ + "benchmark", + "narwhal", + "node", + "performance", + "ringo", + "speed" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://mths.be/mit" + } + ], + "main": "benchmark", + "maintainers": [ + { + "name": "jdalton", + "email": "john@fusejs.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + } + ], + "name": "benchmark", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/bestiejs/benchmark.js.git" + }, + "version": "1.0.0" +} diff --git a/node_modules/benchmark/test/run-test.sh b/node_modules/benchmark/test/run-test.sh new file mode 100644 index 0000000..43424e4 --- /dev/null +++ b/node_modules/benchmark/test/run-test.sh @@ -0,0 +1,9 @@ +cd "$(dirname "$0")" +for cmd in rhino ringo narwhal node; do + echo "" + echo "Testing in $cmd..." + $cmd test.js +done +echo "" +echo "Testing in a browser..." +open index.html diff --git a/node_modules/benchmark/test/test.js b/node_modules/benchmark/test/test.js new file mode 100644 index 0000000..d694494 --- /dev/null +++ b/node_modules/benchmark/test/test.js @@ -0,0 +1,2074 @@ +;(function(window, undefined) { + 'use strict'; + + /** Use a single load function */ + var load = typeof require == 'function' ? require : window.load; + + /** The `platform` object to check */ + var platform = + window.platform || + load('../vendor/platform.js/platform.js') || + window.platform; + + /** The unit testing framework */ + var QUnit = + window.QUnit || ( + window.setTimeout || (window.addEventListener = window.setTimeout = / /), + window.QUnit = load('../vendor/qunit/qunit/qunit' + (platform.name == 'Narwhal' ? '-1.8.0' : '') + '.js') || window.QUnit, + load('../vendor/qunit-clib/qunit-clib.js'), + (window.addEventListener || 0).test && delete window.addEventListener, + window.QUnit + ); + + /** The `Benchmark` constructor to test */ + var Benchmark = + window.Benchmark || ( + Benchmark = load('../benchmark.js') || window.Benchmark, + Benchmark.Benchmark || Benchmark + ); + + /** API shortcut */ + var forOwn = Benchmark.forOwn; + + /** Used to get property descriptors */ + var getDescriptor = Object.getOwnPropertyDescriptor; + + /** Used to set property descriptors */ + var setDescriptor = Object.defineProperty; + + /** Shortcut used to convert array-like objects to arrays */ + var slice = [].slice; + + /** Used to resolve a value's internal [[Class]] */ + var toString = {}.toString; + + /** Used to check problem JScript properties (a.k.a. the [[DontEnum]] bug) */ + var shadowed = { + 'constructor': 1, + 'hasOwnProperty': 2, + 'isPrototypeOf': 3, + 'propertyIsEnumerable': 4, + 'toLocaleString': 5, + 'toString': 6, + 'valueOf': 7 + }; + + /** Used to flag environments/features */ + var support = { + 'descriptors': !!function() { + try { + var o = {}; + return (setDescriptor(o, o, o), 'value' in getDescriptor(o, o)); + } catch(e) { } + }() + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Skips a given number of tests with a passing result. + * + * @private + * @param {Number} [count=1] The number of tests to skip. + */ + function skipTest(count) { + count || (count = 1); + while (count--) { + ok(true, 'test skipped'); + } + } + + /*--------------------------------------------------------------------------*/ + + // init Benchmark.options.minTime + Benchmark(function() { throw 0; }).run(); + + // set a shorter max time + Benchmark.options.maxTime = Benchmark.options.minTime * 5; + + // explicitly call `QUnit.module()` instead of `module()` + // in case we are in a CLI environment + QUnit.module('Benchmark'); + + (function() { + test('has the default `Benchmark.platform` value', function() { + if (window.document) { + equal(String(Benchmark.platform), navigator.userAgent); + } else { + skipTest(1) + } + }); + + test('supports loading Benchmark.js as a module', function() { + if (window.document && window.require) { + equal((Benchmark2 || {}).version, Benchmark.version); + } else { + skipTest(1) + } + }); + + test('supports loading Platform.js as a module', function() { + if (window.document && window.require) { + var platform = (Benchmark2 || {}).platform || {}; + equal(typeof platform.name, 'string'); + } else { + skipTest(1) + } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark constructor'); + + (function() { + test('creates a new instance when called without the `new` operator', function() { + ok(Benchmark() instanceof Benchmark); + }); + + test('supports passing an options object', function() { + var bench = Benchmark({ 'name': 'foo', 'fn': function() { } }); + ok(bench.fn && bench.name == 'foo'); + }); + + test('supports passing a "name" and "fn" argument', function() { + var bench = Benchmark('foo', function() { }); + ok(bench.fn && bench.name == 'foo'); + }); + + test('supports passing a "name" argument and an options object', function() { + var bench = Benchmark('foo', { 'fn': function() { } }); + ok(bench.fn && bench.name == 'foo'); + }); + + test('supports passing a "name" argument and an options object', function() { + var bench = Benchmark('foo', function() { }, { 'id': 'bar' }); + ok(bench.fn && bench.name == 'foo' && bench.id == 'bar'); + }); + + test('supports passing an empy string for the "fn" options property', function() { + var bench = Benchmark({ 'fn': '' }).run(); + ok(!bench.error); + }); + + test('detects dead code', function() { + var bench = Benchmark(function() { }).run(); + ok(/setup\(\)/.test(bench.compiled) ? !bench.error : bench.error); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark compilation'); + + (function() { + test('compiles using the default `Function#toString`', function() { + var bench = Benchmark({ + 'setup': function() { var a = 1; }, + 'fn': function() { throw a; }, + 'teardown': function() { a = 2; } + }).run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(); + } + else { + ok(/var a\s*=\s*1/.test(compiled) && /throw a/.test(compiled) && /a\s*=\s*2/.test(compiled)); + } + }); + + test('compiles using a custom "toString" method', function() { + var bench = Benchmark({ + 'setup': function() { }, + 'fn': function() { }, + 'teardown': function() { } + }); + + bench.setup.toString = function() { return 'var a = 1;' }; + bench.fn.toString = function() { return 'throw a;' }; + bench.teardown.toString = function() { return 'a = 2;' }; + bench.run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(); + } + else { + ok(/var a\s*=\s*1/.test(compiled) && /throw a/.test(compiled) && /a\s*=\s*2/.test(compiled)); + } + }); + + test('compiles using a string value', function() { + var bench = Benchmark({ + 'setup': 'var a = 1;', + 'fn': 'throw a;', + 'teardown': 'a = 2;' + }).run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(); + } + else { + ok(/var a\s*=\s*1/.test(compiled) && /throw a/.test(compiled) && /a\s*=\s*2/.test(compiled)); + } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark test binding'); + + (function() { + var count = 0; + + var tests = { + 'inlined "setup", "fn", and "teardown"': ( + 'if(/ops/.test(this))this._fn=true;' + ), + 'called "fn" and inlined "setup"/"teardown" reached by error': function() { + count++; + if (/ops/.test(this)) { + this._fn = true; + } + }, + 'called "fn" and inlined "setup"/"teardown" reached by `return` statement': function() { + if (/ops/.test(this)) { + this._fn = true; + } + return; + } + }; + + forOwn(tests, function(fn, title) { + test('has correct binding for ' + title, function() { + var bench = Benchmark({ + 'setup': 'if(/ops/.test(this))this._setup=true;', + 'fn': fn, + 'teardown': 'if(/ops/.test(this))this._teardown=true;', + 'onCycle': function() { this.abort(); } + }).run(); + + var compiled = bench.compiled; + if (/setup\(\)/.test(compiled)) { + skipTest(3); + } + else { + ok(bench._setup, 'correct binding for "setup"'); + ok(bench._fn, 'correct binding for "fn"'); + ok(bench._teardown, 'correct binding for "teardown"'); + } + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.deepClone'); + + (function() { + function createCircularObject() { + var result = { + 'foo': { 'b': { 'foo': { 'c': { } } } }, + 'bar': { } + }; + + result.foo.b.foo.c.foo = result; + result.bar.b = result.foo.b; + return result; + } + + function Klass() { + this.a = 1; + } + + Klass.prototype = { 'b': 1 }; + + var notCloneable = { + 'an arguments object': arguments, + 'an element': window.document && document.body, + 'a function': Klass, + 'a Klass instance': new Klass + }; + + var objects = { + 'an array': ['a', 'b', 'c', ''], + 'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 }, + 'boolean': false, + 'boolean object': Object(false), + 'an object': { 'a': 0, 'b': 1, 'c': 3 }, + 'an object with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } }, + 'null': null, + 'a number': 3, + 'a number object': Object(3), + 'a regexp': /x/gim, + 'a string': 'x', + 'a string object': Object('x'), + 'undefined': undefined + }; + + objects['an array'].length = 5; + + forOwn(objects, function(object, key) { + test('clones ' + key + ' correctly', function() { + var kind = toString.call(object), + clone = Benchmark.deepClone(object); + + if (object == null) { + equal(clone, object); + } else { + deepEqual(clone.valueOf(), object.valueOf()); + } + if (object === Object(object)) { + ok(clone !== object); + } else { + skipTest(); + } + }); + }); + + forOwn(notCloneable, function(object, key) { + test('does not clone ' + key, function() { + ok(Benchmark.deepClone(object) === object); + }); + }); + + test('clones using Klass#deepClone', function() { + var object = new Klass; + Klass.prototype.deepClone = function() { return new Klass; }; + + var clone = Benchmark.deepClone(object); + ok(clone !== object && clone instanceof Klass); + + delete Klass.prototype.clone; + }); + + test('clones problem JScript properties', function() { + var clone = Benchmark.deepClone(shadowed); + deepEqual(clone, shadowed); + }); + + test('clones string object with custom property', function() { + var object = new String('x'); + object.x = 1; + + var clone = Benchmark.deepClone(object); + ok(clone == 'x' && typeof clone == 'object' && clone.x === 1 && toString.call(clone) == '[object String]'); + }); + + test('clones objects with circular references', function() { + var object = createCircularObject(), + clone = Benchmark.deepClone(object); + + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + }); + + test('clones non-extensible objects with circular references', function() { + if (Object.preventExtensions) { + var object = Object.preventExtensions(createCircularObject()); + Object.preventExtensions(object.bar.b); + + var clone = Benchmark.deepClone(object); + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + } else { + skipTest(1) + } + }); + + test('clones sealed objects with circular references', function() { + if (Object.seal) { + var object = Object.seal(createCircularObject()); + Object.seal(object.bar.b); + + var clone = Benchmark.deepClone(object); + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + } else { + skipTest(1) + } + }); + + test('clones frozen objects with circular references', function() { + if (Object.freeze) { + var object = Object.freeze(createCircularObject()); + Object.freeze(object.bar.b); + + var clone = Benchmark.deepClone(object); + ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.foo.c.foo && clone !== object); + } else { + skipTest(1) + } + }); + + test('clones objects with custom descriptors and circular references', function() { + var accessor, + descriptor; + + if (support.descriptors) { + var object = setDescriptor({}, 'foo', { + 'configurable': true, + 'value': setDescriptor({}, 'b', { + 'writable': true, + 'value': setDescriptor({}, 'foo', { + 'get': function() { return accessor; }, + 'set': function(value) { accessor = value; } + }) + }) + }); + + setDescriptor(object, 'bar', { 'value': {} }); + object.foo.b.foo = { 'c': object }; + object.bar.b = object.foo.b; + + var clone = Benchmark.deepClone(object); + ok(clone !== object && + clone.bar.b === clone.foo.b && + clone !== clone.foo.b.foo.c.foo && + (descriptor = getDescriptor(clone, 'foo')) && + descriptor.configurable && !(descriptor.enumerable && descriptor.writable) && + (descriptor = getDescriptor(clone.foo, 'b')) && + descriptor.writable && !(descriptor.configurable && descriptor.enumerable) && + (descriptor = getDescriptor(clone.foo.b, 'foo')) && + descriptor.get && descriptor.set && + (descriptor = getDescriptor(clone.foo.b, 'foo')) && + !(descriptor.configurable && descriptor.enumerable && descriptor.writable) && + (descriptor = getDescriptor(clone, 'bar')) && + !(descriptor.configurable && descriptor.enumerable && descriptor.writable)); + } + else { + skipTest(1) + } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.each'); + + (function() { + var xpathResult; + + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 }, + 'xpath snapshot': null + }; + + if (window.document && document.evaluate) { + xpathResult = [document.documentElement, document.getElementsByTagName('head')[0], document.body]; + objects['xpath snapshot'] = document.evaluate('//*[self::html or self::head or self::body]', document, null, 7, null); + } + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + if (object) { + var args + Benchmark.each(object, function() { + args || (args = slice.call(arguments)); + }); + + if (key == 'xpath snapshot') { + ok(args[0] === xpathResult[0]); + } else { + equal(args[0], 'a'); + } + equal(args[1], 0); + ok(args[2] === object); + } + else { + skipTest(3); + } + }); + + test('returns the passed object when passing an ' + key, function() { + if (object) { + var actual = Benchmark.each(object, function() { }); + ok(actual === object); + } + else { + skipTest(); + } + }); + + test('iterates over all indexes when passing an ' + key, function() { + if (object) { + var values = []; + Benchmark.each(object, function(value) { + values.push(value); + }); + + deepEqual(values, key == 'xpath snapshot' ? xpathResult : ['a', 'b', 'c', '']); + } + else { + skipTest(); + } + }); + + test('exits early when returning `false` when passing an ' + key, function() { + if (object) { + var values = []; + Benchmark.each(object, function(value) { + values.push(value); + return values.length < 2; + }); + + deepEqual(values, key == 'xpath snapshot' ? xpathResult.slice(0, 2) : ['a', 'b']); + } + else { + skipTest(); + } + }); + }); + + test('passes the third callback argument as an object', function() { + var thirdArg; + Benchmark.each('hello', function(value, index, object) { + thirdArg = object; + }); + + ok(thirdArg && typeof thirdArg == 'object'); + }); + + test('iterates over strings by index', function() { + var values = []; + Benchmark.each('hello', function(value) { + values.push(value) + }); + + deepEqual(values, ['h', 'e', 'l', 'l', 'o']); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.extend'); + + (function() { + test('allows no source argument', function() { + var object = {}; + equal(Benchmark.extend(object), object); + }); + + test('allows a single source argument', function() { + var source = { 'x': 1, 'y': 1 }, + actual = Benchmark.extend({}, source); + + deepEqual(Benchmark.extend({}, source), { 'x': 1, 'y': 1 }); + }); + + test('allows multiple source arguments', function() { + var source1 = { 'x': 1, 'y': 1 }, + source2 = { 'y': 2, 'z': 2 }, + actual = Benchmark.extend({}, source1, source2); + + deepEqual(actual, { 'x': 1, 'y': 2, 'z': 2 }); + }); + + test('will add inherited source properties', function() { + function Source() { } + Source.prototype.x = 1; + deepEqual(Benchmark.extend({}, new Source), { 'x': 1 }); + }); + + test('will add problem JScript properties', function() { + deepEqual(Benchmark.extend({}, shadowed), shadowed); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.filter'); + + (function() { + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + var args; + Benchmark.filter(object, function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, ['a', 0, object]); + }); + + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.filter(object, function(value, index) { + return index > 0; + }); + + deepEqual(actual, ['b', 'c', '']); + }); + + test('iterates over sparse ' + key + 's correctly', function() { + var actual = Benchmark.filter(object, function(value) { + return value === undefined; + }); + + deepEqual(actual, []); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.forOwn'); + + (function() { + function fn() { + // no-op + } + + function KlassA() { + this.a = 1; + this.b = 2; + this.c = 3; + } + + function KlassB() { + this.a = 1; + this.constructor = 2; + this.hasOwnProperty = 3; + this.isPrototypeOf = 4; + this.propertyIsEnumerable = 5; + this.toLocaleString = 6; + this.toString = 7; + this.valueOf = 8; + } + + function KlassC() { + // no-op + } + + fn.a = 1; + fn.b = 2; + fn.c = 3; + + KlassC.prototype.a = 1; + KlassC.prototype.b = 2; + KlassC.prototype.c = 3; + + var objects = { + 'an arguments object': arguments, + 'a function': fn, + 'an object': new KlassA, + 'an object shadowing properties on Object.prototype': new KlassB, + 'a prototype object': KlassC.prototype, + 'a string': 'abc' + }; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing ' + key, function() { + var args; + Benchmark.forOwn(object, function() { + args || (args = slice.call(arguments)); + }); + + equal(typeof args[0], key == 'a string' ? 'string' : 'number'); + equal(typeof args[1], 'string'); + equal(args[2] && typeof args[2], key == 'a function' ? 'function' : 'object'); + }); + + test('returns the passed object when passing ' + key, function() { + var actual = Benchmark.forOwn(object, function() { }); + deepEqual(actual, object); + }); + + test('iterates over own properties when passing ' + key, function() { + var values = []; + Benchmark.forOwn(object, function(value) { + values.push(value); + }); + + if (object instanceof KlassB) { + deepEqual(values.sort(), [1, 2, 3, 4, 5, 6, 7, 8]); + } else if (key == 'a string') { + deepEqual(values, ['a', 'b', 'c']); + } else { + deepEqual(values.sort(), [1, 2, 3]); + } + }); + + test('exits early when returning `false` when passing ' + key, function() { + var values = []; + Benchmark.forOwn(object, function(value) { + values.push(value); + return false; + }); + + equal(values.length, 1); + }); + + if (object instanceof KlassB) { + test('exits correctly when transitioning to the JScript [[DontEnum]] fix', function() { + var values = []; + Benchmark.forOwn(object, function(value) { + values.push(value); + return values.length < 2; + }); + + equal(values.length, 2); + }); + } + }); + }(1, 2, 3)); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.formatNumber'); + + (function() { + test('formats a million correctly', function() { + equal(Benchmark.formatNumber(1e6), '1,000,000'); + }); + + test('formats less than 100 correctly', function() { + equal(Benchmark.formatNumber(23), '23'); + }); + + test('formats numbers with decimal values correctly', function() { + equal(Benchmark.formatNumber(1234.56), '1,234.56'); + }); + + test('formats negative numbers correctly', function() { + equal(Benchmark.formatNumber(-1234.56), '-1,234.56'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.hasKey'); + + (function() { + test('returns `true` for own properties', function() { + var object = { 'x': 1 }; + equal(Benchmark.hasKey(object, 'x'), true); + }); + + test('returns `false` for inherited properties', function() { + equal(Benchmark.hasKey({}, 'toString'), false); + }); + + test('doesn\'t use an object\'s `hasOwnProperty` method', function() { + var object = { 'hasOwnProperty': function() { return true; } }; + equal(Benchmark.hasKey(object, 'x'), false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.indexOf'); + + (function() { + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('produces the correct result when passing an ' + key, function() { + equal(Benchmark.indexOf(object, 'b'), 1); + }); + + test('matches values by strict equality when passing an ' + key, function() { + equal(Benchmark.indexOf(object, new String('b')), -1); + }); + + test('iterates over sparse ' + key + 's correctly', function() { + equal(Benchmark.indexOf(object, undefined), -1); + }); + }); + + test('searches from the given `fromIndex`', function() { + var array = ['a', 'b', 'c', 'a']; + equal(Benchmark.indexOf(array, 'a', 1), 3); + }); + + test('handles extreme negative `fromIndex` values correctly', function() { + var array = ['a']; + array['-1'] = 'z'; + equal(Benchmark.indexOf(array, 'z', -2), -1); + }); + + test('handles extreme positive `fromIndex` values correctly', function() { + var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 2 }; + equal(Benchmark.indexOf(object, 'c', 2), -1); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.interpolate'); + + (function() { + test('replaces tokens correctly', function() { + var actual = Benchmark.interpolate('#{greeting} #{location}.', { + 'greeting': 'Hello', + 'location': 'world' + }); + + equal(actual, 'Hello world.'); + }); + + test('ignores inherited object properties', function() { + var actual = Benchmark.interpolate('x#{toString}', {}); + equal(actual, 'x#{toString}'); + }); + + test('allows for no template object', function() { + var actual = Benchmark.interpolate('x'); + equal(actual, 'x'); + }); + + test('replaces duplicate tokens', function() { + var actual = Benchmark.interpolate('#{x}#{x}#{x}', { 'x': 'a' }); + equal(actual, 'aaa'); + }); + + test('handles keys containing RegExp special characters', function() { + var actual = Benchmark.interpolate('#{.*+?^=!:${}()|[]\\/}', { '.*+?^=!:${}()|[]\\/': 'x' }); + equal(actual, 'x'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.invoke'); + + (function() { + var objects = { + 'array': ['a', ['b'], 'c', null], + 'array-like-object': { '0': 'a', '1': ['b'], '2': 'c', '3': null, 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.invoke(object, 'concat'); + deepEqual(actual, ['a', ['b'], 'c', undefined, undefined]); + equal('4' in actual, false); + }); + + test('passes the correct arguments to the invoked method when passing an ' + key, function() { + var actual = Benchmark.invoke(object, 'concat', 'x', 'y', 'z'); + deepEqual(actual, ['axyz', ['b', 'x', 'y', 'z'], 'cxyz', undefined, undefined]); + equal('4' in actual, false); + }); + + test('handles options object with callbacks correctly when passing an ' + key, function() { + function callback() { + callbacks.push(slice.call(arguments)); + } + + var callbacks = []; + var actual = Benchmark.invoke(object, { + 'name': 'concat', + 'args': ['x', 'y', 'z'], + 'onStart': callback, + 'onCycle': callback, + 'onComplete': callback + }); + + deepEqual(actual, ['axyz', ['b', 'x', 'y', 'z'], 'cxyz', undefined, undefined]); + equal('4' in actual, false); + + equal(callbacks[0].length, 1); + equal(callbacks[0][0].target, 'a'); + deepEqual(callbacks[0][0].currentTarget, object); + equal(callbacks[0][0].type, 'start'); + equal(callbacks[1][0].type, 'cycle'); + equal(callbacks[5][0].type, 'complete'); + }); + + test('supports queuing when passing an ' + key, function() { + var lengths = []; + var actual = Benchmark.invoke(object, { + 'name': 'concat', + 'queued': true, + 'args': 'x', + 'onCycle': function() { + lengths.push(object.length); + } + }); + + deepEqual(lengths, [5, 4, 3, 2]); + deepEqual(actual, ['ax', ['b', 'x'], 'cx', undefined, undefined]); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.join'); + + (function() { + var objects = { + 'array': ['a', 'b', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': '', 'length': 4 }, + 'object': { 'a': '0', 'b': '1', '': '2' } + }; + + objects.array.length = 4; + + forOwn(objects, function(object, key) { + test('joins correctly using the default separator when passing an ' + key, function() { + equal(Benchmark.join(object), key == 'object' ? 'a: 0,b: 1,: 2' : 'a,b,'); + }); + + test('joins correctly using a custom separator when passing an ' + key, function() { + equal(Benchmark.join(object, '+', '@'), key == 'object' ? 'a@0+b@1+@2' : 'a+b+'); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.map'); + + (function() { + var objects = { + 'array': ['a', 'b', 'c', ''], + 'array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + var args; + Benchmark.map(object, function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, ['a', 0, object]); + }); + + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.map(object, function(value, index) { + return value + index; + }); + + deepEqual(actual, ['a0', 'b1', 'c2', '3', undefined]); + equal('4' in actual, false); + }); + + test('produces an array of the correct length for sparse ' + key + 's', function() { + equal(Benchmark.map(object, function() { }).length, 5); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.pluck'); + + (function() { + var objects = { + 'array': [{ '_': 'a' }, { '_': 'b' }, { '_': 'c' }, null], + 'array-like-object': { '0': { '_': 'a' }, '1': { '_': 'b' }, '2': { '_': 'c' }, '3': null, 'length': 5 } + }; + + objects.array.length = 5; + + forOwn(objects, function(object, key) { + test('produces the correct result when passing an ' + key, function() { + var actual = Benchmark.pluck(object, '_'); + deepEqual(actual, ['a', 'b', 'c', undefined, undefined]); + equal('4' in actual, false); + }); + + test('produces the correct result for non-existent keys when passing an ' + key, function() { + var actual = Benchmark.pluck(object, 'non-existent'); + deepEqual(actual, [undefined, undefined, undefined, undefined, undefined]); + equal('4' in actual, false); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.reduce'); + + (function() { + var objects = { + 'array': ['b', 'c', ''], + 'array-like-object': { '0': 'b', '1': 'c', '2': '', 'length': 4 } + }; + + objects.array.length = 4; + + forOwn(objects, function(object, key) { + test('passes the correct arguments when passing an ' + key, function() { + var args; + Benchmark.reduce(object, function() { + args || (args = slice.call(arguments)); + }, 'a'); + + deepEqual(args, ['a', 'b', 0, object]); + }); + + test('accumulates correctly when passing an ' + key, function() { + var actual = Benchmark.reduce(object, function(string, value) { + return string + value; + }, 'a'); + + equal(actual, 'abc'); + }); + + test('handles arguments with no initial value correctly when passing an ' + key, function() { + var args; + Benchmark.reduce(object, function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, ['b', 'c', 1, object]); + }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark#clone'); + + (function() { + var bench = Benchmark(function() { this.count += 0; }).run(); + + test('produces the correct result passing no arguments', function() { + var clone = bench.clone(); + deepEqual(clone, bench); + ok(clone.stats != bench.stats && clone.times != bench.times && clone.options != bench.options); + }); + + test('produces the correct result passing a data object', function() { + var clone = bench.clone({ 'fn': '', 'name': 'foo' }); + ok(clone.fn === '' && clone.options.fn === ''); + ok(clone.name == 'foo' && clone.options.name == 'foo'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark#run'); + + (function() { + var data = { 'onComplete': 0, 'onCycle': 0, 'onStart': 0 }; + + var bench = Benchmark({ + 'fn': function() { + this.count += 0; + }, + 'onStart': function() { + data.onStart++; + }, + 'onComplete': function() { + data.onComplete++; + } + }) + .run(); + + test('onXYZ callbacks should not be triggered by internal benchmark clones', function() { + equal(data.onStart, 1); + equal(data.onComplete, 1); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + forOwn({ + 'Benchmark': Benchmark, + 'Benchmark.Suite': Benchmark.Suite + }, + function(Constructor, namespace) { + + QUnit.module(namespace + '#emit'); + + (function() { + test('emits passed arguments', function() { + var args, + object = Constructor(); + + object.on('args', function() { args = slice.call(arguments, 1); }); + object.emit('args', 'a', 'b', 'c'); + deepEqual(args, ['a', 'b', 'c']); + }); + + test('emits with no listeners', function() { + var event = Benchmark.Event('empty'), + object = Constructor(); + + object.emit(event); + equal(event.cancelled, false); + }); + + test('emits with an event type of "toString"', function() { + var event = Benchmark.Event('toString'), + object = Constructor(); + + object.emit(event); + equal(event.cancelled, false); + }); + + test('returns the last listeners returned value', function() { + var event = Benchmark.Event('result'), + object = Constructor(); + + object.on('result', function() { return 'x'; }); + object.on('result', function() { return 'y'; }); + equal(object.emit(event), 'y'); + }); + + test('aborts the emitters listener iteration when `event.aborted` is `true`', function() { + var event = Benchmark.Event('aborted'), + object = Constructor(); + + object.on('aborted', function(event) { + event.aborted = true; + return false; + }); + + object.on('aborted', function(event) { + // should not get here + event.aborted = false; + return true; + }); + + equal(object.emit(event), false); + equal(event.aborted, true); + }); + + test('cancels the event if a listener explicitly returns `false`', function() { + var event = Benchmark.Event('cancel'), + object = Constructor(); + + object.on('cancel', function() { return false; }); + object.on('cancel', function() { return true; }); + object.emit(event); + equal(event.cancelled, true); + }); + + test('uses a shallow clone of the listeners when emitting', function() { + var event, + listener2 = function(eventObject) { eventObject.listener2 = true }, + object = Constructor(); + + object.on('shallowclone', function(eventObject) { + event = eventObject; + object.off(event.type, listener2); + }) + .on('shallowclone', listener2) + .emit('shallowclone'); + + ok(event.listener2); + }); + + test('emits a custom event object', function() { + var event = Benchmark.Event('custom'), + object = Constructor(); + + object.on('custom', function(eventObject) { eventObject.touched = true; }); + object.emit(event); + ok(event.touched); + }); + + test('sets `event.result` correctly', function() { + var event = Benchmark.Event('result'), + object = Constructor(); + + object.on('result', function() { return 'x'; }); + object.emit(event); + equal(event.result, 'x'); + }); + + test('sets `event.type` correctly', function() { + var event, + object = Constructor(); + + object.on('type', function(eventObj) { + event = eventObj; + }); + + object.emit('type'); + equal(event.type, 'type'); + }); + }()); + + /*------------------------------------------------------------------------*/ + + QUnit.module(namespace + '#listeners'); + + (function() { + test('returns the correct listeners', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + deepEqual(object.listeners('x'), [listener]); + }); + + test('returns an array and initializes previously uninitialized listeners', function() { + var object = Constructor(); + deepEqual(object.listeners('x'), []); + deepEqual(object.events, { 'x': [] }); + }); + }()); + + /*------------------------------------------------------------------------*/ + + QUnit.module(namespace + '#off'); + + (function() { + test('returns the benchmark', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + equal(object.off('x', listener), object); + }); + + test('will ignore inherited properties of the event cache', function() { + var Dummy = function() { }, + listener = function() { }, + object = Constructor(); + + Dummy.prototype.x = [listener]; + object.events = new Dummy; + + object.off('x', listener); + deepEqual(object.events.x, [listener]); + }); + + test('handles an event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.off('x', listener); + deepEqual(object.events.x, []); + }); + + test('handles unregistering duplicate listeners', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.on('x', listener); + + var events = object.events; + object.off('x', listener); + deepEqual(events.x, [listener]); + + object.off('x', listener); + deepEqual(events.x, []); + }); + + test('handles a non-registered listener', function() { + var object = Constructor(); + object.off('x', function() { }); + equal(object.events, undefined); + }); + + test('handles space separated event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.on('y', listener); + + var events = object.events; + object.off('x y', listener); + deepEqual(events.x, []); + deepEqual(events.y, []); + }); + + test('handles space separated event type and no listener', function() { + var listener1 = function() { }, + listener2 = function() { }, + object = Constructor(); + + object.on('x', listener1); + object.on('y', listener2); + + var events = object.events; + object.off('x y'); + deepEqual(events.x, []); + deepEqual(events.y, []); + }); + + test('handles no arguments', function() { + var listener1 = function() { }, + listener2 = function() { }, + listener3 = function() { }, + object = Constructor(); + + object.on('x', listener1); + object.on('y', listener2); + object.on('z', listener3); + + var events = object.events; + object.off(); + deepEqual(events.x, []); + deepEqual(events.y, []); + deepEqual(events.z, []); + }); + }()); + + /*------------------------------------------------------------------------*/ + + QUnit.module(namespace + '#on'); + + (function() { + test('returns the benchmark', function() { + var listener = function() { }, + object = Constructor(); + + equal(object.on('x', listener), object); + }); + + test('will ignore inherited properties of the event cache', function() { + var Dummy = function() { }, + listener1 = function() { }, + listener2 = function() { }, + object = Constructor(); + + Dummy.prototype.x = [listener1]; + object.events = new Dummy; + + object.on('x', listener2); + deepEqual(object.events.x, [listener2]); + }); + + test('handles an event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + deepEqual(object.events.x, [listener]); + }); + + test('handles registering duplicate listeners', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x', listener); + object.on('x', listener); + deepEqual(object.events.x, [listener, listener]); + }); + + test('handles space separated event type and listener', function() { + var listener = function() { }, + object = Constructor(); + + object.on('x y', listener); + + var events = object.events; + deepEqual(events.x, [listener]); + deepEqual(events.y, [listener]); + }); + }()); + }); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#abort'); + + (function() { + test('igores abort calls when the suite isn\'t running', function() { + var fired = false; + var suite = Benchmark.Suite('suite', { + 'onAbort': function() { fired = true; } + }); + + suite.add('foo', function() { }); + suite.abort(); + equal(fired, false); + }); + + test('ignores abort calls from `Benchmark.Suite#reset` when the suite isn\'t running', function() { + var fired = false; + var suite = Benchmark.Suite('suite', { + 'onAbort': function() { fired = true; } + }); + + suite.add('foo', function() { }); + suite.reset(); + equal(fired, false); + }); + + asyncTest('emits an abort event when running', function() { + var fired = false; + + Benchmark.Suite({ + 'onAbort': function() { fired = true; } + }) + .on('start', function() { + this.abort(); + }) + .on('complete', function() { + ok(fired); + QUnit.start(); + }) + .add(function(){ }) + .run({ 'async': true }); + }); + + asyncTest('emits an abort event after calling `Benchmark.Suite#reset`', function() { + var fired = false; + + Benchmark.Suite({ + 'onAbort': function() { fired = true; } + }) + .on('start', function() { + this.reset(); + }) + .on('complete', function() { + ok(fired); + QUnit.start(); + }) + .add(function(){ }) + .run({ 'async': true }); + }); + + asyncTest('should abort deferred benchmark', function() { + var fired = false, + suite = Benchmark.Suite(); + + suite.on('complete', function() { + equal(fired, false); + QUnit.start(); + }) + .add('a', { + 'defer': true, + 'fn': function(deferred) { + // avoid test inlining + suite.name; + // delay resolve + setTimeout(function() { + deferred.resolve(); + suite.abort(); + }, 10); + } + }) + .add('b', { + 'defer': true, + 'fn': function(deferred) { + // avoid test inlining + suite.name; + // delay resolve + setTimeout(function() { + deferred.resolve(); + fired = true; + }, 10); + } + }) + .run(); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#concat'); + + (function() { + var args = arguments; + + test('doesn\'t treat an arguments object like an array', function() { + var suite = Benchmark.Suite(); + deepEqual(suite.concat(args), [args]); + }); + + test('flattens array arguments', function() { + var suite = Benchmark.Suite(); + deepEqual(suite.concat([1, 2], 3, [4, 5]), [1, 2, 3, 4, 5]); + }); + + test('supports concating sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[2] = 2; + suite.length = 3; + + var actual = suite.concat(3); + deepEqual(actual, [0, undefined, 2, 3]); + equal('1' in actual, false); + }); + + test('supports sparse arrays as arguments', function() { + var suite = Benchmark.Suite(), + sparse = []; + + sparse[0] = 0; + sparse[2] = 2; + sparse.length = 3; + + var actual = suite.concat(sparse); + deepEqual(actual, [0, undefined, 2]); + equal('1' in actual, false); + }); + + test('creates a new array', function() { + var suite = Benchmark.Suite(); + ok(suite.concat(1) !== suite); + }); + }(1, 2, 3)); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#reverse'); + + (function() { + test('reverses the element order', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite.length = 2; + + var actual = suite.reverse(); + equal(actual, suite); + deepEqual(slice.call(actual), [1, 0]); + }); + + test('supports reversing sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[2] = 2; + suite.length = 3; + + var actual = suite.reverse(); + equal(actual, suite); + deepEqual(slice.call(actual), [2, undefined, 0]); + equal('1' in actual, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#shift'); + + (function() { + test('removes the first element', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite.length = 2; + + var actual = suite.shift(); + equal(actual, 0); + deepEqual(slice.call(suite), [1]); + }); + + test('shifts an object with no elements', function() { + var suite = Benchmark.Suite(), + actual = suite.shift(); + + equal(actual, undefined); + deepEqual(slice.call(suite), []); + }); + + test('should have no elements when length is 0 after shift', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite.length = 1; + suite.shift(); + + // ensure element is removed + equal('0' in suite, false); + equal(suite.length, 0); + }); + + test('supports shifting sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[1] = 1; + suite[3] = 3; + suite.length = 4; + + var actual = suite.shift(); + equal(actual, undefined); + deepEqual(slice.call(suite), [1, undefined, 3]); + equal('1' in suite, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#slice'); + + (function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite[2] = 2; + suite[3] = 3; + suite.length = 4; + + test('works with no arguments', function() { + var actual = suite.slice(); + deepEqual(actual, [0, 1, 2, 3]); + ok(suite !== actual); + }); + + test('works with positive `start` argument', function() { + var actual = suite.slice(2); + deepEqual(actual, [2, 3]); + ok(suite !== actual); + }); + + test('works with positive `start` and `end` arguments', function() { + var actual = suite.slice(1, 3); + deepEqual(actual, [1, 2]); + ok(suite !== actual); + }); + + test('works with `end` values exceeding length', function() { + var actual = suite.slice(1, 10); + deepEqual(actual, [1, 2, 3]); + ok(suite !== actual); + }); + + test('works with negative `start` and `end` arguments', function() { + var actual = suite.slice(-3, -1); + deepEqual(actual, [1, 2]); + ok(suite !== actual); + }); + + test('works with an extreme negative `end` value', function() { + var actual = suite.slice(1, -10); + deepEqual(actual, []); + equal('-1' in actual, false); + ok(suite !== actual); + }); + + test('supports slicing sparse arrays', function() { + var sparse = Benchmark.Suite(); + sparse[1] = 1; + sparse[3] = 3; + sparse.length = 4; + + var actual = sparse.slice(0, 2); + deepEqual(actual, [undefined, 1]); + equal('0' in actual, false); + + actual = sparse.slice(1); + deepEqual(actual, [1, undefined, 3]); + equal('1' in actual, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#splice'); + + (function() { + test('works with no arguments', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite.length = 1; + + var actual = suite.splice(); + deepEqual(actual, []); + deepEqual(slice.call(suite), [0]); + }); + + test('works with only the `start` argument', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 1; + suite.length = 2; + + var actual = suite.splice(1); + deepEqual(actual, [1]); + deepEqual(slice.call(suite), [0]); + }); + + test('should have no elements when length is 0 after splice', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite.length = 1 + suite.splice(0, 1); + + // ensure element is removed + equal('0' in suite, false); + equal(suite.length, 0); + }); + + test('works with positive `start` argument', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(1, 0, 1, 2); + deepEqual(actual, []); + deepEqual(slice.call(suite), [0, 1, 2, 3]); + }); + + test('works with positive `start` and `deleteCount` arguments', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(1, 1, 1, 2); + deepEqual(actual, [3]); + deepEqual(slice.call(suite), [0, 1, 2]); + }); + + test('works with `deleteCount` values exceeding length', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(1, 10, 1, 2); + deepEqual(actual, [3]); + deepEqual(slice.call(suite), [0, 1, 2]); + }); + + test('works with negative `start` and `deleteCount` arguments', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(-1, -1, 1, 2); + deepEqual(actual, []); + deepEqual(slice.call(suite), [0, 1, 2, 3]); + }); + + test('works with an extreme negative `deleteCount` value', function() { + var suite = Benchmark.Suite(); + suite[0] = 0; + suite[1] = 3; + suite.length = 2; + + var actual = suite.splice(0, -10, 1, 2); + deepEqual(actual, []); + deepEqual(slice.call(suite), [1, 2, 0, 3]); + }); + + test('supports splicing sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[1] = 1; + suite[3] = 3; + suite.length = 4; + + var actual = suite.splice(1, 2, 1, 2); + deepEqual(actual, [1, undefined]); + equal(actual.length, 2); + deepEqual(slice.call(suite), [undefined, 1, 2, 3]); + equal('0' in suite, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite#unshift'); + + (function() { + test('adds a first element', function() { + var suite = Benchmark.Suite(); + suite[0] = 1; + suite.length = 1; + + var actual = suite.unshift(0); + equal(actual, 2); + deepEqual(slice.call(suite), [0, 1]); + }); + + test('adds multiple elements to the front', function() { + var suite = Benchmark.Suite(); + suite[0] = 3; + suite.length = 1; + + var actual = suite.unshift(0, 1, 2); + equal(actual, 4); + deepEqual(slice.call(suite), [0, 1, 2, 3]); + }); + + test('supports unshifting sparse arrays', function() { + var suite = Benchmark.Suite(); + suite[1] = 2; + suite.length = 2; + + var actual = suite.unshift(0); + equal(actual, 3); + deepEqual(slice.call(suite), [0, undefined, 2]); + equal('1' in suite, false); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite filtered results onComplete'); + + (function() { + var count = 0, + suite = Benchmark.Suite(); + + suite.add('a', function() { + count++; + }) + .add('b', function() { + for (var i = 0; i < 1e6; i++) { + count++; + } + }) + .add('c', function() { + throw new TypeError; + }); + + asyncTest('should filter by fastest', function() { + suite.on('complete', function() { + suite.off(); + deepEqual(this.filter('fastest').pluck('name'), ['a']); + QUnit.start(); + }) + .run({ 'async': true }); + }); + + asyncTest('should filter by slowest', function() { + suite.on('complete', function() { + suite.off(); + deepEqual(this.filter('slowest').pluck('name'), ['b']); + QUnit.start(); + }) + .run({ 'async': true }); + }); + + asyncTest('should filter by successful', function() { + suite.on('complete', function() { + suite.off(); + deepEqual(this.filter('successful').pluck('name'), ['a', 'b']); + QUnit.start(); + }) + .run({ 'async': true }); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.Suite event flow'); + + (function() { + var events = [], + callback = function(event) { events.push(event); }; + + var suite = Benchmark.Suite('suite', { + 'onAdd': callback, + 'onAbort': callback, + 'onClone': callback, + 'onError': callback, + 'onStart': callback, + 'onCycle': callback, + 'onComplete': callback, + 'onReset': callback + }) + .add('bench', function() { + throw null; + }, { + 'onAbort': callback, + 'onClone': callback, + 'onError': callback, + 'onStart': callback, + 'onCycle': callback, + 'onComplete': callback, + 'onReset': callback + }) + .run({ 'async': false }); + + // first Suite#onAdd + test('should emit the suite "add" event first', function() { + var event = events[0]; + ok(event.type == 'add' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // next we start the Suite because no reset was needed + test('should emit the suite "start" event', function() { + var event = events[1]; + ok(event.type == 'start' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // and so start the first benchmark + test('should emit the benchmark "start" event', function() { + var event = events[2]; + ok(event.type == 'start' && event.currentTarget.name == 'bench'); + }); + + // oh no! we abort because of an error + test('should emit the benchmark "error" event', function() { + var event = events[3]; + ok(event.type == 'error' && event.currentTarget.name == 'bench'); + }); + + // benchmark error triggered + test('should emit the benchmark "abort" event', function() { + var event = events[4]; + ok(event.type == 'abort' && event.currentTarget.name == 'bench'); + }); + + // we reset the benchmark as part of the abort + test('should emit the benchmark "reset" event', function() { + var event = events[5]; + ok(event.type == 'reset' && event.currentTarget.name == 'bench'); + }); + + // benchmark is cycle is finished + test('should emit the benchmark "cycle" event', function() { + var event = events[6]; + ok(event.type == 'cycle' && event.currentTarget.name == 'bench'); + }); + + // benchmark is complete + test('should emit the benchmark "complete" event', function() { + var event = events[7]; + ok(event.type == 'complete' && event.currentTarget.name == 'bench'); + }); + + // the benchmark error triggers a Suite error + test('should emit the suite "error" event', function() { + var event = events[8]; + ok(event.type == 'error' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // the Suite cycle finishes + test('should emit the suite "cycle" event', function() { + var event = events[9]; + ok(event.type == 'cycle' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + // the Suite completes + test('finally it should emit the suite "complete" event', function() { + var event = events[10]; + ok(event.type == 'complete' && event.currentTarget.name == 'suite' && event.target.name == 'bench'); + }); + + test('emitted all expected events', function() { + ok(events.length == 11); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Deferred benchmarks'); + + (function() { + asyncTest('should run a deferred benchmark correctly', function() { + Benchmark(function(deferred) { + setTimeout(function() { deferred.resolve(); }, 1e3); + }, { + 'defer': true, + 'onComplete': function() { + equal(this.hz.toFixed(0), 1); + QUnit.start(); + } + }) + .run(); + }); + + asyncTest('should run with string values for "fn", "setup", and "teardown"', function() { + Benchmark({ + 'defer': true, + 'setup': 'var x = [3, 2, 1];', + 'fn': 'setTimeout(function() { x.sort(); deferred.resolve(); }, 10);', + 'teardown': 'x.length = 0;', + 'onComplete': function() { + ok(true); + QUnit.start(); + } + }) + .run(); + }); + + asyncTest('should run recursively', function() { + Benchmark({ + 'defer': true, + 'setup': 'var x = [3, 2, 1];', + 'fn': 'for (var i = 0; i < 100; i++) x[ i % 2 ? "sort" : "reverse" ](); deferred.resolve();', + 'teardown': 'x.length = 0;', + 'onComplete': function() { + ok(true); + QUnit.start(); + } + }) + .run(); + }); + + asyncTest('should execute "setup", "fn", and "teardown" in correct order', function() { + var fired = []; + + Benchmark({ + 'defer': true, + 'setup': function() { + fired.push('setup'); + }, + 'fn': function(deferred) { + fired.push('fn'); + setTimeout(function() { deferred.resolve(); }, 10); + }, + 'teardown': function() { + fired.push('teardown'); + }, + 'onComplete': function() { + var actual = fired.join().replace(/(fn,)+/g, '$1').replace(/(setup,fn,teardown(?:,|$))+/, '$1'); + equal(actual, 'setup,fn,teardown'); + QUnit.start(); + } + }) + .run(); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('Benchmark.deepClone'); + + (function() { + asyncTest('avoids call stack limits', function() { + var result, + count = 0, + object = {}, + recurse = function() { count++; recurse(); }; + + setTimeout(function() { + ok(result, 'avoids call stack limits (stack limit is ' + (count - 1) + ')'); + QUnit.start(); + }, 15); + + if (toString.call(window.java) == '[object JavaPackage]') { + // Java throws uncatchable errors on call stack overflows, so to avoid + // them I chose a number higher than Rhino's call stack limit without + // dynamically testing for the actual limit + count = 3e3; + } else { + try { recurse(); } catch(e) { } + } + + // exceed limit + count++; + for (var i = 0, sub = object; i <= count; i++) { + sub = sub[i] = {}; + } + + try { + for (var i = 0, sub = Benchmark.deepClone(object); sub = sub[i]; i++) { } + result = --i == count; + } catch(e) { } + }); + }()); + + /*--------------------------------------------------------------------------*/ + + // explicitly call `QUnit.start()` for Narwhal, Rhino, and RingoJS + if (!window.document) { + QUnit.start(); + } +}(typeof global == 'object' && global || this)); diff --git a/node_modules/better-assert/.npmignore b/node_modules/better-assert/.npmignore new file mode 100644 index 0000000..f1250e5 --- /dev/null +++ b/node_modules/better-assert/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/node_modules/better-assert/History.md b/node_modules/better-assert/History.md new file mode 100644 index 0000000..cbb579b --- /dev/null +++ b/node_modules/better-assert/History.md @@ -0,0 +1,15 @@ + +1.0.0 / 2013-02-03 +================== + + * Stop using the removed magic __stack global getter + +0.1.0 / 2012-10-04 +================== + + * add throwing of AssertionError for test frameworks etc + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/better-assert/Makefile b/node_modules/better-assert/Makefile new file mode 100644 index 0000000..36a3ed7 --- /dev/null +++ b/node_modules/better-assert/Makefile @@ -0,0 +1,5 @@ + +test: + @echo "populate me" + +.PHONY: test \ No newline at end of file diff --git a/node_modules/better-assert/Readme.md b/node_modules/better-assert/Readme.md new file mode 100644 index 0000000..d8d3a63 --- /dev/null +++ b/node_modules/better-assert/Readme.md @@ -0,0 +1,61 @@ + +# better-assert + + Better c-style assertions using [callsite](https://github.com/visionmedia/callsite) for + self-documenting failure messages. + +## Installation + + $ npm install better-assert + +## Example + + By default assertions are enabled, however the __NO_ASSERT__ environment variable + will deactivate them when truthy. + +```js +var assert = require('better-assert'); + +test(); + +function test() { + var user = { name: 'tobi' }; + assert('tobi' == user.name); + assert('number' == typeof user.age); +} + +AssertionError: 'number' == typeof user.age + at test (/Users/tj/projects/better-assert/example.js:9:3) + at Object. (/Users/tj/projects/better-assert/example.js:4:1) + at Module._compile (module.js:449:26) + at Object.Module._extensions..js (module.js:467:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Module.runMain (module.js:492:10) + at process.startup.processNextTick.process._tickCallback (node.js:244:9) +``` + +## License + +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/node_modules/better-assert/example.js b/node_modules/better-assert/example.js new file mode 100644 index 0000000..688c29e --- /dev/null +++ b/node_modules/better-assert/example.js @@ -0,0 +1,10 @@ + +var assert = require('./'); + +test(); + +function test() { + var user = { name: 'tobi' }; + assert('tobi' == user.name); + assert('number' == typeof user.age); +} \ No newline at end of file diff --git a/node_modules/better-assert/index.js b/node_modules/better-assert/index.js new file mode 100644 index 0000000..fd1c9b7 --- /dev/null +++ b/node_modules/better-assert/index.js @@ -0,0 +1,38 @@ +/** + * Module dependencies. + */ + +var AssertionError = require('assert').AssertionError + , callsite = require('callsite') + , fs = require('fs') + +/** + * Expose `assert`. + */ + +module.exports = process.env.NO_ASSERT + ? function(){} + : assert; + +/** + * Assert the given `expr`. + */ + +function assert(expr) { + if (expr) return; + + var stack = callsite(); + var call = stack[1]; + var file = call.getFileName(); + var lineno = call.getLineNumber(); + var src = fs.readFileSync(file, 'utf8'); + var line = src.split('\n')[lineno-1]; + var src = line.match(/assert\((.*)\)/)[1]; + + var err = new AssertionError({ + message: src, + stackStartFunction: stack[0].getFunction() + }); + + throw err; +} diff --git a/node_modules/better-assert/package.json b/node_modules/better-assert/package.json new file mode 100644 index 0000000..49a8f37 --- /dev/null +++ b/node_modules/better-assert/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "better-assert@~1.0.0", + "scope": null, + "escapedName": "better-assert", + "name": "better-assert", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\parsejson" + ] + ], + "_from": "better-assert@>=1.0.0 <1.1.0", + "_id": "better-assert@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/better-assert", + "_npmUser": { + "name": "tony_ado", + "email": "coolhzb@163.com" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "raw": "better-assert@~1.0.0", + "scope": null, + "escapedName": "better-assert", + "name": "better-assert", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/parsejson", + "/parseqs", + "/parseuri" + ], + "_resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "_shasum": "40866b9e1b9e0b55b481894311e68faffaebc522", + "_shrinkwrap": null, + "_spec": "better-assert@~1.0.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\parsejson", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "bugs": { + "url": "https://github.com/visionmedia/better-assert/issues" + }, + "contributors": [ + { + "name": "TonyHe", + "email": "coolhzb@163.com" + }, + { + "name": "ForbesLindesay" + } + ], + "dependencies": { + "callsite": "1.0.0" + }, + "description": "Better assertions for node, reporting the expr, filename, lineno etc", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "40866b9e1b9e0b55b481894311e68faffaebc522", + "tarball": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/visionmedia/better-assert", + "keywords": [ + "assert", + "stack", + "trace", + "debug" + ], + "main": "index", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "tony_ado", + "email": "coolhzb@163.com" + } + ], + "name": "better-assert", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/visionmedia/better-assert.git" + }, + "version": "1.0.2" +} diff --git a/node_modules/bignumber.js/.npmignore b/node_modules/bignumber.js/.npmignore new file mode 100644 index 0000000..2d18542 --- /dev/null +++ b/node_modules/bignumber.js/.npmignore @@ -0,0 +1,4 @@ +test +perf +coverage + diff --git a/node_modules/bignumber.js/.travis.yml b/node_modules/bignumber.js/.travis.yml new file mode 100644 index 0000000..e63fe00 --- /dev/null +++ b/node_modules/bignumber.js/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - "node" + - "4.1" + - "4.0" + - "0.12" + - "0.11" + - "0.10" + - "0.8" + - "0.6" + - "iojs" + diff --git a/node_modules/bignumber.js/LICENCE b/node_modules/bignumber.js/LICENCE new file mode 100644 index 0000000..a5d1b40 --- /dev/null +++ b/node_modules/bignumber.js/LICENCE @@ -0,0 +1,23 @@ +The MIT Expat Licence. + +Copyright (c) 2012 Michael Mclaughlin + +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. + diff --git a/node_modules/bignumber.js/README.md b/node_modules/bignumber.js/README.md new file mode 100644 index 0000000..d2e5d24 --- /dev/null +++ b/node_modules/bignumber.js/README.md @@ -0,0 +1,358 @@ +![bignumber.js](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/bignumberjs.png) + +A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic. + +[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.svg)](https://travis-ci.org/MikeMcl/bignumber.js) + +
    + +## Features + + - Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal + - 8 KB minified and gzipped + - Simple API but full-featured + - Works with numbers with or without fraction digits in bases from 2 to 64 inclusive + - Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type + - Includes a `toFraction` and a correctly-rounded `squareRoot` method + - Supports cryptographically-secure pseudo-random number generation + - No dependencies + - Wide platform compatibility: uses JavaScript 1.5 (ECMAScript 3) features only + - Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set + +![API](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/API.png) + +If a smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/). +It's less than half the size but only works with decimal numbers and only has half the methods. +It also does not allow `NaN` or `Infinity`, or have the configuration options of this library. + +See also [decimal.js](https://github.com/MikeMcl/decimal.js/), which among other things adds support for non-integer powers, and performs all operations to a specified number of significant digits. + +## Load + +The library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*). + +```html + +``` + +For [Node.js](http://nodejs.org) or [io.js](https://iojs.org/en/index.html), the library is available from the [npm](https://npmjs.org/) registry + + $ npm install bignumber.js + +```javascript +var BigNumber = require('bignumber.js'); +``` + +To load with AMD loader libraries such as [requireJS](http://requirejs.org/): + +```javascript +require(['path/to/bignumber'], function(BigNumber) { + // Use BigNumber here in local scope. No global BigNumber. +}); +``` + +## Use + +*In all examples below, `var`, semicolons and `toString` calls are not shown. +If a commented-out value is in quotes it means `toString` has been called on the preceding expression.* + +The library exports a single function: `BigNumber`, the constructor of BigNumber instances. + +It accepts a value of type number *(up to 15 significant digits only)*, string or BigNumber object, + +```javascript +x = new BigNumber(123.4567) +y = BigNumber('123456.7e-3') +z = new BigNumber(x) +x.equals(y) && y.equals(z) && x.equals(z) // true +``` + + +and a base from 2 to 64 inclusive can be specified. + +```javascript +x = new BigNumber(1011, 2) // "11" +y = new BigNumber('zz.9', 36) // "1295.25" +z = x.plus(y) // "1306.25" +``` + +A BigNumber is immutable in the sense that it is not changed by its methods. + +```javascript +0.3 - 0.1 // 0.19999999999999998 +x = new BigNumber(0.3) +x.minus(0.1) // "0.2" +x // "0.3" +``` + +The methods that return a BigNumber can be chained. + +```javascript +x.dividedBy(y).plus(z).times(9).floor() +x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').ceil() +``` + +Many method names have a shorter alias. + +```javascript +x.squareRoot().dividedBy(y).toPower(3).equals(x.sqrt().div(y).pow(3)) // true +x.cmp(y.mod(z).neg()) == 1 && x.comparedTo(y.modulo(z).negated()) == 1 // true +``` + +Like JavaScript's number type, there are `toExponential`, `toFixed` and `toPrecision` methods + +```javascript +x = new BigNumber(255.5) +x.toExponential(5) // "2.55500e+2" +x.toFixed(5) // "255.50000" +x.toPrecision(5) // "255.50" +x.toNumber() // 255.5 +``` + + and a base can be specified for `toString`. + + ```javascript + x.toString(16) // "ff.8" + ``` + +There is also a `toFormat` method which may be useful for internationalisation + +```javascript +y = new BigNumber('1234567.898765') +y.toFormat(2) // "1,234,567.90" +``` + +The maximum number of decimal places of the result of an operation involving division (i.e. a division, square root, base conversion or negative power operation) is set using the `config` method of the `BigNumber` constructor. + +The other arithmetic operations always give the exact result. + +```javascript +BigNumber.config({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 }) +// Alternatively, BigNumber.config( 10, 4 ); + +x = new BigNumber(2); +y = new BigNumber(3); +z = x.div(y) // "0.6666666667" +z.sqrt() // "0.8164965809" +z.pow(-3) // "3.3749999995" +z.toString(2) // "0.1010101011" +z.times(z) // "0.44444444448888888889" +z.times(z).round(10) // "0.4444444445" +``` + +There is a `toFraction` method with an optional *maximum denominator* argument + +```javascript +y = new BigNumber(355) +pi = y.dividedBy(113) // "3.1415929204" +pi.toFraction() // [ "7853982301", "2500000000" ] +pi.toFraction(1000) // [ "355", "113" ] +``` + +and `isNaN` and `isFinite` methods, as `NaN` and `Infinity` are valid `BigNumber` values. + +```javascript +x = new BigNumber(NaN) // "NaN" +y = new BigNumber(Infinity) // "Infinity" +x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true +``` + +The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign. + + +```javascript +x = new BigNumber(-123.456); +x.c // [ 123, 45600000000000 ] coefficient (i.e. significand) +x.e // 2 exponent +x.s // -1 sign +``` + + +Multiple BigNumber constructors can be created, each with their own independent configuration which applies to all BigNumber's created from it. + +```javascript +// Set DECIMAL_PLACES for the original BigNumber constructor +BigNumber.config({ DECIMAL_PLACES: 10 }) + +// Create another BigNumber constructor, optionally passing in a configuration object +BN = BigNumber.another({ DECIMAL_PLACES: 5 }) + +x = new BigNumber(1) +y = new BN(1) + +x.div(3) // '0.3333333333' +y.div(3) // '0.33333' +``` + +For futher information see the [API](http://mikemcl.github.io/bignumber.js/) reference in the *doc* directory. + +## Test + +The *test* directory contains the test scripts for each method. + +The tests can be run with Node or a browser. For Node use + + $ npm test + +or + + $ node test/every-test + +To test a single method, e.g. + + $ node test/toFraction + +For the browser, see *every-test.html* and *single-test.html* in the *test/browser* directory. + +*bignumber-vs-number.html* enables some of the methods of bignumber.js to be compared with those of JavaScript's number type. + +## Versions + +This is version 2.x.x of the library, for version 1.x.x see the tagged releases or switch to the 'original' branch. The advantages of version 2 are that it is considerably faster for numbers with many digits and that there are a some added methods (see Change Log below). The disadvantages are more lines of code and increased code complexity, and the loss of simplicity in no longer having the coefficient of a BigNumber stored in base 10. The 'original' version will continue to be supported. + +## Performance + +See the [README](https://github.com/MikeMcl/bignumber.js/tree/master/perf) in the *perf* directory. + +## Build + +For Node, if [uglify-js](https://github.com/mishoo/UglifyJS2) is installed + + npm install uglify-js -g + +then + + npm run build + +will create *bignumber.min.js*. + +A source map will also be created in the root directory. + +## Feedback + +Open an issue, or email + +Michael + +M8ch88l@gmail.com + +## Licence + +MIT. + +See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE). + +## Change Log + +####2.3.0 +* 07/03/2016 +* #86 Add modulus parameter to `toPower`. + +####2.2.0 +* 03/03/2016 +* #91 Permit larger JS integers. + +####2.1.4 +* 15/12/2015 +* Correct UMD. + +####2.1.3 +* 13/12/2015 +* Refactor re global object and crypto availability when bundling. + +####2.1.2 +* 10/12/2015 +* Bugfix: `window.crypto` not assigned to `crypto`. + +####2.1.1 +* 09/12/2015 +* Prevent code bundler from adding `crypto` shim. + +####2.1.0 +* 26/10/2015 +* For `valueOf` and `toJSON`, include the minus sign with negative zero. + +####2.0.8 +* 2/10/2015 +* Internal round function bugfix. + +####2.0.6 +* 31/03/2015 +* Add bower.json. Tweak division after in-depth review. + +####2.0.5 +* 25/03/2015 +* Amend README. Remove bitcoin address. + +####2.0.4 +* 25/03/2015 +* Critical bugfix #58: division. + +####2.0.3 +* 18/02/2015 +* Amend README. Add source map. + +####2.0.2 +* 18/02/2015 +* Correct links. + +####2.0.1 +* 18/02/2015 +* Add `max`, `min`, `precision`, `random`, `shift`, `toDigits` and `truncated` methods. +* Add the short-forms: `add`, `mul`, `sd`, `sub` and `trunc`. +* Add an `another` method to enable multiple independent constructors to be created. +* Add support for the base 2, 8 and 16 prefixes `0b`, `0o` and `0x`. +* Enable a rounding mode to be specified as a second parameter to `toExponential`, `toFixed`, `toFormat` and `toPrecision`. +* Add a `CRYPTO` configuration property so cryptographically-secure pseudo-random number generation can be specified. +* Add a `MODULO_MODE` configuration property to enable the rounding mode used by the `modulo` operation to be specified. +* Add a `POW_PRECISION` configuration property to enable the number of significant digits calculated by the power operation to be limited. +* Improve code quality. +* Improve documentation. + +####2.0.0 +* 29/12/2014 +* Add `dividedToIntegerBy`, `isInteger` and `toFormat` methods. +* Remove the following short-forms: `isF`, `isZ`, `toE`, `toF`, `toFr`, `toN`, `toP`, `toS`. +* Store a BigNumber's coefficient in base 1e14, rather than base 10. +* Add fast path for integers to BigNumber constructor. +* Incorporate the library into the online documentation. + +####1.5.0 +* 13/11/2014 +* Add `toJSON` and `decimalPlaces` methods. + +####1.4.1 +* 08/06/2014 +* Amend README. + +####1.4.0 +* 08/05/2014 +* Add `toNumber`. + +####1.3.0 +* 08/11/2013 +* Ensure correct rounding of `sqrt` in all, rather than almost all, cases. +* Maximum radix to 64. + +####1.2.1 +* 17/10/2013 +* Sign of zero when x < 0 and x + (-x) = 0. + +####1.2.0 +* 19/9/2013 +* Throw Error objects for stack. + +####1.1.1 +* 22/8/2013 +* Show original value in constructor error message. + +####1.1.0 +* 1/8/2013 +* Allow numbers with trailing radix point. + +####1.0.1 +* Bugfix: error messages with incorrect method name + +####1.0.0 +* 8/11/2012 +* Initial release diff --git a/node_modules/bignumber.js/bignumber.js b/node_modules/bignumber.js/bignumber.js new file mode 100644 index 0000000..e0afb26 --- /dev/null +++ b/node_modules/bignumber.js/bignumber.js @@ -0,0 +1,2733 @@ +/*! bignumber.js v2.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */ + +;(function (globalObj) { + 'use strict'; + + /* + bignumber.js v2.3.0 + A JavaScript library for arbitrary-precision arithmetic. + https://github.com/MikeMcl/bignumber.js + Copyright (c) 2016 Michael Mclaughlin + MIT Expat Licence + */ + + + var cryptoObj, parseNumeric, + isNumeric = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, + mathceil = Math.ceil, + mathfloor = Math.floor, + notBool = ' not a boolean or binary digit', + roundingMode = 'rounding mode', + tooManyDigits = 'number type has more than 15 significant digits', + ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_', + BASE = 1e14, + LOG_BASE = 14, + MAX_SAFE_INTEGER = 0x1fffffffffffff, // 2^53 - 1 + // MAX_INT32 = 0x7fffffff, // 2^31 - 1 + POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], + SQRT_BASE = 1e7, + + /* + * The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and + * the arguments to toExponential, toFixed, toFormat, and toPrecision, beyond which an + * exception is thrown (if ERRORS is true). + */ + MAX = 1E9; // 0 to MAX_INT32 + + if ( typeof crypto != 'undefined' ) cryptoObj = crypto; + + + /* + * Create and return a BigNumber constructor. + */ + function constructorFactory(configObj) { + var div, + + // id tracks the caller function, so its name can be included in error messages. + id = 0, + P = BigNumber.prototype, + ONE = new BigNumber(1), + + + /********************************* EDITABLE DEFAULTS **********************************/ + + + /* + * The default values below must be integers within the inclusive ranges stated. + * The values can also be changed at run-time using BigNumber.config. + */ + + // The maximum number of decimal places for operations involving division. + DECIMAL_PLACES = 20, // 0 to MAX + + /* + * The rounding mode used when rounding to the above decimal places, and when using + * toExponential, toFixed, toFormat and toPrecision, and round (default value). + * UP 0 Away from zero. + * DOWN 1 Towards zero. + * CEIL 2 Towards +Infinity. + * FLOOR 3 Towards -Infinity. + * HALF_UP 4 Towards nearest neighbour. If equidistant, up. + * HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + * HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + * HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + * HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + */ + ROUNDING_MODE = 4, // 0 to 8 + + // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS] + + // The exponent value at and beneath which toString returns exponential notation. + // Number type: -7 + TO_EXP_NEG = -7, // 0 to -MAX + + // The exponent value at and above which toString returns exponential notation. + // Number type: 21 + TO_EXP_POS = 21, // 0 to MAX + + // RANGE : [MIN_EXP, MAX_EXP] + + // The minimum exponent value, beneath which underflow to zero occurs. + // Number type: -324 (5e-324) + MIN_EXP = -1e7, // -1 to -MAX + + // The maximum exponent value, above which overflow to Infinity occurs. + // Number type: 308 (1.7976931348623157e+308) + // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow. + MAX_EXP = 1e7, // 1 to MAX + + // Whether BigNumber Errors are ever thrown. + ERRORS = true, // true or false + + // Change to intValidatorNoErrors if ERRORS is false. + isValidInt = intValidatorWithErrors, // intValidatorWithErrors/intValidatorNoErrors + + // Whether to use cryptographically-secure random number generation, if available. + CRYPTO = false, // true or false + + /* + * The modulo mode used when calculating the modulus: a mod n. + * The quotient (q = a / n) is calculated according to the corresponding rounding mode. + * The remainder (r) is calculated as: r = a - n * q. + * + * UP 0 The remainder is positive if the dividend is negative, else is negative. + * DOWN 1 The remainder has the same sign as the dividend. + * This modulo mode is commonly known as 'truncated division' and is + * equivalent to (a % n) in JavaScript. + * FLOOR 3 The remainder has the same sign as the divisor (Python %). + * HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function. + * EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). + * The remainder is always positive. + * + * The truncated division, floored division, Euclidian division and IEEE 754 remainder + * modes are commonly used for the modulus operation. + * Although the other rounding modes can also be used, they may not give useful results. + */ + MODULO_MODE = 1, // 0 to 9 + + // The maximum number of significant digits of the result of the toPower operation. + // If POW_PRECISION is 0, there will be unlimited significant digits. + POW_PRECISION = 100, // 0 to MAX + + // The format specification used by the BigNumber.prototype.toFormat method. + FORMAT = { + decimalSeparator: '.', + groupSeparator: ',', + groupSize: 3, + secondaryGroupSize: 0, + fractionGroupSeparator: '\xA0', // non-breaking space + fractionGroupSize: 0 + }; + + + /******************************************************************************************/ + + + // CONSTRUCTOR + + + /* + * The BigNumber constructor and exported function. + * Create and return a new instance of a BigNumber object. + * + * n {number|string|BigNumber} A numeric value. + * [b] {number} The base of n. Integer, 2 to 64 inclusive. + */ + function BigNumber( n, b ) { + var c, e, i, num, len, str, + x = this; + + // Enable constructor usage without new. + if ( !( x instanceof BigNumber ) ) { + + // 'BigNumber() constructor call without new: {n}' + if (ERRORS) raise( 26, 'constructor call without new', n ); + return new BigNumber( n, b ); + } + + // 'new BigNumber() base not an integer: {b}' + // 'new BigNumber() base out of range: {b}' + if ( b == null || !isValidInt( b, 2, 64, id, 'base' ) ) { + + // Duplicate. + if ( n instanceof BigNumber ) { + x.s = n.s; + x.e = n.e; + x.c = ( n = n.c ) ? n.slice() : n; + id = 0; + return; + } + + if ( ( num = typeof n == 'number' ) && n * 0 == 0 ) { + x.s = 1 / n < 0 ? ( n = -n, -1 ) : 1; + + // Fast path for integers. + if ( n === ~~n ) { + for ( e = 0, i = n; i >= 10; i /= 10, e++ ); + x.e = e; + x.c = [n]; + id = 0; + return; + } + + str = n + ''; + } else { + if ( !isNumeric.test( str = n + '' ) ) return parseNumeric( x, str, num ); + x.s = str.charCodeAt(0) === 45 ? ( str = str.slice(1), -1 ) : 1; + } + } else { + b = b | 0; + str = n + ''; + + // Ensure return value is rounded to DECIMAL_PLACES as with other bases. + // Allow exponential notation to be used with base 10 argument. + if ( b == 10 ) { + x = new BigNumber( n instanceof BigNumber ? n : str ); + return round( x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE ); + } + + // Avoid potential interpretation of Infinity and NaN as base 44+ values. + // Any number in exponential form will fail due to the [Ee][+-]. + if ( ( num = typeof n == 'number' ) && n * 0 != 0 || + !( new RegExp( '^-?' + ( c = '[' + ALPHABET.slice( 0, b ) + ']+' ) + + '(?:\\.' + c + ')?$',b < 37 ? 'i' : '' ) ).test(str) ) { + return parseNumeric( x, str, num, b ); + } + + if (num) { + x.s = 1 / n < 0 ? ( str = str.slice(1), -1 ) : 1; + + if ( ERRORS && str.replace( /^0\.0*|\./, '' ).length > 15 ) { + + // 'new BigNumber() number type has more than 15 significant digits: {n}' + raise( id, tooManyDigits, n ); + } + + // Prevent later check for length on converted number. + num = false; + } else { + x.s = str.charCodeAt(0) === 45 ? ( str = str.slice(1), -1 ) : 1; + } + + str = convertBase( str, 10, b, x.s ); + } + + // Decimal point? + if ( ( e = str.indexOf('.') ) > -1 ) str = str.replace( '.', '' ); + + // Exponential form? + if ( ( i = str.search( /e/i ) ) > 0 ) { + + // Determine exponent. + if ( e < 0 ) e = i; + e += +str.slice( i + 1 ); + str = str.substring( 0, i ); + } else if ( e < 0 ) { + + // Integer. + e = str.length; + } + + // Determine leading zeros. + for ( i = 0; str.charCodeAt(i) === 48; i++ ); + + // Determine trailing zeros. + for ( len = str.length; str.charCodeAt(--len) === 48; ); + str = str.slice( i, len + 1 ); + + if (str) { + len = str.length; + + // Disallow numbers with over 15 significant digits if number type. + // 'new BigNumber() number type has more than 15 significant digits: {n}' + if ( num && ERRORS && len > 15 && ( n > MAX_SAFE_INTEGER || n !== mathfloor(n) ) ) { + raise( id, tooManyDigits, x.s * n ); + } + + e = e - i - 1; + + // Overflow? + if ( e > MAX_EXP ) { + + // Infinity. + x.c = x.e = null; + + // Underflow? + } else if ( e < MIN_EXP ) { + + // Zero. + x.c = [ x.e = 0 ]; + } else { + x.e = e; + x.c = []; + + // Transform base + + // e is the base 10 exponent. + // i is where to slice str to get the first element of the coefficient array. + i = ( e + 1 ) % LOG_BASE; + if ( e < 0 ) i += LOG_BASE; + + if ( i < len ) { + if (i) x.c.push( +str.slice( 0, i ) ); + + for ( len -= LOG_BASE; i < len; ) { + x.c.push( +str.slice( i, i += LOG_BASE ) ); + } + + str = str.slice(i); + i = LOG_BASE - str.length; + } else { + i -= len; + } + + for ( ; i--; str += '0' ); + x.c.push( +str ); + } + } else { + + // Zero. + x.c = [ x.e = 0 ]; + } + + id = 0; + } + + + // CONSTRUCTOR PROPERTIES + + + BigNumber.another = constructorFactory; + + BigNumber.ROUND_UP = 0; + BigNumber.ROUND_DOWN = 1; + BigNumber.ROUND_CEIL = 2; + BigNumber.ROUND_FLOOR = 3; + BigNumber.ROUND_HALF_UP = 4; + BigNumber.ROUND_HALF_DOWN = 5; + BigNumber.ROUND_HALF_EVEN = 6; + BigNumber.ROUND_HALF_CEIL = 7; + BigNumber.ROUND_HALF_FLOOR = 8; + BigNumber.EUCLID = 9; + + + /* + * Configure infrequently-changing library-wide settings. + * + * Accept an object or an argument list, with one or many of the following properties or + * parameters respectively: + * + * DECIMAL_PLACES {number} Integer, 0 to MAX inclusive + * ROUNDING_MODE {number} Integer, 0 to 8 inclusive + * EXPONENTIAL_AT {number|number[]} Integer, -MAX to MAX inclusive or + * [integer -MAX to 0 incl., 0 to MAX incl.] + * RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or + * [integer -MAX to -1 incl., integer 1 to MAX incl.] + * ERRORS {boolean|number} true, false, 1 or 0 + * CRYPTO {boolean|number} true, false, 1 or 0 + * MODULO_MODE {number} 0 to 9 inclusive + * POW_PRECISION {number} 0 to MAX inclusive + * FORMAT {object} See BigNumber.prototype.toFormat + * decimalSeparator {string} + * groupSeparator {string} + * groupSize {number} + * secondaryGroupSize {number} + * fractionGroupSeparator {string} + * fractionGroupSize {number} + * + * (The values assigned to the above FORMAT object properties are not checked for validity.) + * + * E.g. + * BigNumber.config(20, 4) is equivalent to + * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 }) + * + * Ignore properties/parameters set to null or undefined. + * Return an object with the properties current values. + */ + BigNumber.config = function () { + var v, p, + i = 0, + r = {}, + a = arguments, + o = a[0], + has = o && typeof o == 'object' + ? function () { if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null; } + : function () { if ( a.length > i ) return ( v = a[i++] ) != null; }; + + // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive. + // 'config() DECIMAL_PLACES not an integer: {v}' + // 'config() DECIMAL_PLACES out of range: {v}' + if ( has( p = 'DECIMAL_PLACES' ) && isValidInt( v, 0, MAX, 2, p ) ) { + DECIMAL_PLACES = v | 0; + } + r[p] = DECIMAL_PLACES; + + // ROUNDING_MODE {number} Integer, 0 to 8 inclusive. + // 'config() ROUNDING_MODE not an integer: {v}' + // 'config() ROUNDING_MODE out of range: {v}' + if ( has( p = 'ROUNDING_MODE' ) && isValidInt( v, 0, 8, 2, p ) ) { + ROUNDING_MODE = v | 0; + } + r[p] = ROUNDING_MODE; + + // EXPONENTIAL_AT {number|number[]} + // Integer, -MAX to MAX inclusive or [integer -MAX to 0 inclusive, 0 to MAX inclusive]. + // 'config() EXPONENTIAL_AT not an integer: {v}' + // 'config() EXPONENTIAL_AT out of range: {v}' + if ( has( p = 'EXPONENTIAL_AT' ) ) { + + if ( isArray(v) ) { + if ( isValidInt( v[0], -MAX, 0, 2, p ) && isValidInt( v[1], 0, MAX, 2, p ) ) { + TO_EXP_NEG = v[0] | 0; + TO_EXP_POS = v[1] | 0; + } + } else if ( isValidInt( v, -MAX, MAX, 2, p ) ) { + TO_EXP_NEG = -( TO_EXP_POS = ( v < 0 ? -v : v ) | 0 ); + } + } + r[p] = [ TO_EXP_NEG, TO_EXP_POS ]; + + // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or + // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive]. + // 'config() RANGE not an integer: {v}' + // 'config() RANGE cannot be zero: {v}' + // 'config() RANGE out of range: {v}' + if ( has( p = 'RANGE' ) ) { + + if ( isArray(v) ) { + if ( isValidInt( v[0], -MAX, -1, 2, p ) && isValidInt( v[1], 1, MAX, 2, p ) ) { + MIN_EXP = v[0] | 0; + MAX_EXP = v[1] | 0; + } + } else if ( isValidInt( v, -MAX, MAX, 2, p ) ) { + if ( v | 0 ) MIN_EXP = -( MAX_EXP = ( v < 0 ? -v : v ) | 0 ); + else if (ERRORS) raise( 2, p + ' cannot be zero', v ); + } + } + r[p] = [ MIN_EXP, MAX_EXP ]; + + // ERRORS {boolean|number} true, false, 1 or 0. + // 'config() ERRORS not a boolean or binary digit: {v}' + if ( has( p = 'ERRORS' ) ) { + + if ( v === !!v || v === 1 || v === 0 ) { + id = 0; + isValidInt = ( ERRORS = !!v ) ? intValidatorWithErrors : intValidatorNoErrors; + } else if (ERRORS) { + raise( 2, p + notBool, v ); + } + } + r[p] = ERRORS; + + // CRYPTO {boolean|number} true, false, 1 or 0. + // 'config() CRYPTO not a boolean or binary digit: {v}' + // 'config() crypto unavailable: {crypto}' + if ( has( p = 'CRYPTO' ) ) { + + if ( v === !!v || v === 1 || v === 0 ) { + CRYPTO = !!( v && cryptoObj ); + if ( v && !CRYPTO && ERRORS ) raise( 2, 'crypto unavailable', cryptoObj ); + } else if (ERRORS) { + raise( 2, p + notBool, v ); + } + } + r[p] = CRYPTO; + + // MODULO_MODE {number} Integer, 0 to 9 inclusive. + // 'config() MODULO_MODE not an integer: {v}' + // 'config() MODULO_MODE out of range: {v}' + if ( has( p = 'MODULO_MODE' ) && isValidInt( v, 0, 9, 2, p ) ) { + MODULO_MODE = v | 0; + } + r[p] = MODULO_MODE; + + // POW_PRECISION {number} Integer, 0 to MAX inclusive. + // 'config() POW_PRECISION not an integer: {v}' + // 'config() POW_PRECISION out of range: {v}' + if ( has( p = 'POW_PRECISION' ) && isValidInt( v, 0, MAX, 2, p ) ) { + POW_PRECISION = v | 0; + } + r[p] = POW_PRECISION; + + // FORMAT {object} + // 'config() FORMAT not an object: {v}' + if ( has( p = 'FORMAT' ) ) { + + if ( typeof v == 'object' ) { + FORMAT = v; + } else if (ERRORS) { + raise( 2, p + ' not an object', v ); + } + } + r[p] = FORMAT; + + return r; + }; + + + /* + * Return a new BigNumber whose value is the maximum of the arguments. + * + * arguments {number|string|BigNumber} + */ + BigNumber.max = function () { return maxOrMin( arguments, P.lt ); }; + + + /* + * Return a new BigNumber whose value is the minimum of the arguments. + * + * arguments {number|string|BigNumber} + */ + BigNumber.min = function () { return maxOrMin( arguments, P.gt ); }; + + + /* + * Return a new BigNumber with a random value equal to or greater than 0 and less than 1, + * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing + * zeros are produced). + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * + * 'random() decimal places not an integer: {dp}' + * 'random() decimal places out of range: {dp}' + * 'random() crypto unavailable: {crypto}' + */ + BigNumber.random = (function () { + var pow2_53 = 0x20000000000000; + + // Return a 53 bit integer n, where 0 <= n < 9007199254740992. + // Check if Math.random() produces more than 32 bits of randomness. + // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits. + // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1. + var random53bitInt = (Math.random() * pow2_53) & 0x1fffff + ? function () { return mathfloor( Math.random() * pow2_53 ); } + : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) + + (Math.random() * 0x800000 | 0); }; + + return function (dp) { + var a, b, e, k, v, + i = 0, + c = [], + rand = new BigNumber(ONE); + + dp = dp == null || !isValidInt( dp, 0, MAX, 14 ) ? DECIMAL_PLACES : dp | 0; + k = mathceil( dp / LOG_BASE ); + + if (CRYPTO) { + + // Browsers supporting crypto.getRandomValues. + if ( cryptoObj && cryptoObj.getRandomValues ) { + + a = cryptoObj.getRandomValues( new Uint32Array( k *= 2 ) ); + + for ( ; i < k; ) { + + // 53 bits: + // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2) + // 11111 11111111 11111111 11111111 11100000 00000000 00000000 + // ((Math.pow(2, 32) - 1) >>> 11).toString(2) + // 11111 11111111 11111111 + // 0x20000 is 2^21. + v = a[i] * 0x20000 + (a[i + 1] >>> 11); + + // Rejection sampling: + // 0 <= v < 9007199254740992 + // Probability that v >= 9e15, is + // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251 + if ( v >= 9e15 ) { + b = cryptoObj.getRandomValues( new Uint32Array(2) ); + a[i] = b[0]; + a[i + 1] = b[1]; + } else { + + // 0 <= v <= 8999999999999999 + // 0 <= (v % 1e14) <= 99999999999999 + c.push( v % 1e14 ); + i += 2; + } + } + i = k / 2; + + // Node.js supporting crypto.randomBytes. + } else if ( cryptoObj && cryptoObj.randomBytes ) { + + // buffer + a = cryptoObj.randomBytes( k *= 7 ); + + for ( ; i < k; ) { + + // 0x1000000000000 is 2^48, 0x10000000000 is 2^40 + // 0x100000000 is 2^32, 0x1000000 is 2^24 + // 11111 11111111 11111111 11111111 11111111 11111111 11111111 + // 0 <= v < 9007199254740992 + v = ( ( a[i] & 31 ) * 0x1000000000000 ) + ( a[i + 1] * 0x10000000000 ) + + ( a[i + 2] * 0x100000000 ) + ( a[i + 3] * 0x1000000 ) + + ( a[i + 4] << 16 ) + ( a[i + 5] << 8 ) + a[i + 6]; + + if ( v >= 9e15 ) { + cryptoObj.randomBytes(7).copy( a, i ); + } else { + + // 0 <= (v % 1e14) <= 99999999999999 + c.push( v % 1e14 ); + i += 7; + } + } + i = k / 7; + } else if (ERRORS) { + raise( 14, 'crypto unavailable', cryptoObj ); + } + } + + // Use Math.random: CRYPTO is false or crypto is unavailable and ERRORS is false. + if (!i) { + + for ( ; i < k; ) { + v = random53bitInt(); + if ( v < 9e15 ) c[i++] = v % 1e14; + } + } + + k = c[--i]; + dp %= LOG_BASE; + + // Convert trailing digits to zeros according to dp. + if ( k && dp ) { + v = POWS_TEN[LOG_BASE - dp]; + c[i] = mathfloor( k / v ) * v; + } + + // Remove trailing elements which are zero. + for ( ; c[i] === 0; c.pop(), i-- ); + + // Zero? + if ( i < 0 ) { + c = [ e = 0 ]; + } else { + + // Remove leading elements which are zero and adjust exponent accordingly. + for ( e = -1 ; c[0] === 0; c.shift(), e -= LOG_BASE); + + // Count the digits of the first element of c to determine leading zeros, and... + for ( i = 1, v = c[0]; v >= 10; v /= 10, i++); + + // adjust the exponent accordingly. + if ( i < LOG_BASE ) e -= LOG_BASE - i; + } + + rand.e = e; + rand.c = c; + return rand; + }; + })(); + + + // PRIVATE FUNCTIONS + + + // Convert a numeric string of baseIn to a numeric string of baseOut. + function convertBase( str, baseOut, baseIn, sign ) { + var d, e, k, r, x, xc, y, + i = str.indexOf( '.' ), + dp = DECIMAL_PLACES, + rm = ROUNDING_MODE; + + if ( baseIn < 37 ) str = str.toLowerCase(); + + // Non-integer. + if ( i >= 0 ) { + k = POW_PRECISION; + + // Unlimited precision. + POW_PRECISION = 0; + str = str.replace( '.', '' ); + y = new BigNumber(baseIn); + x = y.pow( str.length - i ); + POW_PRECISION = k; + + // Convert str as if an integer, then restore the fraction part by dividing the + // result by its base raised to a power. + y.c = toBaseOut( toFixedPoint( coeffToString( x.c ), x.e ), 10, baseOut ); + y.e = y.c.length; + } + + // Convert the number as integer. + xc = toBaseOut( str, baseIn, baseOut ); + e = k = xc.length; + + // Remove trailing zeros. + for ( ; xc[--k] == 0; xc.pop() ); + if ( !xc[0] ) return '0'; + + if ( i < 0 ) { + --e; + } else { + x.c = xc; + x.e = e; + + // sign is needed for correct rounding. + x.s = sign; + x = div( x, y, dp, rm, baseOut ); + xc = x.c; + r = x.r; + e = x.e; + } + + d = e + dp + 1; + + // The rounding digit, i.e. the digit to the right of the digit that may be rounded up. + i = xc[d]; + k = baseOut / 2; + r = r || d < 0 || xc[d + 1] != null; + + r = rm < 4 ? ( i != null || r ) && ( rm == 0 || rm == ( x.s < 0 ? 3 : 2 ) ) + : i > k || i == k &&( rm == 4 || r || rm == 6 && xc[d - 1] & 1 || + rm == ( x.s < 0 ? 8 : 7 ) ); + + if ( d < 1 || !xc[0] ) { + + // 1^-dp or 0. + str = r ? toFixedPoint( '1', -dp ) : '0'; + } else { + xc.length = d; + + if (r) { + + // Rounding up may mean the previous digit has to be rounded up and so on. + for ( --baseOut; ++xc[--d] > baseOut; ) { + xc[d] = 0; + + if ( !d ) { + ++e; + xc.unshift(1); + } + } + } + + // Determine trailing zeros. + for ( k = xc.length; !xc[--k]; ); + + // E.g. [4, 11, 15] becomes 4bf. + for ( i = 0, str = ''; i <= k; str += ALPHABET.charAt( xc[i++] ) ); + str = toFixedPoint( str, e ); + } + + // The caller will add the sign. + return str; + } + + + // Perform division in the specified base. Called by div and convertBase. + div = (function () { + + // Assume non-zero x and k. + function multiply( x, k, base ) { + var m, temp, xlo, xhi, + carry = 0, + i = x.length, + klo = k % SQRT_BASE, + khi = k / SQRT_BASE | 0; + + for ( x = x.slice(); i--; ) { + xlo = x[i] % SQRT_BASE; + xhi = x[i] / SQRT_BASE | 0; + m = khi * xlo + xhi * klo; + temp = klo * xlo + ( ( m % SQRT_BASE ) * SQRT_BASE ) + carry; + carry = ( temp / base | 0 ) + ( m / SQRT_BASE | 0 ) + khi * xhi; + x[i] = temp % base; + } + + if (carry) x.unshift(carry); + + return x; + } + + function compare( a, b, aL, bL ) { + var i, cmp; + + if ( aL != bL ) { + cmp = aL > bL ? 1 : -1; + } else { + + for ( i = cmp = 0; i < aL; i++ ) { + + if ( a[i] != b[i] ) { + cmp = a[i] > b[i] ? 1 : -1; + break; + } + } + } + return cmp; + } + + function subtract( a, b, aL, base ) { + var i = 0; + + // Subtract b from a. + for ( ; aL--; ) { + a[aL] -= i; + i = a[aL] < b[aL] ? 1 : 0; + a[aL] = i * base + a[aL] - b[aL]; + } + + // Remove leading zeros. + for ( ; !a[0] && a.length > 1; a.shift() ); + } + + // x: dividend, y: divisor. + return function ( x, y, dp, rm, base ) { + var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0, + yL, yz, + s = x.s == y.s ? 1 : -1, + xc = x.c, + yc = y.c; + + // Either NaN, Infinity or 0? + if ( !xc || !xc[0] || !yc || !yc[0] ) { + + return new BigNumber( + + // Return NaN if either NaN, or both Infinity or 0. + !x.s || !y.s || ( xc ? yc && xc[0] == yc[0] : !yc ) ? NaN : + + // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0. + xc && xc[0] == 0 || !yc ? s * 0 : s / 0 + ); + } + + q = new BigNumber(s); + qc = q.c = []; + e = x.e - y.e; + s = dp + e + 1; + + if ( !base ) { + base = BASE; + e = bitFloor( x.e / LOG_BASE ) - bitFloor( y.e / LOG_BASE ); + s = s / LOG_BASE | 0; + } + + // Result exponent may be one less then the current value of e. + // The coefficients of the BigNumbers from convertBase may have trailing zeros. + for ( i = 0; yc[i] == ( xc[i] || 0 ); i++ ); + if ( yc[i] > ( xc[i] || 0 ) ) e--; + + if ( s < 0 ) { + qc.push(1); + more = true; + } else { + xL = xc.length; + yL = yc.length; + i = 0; + s += 2; + + // Normalise xc and yc so highest order digit of yc is >= base / 2. + + n = mathfloor( base / ( yc[0] + 1 ) ); + + // Not necessary, but to handle odd bases where yc[0] == ( base / 2 ) - 1. + // if ( n > 1 || n++ == 1 && yc[0] < base / 2 ) { + if ( n > 1 ) { + yc = multiply( yc, n, base ); + xc = multiply( xc, n, base ); + yL = yc.length; + xL = xc.length; + } + + xi = yL; + rem = xc.slice( 0, yL ); + remL = rem.length; + + // Add zeros to make remainder as long as divisor. + for ( ; remL < yL; rem[remL++] = 0 ); + yz = yc.slice(); + yz.unshift(0); + yc0 = yc[0]; + if ( yc[1] >= base / 2 ) yc0++; + // Not necessary, but to prevent trial digit n > base, when using base 3. + // else if ( base == 3 && yc0 == 1 ) yc0 = 1 + 1e-15; + + do { + n = 0; + + // Compare divisor and remainder. + cmp = compare( yc, rem, yL, remL ); + + // If divisor < remainder. + if ( cmp < 0 ) { + + // Calculate trial digit, n. + + rem0 = rem[0]; + if ( yL != remL ) rem0 = rem0 * base + ( rem[1] || 0 ); + + // n is how many times the divisor goes into the current remainder. + n = mathfloor( rem0 / yc0 ); + + // Algorithm: + // 1. product = divisor * trial digit (n) + // 2. if product > remainder: product -= divisor, n-- + // 3. remainder -= product + // 4. if product was < remainder at 2: + // 5. compare new remainder and divisor + // 6. If remainder > divisor: remainder -= divisor, n++ + + if ( n > 1 ) { + + // n may be > base only when base is 3. + if (n >= base) n = base - 1; + + // product = divisor * trial digit. + prod = multiply( yc, n, base ); + prodL = prod.length; + remL = rem.length; + + // Compare product and remainder. + // If product > remainder. + // Trial digit n too high. + // n is 1 too high about 5% of the time, and is not known to have + // ever been more than 1 too high. + while ( compare( prod, rem, prodL, remL ) == 1 ) { + n--; + + // Subtract divisor from product. + subtract( prod, yL < prodL ? yz : yc, prodL, base ); + prodL = prod.length; + cmp = 1; + } + } else { + + // n is 0 or 1, cmp is -1. + // If n is 0, there is no need to compare yc and rem again below, + // so change cmp to 1 to avoid it. + // If n is 1, leave cmp as -1, so yc and rem are compared again. + if ( n == 0 ) { + + // divisor < remainder, so n must be at least 1. + cmp = n = 1; + } + + // product = divisor + prod = yc.slice(); + prodL = prod.length; + } + + if ( prodL < remL ) prod.unshift(0); + + // Subtract product from remainder. + subtract( rem, prod, remL, base ); + remL = rem.length; + + // If product was < remainder. + if ( cmp == -1 ) { + + // Compare divisor and new remainder. + // If divisor < new remainder, subtract divisor from remainder. + // Trial digit n too low. + // n is 1 too low about 5% of the time, and very rarely 2 too low. + while ( compare( yc, rem, yL, remL ) < 1 ) { + n++; + + // Subtract divisor from remainder. + subtract( rem, yL < remL ? yz : yc, remL, base ); + remL = rem.length; + } + } + } else if ( cmp === 0 ) { + n++; + rem = [0]; + } // else cmp === 1 and n will be 0 + + // Add the next digit, n, to the result array. + qc[i++] = n; + + // Update the remainder. + if ( rem[0] ) { + rem[remL++] = xc[xi] || 0; + } else { + rem = [ xc[xi] ]; + remL = 1; + } + } while ( ( xi++ < xL || rem[0] != null ) && s-- ); + + more = rem[0] != null; + + // Leading zero? + if ( !qc[0] ) qc.shift(); + } + + if ( base == BASE ) { + + // To calculate q.e, first get the number of digits of qc[0]. + for ( i = 1, s = qc[0]; s >= 10; s /= 10, i++ ); + round( q, dp + ( q.e = i + e * LOG_BASE - 1 ) + 1, rm, more ); + + // Caller is convertBase. + } else { + q.e = e; + q.r = +more; + } + + return q; + }; + })(); + + + /* + * Return a string representing the value of BigNumber n in fixed-point or exponential + * notation rounded to the specified decimal places or significant digits. + * + * n is a BigNumber. + * i is the index of the last digit required (i.e. the digit that may be rounded up). + * rm is the rounding mode. + * caller is caller id: toExponential 19, toFixed 20, toFormat 21, toPrecision 24. + */ + function format( n, i, rm, caller ) { + var c0, e, ne, len, str; + + rm = rm != null && isValidInt( rm, 0, 8, caller, roundingMode ) + ? rm | 0 : ROUNDING_MODE; + + if ( !n.c ) return n.toString(); + c0 = n.c[0]; + ne = n.e; + + if ( i == null ) { + str = coeffToString( n.c ); + str = caller == 19 || caller == 24 && ne <= TO_EXP_NEG + ? toExponential( str, ne ) + : toFixedPoint( str, ne ); + } else { + n = round( new BigNumber(n), i, rm ); + + // n.e may have changed if the value was rounded up. + e = n.e; + + str = coeffToString( n.c ); + len = str.length; + + // toPrecision returns exponential notation if the number of significant digits + // specified is less than the number of digits necessary to represent the integer + // part of the value in fixed-point notation. + + // Exponential notation. + if ( caller == 19 || caller == 24 && ( i <= e || e <= TO_EXP_NEG ) ) { + + // Append zeros? + for ( ; len < i; str += '0', len++ ); + str = toExponential( str, e ); + + // Fixed-point notation. + } else { + i -= ne; + str = toFixedPoint( str, e ); + + // Append zeros? + if ( e + 1 > len ) { + if ( --i > 0 ) for ( str += '.'; i--; str += '0' ); + } else { + i += e - len; + if ( i > 0 ) { + if ( e + 1 == len ) str += '.'; + for ( ; i--; str += '0' ); + } + } + } + } + + return n.s < 0 && c0 ? '-' + str : str; + } + + + // Handle BigNumber.max and BigNumber.min. + function maxOrMin( args, method ) { + var m, n, + i = 0; + + if ( isArray( args[0] ) ) args = args[0]; + m = new BigNumber( args[0] ); + + for ( ; ++i < args.length; ) { + n = new BigNumber( args[i] ); + + // If any number is NaN, return NaN. + if ( !n.s ) { + m = n; + break; + } else if ( method.call( m, n ) ) { + m = n; + } + } + + return m; + } + + + /* + * Return true if n is an integer in range, otherwise throw. + * Use for argument validation when ERRORS is true. + */ + function intValidatorWithErrors( n, min, max, caller, name ) { + if ( n < min || n > max || n != truncate(n) ) { + raise( caller, ( name || 'decimal places' ) + + ( n < min || n > max ? ' out of range' : ' not an integer' ), n ); + } + + return true; + } + + + /* + * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP. + * Called by minus, plus and times. + */ + function normalise( n, c, e ) { + var i = 1, + j = c.length; + + // Remove trailing zeros. + for ( ; !c[--j]; c.pop() ); + + // Calculate the base 10 exponent. First get the number of digits of c[0]. + for ( j = c[0]; j >= 10; j /= 10, i++ ); + + // Overflow? + if ( ( e = i + e * LOG_BASE - 1 ) > MAX_EXP ) { + + // Infinity. + n.c = n.e = null; + + // Underflow? + } else if ( e < MIN_EXP ) { + + // Zero. + n.c = [ n.e = 0 ]; + } else { + n.e = e; + n.c = c; + } + + return n; + } + + + // Handle values that fail the validity test in BigNumber. + parseNumeric = (function () { + var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, + dotAfter = /^([^.]+)\.$/, + dotBefore = /^\.([^.]+)$/, + isInfinityOrNaN = /^-?(Infinity|NaN)$/, + whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g; + + return function ( x, str, num, b ) { + var base, + s = num ? str : str.replace( whitespaceOrPlus, '' ); + + // No exception on ±Infinity or NaN. + if ( isInfinityOrNaN.test(s) ) { + x.s = isNaN(s) ? null : s < 0 ? -1 : 1; + } else { + if ( !num ) { + + // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i + s = s.replace( basePrefix, function ( m, p1, p2 ) { + base = ( p2 = p2.toLowerCase() ) == 'x' ? 16 : p2 == 'b' ? 2 : 8; + return !b || b == base ? p1 : m; + }); + + if (b) { + base = b; + + // E.g. '1.' to '1', '.1' to '0.1' + s = s.replace( dotAfter, '$1' ).replace( dotBefore, '0.$1' ); + } + + if ( str != s ) return new BigNumber( s, base ); + } + + // 'new BigNumber() not a number: {n}' + // 'new BigNumber() not a base {b} number: {n}' + if (ERRORS) raise( id, 'not a' + ( b ? ' base ' + b : '' ) + ' number', str ); + x.s = null; + } + + x.c = x.e = null; + id = 0; + } + })(); + + + // Throw a BigNumber Error. + function raise( caller, msg, val ) { + var error = new Error( [ + 'new BigNumber', // 0 + 'cmp', // 1 + 'config', // 2 + 'div', // 3 + 'divToInt', // 4 + 'eq', // 5 + 'gt', // 6 + 'gte', // 7 + 'lt', // 8 + 'lte', // 9 + 'minus', // 10 + 'mod', // 11 + 'plus', // 12 + 'precision', // 13 + 'random', // 14 + 'round', // 15 + 'shift', // 16 + 'times', // 17 + 'toDigits', // 18 + 'toExponential', // 19 + 'toFixed', // 20 + 'toFormat', // 21 + 'toFraction', // 22 + 'pow', // 23 + 'toPrecision', // 24 + 'toString', // 25 + 'BigNumber' // 26 + ][caller] + '() ' + msg + ': ' + val ); + + error.name = 'BigNumber Error'; + id = 0; + throw error; + } + + + /* + * Round x to sd significant digits using rounding mode rm. Check for over/under-flow. + * If r is truthy, it is known that there are more digits after the rounding digit. + */ + function round( x, sd, rm, r ) { + var d, i, j, k, n, ni, rd, + xc = x.c, + pows10 = POWS_TEN; + + // if x is not Infinity or NaN... + if (xc) { + + // rd is the rounding digit, i.e. the digit after the digit that may be rounded up. + // n is a base 1e14 number, the value of the element of array x.c containing rd. + // ni is the index of n within x.c. + // d is the number of digits of n. + // i is the index of rd within n including leading zeros. + // j is the actual index of rd within n (if < 0, rd is a leading zero). + out: { + + // Get the number of digits of the first element of xc. + for ( d = 1, k = xc[0]; k >= 10; k /= 10, d++ ); + i = sd - d; + + // If the rounding digit is in the first element of xc... + if ( i < 0 ) { + i += LOG_BASE; + j = sd; + n = xc[ ni = 0 ]; + + // Get the rounding digit at index j of n. + rd = n / pows10[ d - j - 1 ] % 10 | 0; + } else { + ni = mathceil( ( i + 1 ) / LOG_BASE ); + + if ( ni >= xc.length ) { + + if (r) { + + // Needed by sqrt. + for ( ; xc.length <= ni; xc.push(0) ); + n = rd = 0; + d = 1; + i %= LOG_BASE; + j = i - LOG_BASE + 1; + } else { + break out; + } + } else { + n = k = xc[ni]; + + // Get the number of digits of n. + for ( d = 1; k >= 10; k /= 10, d++ ); + + // Get the index of rd within n. + i %= LOG_BASE; + + // Get the index of rd within n, adjusted for leading zeros. + // The number of leading zeros of n is given by LOG_BASE - d. + j = i - LOG_BASE + d; + + // Get the rounding digit at index j of n. + rd = j < 0 ? 0 : n / pows10[ d - j - 1 ] % 10 | 0; + } + } + + r = r || sd < 0 || + + // Are there any non-zero digits after the rounding digit? + // The expression n % pows10[ d - j - 1 ] returns all digits of n to the right + // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714. + xc[ni + 1] != null || ( j < 0 ? n : n % pows10[ d - j - 1 ] ); + + r = rm < 4 + ? ( rd || r ) && ( rm == 0 || rm == ( x.s < 0 ? 3 : 2 ) ) + : rd > 5 || rd == 5 && ( rm == 4 || r || rm == 6 && + + // Check whether the digit to the left of the rounding digit is odd. + ( ( i > 0 ? j > 0 ? n / pows10[ d - j ] : 0 : xc[ni - 1] ) % 10 ) & 1 || + rm == ( x.s < 0 ? 8 : 7 ) ); + + if ( sd < 1 || !xc[0] ) { + xc.length = 0; + + if (r) { + + // Convert sd to decimal places. + sd -= x.e + 1; + + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xc[0] = pows10[ ( LOG_BASE - sd % LOG_BASE ) % LOG_BASE ]; + x.e = -sd || 0; + } else { + + // Zero. + xc[0] = x.e = 0; + } + + return x; + } + + // Remove excess digits. + if ( i == 0 ) { + xc.length = ni; + k = 1; + ni--; + } else { + xc.length = ni + 1; + k = pows10[ LOG_BASE - i ]; + + // E.g. 56700 becomes 56000 if 7 is the rounding digit. + // j > 0 means i > number of leading zeros of n. + xc[ni] = j > 0 ? mathfloor( n / pows10[ d - j ] % pows10[j] ) * k : 0; + } + + // Round up? + if (r) { + + for ( ; ; ) { + + // If the digit to be rounded up is in the first element of xc... + if ( ni == 0 ) { + + // i will be the length of xc[0] before k is added. + for ( i = 1, j = xc[0]; j >= 10; j /= 10, i++ ); + j = xc[0] += k; + for ( k = 1; j >= 10; j /= 10, k++ ); + + // if i != k the length has increased. + if ( i != k ) { + x.e++; + if ( xc[0] == BASE ) xc[0] = 1; + } + + break; + } else { + xc[ni] += k; + if ( xc[ni] != BASE ) break; + xc[ni--] = 0; + k = 1; + } + } + } + + // Remove trailing zeros. + for ( i = xc.length; xc[--i] === 0; xc.pop() ); + } + + // Overflow? Infinity. + if ( x.e > MAX_EXP ) { + x.c = x.e = null; + + // Underflow? Zero. + } else if ( x.e < MIN_EXP ) { + x.c = [ x.e = 0 ]; + } + } + + return x; + } + + + // PROTOTYPE/INSTANCE METHODS + + + /* + * Return a new BigNumber whose value is the absolute value of this BigNumber. + */ + P.absoluteValue = P.abs = function () { + var x = new BigNumber(this); + if ( x.s < 0 ) x.s = 1; + return x; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber rounded to a whole + * number in the direction of Infinity. + */ + P.ceil = function () { + return round( new BigNumber(this), this.e + 1, 2 ); + }; + + + /* + * Return + * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b), + * -1 if the value of this BigNumber is less than the value of BigNumber(y, b), + * 0 if they have the same value, + * or null if the value of either is NaN. + */ + P.comparedTo = P.cmp = function ( y, b ) { + id = 1; + return compare( this, new BigNumber( y, b ) ); + }; + + + /* + * Return the number of decimal places of the value of this BigNumber, or null if the value + * of this BigNumber is ±Infinity or NaN. + */ + P.decimalPlaces = P.dp = function () { + var n, v, + c = this.c; + + if ( !c ) return null; + n = ( ( v = c.length - 1 ) - bitFloor( this.e / LOG_BASE ) ) * LOG_BASE; + + // Subtract the number of trailing zeros of the last number. + if ( v = c[v] ) for ( ; v % 10 == 0; v /= 10, n-- ); + if ( n < 0 ) n = 0; + + return n; + }; + + + /* + * n / 0 = I + * n / N = N + * n / I = 0 + * 0 / n = 0 + * 0 / 0 = N + * 0 / N = N + * 0 / I = 0 + * N / n = N + * N / 0 = N + * N / N = N + * N / I = N + * I / n = I + * I / 0 = I + * I / N = N + * I / I = N + * + * Return a new BigNumber whose value is the value of this BigNumber divided by the value of + * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE. + */ + P.dividedBy = P.div = function ( y, b ) { + id = 3; + return div( this, new BigNumber( y, b ), DECIMAL_PLACES, ROUNDING_MODE ); + }; + + + /* + * Return a new BigNumber whose value is the integer part of dividing the value of this + * BigNumber by the value of BigNumber(y, b). + */ + P.dividedToIntegerBy = P.divToInt = function ( y, b ) { + id = 4; + return div( this, new BigNumber( y, b ), 0, 1 ); + }; + + + /* + * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b), + * otherwise returns false. + */ + P.equals = P.eq = function ( y, b ) { + id = 5; + return compare( this, new BigNumber( y, b ) ) === 0; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber rounded to a whole + * number in the direction of -Infinity. + */ + P.floor = function () { + return round( new BigNumber(this), this.e + 1, 3 ); + }; + + + /* + * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b), + * otherwise returns false. + */ + P.greaterThan = P.gt = function ( y, b ) { + id = 6; + return compare( this, new BigNumber( y, b ) ) > 0; + }; + + + /* + * Return true if the value of this BigNumber is greater than or equal to the value of + * BigNumber(y, b), otherwise returns false. + */ + P.greaterThanOrEqualTo = P.gte = function ( y, b ) { + id = 7; + return ( b = compare( this, new BigNumber( y, b ) ) ) === 1 || b === 0; + + }; + + + /* + * Return true if the value of this BigNumber is a finite number, otherwise returns false. + */ + P.isFinite = function () { + return !!this.c; + }; + + + /* + * Return true if the value of this BigNumber is an integer, otherwise return false. + */ + P.isInteger = P.isInt = function () { + return !!this.c && bitFloor( this.e / LOG_BASE ) > this.c.length - 2; + }; + + + /* + * Return true if the value of this BigNumber is NaN, otherwise returns false. + */ + P.isNaN = function () { + return !this.s; + }; + + + /* + * Return true if the value of this BigNumber is negative, otherwise returns false. + */ + P.isNegative = P.isNeg = function () { + return this.s < 0; + }; + + + /* + * Return true if the value of this BigNumber is 0 or -0, otherwise returns false. + */ + P.isZero = function () { + return !!this.c && this.c[0] == 0; + }; + + + /* + * Return true if the value of this BigNumber is less than the value of BigNumber(y, b), + * otherwise returns false. + */ + P.lessThan = P.lt = function ( y, b ) { + id = 8; + return compare( this, new BigNumber( y, b ) ) < 0; + }; + + + /* + * Return true if the value of this BigNumber is less than or equal to the value of + * BigNumber(y, b), otherwise returns false. + */ + P.lessThanOrEqualTo = P.lte = function ( y, b ) { + id = 9; + return ( b = compare( this, new BigNumber( y, b ) ) ) === -1 || b === 0; + }; + + + /* + * n - 0 = n + * n - N = N + * n - I = -I + * 0 - n = -n + * 0 - 0 = 0 + * 0 - N = N + * 0 - I = -I + * N - n = N + * N - 0 = N + * N - N = N + * N - I = N + * I - n = I + * I - 0 = I + * I - N = N + * I - I = N + * + * Return a new BigNumber whose value is the value of this BigNumber minus the value of + * BigNumber(y, b). + */ + P.minus = P.sub = function ( y, b ) { + var i, j, t, xLTy, + x = this, + a = x.s; + + id = 10; + y = new BigNumber( y, b ); + b = y.s; + + // Either NaN? + if ( !a || !b ) return new BigNumber(NaN); + + // Signs differ? + if ( a != b ) { + y.s = -b; + return x.plus(y); + } + + var xe = x.e / LOG_BASE, + ye = y.e / LOG_BASE, + xc = x.c, + yc = y.c; + + if ( !xe || !ye ) { + + // Either Infinity? + if ( !xc || !yc ) return xc ? ( y.s = -b, y ) : new BigNumber( yc ? x : NaN ); + + // Either zero? + if ( !xc[0] || !yc[0] ) { + + // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. + return yc[0] ? ( y.s = -b, y ) : new BigNumber( xc[0] ? x : + + // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity + ROUNDING_MODE == 3 ? -0 : 0 ); + } + } + + xe = bitFloor(xe); + ye = bitFloor(ye); + xc = xc.slice(); + + // Determine which is the bigger number. + if ( a = xe - ye ) { + + if ( xLTy = a < 0 ) { + a = -a; + t = xc; + } else { + ye = xe; + t = yc; + } + + t.reverse(); + + // Prepend zeros to equalise exponents. + for ( b = a; b--; t.push(0) ); + t.reverse(); + } else { + + // Exponents equal. Check digit by digit. + j = ( xLTy = ( a = xc.length ) < ( b = yc.length ) ) ? a : b; + + for ( a = b = 0; b < j; b++ ) { + + if ( xc[b] != yc[b] ) { + xLTy = xc[b] < yc[b]; + break; + } + } + } + + // x < y? Point xc to the array of the bigger number. + if (xLTy) t = xc, xc = yc, yc = t, y.s = -y.s; + + b = ( j = yc.length ) - ( i = xc.length ); + + // Append zeros to xc if shorter. + // No need to add zeros to yc if shorter as subtract only needs to start at yc.length. + if ( b > 0 ) for ( ; b--; xc[i++] = 0 ); + b = BASE - 1; + + // Subtract yc from xc. + for ( ; j > a; ) { + + if ( xc[--j] < yc[j] ) { + for ( i = j; i && !xc[--i]; xc[i] = b ); + --xc[i]; + xc[j] += BASE; + } + + xc[j] -= yc[j]; + } + + // Remove leading zeros and adjust exponent accordingly. + for ( ; xc[0] == 0; xc.shift(), --ye ); + + // Zero? + if ( !xc[0] ) { + + // Following IEEE 754 (2008) 6.3, + // n - n = +0 but n - n = -0 when rounding towards -Infinity. + y.s = ROUNDING_MODE == 3 ? -1 : 1; + y.c = [ y.e = 0 ]; + return y; + } + + // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity + // for finite x and y. + return normalise( y, xc, ye ); + }; + + + /* + * n % 0 = N + * n % N = N + * n % I = n + * 0 % n = 0 + * -0 % n = -0 + * 0 % 0 = N + * 0 % N = N + * 0 % I = 0 + * N % n = N + * N % 0 = N + * N % N = N + * N % I = N + * I % n = N + * I % 0 = N + * I % N = N + * I % I = N + * + * Return a new BigNumber whose value is the value of this BigNumber modulo the value of + * BigNumber(y, b). The result depends on the value of MODULO_MODE. + */ + P.modulo = P.mod = function ( y, b ) { + var q, s, + x = this; + + id = 11; + y = new BigNumber( y, b ); + + // Return NaN if x is Infinity or NaN, or y is NaN or zero. + if ( !x.c || !y.s || y.c && !y.c[0] ) { + return new BigNumber(NaN); + + // Return x if y is Infinity or x is zero. + } else if ( !y.c || x.c && !x.c[0] ) { + return new BigNumber(x); + } + + if ( MODULO_MODE == 9 ) { + + // Euclidian division: q = sign(y) * floor(x / abs(y)) + // r = x - qy where 0 <= r < abs(y) + s = y.s; + y.s = 1; + q = div( x, y, 0, 3 ); + y.s = s; + q.s *= s; + } else { + q = div( x, y, 0, MODULO_MODE ); + } + + return x.minus( q.times(y) ); + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber negated, + * i.e. multiplied by -1. + */ + P.negated = P.neg = function () { + var x = new BigNumber(this); + x.s = -x.s || null; + return x; + }; + + + /* + * n + 0 = n + * n + N = N + * n + I = I + * 0 + n = n + * 0 + 0 = 0 + * 0 + N = N + * 0 + I = I + * N + n = N + * N + 0 = N + * N + N = N + * N + I = N + * I + n = I + * I + 0 = I + * I + N = N + * I + I = I + * + * Return a new BigNumber whose value is the value of this BigNumber plus the value of + * BigNumber(y, b). + */ + P.plus = P.add = function ( y, b ) { + var t, + x = this, + a = x.s; + + id = 12; + y = new BigNumber( y, b ); + b = y.s; + + // Either NaN? + if ( !a || !b ) return new BigNumber(NaN); + + // Signs differ? + if ( a != b ) { + y.s = -b; + return x.minus(y); + } + + var xe = x.e / LOG_BASE, + ye = y.e / LOG_BASE, + xc = x.c, + yc = y.c; + + if ( !xe || !ye ) { + + // Return ±Infinity if either ±Infinity. + if ( !xc || !yc ) return new BigNumber( a / 0 ); + + // Either zero? + // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. + if ( !xc[0] || !yc[0] ) return yc[0] ? y : new BigNumber( xc[0] ? x : a * 0 ); + } + + xe = bitFloor(xe); + ye = bitFloor(ye); + xc = xc.slice(); + + // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts. + if ( a = xe - ye ) { + if ( a > 0 ) { + ye = xe; + t = yc; + } else { + a = -a; + t = xc; + } + + t.reverse(); + for ( ; a--; t.push(0) ); + t.reverse(); + } + + a = xc.length; + b = yc.length; + + // Point xc to the longer array, and b to the shorter length. + if ( a - b < 0 ) t = yc, yc = xc, xc = t, b = a; + + // Only start adding at yc.length - 1 as the further digits of xc can be ignored. + for ( a = 0; b; ) { + a = ( xc[--b] = xc[b] + yc[b] + a ) / BASE | 0; + xc[b] %= BASE; + } + + if (a) { + xc.unshift(a); + ++ye; + } + + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + // ye = MAX_EXP + 1 possible + return normalise( y, xc, ye ); + }; + + + /* + * Return the number of significant digits of the value of this BigNumber. + * + * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. + */ + P.precision = P.sd = function (z) { + var n, v, + x = this, + c = x.c; + + // 'precision() argument not a boolean or binary digit: {z}' + if ( z != null && z !== !!z && z !== 1 && z !== 0 ) { + if (ERRORS) raise( 13, 'argument' + notBool, z ); + if ( z != !!z ) z = null; + } + + if ( !c ) return null; + v = c.length - 1; + n = v * LOG_BASE + 1; + + if ( v = c[v] ) { + + // Subtract the number of trailing zeros of the last element. + for ( ; v % 10 == 0; v /= 10, n-- ); + + // Add the number of digits of the first element. + for ( v = c[0]; v >= 10; v /= 10, n++ ); + } + + if ( z && x.e + 1 > n ) n = x.e + 1; + + return n; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber rounded to a maximum of + * dp decimal places using rounding mode rm, or to 0 and ROUNDING_MODE respectively if + * omitted. + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'round() decimal places out of range: {dp}' + * 'round() decimal places not an integer: {dp}' + * 'round() rounding mode not an integer: {rm}' + * 'round() rounding mode out of range: {rm}' + */ + P.round = function ( dp, rm ) { + var n = new BigNumber(this); + + if ( dp == null || isValidInt( dp, 0, MAX, 15 ) ) { + round( n, ~~dp + this.e + 1, rm == null || + !isValidInt( rm, 0, 8, 15, roundingMode ) ? ROUNDING_MODE : rm | 0 ); + } + + return n; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber shifted by k places + * (powers of 10). Shift to the right if n > 0, and to the left if n < 0. + * + * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive. + * + * If k is out of range and ERRORS is false, the result will be ±0 if k < 0, or ±Infinity + * otherwise. + * + * 'shift() argument not an integer: {k}' + * 'shift() argument out of range: {k}' + */ + P.shift = function (k) { + var n = this; + return isValidInt( k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 16, 'argument' ) + + // k < 1e+21, or truncate(k) will produce exponential notation. + ? n.times( '1e' + truncate(k) ) + : new BigNumber( n.c && n.c[0] && ( k < -MAX_SAFE_INTEGER || k > MAX_SAFE_INTEGER ) + ? n.s * ( k < 0 ? 0 : 1 / 0 ) + : n ); + }; + + + /* + * sqrt(-n) = N + * sqrt( N) = N + * sqrt(-I) = N + * sqrt( I) = I + * sqrt( 0) = 0 + * sqrt(-0) = -0 + * + * Return a new BigNumber whose value is the square root of the value of this BigNumber, + * rounded according to DECIMAL_PLACES and ROUNDING_MODE. + */ + P.squareRoot = P.sqrt = function () { + var m, n, r, rep, t, + x = this, + c = x.c, + s = x.s, + e = x.e, + dp = DECIMAL_PLACES + 4, + half = new BigNumber('0.5'); + + // Negative/NaN/Infinity/zero? + if ( s !== 1 || !c || !c[0] ) { + return new BigNumber( !s || s < 0 && ( !c || c[0] ) ? NaN : c ? x : 1 / 0 ); + } + + // Initial estimate. + s = Math.sqrt( +x ); + + // Math.sqrt underflow/overflow? + // Pass x to Math.sqrt as integer, then adjust the exponent of the result. + if ( s == 0 || s == 1 / 0 ) { + n = coeffToString(c); + if ( ( n.length + e ) % 2 == 0 ) n += '0'; + s = Math.sqrt(n); + e = bitFloor( ( e + 1 ) / 2 ) - ( e < 0 || e % 2 ); + + if ( s == 1 / 0 ) { + n = '1e' + e; + } else { + n = s.toExponential(); + n = n.slice( 0, n.indexOf('e') + 1 ) + e; + } + + r = new BigNumber(n); + } else { + r = new BigNumber( s + '' ); + } + + // Check for zero. + // r could be zero if MIN_EXP is changed after the this value was created. + // This would cause a division by zero (x/t) and hence Infinity below, which would cause + // coeffToString to throw. + if ( r.c[0] ) { + e = r.e; + s = e + dp; + if ( s < 3 ) s = 0; + + // Newton-Raphson iteration. + for ( ; ; ) { + t = r; + r = half.times( t.plus( div( x, t, dp, 1 ) ) ); + + if ( coeffToString( t.c ).slice( 0, s ) === ( n = + coeffToString( r.c ) ).slice( 0, s ) ) { + + // The exponent of r may here be one less than the final result exponent, + // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits + // are indexed correctly. + if ( r.e < e ) --s; + n = n.slice( s - 3, s + 1 ); + + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits + // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the + // iteration. + if ( n == '9999' || !rep && n == '4999' ) { + + // On the first iteration only, check to see if rounding up gives the + // exact result as the nines may infinitely repeat. + if ( !rep ) { + round( t, t.e + DECIMAL_PLACES + 2, 0 ); + + if ( t.times(t).eq(x) ) { + r = t; + break; + } + } + + dp += 4; + s += 4; + rep = 1; + } else { + + // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact + // result. If not, then there are further digits and m will be truthy. + if ( !+n || !+n.slice(1) && n.charAt(0) == '5' ) { + + // Truncate to the first rounding digit. + round( r, r.e + DECIMAL_PLACES + 2, 1 ); + m = !r.times(r).eq(x); + } + + break; + } + } + } + } + + return round( r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m ); + }; + + + /* + * n * 0 = 0 + * n * N = N + * n * I = I + * 0 * n = 0 + * 0 * 0 = 0 + * 0 * N = N + * 0 * I = N + * N * n = N + * N * 0 = N + * N * N = N + * N * I = N + * I * n = I + * I * 0 = N + * I * N = N + * I * I = I + * + * Return a new BigNumber whose value is the value of this BigNumber times the value of + * BigNumber(y, b). + */ + P.times = P.mul = function ( y, b ) { + var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc, + base, sqrtBase, + x = this, + xc = x.c, + yc = ( id = 17, y = new BigNumber( y, b ) ).c; + + // Either NaN, ±Infinity or ±0? + if ( !xc || !yc || !xc[0] || !yc[0] ) { + + // Return NaN if either is NaN, or one is 0 and the other is Infinity. + if ( !x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc ) { + y.c = y.e = y.s = null; + } else { + y.s *= x.s; + + // Return ±Infinity if either is ±Infinity. + if ( !xc || !yc ) { + y.c = y.e = null; + + // Return ±0 if either is ±0. + } else { + y.c = [0]; + y.e = 0; + } + } + + return y; + } + + e = bitFloor( x.e / LOG_BASE ) + bitFloor( y.e / LOG_BASE ); + y.s *= x.s; + xcL = xc.length; + ycL = yc.length; + + // Ensure xc points to longer array and xcL to its length. + if ( xcL < ycL ) zc = xc, xc = yc, yc = zc, i = xcL, xcL = ycL, ycL = i; + + // Initialise the result array with zeros. + for ( i = xcL + ycL, zc = []; i--; zc.push(0) ); + + base = BASE; + sqrtBase = SQRT_BASE; + + for ( i = ycL; --i >= 0; ) { + c = 0; + ylo = yc[i] % sqrtBase; + yhi = yc[i] / sqrtBase | 0; + + for ( k = xcL, j = i + k; j > i; ) { + xlo = xc[--k] % sqrtBase; + xhi = xc[k] / sqrtBase | 0; + m = yhi * xlo + xhi * ylo; + xlo = ylo * xlo + ( ( m % sqrtBase ) * sqrtBase ) + zc[j] + c; + c = ( xlo / base | 0 ) + ( m / sqrtBase | 0 ) + yhi * xhi; + zc[j--] = xlo % base; + } + + zc[j] = c; + } + + if (c) { + ++e; + } else { + zc.shift(); + } + + return normalise( y, zc, e ); + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber rounded to a maximum of + * sd significant digits using rounding mode rm, or ROUNDING_MODE if rm is omitted. + * + * [sd] {number} Significant digits. Integer, 1 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toDigits() precision out of range: {sd}' + * 'toDigits() precision not an integer: {sd}' + * 'toDigits() rounding mode not an integer: {rm}' + * 'toDigits() rounding mode out of range: {rm}' + */ + P.toDigits = function ( sd, rm ) { + var n = new BigNumber(this); + sd = sd == null || !isValidInt( sd, 1, MAX, 18, 'precision' ) ? null : sd | 0; + rm = rm == null || !isValidInt( rm, 0, 8, 18, roundingMode ) ? ROUNDING_MODE : rm | 0; + return sd ? round( n, sd, rm ) : n; + }; + + + /* + * Return a string representing the value of this BigNumber in exponential notation and + * rounded using ROUNDING_MODE to dp fixed decimal places. + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toExponential() decimal places not an integer: {dp}' + * 'toExponential() decimal places out of range: {dp}' + * 'toExponential() rounding mode not an integer: {rm}' + * 'toExponential() rounding mode out of range: {rm}' + */ + P.toExponential = function ( dp, rm ) { + return format( this, + dp != null && isValidInt( dp, 0, MAX, 19 ) ? ~~dp + 1 : null, rm, 19 ); + }; + + + /* + * Return a string representing the value of this BigNumber in fixed-point notation rounding + * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted. + * + * Note: as with JavaScript's number type, (-0).toFixed(0) is '0', + * but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toFixed() decimal places not an integer: {dp}' + * 'toFixed() decimal places out of range: {dp}' + * 'toFixed() rounding mode not an integer: {rm}' + * 'toFixed() rounding mode out of range: {rm}' + */ + P.toFixed = function ( dp, rm ) { + return format( this, dp != null && isValidInt( dp, 0, MAX, 20 ) + ? ~~dp + this.e + 1 : null, rm, 20 ); + }; + + + /* + * Return a string representing the value of this BigNumber in fixed-point notation rounded + * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties + * of the FORMAT object (see BigNumber.config). + * + * FORMAT = { + * decimalSeparator : '.', + * groupSeparator : ',', + * groupSize : 3, + * secondaryGroupSize : 0, + * fractionGroupSeparator : '\xA0', // non-breaking space + * fractionGroupSize : 0 + * }; + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toFormat() decimal places not an integer: {dp}' + * 'toFormat() decimal places out of range: {dp}' + * 'toFormat() rounding mode not an integer: {rm}' + * 'toFormat() rounding mode out of range: {rm}' + */ + P.toFormat = function ( dp, rm ) { + var str = format( this, dp != null && isValidInt( dp, 0, MAX, 21 ) + ? ~~dp + this.e + 1 : null, rm, 21 ); + + if ( this.c ) { + var i, + arr = str.split('.'), + g1 = +FORMAT.groupSize, + g2 = +FORMAT.secondaryGroupSize, + groupSeparator = FORMAT.groupSeparator, + intPart = arr[0], + fractionPart = arr[1], + isNeg = this.s < 0, + intDigits = isNeg ? intPart.slice(1) : intPart, + len = intDigits.length; + + if (g2) i = g1, g1 = g2, g2 = i, len -= i; + + if ( g1 > 0 && len > 0 ) { + i = len % g1 || g1; + intPart = intDigits.substr( 0, i ); + + for ( ; i < len; i += g1 ) { + intPart += groupSeparator + intDigits.substr( i, g1 ); + } + + if ( g2 > 0 ) intPart += groupSeparator + intDigits.slice(i); + if (isNeg) intPart = '-' + intPart; + } + + str = fractionPart + ? intPart + FORMAT.decimalSeparator + ( ( g2 = +FORMAT.fractionGroupSize ) + ? fractionPart.replace( new RegExp( '\\d{' + g2 + '}\\B', 'g' ), + '$&' + FORMAT.fractionGroupSeparator ) + : fractionPart ) + : intPart; + } + + return str; + }; + + + /* + * Return a string array representing the value of this BigNumber as a simple fraction with + * an integer numerator and an integer denominator. The denominator will be a positive + * non-zero value less than or equal to the specified maximum denominator. If a maximum + * denominator is not specified, the denominator will be the lowest value necessary to + * represent the number exactly. + * + * [md] {number|string|BigNumber} Integer >= 1 and < Infinity. The maximum denominator. + * + * 'toFraction() max denominator not an integer: {md}' + * 'toFraction() max denominator out of range: {md}' + */ + P.toFraction = function (md) { + var arr, d0, d2, e, exp, n, n0, q, s, + k = ERRORS, + x = this, + xc = x.c, + d = new BigNumber(ONE), + n1 = d0 = new BigNumber(ONE), + d1 = n0 = new BigNumber(ONE); + + if ( md != null ) { + ERRORS = false; + n = new BigNumber(md); + ERRORS = k; + + if ( !( k = n.isInt() ) || n.lt(ONE) ) { + + if (ERRORS) { + raise( 22, + 'max denominator ' + ( k ? 'out of range' : 'not an integer' ), md ); + } + + // ERRORS is false: + // If md is a finite non-integer >= 1, round it to an integer and use it. + md = !k && n.c && round( n, n.e + 1, 1 ).gte(ONE) ? n : null; + } + } + + if ( !xc ) return x.toString(); + s = coeffToString(xc); + + // Determine initial denominator. + // d is a power of 10 and the minimum max denominator that specifies the value exactly. + e = d.e = s.length - x.e - 1; + d.c[0] = POWS_TEN[ ( exp = e % LOG_BASE ) < 0 ? LOG_BASE + exp : exp ]; + md = !md || n.cmp(d) > 0 ? ( e > 0 ? d : n1 ) : n; + + exp = MAX_EXP; + MAX_EXP = 1 / 0; + n = new BigNumber(s); + + // n0 = d1 = 0 + n0.c[0] = 0; + + for ( ; ; ) { + q = div( n, d, 0, 1 ); + d2 = d0.plus( q.times(d1) ); + if ( d2.cmp(md) == 1 ) break; + d0 = d1; + d1 = d2; + n1 = n0.plus( q.times( d2 = n1 ) ); + n0 = d2; + d = n.minus( q.times( d2 = d ) ); + n = d2; + } + + d2 = div( md.minus(d0), d1, 0, 1 ); + n0 = n0.plus( d2.times(n1) ); + d0 = d0.plus( d2.times(d1) ); + n0.s = n1.s = x.s; + e *= 2; + + // Determine which fraction is closer to x, n0/d0 or n1/d1 + arr = div( n1, d1, e, ROUNDING_MODE ).minus(x).abs().cmp( + div( n0, d0, e, ROUNDING_MODE ).minus(x).abs() ) < 1 + ? [ n1.toString(), d1.toString() ] + : [ n0.toString(), d0.toString() ]; + + MAX_EXP = exp; + return arr; + }; + + + /* + * Return the value of this BigNumber converted to a number primitive. + */ + P.toNumber = function () { + return +this; + }; + + + /* + * Return a BigNumber whose value is the value of this BigNumber raised to the power n. + * If m is present, return the result modulo m. + * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE. + * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using + * ROUNDING_MODE. + * + * The modular power operation works efficiently when x, n, and m are positive integers, + * otherwise it is equivalent to calculating x.toPower(n).modulo(m) (with POW_PRECISION 0). + * + * n {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive. + * [m] {number|string|BigNumber} The modulus. + * + * 'pow() exponent not an integer: {n}' + * 'pow() exponent out of range: {n}' + * + * Performs 54 loop iterations for n of 9007199254740991. + */ + P.toPower = P.pow = function ( n, m ) { + var k, y, z, + i = mathfloor( n < 0 ? -n : +n ), + x = this; + + if ( m != null ) { + id = 23; + m = new BigNumber(m); + } + + // Pass ±Infinity to Math.pow if exponent is out of range. + if ( !isValidInt( n, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 23, 'exponent' ) && + ( !isFinite(n) || i > MAX_SAFE_INTEGER && ( n /= 0 ) || + parseFloat(n) != n && !( n = NaN ) ) || n == 0 ) { + k = Math.pow( +x, n ); + return new BigNumber( m ? k % m : k ); + } + + if (m) { + if ( n > 1 && x.gt(ONE) && x.isInt() && m.gt(ONE) && m.isInt() ) { + x = x.mod(m); + } else { + z = m; + + // Nullify m so only a single mod operation is performed at the end. + m = null; + } + } else if (POW_PRECISION) { + + // Truncating each coefficient array to a length of k after each multiplication + // equates to truncating significant digits to POW_PRECISION + [28, 41], + // i.e. there will be a minimum of 28 guard digits retained. + // (Using + 1.5 would give [9, 21] guard digits.) + k = mathceil( POW_PRECISION / LOG_BASE + 2 ); + } + + y = new BigNumber(ONE); + + for ( ; ; ) { + if ( i % 2 ) { + y = y.times(x); + if ( !y.c ) break; + if (k) { + if ( y.c.length > k ) y.c.length = k; + } else if (m) { + y = y.mod(m); + } + } + + i = mathfloor( i / 2 ); + if ( !i ) break; + x = x.times(x); + if (k) { + if ( x.c && x.c.length > k ) x.c.length = k; + } else if (m) { + x = x.mod(m); + } + } + + if (m) return y; + if ( n < 0 ) y = ONE.div(y); + + return z ? y.mod(z) : k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y; + }; + + + /* + * Return a string representing the value of this BigNumber rounded to sd significant digits + * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits + * necessary to represent the integer part of the value in fixed-point notation, then use + * exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toPrecision() precision not an integer: {sd}' + * 'toPrecision() precision out of range: {sd}' + * 'toPrecision() rounding mode not an integer: {rm}' + * 'toPrecision() rounding mode out of range: {rm}' + */ + P.toPrecision = function ( sd, rm ) { + return format( this, sd != null && isValidInt( sd, 1, MAX, 24, 'precision' ) + ? sd | 0 : null, rm, 24 ); + }; + + + /* + * Return a string representing the value of this BigNumber in base b, or base 10 if b is + * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and + * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent + * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than + * TO_EXP_NEG, return exponential notation. + * + * [b] {number} Integer, 2 to 64 inclusive. + * + * 'toString() base not an integer: {b}' + * 'toString() base out of range: {b}' + */ + P.toString = function (b) { + var str, + n = this, + s = n.s, + e = n.e; + + // Infinity or NaN? + if ( e === null ) { + + if (s) { + str = 'Infinity'; + if ( s < 0 ) str = '-' + str; + } else { + str = 'NaN'; + } + } else { + str = coeffToString( n.c ); + + if ( b == null || !isValidInt( b, 2, 64, 25, 'base' ) ) { + str = e <= TO_EXP_NEG || e >= TO_EXP_POS + ? toExponential( str, e ) + : toFixedPoint( str, e ); + } else { + str = convertBase( toFixedPoint( str, e ), b | 0, 10, s ); + } + + if ( s < 0 && n.c[0] ) str = '-' + str; + } + + return str; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber truncated to a whole + * number. + */ + P.truncated = P.trunc = function () { + return round( new BigNumber(this), this.e + 1, 1 ); + }; + + + + /* + * Return as toString, but do not accept a base argument, and include the minus sign for + * negative zero. + */ + P.valueOf = P.toJSON = function () { + var str, + n = this, + e = n.e; + + if ( e === null ) return n.toString(); + + str = coeffToString( n.c ); + + str = e <= TO_EXP_NEG || e >= TO_EXP_POS + ? toExponential( str, e ) + : toFixedPoint( str, e ); + + return n.s < 0 ? '-' + str : str; + }; + + + // Aliases for BigDecimal methods. + //P.add = P.plus; // P.add included above + //P.subtract = P.minus; // P.sub included above + //P.multiply = P.times; // P.mul included above + //P.divide = P.div; + //P.remainder = P.mod; + //P.compareTo = P.cmp; + //P.negate = P.neg; + + + if ( configObj != null ) BigNumber.config(configObj); + + return BigNumber; + } + + + // PRIVATE HELPER FUNCTIONS + + + function bitFloor(n) { + var i = n | 0; + return n > 0 || n === i ? i : i - 1; + } + + + // Return a coefficient array as a string of base 10 digits. + function coeffToString(a) { + var s, z, + i = 1, + j = a.length, + r = a[0] + ''; + + for ( ; i < j; ) { + s = a[i++] + ''; + z = LOG_BASE - s.length; + for ( ; z--; s = '0' + s ); + r += s; + } + + // Determine trailing zeros. + for ( j = r.length; r.charCodeAt(--j) === 48; ); + return r.slice( 0, j + 1 || 1 ); + } + + + // Compare the value of BigNumbers x and y. + function compare( x, y ) { + var a, b, + xc = x.c, + yc = y.c, + i = x.s, + j = y.s, + k = x.e, + l = y.e; + + // Either NaN? + if ( !i || !j ) return null; + + a = xc && !xc[0]; + b = yc && !yc[0]; + + // Either zero? + if ( a || b ) return a ? b ? 0 : -j : i; + + // Signs differ? + if ( i != j ) return i; + + a = i < 0; + b = k == l; + + // Either Infinity? + if ( !xc || !yc ) return b ? 0 : !xc ^ a ? 1 : -1; + + // Compare exponents. + if ( !b ) return k > l ^ a ? 1 : -1; + + j = ( k = xc.length ) < ( l = yc.length ) ? k : l; + + // Compare digit by digit. + for ( i = 0; i < j; i++ ) if ( xc[i] != yc[i] ) return xc[i] > yc[i] ^ a ? 1 : -1; + + // Compare lengths. + return k == l ? 0 : k > l ^ a ? 1 : -1; + } + + + /* + * Return true if n is a valid number in range, otherwise false. + * Use for argument validation when ERRORS is false. + * Note: parseInt('1e+1') == 1 but parseFloat('1e+1') == 10. + */ + function intValidatorNoErrors( n, min, max ) { + return ( n = truncate(n) ) >= min && n <= max; + } + + + function isArray(obj) { + return Object.prototype.toString.call(obj) == '[object Array]'; + } + + + /* + * Convert string of baseIn to an array of numbers of baseOut. + * Eg. convertBase('255', 10, 16) returns [15, 15]. + * Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. + */ + function toBaseOut( str, baseIn, baseOut ) { + var j, + arr = [0], + arrL, + i = 0, + len = str.length; + + for ( ; i < len; ) { + for ( arrL = arr.length; arrL--; arr[arrL] *= baseIn ); + arr[ j = 0 ] += ALPHABET.indexOf( str.charAt( i++ ) ); + + for ( ; j < arr.length; j++ ) { + + if ( arr[j] > baseOut - 1 ) { + if ( arr[j + 1] == null ) arr[j + 1] = 0; + arr[j + 1] += arr[j] / baseOut | 0; + arr[j] %= baseOut; + } + } + } + + return arr.reverse(); + } + + + function toExponential( str, e ) { + return ( str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str ) + + ( e < 0 ? 'e' : 'e+' ) + e; + } + + + function toFixedPoint( str, e ) { + var len, z; + + // Negative exponent? + if ( e < 0 ) { + + // Prepend zeros. + for ( z = '0.'; ++e; z += '0' ); + str = z + str; + + // Positive exponent + } else { + len = str.length; + + // Append zeros. + if ( ++e > len ) { + for ( z = '0', e -= len; --e; z += '0' ); + str += z; + } else if ( e < len ) { + str = str.slice( 0, e ) + '.' + str.slice(e); + } + } + + return str; + } + + + function truncate(n) { + n = parseFloat(n); + return n < 0 ? mathceil(n) : mathfloor(n); + } + + + // EXPORT + + + // AMD. + if ( typeof define == 'function' && define.amd ) { + define( function () { return constructorFactory(); } ); + + // Node.js and other environments that support module.exports. + } else if ( typeof module != 'undefined' && module.exports ) { + module.exports = constructorFactory(); + + // Split string stops browserify adding crypto shim. + if ( !cryptoObj ) try { cryptoObj = require('cry' + 'pto'); } catch (e) {} + + // Browser. + } else { + if ( !globalObj ) globalObj = typeof self != 'undefined' ? self : Function('return this')(); + globalObj.BigNumber = constructorFactory(); + } +})(this); diff --git a/node_modules/bignumber.js/bignumber.js.map b/node_modules/bignumber.js/bignumber.js.map new file mode 100644 index 0000000..27f146a --- /dev/null +++ b/node_modules/bignumber.js/bignumber.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bignumber.min.js","sources":["bignumber.js"],"names":["globalObj","constructorFactory","configObj","BigNumber","n","b","c","e","i","num","len","str","x","this","ERRORS","raise","isValidInt","id","round","DECIMAL_PLACES","ROUNDING_MODE","RegExp","ALPHABET","slice","test","parseNumeric","s","replace","length","tooManyDigits","charCodeAt","convertBase","isNumeric","indexOf","search","substring","MAX_SAFE_INTEGER","mathfloor","MAX_EXP","MIN_EXP","LOG_BASE","push","baseOut","baseIn","sign","d","k","r","xc","y","dp","rm","toLowerCase","POW_PRECISION","pow","toBaseOut","toFixedPoint","coeffToString","pop","div","unshift","charAt","format","caller","c0","ne","roundingMode","toString","TO_EXP_NEG","toExponential","maxOrMin","args","method","m","isArray","call","intValidatorWithErrors","min","max","name","truncate","normalise","j","msg","val","error","Error","sd","ni","rd","pows10","POWS_TEN","out","mathceil","BASE","P","prototype","ONE","TO_EXP_POS","CRYPTO","MODULO_MODE","FORMAT","decimalSeparator","groupSeparator","groupSize","secondaryGroupSize","fractionGroupSeparator","fractionGroupSize","another","ROUND_UP","ROUND_DOWN","ROUND_CEIL","ROUND_FLOOR","ROUND_HALF_UP","ROUND_HALF_DOWN","ROUND_HALF_EVEN","ROUND_HALF_CEIL","ROUND_HALF_FLOOR","EUCLID","config","v","p","a","arguments","o","has","hasOwnProperty","MAX","intValidatorNoErrors","notBool","cryptoObj","lt","gt","random","pow2_53","random53bitInt","Math","rand","getRandomValues","Uint32Array","randomBytes","copy","shift","multiply","base","temp","xlo","xhi","carry","klo","SQRT_BASE","khi","compare","aL","bL","cmp","subtract","more","prod","prodL","q","qc","rem","remL","rem0","xi","xL","yc0","yL","yz","yc","NaN","bitFloor","basePrefix","dotAfter","dotBefore","isInfinityOrNaN","whitespaceOrPlus","isNaN","p1","p2","absoluteValue","abs","ceil","comparedTo","decimalPlaces","dividedBy","dividedToIntegerBy","divToInt","equals","eq","floor","greaterThan","greaterThanOrEqualTo","gte","isFinite","isInteger","isInt","isNegative","isNeg","isZero","lessThan","lessThanOrEqualTo","lte","minus","sub","t","xLTy","plus","xe","ye","reverse","modulo","mod","times","negated","neg","add","precision","z","squareRoot","sqrt","rep","half","mul","xcL","ycL","ylo","yhi","zc","sqrtBase","toDigits","toFixed","toFormat","arr","split","g1","g2","intPart","fractionPart","intDigits","substr","toFraction","md","d0","d2","exp","n0","n1","d1","toNumber","toPower","parseFloat","toPrecision","truncated","trunc","valueOf","toJSON","l","obj","Object","arrL","crypto","define","amd","module","exports","require","self","Function"],"mappings":";CAEC,SAAWA,GACR,YAuCA,SAASC,GAAmBC,GAiHxB,QAASC,GAAWC,EAAGC,GACnB,GAAIC,GAAGC,EAAGC,EAAGC,EAAKC,EAAKC,EACnBC,EAAIC,IAGR,MAAQD,YAAaT,IAIjB,MADIW,IAAQC,EAAO,GAAI,+BAAgCX,GAChD,GAAID,GAAWC,EAAGC,EAK7B,IAAU,MAALA,GAAcW,EAAYX,EAAG,EAAG,GAAIY,EAAI,QA4BtC,CAMH,GALAZ,EAAQ,EAAJA,EACJM,EAAMP,EAAI,GAIA,IAALC,EAED,MADAO,GAAI,GAAIT,GAAWC,YAAaD,GAAYC,EAAIO,GACzCO,EAAON,EAAGO,EAAiBP,EAAEL,EAAI,EAAGa,EAK/C,KAAOX,EAAkB,gBAALL,KAAuB,EAAJA,GAAS,IAC7C,GAAMiB,QAAQ,OAAUf,EAAI,IAAMgB,EAASC,MAAO,EAAGlB,GAAM,MAC1D,SAAWC,EAAI,MAAU,GAAJD,EAAS,IAAM,IAAOmB,KAAKb,GAChD,MAAOc,GAAcb,EAAGD,EAAKF,EAAKJ,EAGlCI,IACAG,EAAEc,EAAY,EAAR,EAAItB,GAAUO,EAAMA,EAAIY,MAAM,GAAI,IAAO,EAE1CT,GAAUH,EAAIgB,QAAS,YAAa,IAAKC,OAAS,IAGnDb,EAAOE,EAAIY,EAAezB,GAI9BK,GAAM,GAENG,EAAEc,EAA0B,KAAtBf,EAAImB,WAAW,IAAcnB,EAAMA,EAAIY,MAAM,GAAI,IAAO,EAGlEZ,EAAMoB,EAAapB,EAAK,GAAIN,EAAGO,EAAEc,OA9DmB,CAGpD,GAAKtB,YAAaD,GAKd,MAJAS,GAAEc,EAAItB,EAAEsB,EACRd,EAAEL,EAAIH,EAAEG,EACRK,EAAEN,GAAMF,EAAIA,EAAEE,GAAMF,EAAEmB,QAAUnB,OAChCa,EAAK,EAIT,KAAOR,EAAkB,gBAALL,KAAuB,EAAJA,GAAS,EAAI,CAIhD,GAHAQ,EAAEc,EAAY,EAAR,EAAItB,GAAUA,GAAKA,EAAG,IAAO,EAG9BA,MAAQA,EAAI,CACb,IAAMG,EAAI,EAAGC,EAAIJ,EAAGI,GAAK,GAAIA,GAAK,GAAID,KAItC,MAHAK,GAAEL,EAAIA,EACNK,EAAEN,GAAKF,QACPa,EAAK,GAITN,EAAMP,EAAI,OACP,CACH,IAAM4B,EAAUR,KAAMb,EAAMP,EAAI,IAAO,MAAOqB,GAAcb,EAAGD,EAAKF,EACpEG,GAAEc,EAA0B,KAAtBf,EAAImB,WAAW,IAAcnB,EAAMA,EAAIY,MAAM,GAAI,IAAO,GAwDtE,KAhBOhB,EAAII,EAAIsB,QAAQ,MAAS,KAAKtB,EAAMA,EAAIgB,QAAS,IAAK,MAGtDnB,EAAIG,EAAIuB,OAAQ,OAAW,GAGrB,EAAJ3B,IAAQA,EAAIC,GACjBD,IAAMI,EAAIY,MAAOf,EAAI,GACrBG,EAAMA,EAAIwB,UAAW,EAAG3B,IACZ,EAAJD,IAGRA,EAAII,EAAIiB,QAINpB,EAAI,EAAyB,KAAtBG,EAAImB,WAAWtB,GAAWA,KAGvC,IAAME,EAAMC,EAAIiB,OAAkC,KAA1BjB,EAAImB,aAAapB,KAGzC,GAFAC,EAAMA,EAAIY,MAAOf,EAAGE,EAAM,GActB,GAXAA,EAAMC,EAAIiB,OAILnB,GAAOK,GAAUJ,EAAM,KAAQN,EAAIgC,GAAoBhC,IAAMiC,EAAUjC,KACxEW,EAAOE,EAAIY,EAAejB,EAAEc,EAAItB,GAGpCG,EAAIA,EAAIC,EAAI,EAGPD,EAAI+B,EAGL1B,EAAEN,EAAIM,EAAEL,EAAI,SAGT,IAASgC,EAAJhC,EAGRK,EAAEN,GAAMM,EAAEL,EAAI,OACX,CAWH,GAVAK,EAAEL,EAAIA,EACNK,EAAEN,KAMFE,GAAMD,EAAI,GAAMiC,EACP,EAAJjC,IAAQC,GAAKgC,GAET9B,EAAJF,EAAU,CAGX,IAFIA,GAAGI,EAAEN,EAAEmC,MAAO9B,EAAIY,MAAO,EAAGf,IAE1BE,GAAO8B,EAAc9B,EAAJF,GACnBI,EAAEN,EAAEmC,MAAO9B,EAAIY,MAAOf,EAAGA,GAAKgC,GAGlC7B,GAAMA,EAAIY,MAAMf,GAChBA,EAAIgC,EAAW7B,EAAIiB,WAEnBpB,IAAKE,CAGT,MAAQF,IAAKG,GAAO,KACpBC,EAAEN,EAAEmC,MAAO9B,OAKfC,GAAEN,GAAMM,EAAEL,EAAI,EAGlBU,GAAK,EAgVT,QAASc,GAAapB,EAAK+B,EAASC,EAAQC,GACxC,GAAIC,GAAGtC,EAAGuC,EAAGC,EAAGnC,EAAGoC,EAAIC,EACnBzC,EAAIG,EAAIsB,QAAS,KACjBiB,EAAK/B,EACLgC,EAAK/B,CA0BT,KAxBc,GAATuB,IAAchC,EAAMA,EAAIyC,eAGxB5C,GAAK,IACNsC,EAAIO,EAGJA,EAAgB,EAChB1C,EAAMA,EAAIgB,QAAS,IAAK,IACxBsB,EAAI,GAAI9C,GAAUwC,GAClB/B,EAAIqC,EAAEK,IAAK3C,EAAIiB,OAASpB,GACxB6C,EAAgBP,EAIhBG,EAAE3C,EAAIiD,EAAWC,EAAcC,EAAe7C,EAAEN,GAAKM,EAAEL,GAAK,GAAImC,GAChEO,EAAE1C,EAAI0C,EAAE3C,EAAEsB,QAIdoB,EAAKO,EAAW5C,EAAKgC,EAAQD,GAC7BnC,EAAIuC,EAAIE,EAAGpB,OAGQ,GAAXoB,IAAKF,GAASE,EAAGU,OACzB,IAAMV,EAAG,GAAK,MAAO,GA2BrB,IAzBS,EAAJxC,IACCD,GAEFK,EAAEN,EAAI0C,EACNpC,EAAEL,EAAIA,EAGNK,EAAEc,EAAIkB,EACNhC,EAAI+C,EAAK/C,EAAGqC,EAAGC,EAAIC,EAAIT,GACvBM,EAAKpC,EAAEN,EACPyC,EAAInC,EAAEmC,EACNxC,EAAIK,EAAEL,GAGVsC,EAAItC,EAAI2C,EAAK,EAGb1C,EAAIwC,EAAGH,GACPC,EAAIJ,EAAU,EACdK,EAAIA,GAAS,EAAJF,GAAsB,MAAbG,EAAGH,EAAI,GAEzBE,EAAS,EAALI,GAAgB,MAAL3C,GAAauC,KAAe,GAANI,GAAWA,IAAQvC,EAAEc,EAAI,EAAI,EAAI,IACzDlB,EAAIsC,GAAKtC,GAAKsC,IAAY,GAANK,GAAWJ,GAAW,GAANI,GAAuB,EAAZH,EAAGH,EAAI,IACtDM,IAAQvC,EAAEc,EAAI,EAAI,EAAI,IAE1B,EAAJmB,IAAUG,EAAG,GAGdrC,EAAMoC,EAAIS,EAAc,KAAMN,GAAO,QAClC,CAGH,GAFAF,EAAGpB,OAASiB,EAERE,EAGA,MAAQL,IAAWM,IAAKH,GAAKH,GACzBM,EAAGH,GAAK,EAEFA,MACAtC,EACFyC,EAAGY,QAAQ,GAMvB,KAAMd,EAAIE,EAAGpB,QAASoB,IAAKF,KAG3B,IAAMtC,EAAI,EAAGG,EAAM,GAASmC,GAALtC,EAAQG,GAAOW,EAASuC,OAAQb,EAAGxC,OAC1DG,EAAM6C,EAAc7C,EAAKJ,GAI7B,MAAOI,GA4QX,QAASmD,GAAQ1D,EAAGI,EAAG2C,EAAIY,GACvB,GAAIC,GAAIzD,EAAG0D,EAAIvD,EAAKC,CAKpB,IAHAwC,EAAW,MAANA,GAAcnC,EAAYmC,EAAI,EAAG,EAAGY,EAAQG,GACxC,EAALf,EAAS/B,GAEPhB,EAAEE,EAAI,MAAOF,GAAE+D,UAIrB,IAHAH,EAAK5D,EAAEE,EAAE,GACT2D,EAAK7D,EAAEG,EAEG,MAALC,EACDG,EAAM8C,EAAerD,EAAEE,GACvBK,EAAgB,IAAVoD,GAA0B,IAAVA,GAAsBK,GAANH,EAClCI,EAAe1D,EAAKsD,GACpBT,EAAc7C,EAAKsD,OAevB,IAbA7D,EAAIc,EAAO,GAAIf,GAAUC,GAAII,EAAG2C,GAGhC5C,EAAIH,EAAEG,EAENI,EAAM8C,EAAerD,EAAEE,GACvBI,EAAMC,EAAIiB,OAOK,IAAVmC,GAA0B,IAAVA,IAAuBxD,GAALC,GAAe4D,GAAL7D,GAAoB,CAGjE,KAAcC,EAANE,EAASC,GAAO,IAAKD,KAC7BC,EAAM0D,EAAe1D,EAAKJ,OAQ1B,IAJAC,GAAKyD,EACLtD,EAAM6C,EAAc7C,EAAKJ,GAGpBA,EAAI,EAAIG,GACT,KAAOF,EAAI,EAAI,IAAMG,GAAO,IAAKH,IAAKG,GAAO,UAG7C,IADAH,GAAKD,EAAIG,EACJF,EAAI,EAEL,IADKD,EAAI,GAAKG,IAAMC,GAAO,KACnBH,IAAKG,GAAO,KAMpC,MAAOP,GAAEsB,EAAI,GAAKsC,EAAK,IAAMrD,EAAMA,EAKvC,QAAS2D,GAAUC,EAAMC,GACrB,GAAIC,GAAGrE,EACHI,EAAI,CAKR,KAHKkE,EAASH,EAAK,MAAOA,EAAOA,EAAK,IACtCE,EAAI,GAAItE,GAAWoE,EAAK,MAEd/D,EAAI+D,EAAK3C,QAAU,CAIzB,GAHAxB,EAAI,GAAID,GAAWoE,EAAK/D,KAGlBJ,EAAEsB,EAAI,CACR+C,EAAIrE,CACJ,OACQoE,EAAOG,KAAMF,EAAGrE,KACxBqE,EAAIrE,GAIZ,MAAOqE,GAQX,QAASG,GAAwBxE,EAAGyE,EAAKC,EAAKf,EAAQgB,GAMlD,OALSF,EAAJzE,GAAWA,EAAI0E,GAAO1E,GAAK4E,EAAS5E,KACrCW,EAAOgD,GAAUgB,GAAQ,mBACjBF,EAAJzE,GAAWA,EAAI0E,EAAM,gBAAkB,mBAAqB1E,IAG7D,EAQX,QAAS6E,GAAW7E,EAAGE,EAAGC,GAKtB,IAJA,GAAIC,GAAI,EACJ0E,EAAI5E,EAAEsB,QAGDtB,IAAI4E,GAAI5E,EAAEoD,OAGnB,IAAMwB,EAAI5E,EAAE,GAAI4E,GAAK,GAAIA,GAAK,GAAI1E,KAkBlC,OAfOD,EAAIC,EAAID,EAAIiC,EAAW,GAAMF,EAGhClC,EAAEE,EAAIF,EAAEG,EAAI,KAGAgC,EAAJhC,EAGRH,EAAEE,GAAMF,EAAEG,EAAI,IAEdH,EAAEG,EAAIA,EACNH,EAAEE,EAAIA,GAGHF,EAmDX,QAASW,GAAOgD,EAAQoB,EAAKC,GACzB,GAAIC,GAAQ,GAAIC,QACZ,gBACA,MACA,SACA,MACA,WACA,KACA,KACA,MACA,KACA,MACA,QACA,MACA,OACA,YACA,SACA,QACA,QACA,QACA,WACA,gBACA,UACA,WACA,aACA,MACA,cACA,WACA,aACFvB,GAAU,MAAQoB,EAAM,KAAOC,EAIjC,MAFAC,GAAMN,KAAO,kBACb9D,EAAK,EACCoE,EAQV,QAASnE,GAAON,EAAG2E,EAAIpC,EAAIJ,GACvB,GAAIF,GAAGrC,EAAG0E,EAAGpC,EAAG1C,EAAGoF,EAAIC,EACnBzC,EAAKpC,EAAEN,EACPoF,EAASC,CAGb,IAAI3C,EAAI,CAQJ4C,EAAK,CAGD,IAAM/C,EAAI,EAAGC,EAAIE,EAAG,GAAIF,GAAK,GAAIA,GAAK,GAAID,KAI1C,GAHArC,EAAI+E,EAAK1C,EAGA,EAAJrC,EACDA,GAAKgC,EACL0C,EAAIK,EACJnF,EAAI4C,EAAIwC,EAAK,GAGbC,EAAKrF,EAAIsF,EAAQ7C,EAAIqC,EAAI,GAAM,GAAK,MAIpC,IAFAM,EAAKK,GAAYrF,EAAI,GAAMgC,GAEtBgD,GAAMxC,EAAGpB,OAAS,CAEnB,IAAImB,EASA,KAAM6C,EANN,MAAQ5C,EAAGpB,QAAU4D,EAAIxC,EAAGP,KAAK,IACjCrC,EAAIqF,EAAK,EACT5C,EAAI,EACJrC,GAAKgC,EACL0C,EAAI1E,EAAIgC,EAAW,MAIpB,CAIH,IAHApC,EAAI0C,EAAIE,EAAGwC,GAGL3C,EAAI,EAAGC,GAAK,GAAIA,GAAK,GAAID,KAG/BrC,GAAKgC,EAIL0C,EAAI1E,EAAIgC,EAAWK,EAGnB4C,EAAS,EAAJP,EAAQ,EAAI9E,EAAIsF,EAAQ7C,EAAIqC,EAAI,GAAM,GAAK,EAmBxD,GAfAnC,EAAIA,GAAU,EAALwC,GAKO,MAAdvC,EAAGwC,EAAK,KAAoB,EAAJN,EAAQ9E,EAAIA,EAAIsF,EAAQ7C,EAAIqC,EAAI,IAE1DnC,EAAS,EAALI,GACEsC,GAAM1C,KAAe,GAANI,GAAWA,IAAQvC,EAAEc,EAAI,EAAI,EAAI,IAClD+D,EAAK,GAAW,GAANA,IAAmB,GAANtC,GAAWJ,GAAW,GAANI,IAGnC3C,EAAI,EAAI0E,EAAI,EAAI9E,EAAIsF,EAAQ7C,EAAIqC,GAAM,EAAIlC,EAAGwC,EAAK,IAAO,GAAO,GAClErC,IAAQvC,EAAEc,EAAI,EAAI,EAAI,IAElB,EAAL6D,IAAWvC,EAAG,GAiBf,MAhBAA,GAAGpB,OAAS,EAERmB,GAGAwC,GAAM3E,EAAEL,EAAI,EAGZyC,EAAG,GAAK0C,GAAUlD,EAAW+C,EAAK/C,GAAaA,GAC/C5B,EAAEL,GAAKgF,GAAM,GAIbvC,EAAG,GAAKpC,EAAEL,EAAI,EAGXK,CAkBX,IAdU,GAALJ,GACDwC,EAAGpB,OAAS4D,EACZ1C,EAAI,EACJ0C,MAEAxC,EAAGpB,OAAS4D,EAAK,EACjB1C,EAAI4C,EAAQlD,EAAWhC,GAIvBwC,EAAGwC,GAAMN,EAAI,EAAI7C,EAAWjC,EAAIsF,EAAQ7C,EAAIqC,GAAMQ,EAAOR,IAAOpC,EAAI,GAIpEC,EAEA,OAAY,CAGR,GAAW,GAANyC,EAAU,CAGX,IAAMhF,EAAI,EAAG0E,EAAIlC,EAAG,GAAIkC,GAAK,GAAIA,GAAK,GAAI1E,KAE1C,IADA0E,EAAIlC,EAAG,IAAMF,EACPA,EAAI,EAAGoC,GAAK,GAAIA,GAAK,GAAIpC,KAG1BtC,GAAKsC,IACNlC,EAAEL,IACGyC,EAAG,IAAM8C,IAAO9C,EAAG,GAAK,GAGjC,OAGA,GADAA,EAAGwC,IAAO1C,EACLE,EAAGwC,IAAOM,EAAO,KACtB9C,GAAGwC,KAAQ,EACX1C,EAAI,EAMhB,IAAMtC,EAAIwC,EAAGpB,OAAoB,IAAZoB,IAAKxC,GAAUwC,EAAGU,QAItC9C,EAAEL,EAAI+B,EACP1B,EAAEN,EAAIM,EAAEL,EAAI,KAGJK,EAAEL,EAAIgC,IACd3B,EAAEN,GAAMM,EAAEL,EAAI,IAItB,MAAOK,GAnzCX,GAAI+C,GAGA1C,EAAK,EACL8E,EAAI5F,EAAU6F,UACdC,EAAM,GAAI9F,GAAU,GAYpBgB,EAAiB,GAejBC,EAAgB,EAMhBgD,EAAa,GAIb8B,EAAa,GAMb3D,EAAU,KAKVD,EAAU,IAGVxB,GAAS,EAGTE,EAAa4D,EAGbuB,GAAS,EAoBTC,EAAc,EAId/C,EAAgB,IAGhBgD,GACIC,iBAAkB,IAClBC,eAAgB,IAChBC,UAAW,EACXC,mBAAoB,EACpBC,uBAAwB,IACxBC,kBAAmB,EAi3E3B,OA5rEAxG,GAAUyG,QAAU3G,EAEpBE,EAAU0G,SAAW,EACrB1G,EAAU2G,WAAa,EACvB3G,EAAU4G,WAAa,EACvB5G,EAAU6G,YAAc,EACxB7G,EAAU8G,cAAgB,EAC1B9G,EAAU+G,gBAAkB,EAC5B/G,EAAUgH,gBAAkB,EAC5BhH,EAAUiH,gBAAkB,EAC5BjH,EAAUkH,iBAAmB,EAC7BlH,EAAUmH,OAAS,EAoCnBnH,EAAUoH,OAAS,WACf,GAAIC,GAAGC,EACHjH,EAAI,EACJuC,KACA2E,EAAIC,UACJC,EAAIF,EAAE,GACNG,EAAMD,GAAiB,gBAALA,GACd,WAAc,MAAKA,GAAEE,eAAeL,GAA4B,OAAdD,EAAII,EAAEH,IAA1C,QACd,WAAc,MAAKC,GAAE9F,OAASpB,EAA6B,OAAhBgH,EAAIE,EAAElH,MAAnC,OA6GtB,OAxGKqH,GAAKJ,EAAI,mBAAsBzG,EAAYwG,EAAG,EAAGO,EAAK,EAAGN,KAC1DtG,EAAqB,EAAJqG,GAErBzE,EAAE0E,GAAKtG,EAKF0G,EAAKJ,EAAI,kBAAqBzG,EAAYwG,EAAG,EAAG,EAAG,EAAGC,KACvDrG,EAAoB,EAAJoG,GAEpBzE,EAAE0E,GAAKrG,EAMFyG,EAAKJ,EAAI,oBAEL/C,EAAQ8C,GACJxG,EAAYwG,EAAE,IAAKO,EAAK,EAAG,EAAGN,IAAOzG,EAAYwG,EAAE,GAAI,EAAGO,EAAK,EAAGN,KACnErD,EAAoB,EAAPoD,EAAE,GACftB,EAAoB,EAAPsB,EAAE,IAEXxG,EAAYwG,GAAIO,EAAKA,EAAK,EAAGN,KACrCrD,IAAgB8B,EAAkC,GAAf,EAAJsB,GAASA,EAAIA,MAGpDzE,EAAE0E,IAAOrD,EAAY8B,GAOhB2B,EAAKJ,EAAI,WAEL/C,EAAQ8C,GACJxG,EAAYwG,EAAE,IAAKO,EAAK,GAAI,EAAGN,IAAOzG,EAAYwG,EAAE,GAAI,EAAGO,EAAK,EAAGN,KACpElF,EAAiB,EAAPiF,EAAE,GACZlF,EAAiB,EAAPkF,EAAE,IAERxG,EAAYwG,GAAIO,EAAKA,EAAK,EAAGN,KAC5B,EAAJD,EAAQjF,IAAaD,EAA+B,GAAf,EAAJkF,GAASA,EAAIA,IAC1C1G,GAAQC,EAAO,EAAG0G,EAAI,kBAAmBD,KAG1DzE,EAAE0E,IAAOlF,EAASD,GAIbuF,EAAKJ,EAAI,YAELD,MAAQA,GAAW,IAANA,GAAiB,IAANA,GACzBvG,EAAK,EACLD,GAAeF,IAAW0G,GAAM5C,EAAyBoD,GAClDlH,GACPC,EAAO,EAAG0G,EAAIQ,EAAST,IAG/BzE,EAAE0E,GAAK3G,EAKF+G,EAAKJ,EAAI,YAELD,MAAQA,GAAW,IAANA,GAAiB,IAANA,GACzBrB,KAAaqB,IAAKU,GACbV,IAAMrB,GAAUrF,GAASC,EAAO,EAAG,qBAAsBmH,IACvDpH,GACPC,EAAO,EAAG0G,EAAIQ,EAAST,IAG/BzE,EAAE0E,GAAKtB,EAKF0B,EAAKJ,EAAI,gBAAmBzG,EAAYwG,EAAG,EAAG,EAAG,EAAGC,KACrDrB,EAAkB,EAAJoB,GAElBzE,EAAE0E,GAAKrB,EAKFyB,EAAKJ,EAAI,kBAAqBzG,EAAYwG,EAAG,EAAGO,EAAK,EAAGN,KACzDpE,EAAoB,EAAJmE,GAEpBzE,EAAE0E,GAAKpE,EAIFwE,EAAKJ,EAAI,YAEO,gBAALD,GACRnB,EAASmB,EACF1G,GACPC,EAAO,EAAG0G,EAAI,iBAAkBD,IAGxCzE,EAAE0E,GAAKpB,EAEAtD,GASX5C,EAAU2E,IAAM,WAAc,MAAOR,GAAUqD,UAAW5B,EAAEoC,KAQ5DhI,EAAU0E,IAAM,WAAc,MAAOP,GAAUqD,UAAW5B,EAAEqC,KAc5DjI,EAAUkI,OAAS,WACf,GAAIC,GAAU,iBAMVC,EAAkBC,KAAKH,SAAWC,EAAW,QAC7C,WAAc,MAAOjG,GAAWmG,KAAKH,SAAWC,IAChD,WAAc,MAA2C,UAAlB,WAAhBE,KAAKH,SAAwB,IACjC,QAAhBG,KAAKH,SAAsB,GAElC,OAAO,UAAUnF,GACb,GAAIwE,GAAGrH,EAAGE,EAAGuC,EAAG0E,EACZhH,EAAI,EACJF,KACAmI,EAAO,GAAItI,GAAU8F,EAKzB,IAHA/C,EAAW,MAANA,GAAelC,EAAYkC,EAAI,EAAG6E,EAAK,IAA6B,EAAL7E,EAAjB/B,EACnD2B,EAAI+C,EAAU3C,EAAKV,GAEf2D,EAGA,GAAK+B,GAAaA,EAAUQ,gBAAkB,CAI1C,IAFAhB,EAAIQ,EAAUQ,gBAAiB,GAAIC,aAAa7F,GAAK,IAEzCA,EAAJtC,GAQJgH,EAAW,OAAPE,EAAElH,IAAgBkH,EAAElH,EAAI,KAAO,IAM9BgH,GAAK,MACNnH,EAAI6H,EAAUQ,gBAAiB,GAAIC,aAAY,IAC/CjB,EAAElH,GAAKH,EAAE,GACTqH,EAAElH,EAAI,GAAKH,EAAE,KAKbC,EAAEmC,KAAM+E,EAAI,MACZhH,GAAK,EAGbA,GAAIsC,EAAI,MAGL,IAAKoF,GAAaA,EAAUU,YAAc,CAK7C,IAFAlB,EAAIQ,EAAUU,YAAa9F,GAAK,GAEpBA,EAAJtC,GAMJgH,EAAsB,iBAAP,GAAPE,EAAElH,IAA6C,cAAXkH,EAAElH,EAAI,GAC/B,WAAXkH,EAAElH,EAAI,GAAkC,SAAXkH,EAAElH,EAAI,IACnCkH,EAAElH,EAAI,IAAM,KAASkH,EAAElH,EAAI,IAAM,GAAMkH,EAAElH,EAAI,GAEhDgH,GAAK,KACNU,EAAUU,YAAY,GAAGC,KAAMnB,EAAGlH,IAIlCF,EAAEmC,KAAM+E,EAAI,MACZhH,GAAK,EAGbA,GAAIsC,EAAI,MACDhC,IACPC,EAAO,GAAI,qBAAsBmH,EAKzC,KAAK1H,EAED,KAAYsC,EAAJtC,GACJgH,EAAIe,IACK,KAAJf,IAAWlH,EAAEE,KAAOgH,EAAI,KAcrC,KAVA1E,EAAIxC,IAAIE,GACR0C,GAAMV,EAGDM,GAAKI,IACNsE,EAAI7B,EAASnD,EAAWU,GACxB5C,EAAEE,GAAK6B,EAAWS,EAAI0E,GAAMA,GAIf,IAATlH,EAAEE,GAAUF,EAAEoD,MAAOlD,KAG7B,GAAS,EAAJA,EACDF,GAAMC,EAAI,OACP,CAGH,IAAMA,EAAI,GAAc,IAATD,EAAE,GAAUA,EAAEwI,QAASvI,GAAKiC,GAG3C,IAAMhC,EAAI,EAAGgH,EAAIlH,EAAE,GAAIkH,GAAK,GAAIA,GAAK,GAAIhH,KAGhCgC,EAAJhC,IAAeD,GAAKiC,EAAWhC,GAKxC,MAFAiI,GAAKlI,EAAIA,EACTkI,EAAKnI,EAAIA,EACFmI,MAqGf9E,EAAM,WAGF,QAASoF,GAAUnI,EAAGkC,EAAGkG,GACrB,GAAIvE,GAAGwE,EAAMC,EAAKC,EACdC,EAAQ,EACR5I,EAAII,EAAEgB,OACNyH,EAAMvG,EAAIwG,EACVC,EAAMzG,EAAIwG,EAAY,CAE1B,KAAM1I,EAAIA,EAAEW,QAASf,KACjB0I,EAAMtI,EAAEJ,GAAK8I,EACbH,EAAMvI,EAAEJ,GAAK8I,EAAY,EACzB7E,EAAI8E,EAAML,EAAMC,EAAME,EACtBJ,EAAOI,EAAMH,EAAUzE,EAAI6E,EAAcA,EAAcF,EACvDA,GAAUH,EAAOD,EAAO,IAAQvE,EAAI6E,EAAY,GAAMC,EAAMJ,EAC5DvI,EAAEJ,GAAKyI,EAAOD,CAKlB,OAFII,IAAOxI,EAAEgD,QAAQwF,GAEdxI,EAGX,QAAS4I,GAAS9B,EAAGrH,EAAGoJ,EAAIC,GACxB,GAAIlJ,GAAGmJ,CAEP,IAAKF,GAAMC,EACPC,EAAMF,EAAKC,EAAK,EAAI,OAGpB,KAAMlJ,EAAImJ,EAAM,EAAOF,EAAJjJ,EAAQA,IAEvB,GAAKkH,EAAElH,IAAMH,EAAEG,GAAK,CAChBmJ,EAAMjC,EAAElH,GAAKH,EAAEG,GAAK,EAAI,EACxB,OAIZ,MAAOmJ,GAGX,QAASC,GAAUlC,EAAGrH,EAAGoJ,EAAIT,GAIzB,IAHA,GAAIxI,GAAI,EAGAiJ,KACJ/B,EAAE+B,IAAOjJ,EACTA,EAAIkH,EAAE+B,GAAMpJ,EAAEoJ,GAAM,EAAI,EACxB/B,EAAE+B,GAAMjJ,EAAIwI,EAAOtB,EAAE+B,GAAMpJ,EAAEoJ,EAIjC,OAAS/B,EAAE,IAAMA,EAAE9F,OAAS,EAAG8F,EAAEoB,UAIrC,MAAO,UAAWlI,EAAGqC,EAAGC,EAAIC,EAAI6F,GAC5B,GAAIW,GAAKpJ,EAAGC,EAAGqJ,EAAMzJ,EAAG0J,EAAMC,EAAOC,EAAGC,EAAIC,EAAKC,EAAMC,EAAMC,EAAIC,EAAIC,EACjEC,EAAIC,EACJ/I,EAAId,EAAEc,GAAKuB,EAAEvB,EAAI,EAAI,GACrBsB,EAAKpC,EAAEN,EACPoK,EAAKzH,EAAE3C,CAGX,MAAM0C,GAAOA,EAAG,IAAO0H,GAAOA,EAAG,IAE7B,MAAO,IAAIvK,GAGRS,EAAEc,GAAMuB,EAAEvB,IAAOsB,GAAK0H,GAAM1H,EAAG,IAAM0H,EAAG,GAAMA,GAG7C1H,GAAe,GAATA,EAAG,KAAY0H,EAAS,EAAJhJ,EAAQA,EAAI,EAHciJ,IAoB5D,KAbAX,EAAI,GAAI7J,GAAUuB,GAClBuI,EAAKD,EAAE1J,KACPC,EAAIK,EAAEL,EAAI0C,EAAE1C,EACZmB,EAAIwB,EAAK3C,EAAI,EAEPyI,IACFA,EAAOlD,EACPvF,EAAIqK,EAAUhK,EAAEL,EAAIiC,GAAaoI,EAAU3H,EAAE1C,EAAIiC,GACjDd,EAAIA,EAAIc,EAAW,GAKjBhC,EAAI,EAAGkK,EAAGlK,KAAQwC,EAAGxC,IAAM,GAAKA,KAGtC,GAFKkK,EAAGlK,IAAOwC,EAAGxC,IAAM,IAAMD,IAErB,EAAJmB,EACDuI,EAAGxH,KAAK,GACRoH,GAAO,MACJ,CAwBH,IAvBAS,EAAKtH,EAAGpB,OACR4I,EAAKE,EAAG9I,OACRpB,EAAI,EACJkB,GAAK,EAILtB,EAAIiC,EAAW2G,GAAS0B,EAAG,GAAK,IAI3BtK,EAAI,IACLsK,EAAK3B,EAAU2B,EAAItK,EAAG4I,GACtBhG,EAAK+F,EAAU/F,EAAI5C,EAAG4I,GACtBwB,EAAKE,EAAG9I,OACR0I,EAAKtH,EAAGpB,QAGZyI,EAAKG,EACLN,EAAMlH,EAAGzB,MAAO,EAAGiJ,GACnBL,EAAOD,EAAItI,OAGI4I,EAAPL,EAAWD,EAAIC,KAAU,GACjCM,EAAKC,EAAGnJ,QACRkJ,EAAG7G,QAAQ,GACX2G,EAAMG,EAAG,GACJA,EAAG,IAAM1B,EAAO,GAAIuB,GAIzB,GAAG,CAOC,GANAnK,EAAI,EAGJuJ,EAAMH,EAASkB,EAAIR,EAAKM,EAAIL,GAGjB,EAANR,EAAU,CAkBX,GAdAS,EAAOF,EAAI,GACNM,GAAML,IAAOC,EAAOA,EAAOpB,GAASkB,EAAI,IAAM,IAGnD9J,EAAIiC,EAAW+H,EAAOG,GAUjBnK,EAAI,EAeL,IAZIA,GAAK4I,IAAM5I,EAAI4I,EAAO,GAG1Bc,EAAOf,EAAU2B,EAAItK,EAAG4I,GACxBe,EAAQD,EAAKlI,OACbuI,EAAOD,EAAItI,OAOkC,GAArC4H,EAASM,EAAMI,EAAKH,EAAOI,IAC/B/J,IAGAwJ,EAAUE,EAAWC,EAALS,EAAaC,EAAKC,EAAIX,EAAOf,GAC7Ce,EAAQD,EAAKlI,OACb+H,EAAM,MAQA,IAALvJ,IAGDuJ,EAAMvJ,EAAI,GAId0J,EAAOY,EAAGnJ,QACVwI,EAAQD,EAAKlI,MAUjB,IAPauI,EAARJ,GAAeD,EAAKlG,QAAQ,GAGjCgG,EAAUM,EAAKJ,EAAMK,EAAMnB,GAC3BmB,EAAOD,EAAItI,OAGC,IAAP+H,EAMD,KAAQH,EAASkB,EAAIR,EAAKM,EAAIL,GAAS,GACnC/J,IAGAwJ,EAAUM,EAAUC,EAALK,EAAYC,EAAKC,EAAIP,EAAMnB,GAC1CmB,EAAOD,EAAItI,WAGH,KAAR+H,IACRvJ,IACA8J,GAAO,GAIXD,GAAGzJ,KAAOJ,EAGL8J,EAAI,GACLA,EAAIC,KAAUnH,EAAGqH,IAAO,GAExBH,GAAQlH,EAAGqH,IACXF,EAAO,UAEHE,IAAOC,GAAgB,MAAVJ,EAAI,KAAgBxI,IAE7CmI,GAAiB,MAAVK,EAAI,GAGLD,EAAG,IAAKA,EAAGnB,QAGrB,GAAKE,GAAQlD,EAAO,CAGhB,IAAMtF,EAAI,EAAGkB,EAAIuI,EAAG,GAAIvI,GAAK,GAAIA,GAAK,GAAIlB,KAC1CU,EAAO8I,EAAG9G,GAAO8G,EAAEzJ,EAAIC,EAAID,EAAIiC,EAAW,GAAM,EAAGW,EAAI0G,OAIvDG,GAAEzJ,EAAIA,EACNyJ,EAAEjH,GAAK8G,CAGX,OAAOG,OAgJfvI,EAAe,WACX,GAAIoJ,GAAa,8BACbC,EAAW,cACXC,EAAY,cACZC,EAAkB,qBAClBC,EAAmB,4BAEvB,OAAO,UAAWrK,EAAGD,EAAKF,EAAKJ,GAC3B,GAAI2I,GACAtH,EAAIjB,EAAME,EAAMA,EAAIgB,QAASsJ,EAAkB,GAGnD,IAAKD,EAAgBxJ,KAAKE,GACtBd,EAAEc,EAAIwJ,MAAMxJ,GAAK,KAAW,EAAJA,EAAQ,GAAK,MAClC,CACH,IAAMjB,IAGFiB,EAAIA,EAAEC,QAASkJ,EAAY,SAAWpG,EAAG0G,EAAIC,GAEzC,MADApC,GAAoC,MAA3BoC,EAAKA,EAAGhI,eAAyB,GAAW,KAANgI,EAAY,EAAI,EACvD/K,GAAKA,GAAK2I,EAAYvE,EAAL0G,IAGzB9K,IACA2I,EAAO3I,EAGPqB,EAAIA,EAAEC,QAASmJ,EAAU,MAAOnJ,QAASoJ,EAAW,SAGnDpK,GAAOe,GAAI,MAAO,IAAIvB,GAAWuB,EAAGsH,EAKzClI,IAAQC,EAAOE,EAAI,SAAYZ,EAAI,SAAWA,EAAI,IAAO,UAAWM,GACxEC,EAAEc,EAAI,KAGVd,EAAEN,EAAIM,EAAEL,EAAI,KACZU,EAAK,MAmNb8E,EAAEsF,cAAgBtF,EAAEuF,IAAM,WACtB,GAAI1K,GAAI,GAAIT,GAAUU,KAEtB,OADKD,GAAEc,EAAI,IAAId,EAAEc,EAAI,GACdd,GAQXmF,EAAEwF,KAAO,WACL,MAAOrK,GAAO,GAAIf,GAAUU,MAAOA,KAAKN,EAAI,EAAG,IAWnDwF,EAAEyF,WAAazF,EAAE4D,IAAM,SAAW1G,EAAG5C,GAEjC,MADAY,GAAK,EACEuI,EAAS3I,KAAM,GAAIV,GAAW8C,EAAG5C,KAQ5C0F,EAAE0F,cAAgB1F,EAAE7C,GAAK,WACrB,GAAI9C,GAAGoH,EACHlH,EAAIO,KAAKP,CAEb,KAAMA,EAAI,MAAO,KAIjB,IAHAF,IAAQoH,EAAIlH,EAAEsB,OAAS,GAAMgJ,EAAU/J,KAAKN,EAAIiC,IAAeA,EAG1DgF,EAAIlH,EAAEkH,GAAK,KAAQA,EAAI,IAAM,EAAGA,GAAK,GAAIpH,KAG9C,MAFS,GAAJA,IAAQA,EAAI,GAEVA,GAwBX2F,EAAE2F,UAAY3F,EAAEpC,IAAM,SAAWV,EAAG5C,GAEhC,MADAY,GAAK,EACE0C,EAAK9C,KAAM,GAAIV,GAAW8C,EAAG5C,GAAKc,EAAgBC,IAQ7D2E,EAAE4F,mBAAqB5F,EAAE6F,SAAW,SAAW3I,EAAG5C,GAE9C,MADAY,GAAK,EACE0C,EAAK9C,KAAM,GAAIV,GAAW8C,EAAG5C,GAAK,EAAG,IAQhD0F,EAAE8F,OAAS9F,EAAE+F,GAAK,SAAW7I,EAAG5C,GAE5B,MADAY,GAAK,EAC6C,IAA3CuI,EAAS3I,KAAM,GAAIV,GAAW8C,EAAG5C,KAQ5C0F,EAAEgG,MAAQ,WACN,MAAO7K,GAAO,GAAIf,GAAUU,MAAOA,KAAKN,EAAI,EAAG,IAQnDwF,EAAEiG,YAAcjG,EAAEqC,GAAK,SAAWnF,EAAG5C,GAEjC,MADAY,GAAK,EACEuI,EAAS3I,KAAM,GAAIV,GAAW8C,EAAG5C,IAAQ,GAQpD0F,EAAEkG,qBAAuBlG,EAAEmG,IAAM,SAAWjJ,EAAG5C,GAE3C,MADAY,GAAK,EACqD,KAAjDZ,EAAImJ,EAAS3I,KAAM,GAAIV,GAAW8C,EAAG5C,MAAuB,IAANA,GAQnE0F,EAAEoG,SAAW,WACT,QAAStL,KAAKP,GAOlByF,EAAEqG,UAAYrG,EAAEsG,MAAQ,WACpB,QAASxL,KAAKP,GAAKsK,EAAU/J,KAAKN,EAAIiC,GAAa3B,KAAKP,EAAEsB,OAAS,GAOvEmE,EAAEmF,MAAQ,WACN,OAAQrK,KAAKa,GAOjBqE,EAAEuG,WAAavG,EAAEwG,MAAQ,WACrB,MAAO1L,MAAKa,EAAI,GAOpBqE,EAAEyG,OAAS,WACP,QAAS3L,KAAKP,GAAkB,GAAbO,KAAKP,EAAE,IAQ9ByF,EAAE0G,SAAW1G,EAAEoC,GAAK,SAAWlF,EAAG5C,GAE9B,MADAY,GAAK,EACEuI,EAAS3I,KAAM,GAAIV,GAAW8C,EAAG5C,IAAQ,GAQpD0F,EAAE2G,kBAAoB3G,EAAE4G,IAAM,SAAW1J,EAAG5C,GAExC,MADAY,GAAK,EACqD,MAAjDZ,EAAImJ,EAAS3I,KAAM,GAAIV,GAAW8C,EAAG5C,MAAwB,IAANA,GAwBpE0F,EAAE6G,MAAQ7G,EAAE8G,IAAM,SAAW5J,EAAG5C,GAC5B,GAAIG,GAAG0E,EAAG4H,EAAGC,EACTnM,EAAIC,KACJ6G,EAAI9G,EAAEc,CAOV,IALAT,EAAK,GACLgC,EAAI,GAAI9C,GAAW8C,EAAG5C,GACtBA,EAAI4C,EAAEvB,GAGAgG,IAAMrH,EAAI,MAAO,IAAIF,GAAUwK,IAGrC,IAAKjD,GAAKrH,EAEN,MADA4C,GAAEvB,GAAKrB,EACAO,EAAEoM,KAAK/J,EAGlB,IAAIgK,GAAKrM,EAAEL,EAAIiC,EACX0K,EAAKjK,EAAE1C,EAAIiC,EACXQ,EAAKpC,EAAEN,EACPoK,EAAKzH,EAAE3C,CAEX,KAAM2M,IAAOC,EAAK,CAGd,IAAMlK,IAAO0H,EAAK,MAAO1H,IAAOC,EAAEvB,GAAKrB,EAAG4C,GAAM,GAAI9C,GAAWuK,EAAK9J,EAAI+J,IAGxE,KAAM3H,EAAG,KAAO0H,EAAG,GAGf,MAAOA,GAAG,IAAOzH,EAAEvB,GAAKrB,EAAG4C,GAAM,GAAI9C,GAAW6C,EAAG,GAAKpC,EAGrC,GAAjBQ,GAAsB,EAAI,GASpC,GALA6L,EAAKrC,EAASqC,GACdC,EAAKtC,EAASsC,GACdlK,EAAKA,EAAGzB,QAGHmG,EAAIuF,EAAKC,EAAK,CAaf,KAXKH,EAAW,EAAJrF,IACRA,GAAKA,EACLoF,EAAI9J,IAEJkK,EAAKD,EACLH,EAAIpC,GAGRoC,EAAEK,UAGI9M,EAAIqH,EAAGrH,IAAKyM,EAAErK,KAAK,IACzBqK,EAAEK,cAMF,KAFAjI,GAAM6H,GAASrF,EAAI1E,EAAGpB,SAAavB,EAAIqK,EAAG9I,SAAa8F,EAAIrH,EAErDqH,EAAIrH,EAAI,EAAO6E,EAAJ7E,EAAOA,IAEpB,GAAK2C,EAAG3C,IAAMqK,EAAGrK,GAAK,CAClB0M,EAAO/J,EAAG3C,GAAKqK,EAAGrK,EAClB,OAYZ,GANI0M,IAAMD,EAAI9J,EAAIA,EAAK0H,EAAIA,EAAKoC,EAAG7J,EAAEvB,GAAKuB,EAAEvB,GAE5CrB,GAAM6E,EAAIwF,EAAG9I,SAAapB,EAAIwC,EAAGpB,QAI5BvB,EAAI,EAAI,KAAQA,IAAK2C,EAAGxC,KAAO,GAIpC,IAHAH,EAAIyF,EAAO,EAGHZ,EAAIwC,GAAK,CAEb,GAAK1E,IAAKkC,GAAKwF,EAAGxF,GAAK,CACnB,IAAM1E,EAAI0E,EAAG1E,IAAMwC,IAAKxC,GAAIwC,EAAGxC,GAAKH,KAClC2C,EAAGxC,GACLwC,EAAGkC,IAAMY,EAGb9C,EAAGkC,IAAMwF,EAAGxF,GAIhB,KAAiB,GAATlC,EAAG,GAASA,EAAG8F,UAAWoE,GAGlC,MAAMlK,GAAG,GAWFiC,EAAWhC,EAAGD,EAAIkK,IAPrBjK,EAAEvB,EAAqB,GAAjBN,EAAqB,GAAK,EAChC6B,EAAE3C,GAAM2C,EAAE1C,EAAI,GACP0C,IA8Bf8C,EAAEqH,OAASrH,EAAEsH,IAAM,SAAWpK,EAAG5C,GAC7B,GAAI2J,GAAGtI,EACHd,EAAIC,IAMR,OAJAI,GAAK,GACLgC,EAAI,GAAI9C,GAAW8C,EAAG5C,IAGhBO,EAAEN,IAAM2C,EAAEvB,GAAKuB,EAAE3C,IAAM2C,EAAE3C,EAAE,GACtB,GAAIH,GAAUwK,MAGZ1H,EAAE3C,GAAKM,EAAEN,IAAMM,EAAEN,EAAE,GACrB,GAAIH,GAAUS,IAGL,GAAfwF,GAID1E,EAAIuB,EAAEvB,EACNuB,EAAEvB,EAAI,EACNsI,EAAIrG,EAAK/C,EAAGqC,EAAG,EAAG,GAClBA,EAAEvB,EAAIA,EACNsI,EAAEtI,GAAKA,GAEPsI,EAAIrG,EAAK/C,EAAGqC,EAAG,EAAGmD,GAGfxF,EAAEgM,MAAO5C,EAAEsD,MAAMrK,MAQ5B8C,EAAEwH,QAAUxH,EAAEyH,IAAM,WAChB,GAAI5M,GAAI,GAAIT,GAAUU,KAEtB,OADAD,GAAEc,GAAKd,EAAEc,GAAK,KACPd,GAwBXmF,EAAEiH,KAAOjH,EAAE0H,IAAM,SAAWxK,EAAG5C,GAC3B,GAAIyM,GACAlM,EAAIC,KACJ6G,EAAI9G,EAAEc,CAOV,IALAT,EAAK,GACLgC,EAAI,GAAI9C,GAAW8C,EAAG5C,GACtBA,EAAI4C,EAAEvB,GAGAgG,IAAMrH,EAAI,MAAO,IAAIF,GAAUwK,IAGpC,IAAKjD,GAAKrH,EAEP,MADA4C,GAAEvB,GAAKrB,EACAO,EAAEgM,MAAM3J,EAGnB,IAAIgK,GAAKrM,EAAEL,EAAIiC,EACX0K,EAAKjK,EAAE1C,EAAIiC,EACXQ,EAAKpC,EAAEN,EACPoK,EAAKzH,EAAE3C,CAEX,KAAM2M,IAAOC,EAAK,CAGd,IAAMlK,IAAO0H,EAAK,MAAO,IAAIvK,GAAWuH,EAAI,EAI5C,KAAM1E,EAAG,KAAO0H,EAAG,GAAK,MAAOA,GAAG,GAAKzH,EAAI,GAAI9C,GAAW6C,EAAG,GAAKpC,EAAQ,EAAJ8G,GAQ1E,GALAuF,EAAKrC,EAASqC,GACdC,EAAKtC,EAASsC,GACdlK,EAAKA,EAAGzB,QAGHmG,EAAIuF,EAAKC,EAAK,CAUf,IATKxF,EAAI,GACLwF,EAAKD,EACLH,EAAIpC,IAEJhD,GAAKA,EACLoF,EAAI9J,GAGR8J,EAAEK,UACMzF,IAAKoF,EAAErK,KAAK,IACpBqK,EAAEK,UAUN,IAPAzF,EAAI1E,EAAGpB,OACPvB,EAAIqK,EAAG9I,OAGM,EAAR8F,EAAIrH,IAAQyM,EAAIpC,EAAIA,EAAK1H,EAAIA,EAAK8J,EAAGzM,EAAIqH,GAGxCA,EAAI,EAAGrH,GACTqH,GAAM1E,IAAK3C,GAAK2C,EAAG3C,GAAKqK,EAAGrK,GAAKqH,GAAM5B,EAAO,EAC7C9C,EAAG3C,IAAMyF,CAUb,OAPI4B,KACA1E,EAAGY,QAAQ8D,KACTwF,GAKCjI,EAAWhC,EAAGD,EAAIkK,IAS7BnH,EAAE2H,UAAY3H,EAAER,GAAK,SAAUoI,GAC3B,GAAIvN,GAAGoH,EACH5G,EAAIC,KACJP,EAAIM,EAAEN,CAQV,IALU,MAALqN,GAAaA,MAAQA,GAAW,IAANA,GAAiB,IAANA,IAClC7M,GAAQC,EAAO,GAAI,WAAakH,EAAS0F,GACxCA,KAAOA,IAAIA,EAAI,QAGlBrN,EAAI,MAAO,KAIjB,IAHAkH,EAAIlH,EAAEsB,OAAS,EACfxB,EAAIoH,EAAIhF,EAAW,EAEdgF,EAAIlH,EAAEkH,GAAK,CAGZ,KAAQA,EAAI,IAAM,EAAGA,GAAK,GAAIpH,KAG9B,IAAMoH,EAAIlH,EAAE,GAAIkH,GAAK,GAAIA,GAAK,GAAIpH,MAKtC,MAFKuN,IAAK/M,EAAEL,EAAI,EAAIH,IAAIA,EAAIQ,EAAEL,EAAI,GAE3BH,GAiBX2F,EAAE7E,MAAQ,SAAWgC,EAAIC,GACrB,GAAI/C,GAAI,GAAID,GAAUU,KAOtB,QALW,MAANqC,GAAclC,EAAYkC,EAAI,EAAG6E,EAAK,MACvC7G,EAAOd,IAAK8C,EAAKrC,KAAKN,EAAI,EAAS,MAAN4C,GAC1BnC,EAAYmC,EAAI,EAAG,EAAG,GAAIe,GAAsC,EAALf,EAAhB/B,GAG3ChB,GAgBX2F,EAAE+C,MAAQ,SAAUhG,GAChB,GAAI1C,GAAIS,IACR,OAAOG,GAAY8B,GAAIV,EAAkBA,EAAkB,GAAI,YAG3DhC,EAAEkN,MAAO,KAAOtI,EAASlC,IACzB,GAAI3C,GAAWC,EAAEE,GAAKF,EAAEE,EAAE,MAAa8B,EAALU,GAAyBA,EAAIV,GAC7DhC,EAAEsB,GAAU,EAAJoB,EAAQ,EAAI,EAAI,GACxB1C,IAeV2F,EAAE6H,WAAa7H,EAAE8H,KAAO,WACpB,GAAIpJ,GAAGrE,EAAG2C,EAAG+K,EAAKhB,EACdlM,EAAIC,KACJP,EAAIM,EAAEN,EACNoB,EAAId,EAAEc,EACNnB,EAAIK,EAAEL,EACN2C,EAAK/B,EAAiB,EACtB4M,EAAO,GAAI5N,GAAU,MAGzB,IAAW,IAANuB,IAAYpB,IAAMA,EAAE,GACrB,MAAO,IAAIH,IAAYuB,GAAS,EAAJA,KAAYpB,GAAKA,EAAE,IAAOqK,IAAMrK,EAAIM,EAAI,EAAI,EA8B5E,IA1BAc,EAAI8G,KAAKqF,MAAOjN,GAIN,GAALc,GAAUA,GAAK,EAAI,GACpBtB,EAAIqD,EAAcnD,IACXF,EAAEwB,OAASrB,GAAM,GAAK,IAAIH,GAAK,KACtCsB,EAAI8G,KAAKqF,KAAKzN,GACdG,EAAIqK,GAAYrK,EAAI,GAAM,IAAY,EAAJA,GAASA,EAAI,GAE1CmB,GAAK,EAAI,EACVtB,EAAI,KAAOG,GAEXH,EAAIsB,EAAE2C,gBACNjE,EAAIA,EAAEmB,MAAO,EAAGnB,EAAE6B,QAAQ,KAAO,GAAM1B,GAG3CwC,EAAI,GAAI5C,GAAUC,IAElB2C,EAAI,GAAI5C,GAAWuB,EAAI,IAOtBqB,EAAEzC,EAAE,GAML,IALAC,EAAIwC,EAAExC,EACNmB,EAAInB,EAAI2C,EACC,EAAJxB,IAAQA,EAAI,KAOb,GAHAoL,EAAI/J,EACJA,EAAIgL,EAAKT,MAAOR,EAAEE,KAAMrJ,EAAK/C,EAAGkM,EAAG5J,EAAI,KAElCO,EAAeqJ,EAAExM,GAAMiB,MAAO,EAAGG,MAAUtB,EAC3CqD,EAAeV,EAAEzC,IAAMiB,MAAO,EAAGG,GAAM,CAWxC,GANKqB,EAAExC,EAAIA,KAAMmB,EACjBtB,EAAIA,EAAEmB,MAAOG,EAAI,EAAGA,EAAI,GAKd,QAALtB,IAAgB0N,GAAY,QAAL1N,GAgBrB,IAIIA,KAAOA,EAAEmB,MAAM,IAAqB,KAAfnB,EAAEyD,OAAO,MAGjC3C,EAAO6B,EAAGA,EAAExC,EAAIY,EAAiB,EAAG,GACpCsD,GAAK1B,EAAEuK,MAAMvK,GAAG+I,GAAGlL,GAGvB,OAvBA,IAAMkN,IACF5M,EAAO4L,EAAGA,EAAEvM,EAAIY,EAAiB,EAAG,GAE/B2L,EAAEQ,MAAMR,GAAGhB,GAAGlL,IAAK,CACpBmC,EAAI+J,CACJ,OAIR5J,GAAM,EACNxB,GAAK,EACLoM,EAAM,EAkBtB,MAAO5M,GAAO6B,EAAGA,EAAExC,EAAIY,EAAiB,EAAGC,EAAeqD,IAwB9DsB,EAAEuH,MAAQvH,EAAEiI,IAAM,SAAW/K,EAAG5C,GAC5B,GAAIC,GAAGC,EAAGC,EAAG0E,EAAGpC,EAAG2B,EAAGwJ,EAAK/E,EAAKC,EAAK+E,EAAKC,EAAKC,EAAKC,EAChDrF,EAAMsF,EACN1N,EAAIC,KACJmC,EAAKpC,EAAEN,EACPoK,GAAOzJ,EAAK,GAAIgC,EAAI,GAAI9C,GAAW8C,EAAG5C,IAAMC,CAGhD,MAAM0C,GAAO0H,GAAO1H,EAAG,IAAO0H,EAAG,IAmB7B,OAhBM9J,EAAEc,IAAMuB,EAAEvB,GAAKsB,IAAOA,EAAG,KAAO0H,GAAMA,IAAOA,EAAG,KAAO1H,EACzDC,EAAE3C,EAAI2C,EAAE1C,EAAI0C,EAAEvB,EAAI,MAElBuB,EAAEvB,GAAKd,EAAEc,EAGHsB,GAAO0H,GAKTzH,EAAE3C,GAAK,GACP2C,EAAE1C,EAAI,GALN0C,EAAE3C,EAAI2C,EAAE1C,EAAI,MASb0C,CAYX,KATA1C,EAAIqK,EAAUhK,EAAEL,EAAIiC,GAAaoI,EAAU3H,EAAE1C,EAAIiC,GACjDS,EAAEvB,GAAKd,EAAEc,EACTuM,EAAMjL,EAAGpB,OACTsM,EAAMxD,EAAG9I,OAGEsM,EAAND,IAAYI,EAAKrL,EAAIA,EAAK0H,EAAIA,EAAK2D,EAAI7N,EAAIyN,EAAKA,EAAMC,EAAKA,EAAM1N,GAGhEA,EAAIyN,EAAMC,EAAKG,KAAS7N,IAAK6N,EAAG5L,KAAK,IAK3C,IAHAuG,EAAOlD,EACPwI,EAAWhF,EAEL9I,EAAI0N,IAAO1N,GAAK,GAAK,CAKvB,IAJAF,EAAI,EACJ6N,EAAMzD,EAAGlK,GAAK8N,EACdF,EAAM1D,EAAGlK,GAAK8N,EAAW,EAEnBxL,EAAImL,EAAK/I,EAAI1E,EAAIsC,EAAGoC,EAAI1E,GAC1B0I,EAAMlG,IAAKF,GAAKwL,EAChBnF,EAAMnG,EAAGF,GAAKwL,EAAW,EACzB7J,EAAI2J,EAAMlF,EAAMC,EAAMgF,EACtBjF,EAAMiF,EAAMjF,EAAUzE,EAAI6J,EAAaA,EAAaD,EAAGnJ,GAAK5E,EAC5DA,GAAM4I,EAAMF,EAAO,IAAQvE,EAAI6J,EAAW,GAAMF,EAAMjF,EACtDkF,EAAGnJ,KAAOgE,EAAMF,CAGpBqF,GAAGnJ,GAAK5E,EASZ,MANIA,KACEC,EAEF8N,EAAGvF,QAGA7D,EAAWhC,EAAGoL,EAAI9N,IAgB7BwF,EAAEwI,SAAW,SAAWhJ,EAAIpC,GACxB,GAAI/C,GAAI,GAAID,GAAUU,KAGtB,OAFA0E,GAAW,MAANA,GAAevE,EAAYuE,EAAI,EAAGwC,EAAK,GAAI,aAA4B,EAALxC,EAAP,KAChEpC,EAAW,MAANA,GAAenC,EAAYmC,EAAI,EAAG,EAAG,GAAIe,GAAsC,EAALf,EAAhB/B,EACxDmE,EAAKrE,EAAOd,EAAGmF,EAAIpC,GAAO/C,GAgBrC2F,EAAE1B,cAAgB,SAAWnB,EAAIC,GAC7B,MAAOW,GAAQjD,KACP,MAANqC,GAAclC,EAAYkC,EAAI,EAAG6E,EAAK,MAAS7E,EAAK,EAAI,KAAMC,EAAI,KAmBxE4C,EAAEyI,QAAU,SAAWtL,EAAIC,GACvB,MAAOW,GAAQjD,KAAY,MAANqC,GAAclC,EAAYkC,EAAI,EAAG6E,EAAK,MACrD7E,EAAKrC,KAAKN,EAAI,EAAI,KAAM4C,EAAI,KA0BtC4C,EAAE0I,SAAW,SAAWvL,EAAIC,GACxB,GAAIxC,GAAMmD,EAAQjD,KAAY,MAANqC,GAAclC,EAAYkC,EAAI,EAAG6E,EAAK,MACxD7E,EAAKrC,KAAKN,EAAI,EAAI,KAAM4C,EAAI,GAElC,IAAKtC,KAAKP,EAAI,CACV,GAAIE,GACAkO,EAAM/N,EAAIgO,MAAM,KAChBC,GAAMvI,EAAOG,UACbqI,GAAMxI,EAAOI,mBACbF,EAAiBF,EAAOE,eACxBuI,EAAUJ,EAAI,GACdK,EAAeL,EAAI,GACnBnC,EAAQ1L,KAAKa,EAAI,EACjBsN,EAAYzC,EAAQuC,EAAQvN,MAAM,GAAKuN,EACvCpO,EAAMsO,EAAUpN,MAIpB,IAFIiN,IAAIrO,EAAIoO,EAAIA,EAAKC,EAAIA,EAAKrO,EAAGE,GAAOF,GAEnCoO,EAAK,GAAKlO,EAAM,EAAI,CAIrB,IAHAF,EAAIE,EAAMkO,GAAMA,EAChBE,EAAUE,EAAUC,OAAQ,EAAGzO,GAEnBE,EAAJF,EAASA,GAAKoO,EAClBE,GAAWvI,EAAiByI,EAAUC,OAAQzO,EAAGoO,EAGhDC,GAAK,IAAIC,GAAWvI,EAAiByI,EAAUzN,MAAMf,IACtD+L,IAAOuC,EAAU,IAAMA,GAG/BnO,EAAMoO,EACFD,EAAUzI,EAAOC,mBAAuBuI,GAAMxI,EAAOM,mBACnDoI,EAAapN,QAAS,GAAIN,QAAQ,OAASwN,EAAK,OAAQ,KACxD,KAAOxI,EAAOK,wBACdqI,GACFD,EAGR,MAAOnO,IAgBXoF,EAAEmJ,WAAa,SAAUC,GACrB,GAAIT,GAAKU,EAAIC,EAAI9O,EAAG+O,EAAKlP,EAAGmP,EAAIvF,EAAGtI,EAC/BoB,EAAIhC,EACJF,EAAIC,KACJmC,EAAKpC,EAAEN,EACPuC,EAAI,GAAI1C,GAAU8F,GAClBuJ,EAAKJ,EAAK,GAAIjP,GAAU8F,GACxBwJ,EAAKF,EAAK,GAAIpP,GAAU8F,EAoB5B,IAlBW,MAANkJ,IACDrO,GAAS,EACTV,EAAI,GAAID,GAAUgP,GAClBrO,EAASgC,KAEDA,EAAI1C,EAAEiM,UAAajM,EAAE+H,GAAGlC,MAExBnF,GACAC,EAAO,GACL,oBAAuB+B,EAAI,eAAiB,kBAAoBqM,GAKtEA,GAAMrM,GAAK1C,EAAEE,GAAKY,EAAOd,EAAGA,EAAEG,EAAI,EAAG,GAAI2L,IAAIjG,GAAO7F,EAAI,QAI1D4C,EAAK,MAAOpC,GAAEuD,UAgBpB,KAfAzC,EAAI+B,EAAcT,GAIlBzC,EAAIsC,EAAEtC,EAAImB,EAAEE,OAAShB,EAAEL,EAAI,EAC3BsC,EAAEvC,EAAE,GAAKqF,GAAY2J,EAAM/O,EAAIiC,GAAa,EAAIA,EAAW8M,EAAMA,GACjEH,GAAMA,GAAM/O,EAAEuJ,IAAI9G,GAAK,EAAMtC,EAAI,EAAIsC,EAAI2M,EAAOpP,EAEhDkP,EAAMhN,EACNA,EAAU,EAAI,EACdlC,EAAI,GAAID,GAAUuB,GAGlB6N,EAAGjP,EAAE,GAAK,EAGN0J,EAAIrG,EAAKvD,EAAGyC,EAAG,EAAG,GAClBwM,EAAKD,EAAGpC,KAAMhD,EAAEsD,MAAMmC,IACH,GAAdJ,EAAG1F,IAAIwF,IACZC,EAAKK,EACLA,EAAKJ,EACLG,EAAKD,EAAGvC,KAAMhD,EAAEsD,MAAO+B,EAAKG,IAC5BD,EAAKF,EACLxM,EAAIzC,EAAEwM,MAAO5C,EAAEsD,MAAO+B,EAAKxM,IAC3BzC,EAAIiP,CAgBR,OAbAA,GAAK1L,EAAKwL,EAAGvC,MAAMwC,GAAKK,EAAI,EAAG,GAC/BF,EAAKA,EAAGvC,KAAMqC,EAAG/B,MAAMkC,IACvBJ,EAAKA,EAAGpC,KAAMqC,EAAG/B,MAAMmC,IACvBF,EAAG7N,EAAI8N,EAAG9N,EAAId,EAAEc,EAChBnB,GAAK,EAGLmO,EAAM/K,EAAK6L,EAAIC,EAAIlP,EAAGa,GAAgBwL,MAAMhM,GAAG0K,MAAM3B,IAC/ChG,EAAK4L,EAAIH,EAAI7O,EAAGa,GAAgBwL,MAAMhM,GAAG0K,OAAU,GAC7CkE,EAAGrL,WAAYsL,EAAGtL,aAClBoL,EAAGpL,WAAYiL,EAAGjL,YAE9B7B,EAAUgN,EACHZ,GAOX3I,EAAE2J,SAAW,WACT,OAAQ7O,MAsBZkF,EAAE4J,QAAU5J,EAAEzC,IAAM,SAAWlD,EAAGqE,GAC9B,GAAI3B,GAAGG,EAAG0K,EACNnN,EAAI6B,EAAe,EAAJjC,GAASA,GAAKA,GAC7BQ,EAAIC,IAQR,IANU,MAAL4D,IACDxD,EAAK,GACLwD,EAAI,GAAItE,GAAUsE,KAIhBzD,EAAYZ,GAAIgC,EAAkBA,EAAkB,GAAI,eACzD+J,SAAS/L,IAAMI,EAAI4B,IAAsBhC,GAAK,IAC/CwP,WAAWxP,IAAMA,KAAQA,EAAIuK,OAAgB,GAALvK,EAExC,MADA0C,GAAI0F,KAAKlF,KAAM1C,EAAGR,GACX,GAAID,GAAWsE,EAAI3B,EAAI2B,EAAI3B,EAuBtC,KApBI2B,EACKrE,EAAI,GAAKQ,EAAEwH,GAAGnC,IAAQrF,EAAEyL,SAAW5H,EAAE2D,GAAGnC,IAAQxB,EAAE4H,QACnDzL,EAAIA,EAAEyM,IAAI5I,IAEVkJ,EAAIlJ,EAGJA,EAAI,MAEDpB,IAMPP,EAAI+C,EAAUxC,EAAgBb,EAAW,IAG7CS,EAAI,GAAI9C,GAAU8F,KAEN,CACR,GAAKzF,EAAI,EAAI,CAET,GADAyC,EAAIA,EAAEqK,MAAM1M,IACNqC,EAAE3C,EAAI,KACRwC,GACKG,EAAE3C,EAAEsB,OAASkB,IAAIG,EAAE3C,EAAEsB,OAASkB,GAC5B2B,IACPxB,EAAIA,EAAEoK,IAAI5I,IAKlB,GADAjE,EAAI6B,EAAW7B,EAAI,IACbA,EAAI,KACVI,GAAIA,EAAE0M,MAAM1M,GACRkC,EACKlC,EAAEN,GAAKM,EAAEN,EAAEsB,OAASkB,IAAIlC,EAAEN,EAAEsB,OAASkB,GACnC2B,IACP7D,EAAIA,EAAEyM,IAAI5I,IAIlB,MAAIA,GAAUxB,GACL,EAAJ7C,IAAQ6C,EAAIgD,EAAItC,IAAIV,IAElB0K,EAAI1K,EAAEoK,IAAIM,GAAK7K,EAAI5B,EAAO+B,EAAGI,EAAejC,GAAkB6B,IAkBzE8C,EAAE8J,YAAc,SAAWtK,EAAIpC,GAC3B,MAAOW,GAAQjD,KAAY,MAAN0E,GAAcvE,EAAYuE,EAAI,EAAGwC,EAAK,GAAI,aACtD,EAALxC,EAAS,KAAMpC,EAAI,KAgB3B4C,EAAE5B,SAAW,SAAU9D,GACnB,GAAIM,GACAP,EAAIS,KACJa,EAAItB,EAAEsB,EACNnB,EAAIH,EAAEG,CAyBV,OAtBW,QAANA,EAEGmB,GACAf,EAAM,WACG,EAAJe,IAAQf,EAAM,IAAMA,IAEzBA,EAAM,OAGVA,EAAM8C,EAAerD,EAAEE,GAOnBK,EALM,MAALN,GAAcW,EAAYX,EAAG,EAAG,GAAI,GAAI,QAKnC0B,EAAayB,EAAc7C,EAAKJ,GAAS,EAAJF,EAAO,GAAIqB,GAJ3C0C,GAAL7D,GAAmBA,GAAK2F,EAC1B7B,EAAe1D,EAAKJ,GACpBiD,EAAc7C,EAAKJ,GAKlB,EAAJmB,GAAStB,EAAEE,EAAE,KAAKK,EAAM,IAAMA,IAGhCA,GAQXoF,EAAE+J,UAAY/J,EAAEgK,MAAQ,WACpB,MAAO7O,GAAO,GAAIf,GAAUU,MAAOA,KAAKN,EAAI,EAAG,IASnDwF,EAAEiK,QAAUjK,EAAEkK,OAAS,WACnB,GAAItP,GACAP,EAAIS,KACJN,EAAIH,EAAEG,CAEV,OAAW,QAANA,EAAoBH,EAAE+D,YAE3BxD,EAAM8C,EAAerD,EAAEE,GAEvBK,EAAWyD,GAAL7D,GAAmBA,GAAK2F,EACxB7B,EAAe1D,EAAKJ,GACpBiD,EAAc7C,EAAKJ,GAElBH,EAAEsB,EAAI,EAAI,IAAMf,EAAMA,IAcf,MAAbT,GAAoBC,EAAUoH,OAAOrH,GAEnCC,EAOX,QAASyK,GAASxK,GACd,GAAII,GAAQ,EAAJJ,CACR,OAAOA,GAAI,GAAKA,IAAMI,EAAIA,EAAIA,EAAI,EAKtC,QAASiD,GAAciE,GAMnB,IALA,GAAIhG,GAAGiM,EACHnN,EAAI,EACJ0E,EAAIwC,EAAE9F,OACNmB,EAAI2E,EAAE,GAAK,GAEHxC,EAAJ1E,GAAS,CAGb,IAFAkB,EAAIgG,EAAElH,KAAO,GACbmN,EAAInL,EAAWd,EAAEE,OACT+L,IAAKjM,EAAI,IAAMA,GACvBqB,GAAKrB,EAIT,IAAMwD,EAAInC,EAAEnB,OAA8B,KAAtBmB,EAAEjB,aAAaoD,KACnC,MAAOnC,GAAExB,MAAO,EAAG2D,EAAI,GAAK,GAKhC,QAASsE,GAAS5I,EAAGqC,GACjB,GAAIyE,GAAGrH,EACH2C,EAAKpC,EAAEN,EACPoK,EAAKzH,EAAE3C,EACPE,EAAII,EAAEc,EACNwD,EAAIjC,EAAEvB,EACNoB,EAAIlC,EAAEL,EACN2P,EAAIjN,EAAE1C,CAGV,KAAMC,IAAM0E,EAAI,MAAO,KAMvB,IAJAwC,EAAI1E,IAAOA,EAAG,GACd3C,EAAIqK,IAAOA,EAAG,GAGThD,GAAKrH,EAAI,MAAOqH,GAAIrH,EAAI,GAAK6E,EAAI1E,CAGtC,IAAKA,GAAK0E,EAAI,MAAO1E,EAMrB,IAJAkH,EAAQ,EAAJlH,EACJH,EAAIyC,GAAKoN,GAGHlN,IAAO0H,EAAK,MAAOrK,GAAI,GAAK2C,EAAK0E,EAAI,EAAI,EAG/C,KAAMrH,EAAI,MAAOyC,GAAIoN,EAAIxI,EAAI,EAAI,EAKjC,KAHAxC,GAAMpC,EAAIE,EAAGpB,SAAasO,EAAIxF,EAAG9I,QAAWkB,EAAIoN,EAG1C1P,EAAI,EAAO0E,EAAJ1E,EAAOA,IAAM,GAAKwC,EAAGxC,IAAMkK,EAAGlK,GAAK,MAAOwC,GAAGxC,GAAKkK,EAAGlK,GAAKkH,EAAI,EAAI,EAG/E,OAAO5E,IAAKoN,EAAI,EAAIpN,EAAIoN,EAAIxI,EAAI,EAAI,GASxC,QAASM,GAAsB5H,EAAGyE,EAAKC,GACnC,OAAS1E,EAAI4E,EAAS5E,KAAQyE,GAAYC,GAAL1E,EAIzC,QAASsE,GAAQyL,GACb,MAA8C,kBAAvCC,OAAOpK,UAAU7B,SAASQ,KAAKwL,GAS1C,QAAS5M,GAAW5C,EAAKgC,EAAQD,GAO7B,IANA,GAAIwC,GAEAmL,EADA3B,GAAO,GAEPlO,EAAI,EACJE,EAAMC,EAAIiB,OAEFlB,EAAJF,GAAW,CACf,IAAM6P,EAAO3B,EAAI9M,OAAQyO,IAAQ3B,EAAI2B,IAAS1N,GAG9C,IAFA+L,EAAKxJ,EAAI,IAAO5D,EAASW,QAAStB,EAAIkD,OAAQrD,MAEtC0E,EAAIwJ,EAAI9M,OAAQsD,IAEfwJ,EAAIxJ,GAAKxC,EAAU,IACD,MAAdgM,EAAIxJ,EAAI,KAAawJ,EAAIxJ,EAAI,GAAK,GACvCwJ,EAAIxJ,EAAI,IAAMwJ,EAAIxJ,GAAKxC,EAAU,EACjCgM,EAAIxJ,IAAMxC,GAKtB,MAAOgM,GAAIvB,UAIf,QAAS9I,GAAe1D,EAAKJ,GACzB,OAASI,EAAIiB,OAAS,EAAIjB,EAAIkD,OAAO,GAAK,IAAMlD,EAAIY,MAAM,GAAKZ,IACvD,EAAJJ,EAAQ,IAAM,MAASA,EAI/B,QAASiD,GAAc7C,EAAKJ,GACxB,GAAIG,GAAKiN,CAGT,IAAS,EAAJpN,EAAQ,CAGT,IAAMoN,EAAI,OAAQpN,EAAGoN,GAAK,KAC1BhN,EAAMgN,EAAIhN,MAOV,IAHAD,EAAMC,EAAIiB,SAGHrB,EAAIG,EAAM,CACb,IAAMiN,EAAI,IAAKpN,GAAKG,IAAOH,EAAGoN,GAAK,KACnChN,GAAOgN,MACKjN,GAAJH,IACRI,EAAMA,EAAIY,MAAO,EAAGhB,GAAM,IAAMI,EAAIY,MAAMhB,GAIlD,OAAOI,GAIX,QAASqE,GAAS5E,GAEd,MADAA,GAAIwP,WAAWxP,GACJ,EAAJA,EAAQyF,EAASzF,GAAKiC,EAAUjC,GAvoF3C,GAAI8H,GAAWzG,EACXO,EAAY,uCACZ6D,EAAW2C,KAAK+C,KAChBlJ,EAAYmG,KAAKuD,MACjB9D,EAAU,iCACV/D,EAAe,gBACfrC,EAAgB,kDAChBP,EAAW,mEACXwE,EAAO,KACPtD,EAAW,GACXJ,EAAmB,iBAEnBuD,GAAY,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,MAC7E2D,EAAY,IAOZvB,EAAM,GA2nFV,IAznFsB,mBAAVuI,UAAwBpI,EAAYoI,QAynF1B,kBAAVC,SAAwBA,OAAOC,IACvCD,OAAQ,WAAc,MAAOtQ,WAG1B,IAAsB,mBAAVwQ,SAAyBA,OAAOC,SAI/C,GAHAD,OAAOC,QAAUzQ,KAGXiI,EAAY,IAAMA,EAAYyI,QAAQ,UAAkB,MAAOpQ,SAI/DP,KAAYA,EAA2B,mBAAR4Q,MAAsBA,KAAOC,SAAS,kBAC3E7Q,EAAUG,UAAYF,KAE3BY"} \ No newline at end of file diff --git a/node_modules/bignumber.js/bignumber.min.js b/node_modules/bignumber.js/bignumber.min.js new file mode 100644 index 0000000..ec19b34 --- /dev/null +++ b/node_modules/bignumber.js/bignumber.min.js @@ -0,0 +1,3 @@ +/* bignumber.js v2.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */ +!function(e){"use strict";function n(e){function E(e,n){var t,r,i,o,u,s,f=this;if(!(f instanceof E))return j&&L(26,"constructor call without new",e),new E(e,n);if(null!=n&&H(n,2,64,M,"base")){if(n=0|n,s=e+"",10==n)return f=new E(e instanceof E?e:s),U(f,P+f.e+1,k);if((o="number"==typeof e)&&0*e!=0||!new RegExp("^-?"+(t="["+N.slice(0,n)+"]+")+"(?:\\."+t+")?$",37>n?"i":"").test(s))return h(f,s,o,n);o?(f.s=0>1/e?(s=s.slice(1),-1):1,j&&s.replace(/^0\.0*|\./,"").length>15&&L(M,v,e),o=!1):f.s=45===s.charCodeAt(0)?(s=s.slice(1),-1):1,s=D(s,10,n,f.s)}else{if(e instanceof E)return f.s=e.s,f.e=e.e,f.c=(e=e.c)?e.slice():e,void(M=0);if((o="number"==typeof e)&&0*e==0){if(f.s=0>1/e?(e=-e,-1):1,e===~~e){for(r=0,i=e;i>=10;i/=10,r++);return f.e=r,f.c=[e],void(M=0)}s=e+""}else{if(!g.test(s=e+""))return h(f,s,o);f.s=45===s.charCodeAt(0)?(s=s.slice(1),-1):1}}for((r=s.indexOf("."))>-1&&(s=s.replace(".","")),(i=s.search(/e/i))>0?(0>r&&(r=i),r+=+s.slice(i+1),s=s.substring(0,i)):0>r&&(r=s.length),i=0;48===s.charCodeAt(i);i++);for(u=s.length;48===s.charCodeAt(--u););if(s=s.slice(i,u+1))if(u=s.length,o&&j&&u>15&&(e>y||e!==d(e))&&L(M,v,f.s*e),r=r-i-1,r>z)f.c=f.e=null;else if(G>r)f.c=[f.e=0];else{if(f.e=r,f.c=[],i=(r+1)%O,0>r&&(i+=O),u>i){for(i&&f.c.push(+s.slice(0,i)),u-=O;u>i;)f.c.push(+s.slice(i,i+=O));s=s.slice(i),i=O-s.length}else i-=u;for(;i--;s+="0");f.c.push(+s)}else f.c=[f.e=0];M=0}function D(e,n,t,i){var o,u,f,c,a,h,g,p=e.indexOf("."),d=P,m=k;for(37>t&&(e=e.toLowerCase()),p>=0&&(f=J,J=0,e=e.replace(".",""),g=new E(t),a=g.pow(e.length-p),J=f,g.c=s(l(r(a.c),a.e),10,n),g.e=g.c.length),h=s(e,t,n),u=f=h.length;0==h[--f];h.pop());if(!h[0])return"0";if(0>p?--u:(a.c=h,a.e=u,a.s=i,a=C(a,g,d,m,n),h=a.c,c=a.r,u=a.e),o=u+d+1,p=h[o],f=n/2,c=c||0>o||null!=h[o+1],c=4>m?(null!=p||c)&&(0==m||m==(a.s<0?3:2)):p>f||p==f&&(4==m||c||6==m&&1&h[o-1]||m==(a.s<0?8:7)),1>o||!h[0])e=c?l("1",-d):"0";else{if(h.length=o,c)for(--n;++h[--o]>n;)h[o]=0,o||(++u,h.unshift(1));for(f=h.length;!h[--f];);for(p=0,e="";f>=p;e+=N.charAt(h[p++]));e=l(e,u)}return e}function F(e,n,t,i){var o,u,s,c,a;if(t=null!=t&&H(t,0,8,i,w)?0|t:k,!e.c)return e.toString();if(o=e.c[0],s=e.e,null==n)a=r(e.c),a=19==i||24==i&&B>=s?f(a,s):l(a,s);else if(e=U(new E(e),n,t),u=e.e,a=r(e.c),c=a.length,19==i||24==i&&(u>=n||B>=u)){for(;n>c;a+="0",c++);a=f(a,u)}else if(n-=s,a=l(a,u),u+1>c){if(--n>0)for(a+=".";n--;a+="0");}else if(n+=u-c,n>0)for(u+1==c&&(a+=".");n--;a+="0");return e.s<0&&o?"-"+a:a}function _(e,n){var t,r,i=0;for(u(e[0])&&(e=e[0]),t=new E(e[0]);++ie||e>t||e!=c(e))&&L(r,(i||"decimal places")+(n>e||e>t?" out of range":" not an integer"),e),!0}function I(e,n,t){for(var r=1,i=n.length;!n[--i];n.pop());for(i=n[0];i>=10;i/=10,r++);return(t=r+t*O-1)>z?e.c=e.e=null:G>t?e.c=[e.e=0]:(e.e=t,e.c=n),e}function L(e,n,t){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][e]+"() "+n+": "+t);throw r.name="BigNumber Error",M=0,r}function U(e,n,t,r){var i,o,u,s,f,l,c,a=e.c,h=S;if(a){e:{for(i=1,s=a[0];s>=10;s/=10,i++);if(o=n-i,0>o)o+=O,u=n,f=a[l=0],c=f/h[i-u-1]%10|0;else if(l=p((o+1)/O),l>=a.length){if(!r)break e;for(;a.length<=l;a.push(0));f=c=0,i=1,o%=O,u=o-O+1}else{for(f=s=a[l],i=1;s>=10;s/=10,i++);o%=O,u=o-O+i,c=0>u?0:f/h[i-u-1]%10|0}if(r=r||0>n||null!=a[l+1]||(0>u?f:f%h[i-u-1]),r=4>t?(c||r)&&(0==t||t==(e.s<0?3:2)):c>5||5==c&&(4==t||r||6==t&&(o>0?u>0?f/h[i-u]:0:a[l-1])%10&1||t==(e.s<0?8:7)),1>n||!a[0])return a.length=0,r?(n-=e.e+1,a[0]=h[(O-n%O)%O],e.e=-n||0):a[0]=e.e=0,e;if(0==o?(a.length=l,s=1,l--):(a.length=l+1,s=h[O-o],a[l]=u>0?d(f/h[i-u]%h[u])*s:0),r)for(;;){if(0==l){for(o=1,u=a[0];u>=10;u/=10,o++);for(u=a[0]+=s,s=1;u>=10;u/=10,s++);o!=s&&(e.e++,a[0]==b&&(a[0]=1));break}if(a[l]+=s,a[l]!=b)break;a[l--]=0,s=1}for(o=a.length;0===a[--o];a.pop());}e.e>z?e.c=e.e=null:e.et?null!=(e=i[t++]):void 0};return f(n="DECIMAL_PLACES")&&H(e,0,A,2,n)&&(P=0|e),r[n]=P,f(n="ROUNDING_MODE")&&H(e,0,8,2,n)&&(k=0|e),r[n]=k,f(n="EXPONENTIAL_AT")&&(u(e)?H(e[0],-A,0,2,n)&&H(e[1],0,A,2,n)&&(B=0|e[0],$=0|e[1]):H(e,-A,A,2,n)&&(B=-($=0|(0>e?-e:e)))),r[n]=[B,$],f(n="RANGE")&&(u(e)?H(e[0],-A,-1,2,n)&&H(e[1],1,A,2,n)&&(G=0|e[0],z=0|e[1]):H(e,-A,A,2,n)&&(0|e?G=-(z=0|(0>e?-e:e)):j&&L(2,n+" cannot be zero",e))),r[n]=[G,z],f(n="ERRORS")&&(e===!!e||1===e||0===e?(M=0,H=(j=!!e)?x:o):j&&L(2,n+m,e)),r[n]=j,f(n="CRYPTO")&&(e===!!e||1===e||0===e?(V=!(!e||!a),e&&!V&&j&&L(2,"crypto unavailable",a)):j&&L(2,n+m,e)),r[n]=V,f(n="MODULO_MODE")&&H(e,0,9,2,n)&&(W=0|e),r[n]=W,f(n="POW_PRECISION")&&H(e,0,A,2,n)&&(J=0|e),r[n]=J,f(n="FORMAT")&&("object"==typeof e?X=e:j&&L(2,n+" not an object",e)),r[n]=X,r},E.max=function(){return _(arguments,T.lt)},E.min=function(){return _(arguments,T.gt)},E.random=function(){var e=9007199254740992,n=Math.random()*e&2097151?function(){return d(Math.random()*e)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(e){var t,r,i,o,u,s=0,f=[],l=new E(q);if(e=null!=e&&H(e,0,A,14)?0|e:P,o=p(e/O),V)if(a&&a.getRandomValues){for(t=a.getRandomValues(new Uint32Array(o*=2));o>s;)u=131072*t[s]+(t[s+1]>>>11),u>=9e15?(r=a.getRandomValues(new Uint32Array(2)),t[s]=r[0],t[s+1]=r[1]):(f.push(u%1e14),s+=2);s=o/2}else if(a&&a.randomBytes){for(t=a.randomBytes(o*=7);o>s;)u=281474976710656*(31&t[s])+1099511627776*t[s+1]+4294967296*t[s+2]+16777216*t[s+3]+(t[s+4]<<16)+(t[s+5]<<8)+t[s+6],u>=9e15?a.randomBytes(7).copy(t,s):(f.push(u%1e14),s+=7);s=o/7}else j&&L(14,"crypto unavailable",a);if(!s)for(;o>s;)u=n(),9e15>u&&(f[s++]=u%1e14);for(o=f[--s],e%=O,o&&e&&(u=S[O-e],f[s]=d(o/u)*u);0===f[s];f.pop(),s--);if(0>s)f=[i=0];else{for(i=-1;0===f[0];f.shift(),i-=O);for(s=1,u=f[0];u>=10;u/=10,s++);O>s&&(i-=O-s)}return l.e=i,l.c=f,l}}(),C=function(){function e(e,n,t){var r,i,o,u,s=0,f=e.length,l=n%R,c=n/R|0;for(e=e.slice();f--;)o=e[f]%R,u=e[f]/R|0,r=c*o+u*l,i=l*o+r%R*R+s,s=(i/t|0)+(r/R|0)+c*u,e[f]=i%t;return s&&e.unshift(s),e}function n(e,n,t,r){var i,o;if(t!=r)o=t>r?1:-1;else for(i=o=0;t>i;i++)if(e[i]!=n[i]){o=e[i]>n[i]?1:-1;break}return o}function r(e,n,t,r){for(var i=0;t--;)e[t]-=i,i=e[t]1;e.shift());}return function(i,o,u,s,f){var l,c,a,h,g,p,m,w,v,N,y,S,R,A,D,F,_,x=i.s==o.s?1:-1,I=i.c,L=o.c;if(!(I&&I[0]&&L&&L[0]))return new E(i.s&&o.s&&(I?!L||I[0]!=L[0]:L)?I&&0==I[0]||!L?0*x:x/0:NaN);for(w=new E(x),v=w.c=[],c=i.e-o.e,x=u+c+1,f||(f=b,c=t(i.e/O)-t(o.e/O),x=x/O|0),a=0;L[a]==(I[a]||0);a++);if(L[a]>(I[a]||0)&&c--,0>x)v.push(1),h=!0;else{for(A=I.length,F=L.length,a=0,x+=2,g=d(f/(L[0]+1)),g>1&&(L=e(L,g,f),I=e(I,g,f),F=L.length,A=I.length),R=F,N=I.slice(0,F),y=N.length;F>y;N[y++]=0);_=L.slice(),_.unshift(0),D=L[0],L[1]>=f/2&&D++;do{if(g=0,l=n(L,N,F,y),0>l){if(S=N[0],F!=y&&(S=S*f+(N[1]||0)),g=d(S/D),g>1)for(g>=f&&(g=f-1),p=e(L,g,f),m=p.length,y=N.length;1==n(p,N,m,y);)g--,r(p,m>F?_:L,m,f),m=p.length,l=1;else 0==g&&(l=g=1),p=L.slice(),m=p.length;if(y>m&&p.unshift(0),r(N,p,y,f),y=N.length,-1==l)for(;n(L,N,F,y)<1;)g++,r(N,y>F?_:L,y,f),y=N.length}else 0===l&&(g++,N=[0]);v[a++]=g,N[0]?N[y++]=I[R]||0:(N=[I[R]],y=1)}while((R++=10;x/=10,a++);U(w,u+(w.e=a+c*O-1)+1,s,h)}else w.e=c,w.r=+h;return w}}(),h=function(){var e=/^(-?)0([xbo])(?=\w[\w.]*$)/i,n=/^([^.]+)\.$/,t=/^\.([^.]+)$/,r=/^-?(Infinity|NaN)$/,i=/^\s*\+(?=[\w.])|^\s+|\s+$/g;return function(o,u,s,f){var l,c=s?u:u.replace(i,"");if(r.test(c))o.s=isNaN(c)?null:0>c?-1:1;else{if(!s&&(c=c.replace(e,function(e,n,t){return l="x"==(t=t.toLowerCase())?16:"b"==t?2:8,f&&f!=l?e:n}),f&&(l=f,c=c.replace(n,"$1").replace(t,"0.$1")),u!=c))return new E(c,l);j&&L(M,"not a"+(f?" base "+f:"")+" number",u),o.s=null}o.c=o.e=null,M=0}}(),T.absoluteValue=T.abs=function(){var e=new E(this);return e.s<0&&(e.s=1),e},T.ceil=function(){return U(new E(this),this.e+1,2)},T.comparedTo=T.cmp=function(e,n){return M=1,i(this,new E(e,n))},T.decimalPlaces=T.dp=function(){var e,n,r=this.c;if(!r)return null;if(e=((n=r.length-1)-t(this.e/O))*O,n=r[n])for(;n%10==0;n/=10,e--);return 0>e&&(e=0),e},T.dividedBy=T.div=function(e,n){return M=3,C(this,new E(e,n),P,k)},T.dividedToIntegerBy=T.divToInt=function(e,n){return M=4,C(this,new E(e,n),0,1)},T.equals=T.eq=function(e,n){return M=5,0===i(this,new E(e,n))},T.floor=function(){return U(new E(this),this.e+1,3)},T.greaterThan=T.gt=function(e,n){return M=6,i(this,new E(e,n))>0},T.greaterThanOrEqualTo=T.gte=function(e,n){return M=7,1===(n=i(this,new E(e,n)))||0===n},T.isFinite=function(){return!!this.c},T.isInteger=T.isInt=function(){return!!this.c&&t(this.e/O)>this.c.length-2},T.isNaN=function(){return!this.s},T.isNegative=T.isNeg=function(){return this.s<0},T.isZero=function(){return!!this.c&&0==this.c[0]},T.lessThan=T.lt=function(e,n){return M=8,i(this,new E(e,n))<0},T.lessThanOrEqualTo=T.lte=function(e,n){return M=9,-1===(n=i(this,new E(e,n)))||0===n},T.minus=T.sub=function(e,n){var r,i,o,u,s=this,f=s.s;if(M=10,e=new E(e,n),n=e.s,!f||!n)return new E(NaN);if(f!=n)return e.s=-n,s.plus(e);var l=s.e/O,c=e.e/O,a=s.c,h=e.c;if(!l||!c){if(!a||!h)return a?(e.s=-n,e):new E(h?s:NaN);if(!a[0]||!h[0])return h[0]?(e.s=-n,e):new E(a[0]?s:3==k?-0:0)}if(l=t(l),c=t(c),a=a.slice(),f=l-c){for((u=0>f)?(f=-f,o=a):(c=l,o=h),o.reverse(),n=f;n--;o.push(0));o.reverse()}else for(i=(u=(f=a.length)<(n=h.length))?f:n,f=n=0;i>n;n++)if(a[n]!=h[n]){u=a[n]0)for(;n--;a[r++]=0);for(n=b-1;i>f;){if(a[--i]0?(s=u,r=l):(o=-o,r=f),r.reverse();o--;r.push(0));r.reverse()}for(o=f.length,n=l.length,0>o-n&&(r=l,l=f,f=r,n=o),o=0;n;)o=(f[--n]=f[n]+l[n]+o)/b|0,f[n]%=b;return o&&(f.unshift(o),++s),I(e,f,s)},T.precision=T.sd=function(e){var n,t,r=this,i=r.c;if(null!=e&&e!==!!e&&1!==e&&0!==e&&(j&&L(13,"argument"+m,e),e!=!!e&&(e=null)),!i)return null;if(t=i.length-1,n=t*O+1,t=i[t]){for(;t%10==0;t/=10,n--);for(t=i[0];t>=10;t/=10,n++);}return e&&r.e+1>n&&(n=r.e+1),n},T.round=function(e,n){var t=new E(this);return(null==e||H(e,0,A,15))&&U(t,~~e+this.e+1,null!=n&&H(n,0,8,15,w)?0|n:k),t},T.shift=function(e){var n=this;return H(e,-y,y,16,"argument")?n.times("1e"+c(e)):new E(n.c&&n.c[0]&&(-y>e||e>y)?n.s*(0>e?0:1/0):n)},T.squareRoot=T.sqrt=function(){var e,n,i,o,u,s=this,f=s.c,l=s.s,c=s.e,a=P+4,h=new E("0.5");if(1!==l||!f||!f[0])return new E(!l||0>l&&(!f||f[0])?NaN:f?s:1/0);if(l=Math.sqrt(+s),0==l||l==1/0?(n=r(f),(n.length+c)%2==0&&(n+="0"),l=Math.sqrt(n),c=t((c+1)/2)-(0>c||c%2),l==1/0?n="1e"+c:(n=l.toExponential(),n=n.slice(0,n.indexOf("e")+1)+c),i=new E(n)):i=new E(l+""),i.c[0])for(c=i.e,l=c+a,3>l&&(l=0);;)if(u=i,i=h.times(u.plus(C(s,u,a,1))),r(u.c).slice(0,l)===(n=r(i.c)).slice(0,l)){if(i.el&&(d=N,N=y,y=d,o=l,l=h,h=o),o=l+h,d=[];o--;d.push(0));for(m=b,w=R,o=h;--o>=0;){for(r=0,g=y[o]%w,p=y[o]/w|0,s=l,u=o+s;u>o;)c=N[--s]%w,a=N[s]/w|0,f=p*c+a*g,c=g*c+f%w*w+d[u]+r,r=(c/m|0)+(f/w|0)+p*a,d[u--]=c%m;d[u]=r}return r?++i:d.shift(),I(e,d,i)},T.toDigits=function(e,n){var t=new E(this);return e=null!=e&&H(e,1,A,18,"precision")?0|e:null,n=null!=n&&H(n,0,8,18,w)?0|n:k,e?U(t,e,n):t},T.toExponential=function(e,n){return F(this,null!=e&&H(e,0,A,19)?~~e+1:null,n,19)},T.toFixed=function(e,n){return F(this,null!=e&&H(e,0,A,20)?~~e+this.e+1:null,n,20)},T.toFormat=function(e,n){var t=F(this,null!=e&&H(e,0,A,21)?~~e+this.e+1:null,n,21);if(this.c){var r,i=t.split("."),o=+X.groupSize,u=+X.secondaryGroupSize,s=X.groupSeparator,f=i[0],l=i[1],c=this.s<0,a=c?f.slice(1):f,h=a.length;if(u&&(r=o,o=u,u=r,h-=r),o>0&&h>0){for(r=h%o||o,f=a.substr(0,r);h>r;r+=o)f+=s+a.substr(r,o);u>0&&(f+=s+a.slice(r)),c&&(f="-"+f)}t=l?f+X.decimalSeparator+((u=+X.fractionGroupSize)?l.replace(new RegExp("\\d{"+u+"}\\B","g"),"$&"+X.fractionGroupSeparator):l):f}return t},T.toFraction=function(e){var n,t,i,o,u,s,f,l,c,a=j,h=this,g=h.c,p=new E(q),d=t=new E(q),m=f=new E(q);if(null!=e&&(j=!1,s=new E(e),j=a,(!(a=s.isInt())||s.lt(q))&&(j&&L(22,"max denominator "+(a?"out of range":"not an integer"),e),e=!a&&s.c&&U(s,s.e+1,1).gte(q)?s:null)),!g)return h.toString();for(c=r(g),o=p.e=c.length-h.e-1,p.c[0]=S[(u=o%O)<0?O+u:u],e=!e||s.cmp(p)>0?o>0?p:d:s,u=z,z=1/0,s=new E(c),f.c[0]=0;l=C(s,p,0,1),i=t.plus(l.times(m)),1!=i.cmp(e);)t=m,m=i,d=f.plus(l.times(i=d)),f=i,p=s.minus(l.times(i=p)),s=i;return i=C(e.minus(t),m,0,1),f=f.plus(i.times(d)),t=t.plus(i.times(m)),f.s=d.s=h.s,o*=2,n=C(d,m,o,k).minus(h).abs().cmp(C(f,t,o,k).minus(h).abs())<1?[d.toString(),m.toString()]:[f.toString(),t.toString()],z=u,n},T.toNumber=function(){return+this},T.toPower=T.pow=function(e,n){var t,r,i,o=d(0>e?-e:+e),u=this;if(null!=n&&(M=23,n=new E(n)),!H(e,-y,y,23,"exponent")&&(!isFinite(e)||o>y&&(e/=0)||parseFloat(e)!=e&&!(e=NaN))||0==e)return t=Math.pow(+u,e),new E(n?t%n:t);for(n?e>1&&u.gt(q)&&u.isInt()&&n.gt(q)&&n.isInt()?u=u.mod(n):(i=n,n=null):J&&(t=p(J/O+2)),r=new E(q);;){if(o%2){if(r=r.times(u),!r.c)break;t?r.c.length>t&&(r.c.length=t):n&&(r=r.mod(n))}if(o=d(o/2),!o)break;u=u.times(u),t?u.c&&u.c.length>t&&(u.c.length=t):n&&(u=u.mod(n))}return n?r:(0>e&&(r=q.div(r)),i?r.mod(i):t?U(r,J,k):r)},T.toPrecision=function(e,n){return F(this,null!=e&&H(e,1,A,24,"precision")?0|e:null,n,24)},T.toString=function(e){var n,t=this,i=t.s,o=t.e;return null===o?i?(n="Infinity",0>i&&(n="-"+n)):n="NaN":(n=r(t.c),n=null!=e&&H(e,2,64,25,"base")?D(l(n,o),0|e,10,i):B>=o||o>=$?f(n,o):l(n,o),0>i&&t.c[0]&&(n="-"+n)),n},T.truncated=T.trunc=function(){return U(new E(this),this.e+1,1)},T.valueOf=T.toJSON=function(){var e,n=this,t=n.e;return null===t?n.toString():(e=r(n.c),e=B>=t||t>=$?f(e,t):l(e,t),n.s<0?"-"+e:e)},null!=e&&E.config(e),E}function t(e){var n=0|e;return e>0||e===n?n:n-1}function r(e){for(var n,t,r=1,i=e.length,o=e[0]+"";i>r;){for(n=e[r++]+"",t=O-n.length;t--;n="0"+n);o+=n}for(i=o.length;48===o.charCodeAt(--i););return o.slice(0,i+1||1)}function i(e,n){var t,r,i=e.c,o=n.c,u=e.s,s=n.s,f=e.e,l=n.e;if(!u||!s)return null;if(t=i&&!i[0],r=o&&!o[0],t||r)return t?r?0:-s:u;if(u!=s)return u;if(t=0>u,r=f==l,!i||!o)return r?0:!i^t?1:-1;if(!r)return f>l^t?1:-1;for(s=(f=i.length)<(l=o.length)?f:l,u=0;s>u;u++)if(i[u]!=o[u])return i[u]>o[u]^t?1:-1;return f==l?0:f>l^t?1:-1}function o(e,n,t){return(e=c(e))>=n&&t>=e}function u(e){return"[object Array]"==Object.prototype.toString.call(e)}function s(e,n,t){for(var r,i,o=[0],u=0,s=e.length;s>u;){for(i=o.length;i--;o[i]*=n);for(o[r=0]+=N.indexOf(e.charAt(u++));rt-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/t|0,o[r]%=t)}return o.reverse()}function f(e,n){return(e.length>1?e.charAt(0)+"."+e.slice(1):e)+(0>n?"e":"e+")+n}function l(e,n){var t,r;if(0>n){for(r="0.";++n;r+="0");e=r+e}else if(t=e.length,++n>t){for(r="0",n-=t;--n;r+="0");e+=r}else t>n&&(e=e.slice(0,n)+"."+e.slice(n));return e}function c(e){return e=parseFloat(e),0>e?p(e):d(e)}var a,h,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,p=Math.ceil,d=Math.floor,m=" not a boolean or binary digit",w="rounding mode",v="number type has more than 15 significant digits",N="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",b=1e14,O=14,y=9007199254740991,S=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],R=1e7,A=1e9;if("undefined"!=typeof crypto&&(a=crypto),"function"==typeof define&&define.amd)define(function(){return n()});else if("undefined"!=typeof module&&module.exports){if(module.exports=n(),!a)try{a=require("crypto")}catch(E){}}else e||(e="undefined"!=typeof self?self:Function("return this")()),e.BigNumber=n()}(this); +//# sourceMappingURL=bignumber.js.map \ No newline at end of file diff --git a/node_modules/bignumber.js/bower.json b/node_modules/bignumber.js/bower.json new file mode 100644 index 0000000..f83fbca --- /dev/null +++ b/node_modules/bignumber.js/bower.json @@ -0,0 +1,36 @@ +{ + "name": "bignumber.js", + "main": "bignumber.js", + "version": "2.3.0", + "homepage": "https://github.com/MikeMcl/bignumber.js", + "authors": [ + "Michael Mclaughlin " + ], + "description": "A library for arbitrary-precision decimal and non-decimal arithmetic", + "moduleType": [ + "amd", + "globals", + "node" + ], + "keywords": [ + "arbitrary", + "precision", + "arithmetic", + "big", + "number", + "decimal", + "float", + "biginteger", + "bigdecimal", + "bignumber", + "bigint", + "bignum" + ], + "license": "MIT", + "ignore": [ + ".*", + "*.json", + "test" + ] +} + diff --git a/node_modules/bignumber.js/doc/API.html b/node_modules/bignumber.js/doc/API.html new file mode 100644 index 0000000..1c082a2 --- /dev/null +++ b/node_modules/bignumber.js/doc/API.html @@ -0,0 +1,2175 @@ + + + + + + +bignumber.js API + + + + + + +
    + +

    bignumber.js

    + +

    A JavaScript library for arbitrary-precision arithmetic.

    +

    Hosted on GitHub.

    + +

    API

    + +

    + See the README on GitHub for a + quick-start introduction. +

    +

    + In all examples below, var and semicolons are not shown, and if a commented-out + value is in quotes it means toString has been called on the preceding expression. +

    + + +

    CONSTRUCTOR

    + +
    + BigNumberBigNumber(value [, base]) ⇒ BigNumber +
    +
    +
    value
    +
    + number|string|BigNumber: see RANGE for + range. +
    +
    + A numeric value. +
    +
    + Legitimate values include ±0, ±Infinity and + NaN. +
    +
    + Values of type number with more than 15 significant digits are + considered invalid (if ERRORS is true) as calling + toString or valueOf on + such numbers may not result in the intended value. +
    console.log( 823456789123456.3 );    // 823456789123456.2
    +
    +
    + There is no limit to the number of digits of a value of type string (other than + that of JavaScript's maximum array size). +
    +
    + Decimal string values may be in exponential, as well as normal (fixed-point) notation. + Non-decimal values must be in normal notation. +
    +
    + String values in hexadecimal literal form, e.g. '0xff', are valid, as are + string values with the octal and binary prefixs '0o' and '0b'. + String values in octal literal form without the prefix will be interpreted as + decimals, e.g. '011' is interpreted as 11, not 9. +
    +
    Values in any base may have fraction digits.
    +
    + For bases from 10 to 36, lower and/or upper case letters can be + used to represent values from 10 to 35. +
    +
    + For bases above 36, a-z represents values from 10 to + 35, A-Z from 36 to 61, and + $ and _ represent 62 and 63 respectively + (this can be changed by editing the ALPHABET variable near the top of the + source file). +
    +
    +
    +
    base
    +
    + number: integer, 2 to 64 inclusive +
    +
    The base of value.
    +
    + If base is omitted, or is null or undefined, base + 10 is assumed. +
    +
    +
    +

    Returns a new instance of a BigNumber object.

    +

    + If a base is specified, the value is rounded according to + the current DECIMAL_PLACES and + ROUNDING_MODE configuration. +

    +

    + See Errors for the treatment of an invalid value or + base. +

    +
    +x = new BigNumber(9)                       // '9'
    +y = new BigNumber(x)                       // '9'
    +
    +// 'new' is optional if ERRORS is false
    +BigNumber(435.345)                         // '435.345'
    +
    +new BigNumber('5032485723458348569331745.33434346346912144534543')
    +new BigNumber('4.321e+4')                  // '43210'
    +new BigNumber('-735.0918e-430')            // '-7.350918e-428'
    +new BigNumber(Infinity)                    // 'Infinity'
    +new BigNumber(NaN)                         // 'NaN'
    +new BigNumber('.5')                        // '0.5'
    +new BigNumber('+2')                        // '2'
    +new BigNumber(-10110100.1, 2)              // '-180.5'
    +new BigNumber(-0b10110100.1)               // '-180.5'
    +new BigNumber('123412421.234324', 5)       // '607236.557696'
    +new BigNumber('ff.8', 16)                  // '255.5'
    +new BigNumber('0xff.8')                    // '255.5'
    +

    + The following throws 'not a base 2 number' if + ERRORS is true, otherwise it returns a BigNumber with value + NaN. +

    +
    new BigNumber(9, 2)
    +

    + The following throws 'number type has more than 15 significant digits' if + errors is true, otherwise it returns a BigNumber with value + 96517860459076820. +

    +
    new BigNumber(96517860459076817.4395)
    +

    + The following throws 'not a number' if ERRORS + is true, otherwise it returns a BigNumber with value NaN. +

    +
    new BigNumber('blurgh')
    +

    + A value is only rounded by the constructor if a base is specified. +

    +
    BigNumber.config({ DECIMAL_PLACES: 5 })
    +new BigNumber(1.23456789)                  // '1.23456789'
    +new BigNumber(1.23456789, 10)              // '1.23457'
    + + + +

    Methods

    +

    The static methods of a BigNumber constructor.

    + + + + +
    + another.another([obj]) ⇒ BigNumber constructor +
    +

    obj: object

    +

    + Returns a new independent BigNumber constructor with configuration as described by + obj (see config), or with the default + configuration if obj is null or undefined. +

    +
    BigNumber.config({ DECIMAL_PLACES: 5 })
    +BN = BigNumber.another({ DECIMAL_PLACES: 9 })
    +
    +x = new BigNumber(1)
    +y = new BN(1)
    +
    +x.div(3)                        // 0.33333
    +y.div(3)                        // 0.333333333
    +
    +// BN = BigNumber.another({ DECIMAL_PLACES: 9 }) is equivalent to:
    +BN = BigNumber.another()
    +BN.config({ DECIMAL_PLACES: 9 })
    + + + +
    configconfig([obj]) ⇒ object
    +

    + obj: object: an object that contains some or all of the following + properties. +

    +

    Configures the 'global' settings for this particular BigNumber constructor.

    +

    Note: the configuration can also be supplied as an argument list, see below.

    +
    +
    DECIMAL_PLACES
    +
    + number: integer, 0 to 1e+9 inclusive
    + Default value: 20 +
    +
    + The maximum number of decimal places of the results of operations involving + division, i.e. division, square root and base conversion operations, and power + operations with negative exponents.
    +
    +
    +
    BigNumber.config({ DECIMAL_PLACES: 5 })
    +BigNumber.config(5)    // equivalent
    +
    + + + +
    ROUNDING_MODE
    +
    + number: integer, 0 to 8 inclusive
    + Default value: 4 (ROUND_HALF_UP) +
    +
    + The rounding mode used in the above operations and the default rounding mode of + round, + toExponential, + toFixed, + toFormat and + toPrecision. +
    +
    The modes are available as enumerated properties of the BigNumber constructor.
    +
    +
    BigNumber.config({ ROUNDING_MODE: 0 })
    +BigNumber.config(null, BigNumber.ROUND_UP)    // equivalent
    +
    + + + +
    EXPONENTIAL_AT
    +
    + number: integer, magnitude 0 to 1e+9 inclusive, or +
    + number[]: [ integer -1e+9 to 0 inclusive, integer + 0 to 1e+9 inclusive ]
    + Default value: [-7, 20] +
    +
    + The exponent value(s) at which toString returns exponential notation. +
    +
    + If a single number is assigned, the value is the exponent magnitude.
    + If an array of two numbers is assigned then the first number is the negative exponent + value at and beneath which exponential notation is used, and the second number is the + positive exponent value at and above which the same. +
    +
    + For example, to emulate JavaScript numbers in terms of the exponent values at which they + begin to use exponential notation, use [-7, 20]. +
    +
    +
    BigNumber.config({ EXPONENTIAL_AT: 2 })
    +new BigNumber(12.3)         // '12.3'        e is only 1
    +new BigNumber(123)          // '1.23e+2'
    +new BigNumber(0.123)        // '0.123'       e is only -1
    +new BigNumber(0.0123)       // '1.23e-2'
    +
    +BigNumber.config({ EXPONENTIAL_AT: [-7, 20] })
    +new BigNumber(123456789)    // '123456789'   e is only 8
    +new BigNumber(0.000000123)  // '1.23e-7'
    +
    +// Almost never return exponential notation:
    +BigNumber.config({ EXPONENTIAL_AT: 1e+9 })
    +
    +// Always return exponential notation:
    +BigNumber.config({ EXPONENTIAL_AT: 0 })
    +
    +
    + Regardless of the value of EXPONENTIAL_AT, the toFixed method + will always return a value in normal notation and the toExponential method + will always return a value in exponential form. +
    +
    + Calling toString with a base argument, e.g. toString(10), will + also always return normal notation. +
    + + + +
    RANGE
    +
    + number: integer, magnitude 1 to 1e+9 inclusive, or +
    + number[]: [ integer -1e+9 to -1 inclusive, integer + 1 to 1e+9 inclusive ]
    + Default value: [-1e+9, 1e+9] +
    +
    + The exponent value(s) beyond which overflow to Infinity and underflow to + zero occurs. +
    +
    + If a single number is assigned, it is the maximum exponent magnitude: values wth a + positive exponent of greater magnitude become Infinity and those with a + negative exponent of greater magnitude become zero. +
    + If an array of two numbers is assigned then the first number is the negative exponent + limit and the second number is the positive exponent limit. +
    +
    + For example, to emulate JavaScript numbers in terms of the exponent values at which they + become zero and Infinity, use [-324, 308]. +
    +
    +
    BigNumber.config({ RANGE: 500 })
    +BigNumber.config().RANGE     // [ -500, 500 ]
    +new BigNumber('9.999e499')   // '9.999e+499'
    +new BigNumber('1e500')       // 'Infinity'
    +new BigNumber('1e-499')      // '1e-499'
    +new BigNumber('1e-500')      // '0'
    +
    +BigNumber.config({ RANGE: [-3, 4] })
    +new BigNumber(99999)         // '99999'      e is only 4
    +new BigNumber(100000)        // 'Infinity'   e is 5
    +new BigNumber(0.001)         // '0.01'       e is only -3
    +new BigNumber(0.0001)        // '0'          e is -4
    +
    +
    + The largest possible magnitude of a finite BigNumber is + 9.999...e+1000000000.
    + The smallest possible magnitude of a non-zero BigNumber is 1e-1000000000. +
    + + + +
    ERRORS
    +
    + boolean|number: true, false, 0 or + 1.
    + Default value: true +
    +
    + The value that determines whether BigNumber Errors are thrown.
    + If ERRORS is false, no errors will be thrown. +
    +
    See Errors.
    +
    BigNumber.config({ ERRORS: false })
    + + + +
    CRYPTO
    +
    + boolean|number: true, false, 0 or + 1.
    + Default value: false +
    +
    + The value that determines whether cryptographically-secure pseudo-random number + generation is used. +
    +
    + If CRYPTO is set to true then the + random method will generate random digits using + crypto.getRandomValues in browsers that support it, or + crypto.randomBytes if using a version of Node.js that supports it. +
    +
    + If neither function is supported by the host environment then attempting to set + CRYPTO to true will fail, and if ERRORS + is true an exception will be thrown. +
    +
    + If CRYPTO is false then the source of randomness used will be + Math.random (which is assumed to generate at least 30 bits of + randomness). +
    +
    See random.
    +
    +
    BigNumber.config({ CRYPTO: true })
    +BigNumber.config().CRYPTO       // true
    +BigNumber.random()              // 0.54340758610486147524
    +
    + + + +
    MODULO_MODE
    +
    + number: integer, 0 to 9 inclusive
    + Default value: 1 (ROUND_DOWN) +
    +
    The modulo mode used when calculating the modulus: a mod n.
    +
    + The quotient, q = a / n, is calculated according to the + ROUNDING_MODE that corresponds to the chosen + MODULO_MODE. +
    +
    The remainder, r, is calculated as: r = a - n * q.
    +
    + The modes that are most commonly used for the modulus/remainder operation are shown in + the following table. Although the other rounding modes can be used, they may not give + useful results. +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    PropertyValueDescription
    ROUND_UP0 + The remainder is positive if the dividend is negative, otherwise it is negative. +
    ROUND_DOWN1 + The remainder has the same sign as the dividend.
    + This uses 'truncating division' and matches the behaviour of JavaScript's + remainder operator %. +
    ROUND_FLOOR3 + The remainder has the same sign as the divisor.
    + This matches Python's % operator. +
    ROUND_HALF_EVEN6The IEEE 754 remainder function.
    EUCLID9 + The remainder is always positive. Euclidian division:
    + q = sign(n) * floor(a / abs(n)) +
    +
    +
    + The rounding/modulo modes are available as enumerated properties of the BigNumber + constructor. +
    +
    See modulo.
    +
    +
    BigNumber.config({ MODULO_MODE: BigNumber.EUCLID })
    +BigNumber.config({ MODULO_MODE: 9 })          // equivalent
    +
    + + + +
    POW_PRECISION
    +
    + number: integer, 0 to 1e+9 inclusive.
    + Default value: 100 +
    +
    + The maximum number of significant digits of the result of the power operation + (unless a modulus is specified). +
    +
    If set to 0, the number of signifcant digits will not be limited.
    +
    See toPower.
    +
    BigNumber.config({ POW_PRECISION: 100 })
    + + + +
    FORMAT
    +
    object
    +
    + The FORMAT object configures the format of the string returned by the + toFormat method. +
    +
    + The example below shows the properties of the FORMAT object that are + recognised, and their default values. +
    +
    + Unlike the other configuration properties, the values of the properties of the + FORMAT object will not be checked for validity. The existing + FORMAT object will simply be replaced by the object that is passed in. + Note that all the properties shown below do not have to be included. +
    +
    See toFormat for examples of usage.
    +
    +
    +BigNumber.config({
    +    FORMAT: {
    +        // the decimal separator
    +        decimalSeparator: '.',
    +        // the grouping separator of the integer part
    +        groupSeparator: ',',
    +        // the primary grouping size of the integer part
    +        groupSize: 3,
    +        // the secondary grouping size of the integer part
    +        secondaryGroupSize: 0,
    +        // the grouping separator of the fraction part
    +        fractionGroupSeparator: ' ',
    +        // the grouping size of the fraction part
    +        fractionGroupSize: 0
    +    }
    +});
    +
    +
    +
    +

    Returns an object with the above properties and their current values.

    +

    + If the value to be assigned to any of the above properties is null or + undefined it is ignored. +

    +

    See Errors for the treatment of invalid values.

    +
    +BigNumber.config({
    +    DECIMAL_PLACES: 40,
    +    ROUNDING_MODE: BigNumber.ROUND_HALF_CEIL,
    +    EXPONENTIAL_AT: [-10, 20],
    +    RANGE: [-500, 500],
    +    ERRORS: true,
    +    CRYPTO: true,
    +    MODULO_MODE: BigNumber.ROUND_FLOOR,
    +    POW_PRECISION: 80,
    +    FORMAT: {
    +        groupSize: 3,
    +        groupSeparator: ' ',
    +        decimalSeparator: ','
    +    }
    +});
    +
    +// Alternatively but equivalently (excluding FORMAT):
    +BigNumber.config( 40, 7, [-10, 20], 500, 1, 1, 3, 80 )
    +
    +obj = BigNumber.config();
    +obj.ERRORS       // true
    +obj.RANGE        // [-500, 500]
    + + + +
    + max.max([arg1 [, arg2, ...]]) ⇒ BigNumber +
    +

    + arg1, arg2, ...: number|string|BigNumber
    + See BigNumber for further parameter details. +

    +

    + Returns a BigNumber whose value is the maximum of arg1, + arg2,... . +

    +

    The argument to this method can also be an array of values.

    +

    The return value is always exact and unrounded.

    +
    x = new BigNumber('3257869345.0378653')
    +BigNumber.max(4e9, x, '123456789.9')          // '4000000000'
    +
    +arr = [12, '13', new BigNumber(14)]
    +BigNumber.max(arr)                            // '14'
    + + + +
    + min.min([arg1 [, arg2, ...]]) ⇒ BigNumber +
    +

    + arg1, arg2, ...: number|string|BigNumber
    + See BigNumber for further parameter details. +

    +

    + Returns a BigNumber whose value is the minimum of arg1, + arg2,... . +

    +

    The argument to this method can also be an array of values.

    +

    The return value is always exact and unrounded.

    +
    x = new BigNumber('3257869345.0378653')
    +BigNumber.min(4e9, x, '123456789.9')          // '123456789.9'
    +
    +arr = [2, new BigNumber(-14), '-15.9999', -12]
    +BigNumber.min(arr)                            // '-15.9999'
    + + + +
    + random.random([dp]) ⇒ BigNumber +
    +

    dp: number: integer, 0 to 1e+9 inclusive

    +

    + Returns a new BigNumber with a pseudo-random value equal to or greater than 0 and + less than 1. +

    +

    + The return value will have dp decimal places (or less if trailing zeros are + produced).
    + If dp is omitted then the number of decimal places will default to the current + DECIMAL_PLACES setting. +

    +

    + Depending on the value of this BigNumber constructor's + CRYPTO setting and the support for the + crypto object in the host environment, the random digits of the return value are + generated by either Math.random (fastest), crypto.getRandomValues + (Web Cryptography API in recent browsers) or crypto.randomBytes (Node.js). +

    +

    + If CRYPTO is true, i.e. one of the + crypto methods is to be used, the value of a returned BigNumber should be + cryptographically-secure and statistically indistinguishable from a random value. +

    +
    BigNumber.config({ DECIMAL_PLACES: 10 })
    +BigNumber.random()              // '0.4117936847'
    +BigNumber.random(20)            // '0.78193327636914089009'
    + + + +

    Properties

    +

    + The library's enumerated rounding modes are stored as properties of the constructor.
    + (They are not referenced internally by the library itself.) +

    +

    + Rounding modes 0 to 6 (inclusive) are the same as those of Java's + BigDecimal class. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PropertyValueDescription
    ROUND_UP0Rounds away from zero
    ROUND_DOWN1Rounds towards zero
    ROUND_CEIL2Rounds towards Infinity
    ROUND_FLOOR3Rounds towards -Infinity
    ROUND_HALF_UP4 + Rounds towards nearest neighbour.
    + If equidistant, rounds away from zero +
    ROUND_HALF_DOWN5 + Rounds towards nearest neighbour.
    + If equidistant, rounds towards zero +
    ROUND_HALF_EVEN6 + Rounds towards nearest neighbour.
    + If equidistant, rounds towards even neighbour +
    ROUND_HALF_CEIL7 + Rounds towards nearest neighbour.
    + If equidistant, rounds towards Infinity +
    ROUND_HALF_FLOOR8 + Rounds towards nearest neighbour.
    + If equidistant, rounds towards -Infinity +
    +
    +BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_CEIL })
    +BigNumber.config({ ROUNDING_MODE: 2 })     // equivalent
    + + +

    INSTANCE

    + +

    Methods

    +

    The methods inherited by a BigNumber instance from its constructor's prototype object.

    +

    A BigNumber is immutable in the sense that it is not changed by its methods.

    +

    + The treatment of ±0, ±Infinity and NaN is + consistent with how JavaScript treats these values. +

    +

    + Many method names have a shorter alias.
    + (Internally, the library always uses the shorter method names.) +

    + + + +
    absoluteValue.abs() ⇒ BigNumber
    +

    + Returns a BigNumber whose value is the absolute value, i.e. the magnitude, of the value of + this BigNumber. +

    +

    The return value is always exact and unrounded.

    +
    +x = new BigNumber(-0.8)
    +y = x.absoluteValue()           // '0.8'
    +z = y.abs()                     // '0.8'
    + + + +
    ceil.ceil() ⇒ BigNumber
    +

    + Returns a BigNumber whose value is the value of this BigNumber rounded to + a whole number in the direction of positive Infinity. +

    +
    +x = new BigNumber(1.3)
    +x.ceil()                        // '2'
    +y = new BigNumber(-1.8)
    +y.ceil()                        // '-1'
    + + + +
    comparedTo.cmp(n [, base]) ⇒ number
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    + + + + + + + + + + + + + + + + + + +
    Returns 
    1If the value of this BigNumber is greater than the value of n
    -1If the value of this BigNumber is less than the value of n
    0If this BigNumber and n have the same value
    nullIf the value of either this BigNumber or n is NaN
    +
    +x = new BigNumber(Infinity)
    +y = new BigNumber(5)
    +x.comparedTo(y)                 // 1
    +x.comparedTo(x.minus(1))        // 0
    +y.cmp(NaN)                      // null
    +y.cmp('110', 2)                 // -1
    + + + +
    decimalPlaces.dp() ⇒ number
    +

    + Return the number of decimal places of the value of this BigNumber, or null if + the value of this BigNumber is ±Infinity or NaN. +

    +
    +x = new BigNumber(123.45)
    +x.decimalPlaces()               // 2
    +y = new BigNumber('9.9e-101')
    +y.dp()                          // 102
    + + + +
    dividedBy.div(n [, base]) ⇒ BigNumber +
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns a BigNumber whose value is the value of this BigNumber divided by + n, rounded according to the current + DECIMAL_PLACES and + ROUNDING_MODE configuration. +

    +
    +x = new BigNumber(355)
    +y = new BigNumber(113)
    +x.dividedBy(y)                  // '3.14159292035398230088'
    +x.div(5)                        // '71'
    +x.div(47, 16)                   // '5'
    + + + +
    + dividedToIntegerBy.divToInt(n [, base]) ⇒ + BigNumber +
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Return a BigNumber whose value is the integer part of dividing the value of this BigNumber by + n. +

    +
    +x = new BigNumber(5)
    +y = new BigNumber(3)
    +x.dividedToIntegerBy(y)         // '1'
    +x.divToInt(0.7)                 // '7'
    +x.divToInt('0.f', 16)           // '5'
    + + + +
    equals.eq(n [, base]) ⇒ boolean
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns true if the value of this BigNumber equals the value of n, + otherwise returns false.
    + As with JavaScript, NaN does not equal NaN. +

    +

    Note: This method uses the comparedTo method internally.

    +
    +0 === 1e-324                    // true
    +x = new BigNumber(0)
    +x.equals('1e-324')              // false
    +BigNumber(-0).eq(x)             // true  ( -0 === 0 )
    +BigNumber(255).eq('ff', 16)     // true
    +
    +y = new BigNumber(NaN)
    +y.equals(NaN)                   // false
    + + + +
    floor.floor() ⇒ BigNumber
    +

    + Returns a BigNumber whose value is the value of this BigNumber rounded to a whole number in + the direction of negative Infinity. +

    +
    +x = new BigNumber(1.8)
    +x.floor()                       // '1'
    +y = new BigNumber(-1.3)
    +y.floor()                       // '-2'
    + + + +
    greaterThan.gt(n [, base]) ⇒ boolean
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns true if the value of this BigNumber is greater than the value of + n, otherwise returns false. +

    +

    Note: This method uses the comparedTo method internally.

    +
    +0.1 > (0.3 - 0.2)                           // true
    +x = new BigNumber(0.1)
    +x.greaterThan(BigNumber(0.3).minus(0.2))    // false
    +BigNumber(0).gt(x)                          // false
    +BigNumber(11, 3).gt(11.1, 2)                // true
    + + + +
    + greaterThanOrEqualTo.gte(n [, base]) ⇒ boolean +
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns true if the value of this BigNumber is greater than or equal to the value + of n, otherwise returns false. +

    +

    Note: This method uses the comparedTo method internally.

    +
    +(0.3 - 0.2) >= 0.1                   // false
    +x = new BigNumber(0.3).minus(0.2)
    +x.greaterThanOrEqualTo(0.1)          // true
    +BigNumber(1).gte(x)                  // true
    +BigNumber(10, 18).gte('i', 36)       // true
    + + + +
    isFinite.isFinite() ⇒ boolean
    +

    + Returns true if the value of this BigNumber is a finite number, otherwise + returns false. +

    +

    + The only possible non-finite values of a BigNumber are NaN, Infinity + and -Infinity. +

    +
    +x = new BigNumber(1)
    +x.isFinite()                    // true
    +y = new BigNumber(Infinity)
    +y.isFinite()                    // false
    +

    + Note: The native method isFinite() can be used if + n <= Number.MAX_VALUE. +

    + + + +
    isInteger.isInt() ⇒ boolean
    +

    + Returns true if the value of this BigNumber is a whole number, otherwise returns + false. +

    +
    +x = new BigNumber(1)
    +x.isInteger()                   // true
    +y = new BigNumber(123.456)
    +y.isInt()                       // false
    + + + +
    isNaN.isNaN() ⇒ boolean
    +

    + Returns true if the value of this BigNumber is NaN, otherwise + returns false. +

    +
    +x = new BigNumber(NaN)
    +x.isNaN()                       // true
    +y = new BigNumber('Infinity')
    +y.isNaN()                       // false
    +

    Note: The native method isNaN() can also be used.

    + + + +
    isNegative.isNeg() ⇒ boolean
    +

    + Returns true if the value of this BigNumber is negative, otherwise returns + false. +

    +
    +x = new BigNumber(-0)
    +x.isNegative()                  // true
    +y = new BigNumber(2)
    +y.isNeg()                       // false
    +

    Note: n < 0 can be used if n <= -Number.MIN_VALUE.

    + + + +
    isZero.isZero() ⇒ boolean
    +

    + Returns true if the value of this BigNumber is zero or minus zero, otherwise + returns false. +

    +
    +x = new BigNumber(-0)
    +x.isZero() && x.isNeg()         // true
    +y = new BigNumber(Infinity)
    +y.isZero()                      // false
    +

    Note: n == 0 can be used if n >= Number.MIN_VALUE.

    + + + +
    lessThan.lt(n [, base]) ⇒ boolean
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns true if the value of this BigNumber is less than the value of + n, otherwise returns false. +

    +

    Note: This method uses the comparedTo method internally.

    +
    +(0.3 - 0.2) < 0.1                     // true
    +x = new BigNumber(0.3).minus(0.2)
    +x.lessThan(0.1)                       // false
    +BigNumber(0).lt(x)                    // true
    +BigNumber(11.1, 2).lt(11, 3)          // true
    + + + +
    + lessThanOrEqualTo.lte(n [, base]) ⇒ boolean +
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns true if the value of this BigNumber is less than or equal to the value of + n, otherwise returns false. +

    +

    Note: This method uses the comparedTo method internally.

    +
    +0.1 <= (0.3 - 0.2)                                // false
    +x = new BigNumber(0.1)
    +x.lessThanOrEqualTo(BigNumber(0.3).minus(0.2))    // true
    +BigNumber(-1).lte(x)                              // true
    +BigNumber(10, 18).lte('i', 36)                    // true
    + + + +
    + minus.minus(n [, base]) ⇒ BigNumber +
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    Returns a BigNumber whose value is the value of this BigNumber minus n.

    +

    The return value is always exact and unrounded.

    +
    +0.3 - 0.1                       // 0.19999999999999998
    +x = new BigNumber(0.3)
    +x.minus(0.1)                    // '0.2'
    +x.minus(0.6, 20)                // '0'
    + + + +
    modulo.mod(n [, base]) ⇒ BigNumber
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    + Returns a BigNumber whose value is the value of this BigNumber modulo n, i.e. + the integer remainder of dividing this BigNumber by n. +

    +

    + The value returned, and in particular its sign, is dependent on the value of the + MODULO_MODE setting of this BigNumber constructor. + If it is 1 (default value), the result will have the same sign as this BigNumber, + and it will match that of Javascript's % operator (within the limits of double + precision) and BigDecimal's remainder method. +

    +

    The return value is always exact and unrounded.

    +

    + See MODULO_MODE for a description of the other + modulo modes. +

    +
    +1 % 0.9                         // 0.09999999999999998
    +x = new BigNumber(1)
    +x.modulo(0.9)                   // '0.1'
    +y = new BigNumber(33)
    +y.mod('a', 33)                  // '3'
    + + + +
    negated.neg() ⇒ BigNumber
    +

    + Returns a BigNumber whose value is the value of this BigNumber negated, i.e. multiplied by + -1. +

    +
    +x = new BigNumber(1.8)
    +x.negated()                     // '-1.8'
    +y = new BigNumber(-1.3)
    +y.neg()                         // '1.3'
    + + + +
    plus.plus(n [, base]) ⇒ BigNumber
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    Returns a BigNumber whose value is the value of this BigNumber plus n.

    +

    The return value is always exact and unrounded.

    +
    +0.1 + 0.2                       // 0.30000000000000004
    +x = new BigNumber(0.1)
    +y = x.plus(0.2)                 // '0.3'
    +BigNumber(0.7).plus(x).plus(y)  // '1'
    +x.plus('0.1', 8)                // '0.225'
    + + + +
    precision.sd([z]) ⇒ number
    +

    + z: boolean|number: true, false, 0 + or 1 +

    +

    Returns the number of significant digits of the value of this BigNumber.

    +

    + If z is true or 1 then any trailing zeros of the + integer part of a number are counted as significant digits, otherwise they are not. +

    +
    +x = new BigNumber(1.234)
    +x.precision()                   // 4
    +y = new BigNumber(987000)
    +y.sd()                          // 3
    +y.sd(true)                      // 6
    + + + +
    round.round([dp [, rm]]) ⇒ BigNumber
    +

    + dp: number: integer, 0 to 1e+9 inclusive
    + rm: number: integer, 0 to 8 inclusive +

    +

    + Returns a BigNumber whose value is the value of this BigNumber rounded by rounding mode + rm to a maximum of dp decimal places. +

    +

    + if dp is omitted, or is null or undefined, the + return value is n rounded to a whole number.
    + if rm is omitted, or is null or undefined, + ROUNDING_MODE is used. +

    +

    + See Errors for the treatment of other non-integer or out of range + dp or rm values. +

    +
    +x = 1234.56
    +Math.round(x)                             // 1235
    +
    +y = new BigNumber(x)
    +y.round()                                 // '1235'
    +y.round(1)                                // '1234.6'
    +y.round(2)                                // '1234.56'
    +y.round(10)                               // '1234.56'
    +y.round(0, 1)                             // '1234'
    +y.round(0, 6)                             // '1235'
    +y.round(1, 1)                             // '1234.5'
    +y.round(1, BigNumber.ROUND_HALF_EVEN)     // '1234.6'
    +y                                         // '1234.56'
    + + + +
    shift.shift(n) ⇒ BigNumber
    +

    + n: number: integer, + -9007199254740991 to 9007199254740991 inclusive +

    +

    + Returns a BigNumber whose value is the value of this BigNumber shifted n places. +

    + The shift is of the decimal point, i.e. of powers of ten, and is to the left if n + is negative or to the right if n is positive. +

    +

    The return value is always exact and unrounded.

    +
    +x = new BigNumber(1.23)
    +x.shift(3)                      // '1230'
    +x.shift(-3)                     // '0.00123'
    + + + +
    squareRoot.sqrt() ⇒ BigNumber
    +

    + Returns a BigNumber whose value is the square root of the value of this BigNumber, + rounded according to the current + DECIMAL_PLACES and + ROUNDING_MODE configuration. +

    +

    + The return value will be correctly rounded, i.e. rounded as if the result was first calculated + to an infinite number of correct digits before rounding. +

    +
    +x = new BigNumber(16)
    +x.squareRoot()                  // '4'
    +y = new BigNumber(3)
    +y.sqrt()                        // '1.73205080756887729353'
    + + + +
    times.times(n [, base]) ⇒ BigNumber
    +

    + n: number|string|BigNumber
    + base: number
    + See BigNumber for further parameter details. +

    +

    Returns a BigNumber whose value is the value of this BigNumber times n.

    +

    The return value is always exact and unrounded.

    +
    +0.6 * 3                         // 1.7999999999999998
    +x = new BigNumber(0.6)
    +y = x.times(3)                  // '1.8'
    +BigNumber('7e+500').times(y)    // '1.26e+501'
    +x.times('-a', 16)               // '-6'
    + + + +
    + toDigits.toDigits([sd [, rm]]) ⇒ BigNumber +
    +

    + sd: number: integer, 1 to 1e+9 inclusive.
    + rm: number: integer, 0 to 8 inclusive. +

    +

    + Returns a BigNumber whose value is the value of this BigNumber rounded to sd + significant digits using rounding mode rm. +

    +

    + If sd is omitted or is null or undefined, the return + value will not be rounded.
    + If rm is omitted or is null or undefined, + ROUNDING_MODE will be used. +

    +

    + See Errors for the treatment of other non-integer or out of range + sd or rm values. +

    +
    +BigNumber.config({ precision: 5, rounding: 4 })
    +x = new BigNumber(9876.54321)
    +
    +x.toSignificantDigits()                          // '9876.5'
    +x.toSignificantDigits(6)                         // '9876.54'
    +x.toSignificantDigits(6, BigNumber.ROUND_UP)     // '9876.55'
    +x.toSD(2)                                        // '9900'
    +x.toSD(2, 1)                                     // '9800'
    +x                                                // '9876.54321'
    + + + +
    + toExponential.toExponential([dp [, rm]]) ⇒ string +
    +

    + dp: number: integer, 0 to 1e+9 inclusive
    + rm: number: integer, 0 to 8 inclusive +

    +

    + Returns a string representing the value of this BigNumber in exponential notation rounded + using rounding mode rm to dp decimal places, i.e with one digit + before the decimal point and dp digits after it. +

    +

    + If the value of this BigNumber in exponential notation has fewer than dp fraction + digits, the return value will be appended with zeros accordingly. +

    +

    + If dp is omitted, or is null or undefined, the number + of digits after the decimal point defaults to the minimum number of digits necessary to + represent the value exactly.
    + If rm is omitted or is null or undefined, + ROUNDING_MODE is used. +

    +

    + See Errors for the treatment of other non-integer or out of range + dp or rm values. +

    +
    +x = 45.6
    +y = new BigNumber(x)
    +x.toExponential()               // '4.56e+1'
    +y.toExponential()               // '4.56e+1'
    +x.toExponential(0)              // '5e+1'
    +y.toExponential(0)              // '5e+1'
    +x.toExponential(1)              // '4.6e+1'
    +y.toExponential(1)              // '4.6e+1'
    +y.toExponential(1, 1)           // '4.5e+1'  (ROUND_DOWN)
    +x.toExponential(3)              // '4.560e+1'
    +y.toExponential(3)              // '4.560e+1'
    + + + +
    + toFixed.toFixed([dp [, rm]]) ⇒ string +
    +

    + dp: number: integer, 0 to 1e+9 inclusive
    + rm: number: integer, 0 to 8 inclusive +

    +

    + Returns a string representing the value of this BigNumber in normal (fixed-point) notation + rounded to dp decimal places using rounding mode rm. +

    +

    + If the value of this BigNumber in normal notation has fewer than dp fraction + digits, the return value will be appended with zeros accordingly. +

    +

    + Unlike Number.prototype.toFixed, which returns exponential notation if a number + is greater or equal to 1021, this method will always return normal + notation. +

    +

    + If dp is omitted or is null or undefined, the return + value will be unrounded and in normal notation. This is also unlike + Number.prototype.toFixed, which returns the value to zero decimal places.
    + It is useful when fixed-point notation is required and the current + EXPONENTIAL_AT setting causes + toString to return exponential notation.
    + If rm is omitted or is null or undefined, + ROUNDING_MODE is used. +

    +

    + See Errors for the treatment of other non-integer or out of range + dp or rm values. +

    +
    +x = 3.456
    +y = new BigNumber(x)
    +x.toFixed()                     // '3'
    +y.toFixed()                     // '3.456'
    +y.toFixed(0)                    // '3'
    +x.toFixed(2)                    // '3.46'
    +y.toFixed(2)                    // '3.46'
    +y.toFixed(2, 1)                 // '3.45'  (ROUND_DOWN)
    +x.toFixed(5)                    // '3.45600'
    +y.toFixed(5)                    // '3.45600'
    + + + +
    + toFormat.toFormat([dp [, rm]]) ⇒ string +
    +

    + dp: number: integer, 0 to 1e+9 inclusive
    + rm: number: integer, 0 to 8 inclusive +

    +

    +

    + Returns a string representing the value of this BigNumber in normal (fixed-point) notation + rounded to dp decimal places using rounding mode rm, and formatted + according to the properties of the FORMAT object. +

    +

    + See the examples below for the properties of the + FORMAT object, their types and their usage. +

    +

    + If dp is omitted or is null or undefined, then the + return value is not rounded to a fixed number of decimal places.
    + If rm is omitted or is null or undefined, + ROUNDING_MODE is used. +

    +

    + See Errors for the treatment of other non-integer or out of range + dp or rm values. +

    +
    +format = {
    +    decimalSeparator: '.',
    +    groupSeparator: ',',
    +    groupSize: 3,
    +    secondaryGroupSize: 0,
    +    fractionGroupSeparator: ' ',
    +    fractionGroupSize: 0
    +}
    +BigNumber.config({ FORMAT: format })
    +
    +x = new BigNumber('123456789.123456789')
    +x.toFormat()                    // '123,456,789.123456789'
    +x.toFormat(1)                   // '123,456,789.1'
    +
    +// If a reference to the object assigned to FORMAT has been retained,
    +// the format properties can be changed directly
    +format.groupSeparator = ' '
    +format.fractionGroupSize = 5
    +x.toFormat()                    // '123 456 789.12345 6789'
    +
    +BigNumber.config({
    +    FORMAT: {
    +        decimalSeparator = ',',
    +        groupSeparator = '.',
    +        groupSize = 3,
    +        secondaryGroupSize = 2
    +    }
    +})
    +
    +x.toFormat(6)                   // '12.34.56.789,123'
    + + + +
    + toFraction.toFraction([max]) ⇒ [string, string] +
    +

    + max: number|string|BigNumber: integer >= 1 and < + Infinity +

    +

    + Returns a string array representing the value of this BigNumber as a simple fraction with an + integer numerator and an integer denominator. The denominator will be a positive non-zero + value less than or equal to max. +

    +

    + If a maximum denominator, max, is not specified, or is null or + undefined, the denominator will be the lowest value necessary to represent the + number exactly. +

    +

    + See Errors for the treatment of other non-integer or out of range + max values. +

    +
    +x = new BigNumber(1.75)
    +x.toFraction()                  // '7, 4'
    +
    +pi = new BigNumber('3.14159265358')
    +pi.toFraction()                 // '157079632679,50000000000'
    +pi.toFraction(100000)           // '312689, 99532'
    +pi.toFraction(10000)            // '355, 113'
    +pi.toFraction(100)              // '311, 99'
    +pi.toFraction(10)               // '22, 7'
    +pi.toFraction(1)                // '3, 1'
    + + + +
    toJSON.toJSON() ⇒ string
    +

    As valueOf.

    +
    +x = new BigNumber('177.7e+457')
    +y = new BigNumber(235.4325)
    +z = new BigNumber('0.0098074')
    +
    +// Serialize an array of three BigNumbers
    +str = JSON.stringify( [x, y, z] )
    +// "["1.777e+459","235.4325","0.0098074"]"
    +
    +// Return an array of three BigNumbers
    +JSON.parse(str, function (key, val) {
    +    return key === '' ? val : new BigNumber(val)
    +})
    + + + +
    toNumber.toNumber() ⇒ number
    +

    Returns the value of this BigNumber as a JavaScript number primitive.

    +

    + Type coercion with, for example, the unary plus operator will also work, except that a + BigNumber with the value minus zero will be converted to positive zero. +

    +
    +x = new BigNumber(456.789)
    +x.toNumber()                    // 456.789
    ++x                              // 456.789
    +
    +y = new BigNumber('45987349857634085409857349856430985')
    +y.toNumber()                    // 4.598734985763409e+34
    +
    +z = new BigNumber(-0)
    +1 / +z                          // Infinity
    +1 / z.toNumber()                // -Infinity
    + + + +
    toPower.pow(n [, m]) ⇒ BigNumber
    +

    + n: number: integer, + -9007199254740991 to 9007199254740991 inclusive
    + m: number|string|BigNumber +

    +

    + Returns a BigNumber whose value is the value of this BigNumber raised to the power + n, and optionally modulo a modulus m. +

    +

    + If n is negative the result is rounded according to the current + DECIMAL_PLACES and + ROUNDING_MODE configuration. +

    +

    + If n is not an integer or is out of range: +

    +

    + If ERRORS is true a BigNumber Error is thrown,
    + else if n is greater than 9007199254740991, it is interpreted as + Infinity;
    + else if n is less than -9007199254740991, it is interpreted as + -Infinity;
    + else if n is otherwise a number, it is truncated to an integer;
    + else it is interpreted as NaN. +

    +

    + As the number of digits of the result of the power operation can grow so large so quickly, + e.g. 123.45610000 has over 50000 digits, the number of significant + digits calculated is limited to the value of the + POW_PRECISION setting (default value: + 100) unless a modulus m is specified. +

    +

    + Set POW_PRECISION to 0 for an + unlimited number of significant digits to be calculated (this will cause the method to slow + dramatically for larger exponents). +

    +

    + Negative exponents will be calculated to the number of decimal places specified by + DECIMAL_PLACES (but not to more than + POW_PRECISION significant digits). +

    +

    + If m is specified and the value of m, n and this + BigNumber are positive integers, then a fast modular exponentiation algorithm is used, + otherwise if any of the values is not a positive integer the operation will simply be + performed as x.toPower(n).modulo(m) with a + POW_PRECISION of 0. +

    +
    +Math.pow(0.7, 2)                // 0.48999999999999994
    +x = new BigNumber(0.7)
    +x.toPower(2)                    // '0.49'
    +BigNumber(3).pow(-2)            // '0.11111111111111111111'
    + + + +
    + toPrecision.toPrecision([sd [, rm]]) ⇒ string +
    +

    + sd: number: integer, 1 to 1e+9 inclusive
    + rm: number: integer, 0 to 8 inclusive +

    +

    + Returns a string representing the value of this BigNumber rounded to sd + significant digits using rounding mode rm. +

    +

    + If sd is less than the number of digits necessary to represent the integer part + of the value in normal (fixed-point) notation, then exponential notation is used. +

    +

    + If sd is omitted, or is null or undefined, then the + return value is the same as n.toString().
    + If rm is omitted or is null or undefined, + ROUNDING_MODE is used. +

    +

    + See Errors for the treatment of other non-integer or out of range + sd or rm values. +

    +
    +x = 45.6
    +y = new BigNumber(x)
    +x.toPrecision()                 // '45.6'
    +y.toPrecision()                 // '45.6'
    +x.toPrecision(1)                // '5e+1'
    +y.toPrecision(1)                // '5e+1'
    +y.toPrecision(2, 0)             // '4.6e+1'  (ROUND_UP)
    +y.toPrecision(2, 1)             // '4.5e+1'  (ROUND_DOWN)
    +x.toPrecision(5)                // '45.600'
    +y.toPrecision(5)                // '45.600'
    + + + +
    toString.toString([base]) ⇒ string
    +

    base: number: integer, 2 to 64 inclusive

    +

    + Returns a string representing the value of this BigNumber in the specified base, or base + 10 if base is omitted or is null or + undefined. +

    +

    + For bases above 10, values from 10 to 35 are + represented by a-z (as with Number.prototype.toString), + 36 to 61 by A-Z, and 62 and + 63 by $ and _ respectively. +

    +

    + If a base is specified the value is rounded according to the current + DECIMAL_PLACES + and ROUNDING_MODE configuration. +

    +

    + If a base is not specified, and this BigNumber has a positive + exponent that is equal to or greater than the positive component of the + current EXPONENTIAL_AT setting, + or a negative exponent equal to or less than the negative component of the + setting, then exponential notation is returned. +

    +

    If base is null or undefined it is ignored.

    +

    + See Errors for the treatment of other non-integer or out of range + base values. +

    +
    +x = new BigNumber(750000)
    +x.toString()                    // '750000'
    +BigNumber.config({ EXPONENTIAL_AT: 5 })
    +x.toString()                    // '7.5e+5'
    +
    +y = new BigNumber(362.875)
    +y.toString(2)                   // '101101010.111'
    +y.toString(9)                   // '442.77777777777777777778'
    +y.toString(32)                  // 'ba.s'
    +
    +BigNumber.config({ DECIMAL_PLACES: 4 });
    +z = new BigNumber('1.23456789')
    +z.toString()                    // '1.23456789'
    +z.toString(10)                  // '1.2346'
    + + + +
    truncated.trunc() ⇒ BigNumber
    +

    + Returns a BigNumber whose value is the value of this BigNumber truncated to a whole number. +

    +
    +x = new BigNumber(123.456)
    +x.truncated()                   // '123'
    +y = new BigNumber(-12.3)
    +y.trunc()                       // '-12'
    + + + +
    valueOf.valueOf() ⇒ string
    +

    + As toString, but does not accept a base argument and includes the minus sign + for negative zero. +

    +
    +x = new BigNumber('-0')
    +x.toString()                    // '0'
    +x.valueOf()                     // '-0'
    +y = new BigNumber('1.777e+457')
    +y.valueOf()                     // '1.777e+457'
    + + + +

    Properties

    +

    A BigNumber is an object with three properties:

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    PropertyDescriptionTypeValue
    ccoefficient*number[] Array of base 1e14 numbers
    eexponentnumberInteger, -1000000000 to 1000000000 inclusive
    ssignnumber-1 or 1
    +

    *significand

    +

    The value of any of the three properties may also be null.

    +

    + From v2.0.0 of this library, the value of the coefficient of a BigNumber is stored in a + normalised base 100000000000000 floating point format, as opposed to the base + 10 format used in v1.x.x +

    +

    + This change means the properties of a BigNumber are now best considered to be read-only. + Previously it was acceptable to change the exponent of a BigNumber by writing to its exponent + property directly, but this is no longer recommended as the number of digits in the first + element of the coefficient array is dependent on the exponent, so the coefficient would also + need to be altered. +

    +

    + Note that, as with JavaScript numbers, the original exponent and fractional trailing zeros are + not necessarily preserved. +

    +
    x = new BigNumber(0.123)              // '0.123'
    +x.toExponential()                     // '1.23e-1'
    +x.c                                   // '1,2,3'
    +x.e                                   // -1
    +x.s                                   // 1
    +
    +y = new Number(-123.4567000e+2)       // '-12345.67'
    +y.toExponential()                     // '-1.234567e+4'
    +z = new BigNumber('-123.4567000e+2')  // '-12345.67'
    +z.toExponential()                     // '-1.234567e+4'
    +z.c                                   // '1,2,3,4,5,6,7'
    +z.e                                   // 4
    +z.s                                   // -1
    + + + +

    Zero, NaN and Infinity

    +

    + The table below shows how ±0, NaN and + ±Infinity are stored. +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ces
    ±0[0]0±1
    NaNnullnullnull
    ±Infinitynullnull±1
    +
    +x = new Number(-0)              // 0
    +1 / x == -Infinity              // true
    +
    +y = new BigNumber(-0)           // '0'
    +y.c                             // '0' ( [0].toString() )
    +y.e                             // 0
    +y.s                             // -1
    + + + +

    Errors

    +

    + The errors that are thrown are generic Error objects with name + BigNumber Error. +

    +

    + The table below shows the errors that may be thrown if ERRORS is + true, and the action taken if ERRORS is false. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method(s)ERRORS: true
    Throw BigNumber Error
    ERRORS: false
    Action on invalid argument
    + + BigNumber
    + comparedTo
    + dividedBy
    + dividedToIntegerBy
    + equals
    + greaterThan
    + greaterThanOrEqualTo
    + lessThan
    + lessThanOrEqualTo
    + minus
    + modulo
    + plus
    + times +
    number type has more than
    15 significant digits
    Accept.
    not a base... numberSubstitute NaN.
    base not an integerTruncate to integer.
    Ignore if not a number.
    base out of rangeIgnore.
    not a number*Substitute NaN.
    anothernot an objectIgnore.
    configDECIMAL_PLACES not an integerTruncate to integer.
    Ignore if not a number.
    DECIMAL_PLACES out of rangeIgnore.
    ROUNDING_MODE not an integerTruncate to integer.
    Ignore if not a number.
    ROUNDING_MODE out of rangeIgnore.
    EXPONENTIAL_AT not an integer
    or not [integer, integer]
    Truncate to integer(s).
    Ignore if not number(s).
    EXPONENTIAL_AT out of range
    or not [negative, positive]
    Ignore.
    RANGE not an integer
    or not [integer, integer]
    Truncate to integer(s).
    Ignore if not number(s).
    RANGE cannot be zeroIgnore.
    RANGE out of range
    or not [negative, positive]
    Ignore.
    ERRORS not a boolean
    or binary digit
    Ignore.
    CRYPTO not a boolean
    or binary digit
    Ignore.
    CRYPTO crypto unavailableIgnore.
    MODULO_MODE not an integerTruncate to integer.
    Ignore if not a number.
    MODULO_MODE out of rangeIgnore.
    POW_PRECISION not an integerTruncate to integer.
    Ignore if not a number.
    POW_PRECISION out of rangeIgnore.
    FORMAT not an objectIgnore.
    precisionargument not a boolean
    or binary digit
    Ignore.
    rounddecimal places not an integerTruncate to integer.
    Ignore if not a number.
    decimal places out of rangeIgnore.
    rounding mode not an integerTruncate to integer.
    Ignore if not a number.
    rounding mode out of rangeIgnore.
    shiftargument not an integerTruncate to integer.
    Ignore if not a number.
    argument out of rangeSubstitute ±Infinity. +
    + toExponential
    + toFixed
    + toFormat +
    decimal places not an integerTruncate to integer.
    Ignore if not a number.
    decimal places out of rangeIgnore.
    rounding mode not an integerTruncate to integer.
    Ignore if not a number.
    rounding mode out of rangeIgnore.
    toFractionmax denominator not an integerTruncate to integer.
    Ignore if not a number.
    max denominator out of rangeIgnore.
    + toDigits
    + toPrecision +
    precision not an integerTruncate to integer.
    Ignore if not a number.
    precision out of rangeIgnore.
    rounding mode not an integerTruncate to integer.
    Ignore if not a number.
    rounding mode out of rangeIgnore.
    toPowerexponent not an integerTruncate to integer.
    Substitute NaN if not a number.
    exponent out of rangeSubstitute ±Infinity. +
    toStringbase not an integerTruncate to integer.
    Ignore if not a number.
    base out of rangeIgnore.
    +

    *No error is thrown if the value is NaN or 'NaN'.

    +

    + The message of a BigNumber Error will also contain the name of the method from which + the error originated. +

    +

    To determine if an exception is a BigNumber Error:

    +
    +try {
    +    // ...
    +} catch (e) {
    +    if ( e instanceof Error && e.name == 'BigNumber Error' ) {
    +        // ...
    +    }
    +}
    + + + +

    FAQ

    + +
    Why are trailing fractional zeros removed from BigNumbers?
    +

    + Some arbitrary-precision libraries retain trailing fractional zeros as they can indicate the + precision of a value. This can be useful but the results of arithmetic operations can be + misleading. +

    +
    +x = new BigDecimal("1.0")
    +y = new BigDecimal("1.1000")
    +z = x.add(y)                      // 2.1000
    +
    +x = new BigDecimal("1.20")
    +y = new BigDecimal("3.45000")
    +z = x.multiply(y)                 // 4.1400000
    +

    + To specify the precision of a value is to specify that the value lies + within a certain range. +

    +

    + In the first example, x has a value of 1.0. The trailing zero shows + the precision of the value, implying that it is in the range 0.95 to + 1.05. Similarly, the precision indicated by the trailing zeros of y + indicates that the value is in the range 1.09995 to 1.10005. +

    +

    + If we add the two lowest values in the ranges we have, 0.95 + 1.09995 = 2.04995, + and if we add the two highest values we have, 1.05 + 1.10005 = 2.15005, so the + range of the result of the addition implied by the precision of its operands is + 2.04995 to 2.15005. +

    +

    + The result given by BigDecimal of 2.1000 however, indicates that the value is in + the range 2.09995 to 2.10005 and therefore the precision implied by + its trailing zeros may be misleading. +

    +

    + In the second example, the true range is 4.122744 to 4.157256 yet + the BigDecimal answer of 4.1400000 indicates a range of 4.13999995 + to 4.14000005. Again, the precision implied by the trailing zeros may be + misleading. +

    +

    + This library, like binary floating point and most calculators, does not retain trailing + fractional zeros. Instead, the toExponential, toFixed and + toPrecision methods enable trailing zeros to be added if and when required.
    +

    +
    + + + diff --git a/node_modules/bignumber.js/package.json b/node_modules/bignumber.js/package.json new file mode 100644 index 0000000..013bda1 --- /dev/null +++ b/node_modules/bignumber.js/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "bignumber.js@2.3.0", + "scope": null, + "escapedName": "bignumber.js", + "name": "bignumber.js", + "rawSpec": "2.3.0", + "spec": "2.3.0", + "type": "version" + }, + "/mnt/c/Users/const/IdeaProjects/space-game/node_modules/mysql" + ] + ], + "_from": "bignumber.js@2.3.0", + "_id": "bignumber.js@2.3.0", + "_inCache": true, + "_installable": true, + "_location": "/bignumber.js", + "_nodeVersion": "5.7.0", + "_npmOperationalInternal": { + "host": "packages-13-west.internal.npmjs.com", + "tmp": "tmp/bignumber.js-2.3.0.tgz_1457392338289_0.9482216306496412" + }, + "_npmUser": { + "name": "mikemcl", + "email": "M8ch88l@gmail.com" + }, + "_npmVersion": "3.7.1", + "_phantomChildren": {}, + "_requested": { + "raw": "bignumber.js@2.3.0", + "scope": null, + "escapedName": "bignumber.js", + "name": "bignumber.js", + "rawSpec": "2.3.0", + "spec": "2.3.0", + "type": "version" + }, + "_requiredBy": [ + "/mysql" + ], + "_resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.3.0.tgz", + "_shasum": "597a02d791edc3d64f17850e21789e7a4095df66", + "_shrinkwrap": null, + "_spec": "bignumber.js@2.3.0", + "_where": "/mnt/c/Users/const/IdeaProjects/space-game/node_modules/mysql", + "author": { + "name": "Michael Mclaughlin", + "email": "M8ch88l@gmail.com" + }, + "bugs": { + "url": "https://github.com/MikeMcl/bignumber.js/issues" + }, + "dependencies": {}, + "description": "A library for arbitrary-precision decimal and non-decimal arithmetic", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "597a02d791edc3d64f17850e21789e7a4095df66", + "tarball": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.3.0.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "65e21f202adab641efda0d43b85a605791c0816a", + "homepage": "https://github.com/MikeMcl/bignumber.js#readme", + "keywords": [ + "arbitrary", + "precision", + "arithmetic", + "big", + "number", + "decimal", + "float", + "biginteger", + "bigdecimal", + "bignumber", + "bigint", + "bignum" + ], + "license": "MIT", + "main": "bignumber", + "maintainers": [ + { + "name": "mikemcl", + "email": "M8ch88l@gmail.com" + } + ], + "name": "bignumber.js", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/MikeMcl/bignumber.js.git" + }, + "scripts": { + "build": "uglifyjs bignumber.js --source-map bignumber.js.map -c -m -o bignumber.min.js --preamble \"/* bignumber.js v2.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */\"", + "test": "node ./test/every-test.js" + }, + "version": "2.3.0" +} diff --git a/node_modules/blob/.npmignore b/node_modules/blob/.npmignore new file mode 100644 index 0000000..548a368 --- /dev/null +++ b/node_modules/blob/.npmignore @@ -0,0 +1,2 @@ +node_modules +blob.js diff --git a/node_modules/blob/.zuul.yml b/node_modules/blob/.zuul.yml new file mode 100644 index 0000000..380c395 --- /dev/null +++ b/node_modules/blob/.zuul.yml @@ -0,0 +1,14 @@ +ui: mocha-bdd +browsers: + - name: chrome + version: 8..latest + - name: firefox + version: 7..latest + - name: safari + version: 6..latest + - name: opera + version: 12.1..latest + - name: ie + version: 10..latest + - name: android + version: latest diff --git a/node_modules/blob/Makefile b/node_modules/blob/Makefile new file mode 100644 index 0000000..7d9601a --- /dev/null +++ b/node_modules/blob/Makefile @@ -0,0 +1,14 @@ +REPORTER = dot + +build: blob.js + +blob.js: + @./node_modules/.bin/browserify --standalone blob index.js > blob.js + +test: + @./node_modules/.bin/zuul -- test/index.js + +clean: + rm blob.js + +.PHONY: test blob.js diff --git a/node_modules/blob/README.md b/node_modules/blob/README.md new file mode 100644 index 0000000..6915955 --- /dev/null +++ b/node_modules/blob/README.md @@ -0,0 +1,14 @@ +Blob +==== + +A module that exports a constructor that uses window.Blob when available, and a BlobBuilder with any vendor prefix in other cases. If neither is available, it exports undefined. + +Usage: + +```javascript +var Blob = require('blob'); +var b = new Blob(['hi', 'constructing', 'a', 'blob']); +``` + +## Licence +MIT diff --git a/node_modules/blob/index.js b/node_modules/blob/index.js new file mode 100644 index 0000000..cad3f84 --- /dev/null +++ b/node_modules/blob/index.js @@ -0,0 +1,96 @@ +/** + * Create a blob builder even when vendor prefixes exist + */ + +var BlobBuilder = global.BlobBuilder + || global.WebKitBlobBuilder + || global.MSBlobBuilder + || global.MozBlobBuilder; + +/** + * Check if Blob constructor is supported + */ + +var blobSupported = (function() { + try { + var a = new Blob(['hi']); + return a.size === 2; + } catch(e) { + return false; + } +})(); + +/** + * Check if Blob constructor supports ArrayBufferViews + * Fails in Safari 6, so we need to map to ArrayBuffers there. + */ + +var blobSupportsArrayBufferView = blobSupported && (function() { + try { + var b = new Blob([new Uint8Array([1,2])]); + return b.size === 2; + } catch(e) { + return false; + } +})(); + +/** + * Check if BlobBuilder is supported + */ + +var blobBuilderSupported = BlobBuilder + && BlobBuilder.prototype.append + && BlobBuilder.prototype.getBlob; + +/** + * Helper function that maps ArrayBufferViews to ArrayBuffers + * Used by BlobBuilder constructor and old browsers that didn't + * support it in the Blob constructor. + */ + +function mapArrayBufferViews(ary) { + for (var i = 0; i < ary.length; i++) { + var chunk = ary[i]; + if (chunk.buffer instanceof ArrayBuffer) { + var buf = chunk.buffer; + + // if this is a subarray, make a copy so we only + // include the subarray region from the underlying buffer + if (chunk.byteLength !== buf.byteLength) { + var copy = new Uint8Array(chunk.byteLength); + copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); + buf = copy.buffer; + } + + ary[i] = buf; + } + } +} + +function BlobBuilderConstructor(ary, options) { + options = options || {}; + + var bb = new BlobBuilder(); + mapArrayBufferViews(ary); + + for (var i = 0; i < ary.length; i++) { + bb.append(ary[i]); + } + + return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); +}; + +function BlobConstructor(ary, options) { + mapArrayBufferViews(ary); + return new Blob(ary, options || {}); +}; + +module.exports = (function() { + if (blobSupported) { + return blobSupportsArrayBufferView ? global.Blob : BlobConstructor; + } else if (blobBuilderSupported) { + return BlobBuilderConstructor; + } else { + return undefined; + } +})(); diff --git a/node_modules/blob/package.json b/node_modules/blob/package.json new file mode 100644 index 0000000..dc724ee --- /dev/null +++ b/node_modules/blob/package.json @@ -0,0 +1,78 @@ +{ + "_args": [ + [ + { + "raw": "blob@0.0.4", + "scope": null, + "escapedName": "blob", + "name": "blob", + "rawSpec": "0.0.4", + "spec": "0.0.4", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser" + ] + ], + "_from": "blob@0.0.4", + "_id": "blob@0.0.4", + "_inCache": true, + "_installable": true, + "_location": "/blob", + "_npmUser": { + "name": "rase-", + "email": "tonykovanen@hotmail.com" + }, + "_npmVersion": "1.4.6", + "_phantomChildren": {}, + "_requested": { + "raw": "blob@0.0.4", + "scope": null, + "escapedName": "blob", + "name": "blob", + "rawSpec": "0.0.4", + "spec": "0.0.4", + "type": "version" + }, + "_requiredBy": [ + "/engine.io-parser" + ], + "_resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "_shasum": "bcf13052ca54463f30f9fc7e95b9a47630a94921", + "_shrinkwrap": null, + "_spec": "blob@0.0.4", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-parser", + "bugs": { + "url": "https://github.com/rase-/blob/issues" + }, + "dependencies": {}, + "description": "Abstracts out Blob and uses BlobBulder in cases where it is supported with any vendor prefix.", + "devDependencies": { + "browserify": "3.30.1", + "expect.js": "0.2.0", + "mocha": "1.17.1", + "zuul": "1.5.4" + }, + "directories": {}, + "dist": { + "shasum": "bcf13052ca54463f30f9fc7e95b9a47630a94921", + "tarball": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz" + }, + "homepage": "https://github.com/rase-/blob", + "maintainers": [ + { + "name": "rase-", + "email": "tonykovanen@hotmail.com" + } + ], + "name": "blob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/rase-/blob.git" + }, + "scripts": { + "test": "make test" + }, + "version": "0.0.4" +} diff --git a/node_modules/blob/test/index.js b/node_modules/blob/test/index.js new file mode 100644 index 0000000..df9303f --- /dev/null +++ b/node_modules/blob/test/index.js @@ -0,0 +1,94 @@ +var Blob = require('../'); +var expect = require('expect.js'); + +describe('blob', function() { + if (!Blob) { + it('should not have a blob or a blob builder in the global namespace, or blob should not be a constructor function if the module exports false', function() { + try { + var ab = (new Uint8Array(5)).buffer; + global.Blob([ab]); + expect().fail('Blob shouldn\'t be constructable'); + } catch (e) {} + + var BlobBuilder = global.BlobBuilder + || global.WebKitBlobBuilder + || global.MSBlobBuilder + || global.MozBlobBuilder; + expect(BlobBuilder).to.be(undefined); + }); + } else { + it('should encode a proper sized blob when given a string argument', function() { + var b = new Blob(['hi']); + expect(b.size).to.be(2); + }); + + it('should encode a blob with proper size when given two strings as arguments', function() { + var b = new Blob(['hi', 'hello']); + expect(b.size).to.be(7); + }); + + it('should encode arraybuffers with right content', function(done) { + var ary = new Uint8Array(5); + for (var i = 0; i < 5; i++) ary[i] = i; + var b = new Blob([ary.buffer]); + var fr = new FileReader(); + fr.onload = function() { + var newAry = new Uint8Array(this.result); + for (var i = 0; i < 5; i++) expect(newAry[i]).to.be(i); + done(); + }; + fr.readAsArrayBuffer(b); + }); + + it('should encode typed arrays with right content', function(done) { + var ary = new Uint8Array(5); + for (var i = 0; i < 5; i++) ary[i] = i; + var b = new Blob([ary]); + var fr = new FileReader(); + fr.onload = function() { + var newAry = new Uint8Array(this.result); + for (var i = 0; i < 5; i++) expect(newAry[i]).to.be(i); + done(); + }; + fr.readAsArrayBuffer(b); + }); + + it('should encode sliced typed arrays with right content', function(done) { + var ary = new Uint8Array(5); + for (var i = 0; i < 5; i++) ary[i] = i; + var b = new Blob([ary.subarray(2)]); + var fr = new FileReader(); + fr.onload = function() { + var newAry = new Uint8Array(this.result); + for (var i = 0; i < 3; i++) expect(newAry[i]).to.be(i + 2); + done(); + }; + fr.readAsArrayBuffer(b); + }); + + it('should encode with blobs', function(done) { + var ary = new Uint8Array(5); + for (var i = 0; i < 5; i++) ary[i] = i; + var b = new Blob([new Blob([ary.buffer])]); + var fr = new FileReader(); + fr.onload = function() { + var newAry = new Uint8Array(this.result); + for (var i = 0; i < 5; i++) expect(newAry[i]).to.be(i); + done(); + }; + fr.readAsArrayBuffer(b); + }); + + it('should enode mixed contents to right size', function() { + var ary = new Uint8Array(5); + for (var i = 0; i < 5; i++) ary[i] = i; + var b = new Blob([ary.buffer, 'hello']); + expect(b.size).to.be(10); + }); + + it('should accept mime type', function() { + var b = new Blob(['hi', 'hello'], { type: 'text/html' }); + expect(b.type).to.be('text/html'); + }); + } +}); diff --git a/node_modules/body-parser/HISTORY.md b/node_modules/body-parser/HISTORY.md new file mode 100644 index 0000000..f3ea28c --- /dev/null +++ b/node_modules/body-parser/HISTORY.md @@ -0,0 +1,464 @@ +1.15.2 / 2016-06-19 +=================== + + * deps: bytes@2.4.0 + * deps: content-type@~1.0.2 + - perf: enable strict mode + * deps: http-errors@~1.5.0 + - Use `setprototypeof` module to replace `__proto__` setting + - deps: statuses@'>= 1.3.0 < 2' + - perf: enable strict mode + * deps: qs@6.2.0 + * deps: raw-body@~2.1.7 + - deps: bytes@2.4.0 + - perf: remove double-cleanup on happy path + * deps: type-is@~1.6.13 + - deps: mime-types@~2.1.11 + +1.15.1 / 2016-05-05 +=================== + + * deps: bytes@2.3.0 + - Drop partial bytes on all parsed units + - Fix parsing byte string that looks like hex + * deps: raw-body@~2.1.6 + - deps: bytes@2.3.0 + * deps: type-is@~1.6.12 + - deps: mime-types@~2.1.10 + +1.15.0 / 2016-02-10 +=================== + + * deps: http-errors@~1.4.0 + - Add `HttpError` export, for `err instanceof createError.HttpError` + - deps: inherits@2.0.1 + - deps: statuses@'>= 1.2.1 < 2' + * deps: qs@6.1.0 + * deps: type-is@~1.6.11 + - deps: mime-types@~2.1.9 + +1.14.2 / 2015-12-16 +=================== + + * deps: bytes@2.2.0 + * deps: iconv-lite@0.4.13 + * deps: qs@5.2.0 + * deps: raw-body@~2.1.5 + - deps: bytes@2.2.0 + - deps: iconv-lite@0.4.13 + * deps: type-is@~1.6.10 + - deps: mime-types@~2.1.8 + +1.14.1 / 2015-09-27 +=================== + + * Fix issue where invalid charset results in 400 when `verify` used + * deps: iconv-lite@0.4.12 + - Fix CESU-8 decoding in Node.js 4.x + * deps: raw-body@~2.1.4 + - Fix masking critical errors from `iconv-lite` + - deps: iconv-lite@0.4.12 + * deps: type-is@~1.6.9 + - deps: mime-types@~2.1.7 + +1.14.0 / 2015-09-16 +=================== + + * Fix JSON strict parse error to match syntax errors + * Provide static `require` analysis in `urlencoded` parser + * deps: depd@~1.1.0 + - Support web browser loading + * deps: qs@5.1.0 + * deps: raw-body@~2.1.3 + - Fix sync callback when attaching data listener causes sync read + * deps: type-is@~1.6.8 + - Fix type error when given invalid type to match against + - deps: mime-types@~2.1.6 + +1.13.3 / 2015-07-31 +=================== + + * deps: type-is@~1.6.6 + - deps: mime-types@~2.1.4 + +1.13.2 / 2015-07-05 +=================== + + * deps: iconv-lite@0.4.11 + * deps: qs@4.0.0 + - Fix dropping parameters like `hasOwnProperty` + - Fix user-visible incompatibilities from 3.1.0 + - Fix various parsing edge cases + * deps: raw-body@~2.1.2 + - Fix error stack traces to skip `makeError` + - deps: iconv-lite@0.4.11 + * deps: type-is@~1.6.4 + - deps: mime-types@~2.1.2 + - perf: enable strict mode + - perf: remove argument reassignment + +1.13.1 / 2015-06-16 +=================== + + * deps: qs@2.4.2 + - Downgraded from 3.1.0 because of user-visible incompatibilities + +1.13.0 / 2015-06-14 +=================== + + * Add `statusCode` property on `Error`s, in addition to `status` + * Change `type` default to `application/json` for JSON parser + * Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser + * Provide static `require` analysis + * Use the `http-errors` module to generate errors + * deps: bytes@2.1.0 + - Slight optimizations + * deps: iconv-lite@0.4.10 + - The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails + - Leading BOM is now removed when decoding + * deps: on-finished@~2.3.0 + - Add defined behavior for HTTP `CONNECT` requests + - Add defined behavior for HTTP `Upgrade` requests + - deps: ee-first@1.1.1 + * deps: qs@3.1.0 + - Fix dropping parameters like `hasOwnProperty` + - Fix various parsing edge cases + - Parsed object now has `null` prototype + * deps: raw-body@~2.1.1 + - Use `unpipe` module for unpiping requests + - deps: iconv-lite@0.4.10 + * deps: type-is@~1.6.3 + - deps: mime-types@~2.1.1 + - perf: reduce try block size + - perf: remove bitwise operations + * perf: enable strict mode + * perf: remove argument reassignment + * perf: remove delete call + +1.12.4 / 2015-05-10 +=================== + + * deps: debug@~2.2.0 + * deps: qs@2.4.2 + - Fix allowing parameters like `constructor` + * deps: on-finished@~2.2.1 + * deps: raw-body@~2.0.1 + - Fix a false-positive when unpiping in Node.js 0.8 + - deps: bytes@2.0.1 + * deps: type-is@~1.6.2 + - deps: mime-types@~2.0.11 + +1.12.3 / 2015-04-15 +=================== + + * Slight efficiency improvement when not debugging + * deps: depd@~1.0.1 + * deps: iconv-lite@0.4.8 + - Add encoding alias UNICODE-1-1-UTF-7 + * deps: raw-body@1.3.4 + - Fix hanging callback if request aborts during read + - deps: iconv-lite@0.4.8 + +1.12.2 / 2015-03-16 +=================== + + * deps: qs@2.4.1 + - Fix error when parameter `hasOwnProperty` is present + +1.12.1 / 2015-03-15 +=================== + + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + * deps: type-is@~1.6.1 + - deps: mime-types@~2.0.10 + +1.12.0 / 2015-02-13 +=================== + + * add `debug` messages + * accept a function for the `type` option + * use `content-type` to parse `Content-Type` headers + * deps: iconv-lite@0.4.7 + - Gracefully support enumerables on `Object.prototype` + * deps: raw-body@1.3.3 + - deps: iconv-lite@0.4.7 + * deps: type-is@~1.6.0 + - fix argument reassignment + - fix false-positives in `hasBody` `Transfer-Encoding` check + - support wildcard for both type and subtype (`*/*`) + - deps: mime-types@~2.0.9 + +1.11.0 / 2015-01-30 +=================== + + * make internal `extended: true` depth limit infinity + * deps: type-is@~1.5.6 + - deps: mime-types@~2.0.8 + +1.10.2 / 2015-01-20 +=================== + + * deps: iconv-lite@0.4.6 + - Fix rare aliases of single-byte encodings + * deps: raw-body@1.3.2 + - deps: iconv-lite@0.4.6 + +1.10.1 / 2015-01-01 +=================== + + * deps: on-finished@~2.2.0 + * deps: type-is@~1.5.5 + - deps: mime-types@~2.0.7 + +1.10.0 / 2014-12-02 +=================== + + * make internal `extended: true` array limit dynamic + +1.9.3 / 2014-11-21 +================== + + * deps: iconv-lite@0.4.5 + - Fix Windows-31J and X-SJIS encoding support + * deps: qs@2.3.3 + - Fix `arrayLimit` behavior + * deps: raw-body@1.3.1 + - deps: iconv-lite@0.4.5 + * deps: type-is@~1.5.3 + - deps: mime-types@~2.0.3 + +1.9.2 / 2014-10-27 +================== + + * deps: qs@2.3.2 + - Fix parsing of mixed objects and values + +1.9.1 / 2014-10-22 +================== + + * deps: on-finished@~2.1.1 + - Fix handling of pipelined requests + * deps: qs@2.3.0 + - Fix parsing of mixed implicit and explicit arrays + * deps: type-is@~1.5.2 + - deps: mime-types@~2.0.2 + +1.9.0 / 2014-09-24 +================== + + * include the charset in "unsupported charset" error message + * include the encoding in "unsupported content encoding" error message + * deps: depd@~1.0.0 + +1.8.4 / 2014-09-23 +================== + + * fix content encoding to be case-insensitive + +1.8.3 / 2014-09-19 +================== + + * deps: qs@2.2.4 + - Fix issue with object keys starting with numbers truncated + +1.8.2 / 2014-09-15 +================== + + * deps: depd@0.4.5 + +1.8.1 / 2014-09-07 +================== + + * deps: media-typer@0.3.0 + * deps: type-is@~1.5.1 + +1.8.0 / 2014-09-05 +================== + + * make empty-body-handling consistent between chunked requests + - empty `json` produces `{}` + - empty `raw` produces `new Buffer(0)` + - empty `text` produces `''` + - empty `urlencoded` produces `{}` + * deps: qs@2.2.3 + - Fix issue where first empty value in array is discarded + * deps: type-is@~1.5.0 + - fix `hasbody` to be true for `content-length: 0` + +1.7.0 / 2014-09-01 +================== + + * add `parameterLimit` option to `urlencoded` parser + * change `urlencoded` extended array limit to 100 + * respond with 413 when over `parameterLimit` in `urlencoded` + +1.6.7 / 2014-08-29 +================== + + * deps: qs@2.2.2 + - Remove unnecessary cloning + +1.6.6 / 2014-08-27 +================== + + * deps: qs@2.2.0 + - Array parsing fix + - Performance improvements + +1.6.5 / 2014-08-16 +================== + + * deps: on-finished@2.1.0 + +1.6.4 / 2014-08-14 +================== + + * deps: qs@1.2.2 + +1.6.3 / 2014-08-10 +================== + + * deps: qs@1.2.1 + +1.6.2 / 2014-08-07 +================== + + * deps: qs@1.2.0 + - Fix parsing array of objects + +1.6.1 / 2014-08-06 +================== + + * deps: qs@1.1.0 + - Accept urlencoded square brackets + - Accept empty values in implicit array notation + +1.6.0 / 2014-08-05 +================== + + * deps: qs@1.0.2 + - Complete rewrite + - Limits array length to 20 + - Limits object depth to 5 + - Limits parameters to 1,000 + +1.5.2 / 2014-07-27 +================== + + * deps: depd@0.4.4 + - Work-around v8 generating empty stack traces + +1.5.1 / 2014-07-26 +================== + + * deps: depd@0.4.3 + - Fix exception when global `Error.stackTraceLimit` is too low + +1.5.0 / 2014-07-20 +================== + + * deps: depd@0.4.2 + - Add `TRACE_DEPRECATION` environment variable + - Remove non-standard grey color from color output + - Support `--no-deprecation` argument + - Support `--trace-deprecation` argument + * deps: iconv-lite@0.4.4 + - Added encoding UTF-7 + * deps: raw-body@1.3.0 + - deps: iconv-lite@0.4.4 + - Added encoding UTF-7 + - Fix `Cannot switch to old mode now` error on Node.js 0.10+ + * deps: type-is@~1.3.2 + +1.4.3 / 2014-06-19 +================== + + * deps: type-is@1.3.1 + - fix global variable leak + +1.4.2 / 2014-06-19 +================== + + * deps: type-is@1.3.0 + - improve type parsing + +1.4.1 / 2014-06-19 +================== + + * fix urlencoded extended deprecation message + +1.4.0 / 2014-06-19 +================== + + * add `text` parser + * add `raw` parser + * check accepted charset in content-type (accepts utf-8) + * check accepted encoding in content-encoding (accepts identity) + * deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed + * deprecate `urlencoded()` without provided `extended` option + * lazy-load urlencoded parsers + * parsers split into files for reduced mem usage + * support gzip and deflate bodies + - set `inflate: false` to turn off + * deps: raw-body@1.2.2 + - Support all encodings from `iconv-lite` + +1.3.1 / 2014-06-11 +================== + + * deps: type-is@1.2.1 + - Switch dependency from mime to mime-types@1.0.0 + +1.3.0 / 2014-05-31 +================== + + * add `extended` option to urlencoded parser + +1.2.2 / 2014-05-27 +================== + + * deps: raw-body@1.1.6 + - assert stream encoding on node.js 0.8 + - assert stream encoding on node.js < 0.10.6 + - deps: bytes@1 + +1.2.1 / 2014-05-26 +================== + + * invoke `next(err)` after request fully read + - prevents hung responses and socket hang ups + +1.2.0 / 2014-05-11 +================== + + * add `verify` option + * deps: type-is@1.2.0 + - support suffix matching + +1.1.2 / 2014-05-11 +================== + + * improve json parser speed + +1.1.1 / 2014-05-11 +================== + + * fix repeated limit parsing with every request + +1.1.0 / 2014-05-10 +================== + + * add `type` option + * deps: pin for safety and consistency + +1.0.2 / 2014-04-14 +================== + + * use `type-is` module + +1.0.1 / 2014-03-20 +================== + + * lower default limits to 100kb diff --git a/node_modules/body-parser/LICENSE b/node_modules/body-parser/LICENSE new file mode 100644 index 0000000..386b7b6 --- /dev/null +++ b/node_modules/body-parser/LICENSE @@ -0,0 +1,23 @@ +(The MIT License) + +Copyright (c) 2014 Jonathan Ong +Copyright (c) 2014-2015 Douglas Christopher Wilson + +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. diff --git a/node_modules/body-parser/README.md b/node_modules/body-parser/README.md new file mode 100644 index 0000000..6376536 --- /dev/null +++ b/node_modules/body-parser/README.md @@ -0,0 +1,409 @@ +# body-parser + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] +[![Gratipay][gratipay-image]][gratipay-url] + +Node.js body parsing middleware. + +Parse incoming request bodies in a middleware before your handlers, availabe +under the `req.body` property. + +[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/). + +_This does not handle multipart bodies_, due to their complex and typically +large nature. For multipart bodies, you may be interested in the following +modules: + + * [busboy](https://www.npmjs.org/package/busboy#readme) and + [connect-busboy](https://www.npmjs.org/package/connect-busboy#readme) + * [multiparty](https://www.npmjs.org/package/multiparty#readme) and + [connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme) + * [formidable](https://www.npmjs.org/package/formidable#readme) + * [multer](https://www.npmjs.org/package/multer#readme) + +This module provides the following parsers: + + * [JSON body parser](#bodyparserjsonoptions) + * [Raw body parser](#bodyparserrawoptions) + * [Text body parser](#bodyparsertextoptions) + * [URL-encoded form body parser](#bodyparserurlencodedoptions) + +Other body parsers you might be interested in: + +- [body](https://www.npmjs.org/package/body#readme) +- [co-body](https://www.npmjs.org/package/co-body#readme) + +## Installation + +```sh +$ npm install body-parser +``` + +## API + +```js +var bodyParser = require('body-parser') +``` + +The `bodyParser` object exposes various factories to create middlewares. All +middlewares will populate the `req.body` property with the parsed body, or an +empty object (`{}`) if there was no body to parse (or an error was returned). + +The various errors returned by this module are described in the +[errors section](#errors). + +### bodyParser.json(options) + +Returns middleware that only parses `json`. This parser accepts any Unicode +encoding of the body and supports automatic inflation of `gzip` and `deflate` +encodings. + +A new `body` object containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). + +#### Options + +The `json` function takes an option `options` object that may contain any of +the following keys: + +##### inflate + +When set to `true`, then deflated (compressed) bodies will be inflated; when +`false`, deflated bodies are rejected. Defaults to `true`. + +##### limit + +Controls the maximum request body size. If this is a number, then the value +specifies the number of bytes; if it is a string, the value is passed to the +[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults +to `'100kb'`. + +##### reviver + +The `reviver` option is passed directly to `JSON.parse` as the second +argument. You can find more information on this argument +[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter). + +##### strict + +When set to `true`, will only accept arrays and objects; when `false` will +accept anything `JSON.parse` accepts. Defaults to `true`. + +##### type + +The `type` option is used to determine what media type the middleware will +parse. This option can be a function or a string. If a string, `type` option +is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) +library and this can be an extension name (like `json`), a mime type (like +`application/json`), or a mime type with a wildcard (like `*/*` or `*/json`). +If a function, the `type` option is called as `fn(req)` and the request is +parsed if it returns a truthy value. Defaults to `application/json`. + +##### verify + +The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, +where `buf` is a `Buffer` of the raw request body and `encoding` is the +encoding of the request. The parsing can be aborted by throwing an error. + +### bodyParser.raw(options) + +Returns middleware that parses all bodies as a `Buffer`. This parser +supports automatic inflation of `gzip` and `deflate` encodings. + +A new `body` object containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a `Buffer` object +of the body. + +#### Options + +The `raw` function takes an option `options` object that may contain any of +the following keys: + +##### inflate + +When set to `true`, then deflated (compressed) bodies will be inflated; when +`false`, deflated bodies are rejected. Defaults to `true`. + +##### limit + +Controls the maximum request body size. If this is a number, then the value +specifies the number of bytes; if it is a string, the value is passed to the +[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults +to `'100kb'`. + +##### type + +The `type` option is used to determine what media type the middleware will +parse. This option can be a function or a string. If a string, `type` option +is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) +library and this can be an extension name (like `bin`), a mime type (like +`application/octet-stream`), or a mime type with a wildcard (like `*/*` or +`application/*`). If a function, the `type` option is called as `fn(req)` +and the request is parsed if it returns a truthy value. Defaults to +`application/octet-stream`. + +##### verify + +The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, +where `buf` is a `Buffer` of the raw request body and `encoding` is the +encoding of the request. The parsing can be aborted by throwing an error. + +### bodyParser.text(options) + +Returns middleware that parses all bodies as a string. This parser supports +automatic inflation of `gzip` and `deflate` encodings. + +A new `body` string containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This will be a string of the +body. + +#### Options + +The `text` function takes an option `options` object that may contain any of +the following keys: + +##### defaultCharset + +Specify the default character set for the text content if the charset is not +specified in the `Content-Type` header of the request. Defaults to `utf-8`. + +##### inflate + +When set to `true`, then deflated (compressed) bodies will be inflated; when +`false`, deflated bodies are rejected. Defaults to `true`. + +##### limit + +Controls the maximum request body size. If this is a number, then the value +specifies the number of bytes; if it is a string, the value is passed to the +[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults +to `'100kb'`. + +##### type + +The `type` option is used to determine what media type the middleware will +parse. This option can be a function or a string. If a string, `type` option +is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) +library and this can be an extension name (like `txt`), a mime type (like +`text/plain`), or a mime type with a wildcard (like `*/*` or `text/*`). +If a function, the `type` option is called as `fn(req)` and the request is +parsed if it returns a truthy value. Defaults to `text/plain`. + +##### verify + +The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, +where `buf` is a `Buffer` of the raw request body and `encoding` is the +encoding of the request. The parsing can be aborted by throwing an error. + +### bodyParser.urlencoded(options) + +Returns middleware that only parses `urlencoded` bodies. This parser accepts +only UTF-8 encoding of the body and supports automatic inflation of `gzip` +and `deflate` encodings. + +A new `body` object containing the parsed data is populated on the `request` +object after the middleware (i.e. `req.body`). This object will contain +key-value pairs, where the value can be a string or array (when `extended` is +`false`), or any type (when `extended` is `true`). + +#### Options + +The `urlencoded` function takes an option `options` object that may contain +any of the following keys: + +##### extended + +The `extended` option allows to choose between parsing the URL-encoded data +with the `querystring` library (when `false`) or the `qs` library (when +`true`). The "extended" syntax allows for rich objects and arrays to be +encoded into the URL-encoded format, allowing for a JSON-like experience +with URL-encoded. For more information, please +[see the qs library](https://www.npmjs.org/package/qs#readme). + +Defaults to `true`, but using the default has been deprecated. Please +research into the difference between `qs` and `querystring` and choose the +appropriate setting. + +##### inflate + +When set to `true`, then deflated (compressed) bodies will be inflated; when +`false`, deflated bodies are rejected. Defaults to `true`. + +##### limit + +Controls the maximum request body size. If this is a number, then the value +specifies the number of bytes; if it is a string, the value is passed to the +[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults +to `'100kb'`. + +##### parameterLimit + +The `parameterLimit` option controls the maximum number of parameters that +are allowed in the URL-encoded data. If a request contains more parameters +than this value, a 413 will be returned to the client. Defaults to `1000`. + +##### type + +The `type` option is used to determine what media type the middleware will +parse. This option can be a function or a string. If a string, `type` option +is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) +library and this can be an extension name (like `urlencoded`), a mime type (like +`application/x-www-form-urlencoded`), or a mime type with a wildcard (like +`*/x-www-form-urlencoded`). If a function, the `type` option is called as +`fn(req)` and the request is parsed if it returns a truthy value. Defaults +to `application/x-www-form-urlencoded`. + +##### verify + +The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, +where `buf` is a `Buffer` of the raw request body and `encoding` is the +encoding of the request. The parsing can be aborted by throwing an error. + +## Errors + +The middlewares provided by this module create errors depending on the error +condition during parsing. The errors will typically have a `status` property +that contains the suggested HTTP response code and a `body` property containing +the read body, if available. + +The following are the common errors emitted, though any error can come through +for various reasons. + +### content encoding unsupported + +This error will occur when the request had a `Content-Encoding` header that +contained an encoding but the "inflation" option was set to `false`. The +`status` property is set to `415`. + +### request aborted + +This error will occur when the request is aborted by the client before reading +the body has finished. The `received` property will be set to the number of +bytes received before the request was aborted and the `expected` property is +set to the number of expected bytes. The `status` property is set to `400`. + +### request entity too large + +This error will occur when the request body's size is larger than the "limit" +option. The `limit` property will be set to the byte limit and the `length` +property will be set to the request body's length. The `status` property is +set to `413`. + +### request size did not match content length + +This error will occur when the request's length did not match the length from +the `Content-Length` header. This typically occurs when the request is malformed, +typically when the `Content-Length` header was calculated based on characters +instead of bytes. The `status` property is set to `400`. + +### stream encoding should not be set + +This error will occur when something called the `req.setEncoding` method prior +to this middleware. This module operates directly on bytes only and you cannot +call `req.setEncoding` when using this module. The `status` property is set to +`500`. + +### unsupported charset "BOGUS" + +This error will occur when the request had a charset parameter in the +`Content-Type` header, but the `iconv-lite` module does not support it OR the +parser does not support it. The charset is contained in the message as well +as in the `charset` property. The `status` property is set to `415`. + +### unsupported content encoding "bogus" + +This error will occur when the request had a `Content-Encoding` header that +contained an unsupported encoding. The encoding is contained in the message +as well as in the `encoding` property. The `status` property is set to `415`. + +## Examples + +### Express/Connect top-level generic + +This example demonstrates adding a generic JSON and URL-encoded parser as a +top-level middleware, which will parse the bodies of all incoming requests. +This is the simplest setup. + +```js +var express = require('express') +var bodyParser = require('body-parser') + +var app = express() + +// parse application/x-www-form-urlencoded +app.use(bodyParser.urlencoded({ extended: false })) + +// parse application/json +app.use(bodyParser.json()) + +app.use(function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.write('you posted:\n') + res.end(JSON.stringify(req.body, null, 2)) +}) +``` + +### Express route-specific + +This example demonstrates adding body parsers specifically to the routes that +need them. In general, this is the most recommended way to use body-parser with +Express. + +```js +var express = require('express') +var bodyParser = require('body-parser') + +var app = express() + +// create application/json parser +var jsonParser = bodyParser.json() + +// create application/x-www-form-urlencoded parser +var urlencodedParser = bodyParser.urlencoded({ extended: false }) + +// POST /login gets urlencoded bodies +app.post('/login', urlencodedParser, function (req, res) { + if (!req.body) return res.sendStatus(400) + res.send('welcome, ' + req.body.username) +}) + +// POST /api/users gets JSON bodies +app.post('/api/users', jsonParser, function (req, res) { + if (!req.body) return res.sendStatus(400) + // create user in req.body +}) +``` + +### Change accepted type for parsers + +All the parsers accept a `type` option which allows you to change the +`Content-Type` that the middleware will parse. + +```js +// parse various different custom JSON types as JSON +app.use(bodyParser.json({ type: 'application/*+json' })) + +// parse some custom thing into a Buffer +app.use(bodyParser.raw({ type: 'application/vnd.custom-type' })) + +// parse an HTML body into a string +app.use(bodyParser.text({ type: 'text/html' })) +``` + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/body-parser.svg +[npm-url]: https://npmjs.org/package/body-parser +[travis-image]: https://img.shields.io/travis/expressjs/body-parser/master.svg +[travis-url]: https://travis-ci.org/expressjs/body-parser +[coveralls-image]: https://img.shields.io/coveralls/expressjs/body-parser/master.svg +[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master +[downloads-image]: https://img.shields.io/npm/dm/body-parser.svg +[downloads-url]: https://npmjs.org/package/body-parser +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg +[gratipay-url]: https://www.gratipay.com/dougwilson/ diff --git a/node_modules/body-parser/index.js b/node_modules/body-parser/index.js new file mode 100644 index 0000000..93c3a1f --- /dev/null +++ b/node_modules/body-parser/index.js @@ -0,0 +1,157 @@ +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var deprecate = require('depd')('body-parser') + +/** + * Cache of loaded parsers. + * @private + */ + +var parsers = Object.create(null) + +/** + * @typedef Parsers + * @type {function} + * @property {function} json + * @property {function} raw + * @property {function} text + * @property {function} urlencoded + */ + +/** + * Module exports. + * @type {Parsers} + */ + +exports = module.exports = deprecate.function(bodyParser, + 'bodyParser: use individual json/urlencoded middlewares') + +/** + * JSON parser. + * @public + */ + +Object.defineProperty(exports, 'json', { + configurable: true, + enumerable: true, + get: createParserGetter('json') +}) + +/** + * Raw parser. + * @public + */ + +Object.defineProperty(exports, 'raw', { + configurable: true, + enumerable: true, + get: createParserGetter('raw') +}) + +/** + * Text parser. + * @public + */ + +Object.defineProperty(exports, 'text', { + configurable: true, + enumerable: true, + get: createParserGetter('text') +}) + +/** + * URL-encoded parser. + * @public + */ + +Object.defineProperty(exports, 'urlencoded', { + configurable: true, + enumerable: true, + get: createParserGetter('urlencoded') +}) + +/** + * Create a middleware to parse json and urlencoded bodies. + * + * @param {object} [options] + * @return {function} + * @deprecated + * @public + */ + +function bodyParser (options) { + var opts = {} + + // exclude type option + if (options) { + for (var prop in options) { + if (prop !== 'type') { + opts[prop] = options[prop] + } + } + } + + var _urlencoded = exports.urlencoded(opts) + var _json = exports.json(opts) + + return function bodyParser (req, res, next) { + _json(req, res, function (err) { + if (err) return next(err) + _urlencoded(req, res, next) + }) + } +} + +/** + * Create a getter for loading a parser. + * @private + */ + +function createParserGetter (name) { + return function get () { + return loadParser(name) + } +} + +/** + * Load a parser module. + * @private + */ + +function loadParser (parserName) { + var parser = parsers[parserName] + + if (parser !== undefined) { + return parser + } + + // this uses a switch for static require analysis + switch (parserName) { + case 'json': + parser = require('./lib/types/json') + break + case 'raw': + parser = require('./lib/types/raw') + break + case 'text': + parser = require('./lib/types/text') + break + case 'urlencoded': + parser = require('./lib/types/urlencoded') + break + } + + // store to prevent invoking require() + return (parsers[parserName] = parser) +} diff --git a/node_modules/body-parser/lib/read.js b/node_modules/body-parser/lib/read.js new file mode 100644 index 0000000..3c0fe93 --- /dev/null +++ b/node_modules/body-parser/lib/read.js @@ -0,0 +1,188 @@ +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var createError = require('http-errors') +var getBody = require('raw-body') +var iconv = require('iconv-lite') +var onFinished = require('on-finished') +var zlib = require('zlib') + +/** + * Module exports. + */ + +module.exports = read + +/** + * Read a request into a buffer and parse. + * + * @param {object} req + * @param {object} res + * @param {function} next + * @param {function} parse + * @param {function} debug + * @param {object} [options] + * @api private + */ + +function read (req, res, next, parse, debug, options) { + var length + var opts = options || {} + var stream + + // flag as parsed + req._body = true + + // read options + var encoding = opts.encoding !== null + ? opts.encoding || 'utf-8' + : null + var verify = opts.verify + + try { + // get the content stream + stream = contentstream(req, debug, opts.inflate) + length = stream.length + stream.length = undefined + } catch (err) { + return next(err) + } + + // set raw-body options + opts.length = length + opts.encoding = verify + ? null + : encoding + + // assert charset is supported + if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { + return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase() + })) + } + + // read body + debug('read body') + getBody(stream, opts, function (err, body) { + if (err) { + // default to 400 + setErrorStatus(err, 400) + + // echo back charset + if (err.type === 'encoding.unsupported') { + err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase() + }) + } + + // read off entire request + stream.resume() + onFinished(req, function onfinished () { + next(err) + }) + return + } + + // verify + if (verify) { + try { + debug('verify body') + verify(req, res, body, encoding) + } catch (err) { + // default to 403 + setErrorStatus(err, 403) + next(err) + return + } + } + + // parse + var str + try { + debug('parse body') + str = typeof body !== 'string' && encoding !== null + ? iconv.decode(body, encoding) + : body + req.body = parse(str) + } catch (err) { + err.body = str === undefined + ? body + : str + + // default to 400 + setErrorStatus(err, 400) + + next(err) + return + } + + next() + }) +} + +/** + * Get the content stream of the request. + * + * @param {object} req + * @param {function} debug + * @param {boolean} [inflate=true] + * @return {object} + * @api private + */ + +function contentstream (req, debug, inflate) { + var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() + var length = req.headers['content-length'] + var stream + + debug('content-encoding "%s"', encoding) + + if (inflate === false && encoding !== 'identity') { + throw createError(415, 'content encoding unsupported') + } + + switch (encoding) { + case 'deflate': + stream = zlib.createInflate() + debug('inflate body') + req.pipe(stream) + break + case 'gzip': + stream = zlib.createGunzip() + debug('gunzip body') + req.pipe(stream) + break + case 'identity': + stream = req + stream.length = length + break + default: + throw createError(415, 'unsupported content encoding "' + encoding + '"', { + encoding: encoding + }) + } + + return stream +} + +/** + * Set a status on an error object, if ones does not exist + * @private + */ + +function setErrorStatus (error, status) { + if (!error.status && !error.statusCode) { + error.status = status + error.statusCode = status + } +} diff --git a/node_modules/body-parser/lib/types/json.js b/node_modules/body-parser/lib/types/json.js new file mode 100644 index 0000000..d0023c7 --- /dev/null +++ b/node_modules/body-parser/lib/types/json.js @@ -0,0 +1,175 @@ +/*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var bytes = require('bytes') +var contentType = require('content-type') +var createError = require('http-errors') +var debug = require('debug')('body-parser:json') +var read = require('../read') +var typeis = require('type-is') + +/** + * Module exports. + */ + +module.exports = json + +/** + * RegExp to match the first non-space in a string. + * + * Allowed whitespace is defined in RFC 7159: + * + * ws = *( + * %x20 / ; Space + * %x09 / ; Horizontal tab + * %x0A / ; Line feed or New line + * %x0D ) ; Carriage return + */ + +var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*(.)/ // eslint-disable-line no-control-regex + +/** + * Create a middleware to parse JSON bodies. + * + * @param {object} [options] + * @return {function} + * @public + */ + +function json (options) { + var opts = options || {} + + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var inflate = opts.inflate !== false + var reviver = opts.reviver + var strict = opts.strict !== false + var type = opts.type || 'application/json' + var verify = opts.verify || false + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type + + function parse (body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {} + } + + if (strict) { + var first = firstchar(body) + + if (first !== '{' && first !== '[') { + debug('strict violation') + throw new SyntaxError('Unexpected token ' + first) + } + } + + debug('parse json') + return JSON.parse(body, reviver) + } + + return function jsonParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return + } + + req.body = req.body || {} + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return + } + + debug('content-type %j', req.headers['content-type']) + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() + return + } + + // assert charset per RFC 7159 sec 8.1 + var charset = getCharset(req) || 'utf-8' + if (charset.substr(0, 4) !== 'utf-') { + debug('invalid charset') + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset + })) + return + } + + // read + read(req, res, next, parse, debug, { + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }) + } +} + +/** + * Get the first non-whitespace character in a string. + * + * @param {string} str + * @return {function} + * @api public + */ + +function firstchar (str) { + var match = FIRST_CHAR_REGEXP.exec(str) + return match ? match[1] : '' +} + +/** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + +function getCharset (req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase() + } catch (e) { + return undefined + } +} + +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) + } +} diff --git a/node_modules/body-parser/lib/types/raw.js b/node_modules/body-parser/lib/types/raw.js new file mode 100644 index 0000000..f5d1b67 --- /dev/null +++ b/node_modules/body-parser/lib/types/raw.js @@ -0,0 +1,101 @@ +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + */ + +var bytes = require('bytes') +var debug = require('debug')('body-parser:raw') +var read = require('../read') +var typeis = require('type-is') + +/** + * Module exports. + */ + +module.exports = raw + +/** + * Create a middleware to parse raw bodies. + * + * @param {object} [options] + * @return {function} + * @api public + */ + +function raw (options) { + var opts = options || {} + + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'application/octet-stream' + var verify = opts.verify || false + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type + + function parse (buf) { + return buf + } + + return function rawParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return + } + + req.body = req.body || {} + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return + } + + debug('content-type %j', req.headers['content-type']) + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() + return + } + + // read + read(req, res, next, parse, debug, { + encoding: null, + inflate: inflate, + limit: limit, + verify: verify + }) + } +} + +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) + } +} diff --git a/node_modules/body-parser/lib/types/text.js b/node_modules/body-parser/lib/types/text.js new file mode 100644 index 0000000..8bf2637 --- /dev/null +++ b/node_modules/body-parser/lib/types/text.js @@ -0,0 +1,121 @@ +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + */ + +var bytes = require('bytes') +var contentType = require('content-type') +var debug = require('debug')('body-parser:text') +var read = require('../read') +var typeis = require('type-is') + +/** + * Module exports. + */ + +module.exports = text + +/** + * Create a middleware to parse text bodies. + * + * @param {object} [options] + * @return {function} + * @api public + */ + +function text (options) { + var opts = options || {} + + var defaultCharset = opts.defaultCharset || 'utf-8' + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'text/plain' + var verify = opts.verify || false + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type + + function parse (buf) { + return buf + } + + return function textParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return + } + + req.body = req.body || {} + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return + } + + debug('content-type %j', req.headers['content-type']) + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() + return + } + + // get charset + var charset = getCharset(req) || defaultCharset + + // read + read(req, res, next, parse, debug, { + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }) + } +} + +/** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + +function getCharset (req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase() + } catch (e) { + return undefined + } +} + +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) + } +} diff --git a/node_modules/body-parser/lib/types/urlencoded.js b/node_modules/body-parser/lib/types/urlencoded.js new file mode 100644 index 0000000..08157ae --- /dev/null +++ b/node_modules/body-parser/lib/types/urlencoded.js @@ -0,0 +1,279 @@ +/*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var bytes = require('bytes') +var contentType = require('content-type') +var createError = require('http-errors') +var debug = require('debug')('body-parser:urlencoded') +var deprecate = require('depd')('body-parser') +var read = require('../read') +var typeis = require('type-is') + +/** + * Module exports. + */ + +module.exports = urlencoded + +/** + * Cache of parser modules. + */ + +var parsers = Object.create(null) + +/** + * Create a middleware to parse urlencoded bodies. + * + * @param {object} [options] + * @return {function} + * @public + */ + +function urlencoded (options) { + var opts = options || {} + + // notice because option default will flip in next major + if (opts.extended === undefined) { + deprecate('undefined extended: provide extended option') + } + + var extended = opts.extended !== false + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'application/x-www-form-urlencoded' + var verify = opts.verify || false + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } + + // create the appropriate query parser + var queryparse = extended + ? extendedparser(opts) + : simpleparser(opts) + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type + + function parse (body) { + return body.length + ? queryparse(body) + : {} + } + + return function urlencodedParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return + } + + req.body = req.body || {} + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return + } + + debug('content-type %j', req.headers['content-type']) + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() + return + } + + // assert charset + var charset = getCharset(req) || 'utf-8' + if (charset !== 'utf-8') { + debug('invalid charset') + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset + })) + return + } + + // read + read(req, res, next, parse, debug, { + debug: debug, + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }) + } +} + +/** + * Get the extended query parser. + * + * @param {object} options + */ + +function extendedparser (options) { + var parameterLimit = options.parameterLimit !== undefined + ? options.parameterLimit + : 1000 + var parse = parser('qs') + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number') + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0 + } + + return function queryparse (body) { + var paramCount = parameterCount(body, parameterLimit) + + if (paramCount === undefined) { + debug('too many parameters') + throw createError(413, 'too many parameters') + } + + var arrayLimit = Math.max(100, paramCount) + + debug('parse extended urlencoding') + return parse(body, { + allowPrototypes: true, + arrayLimit: arrayLimit, + depth: Infinity, + parameterLimit: parameterLimit + }) + } +} + +/** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + +function getCharset (req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase() + } catch (e) { + return undefined + } +} + +/** + * Count the number of parameters, stopping once limit reached + * + * @param {string} body + * @param {number} limit + * @api private + */ + +function parameterCount (body, limit) { + var count = 0 + var index = 0 + + while ((index = body.indexOf('&', index)) !== -1) { + count++ + index++ + + if (count === limit) { + return undefined + } + } + + return count +} + +/** + * Get parser for module name dynamically. + * + * @param {string} name + * @return {function} + * @api private + */ + +function parser (name) { + var mod = parsers[name] + + if (mod !== undefined) { + return mod.parse + } + + // this uses a switch for static require analysis + switch (name) { + case 'qs': + mod = require('qs') + break + case 'querystring': + mod = require('querystring') + break + } + + // store to prevent invoking require() + parsers[name] = mod + + return mod.parse +} + +/** + * Get the simple query parser. + * + * @param {object} options + */ + +function simpleparser (options) { + var parameterLimit = options.parameterLimit !== undefined + ? options.parameterLimit + : 1000 + var parse = parser('querystring') + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number') + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0 + } + + return function queryparse (body) { + var paramCount = parameterCount(body, parameterLimit) + + if (paramCount === undefined) { + debug('too many parameters') + throw createError(413, 'too many parameters') + } + + debug('parse urlencoding') + return parse(body, undefined, undefined, {maxKeys: parameterLimit}) + } +} + +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) + } +} diff --git a/node_modules/body-parser/package.json b/node_modules/body-parser/package.json new file mode 100644 index 0000000..5fae396 --- /dev/null +++ b/node_modules/body-parser/package.json @@ -0,0 +1,123 @@ +{ + "_args": [ + [ + { + "raw": "body-parser", + "scope": null, + "escapedName": "body-parser", + "name": "body-parser", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "/mnt/c/Users/const/IdeaProjects/space-game" + ] + ], + "_from": "body-parser@latest", + "_id": "body-parser@1.15.2", + "_inCache": true, + "_installable": true, + "_location": "/body-parser", + "_nodeVersion": "4.4.3", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/body-parser-1.15.2.tgz_1466393694089_0.7908455491997302" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "2.15.1", + "_phantomChildren": {}, + "_requested": { + "raw": "body-parser", + "scope": null, + "escapedName": "body-parser", + "name": "body-parser", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER" + ], + "_resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.15.2.tgz", + "_shasum": "d7578cf4f1d11d5f6ea804cef35dc7a7ff6dae67", + "_shrinkwrap": null, + "_spec": "body-parser", + "_where": "/mnt/c/Users/const/IdeaProjects/space-game", + "bugs": { + "url": "https://github.com/expressjs/body-parser/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + } + ], + "dependencies": { + "bytes": "2.4.0", + "content-type": "~1.0.2", + "debug": "~2.2.0", + "depd": "~1.1.0", + "http-errors": "~1.5.0", + "iconv-lite": "0.4.13", + "on-finished": "~2.3.0", + "qs": "6.2.0", + "raw-body": "~2.1.7", + "type-is": "~1.6.13" + }, + "description": "Node.js body parsing middleware", + "devDependencies": { + "eslint": "2.13.0", + "eslint-config-standard": "5.3.1", + "eslint-plugin-promise": "1.3.2", + "eslint-plugin-standard": "1.3.2", + "istanbul": "0.4.3", + "methods": "1.1.2", + "mocha": "2.5.3", + "supertest": "1.1.0" + }, + "directories": {}, + "dist": { + "shasum": "d7578cf4f1d11d5f6ea804cef35dc7a7ff6dae67", + "tarball": "https://registry.npmjs.org/body-parser/-/body-parser-1.15.2.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "files": [ + "lib/", + "LICENSE", + "HISTORY.md", + "index.js" + ], + "gitHead": "3c8218446d919a5e87fa696971fb7f69b10afc1c", + "homepage": "https://github.com/expressjs/body-parser#readme", + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "body-parser", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/body-parser.git" + }, + "scripts": { + "lint": "eslint **/*.js", + "test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/" + }, + "version": "1.15.2" +} diff --git a/node_modules/bytes/History.md b/node_modules/bytes/History.md new file mode 100644 index 0000000..56932a4 --- /dev/null +++ b/node_modules/bytes/History.md @@ -0,0 +1,70 @@ +2.4.0 / 2016-06-01 +================== + + * Add option "unitSeparator" + +2.3.0 / 2016-02-15 +================== + + * Drop partial bytes on all parsed units + * Fix non-finite numbers to `.format` to return `null` + * Fix parsing byte string that looks like hex + * perf: hoist regular expressions + +2.2.0 / 2015-11-13 +================== + + * add option "decimalPlaces" + * add option "fixedDecimals" + +2.1.0 / 2015-05-21 +================== + + * add `.format` export + * add `.parse` export + +2.0.2 / 2015-05-20 +================== + + * remove map recreation + * remove unnecessary object construction + +2.0.1 / 2015-05-07 +================== + + * fix browserify require + * remove node.extend dependency + +2.0.0 / 2015-04-12 +================== + + * add option "case" + * add option "thousandsSeparator" + * return "null" on invalid parse input + * support proper round-trip: bytes(bytes(num)) === num + * units no longer case sensitive when parsing + +1.0.0 / 2014-05-05 +================== + + * add negative support. fixes #6 + +0.3.0 / 2014-03-19 +================== + + * added terabyte support + +0.2.1 / 2013-04-01 +================== + + * add .component + +0.2.0 / 2012-10-28 +================== + + * bytes(200).should.eql('200b') + +0.1.0 / 2012-07-04 +================== + + * add bytes to string conversion [yields] diff --git a/node_modules/bytes/LICENSE b/node_modules/bytes/LICENSE new file mode 100644 index 0000000..63e95a9 --- /dev/null +++ b/node_modules/bytes/LICENSE @@ -0,0 +1,23 @@ +(The MIT License) + +Copyright (c) 2012-2014 TJ Holowaychuk +Copyright (c) 2015 Jed Watson + +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. diff --git a/node_modules/bytes/Readme.md b/node_modules/bytes/Readme.md new file mode 100644 index 0000000..7465fde --- /dev/null +++ b/node_modules/bytes/Readme.md @@ -0,0 +1,114 @@ +# Bytes utility + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Build Status][travis-image]][travis-url] + +Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa. + +## Usage + +```js +var bytes = require('bytes'); +``` + +#### bytes.format(number value, [options]): string|null + +Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is + rounded. + +**Arguments** + +| Name | Type | Description | +|---------|--------|--------------------| +| value | `number` | Value in bytes | +| options | `Object` | Conversion options | + +**Options** + +| Property | Type | Description | +|-------------------|--------|-----------------------------------------------------------------------------------------| +| decimalPlaces | `number`|`null` | Maximum number of decimal places to include in output. Default value to `2`. | +| fixedDecimals | `boolean`|`null` | Whether to always display the maximum number of decimal places. Default value to `false` | +| thousandsSeparator | `string`|`null` | Example of values: `' '`, `','` and `.`... Default value to `' '`. | +| unitSeparator | `string`|`null` | Separator to use between number and unit. Default value to `''`. | + +**Returns** + +| Name | Type | Description | +|---------|-------------|-------------------------| +| results | `string`|`null` | Return null upon error. String value otherwise. | + +**Example** + +```js +bytes(1024); +// output: '1kB' + +bytes(1000); +// output: '1000B' + +bytes(1000, {thousandsSeparator: ' '}); +// output: '1 000B' + +bytes(1024 * 1.7, {decimalPlaces: 0}); +// output: '2kB' + +bytes(1024, {unitSeparator: ' '}); +// output: '1 kB' + +``` + +#### bytes.parse(string value): number|null + +Parse the string value into an integer in bytes. If no unit is given, it is assumed the value is in bytes. + +Supported units and abbreviations are as follows and are case-insensitive: + + * "b" for bytes + * "kb" for kilobytes + * "mb" for megabytes + * "gb" for gigabytes + * "tb" for terabytes + +The units are in powers of two, not ten. This means 1kb = 1024b according to this parser. + +**Arguments** + +| Name | Type | Description | +|---------------|--------|--------------------| +| value | `string` | String to parse. | + +**Returns** + +| Name | Type | Description | +|---------|-------------|-------------------------| +| results | `number`|`null` | Return null upon error. Value in bytes otherwise. | + +**Example** + +```js +bytes('1kB'); +// output: 1024 + +bytes('1024'); +// output: 1024 +``` + +## Installation + +```bash +npm install bytes --save +component install visionmedia/bytes.js +``` + +## License + +[![npm](https://img.shields.io/npm/l/express.svg)](https://github.com/visionmedia/bytes.js/blob/master/LICENSE) + +[downloads-image]: https://img.shields.io/npm/dm/bytes.svg +[downloads-url]: https://npmjs.org/package/bytes +[npm-image]: https://img.shields.io/npm/v/bytes.svg +[npm-url]: https://npmjs.org/package/bytes +[travis-image]: https://img.shields.io/travis/visionmedia/bytes.js/master.svg +[travis-url]: https://travis-ci.org/visionmedia/bytes.js diff --git a/node_modules/bytes/index.js b/node_modules/bytes/index.js new file mode 100644 index 0000000..aa24231 --- /dev/null +++ b/node_modules/bytes/index.js @@ -0,0 +1,157 @@ +/*! + * bytes + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015 Jed Watson + * MIT Licensed + */ + +'use strict'; + +/** + * Module exports. + * @public + */ + +module.exports = bytes; +module.exports.format = format; +module.exports.parse = parse; + +/** + * Module variables. + * @private + */ + +var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; + +var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; + +var map = { + b: 1, + kb: 1 << 10, + mb: 1 << 20, + gb: 1 << 30, + tb: ((1 << 30) * 1024) +}; + +// TODO: use is-finite module? +var numberIsFinite = Number.isFinite || function (v) { return typeof v === 'number' && isFinite(v); }; + +var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i; + +/** + * Convert the given value in bytes into a string or parse to string to an integer in bytes. + * + * @param {string|number} value + * @param {{ + * case: [string], + * decimalPlaces: [number] + * fixedDecimals: [boolean] + * thousandsSeparator: [string] + * unitSeparator: [string] + * }} [options] bytes options. + * + * @returns {string|number|null} + */ + +function bytes(value, options) { + if (typeof value === 'string') { + return parse(value); + } + + if (typeof value === 'number') { + return format(value, options); + } + + return null; +} + +/** + * Format the given value in bytes into a string. + * + * If the value is negative, it is kept as such. If it is a float, + * it is rounded. + * + * @param {number} value + * @param {object} [options] + * @param {number} [options.decimalPlaces=2] + * @param {number} [options.fixedDecimals=false] + * @param {string} [options.thousandsSeparator=] + * @param {string} [options.unitSeparator=] + * + * @returns {string|null} + * @public + */ + +function format(value, options) { + if (!numberIsFinite(value)) { + return null; + } + + var mag = Math.abs(value); + var thousandsSeparator = (options && options.thousandsSeparator) || ''; + var unitSeparator = (options && options.unitSeparator) || ''; + var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; + var fixedDecimals = Boolean(options && options.fixedDecimals); + var unit = 'B'; + + if (mag >= map.tb) { + unit = 'TB'; + } else if (mag >= map.gb) { + unit = 'GB'; + } else if (mag >= map.mb) { + unit = 'MB'; + } else if (mag >= map.kb) { + unit = 'kB'; + } + + var val = value / map[unit.toLowerCase()]; + var str = val.toFixed(decimalPlaces); + + if (!fixedDecimals) { + str = str.replace(formatDecimalsRegExp, '$1'); + } + + if (thousandsSeparator) { + str = str.replace(formatThousandsRegExp, thousandsSeparator); + } + + return str + unitSeparator + unit; +} + +/** + * Parse the string value into an integer in bytes. + * + * If no unit is given, it is assumed the value is in bytes. + * + * @param {number|string} val + * + * @returns {number|null} + * @public + */ + +function parse(val) { + if (typeof val === 'number' && !isNaN(val)) { + return val; + } + + if (typeof val !== 'string') { + return null; + } + + // Test if the string passed is valid + var results = parseRegExp.exec(val); + var floatValue; + var unit = 'b'; + + if (!results) { + // Nothing could be extracted from the given string + floatValue = parseInt(val, 10); + unit = 'b' + } else { + // Retrieve the value and the unit + floatValue = parseFloat(results[1]); + unit = results[4].toLowerCase(); + } + + return Math.floor(map[unit] * floatValue); +} diff --git a/node_modules/bytes/package.json b/node_modules/bytes/package.json new file mode 100644 index 0000000..15a9085 --- /dev/null +++ b/node_modules/bytes/package.json @@ -0,0 +1,121 @@ +{ + "_args": [ + [ + { + "raw": "bytes@2.4.0", + "scope": null, + "escapedName": "bytes", + "name": "bytes", + "rawSpec": "2.4.0", + "spec": "2.4.0", + "type": "version" + }, + "/mnt/c/Users/const/IdeaProjects/space-game/node_modules/body-parser" + ] + ], + "_from": "bytes@2.4.0", + "_id": "bytes@2.4.0", + "_inCache": true, + "_installable": true, + "_location": "/bytes", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/bytes-2.4.0.tgz_1464812473023_0.6271433881483972" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "bytes@2.4.0", + "scope": null, + "escapedName": "bytes", + "name": "bytes", + "rawSpec": "2.4.0", + "spec": "2.4.0", + "type": "version" + }, + "_requiredBy": [ + "/body-parser", + "/raw-body" + ], + "_resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "_shasum": "7d97196f9d5baf7f6935e25985549edd2a6c2339", + "_shrinkwrap": null, + "_spec": "bytes@2.4.0", + "_where": "/mnt/c/Users/const/IdeaProjects/space-game/node_modules/body-parser", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "bugs": { + "url": "https://github.com/visionmedia/bytes.js/issues" + }, + "component": { + "scripts": { + "bytes/index.js": "index.js" + } + }, + "contributors": [ + { + "name": "Jed Watson", + "email": "jed.watson@me.com" + }, + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "dependencies": {}, + "description": "Utility to parse a string bytes to bytes and vice-versa", + "devDependencies": { + "mocha": "1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "7d97196f9d5baf7f6935e25985549edd2a6c2339", + "tarball": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz" + }, + "files": [ + "History.md", + "LICENSE", + "Readme.md", + "index.js" + ], + "gitHead": "2a598442bdfa796df8d01a96cc54495cda550e70", + "homepage": "https://github.com/visionmedia/bytes.js", + "keywords": [ + "byte", + "bytes", + "utility", + "parse", + "parser", + "convert", + "converter" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "name": "bytes", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/visionmedia/bytes.js.git" + }, + "scripts": { + "test": "mocha --check-leaks --reporter spec" + }, + "version": "2.4.0" +} diff --git a/node_modules/callsite/.npmignore b/node_modules/callsite/.npmignore new file mode 100644 index 0000000..f1250e5 --- /dev/null +++ b/node_modules/callsite/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/node_modules/callsite/History.md b/node_modules/callsite/History.md new file mode 100644 index 0000000..4994198 --- /dev/null +++ b/node_modules/callsite/History.md @@ -0,0 +1,10 @@ + +1.0.0 / 2013-01-24 +================== + + * remove lame magical getters + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/callsite/Makefile b/node_modules/callsite/Makefile new file mode 100644 index 0000000..634e372 --- /dev/null +++ b/node_modules/callsite/Makefile @@ -0,0 +1,6 @@ + +test: + @./node_modules/.bin/mocha \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/node_modules/callsite/Readme.md b/node_modules/callsite/Readme.md new file mode 100644 index 0000000..0dbd16a --- /dev/null +++ b/node_modules/callsite/Readme.md @@ -0,0 +1,44 @@ +# callstack + + Access to v8's "raw" `CallSite`s. + +## Installation + + $ npm install callsite + +## Example + +```js +var stack = require('callsite'); + +foo(); + +function foo() { + bar(); +} + +function bar() { + baz(); +} + +function baz() { + console.log(); + stack().forEach(function(site){ + console.log(' \033[36m%s\033[90m in %s:%d\033[0m' + , site.getFunctionName() || 'anonymous' + , site.getFileName() + , site.getLineNumber()); + }); + console.log(); +} +``` + +## Why? + + Because you can do weird, stupid, clever, wacky things such as: + + - [better-assert](https://github.com/visionmedia/better-assert) + +## License + + MIT diff --git a/node_modules/callsite/index.js b/node_modules/callsite/index.js new file mode 100644 index 0000000..d3ee6f8 --- /dev/null +++ b/node_modules/callsite/index.js @@ -0,0 +1,10 @@ + +module.exports = function(){ + var orig = Error.prepareStackTrace; + Error.prepareStackTrace = function(_, stack){ return stack; }; + var err = new Error; + Error.captureStackTrace(err, arguments.callee); + var stack = err.stack; + Error.prepareStackTrace = orig; + return stack; +}; diff --git a/node_modules/callsite/package.json b/node_modules/callsite/package.json new file mode 100644 index 0000000..8b1d4be --- /dev/null +++ b/node_modules/callsite/package.json @@ -0,0 +1,78 @@ +{ + "_args": [ + [ + { + "raw": "callsite@1.0.0", + "scope": null, + "escapedName": "callsite", + "name": "callsite", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\better-assert" + ] + ], + "_from": "callsite@1.0.0", + "_id": "callsite@1.0.0", + "_inCache": true, + "_installable": true, + "_location": "/callsite", + "_npmUser": { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + "_npmVersion": "1.2.2", + "_phantomChildren": {}, + "_requested": { + "raw": "callsite@1.0.0", + "scope": null, + "escapedName": "callsite", + "name": "callsite", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "_requiredBy": [ + "/better-assert" + ], + "_resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "_shasum": "280398e5d664bd74038b6f0905153e6e8af1bc20", + "_shrinkwrap": null, + "_spec": "callsite@1.0.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\better-assert", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "dependencies": {}, + "description": "access to v8's CallSites", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "280398e5d664bd74038b6f0905153e6e8af1bc20", + "tarball": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz" + }, + "engines": { + "node": "*" + }, + "keywords": [ + "stack", + "trace", + "line" + ], + "main": "index", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "name": "callsite", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "version": "1.0.0" +} diff --git a/node_modules/component-bind/.npmignore b/node_modules/component-bind/.npmignore new file mode 100644 index 0000000..f1250e5 --- /dev/null +++ b/node_modules/component-bind/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/node_modules/component-bind/History.md b/node_modules/component-bind/History.md new file mode 100644 index 0000000..2795fdb --- /dev/null +++ b/node_modules/component-bind/History.md @@ -0,0 +1,13 @@ + +1.0.0 / 2014-05-27 +================== + + * index: use slice ref (#7, @viatropos) + * package: rename package to "component-bind" + * package: add "repository" field (#6, @repoify) + * package: add "component" section + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/component-bind/Makefile b/node_modules/component-bind/Makefile new file mode 100644 index 0000000..4e9c8d3 --- /dev/null +++ b/node_modules/component-bind/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec + +.PHONY: test \ No newline at end of file diff --git a/node_modules/component-bind/Readme.md b/node_modules/component-bind/Readme.md new file mode 100644 index 0000000..6a8febc --- /dev/null +++ b/node_modules/component-bind/Readme.md @@ -0,0 +1,64 @@ +# bind + + Function binding utility. + +## Installation + +``` +$ component install component/bind +``` + +## API + + - [bind(obj, fn)](#bindobj-fn) + - [bind(obj, fn, ...)](#bindobj-fn-) + - [bind(obj, name)](#bindobj-name) + + + +### bind(obj, fn) +should bind the function to the given object. + +```js +var tobi = { name: 'tobi' }; + +function name() { + return this.name; +} + +var fn = bind(tobi, name); +fn().should.equal('tobi'); +``` + + +### bind(obj, fn, ...) +should curry the remaining arguments. + +```js +function add(a, b) { + return a + b; +} + +bind(null, add)(1, 2).should.equal(3); +bind(null, add, 1)(2).should.equal(3); +bind(null, add, 1, 2)().should.equal(3); +``` + + +### bind(obj, name) +should bind the method of the given name. + +```js +var tobi = { name: 'tobi' }; + +tobi.getName = function() { + return this.name; +}; + +var fn = bind(tobi, 'getName'); +fn().should.equal('tobi'); +``` + +## License + + MIT \ No newline at end of file diff --git a/node_modules/component-bind/component.json b/node_modules/component-bind/component.json new file mode 100644 index 0000000..4e1e93f --- /dev/null +++ b/node_modules/component-bind/component.json @@ -0,0 +1,13 @@ +{ + "name": "bind", + "version": "1.0.0", + "description": "function binding utility", + "keywords": [ + "bind", + "utility" + ], + "dependencies": {}, + "scripts": [ + "index.js" + ] +} diff --git a/node_modules/component-bind/index.js b/node_modules/component-bind/index.js new file mode 100644 index 0000000..4eeb2c0 --- /dev/null +++ b/node_modules/component-bind/index.js @@ -0,0 +1,23 @@ +/** + * Slice reference. + */ + +var slice = [].slice; + +/** + * Bind `obj` to `fn`. + * + * @param {Object} obj + * @param {Function|String} fn or string + * @return {Function} + * @api public + */ + +module.exports = function(obj, fn){ + if ('string' == typeof fn) fn = obj[fn]; + if ('function' != typeof fn) throw new Error('bind() requires a function'); + var args = slice.call(arguments, 2); + return function(){ + return fn.apply(obj, args.concat(slice.call(arguments))); + } +}; diff --git a/node_modules/component-bind/package.json b/node_modules/component-bind/package.json new file mode 100644 index 0000000..37ca9e7 --- /dev/null +++ b/node_modules/component-bind/package.json @@ -0,0 +1,82 @@ +{ + "_args": [ + [ + { + "raw": "component-bind@1.0.0", + "scope": null, + "escapedName": "component-bind", + "name": "component-bind", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-client" + ] + ], + "_from": "component-bind@1.0.0", + "_id": "component-bind@1.0.0", + "_inCache": true, + "_installable": true, + "_location": "/component-bind", + "_npmUser": { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "raw": "component-bind@1.0.0", + "scope": null, + "escapedName": "component-bind", + "name": "component-bind", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "_requiredBy": [ + "/socket.io-client" + ], + "_resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "_shasum": "00c608ab7dcd93897c0009651b1d3a8e1e73bbd1", + "_shrinkwrap": null, + "_spec": "component-bind@1.0.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-client", + "bugs": { + "url": "https://github.com/component/bind/issues" + }, + "component": { + "scripts": { + "bind/index.js": "index.js" + } + }, + "dependencies": {}, + "description": "function binding utility", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "00c608ab7dcd93897c0009651b1d3a8e1e73bbd1", + "tarball": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz" + }, + "homepage": "https://github.com/component/bind", + "keywords": [ + "bind", + "utility" + ], + "maintainers": [ + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + } + ], + "name": "component-bind", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/component/bind.git" + }, + "version": "1.0.0" +} diff --git a/node_modules/component-emitter/.npmignore b/node_modules/component-emitter/.npmignore new file mode 100644 index 0000000..f05b1f2 --- /dev/null +++ b/node_modules/component-emitter/.npmignore @@ -0,0 +1,2 @@ +node_modules +test diff --git a/node_modules/component-emitter/.travis.yml b/node_modules/component-emitter/.travis.yml new file mode 100644 index 0000000..8750e3b --- /dev/null +++ b/node_modules/component-emitter/.travis.yml @@ -0,0 +1,4 @@ +node_js: +- "0.8" +- "0.10" +language: node_js \ No newline at end of file diff --git a/node_modules/component-emitter/History.md b/node_modules/component-emitter/History.md new file mode 100644 index 0000000..b898ca6 --- /dev/null +++ b/node_modules/component-emitter/History.md @@ -0,0 +1,52 @@ + +1.1.2 / 2014-02-10 +================== + + * package: rename to "component-emitter" + * package: update "main" and "component" fields + * Add license to Readme (same format as the other components) + * created .npmignore + * travis stuff + +1.1.1 / 2013-12-01 +================== + + * fix .once adding .on to the listener + * docs: Emitter#off() + * component: add `.repo` prop + +1.1.0 / 2013-10-20 +================== + + * add `.addEventListener()` and `.removeEventListener()` aliases + +1.0.1 / 2013-06-27 +================== + + * add support for legacy ie + +1.0.0 / 2013-02-26 +================== + + * add `.off()` support for removing all listeners + +0.0.6 / 2012-10-08 +================== + + * add `this._callbacks` initialization to prevent funky gotcha + +0.0.5 / 2012-09-07 +================== + + * fix `Emitter.call(this)` usage + +0.0.3 / 2012-07-11 +================== + + * add `.listeners()` + * rename `.has()` to `.hasListeners()` + +0.0.2 / 2012-06-28 +================== + + * fix `.off()` with `.once()`-registered callbacks diff --git a/node_modules/component-emitter/Makefile b/node_modules/component-emitter/Makefile new file mode 100644 index 0000000..4e9c8d3 --- /dev/null +++ b/node_modules/component-emitter/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec + +.PHONY: test \ No newline at end of file diff --git a/node_modules/component-emitter/Readme.md b/node_modules/component-emitter/Readme.md new file mode 100644 index 0000000..0f3f9b9 --- /dev/null +++ b/node_modules/component-emitter/Readme.md @@ -0,0 +1,74 @@ +# Emitter [![Build Status](https://travis-ci.org/component/emitter.png)](https://travis-ci.org/component/emitter) + + Event emitter component. + +## Installation + +``` +$ component install component/emitter +``` + +## API + +### Emitter(obj) + + The `Emitter` may also be used as a mixin. For example + a "plain" object may become an emitter, or you may + extend an existing prototype. + + As an `Emitter` instance: + +```js +var Emitter = require('emitter'); +var emitter = new Emitter; +emitter.emit('something'); +``` + + As a mixin: + +```js +var Emitter = require('emitter'); +var user = { name: 'tobi' }; +Emitter(user); + +user.emit('im a user'); +``` + + As a prototype mixin: + +```js +var Emitter = require('emitter'); +Emitter(User.prototype); +``` + +### Emitter#on(event, fn) + + Register an `event` handler `fn`. + +### Emitter#once(event, fn) + + Register a single-shot `event` handler `fn`, + removed immediately after it is invoked the + first time. + +### Emitter#off(event, fn) + + * Pass `event` and `fn` to remove a listener. + * Pass `event` to remove all listeners on that event. + * Pass nothing to remove all listeners on all events. + +### Emitter#emit(event, ...) + + Emit an `event` with variable option args. + +### Emitter#listeners(event) + + Return an array of callbacks, or an empty array. + +### Emitter#hasListeners(event) + + Check if this emitter has `event` handlers. + +## License + +MIT diff --git a/node_modules/component-emitter/bower.json b/node_modules/component-emitter/bower.json new file mode 100644 index 0000000..c618d41 --- /dev/null +++ b/node_modules/component-emitter/bower.json @@ -0,0 +1,21 @@ +{ + "name": "emitter", + "description": "Event emitter", + "keywords": [ + "emitter", + "events" + ], + "version": "1.1.2", + "license": "MIT", + "main": "index.js", + "homepage": "https://github.com/component/emitter", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "Makefile", + "package.json", + "component.json" + ] +} diff --git a/node_modules/component-emitter/component.json b/node_modules/component-emitter/component.json new file mode 100644 index 0000000..68ba0b1 --- /dev/null +++ b/node_modules/component-emitter/component.json @@ -0,0 +1,14 @@ +{ + "name": "emitter", + "repo": "component/emitter", + "description": "Event emitter", + "keywords": [ + "emitter", + "events" + ], + "version": "1.1.2", + "scripts": [ + "index.js" + ], + "license": "MIT" +} diff --git a/node_modules/component-emitter/index.js b/node_modules/component-emitter/index.js new file mode 100644 index 0000000..ad71163 --- /dev/null +++ b/node_modules/component-emitter/index.js @@ -0,0 +1,164 @@ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; diff --git a/node_modules/component-emitter/package.json b/node_modules/component-emitter/package.json new file mode 100644 index 0000000..81a33ea --- /dev/null +++ b/node_modules/component-emitter/package.json @@ -0,0 +1,84 @@ +{ + "_args": [ + [ + { + "raw": "component-emitter@1.1.2", + "scope": null, + "escapedName": "component-emitter", + "name": "component-emitter", + "rawSpec": "1.1.2", + "spec": "1.1.2", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-adapter\\node_modules\\socket.io-parser" + ] + ], + "_from": "component-emitter@1.1.2", + "_id": "component-emitter@1.1.2", + "_inCache": true, + "_installable": true, + "_location": "/component-emitter", + "_npmUser": { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "raw": "component-emitter@1.1.2", + "scope": null, + "escapedName": "component-emitter", + "name": "component-emitter", + "rawSpec": "1.1.2", + "spec": "1.1.2", + "type": "version" + }, + "_requiredBy": [ + "/engine.io-client", + "/socket.io-adapter/socket.io-parser", + "/socket.io-parser" + ], + "_resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "_shasum": "296594f2753daa63996d2af08d15a95116c9aec3", + "_shrinkwrap": null, + "_spec": "component-emitter@1.1.2", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\socket.io-adapter\\node_modules\\socket.io-parser", + "bugs": { + "url": "https://github.com/component/emitter/issues" + }, + "component": { + "scripts": { + "emitter/index.js": "index.js" + } + }, + "dependencies": {}, + "description": "Event emitter", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "296594f2753daa63996d2af08d15a95116c9aec3", + "tarball": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz" + }, + "homepage": "https://github.com/component/emitter", + "main": "index.js", + "maintainers": [ + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + } + ], + "name": "component-emitter", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/component/emitter.git" + }, + "scripts": { + "test": "make test" + }, + "version": "1.1.2" +} diff --git a/node_modules/component-inherit/.npmignore b/node_modules/component-inherit/.npmignore new file mode 100644 index 0000000..665aa21 --- /dev/null +++ b/node_modules/component-inherit/.npmignore @@ -0,0 +1,3 @@ +components +build +node_modules diff --git a/node_modules/component-inherit/History.md b/node_modules/component-inherit/History.md new file mode 100644 index 0000000..22d87e1 --- /dev/null +++ b/node_modules/component-inherit/History.md @@ -0,0 +1,5 @@ + +0.0.2 / 2012-09-03 +================== + + * fix typo in package.json diff --git a/node_modules/component-inherit/Makefile b/node_modules/component-inherit/Makefile new file mode 100644 index 0000000..ebbc52a --- /dev/null +++ b/node_modules/component-inherit/Makefile @@ -0,0 +1,16 @@ + +build: components index.js + @component build + +components: + @Component install + +clean: + rm -fr build components template.js + +test: + @node_modules/.bin/mocha \ + --require should \ + --reporter spec + +.PHONY: clean test diff --git a/node_modules/component-inherit/Readme.md b/node_modules/component-inherit/Readme.md new file mode 100644 index 0000000..f03ab27 --- /dev/null +++ b/node_modules/component-inherit/Readme.md @@ -0,0 +1,24 @@ +# inherit + + Prototype inheritance utility. + +## Installation + +``` +$ component install component/inherit +``` + +## Example + +```js +var inherit = require('inherit'); + +function Human() {} +function Woman() {} + +inherit(Woman, Human); +``` + +## License + + MIT diff --git a/node_modules/component-inherit/component.json b/node_modules/component-inherit/component.json new file mode 100644 index 0000000..ae57747 --- /dev/null +++ b/node_modules/component-inherit/component.json @@ -0,0 +1,10 @@ +{ + "name": "inherit", + "description": "Prototype inheritance utility", + "version": "0.0.3", + "keywords": ["inherit", "utility"], + "dependencies": {}, + "scripts": [ + "index.js" + ] +} diff --git a/node_modules/component-inherit/index.js b/node_modules/component-inherit/index.js new file mode 100644 index 0000000..aaebc03 --- /dev/null +++ b/node_modules/component-inherit/index.js @@ -0,0 +1,7 @@ + +module.exports = function(a, b){ + var fn = function(){}; + fn.prototype = b.prototype; + a.prototype = new fn; + a.prototype.constructor = a; +}; \ No newline at end of file diff --git a/node_modules/component-inherit/package.json b/node_modules/component-inherit/package.json new file mode 100644 index 0000000..0bf48b4 --- /dev/null +++ b/node_modules/component-inherit/package.json @@ -0,0 +1,79 @@ +{ + "_args": [ + [ + { + "raw": "component-inherit@0.0.3", + "scope": null, + "escapedName": "component-inherit", + "name": "component-inherit", + "rawSpec": "0.0.3", + "spec": "0.0.3", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-client" + ] + ], + "_from": "component-inherit@0.0.3", + "_id": "component-inherit@0.0.3", + "_inCache": true, + "_installable": true, + "_location": "/component-inherit", + "_npmUser": { + "name": "coreh", + "email": "thecoreh@gmail.com" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "raw": "component-inherit@0.0.3", + "scope": null, + "escapedName": "component-inherit", + "name": "component-inherit", + "rawSpec": "0.0.3", + "spec": "0.0.3", + "type": "version" + }, + "_requiredBy": [ + "/engine.io-client" + ], + "_resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "_shasum": "645fc4adf58b72b649d5cae65135619db26ff143", + "_shrinkwrap": null, + "_spec": "component-inherit@0.0.3", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\engine.io-client", + "bugs": { + "url": "https://github.com/component/inherit/issues" + }, + "component": { + "scripts": { + "inherit/index.js": "index.js" + } + }, + "dependencies": {}, + "description": "Prototype inheritance utility", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "645fc4adf58b72b649d5cae65135619db26ff143", + "tarball": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz" + }, + "homepage": "https://github.com/component/inherit", + "keywords": [ + "inherit", + "utility" + ], + "maintainers": [ + { + "name": "coreh", + "email": "thecoreh@gmail.com" + } + ], + "name": "component-inherit", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/component/inherit.git" + }, + "version": "0.0.3" +} diff --git a/node_modules/component-inherit/test/inherit.js b/node_modules/component-inherit/test/inherit.js new file mode 100644 index 0000000..14852f2 --- /dev/null +++ b/node_modules/component-inherit/test/inherit.js @@ -0,0 +1,21 @@ + +/** + * Module dependencies. + */ + +var inherit = require('..'); + +describe('inherit(a, b)', function(){ + it('should inherit b\'s prototype', function(){ + function Loki(){} + function Animal(){} + + Animal.prototype.species = 'unknown'; + + inherit(Loki, Animal); + + var loki = new Loki; + loki.species.should.equal('unknown'); + loki.constructor.should.equal(Loki); + }) +}) \ No newline at end of file diff --git a/node_modules/connect/History.md b/node_modules/connect/History.md new file mode 100644 index 0000000..ade42d6 --- /dev/null +++ b/node_modules/connect/History.md @@ -0,0 +1,2407 @@ +3.4.1 / 2016-01-23 +================== + + * deps: finalhandler@0.4.1 + - deps: escape-html@~1.0.3 + * deps: parseurl@~1.3.1 + - perf: enable strict mode + +3.4.0 / 2015-06-18 +================== + + * deps: debug@~2.2.0 + - deps: ms@0.7.1 + * deps: finalhandler@0.4.0 + - Fix a false-positive when unpiping in Node.js 0.8 + - Support `statusCode` property on `Error` objects + - Use `unpipe` module for unpiping requests + - deps: debug@~2.2.0 + - deps: escape-html@1.0.2 + - deps: on-finished@~2.3.0 + - perf: enable strict mode + - perf: remove argument reassignment + * perf: enable strict mode + * perf: remove argument reassignments + +3.3.5 / 2015-03-16 +================== + + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + * deps: finalhandler@0.3.4 + - deps: debug@~2.1.3 + +3.3.4 / 2015-01-07 +================== + + * deps: debug@~2.1.1 + * deps: finalhandler@0.3.3 + - deps: debug@~2.1.1 + - deps: on-finished@~2.2.0 + +3.3.3 / 2014-11-09 +================== + + * Correctly invoke async callback asynchronously + +3.3.2 / 2014-10-28 +================== + + * Fix handling of URLs containing `://` in the path + +3.3.1 / 2014-10-22 +================== + + * deps: finalhandler@0.3.2 + - deps: on-finished@~2.1.1 + +3.3.0 / 2014-10-17 +================== + + * deps: debug@~2.1.0 + - Implement `DEBUG_FD` env variable support + * deps: finalhandler@0.3.1 + - Terminate in progress response only on error + - Use `on-finished` to determine request status + - deps: debug@~2.1.0 + +3.2.0 / 2014-09-08 +================== + + * deps: debug@~2.0.0 + * deps: finalhandler@0.2.0 + - Set `X-Content-Type-Options: nosniff` header + - deps: debug@~2.0.0 + +3.1.1 / 2014-08-10 +================== + + * deps: parseurl@~1.3.0 + +3.1.0 / 2014-07-22 +================== + + * deps: debug@1.0.4 + * deps: finalhandler@0.1.0 + - Respond after request fully read + - deps: debug@1.0.4 + * deps: parseurl@~1.2.0 + - Cache URLs based on original value + - Remove no-longer-needed URL mis-parse work-around + - Simplify the "fast-path" `RegExp` + * perf: reduce executed logic in routing + * perf: refactor location of `try` block + +3.0.2 / 2014-07-10 +================== + + * deps: debug@1.0.3 + - Add support for multiple wildcards in namespaces + * deps: parseurl@~1.1.3 + - faster parsing of href-only URLs + +3.0.1 / 2014-06-19 +================== + + * use `finalhandler` for final response handling + * deps: debug@1.0.2 + +3.0.0 / 2014-05-29 +================== + + * No changes + +3.0.0-rc.2 / 2014-05-04 +======================= + + * Call error stack even when response has been sent + * Prevent default 404 handler after response sent + * dep: debug@0.8.1 + * encode stack in HTML for default error handler + * remove `proto` export + +3.0.0-rc.1 / 2014-03-06 +======================= + + * move middleware to separate repos + * remove docs + * remove node patches + * remove connect(middleware...) + * remove the old `connect.createServer()` method + * remove various private `connect.utils` functions + * drop node.js 0.8 support + +2.30.2 / 2015-07-31 +=================== + + * deps: body-parser@~1.13.3 + - deps: type-is@~1.6.6 + * deps: compression@~1.5.2 + - deps: accepts@~1.2.12 + - deps: compressible@~2.0.5 + - deps: vary@~1.0.1 + * deps: errorhandler@~1.4.2 + - deps: accepts@~1.2.12 + * deps: method-override@~2.3.5 + - deps: vary@~1.0.1 + - perf: enable strict mode + * deps: serve-index@~1.7.2 + - deps: accepts@~1.2.12 + - deps: mime-types@~2.1.4 + * deps: type-is@~1.6.6 + - deps: mime-types@~2.1.4 + * deps: vhost@~3.0.1 + - perf: enable strict mode + +2.30.1 / 2015-07-05 +=================== + + * deps: body-parser@~1.13.2 + - deps: iconv-lite@0.4.11 + - deps: qs@4.0.0 + - deps: raw-body@~2.1.2 + - deps: type-is@~1.6.4 + * deps: compression@~1.5.1 + - deps: accepts@~1.2.10 + - deps: compressible@~2.0.4 + * deps: errorhandler@~1.4.1 + - deps: accepts@~1.2.10 + * deps: qs@4.0.0 + - Fix dropping parameters like `hasOwnProperty` + - Fix various parsing edge cases + * deps: morgan@~1.6.1 + - deps: basic-auth@~1.0.3 + * deps: pause@0.1.0 + - Re-emit events with all original arguments + - Refactor internals + - perf: enable strict mode + * deps: serve-index@~1.7.1 + - deps: accepts@~1.2.10 + - deps: mime-types@~2.1.2 + * deps: type-is@~1.6.4 + - deps: mime-types@~2.1.2 + - perf: enable strict mode + - perf: remove argument reassignment + +2.30.0 / 2015-06-18 +=================== + + * deps: body-parser@~1.13.1 + - Add `statusCode` property on `Error`s, in addition to `status` + - Change `type` default to `application/json` for JSON parser + - Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser + - Provide static `require` analysis + - Use the `http-errors` module to generate errors + - deps: bytes@2.1.0 + - deps: iconv-lite@0.4.10 + - deps: on-finished@~2.3.0 + - deps: raw-body@~2.1.1 + - deps: type-is@~1.6.3 + - perf: enable strict mode + - perf: remove argument reassignment + - perf: remove delete call + * deps: bytes@2.1.0 + - Slight optimizations + - Units no longer case sensitive when parsing + * deps: compression@~1.5.0 + - Fix return value from `.end` and `.write` after end + - Improve detection of zero-length body without `Content-Length` + - deps: accepts@~1.2.9 + - deps: bytes@2.1.0 + - deps: compressible@~2.0.3 + - perf: enable strict mode + - perf: remove flush reassignment + - perf: simplify threshold detection + * deps: cookie@0.1.3 + - Slight optimizations + * deps: cookie-parser@~1.3.5 + - deps: cookie@0.1.3 + * deps: csurf@~1.8.3 + - Add `sessionKey` option + - deps: cookie@0.1.3 + - deps: csrf@~3.0.0 + * deps: errorhandler@~1.4.0 + - Add charset to the `Content-Type` header + - Support `statusCode` property on `Error` objects + - deps: accepts@~1.2.9 + - deps: escape-html@1.0.2 + * deps: express-session@~1.11.3 + - Support an array in `secret` option for key rotation + - deps: cookie@0.1.3 + - deps: crc@3.3.0 + - deps: debug@~2.2.0 + - deps: depd@~1.0.1 + - deps: uid-safe@~2.0.0 + * deps: finalhandler@0.4.0 + - Fix a false-positive when unpiping in Node.js 0.8 + - Support `statusCode` property on `Error` objects + - Use `unpipe` module for unpiping requests + - deps: escape-html@1.0.2 + - deps: on-finished@~2.3.0 + - perf: enable strict mode + - perf: remove argument reassignment + * deps: fresh@0.3.0 + - Add weak `ETag` matching support + * deps: morgan@~1.6.0 + - Add `morgan.compile(format)` export + - Do not color 1xx status codes in `dev` format + - Fix `response-time` token to not include response latency + - Fix `status` token incorrectly displaying before response in `dev` format + - Fix token return values to be `undefined` or a string + - Improve representation of multiple headers in `req` and `res` tokens + - Use `res.getHeader` in `res` token + - deps: basic-auth@~1.0.2 + - deps: on-finished@~2.3.0 + - pref: enable strict mode + - pref: reduce function closure scopes + - pref: remove dynamic compile on every request for `dev` format + - pref: remove an argument reassignment + - pref: skip function call without `skip` option + * deps: serve-favicon@~2.3.0 + - Send non-chunked response for `OPTIONS` + - deps: etag@~1.7.0 + - deps: fresh@0.3.0 + - perf: enable strict mode + - perf: remove argument reassignment + - perf: remove bitwise operations + * deps: serve-index@~1.7.0 + - Accept `function` value for `template` option + - Send non-chunked response for `OPTIONS` + - Stat parent directory when necessary + - Use `Date.prototype.toLocaleDateString` to format date + - deps: accepts@~1.2.9 + - deps: escape-html@1.0.2 + - deps: mime-types@~2.1.1 + - perf: enable strict mode + - perf: remove argument reassignment + * deps: serve-static@~1.10.0 + - Add `fallthrough` option + - Fix reading options from options prototype + - Improve the default redirect response headers + - Malformed URLs now `next()` instead of 400 + - deps: escape-html@1.0.2 + - deps: send@0.13.0 + - perf: enable strict mode + - perf: remove argument reassignment + * deps: type-is@~1.6.3 + - deps: mime-types@~2.1.1 + - perf: reduce try block size + - perf: remove bitwise operations + +2.29.2 / 2015-05-14 +=================== + + * deps: body-parser@~1.12.4 + - Slight efficiency improvement when not debugging + - deps: debug@~2.2.0 + - deps: depd@~1.0.1 + - deps: iconv-lite@0.4.8 + - deps: on-finished@~2.2.1 + - deps: qs@2.4.2 + - deps: raw-body@~2.0.1 + - deps: type-is@~1.6.2 + * deps: compression@~1.4.4 + - deps: accepts@~1.2.7 + - deps: debug@~2.2.0 + * deps: connect-timeout@~1.6.2 + - deps: debug@~2.2.0 + - deps: ms@0.7.1 + * deps: debug@~2.2.0 + - deps: ms@0.7.1 + * deps: depd@~1.0.1 + * deps: errorhandler@~1.3.6 + - deps: accepts@~1.2.7 + * deps: finalhandler@0.3.6 + - deps: debug@~2.2.0 + - deps: on-finished@~2.2.1 + * deps: method-override@~2.3.3 + - deps: debug@~2.2.0 + * deps: morgan@~1.5.3 + - deps: basic-auth@~1.0.1 + - deps: debug@~2.2.0 + - deps: depd@~1.0.1 + - deps: on-finished@~2.2.1 + * deps: qs@2.4.2 + - Fix allowing parameters like `constructor` + * deps: response-time@~2.3.1 + - deps: depd@~1.0.1 + * deps: serve-favicon@~2.2.1 + - deps: etag@~1.6.0 + - deps: ms@0.7.1 + * deps: serve-index@~1.6.4 + - deps: accepts@~1.2.7 + - deps: debug@~2.2.0 + - deps: mime-types@~2.0.11 + * deps: serve-static@~1.9.3 + - deps: send@0.12.3 + * deps: type-is@~1.6.2 + - deps: mime-types@~2.0.11 + +2.29.1 / 2015-03-16 +=================== + + * deps: body-parser@~1.12.2 + - deps: debug@~2.1.3 + - deps: qs@2.4.1 + - deps: type-is@~1.6.1 + * deps: compression@~1.4.3 + - Fix error when code calls `res.end(str, encoding)` + - deps: accepts@~1.2.5 + - deps: debug@~2.1.3 + * deps: connect-timeout@~1.6.1 + - deps: debug@~2.1.3 + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + * deps: errorhandler@~1.3.5 + - deps: accepts@~1.2.5 + * deps: express-session@~1.10.4 + - deps: debug@~2.1.3 + * deps: finalhandler@0.3.4 + - deps: debug@~2.1.3 + * deps: method-override@~2.3.2 + - deps: debug@~2.1.3 + * deps: morgan@~1.5.2 + - deps: debug@~2.1.3 + * deps: qs@2.4.1 + - Fix error when parameter `hasOwnProperty` is present + * deps: serve-index@~1.6.3 + - Properly escape file names in HTML + - deps: accepts@~1.2.5 + - deps: debug@~2.1.3 + - deps: escape-html@1.0.1 + - deps: mime-types@~2.0.10 + * deps: serve-static@~1.9.2 + - deps: send@0.12.2 + * deps: type-is@~1.6.1 + - deps: mime-types@~2.0.10 + +2.29.0 / 2015-02-17 +=================== + + * Use `content-type` to parse `Content-Type` headers + * deps: body-parser@~1.12.0 + - add `debug` messages + - accept a function for the `type` option + - make internal `extended: true` depth limit infinity + - use `content-type` to parse `Content-Type` headers + - deps: iconv-lite@0.4.7 + - deps: raw-body@1.3.3 + - deps: type-is@~1.6.0 + * deps: compression@~1.4.1 + - Prefer `gzip` over `deflate` on the server + - deps: accepts@~1.2.4 + * deps: connect-timeout@~1.6.0 + - deps: http-errors@~1.3.1 + * deps: cookie-parser@~1.3.4 + - deps: cookie-signature@1.0.6 + * deps: cookie-signature@1.0.6 + * deps: csurf@~1.7.0 + - Accept `CSRF-Token` and `XSRF-Token` request headers + - Default `cookie.path` to `'/'`, if using cookies + - deps: cookie-signature@1.0.6 + - deps: csrf@~2.0.6 + - deps: http-errors@~1.3.1 + * deps: errorhandler@~1.3.4 + - deps: accepts@~1.2.4 + * deps: express-session@~1.10.3 + - deps: cookie-signature@1.0.6 + - deps: uid-safe@1.1.0 + * deps: http-errors@~1.3.1 + - Construct errors using defined constructors from `createError` + - Fix error names that are not identifiers + - Set a meaningful `name` property on constructed errors + * deps: response-time@~2.3.0 + - Add function argument to support recording of response time + * deps: serve-index@~1.6.2 + - deps: accepts@~1.2.4 + - deps: http-errors@~1.3.1 + - deps: mime-types@~2.0.9 + * deps: serve-static@~1.9.1 + - deps: send@0.12.1 + * deps: type-is@~1.6.0 + - fix argument reassignment + - fix false-positives in `hasBody` `Transfer-Encoding` check + - support wildcard for both type and subtype (`*/*`) + - deps: mime-types@~2.0.9 + +2.28.3 / 2015-01-31 +=================== + + * deps: compression@~1.3.1 + - deps: accepts@~1.2.3 + - deps: compressible@~2.0.2 + * deps: csurf@~1.6.6 + - deps: csrf@~2.0.5 + * deps: errorhandler@~1.3.3 + - deps: accepts@~1.2.3 + * deps: express-session@~1.10.2 + - deps: uid-safe@1.0.3 + * deps: serve-index@~1.6.1 + - deps: accepts@~1.2.3 + - deps: mime-types@~2.0.8 + * deps: type-is@~1.5.6 + - deps: mime-types@~2.0.8 + +2.28.2 / 2015-01-20 +=================== + + * deps: body-parser@~1.10.2 + - deps: iconv-lite@0.4.6 + - deps: raw-body@1.3.2 + * deps: serve-static@~1.8.1 + - Fix redirect loop in Node.js 0.11.14 + - Fix root path disclosure + - deps: send@0.11.1 + +2.28.1 / 2015-01-08 +=================== + + * deps: csurf@~1.6.5 + - deps: csrf@~2.0.4 + * deps: express-session@~1.10.1 + - deps: uid-safe@~1.0.2 + +2.28.0 / 2015-01-05 +=================== + + * deps: body-parser@~1.10.1 + - Make internal `extended: true` array limit dynamic + - deps: on-finished@~2.2.0 + - deps: type-is@~1.5.5 + * deps: compression@~1.3.0 + - Export the default `filter` function for wrapping + - deps: accepts@~1.2.2 + - deps: debug@~2.1.1 + * deps: connect-timeout@~1.5.0 + - deps: debug@~2.1.1 + - deps: http-errors@~1.2.8 + - deps: ms@0.7.0 + * deps: csurf@~1.6.4 + - deps: csrf@~2.0.3 + - deps: http-errors@~1.2.8 + * deps: debug@~2.1.1 + * deps: errorhandler@~1.3.2 + - Add `log` option + - Fix heading content to not include stack + - deps: accepts@~1.2.2 + * deps: express-session@~1.10.0 + - Add `store.touch` interface for session stores + - Fix `MemoryStore` expiration with `resave: false` + - deps: debug@~2.1.1 + * deps: finalhandler@0.3.3 + - deps: debug@~2.1.1 + - deps: on-finished@~2.2.0 + * deps: method-override@~2.3.1 + - deps: debug@~2.1.1 + - deps: methods@~1.1.1 + * deps: morgan@~1.5.1 + - Add multiple date formats `clf`, `iso`, and `web` + - Deprecate `buffer` option + - Fix date format in `common` and `combined` formats + - Fix token arguments to accept values with `"` + - deps: debug@~2.1.1 + - deps: on-finished@~2.2.0 + * deps: serve-favicon@~2.2.0 + - Support query string in the URL + - deps: etag@~1.5.1 + - deps: ms@0.7.0 + * deps: serve-index@~1.6.0 + - Add link to root directory + - deps: accepts@~1.2.2 + - deps: batch@0.5.2 + - deps: debug@~2.1.1 + - deps: mime-types@~2.0.7 + * deps: serve-static@~1.8.0 + - Fix potential open redirect when mounted at root + - deps: send@0.11.0 + * deps: type-is@~1.5.5 + - deps: mime-types@~2.0.7 + +2.27.6 / 2014-12-10 +=================== + + * deps: serve-index@~1.5.3 + - deps: accepts@~1.1.4 + - deps: http-errors@~1.2.8 + - deps: mime-types@~2.0.4 + +2.27.5 / 2014-12-10 +=================== + + * deps: compression@~1.2.2 + - Fix `.end` to only proxy to `.end` + - deps: accepts@~1.1.4 + * deps: express-session@~1.9.3 + - Fix error when `req.sessionID` contains a non-string value + * deps: http-errors@~1.2.8 + - Fix stack trace from exported function + - Remove `arguments.callee` usage + * deps: serve-index@~1.5.2 + - Fix icon name background alignment on mobile view + * deps: type-is@~1.5.4 + - deps: mime-types@~2.0.4 + +2.27.4 / 2014-11-23 +=================== + + * deps: body-parser@~1.9.3 + - deps: iconv-lite@0.4.5 + - deps: qs@2.3.3 + - deps: raw-body@1.3.1 + - deps: type-is@~1.5.3 + * deps: compression@~1.2.1 + - deps: accepts@~1.1.3 + * deps: errorhandler@~1.2.3 + - deps: accepts@~1.1.3 + * deps: express-session@~1.9.2 + - deps: crc@3.2.1 + * deps: qs@2.3.3 + - Fix `arrayLimit` behavior + * deps: serve-favicon@~2.1.7 + - Avoid errors from enumerables on `Object.prototype` + * deps: serve-index@~1.5.1 + - deps: accepts@~1.1.3 + - deps: mime-types@~2.0.3 + * deps: type-is@~1.5.3 + - deps: mime-types@~2.0.3 + +2.27.3 / 2014-11-09 +=================== + + * Correctly invoke async callback asynchronously + * deps: csurf@~1.6.3 + - bump csrf + - bump http-errors + +2.27.2 / 2014-10-28 +=================== + + * Fix handling of URLs containing `://` in the path + * deps: body-parser@~1.9.2 + - deps: qs@2.3.2 + * deps: qs@2.3.2 + - Fix parsing of mixed objects and values + +2.27.1 / 2014-10-22 +=================== + + * deps: body-parser@~1.9.1 + - deps: on-finished@~2.1.1 + - deps: qs@2.3.0 + - deps: type-is@~1.5.2 + * deps: express-session@~1.9.1 + - Remove unnecessary empty write call + * deps: finalhandler@0.3.2 + - deps: on-finished@~2.1.1 + * deps: morgan@~1.4.1 + - deps: on-finished@~2.1.1 + * deps: qs@2.3.0 + - Fix parsing of mixed implicit and explicit arrays + * deps: serve-static@~1.7.1 + - deps: send@0.10.1 + +2.27.0 / 2014-10-16 +=================== + + * Use `http-errors` module for creating errors + * Use `utils-merge` module for merging objects + * deps: body-parser@~1.9.0 + - include the charset in "unsupported charset" error message + - include the encoding in "unsupported content encoding" error message + - deps: depd@~1.0.0 + * deps: compression@~1.2.0 + - deps: debug@~2.1.0 + * deps: connect-timeout@~1.4.0 + - Create errors with `http-errors` + - deps: debug@~2.1.0 + * deps: debug@~2.1.0 + - Implement `DEBUG_FD` env variable support + * deps: depd@~1.0.0 + * deps: express-session@~1.9.0 + - deps: debug@~2.1.0 + - deps: depd@~1.0.0 + * deps: finalhandler@0.3.1 + - Terminate in progress response only on error + - Use `on-finished` to determine request status + - deps: debug@~2.1.0 + * deps: method-override@~2.3.0 + - deps: debug@~2.1.0 + * deps: morgan@~1.4.0 + - Add `debug` messages + - deps: depd@~1.0.0 + * deps: response-time@~2.2.0 + - Add `header` option for custom header name + - Add `suffix` option + - Change `digits` argument to an `options` argument + - deps: depd@~1.0.0 + * deps: serve-favicon@~2.1.6 + - deps: etag@~1.5.0 + * deps: serve-index@~1.5.0 + - Add `dir` argument to `filter` function + - Add icon for mkv files + - Create errors with `http-errors` + - Fix incorrect 403 on Windows and Node.js 0.11 + - Lookup icon by mime type for greater icon support + - Support using tokens multiple times + - deps: accepts@~1.1.2 + - deps: debug@~2.1.0 + - deps: mime-types@~2.0.2 + * deps: serve-static@~1.7.0 + - deps: send@0.10.0 + +2.26.6 / 2014-10-15 +=================== + + * deps: compression@~1.1.2 + - deps: accepts@~1.1.2 + - deps: compressible@~2.0.1 + * deps: csurf@~1.6.2 + - bump http-errors + - fix cookie name when using `cookie: true` + * deps: errorhandler@~1.2.2 + - deps: accepts@~1.1.2 + +2.26.5 / 2014-10-08 +=================== + + * Fix accepting non-object arguments to `logger` + * deps: serve-static@~1.6.4 + - Fix redirect loop when index file serving disabled + +2.26.4 / 2014-10-02 +=================== + + * deps: morgan@~1.3.2 + - Fix `req.ip` integration when `immediate: false` + * deps: type-is@~1.5.2 + - deps: mime-types@~2.0.2 + +2.26.3 / 2014-09-24 +=================== + + * deps: body-parser@~1.8.4 + - fix content encoding to be case-insensitive + * deps: serve-favicon@~2.1.5 + - deps: etag@~1.4.0 + * deps: serve-static@~1.6.3 + - deps: send@0.9.3 + +2.26.2 / 2014-09-19 +=================== + + * deps: body-parser@~1.8.3 + - deps: qs@2.2.4 + * deps: qs@2.2.4 + - Fix issue with object keys starting with numbers truncated + +2.26.1 / 2014-09-15 +=================== + + * deps: body-parser@~1.8.2 + - deps: depd@0.4.5 + * deps: depd@0.4.5 + * deps: express-session@~1.8.2 + - Use `crc` instead of `buffer-crc32` for speed + - deps: depd@0.4.5 + * deps: morgan@~1.3.1 + - Remove un-used `bytes` dependency + - deps: depd@0.4.5 + * deps: serve-favicon@~2.1.4 + - Fix content headers being sent in 304 response + - deps: etag@~1.3.1 + * deps: serve-static@~1.6.2 + - deps: send@0.9.2 + +2.26.0 / 2014-09-08 +=================== + + * deps: body-parser@~1.8.1 + - add `parameterLimit` option to `urlencoded` parser + - change `urlencoded` extended array limit to 100 + - make empty-body-handling consistent between chunked requests + - respond with 415 when over `parameterLimit` in `urlencoded` + - deps: media-typer@0.3.0 + - deps: qs@2.2.3 + - deps: type-is@~1.5.1 + * deps: compression@~1.1.0 + - deps: accepts@~1.1.0 + - deps: compressible@~2.0.0 + - deps: debug@~2.0.0 + * deps: connect-timeout@~1.3.0 + - deps: debug@~2.0.0 + * deps: cookie-parser@~1.3.3 + - deps: cookie-signature@1.0.5 + * deps: cookie-signature@1.0.5 + * deps: csurf@~1.6.1 + - add `ignoreMethods` option + - bump cookie-signature + - csrf-tokens -> csrf + - set `code` property on CSRF token errors + * deps: debug@~2.0.0 + * deps: errorhandler@~1.2.0 + - Display error using `util.inspect` if no other representation + - deps: accepts@~1.1.0 + * deps: express-session@~1.8.1 + - Do not resave already-saved session at end of request + - Prevent session prototype methods from being overwritten + - deps: cookie-signature@1.0.5 + - deps: debug@~2.0.0 + * deps: finalhandler@0.2.0 + - Set `X-Content-Type-Options: nosniff` header + - deps: debug@~2.0.0 + * deps: fresh@0.2.4 + * deps: media-typer@0.3.0 + - Throw error when parameter format invalid on parse + * deps: method-override@~2.2.0 + - deps: debug@~2.0.0 + * deps: morgan@~1.3.0 + - Assert if `format` is not a function or string + * deps: qs@2.2.3 + - Fix issue where first empty value in array is discarded + * deps: serve-favicon@~2.1.3 + - Accept string for `maxAge` (converted by `ms`) + - Use `etag` to generate `ETag` header + - deps: fresh@0.2.4 + * deps: serve-index@~1.2.1 + - Add `debug` messages + - Resolve relative paths at middleware setup + - deps: accepts@~1.1.0 + * deps: serve-static@~1.6.1 + - Add `lastModified` option + - deps: send@0.9.1 + * deps: type-is@~1.5.1 + - fix `hasbody` to be true for `content-length: 0` + - deps: media-typer@0.3.0 + - deps: mime-types@~2.0.1 + * deps: vhost@~3.0.0 + +2.25.10 / 2014-09-04 +==================== + + * deps: serve-static@~1.5.4 + - deps: send@0.8.5 + +2.25.9 / 2014-08-29 +=================== + + * deps: body-parser@~1.6.7 + - deps: qs@2.2.2 + * deps: qs@2.2.2 + +2.25.8 / 2014-08-27 +=================== + + * deps: body-parser@~1.6.6 + - deps: qs@2.2.0 + * deps: csurf@~1.4.1 + * deps: qs@2.2.0 + - Array parsing fix + - Performance improvements + +2.25.7 / 2014-08-18 +=================== + + * deps: body-parser@~1.6.5 + - deps: on-finished@2.1.0 + * deps: express-session@~1.7.6 + - Fix exception on `res.end(null)` calls + * deps: morgan@~1.2.3 + - deps: on-finished@2.1.0 + * deps: serve-static@~1.5.3 + - deps: send@0.8.3 + +2.25.6 / 2014-08-14 +=================== + + * deps: body-parser@~1.6.4 + - deps: qs@1.2.2 + * deps: qs@1.2.2 + * deps: serve-static@~1.5.2 + - deps: send@0.8.2 + +2.25.5 / 2014-08-11 +=================== + + * Fix backwards compatibility in `logger` + +2.25.4 / 2014-08-10 +=================== + + * Fix `query` middleware breaking with argument + - It never really took one in the first place + * deps: body-parser@~1.6.3 + - deps: qs@1.2.1 + * deps: compression@~1.0.11 + - deps: on-headers@~1.0.0 + - deps: parseurl@~1.3.0 + * deps: connect-timeout@~1.2.2 + - deps: on-headers@~1.0.0 + * deps: express-session@~1.7.5 + - Fix parsing original URL + - deps: on-headers@~1.0.0 + - deps: parseurl@~1.3.0 + * deps: method-override@~2.1.3 + * deps: on-headers@~1.0.0 + * deps: parseurl@~1.3.0 + * deps: qs@1.2.1 + * deps: response-time@~2.0.1 + - deps: on-headers@~1.0.0 + * deps: serve-index@~1.1.6 + - Fix URL parsing + * deps: serve-static@~1.5.1 + - Fix parsing of weird `req.originalUrl` values + - deps: parseurl@~1.3.0 + = deps: utils-merge@1.0.0 + +2.25.3 / 2014-08-07 +=================== + + * deps: multiparty@3.3.2 + - Fix potential double-callback + +2.25.2 / 2014-08-07 +=================== + + * deps: body-parser@~1.6.2 + - deps: qs@1.2.0 + * deps: qs@1.2.0 + - Fix parsing array of objects + +2.25.1 / 2014-08-06 +=================== + + * deps: body-parser@~1.6.1 + - deps: qs@1.1.0 + * deps: qs@1.1.0 + - Accept urlencoded square brackets + - Accept empty values in implicit array notation + +2.25.0 / 2014-08-05 +=================== + + * deps: body-parser@~1.6.0 + - deps: qs@1.0.2 + * deps: compression@~1.0.10 + - Fix upper-case Content-Type characters prevent compression + - deps: compressible@~1.1.1 + * deps: csurf@~1.4.0 + - Support changing `req.session` after `csurf` middleware + - Calling `res.csrfToken()` after `req.session.destroy()` will now work + * deps: express-session@~1.7.4 + - Fix `res.end` patch to call correct upstream `res.write` + - Fix response end delay for non-chunked responses + * deps: qs@1.0.2 + - Complete rewrite + - Limits array length to 20 + - Limits object depth to 5 + - Limits parameters to 1,000 + * deps: serve-static@~1.5.0 + - Add `extensions` option + - deps: send@0.8.1 + +2.24.3 / 2014-08-04 +=================== + + * deps: serve-index@~1.1.5 + - Fix Content-Length calculation for multi-byte file names + - deps: accepts@~1.0.7 + * deps: serve-static@~1.4.4 + - Fix incorrect 403 on Windows and Node.js 0.11 + - deps: send@0.7.4 + +2.24.2 / 2014-07-27 +=================== + + * deps: body-parser@~1.5.2 + * deps: depd@0.4.4 + - Work-around v8 generating empty stack traces + * deps: express-session@~1.7.2 + * deps: morgan@~1.2.2 + * deps: serve-static@~1.4.2 + +2.24.1 / 2014-07-26 +=================== + + * deps: body-parser@~1.5.1 + * deps: depd@0.4.3 + - Fix exception when global `Error.stackTraceLimit` is too low + * deps: express-session@~1.7.1 + * deps: morgan@~1.2.1 + * deps: serve-index@~1.1.4 + * deps: serve-static@~1.4.1 + +2.24.0 / 2014-07-22 +=================== + + * deps: body-parser@~1.5.0 + - deps: depd@0.4.2 + - deps: iconv-lite@0.4.4 + - deps: raw-body@1.3.0 + - deps: type-is@~1.3.2 + * deps: compression@~1.0.9 + - Add `debug` messages + - deps: accepts@~1.0.7 + * deps: connect-timeout@~1.2.1 + - Accept string for `time` (converted by `ms`) + - deps: debug@1.0.4 + * deps: debug@1.0.4 + * deps: depd@0.4.2 + - Add `TRACE_DEPRECATION` environment variable + - Remove non-standard grey color from color output + - Support `--no-deprecation` argument + - Support `--trace-deprecation` argument + * deps: express-session@~1.7.0 + - Improve session-ending error handling + - deps: debug@1.0.4 + - deps: depd@0.4.2 + * deps: finalhandler@0.1.0 + - Respond after request fully read + - deps: debug@1.0.4 + * deps: method-override@~2.1.2 + - deps: debug@1.0.4 + - deps: parseurl@~1.2.0 + * deps: morgan@~1.2.0 + - Add `:remote-user` token + - Add `combined` log format + - Add `common` log format + - Remove non-standard grey color from `dev` format + * deps: multiparty@3.3.1 + * deps: parseurl@~1.2.0 + - Cache URLs based on original value + - Remove no-longer-needed URL mis-parse work-around + - Simplify the "fast-path" `RegExp` + * deps: serve-static@~1.4.0 + - Add `dotfiles` option + - deps: parseurl@~1.2.0 + - deps: send@0.7.0 + +2.23.0 / 2014-07-10 +=================== + + * deps: debug@1.0.3 + - Add support for multiple wildcards in namespaces + * deps: express-session@~1.6.4 + * deps: method-override@~2.1.0 + - add simple debug output + - deps: methods@1.1.0 + - deps: parseurl@~1.1.3 + * deps: parseurl@~1.1.3 + - faster parsing of href-only URLs + * deps: serve-static@~1.3.1 + - deps: parseurl@~1.1.3 + +2.22.0 / 2014-07-03 +=================== + + * deps: csurf@~1.3.0 + - Fix `cookie.signed` option to actually sign cookie + * deps: express-session@~1.6.1 + - Fix `res.end` patch to return correct value + - Fix `res.end` patch to handle multiple `res.end` calls + - Reject cookies with missing signatures + * deps: multiparty@3.3.0 + - Always emit close after all parts ended + - Fix callback hang in node.js 0.8 on errors + * deps: serve-static@~1.3.0 + - Accept string for `maxAge` (converted by `ms`) + - Add `setHeaders` option + - Include HTML link in redirect response + - deps: send@0.5.0 + +2.21.1 / 2014-06-26 +=================== + + * deps: cookie-parser@1.3.2 + - deps: cookie-signature@1.0.4 + * deps: cookie-signature@1.0.4 + - fix for timing attacks + * deps: express-session@~1.5.2 + - deps: cookie-signature@1.0.4 + * deps: type-is@~1.3.2 + - more mime types + +2.21.0 / 2014-06-20 +=================== + + * deprecate `connect(middleware)` -- use `app.use(middleware)` instead + * deprecate `connect.createServer()` -- use `connect()` instead + * fix `res.setHeader()` patch to work with get -> append -> set pattern + * deps: compression@~1.0.8 + * deps: errorhandler@~1.1.1 + * deps: express-session@~1.5.0 + - Deprecate integration with `cookie-parser` middleware + - Deprecate looking for secret in `req.secret` + - Directly read cookies; `cookie-parser` no longer required + - Directly set cookies; `res.cookie` no longer required + - Generate session IDs with `uid-safe`, faster and even less collisions + * deps: serve-index@~1.1.3 + +2.20.2 / 2014-06-19 +=================== + + * deps: body-parser@1.4.3 + - deps: type-is@1.3.1 + +2.20.1 / 2014-06-19 +=================== + + * deps: type-is@1.3.1 + - fix global variable leak + +2.20.0 / 2014-06-19 +=================== + + * deprecate `verify` option to `json` -- use `body-parser` npm module instead + * deprecate `verify` option to `urlencoded` -- use `body-parser` npm module instead + * deprecate things with `depd` module + * use `finalhandler` for final response handling + * use `media-typer` to parse `content-type` for charset + * deps: body-parser@1.4.2 + - check accepted charset in content-type (accepts utf-8) + - check accepted encoding in content-encoding (accepts identity) + - deprecate `urlencoded()` without provided `extended` option + - lazy-load urlencoded parsers + - support gzip and deflate bodies + - set `inflate: false` to turn off + - deps: raw-body@1.2.2 + - deps: type-is@1.3.0 + - Support all encodings from `iconv-lite` + * deps: connect-timeout@1.1.1 + - deps: debug@1.0.2 + * deps: cookie-parser@1.3.1 + - export parsing functions + - `req.cookies` and `req.signedCookies` are now plain objects + - slightly faster parsing of many cookies + * deps: csurf@1.2.2 + * deps: errorhandler@1.1.0 + - Display error on console formatted like `throw` + - Escape HTML in stack trace + - Escape HTML in title + - Fix up edge cases with error sent in response + - Set `X-Content-Type-Options: nosniff` header + - Use accepts for negotiation + * deps: express-session@1.4.0 + - Add `genid` option to generate custom session IDs + - Add `saveUninitialized` option to control saving uninitialized sessions + - Add `unset` option to control unsetting `req.session` + - Generate session IDs with `rand-token` by default; reduce collisions + - Integrate with express "trust proxy" by default + - deps: buffer-crc32@0.2.3 + - deps: debug@1.0.2 + * deps: multiparty@3.2.9 + * deps: serve-index@1.1.2 + - deps: batch@0.5.1 + * deps: type-is@1.3.0 + - improve type parsing + * deps: vhost@2.0.0 + - Accept `RegExp` object for `hostname` + - Provide `req.vhost` object + - Support IPv6 literal in `Host` header + +2.19.6 / 2014-06-11 +=================== + + * deps: body-parser@1.3.1 + - deps: type-is@1.2.1 + * deps: compression@1.0.7 + - use vary module for better `Vary` behavior + - deps: accepts@1.0.3 + - deps: compressible@1.1.0 + * deps: debug@1.0.2 + * deps: serve-index@1.1.1 + - deps: accepts@1.0.3 + * deps: serve-static@1.2.3 + - Do not throw un-catchable error on file open race condition + - deps: send@0.4.3 + +2.19.5 / 2014-06-09 +=================== + + * deps: csurf@1.2.1 + - refactor to use csrf-tokens@~1.0.2 + * deps: debug@1.0.1 + * deps: serve-static@1.2.2 + - fix "event emitter leak" warnings + - deps: send@0.4.2 + * deps: type-is@1.2.1 + - Switch dependency from `mime` to `mime-types@1.0.0` + +2.19.4 / 2014-06-05 +=================== + + * deps: errorhandler@1.0.2 + - Pass on errors from reading error files + * deps: method-override@2.0.2 + - use vary module for better `Vary` behavior + * deps: serve-favicon@2.0.1 + - Reduce byte size of `ETag` header + +2.19.3 / 2014-06-03 +=================== + + * deps: compression@1.0.6 + - fix listeners for delayed stream creation + - fix regression for certain `stream.pipe(res)` situations + - fix regression when negotiation fails + +2.19.2 / 2014-06-03 +=================== + + * deps: compression@1.0.4 + - fix adding `Vary` when value stored as array + - fix back-pressure behavior + - fix length check for `res.end` + +2.19.1 / 2014-06-02 +=================== + + * fix deprecated `utils.escape` + +2.19.0 / 2014-06-02 +=================== + + * deprecate `methodOverride()` -- use `method-override` npm module instead + * deps: body-parser@1.3.0 + - add `extended` option to urlencoded parser + * deps: method-override@2.0.1 + - set `Vary` header + - deps: methods@1.0.1 + * deps: multiparty@3.2.8 + * deps: response-time@2.0.0 + - add `digits` argument + - do not override existing `X-Response-Time` header + - timer not subject to clock drift + - timer resolution down to nanoseconds + * deps: serve-static@1.2.1 + - send max-age in Cache-Control in correct format + - use `escape-html` for escaping + - deps: send@0.4.1 + +2.18.0 / 2014-05-29 +=================== + + * deps: compression@1.0.3 + * deps: serve-index@1.1.0 + - Fix content negotiation when no `Accept` header + - Properly support all HTTP methods + - Support vanilla node.js http servers + - Treat `ENAMETOOLONG` as code 414 + - Use accepts for negotiation + * deps: serve-static@1.2.0 + - Calculate ETag with md5 for reduced collisions + - Fix wrong behavior when index file matches directory + - Ignore stream errors after request ends + - Skip directories in index file search + - deps: send@0.4.0 + +2.17.3 / 2014-05-27 +=================== + + * deps: express-session@1.2.1 + - Fix `resave` such that `resave: true` works + +2.17.2 / 2014-05-27 +=================== + + * deps: body-parser@1.2.2 + - invoke `next(err)` after request fully read + - deps: raw-body@1.1.6 + * deps: method-override@1.0.2 + - Handle `req.body` key referencing array or object + - Handle multiple HTTP headers + +2.17.1 / 2014-05-21 +=================== + + * fix `res.charset` appending charset when `content-type` has one + +2.17.0 / 2014-05-20 +=================== + + * deps: express-session@1.2.0 + - Add `resave` option to control saving unmodified sessions + * deps: morgan@1.1.1 + - "dev" format will use same tokens as other formats + - `:response-time` token is now empty when immediate used + - `:response-time` token is now monotonic + - `:response-time` token has precision to 1 μs + - fix `:status` + immediate output in node.js 0.8 + - improve `buffer` option to prevent indefinite event loop holding + - simplify method to get remote address + - deps: bytes@1.0.0 + * deps: serve-index@1.0.3 + - Fix error from non-statable files in HTML view + +2.16.2 / 2014-05-18 +=================== + + * fix edge-case in `res.appendHeader` that would append in wrong order + * deps: method-override@1.0.1 + +2.16.1 / 2014-05-17 +=================== + + * remove usages of `res.headerSent` from core + +2.16.0 / 2014-05-17 +=================== + + * deprecate `res.headerSent` -- use `res.headersSent` + * deprecate `res.on("header")` -- use on-headers module instead + * fix `connect.version` to reflect the actual version + * json: use body-parser + - add `type` option + - fix repeated limit parsing with every request + - improve parser speed + * urlencoded: use body-parser + - add `type` option + - fix repeated limit parsing with every request + * dep: bytes@1.0.0 + * add negative support + * dep: cookie-parser@1.1.0 + - deps: cookie@0.1.2 + * dep: csurf@1.2.0 + - add support for double-submit cookie + * dep: express-session@1.1.0 + - Add `name` option; replacement for `key` option + - Use `setImmediate` in MemoryStore for node.js >= 0.10 + +2.15.0 / 2014-05-04 +=================== + + * Add simple `res.cookie` support + * Add `res.appendHeader` + * Call error stack even when response has been sent + * Patch `res.headerSent` to return Boolean + * Patch `res.headersSent` for node.js 0.8 + * Prevent default 404 handler after response sent + * dep: compression@1.0.2 + * support headers given to `res.writeHead` + * deps: bytes@0.3.0 + * deps: negotiator@0.4.3 + * dep: connect-timeout@1.1.0 + * Add `req.timedout` property + * Add `respond` option to constructor + * Clear timer on socket destroy + * deps: debug@0.8.1 + * dep: debug@^0.8.0 + * add `enable()` method + * change from stderr to stdout + * dep: errorhandler@1.0.1 + * Clean up error CSS + * Do not respond after headers sent + * dep: express-session@1.0.4 + * Remove import of `setImmediate` + * Use `res.cookie()` instead of `res.setHeader()` + * deps: cookie@0.1.2 + * deps: debug@0.8.1 + * dep: morgan@1.0.1 + * Make buffer unique per morgan instance + * deps: bytes@0.3.0 + * dep: serve-favicon@2.0.0 + * Accept `Buffer` of icon as first argument + * Non-GET and HEAD requests are denied + * Send valid max-age value + * Support conditional requests + * Support max-age=0 + * Support OPTIONS method + * Throw if `path` argument is directory + * dep: serve-index@1.0.2 + * Add stylesheet option + * deps: negotiator@0.4.3 + +2.14.5 / 2014-04-24 +=================== + + * dep: raw-body@1.1.4 + * allow true as an option + * deps: bytes@0.3.0 + * dep: serve-static@1.1.0 + * Accept options directly to `send` module + * deps: send@0.3.0 + +2.14.4 / 2014-04-07 +=================== + + * dep: bytes@0.3.0 + * added terabyte support + * dep: csurf@1.1.0 + * add constant-time string compare + * dep: serve-static@1.0.4 + * Resolve relative paths at middleware setup + * Use parseurl to parse the URL from request + * fix node.js 0.8 compatibility with memory session + +2.14.3 / 2014-03-18 +=================== + + * dep: static-favicon@1.0.2 + * Fixed content of default icon + +2.14.2 / 2014-03-11 +=================== + + * dep: static-favicon@1.0.1 + * Fixed path to default icon + +2.14.1 / 2014-03-06 +=================== + + * dep: fresh@0.2.2 + * no real changes + * dep: serve-index@1.0.1 + * deps: negotiator@0.4.2 + * dep: serve-static@1.0.2 + * deps: send@0.2.0 + +2.14.0 / 2014-03-05 +=================== + + * basicAuth: use basic-auth-connect + * cookieParser: use cookie-parser + * compress: use compression + * csrf: use csurf + * dep: cookie-signature@1.0.3 + * directory: use serve-index + * errorHandler: use errorhandler + * favicon: use static-favicon + * logger: use morgan + * methodOverride: use method-override + * responseTime: use response-time + * session: use express-session + * static: use serve-static + * timeout: use connect-timeout + * vhost: use vhost + +2.13.1 / 2014-03-05 +=================== + + * cookieSession: compare full value rather than crc32 + * deps: raw-body@1.1.3 + +2.13.0 / 2014-02-14 +=================== + + * fix typo in memory store warning #974 @rvagg + * compress: use compressible + * directory: add template option #990 @gottaloveit @Earl-Brown + * csrf: prevent deprecated warning with old sessions + +2.12.0 / 2013-12-10 +=================== + + * bump qs + * directory: sort folders before files + * directory: add folder icons + * directory: de-duplicate icons, details/mobile views #968 @simov + * errorHandler: end default 404 handler with a newline #972 @rlidwka + * session: remove long cookie expire check #870 @undoZen + +2.11.2 / 2013-12-01 +=================== + + * bump raw-body + +2.11.1 / 2013-11-27 +=================== + + * bump raw-body + * errorHandler: use `res.setHeader()` instead of `res.writeHead()` #949 @lo1tuma + +2.11.0 / 2013-10-29 +=================== + + * update bytes + * update uid2 + * update negotiator + * sessions: add rolling session option #944 @ilmeo + * sessions: property set cookies when given FQDN + * cookieSessions: properly set cookies when given FQDN #948 @bmancini55 + * proto: fix FQDN mounting when multiple handlers #945 @bmancini55 + +2.10.1 / 2013-10-23 +=================== + + * fixed; fixed a bug with static middleware at root and trailing slashes #942 (@dougwilson) + +2.10.0 / 2013-10-22 +=================== + + * fixed: set headers written by writeHead before emitting 'header' + * fixed: mounted path should ignore querystrings on FQDNs #940 (@dougwilson) + * fixed: parsing protocol-relative URLs with @ as pathnames #938 (@dougwilson) + * fixed: fix static directory redirect for mount's root #937 (@dougwilson) + * fixed: setting set-cookie header when mixing arrays and strings #893 (@anuj123) + * bodyParser: optional verify function for urlencoded and json parsers for signing request bodies + * compress: compress checks content-length to check threshold + * compress: expose `res.flush()` for flushing responses + * cookieParser: pass options into node-cookie #803 (@cauldrath) + * errorHandler: replace `\n`s with `
    `s in error handler + +2.9.2 / 2013-10-18 +================== + + * warn about multiparty and limit middleware deprecation for v3 + * fix fully qualified domain name mounting. #920 (@dougwilson) + * directory: Fix potential security issue with serving files outside the root. #929 (@dougwilson) + * logger: store IP at beginning in case socket prematurely closes #930 (@dougwilson) + +2.9.1 / 2013-10-15 +================== + + * update multiparty + * compress: Set vary header only if Content-Type passes filter #904 + * directory: Fix directory middleware URI escaping #917 (@dougwilson) + * directory: Fix directory seperators for Windows #914 (@dougwilson) + * directory: Keep query string intact during directory redirect #913 (@dougwilson) + * directory: Fix paths in links #730 (@JacksonTian) + * errorHandler: Don't escape text/plain as HTML #875 (@johan) + * logger: Write '0' instead of '-' when response time is zero #910 (@dougwilson) + * logger: Log even when connections are aborted #760 (@dylanahsmith) + * methodOverride: Check req.body is an object #907 (@kbjr) + * multipart: Add .type back to file parts for backwards compatibility #912 (@dougwilson) + * multipart: Allow passing options to the Multiparty constructor #902 (@niftylettuce) + +2.9.0 / 2013-09-07 +================== + + * multipart: add docs regarding tmpfiles + * multipart: add .name back to file parts + * multipart: use multiparty instead of formidable + +2.8.8 / 2013-09-02 +================== + + * csrf: change to math.random() salt and remove csrfToken() callback + +2.8.7 / 2013-08-28 +================== + + * csrf: prevent salt generation on every request, and add async req.csrfToken(fn) + +2.8.6 / 2013-08-28 +================== + + * csrf: refactor to use HMAC tokens (BREACH attack) + * compress: add compression of SVG and common font files by default. + +2.8.5 / 2013-08-11 +================== + + * add: compress Dart source files by default + * update fresh + +2.8.4 / 2013-07-08 +================== + + * update send + +2.8.3 / 2013-07-04 +================== + + * add a name back to static middleware ("staticMiddleware") + * fix .hasBody() utility to require transfer-encoding or content-length + +2.8.2 / 2013-07-03 +================== + + * update send + * update cookie dep. + * add better debug() for middleware + * add whitelisting of supported methods to methodOverride() + +2.8.1 / 2013-06-27 +================== + + * fix: escape req.method in 404 response + +2.8.0 / 2013-06-26 +================== + + * add `threshold` option to `compress()` to prevent compression of small responses + * add support for vendor JSON mime types in json() + * add X-Forwarded-Proto initial https proxy support + * change static redirect to 303 + * change octal escape sequences for strict mode + * change: replace utils.uid() with uid2 lib + * remove other "static" function name. Fixes #794 + * fix: hasBody() should return false if Content-Length: 0 + +2.7.11 / 2013-06-02 +================== + + * update send + +2.7.10 / 2013-05-21 +================== + + * update qs + * update formidable + * fix: write/end to noop() when request aborted + +2.7.9 / 2013-05-07 +================== + + * update qs + * drop support for node < v0.8 + +2.7.8 / 2013-05-03 +================== + + * update qs + +2.7.7 / 2013-04-29 +================== + + * update qs dependency + * remove "static" function name. Closes #794 + * update node-formidable + * update buffer-crc32 + +2.7.6 / 2013-04-15 +================== + + * revert cookie signature which was creating session race conditions + +2.7.5 / 2013-04-12 +================== + + * update cookie-signature + * limit: do not consume request in node 0.10.x + +2.7.4 / 2013-04-01 +================== + + * session: add long expires check and prevent excess set-cookie + * session: add console.error() of session#save() errors + +2.7.3 / 2013-02-19 +================== + + * add name to compress middleware + * add appending Accept-Encoding to Vary when set but missing + * add tests for csrf middleware + * add 'next' support for connect() server handler + * change utils.uid() to return url-safe chars. Closes #753 + * fix treating '.' as a regexp in vhost() + * fix duplicate bytes dep in package.json. Closes #743 + * fix #733 - parse x-forwarded-proto in a more generally compatibly way + * revert "add support for `next(status[, msg])`"; makes composition hard + +2.7.2 / 2013-01-04 +================== + + * add support for `next(status[, msg])` back + * add utf-8 meta tag to support foreign characters in filenames/directories + * change `timeout()` 408 to 503 + * replace 'node-crc' with 'buffer-crc32', fixes licensing + * fix directory.html IE support + +2.7.1 / 2012-12-05 +================== + + * add directory() tests + * add support for bodyParser to ignore Content-Type if no body is present (jquery primarily does this poorely) + * fix errorHandler signature + +2.7.0 / 2012-11-13 +================== + + * add support for leading JSON whitespace + * add logging of `req.ip` when present + * add basicAuth support for `:`-delimited string + * update cookie module. Closes #688 + +2.6.2 / 2012-11-01 +================== + + * add `debug()` for disconnected session store + * fix session regeneration bug. Closes #681 + +2.6.1 / 2012-10-25 +================== + + * add passing of `connect.timeout()` errors to `next()` + * replace signature utils with cookie-signature module + +2.6.0 / 2012-10-09 +================== + + * add `defer` option to `multipart()` [Blake Miner] + * fix mount path case sensitivity. Closes #663 + * fix default of ascii encoding from `logger()`, now utf8. Closes #293 + +2.5.0 / 2012-09-27 +================== + + * add `err.status = 400` to multipart() errors + * add double-encoding protection to `compress()`. Closes #659 + * add graceful handling cookie parsing errors [shtylman] + * fix typo X-Response-time to X-Response-Time + +2.4.6 / 2012-09-18 +================== + + * update qs + +2.4.5 / 2012-09-03 +================== + + * add session store "connect" / "disconnect" support [louischatriot] + * fix `:url` log token + +2.4.4 / 2012-08-21 +================== + + * fix `static()` pause regression from "send" integration + +2.4.3 / 2012-08-07 +================== + + * fix `.write()` encoding for zlib inconstancy. Closes #561 + +2.4.2 / 2012-07-25 +================== + + * remove limit default from `urlencoded()` + * remove limit default from `json()` + * remove limit default from `multipart()` + * fix `cookieSession()` clear cookie path / domain bug. Closes #636 + +2.4.1 / 2012-07-24 +================== + + * fix `options` mutation in `static()` + +2.4.0 / 2012-07-23 +================== + + * add `connect.timeout()` + * add __GET__ / __HEAD__ check to `directory()`. Closes #634 + * add "pause" util dep + * update send dep for normalization bug + +2.3.9 / 2012-07-16 +================== + + * add more descriptive invalid json error message + * update send dep for root normalization regression + * fix staticCache fresh dep + +2.3.8 / 2012-07-12 +================== + + * fix `connect.static()` 404 regression, pass `next()`. Closes #629 + +2.3.7 / 2012-07-05 +================== + + * add `json()` utf-8 illustration test. Closes #621 + * add "send" dependency + * change `connect.static()` internals to use "send" + * fix `session()` req.session generation with pathname mismatch + * fix `cookieSession()` req.session generation with pathname mismatch + * fix mime export. Closes #618 + +2.3.6 / 2012-07-03 +================== + + * Fixed cookieSession() with cookieParser() secret regression. Closes #602 + * Fixed set-cookie header fields on cookie.path mismatch. Closes #615 + +2.3.5 / 2012-06-28 +================== + + * Remove `logger()` mount check + * Fixed `staticCache()` dont cache responses with set-cookie. Closes #607 + * Fixed `staticCache()` when Cookie is present + +2.3.4 / 2012-06-22 +================== + + * Added `err.buf` to urlencoded() and json() + * Update cookie to 0.0.4. Closes #604 + * Fixed: only send 304 if original response in 2xx or 304 [timkuijsten] + +2.3.3 / 2012-06-11 +================== + + * Added ETags back to `static()` [timkuijsten] + * Replaced `utils.parseRange()` with `range-parser` module + * Replaced `utils.parseBytes()` with `bytes` module + * Replaced `utils.modified()` with `fresh` module + * Fixed `cookieSession()` regression with invalid cookie signing [shtylman] + +2.3.2 / 2012-06-08 +================== + + * expose mime module + * Update crc dep (which bundled nodeunit) + +2.3.1 / 2012-06-06 +================== + + * Added `secret` option to `cookieSession` middleware [shtylman] + * Added `secret` option to `session` middleware [shtylman] + * Added `req.remoteUser` back to `basicAuth()` as alias of `req.user` + * Performance: improve signed cookie parsing + * Update `cookie` dependency [shtylman] + +2.3.0 / 2012-05-20 +================== + + * Added limit option to `json()` + * Added limit option to `urlencoded()` + * Added limit option to `multipart()` + * Fixed: remove socket error event listener on callback + * Fixed __ENOTDIR__ error on `static` middleware + +2.2.2 / 2012-05-07 +================== + + * Added support to csrf middle for pre-flight CORS requests + * Updated `engines` to allow newer version of node + * Removed duplicate repo prop. Closes #560 + +2.2.1 / 2012-04-28 +================== + + * Fixed `static()` redirect when mounted. Closes #554 + +2.2.0 / 2012-04-25 +================== + + * Added `make benchmark` + * Perf: memoize url parsing (~20% increase) + * Fixed `connect(fn, fn2, ...)`. Closes #549 + +2.1.3 / 2012-04-20 +================== + + * Added optional json() `reviver` function to be passed to JSON.parse [jed] + * Fixed: emit drain in compress middleware [nsabovic] + +2.1.2 / 2012-04-11 +================== + + * Fixed cookieParser() `req.cookies` regression + +2.1.1 / 2012-04-11 +================== + + * Fixed `session()` browser-session length cookies & examples + * Fixed: make `query()` "self-aware" [jed] + +2.1.0 / 2012-04-05 +================== + + * Added `debug()` calls to `.use()` (`DEBUG=connect:displatcher`) + * Added `urlencoded()` support for GET + * Added `json()` support for GET. Closes #497 + * Added `strict` option to `json()` + * Changed: `session()` only set-cookie when modified + * Removed `Session#lastAccess` property. Closes #399 + +2.0.3 / 2012-03-20 +================== + + * Added: `cookieSession()` only sets cookie on change. Closes #442 + * Added `connect:dispatcher` debug() probes + +2.0.2 / 2012-03-04 +================== + + * Added test for __ENAMETOOLONG__ now that node is fixed + * Fixed static() index "/" check on windows. Closes #498 + * Fixed Content-Range behaviour to match RFC2616 [matthiasdg / visionmedia] + +2.0.1 / 2012-02-29 +================== + + * Added test coverage for `vhost()` middleware + * Changed `cookieParser()` signed cookie support to use SHA-2 [senotrusov] + * Fixed `static()` Range: respond with 416 when unsatisfiable + * Fixed `vhost()` middleware. Closes #494 + +2.0.0 / 2011-10-05 +================== + + * Added `cookieSession()` middleware for cookie-only sessions + * Added `compress()` middleware for gzip / deflate support + * Added `session()` "proxy" setting to trust `X-Forwarded-Proto` + * Added `json()` middleware to parse "application/json" + * Added `urlencoded()` middleware to parse "application/x-www-form-urlencoded" + * Added `multipart()` middleware to parse "multipart/form-data" + * Added `cookieParser(secret)` support so anything using this middleware may access signed cookies + * Added signed cookie support to `cookieParser()` + * Added support for JSON-serialized cookies to `cookieParser()` + * Added `err.status` support in Connect's default end-point + * Added X-Cache MISS / HIT to `staticCache()` + * Added public `res.headerSent` checking nodes `res._headerSent` until node does + * Changed `basicAuth()` req.remoteUser to req.user + * Changed: default `session()` to a browser-session cookie. Closes #475 + * Changed: no longer lowercase cookie names + * Changed `bodyParser()` to use `json()`, `urlencoded()`, and `multipart()` + * Changed: `errorHandler()` is now a development-only middleware + * Changed middleware to `next()` errors when possible so applications can unify logging / handling + * Removed `http[s].Server` inheritance, now just a function, making it easy to have an app providing both http and https + * Removed `.createServer()` (use `connect()`) + * Removed `secret` option from `session()`, use `cookieParser(secret)` + * Removed `connect.session.ignore` array support + * Removed `router()` middleware. Closes #262 + * Fixed: set-cookie only once for browser-session cookies + * Fixed FQDN support. dont add leading "/" + * Fixed 404 XSS attack vector. Closes #473 + * Fixed __HEAD__ support for 404s and 500s generated by Connect's end-point + +1.8.5 / 2011-12-22 +================== + + * Fixed: actually allow empty body for json + +1.8.4 / 2011-12-22 +================== + + * Changed: allow empty body for json/urlencoded requests. Backport for #443 + +1.8.3 / 2011-12-16 +================== + + * Fixed `static()` _index.html_ support on windows + +1.8.2 / 2011-12-03 +================== + + * Fixed potential security issue, store files in req.files. Closes #431 [reported by dobesv] + +1.8.1 / 2011-11-21 +================== + + * Added nesting support for _multipart/form-data_ [jackyz] + +1.8.0 / 2011-11-17 +================== + + * Added _multipart/form-data_ support to `bodyParser()` using formidable + +1.7.3 / 2011-11-11 +================== + + * Fixed `req.body`, always default to {} + * Fixed HEAD support for 404s and 500s + +1.7.2 / 2011-10-24 +================== + + * "node": ">= 0.4.1 < 0.7.0" + * Added `static()` redirect option. Closes #398 + * Changed `limit()`: respond with 413 when content-length exceeds the limit + * Removed socket error listener in static(). Closes #389 + * Fixed `staticCache()` Age header field + * Fixed race condition causing errors reported in #329. + +1.7.1 / 2011-09-12 +================== + + * Added: make `Store` inherit from `EventEmitter` + * Added session `Store#load(sess, fn)` to fetch a `Session` instance + * Added backpressure support to `staticCache()` + * Changed `res.socket.destroy()` to `req.socket.destroy()` + +1.7.0 / 2011-08-31 +================== + + * Added `staticCache()` middleware, a memory cache for `static()` + * Added public `res.headerSent` checking nodes `res._headerSent` (remove when node adds this) + * Changed: ignore error handling middleware when header is sent + * Changed: dispatcher errors after header is sent destroy the sock + +1.6.4 / 2011-08-26 +================== + + * Revert "Added double-next reporting" + +1.6.3 / 2011-08-26 +================== + + * Added double-`next()` reporting + * Added `immediate` option to `logger()`. Closes #321 + * Dependency `qs >= 0.3.1` + +1.6.2 / 2011-08-11 +================== + + * Fixed `connect.static()` null byte vulnerability + * Fixed `connect.directory()` null byte vulnerability + * Changed: 301 redirect in `static()` to postfix "/" on directory. Closes #289 + +1.6.1 / 2011-08-03 +================== + + * Added: allow retval `== null` from logger callback to ignore line + * Added `getOnly` option to `connect.static.send()` + * Added response "header" event allowing augmentation + * Added `X-CSRF-Token` header field check + * Changed dep `qs >= 0.3.0` + * Changed: persist csrf token. Closes #322 + * Changed: sort directory middleware files alphabetically + +1.6.0 / 2011-07-10 +================== + + * Added :response-time to "dev" logger format + * Added simple `csrf()` middleware. Closes #315 + * Fixed `res._headers` logger regression. Closes #318 + * Removed support for multiple middleware being passed to `.use()` + +1.5.2 / 2011-07-06 +================== + + * Added `filter` function option to `directory()` [David Rio Deiros] + * Changed: re-write of the `logger()` middleware, with extensible tokens and formats + * Changed: `static.send()` ".." in path without root considered malicious + * Fixed quotes in docs. Closes #312 + * Fixed urls when mounting `directory()`, use `originalUrl` [Daniel Dickison] + + +1.5.1 / 2011-06-20 +================== + + * Added malicious path check to `directory()` middleware + * Added `utils.forbidden(res)` + * Added `connect.query()` middleware + +1.5.0 / 2011-06-20 +================== + + * Added `connect.directory()` middleware for serving directory listings + +1.4.6 / 2011-06-18 +================== + + * Fixed `connect.static()` root with `..` + * Fixed `connect.static()` __EBADF__ + +1.4.5 / 2011-06-17 +================== + + * Fixed EBADF in `connect.static()`. Closes #297 + +1.4.4 / 2011-06-16 +================== + + * Changed `connect.static()` to check resolved dirname. Closes #294 + +1.4.3 / 2011-06-06 +================== + + * Fixed fd leak in `connect.static()` when the socket is closed + * Fixed; `bodyParser()` ignoring __GET/HEAD__. Closes #285 + +1.4.2 / 2011-05-27 +================== + + * Changed to `devDependencies` + * Fixed stream creation on `static()` __HEAD__ request. [Andreas Lind Petersen] + * Fixed Win32 support for `static()` + * Fixed monkey-patch issue. Closes #261 + +1.4.1 / 2011-05-08 +================== + + * Added "hidden" option to `static()`. ignores hidden files by default. Closes * Added; expose `connect.static.mime.define()`. Closes #251 + * Fixed `errorHandler` middleware for missing stack traces. [aseemk] +#274 + +1.4.0 / 2011-04-25 +================== + + * Added route-middleware `next('route')` support to jump passed the route itself + * Added Content-Length support to `limit()` + * Added route-specific middleware support (used to be in express) + * Changed; refactored duplicate session logic + * Changed; prevent redefining `store.generate` per request + * Fixed; `static()` does not set Content-Type when explicitly set [nateps] + * Fixed escape `errorHandler()` {error} contents + * NOTE: `router` will be removed in 2.0 + + +1.3.0 / 2011-04-06 +================== + + * Added `router.remove(path[, method])` to remove a route + +1.2.3 / 2011-04-05 +================== + + * Fixed basicAuth realm issue when passing strings. Closes #253 + +1.2.2 / 2011-04-05 +================== + + * Added `basicAuth(username, password)` support + * Added `errorHandler.title` defaulting to "Connect" + * Changed `errorHandler` css + +1.2.1 / 2011-03-30 +================== + + * Fixed `logger()` https `remoteAddress` logging [Alexander Simmerl] + +1.2.0 / 2011-03-30 +================== + + * Added `router.lookup(path[, method])` + * Added `router.match(url[, method])` + * Added basicAuth async support. Closes #223 + +1.1.5 / 2011-03-27 +================== + + * Added; allow `logger()` callback function to return an empty string to ignore logging + * Fixed; utilizing `mime.charsets.lookup()` for `static()`. Closes 245 + +1.1.4 / 2011-03-23 +================== + + * Added `logger()` support for format function + * Fixed `logger()` to support mess of writeHead()/progressive api for node 0.4.x + +1.1.3 / 2011-03-21 +================== + + * Changed; `limit()` now calls `req.destroy()` + +1.1.2 / 2011-03-21 +================== + + * Added request "limit" event to `limit()` middleware + * Changed; `limit()` middleware will `next(err)` on failure + +1.1.1 / 2011-03-18 +================== + + * Fixed session middleware for HTTPS. Closes #241 [reported by mt502] + +1.1.0 / 2011-03-17 +================== + + * Added `Session#reload(fn)` + +1.0.6 / 2011-03-09 +================== + + * Fixed `res.setHeader()` patch, preserve casing + +1.0.5 / 2011-03-09 +================== + + * Fixed; `logger()` using `req.originalUrl` instead of `req.url` + +1.0.4 / 2011-03-09 +================== + + * Added `res.charset` + * Added conditional sessions example + * Added support for `session.ignore` to be replaced. Closes #227 + * Fixed `Cache-Control` delimiters. Closes #228 + +1.0.3 / 2011-03-03 +================== + + * Fixed; `static.send()` invokes callback with connection error + +1.0.2 / 2011-03-02 +================== + + * Fixed exported connect function + * Fixed package.json; node ">= 0.4.1 < 0.5.0" + +1.0.1 / 2011-03-02 +================== + + * Added `Session#save(fn)`. Closes #213 + * Added callback support to `connect.static.send()` for express + * Added `connect.static.send()` "path" option + * Fixed content-type in `static()` for _index.html_ + +1.0.0 / 2011-03-01 +================== + + * Added `stack`, `message`, and `dump` errorHandler option aliases + * Added `req.originalMethod` to methodOverride + * Added `favicon()` maxAge option support + * Added `connect()` alternative to `connect.createServer()` + * Added new [documentation](http://senchalabs.github.com/connect) + * Added Range support to `static()` + * Added HTTPS support + * Rewrote session middleware. The session API now allows for + session-specific cookies, so you may alter each individually. + Click to view the new [session api](http://senchalabs.github.com/connect/middleware-session.html). + * Added middleware self-awareness. This helps prevent + middleware breakage when used within mounted servers. + For example `cookieParser()` will not parse cookies more + than once even when within a mounted server. + * Added new examples in the `./examples` directory + * Added [limit()](http://senchalabs.github.com/connect/middleware-limit.html) middleware + * Added [profiler()](http://senchalabs.github.com/connect/middleware-profiler.html) middleware + * Added [responseTime()](http://senchalabs.github.com/connect/middleware-responseTime.html) middleware + * Renamed `staticProvider` to `static` + * Renamed `bodyDecoder` to `bodyParser` + * Renamed `cookieDecoder` to `cookieParser` + * Fixed ETag quotes. [reported by papandreou] + * Fixed If-None-Match comma-delimited ETag support. [reported by papandreou] + * Fixed; only set req.originalUrl once. Closes #124 + * Fixed symlink support for `static()`. Closes #123 + +0.5.10 / 2011-02-14 +================== + + * Fixed SID space issue. Closes #196 + * Fixed; proxy `res.end()` to commit session data + * Fixed directory traversal attack in `staticProvider`. Closes #198 + +0.5.9 / 2011-02-09 +================== + + * qs >= 0.0.4 + +0.5.8 / 2011-02-04 +================== + + * Added `qs` dependency + * Fixed router race-condition causing possible failure + when `next()`ing to one or more routes with parallel + requests + +0.5.7 / 2011-02-01 +================== + + * Added `onvhost()` call so Express (and others) can know when they are + * Revert "Added stylus support" (use the middleware which ships with stylus) + * Removed custom `Server#listen()` to allow regular `http.Server#listen()` args to work properly + * Fixed long standing router issue (#83) that causes '.' to be disallowed within named placeholders in routes [Andreas Lind Petersen] + * Fixed `utils.uid()` length error [Jxck] +mounted + +0.5.6 / 2011-01-23 +================== + + * Added stylus support to `compiler` + * _favicon.js_ cleanup + * _compiler.js_ cleanup + * _bodyDecoder.js_ cleanup + +0.5.5 / 2011-01-13 +================== + + * Changed; using sha256 HMAC instead of md5. [Paul Querna] + * Changed; generated a longer random UID, without time influence. [Paul Querna] + * Fixed; session middleware throws when secret is not present. [Paul Querna] + +0.5.4 / 2011-01-07 +================== + + * Added; throw when router path or callback is missing + * Fixed; `next(err)` on cookie parse exception instead of ignoring + * Revert "Added utils.pathname(), memoized url.parse(str).pathname" + +0.5.3 / 2011-01-05 +================== + + * Added _docs/api.html_ + * Added `utils.pathname()`, memoized url.parse(str).pathname + * Fixed `session.id` issue. Closes #183 + * Changed; Defaulting `staticProvider` maxAge to 0 not 1 year. Closes #179 + * Removed bad outdated docs, we need something new / automated eventually + +0.5.2 / 2010-12-28 +================== + + * Added default __OPTIONS__ support to _router_ middleware + +0.5.1 / 2010-12-28 +================== + + * Added `req.session.id` mirroring `req.sessionID` + * Refactored router, exposing `connect.router.methods` + * Exclude non-lib files from npm + * Removed imposed headers `X-Powered-By`, `Server`, etc + +0.5.0 / 2010-12-06 +================== + + * Added _./index.js_ + * Added route segment precondition support and example + * Added named capture group support to router + +0.4.0 / 2010-11-29 +================== + + * Added `basicAuth` middleware + * Added more HTTP methods to the `router` middleware + +0.3.0 / 2010-07-21 +================== + + * Added _staticGzip_ middleware + * Added `connect.utils` to expose utils + * Added `connect.session.Session` + * Added `connect.session.Store` + * Added `connect.session.MemoryStore` + * Added `connect.middleware` to expose the middleware getters + * Added `buffer` option to _logger_ for performance increase + * Added _favicon_ middleware for serving your own favicon or the connect default + * Added option support to _staticProvider_, can now pass _root_ and _lifetime_. + * Added; mounted `Server` instances now have the `route` property exposed for reflection + * Added support for callback as first arg to `Server#use()` + * Added support for `next(true)` in _router_ to bypass match attempts + * Added `Server#listen()` _host_ support + * Added `Server#route` when `Server#use()` is called with a route on a `Server` instance + * Added _methodOverride_ X-HTTP-Method-Override support + * Refactored session internals, adds _secret_ option + * Renamed `lifetime` option to `maxAge` in _staticProvider_ + * Removed connect(1), it is now [spark(1)](http://github.com/senchalabs/spark) + * Removed connect(1) dependency on examples, they can all now run with node(1) + * Remove a typo that was leaking a global. + * Removed `Object.prototype` forEach() and map() methods + * Removed a few utils not used + * Removed `connect.createApp()` + * Removed `res.simpleBody()` + * Removed _format_ middleware + * Removed _flash_ middleware + * Removed _redirect_ middleware + * Removed _jsonrpc_ middleware, use [visionmedia/connect-jsonrpc](http://github.com/visionmedia/connect-jsonrpc) + * Removed _pubsub_ middleware + * Removed need for `params.{captures,splat}` in _router_ middleware, `params` is an array + * Changed; _compiler_ no longer 404s + * Changed; _router_ signature now matches connect middleware signature + * Fixed a require in _session_ for default `MemoryStore` + * Fixed nasty request body bug in _router_. Closes #54 + * Fixed _less_ support in _compiler_ + * Fixed bug preventing proper bubbling of exceptions in mounted servers + * Fixed bug in `Server#use()` preventing `Server` instances as the first arg + * Fixed **ENOENT** special case, is now treated as any other exception + * Fixed spark env support + +0.2.1 / 2010-07-09 +================== + + * Added support for _router_ `next()` to continue calling matched routes + * Added mime type for _cache.manifest_ files. + * Changed _compiler_ middleware to use async require + * Changed session api, stores now only require `#get()`, and `#set()` + * Fixed _cacheManifest_ by adding `utils.find()` back + +0.2.0 / 2010-07-01 +================== + + * Added calls to `Session()` casts the given object as a `Session` instance + * Added passing of `next()` to _router_ callbacks. Closes #46 + * Changed; `MemoryStore#destroy()` removes `req.session` + * Changed `res.redirect("back")` to default to "/" when Referr?er is not present + * Fixed _staticProvider_ urlencoded paths issue. Closes #47 + * Fixed _staticProvider_ middleware responding to **GET** requests + * Fixed _jsonrpc_ middleware `Accept` header check. Closes #43 + * Fixed _logger_ format option + * Fixed typo in _compiler_ middleware preventing the _dest_ option from working + +0.1.0 / 2010-06-25 +================== + + * Revamped the api, view the [Connect documentation](http://extjs.github.com/Connect/index.html#Middleware-Authoring) for more info (hover on the right for menu) + * Added [extended api docs](http://extjs.github.com/Connect/api.html) + * Added docs for several more middleware layers + * Added `connect.Server#use()` + * Added _compiler_ middleware which provides arbitrary static compilation + * Added `req.originalUrl` + * Removed _blog_ example + * Removed _sass_ middleware (use _compiler_) + * Removed _less_ middleware (use _compiler_) + * Renamed middleware to be camelcase, _body-decoder_ is now _bodyDecoder_ etc. + * Fixed `req.url` mutation bug when matching `connect.Server#use()` routes + * Fixed `mkdir -p` implementation used in _bin/connect_. Closes #39 + * Fixed bug in _bodyDecoder_ throwing exceptions on request empty bodies + * `make install` installing lib to $LIB_PREFIX aka $HOME/.node_libraries + +0.0.6 / 2010-06-22 +================== + + * Added _static_ middleware usage example + * Added support for regular expressions as paths for _router_ + * Added `util.merge()` + * Increased performance of _static_ by ~ 200 rps + * Renamed the _rest_ middleware to _router_ + * Changed _rest_ api to accept a callback function + * Removed _router_ middleware + * Removed _proto.js_, only `Object#forEach()` remains + +0.0.5 / 2010-06-21 +================== + + * Added Server#use() which contains the Layer normalization logic + * Added documentation for several middleware + * Added several new examples + * Added _less_ middleware + * Added _repl_ middleware + * Added _vhost_ middleware + * Added _flash_ middleware + * Added _cookie_ middleware + * Added _session_ middleware + * Added `utils.htmlEscape()` + * Added `utils.base64Decode()` + * Added `utils.base64Encode()` + * Added `utils.uid()` + * Added bin/connect app path and --config path support for .js suffix, although optional. Closes #26 + * Moved mime code to `utils.mime`, ex `utils.mime.types`, and `utils.mime.type()` + * Renamed req.redirect() to res.redirect(). Closes #29 + * Fixed _sass_ 404 on **ENOENT** + * Fixed +new Date duplication. Closes #24 + +0.0.4 / 2010-06-16 +================== + + * Added workerPidfile() to bin/connect + * Added --workers support to bin/connect stop and status commands + * Added _redirect_ middleware + * Added better --config support to bin/connect. All flags can be utilized + * Added auto-detection of _./config.js_ + * Added config example + * Added `net.Server` support to bin/connect + * Writing worker pids relative to `env.pidfile` + * s/parseQuery/parse/g + * Fixed npm support + +0.0.3 / 2010-06-16 +================== + + * Fixed node dependency in package.json, now _">= 0.1.98-0"_ to support __HEAD__ + +0.0.2 / 2010-06-15 +================== + + * Added `-V, --version` to bin/connect + * Added `utils.parseCookie()` + * Added `utils.serializeCookie()` + * Added `utils.toBoolean()` + * Added _sass_ middleware + * Added _cookie_ middleware + * Added _format_ middleware + * Added _lint_ middleware + * Added _rest_ middleware + * Added _./package.json_ (npm install connect) + * Added `handleError()` support + * Added `process.connectEnv` + * Added custom log format support to _log_ middleware + * Added arbitrary env variable support to bin/connect (ext: --logFormat ":method :url") + * Added -w, --workers to bin/connect + * Added bin/connect support for --user NAME and --group NAME + * Fixed url re-writing support + +0.0.1 / 2010-06-03 +================== + + * Initial release + diff --git a/node_modules/connect/LICENSE b/node_modules/connect/LICENSE new file mode 100644 index 0000000..9c27617 --- /dev/null +++ b/node_modules/connect/LICENSE @@ -0,0 +1,25 @@ +(The MIT License) + +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 LearnBoost +Copyright (c) 2011-2014 TJ Holowaychuk +Copyright (c) 2015 Douglas Christopher Wilson + +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. diff --git a/node_modules/connect/Readme.md b/node_modules/connect/Readme.md new file mode 100644 index 0000000..74dc98f --- /dev/null +++ b/node_modules/connect/Readme.md @@ -0,0 +1,194 @@ +# Connect + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] +[![Gratipay][gratipay-image]][gratipay-url] + + Connect is an extensible HTTP server framework for [node](http://nodejs.org) using "plugins" known as _middleware_. + +```js +var connect = require('connect'); +var http = require('http'); + +var app = connect(); + +// gzip/deflate outgoing responses +var compression = require('compression'); +app.use(compression()); + +// store session state in browser cookie +var cookieSession = require('cookie-session'); +app.use(cookieSession({ + keys: ['secret1', 'secret2'] +})); + +// parse urlencoded request bodies into req.body +var bodyParser = require('body-parser'); +app.use(bodyParser.urlencoded()); + +// respond to all requests +app.use(function(req, res){ + res.end('Hello from Connect!\n'); +}); + +//create node.js http server and listen on port +http.createServer(app).listen(3000); +``` + +## Getting Started + +Connect is a simple framework to glue together various "middleware" to handle requests. + +### Install Connect + +```sh +$ npm install connect +``` + +### Create an app + +The main component is a Connect "app". This will store all the middleware +added and is, itself, a function. + +```js +var app = connect(); +``` + +### Use middleware + +The core of Connect is "using" middleware. Middleware are added as a "stack" +where incoming requests will execute each middleware one-by-one until a middleware +does not call `next()` within it. + +```js +app.use(function middleware1(req, res, next) { + // middleware 1 + next(); +}); +app.use(function middleware2(req, res, next) { + // middleware 2 + next(); +}); +``` + +### Mount middleware + +The `.use()` method also takes an optional path string that is matched against +the beginning of the incoming request URL. This allows for basic routing. + +```js +app.use('/foo', function fooMiddleware(req, res, next) { + // req.url starts with "/foo" + next(); +}); +app.use('/bar', function barMiddleware(req, res, next) { + // req.url starts with "/bar" + next(); +}); +``` + +### Error middleware + +There are special cases of "error-handling" middleware. There are middleware +where the function takes exactly 4 arguments. Errors that occur in the middleware +added before the error middleware will invoke this middleware when errors occur. + +```js +app.use(function onerror(err, req, res, next) { + // an error occurred! +}); +``` + +### Create a server from the app + +The last step is to actually use the Connect app in a server. The `.listen()` method +is a convenience to start a HTTP server. + +```js +var server = app.listen(port); +``` + +The app itself is really just a function with three arguments, so it can also be handed +to `.createServer()` in Node.js. + +```js +var server = http.createServer(app); +``` + +## Middleware + +These middleware and libraries are officially supported by the Connect/Express team: + + - [body-parser](https://www.npmjs.com/package/body-parser) - previous `bodyParser`, `json`, and `urlencoded`. You may also be interested in: + - [body](https://www.npmjs.com/package/body) + - [co-body](https://www.npmjs.com/package/co-body) + - [raw-body](https://www.npmjs.com/package/raw-body) + - [compression](https://www.npmjs.com/package/compression) - previously `compress` + - [connect-timeout](https://www.npmjs.com/package/connect-timeout) - previously `timeout` + - [cookie-parser](https://www.npmjs.com/package/cookie-parser) - previously `cookieParser` + - [cookie-session](https://www.npmjs.com/package/cookie-session) - previously `cookieSession` + - [csurf](https://www.npmjs.com/package/csurf) - previously `csrf` + - [errorhandler](https://www.npmjs.com/package/errorhandler) - previously `error-handler` + - [express-session](https://www.npmjs.com/package/express-session) - previously `session` + - [method-override](https://www.npmjs.com/package/method-override) - previously `method-override` + - [morgan](https://www.npmjs.com/package/morgan) - previously `logger` + - [response-time](https://www.npmjs.com/package/response-time) - previously `response-time` + - [serve-favicon](https://www.npmjs.com/package/serve-favicon) - previously `favicon` + - [serve-index](https://www.npmjs.com/package/serve-index) - previously `directory` + - [serve-static](https://www.npmjs.com/package/serve-static) - previously `static` + - [vhost](https://www.npmjs.com/package/vhost) - previously `vhost` + +Most of these are exact ports of their Connect 2.x equivalents. The primary exception is `cookie-session`. + +Some middleware previously included with Connect are no longer supported by the Connect/Express team, are replaced by an alternative module, or should be superseded by a better module. Use one of these alternatives instead: + + - `cookieParser` + - [cookies](https://www.npmjs.com/package/cookies) and [keygrip](https://www.npmjs.com/package/keygrip) + - `limit` + - [raw-body](https://www.npmjs.com/package/raw-body) + - `multipart` + - [connect-multiparty](https://www.npmjs.com/package/connect-multiparty) + - [connect-busboy](https://www.npmjs.com/package/connect-busboy) + - `query` + - [qs](https://www.npmjs.com/package/qs) + - `staticCache` + - [st](https://www.npmjs.com/package/st) + - [connect-static](https://www.npmjs.com/package/connect-static) + +Checkout [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) for many other compatible middleware! + +## Running Tests + +```bash +npm install +npm test +``` + +## Contributors + + https://github.com/senchalabs/connect/graphs/contributors + +## Node Compatibility + + - Connect `< 1.x` - node `0.2` + - Connect `1.x` - node `0.4` + - Connect `< 2.8` - node `0.6` + - Connect `>= 2.8 < 3` - node `0.8` + - Connect `>= 3` - node `0.10`, `0.12`; io.js `1.x`, `2.x` + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/connect.svg +[npm-url]: https://npmjs.org/package/connect +[travis-image]: https://img.shields.io/travis/senchalabs/connect/master.svg +[travis-url]: https://travis-ci.org/senchalabs/connect +[coveralls-image]: https://img.shields.io/coveralls/senchalabs/connect/master.svg +[coveralls-url]: https://coveralls.io/r/senchalabs/connect +[downloads-image]: https://img.shields.io/npm/dm/connect.svg +[downloads-url]: https://npmjs.org/package/connect +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg +[gratipay-url]: https://www.gratipay.com/dougwilson/ diff --git a/node_modules/connect/index.js b/node_modules/connect/index.js new file mode 100644 index 0000000..6473a3a --- /dev/null +++ b/node_modules/connect/index.js @@ -0,0 +1,283 @@ +/*! + * connect + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module dependencies. + * @private + */ + +var debug = require('debug')('connect:dispatcher'); +var EventEmitter = require('events').EventEmitter; +var finalhandler = require('finalhandler'); +var http = require('http'); +var merge = require('utils-merge'); +var parseUrl = require('parseurl'); + +/** + * Module exports. + * @public + */ + +module.exports = createServer; + +/** + * Module variables. + * @private + */ + +var env = process.env.NODE_ENV || 'development'; +var proto = {}; + +/* istanbul ignore next */ +var defer = typeof setImmediate === 'function' + ? setImmediate + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } + +/** + * Create a new connect server. + * + * @return {function} + * @public + */ + +function createServer() { + function app(req, res, next){ app.handle(req, res, next); } + merge(app, proto); + merge(app, EventEmitter.prototype); + app.route = '/'; + app.stack = []; + return app; +} + +/** + * Utilize the given middleware `handle` to the given `route`, + * defaulting to _/_. This "route" is the mount-point for the + * middleware, when given a value other than _/_ the middleware + * is only effective when that segment is present in the request's + * pathname. + * + * For example if we were to mount a function at _/admin_, it would + * be invoked on _/admin_, and _/admin/settings_, however it would + * not be invoked for _/_, or _/posts_. + * + * @param {String|Function|Server} route, callback or server + * @param {Function|Server} callback or server + * @return {Server} for chaining + * @public + */ + +proto.use = function use(route, fn) { + var handle = fn; + var path = route; + + // default route to '/' + if (typeof route !== 'string') { + handle = route; + path = '/'; + } + + // wrap sub-apps + if (typeof handle.handle === 'function') { + var server = handle; + server.route = path; + handle = function (req, res, next) { + server.handle(req, res, next); + }; + } + + // wrap vanilla http.Servers + if (handle instanceof http.Server) { + handle = handle.listeners('request')[0]; + } + + // strip trailing slash + if (path[path.length - 1] === '/') { + path = path.slice(0, -1); + } + + // add the middleware + debug('use %s %s', path || '/', handle.name || 'anonymous'); + this.stack.push({ route: path, handle: handle }); + + return this; +}; + +/** + * Handle server requests, punting them down + * the middleware stack. + * + * @private + */ + +proto.handle = function handle(req, res, out) { + var index = 0; + var protohost = getProtohost(req.url) || ''; + var removed = ''; + var slashAdded = false; + var stack = this.stack; + + // final function handler + var done = out || finalhandler(req, res, { + env: env, + onerror: logerror + }); + + // store the original URL + req.originalUrl = req.originalUrl || req.url; + + function next(err) { + if (slashAdded) { + req.url = req.url.substr(1); + slashAdded = false; + } + + if (removed.length !== 0) { + req.url = protohost + removed + req.url.substr(protohost.length); + removed = ''; + } + + // next callback + var layer = stack[index++]; + + // all done + if (!layer) { + defer(done, err); + return; + } + + // route data + var path = parseUrl(req).pathname || '/'; + var route = layer.route; + + // skip this layer if the route doesn't match + if (path.toLowerCase().substr(0, route.length) !== route.toLowerCase()) { + return next(err); + } + + // skip if route match does not border "/", ".", or end + var c = path[route.length]; + if (c !== undefined && '/' !== c && '.' !== c) { + return next(err); + } + + // trim off the part of the url that matches the route + if (route.length !== 0 && route !== '/') { + removed = route; + req.url = protohost + req.url.substr(protohost.length + removed.length); + + // ensure leading slash + if (!protohost && req.url[0] !== '/') { + req.url = '/' + req.url; + slashAdded = true; + } + } + + // call the layer handle + call(layer.handle, route, err, req, res, next); + } + + next(); +}; + +/** + * Listen for connections. + * + * This method takes the same arguments + * as node's `http.Server#listen()`. + * + * HTTP and HTTPS: + * + * If you run your application both as HTTP + * and HTTPS you may wrap them individually, + * since your Connect "server" is really just + * a JavaScript `Function`. + * + * var connect = require('connect') + * , http = require('http') + * , https = require('https'); + * + * var app = connect(); + * + * http.createServer(app).listen(80); + * https.createServer(options, app).listen(443); + * + * @return {http.Server} + * @api public + */ + +proto.listen = function listen() { + var server = http.createServer(this); + return server.listen.apply(server, arguments); +}; + +/** + * Invoke a route handle. + * @private + */ + +function call(handle, route, err, req, res, next) { + var arity = handle.length; + var error = err; + var hasError = Boolean(err); + + debug('%s %s : %s', handle.name || '', route, req.originalUrl); + + try { + if (hasError && arity === 4) { + // error-handling middleware + handle(err, req, res, next); + return; + } else if (!hasError && arity < 4) { + // request-handling middleware + handle(req, res, next); + return; + } + } catch (e) { + // replace the error + error = e; + } + + // continue + next(error); +} + +/** + * Log error using console.error. + * + * @param {Error} err + * @private + */ + +function logerror(err) { + if (env !== 'test') console.error(err.stack || err.toString()); +} + +/** + * Get get protocol + host for a URL. + * + * @param {string} url + * @private + */ + +function getProtohost(url) { + if (url.length === 0 || url[0] === '/') { + return undefined; + } + + var searchIndex = url.indexOf('?'); + var pathLength = searchIndex !== -1 + ? searchIndex + : url.length; + var fqdnIndex = url.substr(0, pathLength).indexOf('://'); + + return fqdnIndex !== -1 + ? url.substr(0, url.indexOf('/', 3 + fqdnIndex)) + : undefined; +} diff --git a/node_modules/connect/node_modules/finalhandler/HISTORY.md b/node_modules/connect/node_modules/finalhandler/HISTORY.md new file mode 100644 index 0000000..78dddc0 --- /dev/null +++ b/node_modules/connect/node_modules/finalhandler/HISTORY.md @@ -0,0 +1,98 @@ +0.4.1 / 2015-12-02 +================== + + * deps: escape-html@~1.0.3 + - perf: enable strict mode + - perf: optimize string replacement + - perf: use faster string coercion + +0.4.0 / 2015-06-14 +================== + + * Fix a false-positive when unpiping in Node.js 0.8 + * Support `statusCode` property on `Error` objects + * Use `unpipe` module for unpiping requests + * deps: escape-html@1.0.2 + * deps: on-finished@~2.3.0 + - Add defined behavior for HTTP `CONNECT` requests + - Add defined behavior for HTTP `Upgrade` requests + - deps: ee-first@1.1.1 + * perf: enable strict mode + * perf: remove argument reassignment + +0.3.6 / 2015-05-11 +================== + + * deps: debug@~2.2.0 + - deps: ms@0.7.1 + +0.3.5 / 2015-04-22 +================== + + * deps: on-finished@~2.2.1 + - Fix `isFinished(req)` when data buffered + +0.3.4 / 2015-03-15 +================== + + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + +0.3.3 / 2015-01-01 +================== + + * deps: debug@~2.1.1 + * deps: on-finished@~2.2.0 + +0.3.2 / 2014-10-22 +================== + + * deps: on-finished@~2.1.1 + - Fix handling of pipelined requests + +0.3.1 / 2014-10-16 +================== + + * deps: debug@~2.1.0 + - Implement `DEBUG_FD` env variable support + +0.3.0 / 2014-09-17 +================== + + * Terminate in progress response only on error + * Use `on-finished` to determine request status + +0.2.0 / 2014-09-03 +================== + + * Set `X-Content-Type-Options: nosniff` header + * deps: debug@~2.0.0 + +0.1.0 / 2014-07-16 +================== + + * Respond after request fully read + - prevents hung responses and socket hang ups + * deps: debug@1.0.4 + +0.0.3 / 2014-07-11 +================== + + * deps: debug@1.0.3 + - Add support for multiple wildcards in namespaces + +0.0.2 / 2014-06-19 +================== + + * Handle invalid status codes + +0.0.1 / 2014-06-05 +================== + + * deps: debug@1.0.2 + +0.0.0 / 2014-06-05 +================== + + * Extracted from connect/express diff --git a/node_modules/connect/node_modules/finalhandler/LICENSE b/node_modules/connect/node_modules/finalhandler/LICENSE new file mode 100644 index 0000000..b60a5ad --- /dev/null +++ b/node_modules/connect/node_modules/finalhandler/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014-2015 Douglas Christopher Wilson + +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. diff --git a/node_modules/connect/node_modules/finalhandler/README.md b/node_modules/connect/node_modules/finalhandler/README.md new file mode 100644 index 0000000..6b171d4 --- /dev/null +++ b/node_modules/connect/node_modules/finalhandler/README.md @@ -0,0 +1,133 @@ +# finalhandler + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-image]][node-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +Node.js function to invoke as the final step to respond to HTTP request. + +## Installation + +```sh +$ npm install finalhandler +``` + +## API + +```js +var finalhandler = require('finalhandler') +``` + +### finalhandler(req, res, [options]) + +Returns function to be invoked as the final step for the given `req` and `res`. +This function is to be invoked as `fn(err)`. If `err` is falsy, the handler will +write out a 404 response to the `res`. If it is truthy, an error response will +be written out to the `res`, and `res.statusCode` is set from `err.status`. + +The final handler will also unpipe anything from `req` when it is invoked. + +#### options.env + +By default, the environment is determined by `NODE_ENV` variable, but it can be +overridden by this option. + +#### options.onerror + +Provide a function to be called with the `err` when it exists. Can be used for +writing errors to a central location without excessive function generation. Called +as `onerror(err, req, res)`. + +## Examples + +### always 404 + +```js +var finalhandler = require('finalhandler') +var http = require('http') + +var server = http.createServer(function (req, res) { + var done = finalhandler(req, res) + done() +}) + +server.listen(3000) +``` + +### perform simple action + +```js +var finalhandler = require('finalhandler') +var fs = require('fs') +var http = require('http') + +var server = http.createServer(function (req, res) { + var done = finalhandler(req, res) + + fs.readFile('index.html', function (err, buf) { + if (err) return done(err) + res.setHeader('Content-Type', 'text/html') + res.end(buf) + }) +}) + +server.listen(3000) +``` + +### use with middleware-style functions + +```js +var finalhandler = require('finalhandler') +var http = require('http') +var serveStatic = require('serve-static') + +var serve = serveStatic('public') + +var server = http.createServer(function (req, res) { + var done = finalhandler(req, res) + serve(req, res, done) +}) + +server.listen(3000) +``` + +### keep log of all errors + +```js +var finalhandler = require('finalhandler') +var fs = require('fs') +var http = require('http') + +var server = http.createServer(function (req, res) { + var done = finalhandler(req, res, {onerror: logerror}) + + fs.readFile('index.html', function (err, buf) { + if (err) return done(err) + res.setHeader('Content-Type', 'text/html') + res.end(buf) + }) +}) + +server.listen(3000) + +function logerror(err) { + console.error(err.stack || err.toString()) +} +``` + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/finalhandler.svg +[npm-url]: https://npmjs.org/package/finalhandler +[node-image]: https://img.shields.io/node/v/finalhandler.svg +[node-url]: http://nodejs.org/download/ +[travis-image]: https://img.shields.io/travis/pillarjs/finalhandler.svg +[travis-url]: https://travis-ci.org/pillarjs/finalhandler +[coveralls-image]: https://img.shields.io/coveralls/pillarjs/finalhandler.svg +[coveralls-url]: https://coveralls.io/r/pillarjs/finalhandler?branch=master +[downloads-image]: https://img.shields.io/npm/dm/finalhandler.svg +[downloads-url]: https://npmjs.org/package/finalhandler diff --git a/node_modules/connect/node_modules/finalhandler/index.js b/node_modules/connect/node_modules/finalhandler/index.js new file mode 100644 index 0000000..0de7c6b --- /dev/null +++ b/node_modules/connect/node_modules/finalhandler/index.js @@ -0,0 +1,151 @@ +/*! + * finalhandler + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var debug = require('debug')('finalhandler') +var escapeHtml = require('escape-html') +var http = require('http') +var onFinished = require('on-finished') +var unpipe = require('unpipe') + +/** + * Module variables. + * @private + */ + +/* istanbul ignore next */ +var defer = typeof setImmediate === 'function' + ? setImmediate + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } +var isFinished = onFinished.isFinished + +/** + * Module exports. + * @public + */ + +module.exports = finalhandler + +/** + * Create a function to handle the final response. + * + * @param {Request} req + * @param {Response} res + * @param {Object} [options] + * @return {Function} + * @public + */ + +function finalhandler(req, res, options) { + var opts = options || {} + + // get environment + var env = opts.env || process.env.NODE_ENV || 'development' + + // get error callback + var onerror = opts.onerror + + return function (err) { + var status = res.statusCode + + // ignore 404 on in-flight response + if (!err && res._header) { + debug('cannot 404 after headers sent') + return + } + + // unhandled error + if (err) { + // respect err.statusCode + if (err.statusCode) { + status = err.statusCode + } + + // respect err.status + if (err.status) { + status = err.status + } + + // default status code to 500 + if (!status || status < 400) { + status = 500 + } + + // production gets a basic error message + var msg = env === 'production' + ? http.STATUS_CODES[status] + : err.stack || err.toString() + msg = escapeHtml(msg) + .replace(/\n/g, '
    ') + .replace(/ /g, '  ') + '\n' + } else { + status = 404 + msg = 'Cannot ' + escapeHtml(req.method) + ' ' + escapeHtml(req.originalUrl || req.url) + '\n' + } + + debug('default %s', status) + + // schedule onerror callback + if (err && onerror) { + defer(onerror, err, req, res) + } + + // cannot actually respond + if (res._header) { + return req.socket.destroy() + } + + send(req, res, status, msg) + } +} + +/** + * Send response. + * + * @param {IncomingMessage} req + * @param {OutgoingMessage} res + * @param {number} status + * @param {string} body + * @private + */ + +function send(req, res, status, body) { + function write() { + res.statusCode = status + + // security header for content sniffing + res.setHeader('X-Content-Type-Options', 'nosniff') + + // standard headers + res.setHeader('Content-Type', 'text/html; charset=utf-8') + res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8')) + + if (req.method === 'HEAD') { + res.end() + return + } + + res.end(body, 'utf8') + } + + if (isFinished(req)) { + write() + return + } + + // unpipe everything from the request + unpipe(req) + + // flush the request + onFinished(req, write) + req.resume() +} diff --git a/node_modules/connect/node_modules/finalhandler/package.json b/node_modules/connect/node_modules/finalhandler/package.json new file mode 100644 index 0000000..0c79c2b --- /dev/null +++ b/node_modules/connect/node_modules/finalhandler/package.json @@ -0,0 +1,115 @@ +{ + "_args": [ + [ + { + "raw": "finalhandler@0.4.1", + "scope": null, + "escapedName": "finalhandler", + "name": "finalhandler", + "rawSpec": "0.4.1", + "spec": "0.4.1", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\connect" + ] + ], + "_from": "finalhandler@0.4.1", + "_id": "finalhandler@0.4.1", + "_inCache": true, + "_installable": true, + "_location": "/connect/finalhandler", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "finalhandler@0.4.1", + "scope": null, + "escapedName": "finalhandler", + "name": "finalhandler", + "rawSpec": "0.4.1", + "spec": "0.4.1", + "type": "version" + }, + "_requiredBy": [ + "/connect" + ], + "_resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.1.tgz", + "_shasum": "85a17c6c59a94717d262d61230d4b0ebe3d4a14d", + "_shrinkwrap": null, + "_spec": "finalhandler@0.4.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\connect", + "author": { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + "bugs": { + "url": "https://github.com/pillarjs/finalhandler/issues" + }, + "dependencies": { + "debug": "~2.2.0", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "unpipe": "~1.0.0" + }, + "description": "Node.js final http responder", + "devDependencies": { + "istanbul": "0.4.1", + "mocha": "2.3.4", + "readable-stream": "2.0.4", + "supertest": "1.1.0" + }, + "directories": {}, + "dist": { + "shasum": "85a17c6c59a94717d262d61230d4b0ebe3d4a14d", + "tarball": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.1.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "files": [ + "LICENSE", + "HISTORY.md", + "index.js" + ], + "gitHead": "ac2036774059eb93dbac8475580e52433204d4d4", + "homepage": "https://github.com/pillarjs/finalhandler", + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "fishrock123", + "email": "fishrock123@rocketmail.com" + }, + { + "name": "defunctzombie", + "email": "shtylman@gmail.com" + } + ], + "name": "finalhandler", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/pillarjs/finalhandler.git" + }, + "scripts": { + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" + }, + "version": "0.4.1" +} diff --git a/node_modules/connect/package.json b/node_modules/connect/package.json new file mode 100644 index 0000000..9b4aed1 --- /dev/null +++ b/node_modules/connect/package.json @@ -0,0 +1,135 @@ +{ + "_args": [ + [ + { + "raw": "connect", + "scope": null, + "escapedName": "connect", + "name": "connect", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "C:\\Users\\const\\IdeaProjects\\space-game" + ] + ], + "_from": "connect@latest", + "_id": "connect@3.4.1", + "_inCache": true, + "_installable": true, + "_location": "/connect", + "_nodeVersion": "4.2.3", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "2.14.7", + "_phantomChildren": { + "debug": "2.2.0", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "unpipe": "1.0.0" + }, + "_requested": { + "raw": "connect", + "scope": null, + "escapedName": "connect", + "name": "connect", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER" + ], + "_resolved": "https://registry.npmjs.org/connect/-/connect-3.4.1.tgz", + "_shasum": "a21361d3f4099ef761cda6dc4a973bb1ebb0a34d", + "_shrinkwrap": null, + "_spec": "connect", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "bugs": { + "url": "https://github.com/senchalabs/connect/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "Jonathan Ong", + "email": "me@jongleberry.com" + }, + { + "name": "Tim Caswell", + "email": "tim@creationix.com" + } + ], + "dependencies": { + "debug": "~2.2.0", + "finalhandler": "0.4.1", + "parseurl": "~1.3.1", + "utils-merge": "1.0.0" + }, + "description": "High performance middleware framework", + "devDependencies": { + "istanbul": "0.4.2", + "mocha": "2.3.4", + "supertest": "1.1.0" + }, + "directories": {}, + "dist": { + "shasum": "a21361d3f4099ef761cda6dc4a973bb1ebb0a34d", + "tarball": "https://registry.npmjs.org/connect/-/connect-3.4.1.tgz" + }, + "engines": { + "node": ">= 0.10.0" + }, + "files": [ + "LICENSE", + "History.md", + "Readme.md", + "index.js" + ], + "gitHead": "5cc4b6aab3fd7458719ba61edee6ac149831dbbf", + "homepage": "https://github.com/senchalabs/connect#readme", + "keywords": [ + "framework", + "web", + "middleware", + "connect", + "rack" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "name": "connect", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/senchalabs/connect.git" + }, + "scripts": { + "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/" + }, + "version": "3.4.1" +} diff --git a/node_modules/content-disposition/HISTORY.md b/node_modules/content-disposition/HISTORY.md new file mode 100644 index 0000000..76d494c --- /dev/null +++ b/node_modules/content-disposition/HISTORY.md @@ -0,0 +1,45 @@ +0.5.1 / 2016-01-17 +================== + + * perf: enable strict mode + +0.5.0 / 2014-10-11 +================== + + * Add `parse` function + +0.4.0 / 2014-09-21 +================== + + * Expand non-Unicode `filename` to the full ISO-8859-1 charset + +0.3.0 / 2014-09-20 +================== + + * Add `fallback` option + * Add `type` option + +0.2.0 / 2014-09-19 +================== + + * Reduce ambiguity of file names with hex escape in buggy browsers + +0.1.2 / 2014-09-19 +================== + + * Fix periodic invalid Unicode filename header + +0.1.1 / 2014-09-19 +================== + + * Fix invalid characters appearing in `filename*` parameter + +0.1.0 / 2014-09-18 +================== + + * Make the `filename` argument optional + +0.0.0 / 2014-09-18 +================== + + * Initial release diff --git a/node_modules/content-disposition/LICENSE b/node_modules/content-disposition/LICENSE new file mode 100644 index 0000000..b7dce6c --- /dev/null +++ b/node_modules/content-disposition/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014 Douglas Christopher Wilson + +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. diff --git a/node_modules/content-disposition/README.md b/node_modules/content-disposition/README.md new file mode 100644 index 0000000..5cebce4 --- /dev/null +++ b/node_modules/content-disposition/README.md @@ -0,0 +1,141 @@ +# content-disposition + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +Create and parse HTTP `Content-Disposition` header + +## Installation + +```sh +$ npm install content-disposition +``` + +## API + +```js +var contentDisposition = require('content-disposition') +``` + +### contentDisposition(filename, options) + +Create an attachment `Content-Disposition` header value using the given file name, +if supplied. The `filename` is optional and if no file name is desired, but you +want to specify `options`, set `filename` to `undefined`. + +```js +res.setHeader('Content-Disposition', contentDisposition('∫ maths.pdf')) +``` + +**note** HTTP headers are of the ISO-8859-1 character set. If you are writing this +header through a means different from `setHeader` in Node.js, you'll want to specify +the `'binary'` encoding in Node.js. + +#### Options + +`contentDisposition` accepts these properties in the options object. + +##### fallback + +If the `filename` option is outside ISO-8859-1, then the file name is actually +stored in a supplemental field for clients that support Unicode file names and +a ISO-8859-1 version of the file name is automatically generated. + +This specifies the ISO-8859-1 file name to override the automatic generation or +disables the generation all together, defaults to `true`. + + - A string will specify the ISO-8859-1 file name to use in place of automatic + generation. + - `false` will disable including a ISO-8859-1 file name and only include the + Unicode version (unless the file name is already ISO-8859-1). + - `true` will enable automatic generation if the file name is outside ISO-8859-1. + +If the `filename` option is ISO-8859-1 and this option is specified and has a +different value, then the `filename` option is encoded in the extended field +and this set as the fallback field, even though they are both ISO-8859-1. + +##### type + +Specifies the disposition type, defaults to `"attachment"`. This can also be +`"inline"`, or any other value (all values except inline are treated like +`attachment`, but can convey additional information if both parties agree to +it). The type is normalized to lower-case. + +### contentDisposition.parse(string) + +```js +var disposition = contentDisposition.parse('attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt'); +``` + +Parse a `Content-Disposition` header string. This automatically handles extended +("Unicode") parameters by decoding them and providing them under the standard +parameter name. This will return an object with the following properties (examples +are shown for the string `'attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt'`): + + - `type`: The disposition type (always lower case). Example: `'attachment'` + + - `parameters`: An object of the parameters in the disposition (name of parameter + always lower case and extended versions replace non-extended versions). Example: + `{filename: "€ rates.txt"}` + +## Examples + +### Send a file for download + +```js +var contentDisposition = require('content-disposition') +var destroy = require('destroy') +var http = require('http') +var onFinished = require('on-finished') + +var filePath = '/path/to/public/plans.pdf' + +http.createServer(function onRequest(req, res) { + // set headers + res.setHeader('Content-Type', 'application/pdf') + res.setHeader('Content-Disposition', contentDisposition(filePath)) + + // send file + var stream = fs.createReadStream(filePath) + stream.pipe(res) + onFinished(res, function (err) { + destroy(stream) + }) +}) +``` + +## Testing + +```sh +$ npm test +``` + +## References + +- [RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1][rfc-2616] +- [RFC 5987: Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters][rfc-5987] +- [RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)][rfc-6266] +- [Test Cases for HTTP Content-Disposition header field (RFC 6266) and the Encodings defined in RFCs 2047, 2231 and 5987][tc-2231] + +[rfc-2616]: https://tools.ietf.org/html/rfc2616 +[rfc-5987]: https://tools.ietf.org/html/rfc5987 +[rfc-6266]: https://tools.ietf.org/html/rfc6266 +[tc-2231]: http://greenbytes.de/tech/tc2231/ + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/content-disposition.svg?style=flat +[npm-url]: https://npmjs.org/package/content-disposition +[node-version-image]: https://img.shields.io/node/v/content-disposition.svg?style=flat +[node-version-url]: http://nodejs.org/download/ +[travis-image]: https://img.shields.io/travis/jshttp/content-disposition.svg?style=flat +[travis-url]: https://travis-ci.org/jshttp/content-disposition +[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-disposition.svg?style=flat +[coveralls-url]: https://coveralls.io/r/jshttp/content-disposition?branch=master +[downloads-image]: https://img.shields.io/npm/dm/content-disposition.svg?style=flat +[downloads-url]: https://npmjs.org/package/content-disposition diff --git a/node_modules/content-disposition/index.js b/node_modules/content-disposition/index.js new file mode 100644 index 0000000..4a352dc --- /dev/null +++ b/node_modules/content-disposition/index.js @@ -0,0 +1,445 @@ +/*! + * content-disposition + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + */ + +module.exports = contentDisposition +module.exports.parse = parse + +/** + * Module dependencies. + */ + +var basename = require('path').basename + +/** + * RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%") + */ + +var encodeUriAttrCharRegExp = /[\x00-\x20"'\(\)*,\/:;<=>?@\[\\\]\{\}\x7f]/g + +/** + * RegExp to match percent encoding escape. + */ + +var hexEscapeRegExp = /%[0-9A-Fa-f]{2}/ +var hexEscapeReplaceRegExp = /%([0-9A-Fa-f]{2})/g + +/** + * RegExp to match non-latin1 characters. + */ + +var nonLatin1RegExp = /[^\x20-\x7e\xa0-\xff]/g + +/** + * RegExp to match quoted-pair in RFC 2616 + * + * quoted-pair = "\" CHAR + * CHAR = + */ + +var qescRegExp = /\\([\u0000-\u007f])/g; + +/** + * RegExp to match chars that must be quoted-pair in RFC 2616 + */ + +var quoteRegExp = /([\\"])/g + +/** + * RegExp for various RFC 2616 grammar + * + * parameter = token "=" ( token | quoted-string ) + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) + * qdtext = > + * quoted-pair = "\" CHAR + * CHAR = + * TEXT = + * LWS = [CRLF] 1*( SP | HT ) + * CRLF = CR LF + * CR = + * LF = + * SP = + * HT = + * CTL = + * OCTET = + */ + +var paramRegExp = /; *([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *= *("(?:[ !\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) */g +var textRegExp = /^[\x20-\x7e\x80-\xff]+$/ +var tokenRegExp = /^[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+$/ + +/** + * RegExp for various RFC 5987 grammar + * + * ext-value = charset "'" [ language ] "'" value-chars + * charset = "UTF-8" / "ISO-8859-1" / mime-charset + * mime-charset = 1*mime-charsetc + * mime-charsetc = ALPHA / DIGIT + * / "!" / "#" / "$" / "%" / "&" + * / "+" / "-" / "^" / "_" / "`" + * / "{" / "}" / "~" + * language = ( 2*3ALPHA [ extlang ] ) + * / 4ALPHA + * / 5*8ALPHA + * extlang = *3( "-" 3ALPHA ) + * value-chars = *( pct-encoded / attr-char ) + * pct-encoded = "%" HEXDIG HEXDIG + * attr-char = ALPHA / DIGIT + * / "!" / "#" / "$" / "&" / "+" / "-" / "." + * / "^" / "_" / "`" / "|" / "~" + */ + +var extValueRegExp = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+\-\.^_`|~])+)$/ + +/** + * RegExp for various RFC 6266 grammar + * + * disposition-type = "inline" | "attachment" | disp-ext-type + * disp-ext-type = token + * disposition-parm = filename-parm | disp-ext-parm + * filename-parm = "filename" "=" value + * | "filename*" "=" ext-value + * disp-ext-parm = token "=" value + * | ext-token "=" ext-value + * ext-token = + */ + +var dispositionTypeRegExp = /^([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *(?:$|;)/ + +/** + * Create an attachment Content-Disposition header. + * + * @param {string} [filename] + * @param {object} [options] + * @param {string} [options.type=attachment] + * @param {string|boolean} [options.fallback=true] + * @return {string} + * @api public + */ + +function contentDisposition(filename, options) { + var opts = options || {} + + // get type + var type = opts.type || 'attachment' + + // get parameters + var params = createparams(filename, opts.fallback) + + // format into string + return format(new ContentDisposition(type, params)) +} + +/** + * Create parameters object from filename and fallback. + * + * @param {string} [filename] + * @param {string|boolean} [fallback=true] + * @return {object} + * @api private + */ + +function createparams(filename, fallback) { + if (filename === undefined) { + return + } + + var params = {} + + if (typeof filename !== 'string') { + throw new TypeError('filename must be a string') + } + + // fallback defaults to true + if (fallback === undefined) { + fallback = true + } + + if (typeof fallback !== 'string' && typeof fallback !== 'boolean') { + throw new TypeError('fallback must be a string or boolean') + } + + if (typeof fallback === 'string' && nonLatin1RegExp.test(fallback)) { + throw new TypeError('fallback must be ISO-8859-1 string') + } + + // restrict to file base name + var name = basename(filename) + + // determine if name is suitable for quoted string + var isQuotedString = textRegExp.test(name) + + // generate fallback name + var fallbackName = typeof fallback !== 'string' + ? fallback && getlatin1(name) + : basename(fallback) + var hasFallback = typeof fallbackName === 'string' && fallbackName !== name + + // set extended filename parameter + if (hasFallback || !isQuotedString || hexEscapeRegExp.test(name)) { + params['filename*'] = name + } + + // set filename parameter + if (isQuotedString || hasFallback) { + params.filename = hasFallback + ? fallbackName + : name + } + + return params +} + +/** + * Format object to Content-Disposition header. + * + * @param {object} obj + * @param {string} obj.type + * @param {object} [obj.parameters] + * @return {string} + * @api private + */ + +function format(obj) { + var parameters = obj.parameters + var type = obj.type + + if (!type || typeof type !== 'string' || !tokenRegExp.test(type)) { + throw new TypeError('invalid type') + } + + // start with normalized type + var string = String(type).toLowerCase() + + // append parameters + if (parameters && typeof parameters === 'object') { + var param + var params = Object.keys(parameters).sort() + + for (var i = 0; i < params.length; i++) { + param = params[i] + + var val = param.substr(-1) === '*' + ? ustring(parameters[param]) + : qstring(parameters[param]) + + string += '; ' + param + '=' + val + } + } + + return string +} + +/** + * Decode a RFC 6987 field value (gracefully). + * + * @param {string} str + * @return {string} + * @api private + */ + +function decodefield(str) { + var match = extValueRegExp.exec(str) + + if (!match) { + throw new TypeError('invalid extended field value') + } + + var charset = match[1].toLowerCase() + var encoded = match[2] + var value + + // to binary string + var binary = encoded.replace(hexEscapeReplaceRegExp, pdecode) + + switch (charset) { + case 'iso-8859-1': + value = getlatin1(binary) + break + case 'utf-8': + value = new Buffer(binary, 'binary').toString('utf8') + break + default: + throw new TypeError('unsupported charset in extended field') + } + + return value +} + +/** + * Get ISO-8859-1 version of string. + * + * @param {string} val + * @return {string} + * @api private + */ + +function getlatin1(val) { + // simple Unicode -> ISO-8859-1 transformation + return String(val).replace(nonLatin1RegExp, '?') +} + +/** + * Parse Content-Disposition header string. + * + * @param {string} string + * @return {object} + * @api private + */ + +function parse(string) { + if (!string || typeof string !== 'string') { + throw new TypeError('argument string is required') + } + + var match = dispositionTypeRegExp.exec(string) + + if (!match) { + throw new TypeError('invalid type format') + } + + // normalize type + var index = match[0].length + var type = match[1].toLowerCase() + + var key + var names = [] + var params = {} + var value + + // calculate index to start at + index = paramRegExp.lastIndex = match[0].substr(-1) === ';' + ? index - 1 + : index + + // match parameters + while (match = paramRegExp.exec(string)) { + if (match.index !== index) { + throw new TypeError('invalid parameter format') + } + + index += match[0].length + key = match[1].toLowerCase() + value = match[2] + + if (names.indexOf(key) !== -1) { + throw new TypeError('invalid duplicate parameter') + } + + names.push(key) + + if (key.indexOf('*') + 1 === key.length) { + // decode extended value + key = key.slice(0, -1) + value = decodefield(value) + + // overwrite existing value + params[key] = value + continue + } + + if (typeof params[key] === 'string') { + continue + } + + if (value[0] === '"') { + // remove quotes and escapes + value = value + .substr(1, value.length - 2) + .replace(qescRegExp, '$1') + } + + params[key] = value + } + + if (index !== -1 && index !== string.length) { + throw new TypeError('invalid parameter format') + } + + return new ContentDisposition(type, params) +} + +/** + * Percent decode a single character. + * + * @param {string} str + * @param {string} hex + * @return {string} + * @api private + */ + +function pdecode(str, hex) { + return String.fromCharCode(parseInt(hex, 16)) +} + +/** + * Percent encode a single character. + * + * @param {string} char + * @return {string} + * @api private + */ + +function pencode(char) { + var hex = String(char) + .charCodeAt(0) + .toString(16) + .toUpperCase() + return hex.length === 1 + ? '%0' + hex + : '%' + hex +} + +/** + * Quote a string for HTTP. + * + * @param {string} val + * @return {string} + * @api private + */ + +function qstring(val) { + var str = String(val) + + return '"' + str.replace(quoteRegExp, '\\$1') + '"' +} + +/** + * Encode a Unicode string for HTTP (RFC 5987). + * + * @param {string} val + * @return {string} + * @api private + */ + +function ustring(val) { + var str = String(val) + + // percent encode as UTF-8 + var encoded = encodeURIComponent(str) + .replace(encodeUriAttrCharRegExp, pencode) + + return 'UTF-8\'\'' + encoded +} + +/** + * Class for parsed Content-Disposition header for v8 optimization + */ + +function ContentDisposition(type, parameters) { + this.type = type + this.parameters = parameters +} diff --git a/node_modules/content-disposition/package.json b/node_modules/content-disposition/package.json new file mode 100644 index 0000000..4b3ce88 --- /dev/null +++ b/node_modules/content-disposition/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "content-disposition@0.5.1", + "scope": null, + "escapedName": "content-disposition", + "name": "content-disposition", + "rawSpec": "0.5.1", + "spec": "0.5.1", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "content-disposition@0.5.1", + "_id": "content-disposition@0.5.1", + "_inCache": true, + "_installable": true, + "_location": "/content-disposition", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "content-disposition@0.5.1", + "scope": null, + "escapedName": "content-disposition", + "name": "content-disposition", + "rawSpec": "0.5.1", + "spec": "0.5.1", + "type": "version" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.1.tgz", + "_shasum": "87476c6a67c8daa87e32e87616df883ba7fb071b", + "_shrinkwrap": null, + "_spec": "content-disposition@0.5.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "bugs": { + "url": "https://github.com/jshttp/content-disposition/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "Create and parse Content-Disposition header", + "devDependencies": { + "istanbul": "0.4.2", + "mocha": "1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "87476c6a67c8daa87e32e87616df883ba7fb071b", + "tarball": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.1.tgz" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "LICENSE", + "HISTORY.md", + "README.md", + "index.js" + ], + "gitHead": "7b391db3af5629d4c698f1de21802940bb9f22a5", + "homepage": "https://github.com/jshttp/content-disposition", + "keywords": [ + "content-disposition", + "http", + "rfc6266", + "res" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "content-disposition", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jshttp/content-disposition.git" + }, + "scripts": { + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" + }, + "version": "0.5.1" +} diff --git a/node_modules/content-type/HISTORY.md b/node_modules/content-type/HISTORY.md new file mode 100644 index 0000000..01652ff --- /dev/null +++ b/node_modules/content-type/HISTORY.md @@ -0,0 +1,14 @@ +1.0.2 / 2016-05-09 +================== + + * perf: enable strict mode + +1.0.1 / 2015-02-13 +================== + + * Improve missing `Content-Type` header error message + +1.0.0 / 2015-02-01 +================== + + * Initial implementation, derived from `media-typer@0.3.0` diff --git a/node_modules/content-type/LICENSE b/node_modules/content-type/LICENSE new file mode 100644 index 0000000..34b1a2d --- /dev/null +++ b/node_modules/content-type/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2015 Douglas Christopher Wilson + +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. diff --git a/node_modules/content-type/README.md b/node_modules/content-type/README.md new file mode 100644 index 0000000..3ed6741 --- /dev/null +++ b/node_modules/content-type/README.md @@ -0,0 +1,92 @@ +# content-type + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +Create and parse HTTP Content-Type header according to RFC 7231 + +## Installation + +```sh +$ npm install content-type +``` + +## API + +```js +var contentType = require('content-type') +``` + +### contentType.parse(string) + +```js +var obj = contentType.parse('image/svg+xml; charset=utf-8') +``` + +Parse a content type string. This will return an object with the following +properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`): + + - `type`: The media type (the type and subtype, always lower case). + Example: `'image/svg+xml'` + + - `parameters`: An object of the parameters in the media type (name of parameter + always lower case). Example: `{charset: 'utf-8'}` + +Throws a `TypeError` if the string is missing or invalid. + +### contentType.parse(req) + +```js +var obj = contentType.parse(req) +``` + +Parse the `content-type` header from the given `req`. Short-cut for +`contentType.parse(req.headers['content-type'])`. + +Throws a `TypeError` if the `Content-Type` header is missing or invalid. + +### contentType.parse(res) + +```js +var obj = contentType.parse(res) +``` + +Parse the `content-type` header set on the given `res`. Short-cut for +`contentType.parse(res.getHeader('content-type'))`. + +Throws a `TypeError` if the `Content-Type` header is missing or invalid. + +### contentType.format(obj) + +```js +var str = contentType.format({type: 'image/svg+xml'}) +``` + +Format an object into a content type string. This will return a string of the +content type for the given object with the following properties (examples are +shown that produce the string `'image/svg+xml; charset=utf-8'`): + + - `type`: The media type (will be lower-cased). Example: `'image/svg+xml'` + + - `parameters`: An object of the parameters in the media type (name of the + parameter will be lower-cased). Example: `{charset: 'utf-8'}` + +Throws a `TypeError` if the object contains an invalid type or parameter names. + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/content-type.svg +[npm-url]: https://npmjs.org/package/content-type +[node-version-image]: https://img.shields.io/node/v/content-type.svg +[node-version-url]: http://nodejs.org/download/ +[travis-image]: https://img.shields.io/travis/jshttp/content-type/master.svg +[travis-url]: https://travis-ci.org/jshttp/content-type +[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-type/master.svg +[coveralls-url]: https://coveralls.io/r/jshttp/content-type +[downloads-image]: https://img.shields.io/npm/dm/content-type.svg +[downloads-url]: https://npmjs.org/package/content-type diff --git a/node_modules/content-type/index.js b/node_modules/content-type/index.js new file mode 100644 index 0000000..61ba6b5 --- /dev/null +++ b/node_modules/content-type/index.js @@ -0,0 +1,216 @@ +/*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 + * + * parameter = token "=" ( token / quoted-string ) + * token = 1*tchar + * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + * / DIGIT / ALPHA + * ; any VCHAR, except delimiters + * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text + * obs-text = %x80-FF + * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + */ +var paramRegExp = /; *([!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) */g +var textRegExp = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ +var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/ + +/** + * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 + * + * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + * obs-text = %x80-FF + */ +var qescRegExp = /\\([\u000b\u0020-\u00ff])/g + +/** + * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 + */ +var quoteRegExp = /([\\"])/g + +/** + * RegExp to match type in RFC 6838 + * + * media-type = type "/" subtype + * type = token + * subtype = token + */ +var typeRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+\/[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/ + +/** + * Module exports. + * @public + */ + +exports.format = format +exports.parse = parse + +/** + * Format object to media type. + * + * @param {object} obj + * @return {string} + * @public + */ + +function format(obj) { + if (!obj || typeof obj !== 'object') { + throw new TypeError('argument obj is required') + } + + var parameters = obj.parameters + var type = obj.type + + if (!type || !typeRegExp.test(type)) { + throw new TypeError('invalid type') + } + + var string = type + + // append parameters + if (parameters && typeof parameters === 'object') { + var param + var params = Object.keys(parameters).sort() + + for (var i = 0; i < params.length; i++) { + param = params[i] + + if (!tokenRegExp.test(param)) { + throw new TypeError('invalid parameter name') + } + + string += '; ' + param + '=' + qstring(parameters[param]) + } + } + + return string +} + +/** + * Parse media type to object. + * + * @param {string|object} string + * @return {Object} + * @public + */ + +function parse(string) { + if (!string) { + throw new TypeError('argument string is required') + } + + if (typeof string === 'object') { + // support req/res-like objects as argument + string = getcontenttype(string) + + if (typeof string !== 'string') { + throw new TypeError('content-type header is missing from object'); + } + } + + if (typeof string !== 'string') { + throw new TypeError('argument string is required to be a string') + } + + var index = string.indexOf(';') + var type = index !== -1 + ? string.substr(0, index).trim() + : string.trim() + + if (!typeRegExp.test(type)) { + throw new TypeError('invalid media type') + } + + var key + var match + var obj = new ContentType(type.toLowerCase()) + var value + + paramRegExp.lastIndex = index + + while (match = paramRegExp.exec(string)) { + if (match.index !== index) { + throw new TypeError('invalid parameter format') + } + + index += match[0].length + key = match[1].toLowerCase() + value = match[2] + + if (value[0] === '"') { + // remove quotes and escapes + value = value + .substr(1, value.length - 2) + .replace(qescRegExp, '$1') + } + + obj.parameters[key] = value + } + + if (index !== -1 && index !== string.length) { + throw new TypeError('invalid parameter format') + } + + return obj +} + +/** + * Get content-type from req/res objects. + * + * @param {object} + * @return {Object} + * @private + */ + +function getcontenttype(obj) { + if (typeof obj.getHeader === 'function') { + // res-like + return obj.getHeader('content-type') + } + + if (typeof obj.headers === 'object') { + // req-like + return obj.headers && obj.headers['content-type'] + } +} + +/** + * Quote a string if necessary. + * + * @param {string} val + * @return {string} + * @private + */ + +function qstring(val) { + var str = String(val) + + // no need to quote tokens + if (tokenRegExp.test(str)) { + return str + } + + if (str.length > 0 && !textRegExp.test(str)) { + throw new TypeError('invalid parameter value') + } + + return '"' + str.replace(quoteRegExp, '\\$1') + '"' +} + +/** + * Class to represent a content type. + * @private + */ +function ContentType(type) { + this.parameters = Object.create(null) + this.type = type +} diff --git a/node_modules/content-type/package.json b/node_modules/content-type/package.json new file mode 100644 index 0000000..814559a --- /dev/null +++ b/node_modules/content-type/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "content-type@~1.0.2", + "scope": null, + "escapedName": "content-type", + "name": "content-type", + "rawSpec": "~1.0.2", + "spec": ">=1.0.2 <1.1.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "content-type@>=1.0.2 <1.1.0", + "_id": "content-type@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/content-type", + "_nodeVersion": "4.4.3", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/content-type-1.0.2.tgz_1462852785748_0.5491233412176371" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "2.15.1", + "_phantomChildren": {}, + "_requested": { + "raw": "content-type@~1.0.2", + "scope": null, + "escapedName": "content-type", + "name": "content-type", + "rawSpec": "~1.0.2", + "spec": ">=1.0.2 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "_shasum": "b7d113aee7a8dd27bd21133c4dc2529df1721eed", + "_shrinkwrap": null, + "_spec": "content-type@~1.0.2", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + "bugs": { + "url": "https://github.com/jshttp/content-type/issues" + }, + "dependencies": {}, + "description": "Create and parse HTTP Content-Type header", + "devDependencies": { + "istanbul": "0.4.3", + "mocha": "~1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "b7d113aee7a8dd27bd21133c4dc2529df1721eed", + "tarball": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "LICENSE", + "HISTORY.md", + "README.md", + "index.js" + ], + "gitHead": "8118763adfbbac80cf1254191889330aec8b8be7", + "homepage": "https://github.com/jshttp/content-type#readme", + "keywords": [ + "content-type", + "http", + "req", + "res", + "rfc7231" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "content-type", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jshttp/content-type.git" + }, + "scripts": { + "test": "mocha --reporter spec --check-leaks --bail test/", + "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/" + }, + "version": "1.0.2" +} diff --git a/node_modules/cookie-signature/.npmignore b/node_modules/cookie-signature/.npmignore new file mode 100644 index 0000000..f1250e5 --- /dev/null +++ b/node_modules/cookie-signature/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/node_modules/cookie-signature/History.md b/node_modules/cookie-signature/History.md new file mode 100644 index 0000000..78513cc --- /dev/null +++ b/node_modules/cookie-signature/History.md @@ -0,0 +1,38 @@ +1.0.6 / 2015-02-03 +================== + +* use `npm test` instead of `make test` to run tests +* clearer assertion messages when checking input + + +1.0.5 / 2014-09-05 +================== + +* add license to package.json + +1.0.4 / 2014-06-25 +================== + + * corrected avoidance of timing attacks (thanks @tenbits!) + +1.0.3 / 2014-01-28 +================== + + * [incorrect] fix for timing attacks + +1.0.2 / 2014-01-28 +================== + + * fix missing repository warning + * fix typo in test + +1.0.1 / 2013-04-15 +================== + + * Revert "Changed underlying HMAC algo. to sha512." + * Revert "Fix for timing attacks on MAC verification." + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/cookie-signature/Readme.md b/node_modules/cookie-signature/Readme.md new file mode 100644 index 0000000..2559e84 --- /dev/null +++ b/node_modules/cookie-signature/Readme.md @@ -0,0 +1,42 @@ + +# cookie-signature + + Sign and unsign cookies. + +## Example + +```js +var cookie = require('cookie-signature'); + +var val = cookie.sign('hello', 'tobiiscool'); +val.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI'); + +var val = cookie.sign('hello', 'tobiiscool'); +cookie.unsign(val, 'tobiiscool').should.equal('hello'); +cookie.unsign(val, 'luna').should.be.false; +``` + +## License + +(The MIT License) + +Copyright (c) 2012 LearnBoost <tj@learnboost.com> + +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. \ No newline at end of file diff --git a/node_modules/cookie-signature/index.js b/node_modules/cookie-signature/index.js new file mode 100644 index 0000000..b8c9463 --- /dev/null +++ b/node_modules/cookie-signature/index.js @@ -0,0 +1,51 @@ +/** + * Module dependencies. + */ + +var crypto = require('crypto'); + +/** + * Sign the given `val` with `secret`. + * + * @param {String} val + * @param {String} secret + * @return {String} + * @api private + */ + +exports.sign = function(val, secret){ + if ('string' != typeof val) throw new TypeError("Cookie value must be provided as a string."); + if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); + return val + '.' + crypto + .createHmac('sha256', secret) + .update(val) + .digest('base64') + .replace(/\=+$/, ''); +}; + +/** + * Unsign and decode the given `val` with `secret`, + * returning `false` if the signature is invalid. + * + * @param {String} val + * @param {String} secret + * @return {String|Boolean} + * @api private + */ + +exports.unsign = function(val, secret){ + if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided."); + if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); + var str = val.slice(0, val.lastIndexOf('.')) + , mac = exports.sign(str, secret); + + return sha1(mac) == sha1(val) ? str : false; +}; + +/** + * Private + */ + +function sha1(str){ + return crypto.createHash('sha1').update(str).digest('hex'); +} diff --git a/node_modules/cookie-signature/package.json b/node_modules/cookie-signature/package.json new file mode 100644 index 0000000..40c1d32 --- /dev/null +++ b/node_modules/cookie-signature/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "cookie-signature@1.0.6", + "scope": null, + "escapedName": "cookie-signature", + "name": "cookie-signature", + "rawSpec": "1.0.6", + "spec": "1.0.6", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "cookie-signature@1.0.6", + "_id": "cookie-signature@1.0.6", + "_inCache": true, + "_installable": true, + "_location": "/cookie-signature", + "_nodeVersion": "0.10.36", + "_npmUser": { + "name": "natevw", + "email": "natevw@yahoo.com" + }, + "_npmVersion": "2.3.0", + "_phantomChildren": {}, + "_requested": { + "raw": "cookie-signature@1.0.6", + "scope": null, + "escapedName": "cookie-signature", + "name": "cookie-signature", + "rawSpec": "1.0.6", + "spec": "1.0.6", + "type": "version" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "_shasum": "e303a882b342cc3ee8ca513a79999734dab3ae2c", + "_shrinkwrap": null, + "_spec": "cookie-signature@1.0.6", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@learnboost.com" + }, + "bugs": { + "url": "https://github.com/visionmedia/node-cookie-signature/issues" + }, + "dependencies": {}, + "description": "Sign and unsign cookies", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "e303a882b342cc3ee8ca513a79999734dab3ae2c", + "tarball": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + }, + "gitHead": "391b56cf44d88c493491b7e3fc53208cfb976d2a", + "homepage": "https://github.com/visionmedia/node-cookie-signature", + "keywords": [ + "cookie", + "sign", + "unsign" + ], + "license": "MIT", + "main": "index", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "natevw", + "email": "natevw@yahoo.com" + } + ], + "name": "cookie-signature", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/visionmedia/node-cookie-signature.git" + }, + "scripts": { + "test": "mocha --require should --reporter spec" + }, + "version": "1.0.6" +} diff --git a/node_modules/cookie/HISTORY.md b/node_modules/cookie/HISTORY.md new file mode 100644 index 0000000..5bd6485 --- /dev/null +++ b/node_modules/cookie/HISTORY.md @@ -0,0 +1,118 @@ +0.3.1 / 2016-05-26 +================== + + * Fix `sameSite: true` to work with draft-7 clients + - `true` now sends `SameSite=Strict` instead of `SameSite` + +0.3.0 / 2016-05-26 +================== + + * Add `sameSite` option + - Replaces `firstPartyOnly` option, never implemented by browsers + * Improve error message when `encode` is not a function + * Improve error message when `expires` is not a `Date` + +0.2.4 / 2016-05-20 +================== + + * perf: enable strict mode + * perf: use for loop in parse + * perf: use string concatination for serialization + +0.2.3 / 2015-10-25 +================== + + * Fix cookie `Max-Age` to never be a floating point number + +0.2.2 / 2015-09-17 +================== + + * Fix regression when setting empty cookie value + - Ease the new restriction, which is just basic header-level validation + * Fix typo in invalid value errors + +0.2.1 / 2015-09-17 +================== + + * Throw on invalid values provided to `serialize` + - Ensures the resulting string is a valid HTTP header value + +0.2.0 / 2015-08-13 +================== + + * Add `firstPartyOnly` option + * Throw better error for invalid argument to parse + * perf: hoist regular expression + +0.1.5 / 2015-09-17 +================== + + * Fix regression when setting empty cookie value + - Ease the new restriction, which is just basic header-level validation + * Fix typo in invalid value errors + +0.1.4 / 2015-09-17 +================== + + * Throw better error for invalid argument to parse + * Throw on invalid values provided to `serialize` + - Ensures the resulting string is a valid HTTP header value + +0.1.3 / 2015-05-19 +================== + + * Reduce the scope of try-catch deopt + * Remove argument reassignments + +0.1.2 / 2014-04-16 +================== + + * Remove unnecessary files from npm package + +0.1.1 / 2014-02-23 +================== + + * Fix bad parse when cookie value contained a comma + * Fix support for `maxAge` of `0` + +0.1.0 / 2013-05-01 +================== + + * Add `decode` option + * Add `encode` option + +0.0.6 / 2013-04-08 +================== + + * Ignore cookie parts missing `=` + +0.0.5 / 2012-10-29 +================== + + * Return raw cookie value if value unescape errors + +0.0.4 / 2012-06-21 +================== + + * Use encode/decodeURIComponent for cookie encoding/decoding + - Improve server/client interoperability + +0.0.3 / 2012-06-06 +================== + + * Only escape special characters per the cookie RFC + +0.0.2 / 2012-06-01 +================== + + * Fix `maxAge` option to not throw error + +0.0.1 / 2012-05-28 +================== + + * Add more tests + +0.0.0 / 2012-05-28 +================== + + * Initial release diff --git a/node_modules/cookie/LICENSE b/node_modules/cookie/LICENSE new file mode 100644 index 0000000..058b6b4 --- /dev/null +++ b/node_modules/cookie/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2012-2014 Roman Shtylman +Copyright (c) 2015 Douglas Christopher Wilson + +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. + diff --git a/node_modules/cookie/README.md b/node_modules/cookie/README.md new file mode 100644 index 0000000..db0d078 --- /dev/null +++ b/node_modules/cookie/README.md @@ -0,0 +1,220 @@ +# cookie + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +Basic HTTP cookie parser and serializer for HTTP servers. + +## Installation + +```sh +$ npm install cookie +``` + +## API + +```js +var cookie = require('cookie'); +``` + +### cookie.parse(str, options) + +Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs. +The `str` argument is the string representing a `Cookie` header value and `options` is an +optional object containing additional parsing options. + +```js +var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2'); +// { foo: 'bar', equation: 'E=mc^2' } +``` + +#### Options + +`cookie.parse` accepts these properties in the options object. + +##### decode + +Specifies a function that will be used to decode a cookie's value. Since the value of a cookie +has a limited character set (and must be a simple string), this function can be used to decode +a previously-encoded cookie value into a JavaScript string or other object. + +The default function is the global `decodeURIComponent`, which will decode any URL-encoded +sequences into their byte representations. + +**note** if an error is thrown from this function, the original, non-decoded cookie value will +be returned as the cookie's value. + +### cookie.serialize(name, value, options) + +Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the +name for the cookie, the `value` argument is the value to set the cookie to, and the `options` +argument is an optional object containing additional serialization options. + +```js +var setCookie = cookie.serialize('foo', 'bar'); +// foo=bar +``` + +#### Options + +`cookie.serialize` accepts these properties in the options object. + +##### domain + +Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6266-5.2.3]. By default, no +domain is set, and most clients will consider the cookie to apply to only the current domain. + +##### encode + +Specifies a function that will be used to encode a cookie's value. Since value of a cookie +has a limited character set (and must be a simple string), this function can be used to encode +a value into a string suited for a cookie's value. + +The default function is the global `ecodeURIComponent`, which will encode a JavaScript string +into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range. + +##### expires + +Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6266-5.2.1]. +By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and +will delete it on a condition like exiting a web browser application. + +**note** the [cookie storage model specification][rfc-6266-5.3] states that if both `expires` and +`magAge` are set, then `maxAge` takes precedence, but it is possiblke not all clients by obey this, +so if both are set, they should point to the same date and time. + +##### httpOnly + +Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6266-5.2.6]. When truthy, +the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set. + +**note** be careful when setting this to `true`, as compliant clients will not allow client-side +JavaScript to see the cookie in `document.cookie`. + +##### maxAge + +Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6266-5.2.2]. +The given number will be converted to an integer by rounding down. By default, no maximum age is set. + +**note** the [cookie storage model specification][rfc-6266-5.3] states that if both `expires` and +`magAge` are set, then `maxAge` takes precedence, but it is possiblke not all clients by obey this, +so if both are set, they should point to the same date and time. + +##### path + +Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6266-5.2.4]. By default, the path +is considered the ["default path"][rfc-6266-5.1.4]. By default, no maximum age is set, and most +clients will consider this a "non-persistent cookie" and will delete it on a condition like exiting +a web browser application. + +##### sameSite + +Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][draft-west-first-party-cookies-07]. + + - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. + - `false` will not set the `SameSite` attribute. + - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. + - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. + +More information about the different enforcement levels can be found in the specification +https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1.1 + +**note** This is an attribute that has not yet been fully standardized, and may change in the future. +This also means many clients may ignore this attribute until they understand it. + +##### secure + +Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6266-5.2.5]. When truthy, +the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set. + +**note** be careful when setting this to `true`, as compliant clients will not send the cookie back to +the server in the future if the browser does not have an HTTPS connection. + +## Example + +The following example uses this module in conjunction with the Node.js core HTTP server +to prompt a user for their name and display it back on future visits. + +```js +var cookie = require('cookie'); +var escapeHtml = require('escape-html'); +var http = require('http'); +var url = require('url'); + +function onRequest(req, res) { + // Parse the query string + var query = url.parse(req.url, true, true).query; + + if (query && query.name) { + // Set a new cookie with the name + res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), { + httpOnly: true, + maxAge: 60 * 60 * 24 * 7 // 1 week + })); + + // Redirect back after setting cookie + res.statusCode = 302; + res.setHeader('Location', req.headers.referer || '/'); + res.end(); + return; + } + + // Parse the cookies on the request + var cookies = cookie.parse(req.headers.cookie || ''); + + // Get the visitor name set in the cookie + var name = cookies.name; + + res.setHeader('Content-Type', 'text/html; charset=UTF-8'); + + if (name) { + res.write('

    Welcome back, ' + escapeHtml(name) + '!

    '); + } else { + res.write('

    Hello, new visitor!

    '); + } + + res.write('
    '); + res.write(' '); + res.end(' values + * + * @param {string} str + * @param {object} [options] + * @return {object} + * @public + */ + +function parse(str, options) { + if (typeof str !== 'string') { + throw new TypeError('argument str must be a string'); + } + + var obj = {} + var opt = options || {}; + var pairs = str.split(pairSplitRegExp); + var dec = opt.decode || decode; + + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i]; + var eq_idx = pair.indexOf('='); + + // skip things that don't look like key=value + if (eq_idx < 0) { + continue; + } + + var key = pair.substr(0, eq_idx).trim() + var val = pair.substr(++eq_idx, pair.length).trim(); + + // quoted values + if ('"' == val[0]) { + val = val.slice(1, -1); + } + + // only assign once + if (undefined == obj[key]) { + obj[key] = tryDecode(val, dec); + } + } + + return obj; +} + +/** + * Serialize data into a cookie header. + * + * Serialize the a name value pair into a cookie string suitable for + * http headers. An optional options object specified cookie parameters. + * + * serialize('foo', 'bar', { httpOnly: true }) + * => "foo=bar; httpOnly" + * + * @param {string} name + * @param {string} val + * @param {object} [options] + * @return {string} + * @public + */ + +function serialize(name, val, options) { + var opt = options || {}; + var enc = opt.encode || encode; + + if (typeof enc !== 'function') { + throw new TypeError('option encode is invalid'); + } + + if (!fieldContentRegExp.test(name)) { + throw new TypeError('argument name is invalid'); + } + + var value = enc(val); + + if (value && !fieldContentRegExp.test(value)) { + throw new TypeError('argument val is invalid'); + } + + var str = name + '=' + value; + + if (null != opt.maxAge) { + var maxAge = opt.maxAge - 0; + if (isNaN(maxAge)) throw new Error('maxAge should be a Number'); + str += '; Max-Age=' + Math.floor(maxAge); + } + + if (opt.domain) { + if (!fieldContentRegExp.test(opt.domain)) { + throw new TypeError('option domain is invalid'); + } + + str += '; Domain=' + opt.domain; + } + + if (opt.path) { + if (!fieldContentRegExp.test(opt.path)) { + throw new TypeError('option path is invalid'); + } + + str += '; Path=' + opt.path; + } + + if (opt.expires) { + if (typeof opt.expires.toUTCString !== 'function') { + throw new TypeError('option expires is invalid'); + } + + str += '; Expires=' + opt.expires.toUTCString(); + } + + if (opt.httpOnly) { + str += '; HttpOnly'; + } + + if (opt.secure) { + str += '; Secure'; + } + + if (opt.sameSite) { + var sameSite = typeof opt.sameSite === 'string' + ? opt.sameSite.toLowerCase() : opt.sameSite; + + switch (sameSite) { + case true: + str += '; SameSite=Strict'; + break; + case 'lax': + str += '; SameSite=Lax'; + break; + case 'strict': + str += '; SameSite=Strict'; + break; + default: + throw new TypeError('option sameSite is invalid'); + } + } + + return str; +} + +/** + * Try decoding a string using a decoding function. + * + * @param {string} str + * @param {function} decode + * @private + */ + +function tryDecode(str, decode) { + try { + return decode(str); + } catch (e) { + return str; + } +} diff --git a/node_modules/cookie/package.json b/node_modules/cookie/package.json new file mode 100644 index 0000000..9ce512c --- /dev/null +++ b/node_modules/cookie/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "cookie@0.3.1", + "scope": null, + "escapedName": "cookie", + "name": "cookie", + "rawSpec": "0.3.1", + "spec": "0.3.1", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "cookie@0.3.1", + "_id": "cookie@0.3.1", + "_inCache": true, + "_installable": true, + "_location": "/cookie", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/cookie-0.3.1.tgz_1464323556714_0.6435900838114321" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "cookie@0.3.1", + "scope": null, + "escapedName": "cookie", + "name": "cookie", + "rawSpec": "0.3.1", + "spec": "0.3.1", + "type": "version" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "_shasum": "e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb", + "_shrinkwrap": null, + "_spec": "cookie@0.3.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "Roman Shtylman", + "email": "shtylman@gmail.com" + }, + "bugs": { + "url": "https://github.com/jshttp/cookie/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "HTTP server cookie parsing and serialization", + "devDependencies": { + "istanbul": "0.4.3", + "mocha": "1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb", + "tarball": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "HISTORY.md", + "LICENSE", + "README.md", + "index.js" + ], + "gitHead": "e3c77d497d66c8b8d4b677b8954c1b192a09f0b3", + "homepage": "https://github.com/jshttp/cookie", + "keywords": [ + "cookie", + "cookies" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "cookie", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jshttp/cookie.git" + }, + "scripts": { + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/" + }, + "version": "0.3.1" +} diff --git a/node_modules/core-util-is/LICENSE b/node_modules/core-util-is/LICENSE new file mode 100644 index 0000000..d8d7f94 --- /dev/null +++ b/node_modules/core-util-is/LICENSE @@ -0,0 +1,19 @@ +Copyright Node.js contributors. All rights reserved. + +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. diff --git a/node_modules/core-util-is/README.md b/node_modules/core-util-is/README.md new file mode 100644 index 0000000..5a76b41 --- /dev/null +++ b/node_modules/core-util-is/README.md @@ -0,0 +1,3 @@ +# core-util-is + +The `util.is*` functions introduced in Node v0.12. diff --git a/node_modules/core-util-is/float.patch b/node_modules/core-util-is/float.patch new file mode 100644 index 0000000..a06d5c0 --- /dev/null +++ b/node_modules/core-util-is/float.patch @@ -0,0 +1,604 @@ +diff --git a/lib/util.js b/lib/util.js +index a03e874..9074e8e 100644 +--- a/lib/util.js ++++ b/lib/util.js +@@ -19,430 +19,6 @@ + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + +-var formatRegExp = /%[sdj%]/g; +-exports.format = function(f) { +- if (!isString(f)) { +- var objects = []; +- for (var i = 0; i < arguments.length; i++) { +- objects.push(inspect(arguments[i])); +- } +- return objects.join(' '); +- } +- +- var i = 1; +- var args = arguments; +- var len = args.length; +- var str = String(f).replace(formatRegExp, function(x) { +- if (x === '%%') return '%'; +- if (i >= len) return x; +- switch (x) { +- case '%s': return String(args[i++]); +- case '%d': return Number(args[i++]); +- case '%j': +- try { +- return JSON.stringify(args[i++]); +- } catch (_) { +- return '[Circular]'; +- } +- default: +- return x; +- } +- }); +- for (var x = args[i]; i < len; x = args[++i]) { +- if (isNull(x) || !isObject(x)) { +- str += ' ' + x; +- } else { +- str += ' ' + inspect(x); +- } +- } +- return str; +-}; +- +- +-// Mark that a method should not be used. +-// Returns a modified function which warns once by default. +-// If --no-deprecation is set, then it is a no-op. +-exports.deprecate = function(fn, msg) { +- // Allow for deprecating things in the process of starting up. +- if (isUndefined(global.process)) { +- return function() { +- return exports.deprecate(fn, msg).apply(this, arguments); +- }; +- } +- +- if (process.noDeprecation === true) { +- return fn; +- } +- +- var warned = false; +- function deprecated() { +- if (!warned) { +- if (process.throwDeprecation) { +- throw new Error(msg); +- } else if (process.traceDeprecation) { +- console.trace(msg); +- } else { +- console.error(msg); +- } +- warned = true; +- } +- return fn.apply(this, arguments); +- } +- +- return deprecated; +-}; +- +- +-var debugs = {}; +-var debugEnviron; +-exports.debuglog = function(set) { +- if (isUndefined(debugEnviron)) +- debugEnviron = process.env.NODE_DEBUG || ''; +- set = set.toUpperCase(); +- if (!debugs[set]) { +- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { +- var pid = process.pid; +- debugs[set] = function() { +- var msg = exports.format.apply(exports, arguments); +- console.error('%s %d: %s', set, pid, msg); +- }; +- } else { +- debugs[set] = function() {}; +- } +- } +- return debugs[set]; +-}; +- +- +-/** +- * Echos the value of a value. Trys to print the value out +- * in the best way possible given the different types. +- * +- * @param {Object} obj The object to print out. +- * @param {Object} opts Optional options object that alters the output. +- */ +-/* legacy: obj, showHidden, depth, colors*/ +-function inspect(obj, opts) { +- // default options +- var ctx = { +- seen: [], +- stylize: stylizeNoColor +- }; +- // legacy... +- if (arguments.length >= 3) ctx.depth = arguments[2]; +- if (arguments.length >= 4) ctx.colors = arguments[3]; +- if (isBoolean(opts)) { +- // legacy... +- ctx.showHidden = opts; +- } else if (opts) { +- // got an "options" object +- exports._extend(ctx, opts); +- } +- // set default options +- if (isUndefined(ctx.showHidden)) ctx.showHidden = false; +- if (isUndefined(ctx.depth)) ctx.depth = 2; +- if (isUndefined(ctx.colors)) ctx.colors = false; +- if (isUndefined(ctx.customInspect)) ctx.customInspect = true; +- if (ctx.colors) ctx.stylize = stylizeWithColor; +- return formatValue(ctx, obj, ctx.depth); +-} +-exports.inspect = inspect; +- +- +-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +-inspect.colors = { +- 'bold' : [1, 22], +- 'italic' : [3, 23], +- 'underline' : [4, 24], +- 'inverse' : [7, 27], +- 'white' : [37, 39], +- 'grey' : [90, 39], +- 'black' : [30, 39], +- 'blue' : [34, 39], +- 'cyan' : [36, 39], +- 'green' : [32, 39], +- 'magenta' : [35, 39], +- 'red' : [31, 39], +- 'yellow' : [33, 39] +-}; +- +-// Don't use 'blue' not visible on cmd.exe +-inspect.styles = { +- 'special': 'cyan', +- 'number': 'yellow', +- 'boolean': 'yellow', +- 'undefined': 'grey', +- 'null': 'bold', +- 'string': 'green', +- 'date': 'magenta', +- // "name": intentionally not styling +- 'regexp': 'red' +-}; +- +- +-function stylizeWithColor(str, styleType) { +- var style = inspect.styles[styleType]; +- +- if (style) { +- return '\u001b[' + inspect.colors[style][0] + 'm' + str + +- '\u001b[' + inspect.colors[style][1] + 'm'; +- } else { +- return str; +- } +-} +- +- +-function stylizeNoColor(str, styleType) { +- return str; +-} +- +- +-function arrayToHash(array) { +- var hash = {}; +- +- array.forEach(function(val, idx) { +- hash[val] = true; +- }); +- +- return hash; +-} +- +- +-function formatValue(ctx, value, recurseTimes) { +- // Provide a hook for user-specified inspect functions. +- // Check that value is an object with an inspect function on it +- if (ctx.customInspect && +- value && +- isFunction(value.inspect) && +- // Filter out the util module, it's inspect function is special +- value.inspect !== exports.inspect && +- // Also filter out any prototype objects using the circular check. +- !(value.constructor && value.constructor.prototype === value)) { +- var ret = value.inspect(recurseTimes, ctx); +- if (!isString(ret)) { +- ret = formatValue(ctx, ret, recurseTimes); +- } +- return ret; +- } +- +- // Primitive types cannot have properties +- var primitive = formatPrimitive(ctx, value); +- if (primitive) { +- return primitive; +- } +- +- // Look up the keys of the object. +- var keys = Object.keys(value); +- var visibleKeys = arrayToHash(keys); +- +- if (ctx.showHidden) { +- keys = Object.getOwnPropertyNames(value); +- } +- +- // Some type of object without properties can be shortcutted. +- if (keys.length === 0) { +- if (isFunction(value)) { +- var name = value.name ? ': ' + value.name : ''; +- return ctx.stylize('[Function' + name + ']', 'special'); +- } +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } +- if (isDate(value)) { +- return ctx.stylize(Date.prototype.toString.call(value), 'date'); +- } +- if (isError(value)) { +- return formatError(value); +- } +- } +- +- var base = '', array = false, braces = ['{', '}']; +- +- // Make Array say that they are Array +- if (isArray(value)) { +- array = true; +- braces = ['[', ']']; +- } +- +- // Make functions say that they are functions +- if (isFunction(value)) { +- var n = value.name ? ': ' + value.name : ''; +- base = ' [Function' + n + ']'; +- } +- +- // Make RegExps say that they are RegExps +- if (isRegExp(value)) { +- base = ' ' + RegExp.prototype.toString.call(value); +- } +- +- // Make dates with properties first say the date +- if (isDate(value)) { +- base = ' ' + Date.prototype.toUTCString.call(value); +- } +- +- // Make error with message first say the error +- if (isError(value)) { +- base = ' ' + formatError(value); +- } +- +- if (keys.length === 0 && (!array || value.length == 0)) { +- return braces[0] + base + braces[1]; +- } +- +- if (recurseTimes < 0) { +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } else { +- return ctx.stylize('[Object]', 'special'); +- } +- } +- +- ctx.seen.push(value); +- +- var output; +- if (array) { +- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); +- } else { +- output = keys.map(function(key) { +- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); +- }); +- } +- +- ctx.seen.pop(); +- +- return reduceToSingleString(output, base, braces); +-} +- +- +-function formatPrimitive(ctx, value) { +- if (isUndefined(value)) +- return ctx.stylize('undefined', 'undefined'); +- if (isString(value)) { +- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') +- .replace(/'/g, "\\'") +- .replace(/\\"/g, '"') + '\''; +- return ctx.stylize(simple, 'string'); +- } +- if (isNumber(value)) { +- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, +- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . +- if (value === 0 && 1 / value < 0) +- return ctx.stylize('-0', 'number'); +- return ctx.stylize('' + value, 'number'); +- } +- if (isBoolean(value)) +- return ctx.stylize('' + value, 'boolean'); +- // For some reason typeof null is "object", so special case here. +- if (isNull(value)) +- return ctx.stylize('null', 'null'); +-} +- +- +-function formatError(value) { +- return '[' + Error.prototype.toString.call(value) + ']'; +-} +- +- +-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { +- var output = []; +- for (var i = 0, l = value.length; i < l; ++i) { +- if (hasOwnProperty(value, String(i))) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- String(i), true)); +- } else { +- output.push(''); +- } +- } +- keys.forEach(function(key) { +- if (!key.match(/^\d+$/)) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- key, true)); +- } +- }); +- return output; +-} +- +- +-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { +- var name, str, desc; +- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; +- if (desc.get) { +- if (desc.set) { +- str = ctx.stylize('[Getter/Setter]', 'special'); +- } else { +- str = ctx.stylize('[Getter]', 'special'); +- } +- } else { +- if (desc.set) { +- str = ctx.stylize('[Setter]', 'special'); +- } +- } +- if (!hasOwnProperty(visibleKeys, key)) { +- name = '[' + key + ']'; +- } +- if (!str) { +- if (ctx.seen.indexOf(desc.value) < 0) { +- if (isNull(recurseTimes)) { +- str = formatValue(ctx, desc.value, null); +- } else { +- str = formatValue(ctx, desc.value, recurseTimes - 1); +- } +- if (str.indexOf('\n') > -1) { +- if (array) { +- str = str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n').substr(2); +- } else { +- str = '\n' + str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n'); +- } +- } +- } else { +- str = ctx.stylize('[Circular]', 'special'); +- } +- } +- if (isUndefined(name)) { +- if (array && key.match(/^\d+$/)) { +- return str; +- } +- name = JSON.stringify('' + key); +- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { +- name = name.substr(1, name.length - 2); +- name = ctx.stylize(name, 'name'); +- } else { +- name = name.replace(/'/g, "\\'") +- .replace(/\\"/g, '"') +- .replace(/(^"|"$)/g, "'"); +- name = ctx.stylize(name, 'string'); +- } +- } +- +- return name + ': ' + str; +-} +- +- +-function reduceToSingleString(output, base, braces) { +- var numLinesEst = 0; +- var length = output.reduce(function(prev, cur) { +- numLinesEst++; +- if (cur.indexOf('\n') >= 0) numLinesEst++; +- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; +- }, 0); +- +- if (length > 60) { +- return braces[0] + +- (base === '' ? '' : base + '\n ') + +- ' ' + +- output.join(',\n ') + +- ' ' + +- braces[1]; +- } +- +- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +-} +- +- + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { +@@ -522,166 +98,10 @@ function isPrimitive(arg) { + exports.isPrimitive = isPrimitive; + + function isBuffer(arg) { +- return arg instanceof Buffer; ++ return Buffer.isBuffer(arg); + } + exports.isBuffer = isBuffer; + + function objectToString(o) { + return Object.prototype.toString.call(o); +-} +- +- +-function pad(n) { +- return n < 10 ? '0' + n.toString(10) : n.toString(10); +-} +- +- +-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', +- 'Oct', 'Nov', 'Dec']; +- +-// 26 Feb 16:19:34 +-function timestamp() { +- var d = new Date(); +- var time = [pad(d.getHours()), +- pad(d.getMinutes()), +- pad(d.getSeconds())].join(':'); +- return [d.getDate(), months[d.getMonth()], time].join(' '); +-} +- +- +-// log is just a thin wrapper to console.log that prepends a timestamp +-exports.log = function() { +- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +-}; +- +- +-/** +- * Inherit the prototype methods from one constructor into another. +- * +- * The Function.prototype.inherits from lang.js rewritten as a standalone +- * function (not on Function.prototype). NOTE: If this file is to be loaded +- * during bootstrapping this function needs to be rewritten using some native +- * functions as prototype setup using normal JavaScript does not work as +- * expected during bootstrapping (see mirror.js in r114903). +- * +- * @param {function} ctor Constructor function which needs to inherit the +- * prototype. +- * @param {function} superCtor Constructor function to inherit prototype from. +- */ +-exports.inherits = function(ctor, superCtor) { +- ctor.super_ = superCtor; +- ctor.prototype = Object.create(superCtor.prototype, { +- constructor: { +- value: ctor, +- enumerable: false, +- writable: true, +- configurable: true +- } +- }); +-}; +- +-exports._extend = function(origin, add) { +- // Don't do anything if add isn't an object +- if (!add || !isObject(add)) return origin; +- +- var keys = Object.keys(add); +- var i = keys.length; +- while (i--) { +- origin[keys[i]] = add[keys[i]]; +- } +- return origin; +-}; +- +-function hasOwnProperty(obj, prop) { +- return Object.prototype.hasOwnProperty.call(obj, prop); +-} +- +- +-// Deprecated old stuff. +- +-exports.p = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- console.error(exports.inspect(arguments[i])); +- } +-}, 'util.p: Use console.error() instead'); +- +- +-exports.exec = exports.deprecate(function() { +- return require('child_process').exec.apply(this, arguments); +-}, 'util.exec is now called `child_process.exec`.'); +- +- +-exports.print = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(String(arguments[i])); +- } +-}, 'util.print: Use console.log instead'); +- +- +-exports.puts = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(arguments[i] + '\n'); +- } +-}, 'util.puts: Use console.log instead'); +- +- +-exports.debug = exports.deprecate(function(x) { +- process.stderr.write('DEBUG: ' + x + '\n'); +-}, 'util.debug: Use console.error instead'); +- +- +-exports.error = exports.deprecate(function(x) { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stderr.write(arguments[i] + '\n'); +- } +-}, 'util.error: Use console.error instead'); +- +- +-exports.pump = exports.deprecate(function(readStream, writeStream, callback) { +- var callbackCalled = false; +- +- function call(a, b, c) { +- if (callback && !callbackCalled) { +- callback(a, b, c); +- callbackCalled = true; +- } +- } +- +- readStream.addListener('data', function(chunk) { +- if (writeStream.write(chunk) === false) readStream.pause(); +- }); +- +- writeStream.addListener('drain', function() { +- readStream.resume(); +- }); +- +- readStream.addListener('end', function() { +- writeStream.end(); +- }); +- +- readStream.addListener('close', function() { +- call(); +- }); +- +- readStream.addListener('error', function(err) { +- writeStream.end(); +- call(err); +- }); +- +- writeStream.addListener('error', function(err) { +- readStream.destroy(); +- call(err); +- }); +-}, 'util.pump(): Use readableStream.pipe() instead'); +- +- +-var uv; +-exports._errnoException = function(err, syscall) { +- if (isUndefined(uv)) uv = process.binding('uv'); +- var errname = uv.errname(err); +- var e = new Error(syscall + ' ' + errname); +- e.code = errname; +- e.errno = errname; +- e.syscall = syscall; +- return e; +-}; ++} \ No newline at end of file diff --git a/node_modules/core-util-is/lib/util.js b/node_modules/core-util-is/lib/util.js new file mode 100644 index 0000000..ff4c851 --- /dev/null +++ b/node_modules/core-util-is/lib/util.js @@ -0,0 +1,107 @@ +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/node_modules/core-util-is/package.json b/node_modules/core-util-is/package.json new file mode 100644 index 0000000..692eb89 --- /dev/null +++ b/node_modules/core-util-is/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "core-util-is@~1.0.0", + "scope": null, + "escapedName": "core-util-is", + "name": "core-util-is", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/mnt/c/Users/const/IdeaProjects/space-game/node_modules/readable-stream" + ] + ], + "_from": "core-util-is@>=1.0.0 <1.1.0", + "_id": "core-util-is@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/core-util-is", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.3.2", + "_phantomChildren": {}, + "_requested": { + "raw": "core-util-is@~1.0.0", + "scope": null, + "escapedName": "core-util-is", + "name": "core-util-is", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "_shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", + "_shrinkwrap": null, + "_spec": "core-util-is@~1.0.0", + "_where": "/mnt/c/Users/const/IdeaProjects/space-game/node_modules/readable-stream", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/core-util-is/issues" + }, + "dependencies": {}, + "description": "The `util.is*` functions introduced in Node v0.12.", + "devDependencies": { + "tap": "^2.3.0" + }, + "directories": {}, + "dist": { + "shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", + "tarball": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "gitHead": "a177da234df5638b363ddc15fa324619a38577c8", + "homepage": "https://github.com/isaacs/core-util-is#readme", + "keywords": [ + "util", + "isBuffer", + "isArray", + "isNumber", + "isString", + "isRegExp", + "isThis", + "isThat", + "polyfill" + ], + "license": "MIT", + "main": "lib/util.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "core-util-is", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/core-util-is.git" + }, + "scripts": { + "test": "tap test.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/core-util-is/test.js b/node_modules/core-util-is/test.js new file mode 100644 index 0000000..1a490c6 --- /dev/null +++ b/node_modules/core-util-is/test.js @@ -0,0 +1,68 @@ +var assert = require('tap'); + +var t = require('./lib/util'); + +assert.equal(t.isArray([]), true); +assert.equal(t.isArray({}), false); + +assert.equal(t.isBoolean(null), false); +assert.equal(t.isBoolean(true), true); +assert.equal(t.isBoolean(false), true); + +assert.equal(t.isNull(null), true); +assert.equal(t.isNull(undefined), false); +assert.equal(t.isNull(false), false); +assert.equal(t.isNull(), false); + +assert.equal(t.isNullOrUndefined(null), true); +assert.equal(t.isNullOrUndefined(undefined), true); +assert.equal(t.isNullOrUndefined(false), false); +assert.equal(t.isNullOrUndefined(), true); + +assert.equal(t.isNumber(null), false); +assert.equal(t.isNumber('1'), false); +assert.equal(t.isNumber(1), true); + +assert.equal(t.isString(null), false); +assert.equal(t.isString('1'), true); +assert.equal(t.isString(1), false); + +assert.equal(t.isSymbol(null), false); +assert.equal(t.isSymbol('1'), false); +assert.equal(t.isSymbol(1), false); +assert.equal(t.isSymbol(Symbol()), true); + +assert.equal(t.isUndefined(null), false); +assert.equal(t.isUndefined(undefined), true); +assert.equal(t.isUndefined(false), false); +assert.equal(t.isUndefined(), true); + +assert.equal(t.isRegExp(null), false); +assert.equal(t.isRegExp('1'), false); +assert.equal(t.isRegExp(new RegExp()), true); + +assert.equal(t.isObject({}), true); +assert.equal(t.isObject([]), true); +assert.equal(t.isObject(new RegExp()), true); +assert.equal(t.isObject(new Date()), true); + +assert.equal(t.isDate(null), false); +assert.equal(t.isDate('1'), false); +assert.equal(t.isDate(new Date()), true); + +assert.equal(t.isError(null), false); +assert.equal(t.isError({ err: true }), false); +assert.equal(t.isError(new Error()), true); + +assert.equal(t.isFunction(null), false); +assert.equal(t.isFunction({ }), false); +assert.equal(t.isFunction(function() {}), true); + +assert.equal(t.isPrimitive(null), true); +assert.equal(t.isPrimitive(''), true); +assert.equal(t.isPrimitive(0), true); +assert.equal(t.isPrimitive(new Date()), false); + +assert.equal(t.isBuffer(null), false); +assert.equal(t.isBuffer({}), false); +assert.equal(t.isBuffer(new Buffer(0)), true); diff --git a/node_modules/debug/.jshintrc b/node_modules/debug/.jshintrc new file mode 100644 index 0000000..299877f --- /dev/null +++ b/node_modules/debug/.jshintrc @@ -0,0 +1,3 @@ +{ + "laxbreak": true +} diff --git a/node_modules/debug/.npmignore b/node_modules/debug/.npmignore new file mode 100644 index 0000000..7e6163d --- /dev/null +++ b/node_modules/debug/.npmignore @@ -0,0 +1,6 @@ +support +test +examples +example +*.sock +dist diff --git a/node_modules/debug/History.md b/node_modules/debug/History.md new file mode 100644 index 0000000..854c971 --- /dev/null +++ b/node_modules/debug/History.md @@ -0,0 +1,195 @@ + +2.2.0 / 2015-05-09 +================== + + * package: update "ms" to v0.7.1 (#202, @dougwilson) + * README: add logging to file example (#193, @DanielOchoa) + * README: fixed a typo (#191, @amir-s) + * browser: expose `storage` (#190, @stephenmathieson) + * Makefile: add a `distclean` target (#189, @stephenmathieson) + +2.1.3 / 2015-03-13 +================== + + * Updated stdout/stderr example (#186) + * Updated example/stdout.js to match debug current behaviour + * Renamed example/stderr.js to stdout.js + * Update Readme.md (#184) + * replace high intensity foreground color for bold (#182, #183) + +2.1.2 / 2015-03-01 +================== + + * dist: recompile + * update "ms" to v0.7.0 + * package: update "browserify" to v9.0.3 + * component: fix "ms.js" repo location + * changed bower package name + * updated documentation about using debug in a browser + * fix: security error on safari (#167, #168, @yields) + +2.1.1 / 2014-12-29 +================== + + * browser: use `typeof` to check for `console` existence + * browser: check for `console.log` truthiness (fix IE 8/9) + * browser: add support for Chrome apps + * Readme: added Windows usage remarks + * Add `bower.json` to properly support bower install + +2.1.0 / 2014-10-15 +================== + + * node: implement `DEBUG_FD` env variable support + * package: update "browserify" to v6.1.0 + * package: add "license" field to package.json (#135, @panuhorsmalahti) + +2.0.0 / 2014-09-01 +================== + + * package: update "browserify" to v5.11.0 + * node: use stderr rather than stdout for logging (#29, @stephenmathieson) + +1.0.4 / 2014-07-15 +================== + + * dist: recompile + * example: remove `console.info()` log usage + * example: add "Content-Type" UTF-8 header to browser example + * browser: place %c marker after the space character + * browser: reset the "content" color via `color: inherit` + * browser: add colors support for Firefox >= v31 + * debug: prefer an instance `log()` function over the global one (#119) + * Readme: update documentation about styled console logs for FF v31 (#116, @wryk) + +1.0.3 / 2014-07-09 +================== + + * Add support for multiple wildcards in namespaces (#122, @seegno) + * browser: fix lint + +1.0.2 / 2014-06-10 +================== + + * browser: update color palette (#113, @gscottolson) + * common: make console logging function configurable (#108, @timoxley) + * node: fix %o colors on old node <= 0.8.x + * Makefile: find node path using shell/which (#109, @timoxley) + +1.0.1 / 2014-06-06 +================== + + * browser: use `removeItem()` to clear localStorage + * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777) + * package: add "contributors" section + * node: fix comment typo + * README: list authors + +1.0.0 / 2014-06-04 +================== + + * make ms diff be global, not be scope + * debug: ignore empty strings in enable() + * node: make DEBUG_COLORS able to disable coloring + * *: export the `colors` array + * npmignore: don't publish the `dist` dir + * Makefile: refactor to use browserify + * package: add "browserify" as a dev dependency + * Readme: add Web Inspector Colors section + * node: reset terminal color for the debug content + * node: map "%o" to `util.inspect()` + * browser: map "%j" to `JSON.stringify()` + * debug: add custom "formatters" + * debug: use "ms" module for humanizing the diff + * Readme: add "bash" syntax highlighting + * browser: add Firebug color support + * browser: add colors for WebKit browsers + * node: apply log to `console` + * rewrite: abstract common logic for Node & browsers + * add .jshintrc file + +0.8.1 / 2014-04-14 +================== + + * package: re-add the "component" section + +0.8.0 / 2014-03-30 +================== + + * add `enable()` method for nodejs. Closes #27 + * change from stderr to stdout + * remove unnecessary index.js file + +0.7.4 / 2013-11-13 +================== + + * remove "browserify" key from package.json (fixes something in browserify) + +0.7.3 / 2013-10-30 +================== + + * fix: catch localStorage security error when cookies are blocked (Chrome) + * add debug(err) support. Closes #46 + * add .browser prop to package.json. Closes #42 + +0.7.2 / 2013-02-06 +================== + + * fix package.json + * fix: Mobile Safari (private mode) is broken with debug + * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript + +0.7.1 / 2013-02-05 +================== + + * add repository URL to package.json + * add DEBUG_COLORED to force colored output + * add browserify support + * fix component. Closes #24 + +0.7.0 / 2012-05-04 +================== + + * Added .component to package.json + * Added debug.component.js build + +0.6.0 / 2012-03-16 +================== + + * Added support for "-" prefix in DEBUG [Vinay Pulim] + * Added `.enabled` flag to the node version [TooTallNate] + +0.5.0 / 2012-02-02 +================== + + * Added: humanize diffs. Closes #8 + * Added `debug.disable()` to the CS variant + * Removed padding. Closes #10 + * Fixed: persist client-side variant again. Closes #9 + +0.4.0 / 2012-02-01 +================== + + * Added browser variant support for older browsers [TooTallNate] + * Added `debug.enable('project:*')` to browser variant [TooTallNate] + * Added padding to diff (moved it to the right) + +0.3.0 / 2012-01-26 +================== + + * Added millisecond diff when isatty, otherwise UTC string + +0.2.0 / 2012-01-22 +================== + + * Added wildcard support + +0.1.0 / 2011-12-02 +================== + + * Added: remove colors unless stderr isatty [TooTallNate] + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/debug/Makefile b/node_modules/debug/Makefile new file mode 100644 index 0000000..5cf4a59 --- /dev/null +++ b/node_modules/debug/Makefile @@ -0,0 +1,36 @@ + +# get Makefile directory name: http://stackoverflow.com/a/5982798/376773 +THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) +THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd) + +# BIN directory +BIN := $(THIS_DIR)/node_modules/.bin + +# applications +NODE ?= $(shell which node) +NPM ?= $(NODE) $(shell which npm) +BROWSERIFY ?= $(NODE) $(BIN)/browserify + +all: dist/debug.js + +install: node_modules + +clean: + @rm -rf dist + +dist: + @mkdir -p $@ + +dist/debug.js: node_modules browser.js debug.js dist + @$(BROWSERIFY) \ + --standalone debug \ + . > $@ + +distclean: clean + @rm -rf node_modules + +node_modules: package.json + @NODE_ENV= $(NPM) install + @touch node_modules + +.PHONY: all install clean distclean diff --git a/node_modules/debug/Readme.md b/node_modules/debug/Readme.md new file mode 100644 index 0000000..b4f45e3 --- /dev/null +++ b/node_modules/debug/Readme.md @@ -0,0 +1,188 @@ +# debug + + tiny node.js debugging utility modelled after node core's debugging technique. + +## Installation + +```bash +$ npm install debug +``` + +## Usage + + With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility. + +Example _app.js_: + +```js +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; + +// fake app + +debug('booting %s', name); + +http.createServer(function(req, res){ + debug(req.method + ' ' + req.url); + res.end('hello\n'); +}).listen(3000, function(){ + debug('listening'); +}); + +// fake worker of some kind + +require('./worker'); +``` + +Example _worker.js_: + +```js +var debug = require('debug')('worker'); + +setInterval(function(){ + debug('doing some work'); +}, 1000); +``` + + The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: + + ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) + + ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) + +#### Windows note + + On Windows the environment variable is set using the `set` command. + + ```cmd + set DEBUG=*,-not_this + ``` + +Then, run the program to be debugged as usual. + +## Millisecond diff + + When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. + + ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) + + When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: + + ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) + +## Conventions + + If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". + +## Wildcards + + The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. + + You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:". + +## Browser support + + Debug works in the browser as well, currently persisted by `localStorage`. Consider the situation shown below where you have `worker:a` and `worker:b`, and wish to debug both. Somewhere in the code on your page, include: + +```js +window.myDebug = require("debug"); +``` + + ("debug" is a global object in the browser so we give this object a different name.) When your page is open in the browser, type the following in the console: + +```js +myDebug.enable("worker:*") +``` + + Refresh the page. Debug output will continue to be sent to the console until it is disabled by typing `myDebug.disable()` in the console. + +```js +a = debug('worker:a'); +b = debug('worker:b'); + +setInterval(function(){ + a('doing some work'); +}, 1000); + +setInterval(function(){ + b('doing some work'); +}, 1200); +``` + +#### Web Inspector Colors + + Colors are also enabled on "Web Inspectors" that understand the `%c` formatting + option. These are WebKit web inspectors, Firefox ([since version + 31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) + and the Firebug plugin for Firefox (any version). + + Colored output looks something like: + + ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png) + +### stderr vs stdout + +You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally: + +Example _stdout.js_: + +```js +var debug = require('debug'); +var error = debug('app:error'); + +// by default stderr is used +error('goes to stderr!'); + +var log = debug('app:log'); +// set this namespace to log via console.log +log.log = console.log.bind(console); // don't forget to bind to console! +log('goes to stdout'); +error('still goes to stderr!'); + +// set all output to go via console.info +// overrides all per-namespace log settings +debug.log = console.info.bind(console); +error('now goes to stdout via console.info'); +log('still goes to stdout, but via console.info now'); +``` + +### Save debug output to a file + +You can save all debug statements to a file by piping them. + +Example: + +```bash +$ DEBUG_FD=3 node your-app.js 3> whatever.log +``` + +## Authors + + - TJ Holowaychuk + - Nathan Rajlich + +## License + +(The MIT License) + +Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca> + +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. diff --git a/node_modules/debug/bower.json b/node_modules/debug/bower.json new file mode 100644 index 0000000..6af573f --- /dev/null +++ b/node_modules/debug/bower.json @@ -0,0 +1,28 @@ +{ + "name": "visionmedia-debug", + "main": "dist/debug.js", + "version": "2.2.0", + "homepage": "https://github.com/visionmedia/debug", + "authors": [ + "TJ Holowaychuk " + ], + "description": "visionmedia-debug", + "moduleType": [ + "amd", + "es6", + "globals", + "node" + ], + "keywords": [ + "visionmedia", + "debug" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/node_modules/debug/browser.js b/node_modules/debug/browser.js new file mode 100644 index 0000000..7c76452 --- /dev/null +++ b/node_modules/debug/browser.js @@ -0,0 +1,168 @@ + +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = require('./debug'); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); + +/** + * Colors. + */ + +exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + return ('WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage(){ + try { + return window.localStorage; + } catch (e) {} +} diff --git a/node_modules/debug/component.json b/node_modules/debug/component.json new file mode 100644 index 0000000..ca10637 --- /dev/null +++ b/node_modules/debug/component.json @@ -0,0 +1,19 @@ +{ + "name": "debug", + "repo": "visionmedia/debug", + "description": "small debugging utility", + "version": "2.2.0", + "keywords": [ + "debug", + "log", + "debugger" + ], + "main": "browser.js", + "scripts": [ + "browser.js", + "debug.js" + ], + "dependencies": { + "rauchg/ms.js": "0.7.1" + } +} diff --git a/node_modules/debug/debug.js b/node_modules/debug/debug.js new file mode 100644 index 0000000..7571a86 --- /dev/null +++ b/node_modules/debug/debug.js @@ -0,0 +1,197 @@ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = Array.prototype.slice.call(arguments); + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + if ('function' === typeof exports.formatArgs) { + args = exports.formatArgs.apply(self, args); + } + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} diff --git a/node_modules/debug/node.js b/node_modules/debug/node.js new file mode 100644 index 0000000..1d392a8 --- /dev/null +++ b/node_modules/debug/node.js @@ -0,0 +1,209 @@ + +/** + * Module dependencies. + */ + +var tty = require('tty'); +var util = require('util'); + +/** + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = require('./debug'); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; + +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +/** + * The file descriptor to write the `debug()` calls to. + * Set the `DEBUG_FD` env variable to override with another value. i.e.: + * + * $ DEBUG_FD=3 node script.js 3>debug.log + */ + +var fd = parseInt(process.env.DEBUG_FD, 10) || 2; +var stream = 1 === fd ? process.stdout : + 2 === fd ? process.stderr : + createWritableStdioStream(fd); + +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase(); + if (0 === debugColors.length) { + return tty.isatty(fd); + } else { + return '0' !== debugColors + && 'no' !== debugColors + && 'false' !== debugColors + && 'disabled' !== debugColors; + } +} + +/** + * Map %o to `util.inspect()`, since Node doesn't do that out of the box. + */ + +var inspect = (4 === util.inspect.length ? + // node <= 0.8.x + function (v, colors) { + return util.inspect(v, void 0, void 0, colors); + } : + // node > 0.8.x + function (v, colors) { + return util.inspect(v, { colors: colors }); + } +); + +exports.formatters.o = function(v) { + return inspect(v, this.useColors) + .replace(/\s*\n\s*/g, ' '); +}; + +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + var name = this.namespace; + + if (useColors) { + var c = this.color; + + args[0] = ' \u001b[3' + c + ';1m' + name + ' ' + + '\u001b[0m' + + args[0] + '\u001b[3' + c + 'm' + + ' +' + exports.humanize(this.diff) + '\u001b[0m'; + } else { + args[0] = new Date().toUTCString() + + ' ' + name + ' ' + args[0]; + } + return args; +} + +/** + * Invokes `console.error()` with the specified arguments. + */ + +function log() { + return stream.write(util.format.apply(this, arguments) + '\n'); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + if (null == namespaces) { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + return process.env.DEBUG; +} + +/** + * Copied from `node/src/node.js`. + * + * XXX: It's lame that node doesn't expose this API out-of-the-box. It also + * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. + */ + +function createWritableStdioStream (fd) { + var stream; + var tty_wrap = process.binding('tty_wrap'); + + // Note stream._type is used for test-module-load-list.js + + switch (tty_wrap.guessHandleType(fd)) { + case 'TTY': + stream = new tty.WriteStream(fd); + stream._type = 'tty'; + + // Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + case 'FILE': + var fs = require('fs'); + stream = new fs.SyncWriteStream(fd, { autoClose: false }); + stream._type = 'fs'; + break; + + case 'PIPE': + case 'TCP': + var net = require('net'); + stream = new net.Socket({ + fd: fd, + readable: false, + writable: true + }); + + // FIXME Should probably have an option in net.Socket to create a + // stream from an existing fd which is writable only. But for now + // we'll just add this hack and set the `readable` member to false. + // Test: ./node test/fixtures/echo.js < /etc/passwd + stream.readable = false; + stream.read = null; + stream._type = 'pipe'; + + // FIXME Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + default: + // Probably an error on in uv_guess_handle() + throw new Error('Implement me. Unknown stream file type!'); + } + + // For supporting legacy API we put the FD here. + stream.fd = fd; + + stream._isStdio = true; + + return stream; +} + +/** + * Enable namespaces listed in `process.env.DEBUG` initially. + */ + +exports.enable(load()); diff --git a/node_modules/debug/package.json b/node_modules/debug/package.json new file mode 100644 index 0000000..fcd2018 --- /dev/null +++ b/node_modules/debug/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "debug@~2.2.0", + "scope": null, + "escapedName": "debug", + "name": "debug", + "rawSpec": "~2.2.0", + "spec": ">=2.2.0 <2.3.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "debug@>=2.2.0 <2.3.0", + "_id": "debug@2.2.0", + "_inCache": true, + "_installable": true, + "_location": "/debug", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + "_npmVersion": "2.7.4", + "_phantomChildren": {}, + "_requested": { + "raw": "debug@~2.2.0", + "scope": null, + "escapedName": "debug", + "name": "debug", + "rawSpec": "~2.2.0", + "spec": ">=2.2.0 <2.3.0", + "type": "range" + }, + "_requiredBy": [ + "/express", + "/finalhandler", + "/send" + ], + "_resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "_shasum": "f87057e995b1a1f6ae6a4960664137bc56f039da", + "_shrinkwrap": null, + "_spec": "debug@~2.2.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "browser": "./browser.js", + "bugs": { + "url": "https://github.com/visionmedia/debug/issues" + }, + "component": { + "scripts": { + "debug/index.js": "browser.js", + "debug/debug.js": "debug.js" + } + }, + "contributors": [ + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net", + "url": "http://n8.io" + } + ], + "dependencies": { + "ms": "0.7.1" + }, + "description": "small debugging utility", + "devDependencies": { + "browserify": "9.0.3", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "f87057e995b1a1f6ae6a4960664137bc56f039da", + "tarball": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz" + }, + "gitHead": "b38458422b5aa8aa6d286b10dfe427e8a67e2b35", + "homepage": "https://github.com/visionmedia/debug", + "keywords": [ + "debug", + "log", + "debugger" + ], + "license": "MIT", + "main": "./node.js", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + } + ], + "name": "debug", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/debug.git" + }, + "scripts": {}, + "version": "2.2.0" +} diff --git a/node_modules/depd/History.md b/node_modules/depd/History.md new file mode 100644 index 0000000..ace1171 --- /dev/null +++ b/node_modules/depd/History.md @@ -0,0 +1,84 @@ +1.1.0 / 2015-09-14 +================== + + * Enable strict mode in more places + * Support io.js 3.x + * Support io.js 2.x + * Support web browser loading + - Requires bundler like Browserify or webpack + +1.0.1 / 2015-04-07 +================== + + * Fix `TypeError`s when under `'use strict'` code + * Fix useless type name on auto-generated messages + * Support io.js 1.x + * Support Node.js 0.12 + +1.0.0 / 2014-09-17 +================== + + * No changes + +0.4.5 / 2014-09-09 +================== + + * Improve call speed to functions using the function wrapper + * Support Node.js 0.6 + +0.4.4 / 2014-07-27 +================== + + * Work-around v8 generating empty stack traces + +0.4.3 / 2014-07-26 +================== + + * Fix exception when global `Error.stackTraceLimit` is too low + +0.4.2 / 2014-07-19 +================== + + * Correct call site for wrapped functions and properties + +0.4.1 / 2014-07-19 +================== + + * Improve automatic message generation for function properties + +0.4.0 / 2014-07-19 +================== + + * Add `TRACE_DEPRECATION` environment variable + * Remove non-standard grey color from color output + * Support `--no-deprecation` argument + * Support `--trace-deprecation` argument + * Support `deprecate.property(fn, prop, message)` + +0.3.0 / 2014-06-16 +================== + + * Add `NO_DEPRECATION` environment variable + +0.2.0 / 2014-06-15 +================== + + * Add `deprecate.property(obj, prop, message)` + * Remove `supports-color` dependency for node.js 0.8 + +0.1.0 / 2014-06-15 +================== + + * Add `deprecate.function(fn, message)` + * Add `process.on('deprecation', fn)` emitter + * Automatically generate message when omitted from `deprecate()` + +0.0.1 / 2014-06-15 +================== + + * Fix warning for dynamic calls at singe call site + +0.0.0 / 2014-06-15 +================== + + * Initial implementation diff --git a/node_modules/depd/LICENSE b/node_modules/depd/LICENSE new file mode 100644 index 0000000..142ede3 --- /dev/null +++ b/node_modules/depd/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014-2015 Douglas Christopher Wilson + +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. diff --git a/node_modules/depd/Readme.md b/node_modules/depd/Readme.md new file mode 100644 index 0000000..09bb979 --- /dev/null +++ b/node_modules/depd/Readme.md @@ -0,0 +1,281 @@ +# depd + +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][npm-url] +[![Node.js Version][node-image]][node-url] +[![Linux Build][travis-image]][travis-url] +[![Windows Build][appveyor-image]][appveyor-url] +[![Coverage Status][coveralls-image]][coveralls-url] +[![Gratipay][gratipay-image]][gratipay-url] + +Deprecate all the things + +> With great modules comes great responsibility; mark things deprecated! + +## Install + +This module is installed directly using `npm`: + +```sh +$ npm install depd +``` + +This module can also be bundled with systems like +[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/), +though by default this module will alter it's API to no longer display or +track deprecations. + +## API + +```js +var deprecate = require('depd')('my-module') +``` + +This library allows you to display deprecation messages to your users. +This library goes above and beyond with deprecation warnings by +introspection of the call stack (but only the bits that it is interested +in). + +Instead of just warning on the first invocation of a deprecated +function and never again, this module will warn on the first invocation +of a deprecated function per unique call site, making it ideal to alert +users of all deprecated uses across the code base, rather than just +whatever happens to execute first. + +The deprecation warnings from this module also include the file and line +information for the call into the module that the deprecated function was +in. + +**NOTE** this library has a similar interface to the `debug` module, and +this module uses the calling file to get the boundary for the call stacks, +so you should always create a new `deprecate` object in each file and not +within some central file. + +### depd(namespace) + +Create a new deprecate function that uses the given namespace name in the +messages and will display the call site prior to the stack entering the +file this function was called from. It is highly suggested you use the +name of your module as the namespace. + +### deprecate(message) + +Call this function from deprecated code to display a deprecation message. +This message will appear once per unique caller site. Caller site is the +first call site in the stack in a different file from the caller of this +function. + +If the message is omitted, a message is generated for you based on the site +of the `deprecate()` call and will display the name of the function called, +similar to the name displayed in a stack trace. + +### deprecate.function(fn, message) + +Call this function to wrap a given function in a deprecation message on any +call to the function. An optional message can be supplied to provide a custom +message. + +### deprecate.property(obj, prop, message) + +Call this function to wrap a given property on object in a deprecation message +on any accessing or setting of the property. An optional message can be supplied +to provide a custom message. + +The method must be called on the object where the property belongs (not +inherited from the prototype). + +If the property is a data descriptor, it will be converted to an accessor +descriptor in order to display the deprecation message. + +### process.on('deprecation', fn) + +This module will allow easy capturing of deprecation errors by emitting the +errors as the type "deprecation" on the global `process`. If there are no +listeners for this type, the errors are written to STDERR as normal, but if +there are any listeners, nothing will be written to STDERR and instead only +emitted. From there, you can write the errors in a different format or to a +logging source. + +The error represents the deprecation and is emitted only once with the same +rules as writing to STDERR. The error has the following properties: + + - `message` - This is the message given by the library + - `name` - This is always `'DeprecationError'` + - `namespace` - This is the namespace the deprecation came from + - `stack` - This is the stack of the call to the deprecated thing + +Example `error.stack` output: + +``` +DeprecationError: my-cool-module deprecated oldfunction + at Object. ([eval]-wrapper:6:22) + at Module._compile (module.js:456:26) + at evalScript (node.js:532:25) + at startup (node.js:80:7) + at node.js:902:3 +``` + +### process.env.NO_DEPRECATION + +As a user of modules that are deprecated, the environment variable `NO_DEPRECATION` +is provided as a quick solution to silencing deprecation warnings from being +output. The format of this is similar to that of `DEBUG`: + +```sh +$ NO_DEPRECATION=my-module,othermod node app.js +``` + +This will suppress deprecations from being output for "my-module" and "othermod". +The value is a list of comma-separated namespaces. To suppress every warning +across all namespaces, use the value `*` for a namespace. + +Providing the argument `--no-deprecation` to the `node` executable will suppress +all deprecations (only available in Node.js 0.8 or higher). + +**NOTE** This will not suppress the deperecations given to any "deprecation" +event listeners, just the output to STDERR. + +### process.env.TRACE_DEPRECATION + +As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION` +is provided as a solution to getting more detailed location information in deprecation +warnings by including the entire stack trace. The format of this is the same as +`NO_DEPRECATION`: + +```sh +$ TRACE_DEPRECATION=my-module,othermod node app.js +``` + +This will include stack traces for deprecations being output for "my-module" and +"othermod". The value is a list of comma-separated namespaces. To trace every +warning across all namespaces, use the value `*` for a namespace. + +Providing the argument `--trace-deprecation` to the `node` executable will trace +all deprecations (only available in Node.js 0.8 or higher). + +**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`. + +## Display + +![message](files/message.png) + +When a user calls a function in your library that you mark deprecated, they +will see the following written to STDERR (in the given colors, similar colors +and layout to the `debug` module): + +``` +bright cyan bright yellow +| | reset cyan +| | | | +▼ ▼ ▼ ▼ +my-cool-module deprecated oldfunction [eval]-wrapper:6:22 +▲ ▲ ▲ ▲ +| | | | +namespace | | location of mycoolmod.oldfunction() call + | deprecation message + the word "deprecated" +``` + +If the user redirects their STDERR to a file or somewhere that does not support +colors, they see (similar layout to the `debug` module): + +``` +Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22 +▲ ▲ ▲ ▲ ▲ +| | | | | +timestamp of message namespace | | location of mycoolmod.oldfunction() call + | deprecation message + the word "deprecated" +``` + +## Examples + +### Deprecating all calls to a function + +This will display a deprecated message about "oldfunction" being deprecated +from "my-module" on STDERR. + +```js +var deprecate = require('depd')('my-cool-module') + +// message automatically derived from function name +// Object.oldfunction +exports.oldfunction = deprecate.function(function oldfunction() { + // all calls to function are deprecated +}) + +// specific message +exports.oldfunction = deprecate.function(function () { + // all calls to function are deprecated +}, 'oldfunction') +``` + +### Conditionally deprecating a function call + +This will display a deprecated message about "weirdfunction" being deprecated +from "my-module" on STDERR when called with less than 2 arguments. + +```js +var deprecate = require('depd')('my-cool-module') + +exports.weirdfunction = function () { + if (arguments.length < 2) { + // calls with 0 or 1 args are deprecated + deprecate('weirdfunction args < 2') + } +} +``` + +When calling `deprecate` as a function, the warning is counted per call site +within your own module, so you can display different deprecations depending +on different situations and the users will still get all the warnings: + +```js +var deprecate = require('depd')('my-cool-module') + +exports.weirdfunction = function () { + if (arguments.length < 2) { + // calls with 0 or 1 args are deprecated + deprecate('weirdfunction args < 2') + } else if (typeof arguments[0] !== 'string') { + // calls with non-string first argument are deprecated + deprecate('weirdfunction non-string first arg') + } +} +``` + +### Deprecating property access + +This will display a deprecated message about "oldprop" being deprecated +from "my-module" on STDERR when accessed. A deprecation will be displayed +when setting the value and when getting the value. + +```js +var deprecate = require('depd')('my-cool-module') + +exports.oldprop = 'something' + +// message automatically derives from property name +deprecate.property(exports, 'oldprop') + +// explicit message +deprecate.property(exports, 'oldprop', 'oldprop >= 0.10') +``` + +## License + +[MIT](LICENSE) + +[npm-version-image]: https://img.shields.io/npm/v/depd.svg +[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg +[npm-url]: https://npmjs.org/package/depd +[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd/master.svg?label=linux +[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd +[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/nodejs-depd/master.svg?label=windows +[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd +[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg +[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master +[node-image]: https://img.shields.io/node/v/depd.svg +[node-url]: http://nodejs.org/download/ +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg +[gratipay-url]: https://www.gratipay.com/dougwilson/ diff --git a/node_modules/depd/index.js b/node_modules/depd/index.js new file mode 100644 index 0000000..fddcae8 --- /dev/null +++ b/node_modules/depd/index.js @@ -0,0 +1,521 @@ +/*! + * depd + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var callSiteToString = require('./lib/compat').callSiteToString +var eventListenerCount = require('./lib/compat').eventListenerCount +var relative = require('path').relative + +/** + * Module exports. + */ + +module.exports = depd + +/** + * Get the path to base files on. + */ + +var basePath = process.cwd() + +/** + * Determine if namespace is contained in the string. + */ + +function containsNamespace(str, namespace) { + var val = str.split(/[ ,]+/) + + namespace = String(namespace).toLowerCase() + + for (var i = 0 ; i < val.length; i++) { + if (!(str = val[i])) continue; + + // namespace contained + if (str === '*' || str.toLowerCase() === namespace) { + return true + } + } + + return false +} + +/** + * Convert a data descriptor to accessor descriptor. + */ + +function convertDataDescriptorToAccessor(obj, prop, message) { + var descriptor = Object.getOwnPropertyDescriptor(obj, prop) + var value = descriptor.value + + descriptor.get = function getter() { return value } + + if (descriptor.writable) { + descriptor.set = function setter(val) { return value = val } + } + + delete descriptor.value + delete descriptor.writable + + Object.defineProperty(obj, prop, descriptor) + + return descriptor +} + +/** + * Create arguments string to keep arity. + */ + +function createArgumentsString(arity) { + var str = '' + + for (var i = 0; i < arity; i++) { + str += ', arg' + i + } + + return str.substr(2) +} + +/** + * Create stack string from stack. + */ + +function createStackString(stack) { + var str = this.name + ': ' + this.namespace + + if (this.message) { + str += ' deprecated ' + this.message + } + + for (var i = 0; i < stack.length; i++) { + str += '\n at ' + callSiteToString(stack[i]) + } + + return str +} + +/** + * Create deprecate for namespace in caller. + */ + +function depd(namespace) { + if (!namespace) { + throw new TypeError('argument namespace is required') + } + + var stack = getStack() + var site = callSiteLocation(stack[1]) + var file = site[0] + + function deprecate(message) { + // call to self as log + log.call(deprecate, message) + } + + deprecate._file = file + deprecate._ignored = isignored(namespace) + deprecate._namespace = namespace + deprecate._traced = istraced(namespace) + deprecate._warned = Object.create(null) + + deprecate.function = wrapfunction + deprecate.property = wrapproperty + + return deprecate +} + +/** + * Determine if namespace is ignored. + */ + +function isignored(namespace) { + /* istanbul ignore next: tested in a child processs */ + if (process.noDeprecation) { + // --no-deprecation support + return true + } + + var str = process.env.NO_DEPRECATION || '' + + // namespace ignored + return containsNamespace(str, namespace) +} + +/** + * Determine if namespace is traced. + */ + +function istraced(namespace) { + /* istanbul ignore next: tested in a child processs */ + if (process.traceDeprecation) { + // --trace-deprecation support + return true + } + + var str = process.env.TRACE_DEPRECATION || '' + + // namespace traced + return containsNamespace(str, namespace) +} + +/** + * Display deprecation message. + */ + +function log(message, site) { + var haslisteners = eventListenerCount(process, 'deprecation') !== 0 + + // abort early if no destination + if (!haslisteners && this._ignored) { + return + } + + var caller + var callFile + var callSite + var i = 0 + var seen = false + var stack = getStack() + var file = this._file + + if (site) { + // provided site + callSite = callSiteLocation(stack[1]) + callSite.name = site.name + file = callSite[0] + } else { + // get call site + i = 2 + site = callSiteLocation(stack[i]) + callSite = site + } + + // get caller of deprecated thing in relation to file + for (; i < stack.length; i++) { + caller = callSiteLocation(stack[i]) + callFile = caller[0] + + if (callFile === file) { + seen = true + } else if (callFile === this._file) { + file = this._file + } else if (seen) { + break + } + } + + var key = caller + ? site.join(':') + '__' + caller.join(':') + : undefined + + if (key !== undefined && key in this._warned) { + // already warned + return + } + + this._warned[key] = true + + // generate automatic message from call site + if (!message) { + message = callSite === site || !callSite.name + ? defaultMessage(site) + : defaultMessage(callSite) + } + + // emit deprecation if listeners exist + if (haslisteners) { + var err = DeprecationError(this._namespace, message, stack.slice(i)) + process.emit('deprecation', err) + return + } + + // format and write message + var format = process.stderr.isTTY + ? formatColor + : formatPlain + var msg = format.call(this, message, caller, stack.slice(i)) + process.stderr.write(msg + '\n', 'utf8') + + return +} + +/** + * Get call site location as array. + */ + +function callSiteLocation(callSite) { + var file = callSite.getFileName() || '' + var line = callSite.getLineNumber() + var colm = callSite.getColumnNumber() + + if (callSite.isEval()) { + file = callSite.getEvalOrigin() + ', ' + file + } + + var site = [file, line, colm] + + site.callSite = callSite + site.name = callSite.getFunctionName() + + return site +} + +/** + * Generate a default message from the site. + */ + +function defaultMessage(site) { + var callSite = site.callSite + var funcName = site.name + + // make useful anonymous name + if (!funcName) { + funcName = '' + } + + var context = callSite.getThis() + var typeName = context && callSite.getTypeName() + + // ignore useless type name + if (typeName === 'Object') { + typeName = undefined + } + + // make useful type name + if (typeName === 'Function') { + typeName = context.name || typeName + } + + return typeName && callSite.getMethodName() + ? typeName + '.' + funcName + : funcName +} + +/** + * Format deprecation message without color. + */ + +function formatPlain(msg, caller, stack) { + var timestamp = new Date().toUTCString() + + var formatted = timestamp + + ' ' + this._namespace + + ' deprecated ' + msg + + // add stack trace + if (this._traced) { + for (var i = 0; i < stack.length; i++) { + formatted += '\n at ' + callSiteToString(stack[i]) + } + + return formatted + } + + if (caller) { + formatted += ' at ' + formatLocation(caller) + } + + return formatted +} + +/** + * Format deprecation message with color. + */ + +function formatColor(msg, caller, stack) { + var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan + + ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow + + ' \x1b[0m' + msg + '\x1b[39m' // reset + + // add stack trace + if (this._traced) { + for (var i = 0; i < stack.length; i++) { + formatted += '\n \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan + } + + return formatted + } + + if (caller) { + formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan + } + + return formatted +} + +/** + * Format call site location. + */ + +function formatLocation(callSite) { + return relative(basePath, callSite[0]) + + ':' + callSite[1] + + ':' + callSite[2] +} + +/** + * Get the stack as array of call sites. + */ + +function getStack() { + var limit = Error.stackTraceLimit + var obj = {} + var prep = Error.prepareStackTrace + + Error.prepareStackTrace = prepareObjectStackTrace + Error.stackTraceLimit = Math.max(10, limit) + + // capture the stack + Error.captureStackTrace(obj) + + // slice this function off the top + var stack = obj.stack.slice(1) + + Error.prepareStackTrace = prep + Error.stackTraceLimit = limit + + return stack +} + +/** + * Capture call site stack from v8. + */ + +function prepareObjectStackTrace(obj, stack) { + return stack +} + +/** + * Return a wrapped function in a deprecation message. + */ + +function wrapfunction(fn, message) { + if (typeof fn !== 'function') { + throw new TypeError('argument fn must be a function') + } + + var args = createArgumentsString(fn.length) + var deprecate = this + var stack = getStack() + var site = callSiteLocation(stack[1]) + + site.name = fn.name + + var deprecatedfn = eval('(function (' + args + ') {\n' + + '"use strict"\n' + + 'log.call(deprecate, message, site)\n' + + 'return fn.apply(this, arguments)\n' + + '})') + + return deprecatedfn +} + +/** + * Wrap property in a deprecation message. + */ + +function wrapproperty(obj, prop, message) { + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { + throw new TypeError('argument obj must be object') + } + + var descriptor = Object.getOwnPropertyDescriptor(obj, prop) + + if (!descriptor) { + throw new TypeError('must call property on owner object') + } + + if (!descriptor.configurable) { + throw new TypeError('property must be configurable') + } + + var deprecate = this + var stack = getStack() + var site = callSiteLocation(stack[1]) + + // set site name + site.name = prop + + // convert data descriptor + if ('value' in descriptor) { + descriptor = convertDataDescriptorToAccessor(obj, prop, message) + } + + var get = descriptor.get + var set = descriptor.set + + // wrap getter + if (typeof get === 'function') { + descriptor.get = function getter() { + log.call(deprecate, message, site) + return get.apply(this, arguments) + } + } + + // wrap setter + if (typeof set === 'function') { + descriptor.set = function setter() { + log.call(deprecate, message, site) + return set.apply(this, arguments) + } + } + + Object.defineProperty(obj, prop, descriptor) +} + +/** + * Create DeprecationError for deprecation + */ + +function DeprecationError(namespace, message, stack) { + var error = new Error() + var stackString + + Object.defineProperty(error, 'constructor', { + value: DeprecationError + }) + + Object.defineProperty(error, 'message', { + configurable: true, + enumerable: false, + value: message, + writable: true + }) + + Object.defineProperty(error, 'name', { + enumerable: false, + configurable: true, + value: 'DeprecationError', + writable: true + }) + + Object.defineProperty(error, 'namespace', { + configurable: true, + enumerable: false, + value: namespace, + writable: true + }) + + Object.defineProperty(error, 'stack', { + configurable: true, + enumerable: false, + get: function () { + if (stackString !== undefined) { + return stackString + } + + // prepare stack trace + return stackString = createStackString.call(this, stack) + }, + set: function setter(val) { + stackString = val + } + }) + + return error +} diff --git a/node_modules/depd/lib/browser/index.js b/node_modules/depd/lib/browser/index.js new file mode 100644 index 0000000..f464e05 --- /dev/null +++ b/node_modules/depd/lib/browser/index.js @@ -0,0 +1,79 @@ +/*! + * depd + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + * @public + */ + +module.exports = depd + +/** + * Create deprecate for namespace in caller. + */ + +function depd(namespace) { + if (!namespace) { + throw new TypeError('argument namespace is required') + } + + function deprecate(message) { + // no-op in browser + } + + deprecate._file = undefined + deprecate._ignored = true + deprecate._namespace = namespace + deprecate._traced = false + deprecate._warned = Object.create(null) + + deprecate.function = wrapfunction + deprecate.property = wrapproperty + + return deprecate +} + +/** + * Return a wrapped function in a deprecation message. + * + * This is a no-op version of the wrapper, which does nothing but call + * validation. + */ + +function wrapfunction(fn, message) { + if (typeof fn !== 'function') { + throw new TypeError('argument fn must be a function') + } + + return fn +} + +/** + * Wrap property in a deprecation message. + * + * This is a no-op version of the wrapper, which does nothing but call + * validation. + */ + +function wrapproperty(obj, prop, message) { + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { + throw new TypeError('argument obj must be object') + } + + var descriptor = Object.getOwnPropertyDescriptor(obj, prop) + + if (!descriptor) { + throw new TypeError('must call property on owner object') + } + + if (!descriptor.configurable) { + throw new TypeError('property must be configurable') + } + + return +} diff --git a/node_modules/depd/lib/compat/buffer-concat.js b/node_modules/depd/lib/compat/buffer-concat.js new file mode 100644 index 0000000..4b73381 --- /dev/null +++ b/node_modules/depd/lib/compat/buffer-concat.js @@ -0,0 +1,35 @@ +/*! + * depd + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + */ + +module.exports = bufferConcat + +/** + * Concatenate an array of Buffers. + */ + +function bufferConcat(bufs) { + var length = 0 + + for (var i = 0, len = bufs.length; i < len; i++) { + length += bufs[i].length + } + + var buf = new Buffer(length) + var pos = 0 + + for (var i = 0, len = bufs.length; i < len; i++) { + bufs[i].copy(buf, pos) + pos += bufs[i].length + } + + return buf +} diff --git a/node_modules/depd/lib/compat/callsite-tostring.js b/node_modules/depd/lib/compat/callsite-tostring.js new file mode 100644 index 0000000..9ecef34 --- /dev/null +++ b/node_modules/depd/lib/compat/callsite-tostring.js @@ -0,0 +1,103 @@ +/*! + * depd + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + */ + +module.exports = callSiteToString + +/** + * Format a CallSite file location to a string. + */ + +function callSiteFileLocation(callSite) { + var fileName + var fileLocation = '' + + if (callSite.isNative()) { + fileLocation = 'native' + } else if (callSite.isEval()) { + fileName = callSite.getScriptNameOrSourceURL() + if (!fileName) { + fileLocation = callSite.getEvalOrigin() + } + } else { + fileName = callSite.getFileName() + } + + if (fileName) { + fileLocation += fileName + + var lineNumber = callSite.getLineNumber() + if (lineNumber != null) { + fileLocation += ':' + lineNumber + + var columnNumber = callSite.getColumnNumber() + if (columnNumber) { + fileLocation += ':' + columnNumber + } + } + } + + return fileLocation || 'unknown source' +} + +/** + * Format a CallSite to a string. + */ + +function callSiteToString(callSite) { + var addSuffix = true + var fileLocation = callSiteFileLocation(callSite) + var functionName = callSite.getFunctionName() + var isConstructor = callSite.isConstructor() + var isMethodCall = !(callSite.isToplevel() || isConstructor) + var line = '' + + if (isMethodCall) { + var methodName = callSite.getMethodName() + var typeName = getConstructorName(callSite) + + if (functionName) { + if (typeName && functionName.indexOf(typeName) !== 0) { + line += typeName + '.' + } + + line += functionName + + if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) { + line += ' [as ' + methodName + ']' + } + } else { + line += typeName + '.' + (methodName || '') + } + } else if (isConstructor) { + line += 'new ' + (functionName || '') + } else if (functionName) { + line += functionName + } else { + addSuffix = false + line += fileLocation + } + + if (addSuffix) { + line += ' (' + fileLocation + ')' + } + + return line +} + +/** + * Get constructor name of reviver. + */ + +function getConstructorName(obj) { + var receiver = obj.receiver + return (receiver.constructor && receiver.constructor.name) || null +} diff --git a/node_modules/depd/lib/compat/event-listener-count.js b/node_modules/depd/lib/compat/event-listener-count.js new file mode 100644 index 0000000..a05fceb --- /dev/null +++ b/node_modules/depd/lib/compat/event-listener-count.js @@ -0,0 +1,22 @@ +/*! + * depd + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + * @public + */ + +module.exports = eventListenerCount + +/** + * Get the count of listeners on an event emitter of a specific type. + */ + +function eventListenerCount(emitter, type) { + return emitter.listeners(type).length +} diff --git a/node_modules/depd/lib/compat/index.js b/node_modules/depd/lib/compat/index.js new file mode 100644 index 0000000..aa3c1de --- /dev/null +++ b/node_modules/depd/lib/compat/index.js @@ -0,0 +1,84 @@ +/*! + * depd + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var Buffer = require('buffer') +var EventEmitter = require('events').EventEmitter + +/** + * Module exports. + * @public + */ + +lazyProperty(module.exports, 'bufferConcat', function bufferConcat() { + return Buffer.concat || require('./buffer-concat') +}) + +lazyProperty(module.exports, 'callSiteToString', function callSiteToString() { + var limit = Error.stackTraceLimit + var obj = {} + var prep = Error.prepareStackTrace + + function prepareObjectStackTrace(obj, stack) { + return stack + } + + Error.prepareStackTrace = prepareObjectStackTrace + Error.stackTraceLimit = 2 + + // capture the stack + Error.captureStackTrace(obj) + + // slice the stack + var stack = obj.stack.slice() + + Error.prepareStackTrace = prep + Error.stackTraceLimit = limit + + return stack[0].toString ? toString : require('./callsite-tostring') +}) + +lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount() { + return EventEmitter.listenerCount || require('./event-listener-count') +}) + +/** + * Define a lazy property. + */ + +function lazyProperty(obj, prop, getter) { + function get() { + var val = getter() + + Object.defineProperty(obj, prop, { + configurable: true, + enumerable: true, + value: val + }) + + return val + } + + Object.defineProperty(obj, prop, { + configurable: true, + enumerable: true, + get: get + }) +} + +/** + * Call toString() on the obj + */ + +function toString(obj) { + return obj.toString() +} diff --git a/node_modules/depd/package.json b/node_modules/depd/package.json new file mode 100644 index 0000000..11f8cce --- /dev/null +++ b/node_modules/depd/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "depd@~1.1.0", + "scope": null, + "escapedName": "depd", + "name": "depd", + "rawSpec": "~1.1.0", + "spec": ">=1.1.0 <1.2.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "depd@>=1.1.0 <1.2.0", + "_id": "depd@1.1.0", + "_inCache": true, + "_installable": true, + "_location": "/depd", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "depd@~1.1.0", + "scope": null, + "escapedName": "depd", + "name": "depd", + "rawSpec": "~1.1.0", + "spec": ">=1.1.0 <1.2.0", + "type": "range" + }, + "_requiredBy": [ + "/express", + "/send" + ], + "_resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "_shasum": "e1bd82c6aab6ced965b97b88b17ed3e528ca18c3", + "_shrinkwrap": null, + "_spec": "depd@~1.1.0", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "author": { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + "browser": "lib/browser/index.js", + "bugs": { + "url": "https://github.com/dougwilson/nodejs-depd/issues" + }, + "dependencies": {}, + "description": "Deprecate all the things", + "devDependencies": { + "beautify-benchmark": "0.2.4", + "benchmark": "1.0.0", + "istanbul": "0.3.5", + "mocha": "~1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "e1bd82c6aab6ced965b97b88b17ed3e528ca18c3", + "tarball": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "lib/", + "History.md", + "LICENSE", + "index.js", + "Readme.md" + ], + "gitHead": "78c659de20283e3a6bee92bda455e6daff01686a", + "homepage": "https://github.com/dougwilson/nodejs-depd", + "keywords": [ + "deprecate", + "deprecated" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "depd", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/dougwilson/nodejs-depd.git" + }, + "scripts": { + "bench": "node benchmark/index.js", + "test": "mocha --reporter spec --bail test/", + "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --no-exit test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/" + }, + "version": "1.1.0" +} diff --git a/node_modules/destroy/LICENSE b/node_modules/destroy/LICENSE new file mode 100644 index 0000000..a7ae8ee --- /dev/null +++ b/node_modules/destroy/LICENSE @@ -0,0 +1,22 @@ + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. diff --git a/node_modules/destroy/README.md b/node_modules/destroy/README.md new file mode 100644 index 0000000..6474bc3 --- /dev/null +++ b/node_modules/destroy/README.md @@ -0,0 +1,60 @@ +# Destroy + +[![NPM version][npm-image]][npm-url] +[![Build status][travis-image]][travis-url] +[![Test coverage][coveralls-image]][coveralls-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] +[![Gittip][gittip-image]][gittip-url] + +Destroy a stream. + +This module is meant to ensure a stream gets destroyed, handling different APIs +and Node.js bugs. + +## API + +```js +var destroy = require('destroy') +``` + +### destroy(stream) + +Destroy the given stream. In most cases, this is identical to a simple +`stream.destroy()` call. The rules are as follows for a given stream: + + 1. If the `stream` is an instance of `ReadStream`, then call `stream.destroy()` + and add a listener to the `open` event to call `stream.close()` if it is + fired. This is for a Node.js bug that will leak a file descriptor if + `.destroy()` is called before `open`. + 2. If the `stream` is not an instance of `Stream`, then nothing happens. + 3. If the `stream` has a `.destroy()` method, then call it. + +The function returns the `stream` passed in as the argument. + +## Example + +```js +var destroy = require('destroy') + +var fs = require('fs') +var stream = fs.createReadStream('package.json') + +// ... and later +destroy(stream) +``` + +[npm-image]: https://img.shields.io/npm/v/destroy.svg?style=flat-square +[npm-url]: https://npmjs.org/package/destroy +[github-tag]: http://img.shields.io/github/tag/stream-utils/destroy.svg?style=flat-square +[github-url]: https://github.com/stream-utils/destroy/tags +[travis-image]: https://img.shields.io/travis/stream-utils/destroy.svg?style=flat-square +[travis-url]: https://travis-ci.org/stream-utils/destroy +[coveralls-image]: https://img.shields.io/coveralls/stream-utils/destroy.svg?style=flat-square +[coveralls-url]: https://coveralls.io/r/stream-utils/destroy?branch=master +[license-image]: http://img.shields.io/npm/l/destroy.svg?style=flat-square +[license-url]: LICENSE.md +[downloads-image]: http://img.shields.io/npm/dm/destroy.svg?style=flat-square +[downloads-url]: https://npmjs.org/package/destroy +[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square +[gittip-url]: https://www.gittip.com/jonathanong/ diff --git a/node_modules/destroy/index.js b/node_modules/destroy/index.js new file mode 100644 index 0000000..6da2d26 --- /dev/null +++ b/node_modules/destroy/index.js @@ -0,0 +1,75 @@ +/*! + * destroy + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var ReadStream = require('fs').ReadStream +var Stream = require('stream') + +/** + * Module exports. + * @public + */ + +module.exports = destroy + +/** + * Destroy a stream. + * + * @param {object} stream + * @public + */ + +function destroy(stream) { + if (stream instanceof ReadStream) { + return destroyReadStream(stream) + } + + if (!(stream instanceof Stream)) { + return stream + } + + if (typeof stream.destroy === 'function') { + stream.destroy() + } + + return stream +} + +/** + * Destroy a ReadStream. + * + * @param {object} stream + * @private + */ + +function destroyReadStream(stream) { + stream.destroy() + + if (typeof stream.close === 'function') { + // node.js core bug work-around + stream.on('open', onOpenClose) + } + + return stream +} + +/** + * On open handler to close stream. + * @private + */ + +function onOpenClose() { + if (typeof this.fd === 'number') { + // actually close down the fd + this.close() + } +} diff --git a/node_modules/destroy/package.json b/node_modules/destroy/package.json new file mode 100644 index 0000000..a420583 --- /dev/null +++ b/node_modules/destroy/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "destroy@~1.0.4", + "scope": null, + "escapedName": "destroy", + "name": "destroy", + "rawSpec": "~1.0.4", + "spec": ">=1.0.4 <1.1.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\send" + ] + ], + "_from": "destroy@>=1.0.4 <1.1.0", + "_id": "destroy@1.0.4", + "_inCache": true, + "_installable": true, + "_location": "/destroy", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "destroy@~1.0.4", + "scope": null, + "escapedName": "destroy", + "name": "destroy", + "rawSpec": "~1.0.4", + "spec": ">=1.0.4 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/send" + ], + "_resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "_shasum": "978857442c44749e4206613e37946205826abd80", + "_shrinkwrap": null, + "_spec": "destroy@~1.0.4", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\send", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "bugs": { + "url": "https://github.com/stream-utils/destroy/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "destroy a stream if possible", + "devDependencies": { + "istanbul": "0.4.2", + "mocha": "2.3.4" + }, + "directories": {}, + "dist": { + "shasum": "978857442c44749e4206613e37946205826abd80", + "tarball": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" + }, + "files": [ + "index.js", + "LICENSE" + ], + "gitHead": "86edea01456f5fa1027f6a47250c34c713cbcc3b", + "homepage": "https://github.com/stream-utils/destroy", + "keywords": [ + "stream", + "streams", + "destroy", + "cleanup", + "leak", + "fd" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "destroy", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/stream-utils/destroy.git" + }, + "scripts": { + "test": "mocha --reporter spec", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot" + }, + "version": "1.0.4" +} diff --git a/node_modules/ee-first/LICENSE b/node_modules/ee-first/LICENSE new file mode 100644 index 0000000..a7ae8ee --- /dev/null +++ b/node_modules/ee-first/LICENSE @@ -0,0 +1,22 @@ + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. diff --git a/node_modules/ee-first/README.md b/node_modules/ee-first/README.md new file mode 100644 index 0000000..cbd2478 --- /dev/null +++ b/node_modules/ee-first/README.md @@ -0,0 +1,80 @@ +# EE First + +[![NPM version][npm-image]][npm-url] +[![Build status][travis-image]][travis-url] +[![Test coverage][coveralls-image]][coveralls-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] +[![Gittip][gittip-image]][gittip-url] + +Get the first event in a set of event emitters and event pairs, +then clean up after itself. + +## Install + +```sh +$ npm install ee-first +``` + +## API + +```js +var first = require('ee-first') +``` + +### first(arr, listener) + +Invoke `listener` on the first event from the list specified in `arr`. `arr` is +an array of arrays, with each array in the format `[ee, ...event]`. `listener` +will be called only once, the first time any of the given events are emitted. If +`error` is one of the listened events, then if that fires first, the `listener` +will be given the `err` argument. + +The `listener` is invoked as `listener(err, ee, event, args)`, where `err` is the +first argument emitted from an `error` event, if applicable; `ee` is the event +emitter that fired; `event` is the string event name that fired; and `args` is an +array of the arguments that were emitted on the event. + +```js +var ee1 = new EventEmitter() +var ee2 = new EventEmitter() + +first([ + [ee1, 'close', 'end', 'error'], + [ee2, 'error'] +], function (err, ee, event, args) { + // listener invoked +}) +``` + +#### .cancel() + +The group of listeners can be cancelled before being invoked and have all the event +listeners removed from the underlying event emitters. + +```js +var thunk = first([ + [ee1, 'close', 'end', 'error'], + [ee2, 'error'] +], function (err, ee, event, args) { + // listener invoked +}) + +// cancel and clean up +thunk.cancel() +``` + +[npm-image]: https://img.shields.io/npm/v/ee-first.svg?style=flat-square +[npm-url]: https://npmjs.org/package/ee-first +[github-tag]: http://img.shields.io/github/tag/jonathanong/ee-first.svg?style=flat-square +[github-url]: https://github.com/jonathanong/ee-first/tags +[travis-image]: https://img.shields.io/travis/jonathanong/ee-first.svg?style=flat-square +[travis-url]: https://travis-ci.org/jonathanong/ee-first +[coveralls-image]: https://img.shields.io/coveralls/jonathanong/ee-first.svg?style=flat-square +[coveralls-url]: https://coveralls.io/r/jonathanong/ee-first?branch=master +[license-image]: http://img.shields.io/npm/l/ee-first.svg?style=flat-square +[license-url]: LICENSE.md +[downloads-image]: http://img.shields.io/npm/dm/ee-first.svg?style=flat-square +[downloads-url]: https://npmjs.org/package/ee-first +[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square +[gittip-url]: https://www.gittip.com/jonathanong/ diff --git a/node_modules/ee-first/index.js b/node_modules/ee-first/index.js new file mode 100644 index 0000000..501287c --- /dev/null +++ b/node_modules/ee-first/index.js @@ -0,0 +1,95 @@ +/*! + * ee-first + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + * @public + */ + +module.exports = first + +/** + * Get the first event in a set of event emitters and event pairs. + * + * @param {array} stuff + * @param {function} done + * @public + */ + +function first(stuff, done) { + if (!Array.isArray(stuff)) + throw new TypeError('arg must be an array of [ee, events...] arrays') + + var cleanups = [] + + for (var i = 0; i < stuff.length; i++) { + var arr = stuff[i] + + if (!Array.isArray(arr) || arr.length < 2) + throw new TypeError('each array member must be [ee, events...]') + + var ee = arr[0] + + for (var j = 1; j < arr.length; j++) { + var event = arr[j] + var fn = listener(event, callback) + + // listen to the event + ee.on(event, fn) + // push this listener to the list of cleanups + cleanups.push({ + ee: ee, + event: event, + fn: fn, + }) + } + } + + function callback() { + cleanup() + done.apply(null, arguments) + } + + function cleanup() { + var x + for (var i = 0; i < cleanups.length; i++) { + x = cleanups[i] + x.ee.removeListener(x.event, x.fn) + } + } + + function thunk(fn) { + done = fn + } + + thunk.cancel = cleanup + + return thunk +} + +/** + * Create the event listener. + * @private + */ + +function listener(event, done) { + return function onevent(arg1) { + var args = new Array(arguments.length) + var ee = this + var err = event === 'error' + ? arg1 + : null + + // copy args to prevent arguments escaping scope + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + + done(err, ee, event, args) + } +} diff --git a/node_modules/ee-first/package.json b/node_modules/ee-first/package.json new file mode 100644 index 0000000..99e8cf1 --- /dev/null +++ b/node_modules/ee-first/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "ee-first@1.1.1", + "scope": null, + "escapedName": "ee-first", + "name": "ee-first", + "rawSpec": "1.1.1", + "spec": "1.1.1", + "type": "version" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\on-finished" + ] + ], + "_from": "ee-first@1.1.1", + "_id": "ee-first@1.1.1", + "_inCache": true, + "_installable": true, + "_location": "/ee-first", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "ee-first@1.1.1", + "scope": null, + "escapedName": "ee-first", + "name": "ee-first", + "rawSpec": "1.1.1", + "spec": "1.1.1", + "type": "version" + }, + "_requiredBy": [ + "/on-finished" + ], + "_resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "_shasum": "590c61156b0ae2f4f0255732a158b266bc56b21d", + "_shrinkwrap": null, + "_spec": "ee-first@1.1.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\on-finished", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "bugs": { + "url": "https://github.com/jonathanong/ee-first/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "return the first event in a set of ee/event pairs", + "devDependencies": { + "istanbul": "0.3.9", + "mocha": "2.2.5" + }, + "directories": {}, + "dist": { + "shasum": "590c61156b0ae2f4f0255732a158b266bc56b21d", + "tarball": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + }, + "files": [ + "index.js", + "LICENSE" + ], + "gitHead": "512e0ce4cc3643f603708f965a97b61b1a9c0441", + "homepage": "https://github.com/jonathanong/ee-first", + "license": "MIT", + "maintainers": [ + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "ee-first", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonathanong/ee-first.git" + }, + "scripts": { + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" + }, + "version": "1.1.1" +} diff --git a/node_modules/encodeurl/HISTORY.md b/node_modules/encodeurl/HISTORY.md new file mode 100644 index 0000000..06d34a5 --- /dev/null +++ b/node_modules/encodeurl/HISTORY.md @@ -0,0 +1,9 @@ +1.0.1 / 2016-06-09 +================== + + * Fix encoding unpaired surrogates at start/end of string + +1.0.0 / 2016-06-08 +================== + + * Initial release diff --git a/node_modules/encodeurl/LICENSE b/node_modules/encodeurl/LICENSE new file mode 100644 index 0000000..8812229 --- /dev/null +++ b/node_modules/encodeurl/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2016 Douglas Christopher Wilson + +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. diff --git a/node_modules/encodeurl/README.md b/node_modules/encodeurl/README.md new file mode 100644 index 0000000..b086133 --- /dev/null +++ b/node_modules/encodeurl/README.md @@ -0,0 +1,124 @@ +# encodeurl + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +Encode a URL to a percent-encoded form, excluding already-encoded sequences + +## Installation + +```sh +$ npm install encodeurl +``` + +## API + +```js +var encodeUrl = require('encodeurl') +``` + +### encodeUrl(url) + +Encode a URL to a percent-encoded form, excluding already-encoded sequences. + +This function will take an already-encoded URL and encode all the non-URL +code points (as UTF-8 byte sequences). This function will not encode the +"%" character unless it is not part of a valid sequence (`%20` will be +left as-is, but `%foo` will be encoded as `%25foo`). + +This encode is meant to be "safe" and does not throw errors. It will try as +hard as it can to properly encode the given URL, including replacing any raw, +unpaired surrogate pairs with the Unicode replacement character prior to +encoding. + +This function is _similar_ to the intrinsic function `encodeURI`, except it +will not encode the `%` character if that is part of a valid sequence, will +not encode `[` and `]` (for IPv6 hostnames) and will replace raw, unpaired +surrogate pairs with the Unicode replacement character (instead of throwing). + +## Examples + +### Encode a URL containing user-controled data + +```js +var encodeUrl = require('encodeurl') +var escapeHtml = require('escape-html') + +http.createServer(function onRequest (req, res) { + // get encoded form of inbound url + var url = encodeUrl(req.url) + + // create html message + var body = '

    Location ' + escapeHtml(url) + ' not found

    ' + + // send a 404 + res.statusCode = 404 + res.setHeader('Content-Type', 'text/html; charset=UTF-8') + res.setHeader('Content-Length', String(Buffer.byteLength(body, 'utf-8'))) + res.end(body, 'utf-8') +}) +``` + +### Encode a URL for use in a header field + +```js +var encodeUrl = require('encodeurl') +var escapeHtml = require('escape-html') +var url = require('url') + +http.createServer(function onRequest (req, res) { + // parse inbound url + var href = url.parse(req) + + // set new host for redirect + href.host = 'localhost' + href.protocol = 'https:' + href.slashes = true + + // create location header + var location = encodeUrl(url.format(href)) + + // create html message + var body = '

    Redirecting to new site: ' + escapeHtml(location) + '

    ' + + // send a 301 + res.statusCode = 301 + res.setHeader('Content-Type', 'text/html; charset=UTF-8') + res.setHeader('Content-Length', String(Buffer.byteLength(body, 'utf-8'))) + res.setHeader('Location', location) + res.end(body, 'utf-8') +}) +``` + +## Testing + +```sh +$ npm test +$ npm run lint +``` + +## References + +- [RFC 3986: Uniform Resource Identifier (URI): Generic Syntax][rfc-3986] +- [WHATWG URL Living Standard][whatwg-url] + +[rfc-3986]: https://tools.ietf.org/html/rfc3986 +[whatwg-url]: https://url.spec.whatwg.org/ + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/encodeurl.svg +[npm-url]: https://npmjs.org/package/encodeurl +[node-version-image]: https://img.shields.io/node/v/encodeurl.svg +[node-version-url]: https://nodejs.org/en/download +[travis-image]: https://img.shields.io/travis/pillarjs/encodeurl.svg +[travis-url]: https://travis-ci.org/pillarjs/encodeurl +[coveralls-image]: https://img.shields.io/coveralls/pillarjs/encodeurl.svg +[coveralls-url]: https://coveralls.io/r/pillarjs/encodeurl?branch=master +[downloads-image]: https://img.shields.io/npm/dm/encodeurl.svg +[downloads-url]: https://npmjs.org/package/encodeurl diff --git a/node_modules/encodeurl/index.js b/node_modules/encodeurl/index.js new file mode 100644 index 0000000..ae77cc9 --- /dev/null +++ b/node_modules/encodeurl/index.js @@ -0,0 +1,60 @@ +/*! + * encodeurl + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + * @public + */ + +module.exports = encodeUrl + +/** + * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") + * and including invalid escape sequences. + * @private + */ + +var ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]))+/g + +/** + * RegExp to match unmatched surrogate pair. + * @private + */ + +var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g + +/** + * String to replace unmatched surrogate pair with. + * @private + */ + +var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2' + +/** + * Encode a URL to a percent-encoded form, excluding already-encoded sequences. + * + * This function will take an already-encoded URL and encode all the non-URL + * code points. This function will not encode the "%" character unless it is + * not part of a valid sequence (`%20` will be left as-is, but `%foo` will + * be encoded as `%25foo`). + * + * This encode is meant to be "safe" and does not throw errors. It will try as + * hard as it can to properly encode the given URL, including replacing any raw, + * unpaired surrogate pairs with the Unicode replacement character prior to + * encoding. + * + * @param {string} url + * @return {string} + * @public + */ + +function encodeUrl (url) { + return String(url) + .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) + .replace(ENCODE_CHARS_REGEXP, encodeURI) +} diff --git a/node_modules/encodeurl/package.json b/node_modules/encodeurl/package.json new file mode 100644 index 0000000..b7c94c0 --- /dev/null +++ b/node_modules/encodeurl/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "encodeurl@~1.0.1", + "scope": null, + "escapedName": "encodeurl", + "name": "encodeurl", + "rawSpec": "~1.0.1", + "spec": ">=1.0.1 <1.1.0", + "type": "range" + }, + "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express" + ] + ], + "_from": "encodeurl@>=1.0.1 <1.1.0", + "_id": "encodeurl@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/encodeurl", + "_nodeVersion": "4.4.3", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/encodeurl-1.0.1.tgz_1465519736251_0.09314409433864057" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "2.15.1", + "_phantomChildren": {}, + "_requested": { + "raw": "encodeurl@~1.0.1", + "scope": null, + "escapedName": "encodeurl", + "name": "encodeurl", + "rawSpec": "~1.0.1", + "spec": ">=1.0.1 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/express", + "/send", + "/serve-static" + ], + "_resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "_shasum": "79e3d58655346909fe6f0f45a5de68103b294d20", + "_shrinkwrap": null, + "_spec": "encodeurl@~1.0.1", + "_where": "C:\\Users\\const\\IdeaProjects\\space-game\\node_modules\\express", + "bugs": { + "url": "https://github.com/pillarjs/encodeurl/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "Encode a URL to a percent-encoded form, excluding already-encoded sequences", + "devDependencies": { + "eslint": "2.11.1", + "eslint-config-standard": "5.3.1", + "eslint-plugin-promise": "1.3.2", + "eslint-plugin-standard": "1.3.2", + "istanbul": "0.4.3", + "mocha": "2.5.3" + }, + "directories": {}, + "dist": { + "shasum": "79e3d58655346909fe6f0f45a5de68103b294d20", + "tarball": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "files": [ + "LICENSE", + "HISTORY.md", + "README.md", + "index.js" + ], + "gitHead": "39ed0c235fed4cea7d012038fd6bb0480561d226", + "homepage": "https://github.com/pillarjs/encodeurl#readme", + "keywords": [ + "encode", + "encodeurl", + "url" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "encodeurl", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/pillarjs/encodeurl.git" + }, + "scripts": { + "lint": "eslint **/*.js", + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" + }, + "version": "1.0.1" +} diff --git a/node_modules/engine.io-client/.npmignore b/node_modules/engine.io-client/.npmignore new file mode 100644 index 0000000..3957910 --- /dev/null +++ b/node_modules/engine.io-client/.npmignore @@ -0,0 +1,2 @@ +support/ +test diff --git a/node_modules/engine.io-client/.travis.yml b/node_modules/engine.io-client/.travis.yml new file mode 100644 index 0000000..3eb12a7 --- /dev/null +++ b/node_modules/engine.io-client/.travis.yml @@ -0,0 +1,46 @@ +language: node_js +sudo: false +node_js: + - '0.10' + - '0.12' + - '4' +notifications: + irc: "irc.freenode.org#socket.io" +matrix: + include: + - node_js: '0.10' + env: BROWSER_NAME=chrome BROWSER_VERSION=latest + - node_js: '0.10' + env: BROWSER_NAME=safari BROWSER_VERSION=latest + - node_js: '0.10' + env: BROWSER_NAME=ie BROWSER_VERSION=6 + - node_js: '0.10' + env: BROWSER_NAME=ie BROWSER_VERSION=7 + - node_js: '0.10' + env: BROWSER_NAME=ie BROWSER_VERSION=8 + - node_js: '0.10' + env: BROWSER_NAME=ie BROWSER_VERSION=9 + - node_js: '0.10' + env: BROWSER_NAME=ie BROWSER_VERSION=10 BROWSER_PLATFORM="Windows 2012" + - node_js: '0.10' + env: BROWSER_NAME=ie BROWSER_VERSION=latest BROWSER_PLATFORM="Windows 2012" + - node_js: '0.10' + env: BROWSER_NAME=iphone BROWSER_VERSION=5.1 + - node_js: '0.10' + env: BROWSER_NAME=iphone BROWSER_VERSION=6.1 + - node_js: '0.10' + env: BROWSER_NAME=iphone BROWSER_VERSION=7.1 + - node_js: '0.10' + env: BROWSER_NAME=iphone BROWSER_VERSION=8.4 + - node_js: '0.10' + env: BROWSER_NAME=iphone BROWSER_VERSION=latest + - node_js: '0.10' + env: BROWSER_NAME=android BROWSER_VERSION=4.0 + - node_js: '0.10' + env: BROWSER_NAME=android BROWSER_VERSION=4.1 + - node_js: '0.10' + env: BROWSER_NAME=android BROWSER_VERSION=4.2 + - node_js: '0.10' + env: BROWSER_NAME=android BROWSER_VERSION=4.3 + - node_js: '0.10' + env: BROWSER_NAME=android BROWSER_VERSION=4.4 diff --git a/node_modules/engine.io-client/.zuul.yml b/node_modules/engine.io-client/.zuul.yml new file mode 100644 index 0000000..15d6892 --- /dev/null +++ b/node_modules/engine.io-client/.zuul.yml @@ -0,0 +1,6 @@ +ui: mocha-bdd +server: ./test/support/server.js +tunnel: + type: ngrok + authtoken: 6Aw8vTgcG5EvXdQywVvbh_3fMxvd4Q7dcL2caAHAFjV + proto: tcp diff --git a/node_modules/engine.io-client/History.md b/node_modules/engine.io-client/History.md new file mode 100644 index 0000000..7b1dc9b --- /dev/null +++ b/node_modules/engine.io-client/History.md @@ -0,0 +1,568 @@ + +1.6.11 / 2016-06-23 +=================== + + * bump version + +1.6.10 / 2016-06-23 +=================== + + * bump version + +1.6.9 / 2016-05-02 +================== + + * default `rejectUnauthorized` to `true` + +1.6.8 / 2016-01-25 +================== + + * safely resolve `ws` module + +1.6.7 / 2016-01-10 +================== + + * prevent `ws` from being added to the bundle + * added jsonp fix for when no ` + +``` + +### With browserify + +Engine.IO is a commonjs module, which means you can include it by using +`require` on the browser and package using [browserify](http://browserify.org/): + +1. install the client package + + ```bash + $ npm install engine.io-client + ``` + +1. write your app code + + ```js + var socket = require('engine.io-client')('ws://localhost'); + socket.on('open', function(){ + socket.on('message', function(data){}); + socket.on('close', function(){}); + }); + ``` + +1. build your app bundle + + ```bash + $ browserify app.js > bundle.js + ``` + +1. include on your page + + ```html + + ``` + +### Sending and receiving binary + +```html + + +``` + +### Node.JS + +Add `engine.io-client` to your `package.json` and then: + +```js +var socket = require('engine.io-client')('ws://localhost'); +socket.on('open', function(){ + socket.on('message', function(data){}); + socket.on('close', function(){}); +}); +``` + +### Node.js with certificates +```js +var opts = { + key: fs.readFileSync('test/fixtures/client.key'), + cert: fs.readFileSync('test/fixtures/client.crt'), + ca: fs.readFileSync('test/fixtures/ca.crt') +}; + +var socket = require('engine.io-client')('ws://localhost', opts); +socket.on('open', function(){ + socket.on('message', function(data){}); + socket.on('close', function(){}); +}); +``` + +### Node.js with extraHeaders +```js +var opts = { + extraHeaders: { + 'X-Custom-Header-For-My-Project': 'my-secret-access-token', + 'Cookie': 'user_session=NI2JlCKF90aE0sJZD9ZzujtdsUqNYSBYxzlTsvdSUe35ZzdtVRGqYFr0kdGxbfc5gUOkR9RGp20GVKza; path=/; expires=Tue, 07-Apr-2015 18:18:08 GMT; secure; HttpOnly' + } +}; + +var socket = require('engine.io-client')('ws://localhost', opts); +socket.on('open', function(){ + socket.on('message', function(data){}); + socket.on('close', function(){}); +}); +``` + +## Features + +- Lightweight +- Runs on browser and node.js seamlessly +- Transports are independent of `Engine` + - Easy to debug + - Easy to unit test +- Runs inside HTML5 WebWorker +- Can send and receive binary data + - Receives as ArrayBuffer or Blob when in browser, and Buffer or ArrayBuffer + in Node + - When XHR2 or WebSockets are used, binary is emitted directly. Otherwise + binary is encoded into base64 strings, and decoded when binary types are + supported. + - With browsers that don't support ArrayBuffer, an object { base64: true, + data: dataAsBase64String } is emitted on the `message` event. + +## API + +### Socket + +The client class. Mixes in [Emitter](http://github.com/component/emitter). +Exposed as `eio` in the browser standalone build. + +#### Properties + +- `protocol` _(Number)_: protocol revision number +- `binaryType` _(String)_ : can be set to 'arraybuffer' or 'blob' in browsers, + and `buffer` or `arraybuffer` in Node. Blob is only used in browser if it's + supported. + +#### Events + +- `open` + - Fired upon successful connection. +- `message` + - Fired when data is received from the server. + - **Arguments** + - `String` | `ArrayBuffer`: utf-8 encoded data or ArrayBuffer containing + binary data +- `close` + - Fired upon disconnection. In compliance with the WebSocket API spec, this event may be + fired even if the `open` event does not occur (i.e. due to connection error or `close()`). +- `error` + - Fired when an error occurs. +- `flush` + - Fired upon completing a buffer flush +- `drain` + - Fired after `drain` event of transport if writeBuffer is empty +- `upgradeError` + - Fired if an error occurs with a transport we're trying to upgrade to. +- `upgrade` + - Fired upon upgrade success, after the new transport is set +- `ping` + - Fired upon _flushing_ a ping packet (ie: actual packet write out) +- `pong` + - Fired upon receiving a pong packet. + +#### Methods + +- **constructor** + - Initializes the client + - **Parameters** + - `String` uri + - `Object`: optional, options object + - **Options** + - `agent` (`http.Agent`): `http.Agent` to use, defaults to `false` (NodeJS only) + - `upgrade` (`Boolean`): defaults to true, whether the client should try + to upgrade the transport from long-polling to something better. + - `forceJSONP` (`Boolean`): forces JSONP for polling transport. + - `jsonp` (`Boolean`): determines whether to use JSONP when + necessary for polling. If disabled (by settings to false) an error will + be emitted (saying "No transports available") if no other transports + are available. If another transport is available for opening a + connection (e.g. WebSocket) that transport + will be used instead. + - `forceBase64` (`Boolean`): forces base 64 encoding for polling transport even when XHR2 responseType is available and WebSocket even if the used standard supports binary. + - `enablesXDR` (`Boolean`): enables XDomainRequest for IE8 to avoid loading bar flashing with click sound. default to `false` because XDomainRequest has a flaw of not sending cookie. + - `timestampRequests` (`Boolean`): whether to add the timestamp with each + transport request. Note: polling requests are always stamped unless this + option is explicitly set to `false` (`false`) + - `timestampParam` (`String`): timestamp parameter (`t`) + - `policyPort` (`Number`): port the policy server listens on (`843`) + - `path` (`String`): path to connect to, default is `/engine.io` + - `transports` (`Array`): a list of transports to try (in order). + Defaults to `['polling', 'websocket']`. `Engine` + always attempts to connect directly with the first one, provided the + feature detection test for it passes. + - `rememberUpgrade` (`Boolean`): defaults to false. + If true and if the previous websocket connection to the server succeeded, + the connection attempt will bypass the normal upgrade process and will initially + try websocket. A connection attempt following a transport error will use the + normal upgrade process. It is recommended you turn this on only when using + SSL/TLS connections, or if you know that your network does not block websockets. + - `pfx` (`String`): Certificate, Private key and CA certificates to use for SSL. Can be used in Node.js client environment to manually specify certificate information. + - `key` (`String`): Private key to use for SSL. Can be used in Node.js client environment to manually specify certificate information. + - `passphrase` (`String`): A string of passphrase for the private key or pfx. Can be used in Node.js client environment to manually specify certificate information. + - `cert` (`String`): Public x509 certificate to use. Can be used in Node.js client environment to manually specify certificate information. + - `ca` (`String`|`Array`): An authority certificate or array of authority certificates to check the remote host against.. Can be used in Node.js client environment to manually specify certificate information. + - `ciphers` (`String`): A string describing the ciphers to use or exclude. Consult the [cipher format list](http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT) for details on the format. Can be used in Node.js client environment to manually specify certificate information. + - `rejectUnauthorized` (`Boolean`): If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent. Can be used in Node.js client environment to manually specify certificate information. + - `perMessageDeflate` (`Object|Boolean`): parameters of the WebSocket permessage-deflate extension + (see [ws module](https://github.com/einaros/ws) api docs). Set to `false` to disable. (`true`) + - `threshold` (`Number`): data is compressed only if the byte size is above this value. This option is ignored on the browser. (`1024`) + - `extraHeaders` (`Object`): Headers that will be passed for each request to the server (via xhr-polling and via websockets). These values then can be used during handshake or for special proxies. Can only be used in Node.js client environment. +- `send` + - Sends a message to the server + - **Parameters** + - `String` | `ArrayBuffer` | `ArrayBufferView` | `Blob`: data to send + - `Object`: optional, options object + - `Function`: optional, callback upon `drain` + - **Options** + - `compress` (`Boolean`): whether to compress sending data. This option is ignored and forced to be `true` on the browser. (`true`) +- `close` + - Disconnects the client. + +### Transport + +The transport class. Private. _Inherits from EventEmitter_. + +#### Events + +- `poll`: emitted by polling transports upon starting a new request +- `pollComplete`: emitted by polling transports upon completing a request +- `drain`: emitted by polling transports upon a buffer drain + +## Tests + +`engine.io-client` is used to test +[engine](http://github.com/socketio/engine.io). Running the `engine.io` +test suite ensures the client works and vice-versa. + +Browser tests are run using [zuul](https://github.com/defunctzombie/zuul). You can +run the tests locally using the following command. + +``` +./node_modules/.bin/zuul --local 8080 -- test/index.js +``` + +Additionally, `engine.io-client` has a standalone test suite you can run +with `make test` which will run node.js and browser tests. You must have zuul setup with +a saucelabs account. + +## Support + +The support channels for `engine.io-client` are the same as `socket.io`: + - irc.freenode.net **#socket.io** + - [Google Groups](http://groups.google.com/group/socket_io) + - [Website](http://socket.io) + +## Development + +To contribute patches, run tests or benchmarks, make sure to clone the +repository: + +```bash +git clone git://github.com/socketio/engine.io-client.git +``` + +Then: + +```bash +cd engine.io-client +npm install +``` + +See the `Tests` section above for how to run tests before submitting any patches. + +## License + +MIT - Copyright (c) 2014 Automattic, Inc. + diff --git a/node_modules/engine.io-client/engine.io.js b/node_modules/engine.io-client/engine.io.js new file mode 100644 index 0000000..eeefaa9 --- /dev/null +++ b/node_modules/engine.io-client/engine.io.js @@ -0,0 +1,4244 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.eio=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + this.extraHeaders = opts.extraHeaders; + } + } + + this.open(); +} + +Socket.priorWebsocketSuccess = false; + +/** + * Mix in `Emitter`. + */ + +Emitter(Socket.prototype); + +/** + * Protocol version. + * + * @api public + */ + +Socket.protocol = parser.protocol; // this is an int + +/** + * Expose deps for legacy compatibility + * and standalone browser access. + */ + +Socket.Socket = Socket; +Socket.Transport = _dereq_('./transport'); +Socket.transports = _dereq_('./transports'); +Socket.parser = _dereq_('engine.io-parser'); + +/** + * Creates transport of the given type. + * + * @param {String} transport name + * @return {Transport} + * @api private + */ + +Socket.prototype.createTransport = function (name) { + debug('creating transport "%s"', name); + var query = clone(this.query); + + // append engine.io protocol identifier + query.EIO = parser.protocol; + + // transport name + query.transport = name; + + // session id if we already have one + if (this.id) query.sid = this.id; + + var transport = new transports[name]({ + agent: this.agent, + hostname: this.hostname, + port: this.port, + secure: this.secure, + path: this.path, + query: query, + forceJSONP: this.forceJSONP, + jsonp: this.jsonp, + forceBase64: this.forceBase64, + enablesXDR: this.enablesXDR, + timestampRequests: this.timestampRequests, + timestampParam: this.timestampParam, + policyPort: this.policyPort, + socket: this, + pfx: this.pfx, + key: this.key, + passphrase: this.passphrase, + cert: this.cert, + ca: this.ca, + ciphers: this.ciphers, + rejectUnauthorized: this.rejectUnauthorized, + perMessageDeflate: this.perMessageDeflate, + extraHeaders: this.extraHeaders + }); + + return transport; +}; + +function clone (obj) { + var o = {}; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + o[i] = obj[i]; + } + } + return o; +} + +/** + * Initializes transport to use and starts probe. + * + * @api private + */ +Socket.prototype.open = function () { + var transport; + if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) { + transport = 'websocket'; + } else if (0 === this.transports.length) { + // Emit error on next tick so it can be listened to + var self = this; + setTimeout(function() { + self.emit('error', 'No transports available'); + }, 0); + return; + } else { + transport = this.transports[0]; + } + this.readyState = 'opening'; + + // Retry with the next transport if the transport is disabled (jsonp: false) + try { + transport = this.createTransport(transport); + } catch (e) { + this.transports.shift(); + this.open(); + return; + } + + transport.open(); + this.setTransport(transport); +}; + +/** + * Sets the current transport. Disables the existing one (if any). + * + * @api private + */ + +Socket.prototype.setTransport = function(transport){ + debug('setting transport %s', transport.name); + var self = this; + + if (this.transport) { + debug('clearing existing transport %s', this.transport.name); + this.transport.removeAllListeners(); + } + + // set up transport + this.transport = transport; + + // set up transport listeners + transport + .on('drain', function(){ + self.onDrain(); + }) + .on('packet', function(packet){ + self.onPacket(packet); + }) + .on('error', function(e){ + self.onError(e); + }) + .on('close', function(){ + self.onClose('transport close'); + }); +}; + +/** + * Probes a transport. + * + * @param {String} transport name + * @api private + */ + +Socket.prototype.probe = function (name) { + debug('probing transport "%s"', name); + var transport = this.createTransport(name, { probe: 1 }) + , failed = false + , self = this; + + Socket.priorWebsocketSuccess = false; + + function onTransportOpen(){ + if (self.onlyBinaryUpgrades) { + var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; + failed = failed || upgradeLosesBinary; + } + if (failed) return; + + debug('probe transport "%s" opened', name); + transport.send([{ type: 'ping', data: 'probe' }]); + transport.once('packet', function (msg) { + if (failed) return; + if ('pong' == msg.type && 'probe' == msg.data) { + debug('probe transport "%s" pong', name); + self.upgrading = true; + self.emit('upgrading', transport); + if (!transport) return; + Socket.priorWebsocketSuccess = 'websocket' == transport.name; + + debug('pausing current transport "%s"', self.transport.name); + self.transport.pause(function () { + if (failed) return; + if ('closed' == self.readyState) return; + debug('changing transport and sending upgrade packet'); + + cleanup(); + + self.setTransport(transport); + transport.send([{ type: 'upgrade' }]); + self.emit('upgrade', transport); + transport = null; + self.upgrading = false; + self.flush(); + }); + } else { + debug('probe transport "%s" failed', name); + var err = new Error('probe error'); + err.transport = transport.name; + self.emit('upgradeError', err); + } + }); + } + + function freezeTransport() { + if (failed) return; + + // Any callback called by transport should be ignored since now + failed = true; + + cleanup(); + + transport.close(); + transport = null; + } + + //Handle any error that happens while probing + function onerror(err) { + var error = new Error('probe error: ' + err); + error.transport = transport.name; + + freezeTransport(); + + debug('probe transport "%s" failed because of error: %s', name, err); + + self.emit('upgradeError', error); + } + + function onTransportClose(){ + onerror("transport closed"); + } + + //When the socket is closed while we're probing + function onclose(){ + onerror("socket closed"); + } + + //When the socket is upgraded while we're probing + function onupgrade(to){ + if (transport && to.name != transport.name) { + debug('"%s" works - aborting "%s"', to.name, transport.name); + freezeTransport(); + } + } + + //Remove all listeners on the transport and on self + function cleanup(){ + transport.removeListener('open', onTransportOpen); + transport.removeListener('error', onerror); + transport.removeListener('close', onTransportClose); + self.removeListener('close', onclose); + self.removeListener('upgrading', onupgrade); + } + + transport.once('open', onTransportOpen); + transport.once('error', onerror); + transport.once('close', onTransportClose); + + this.once('close', onclose); + this.once('upgrading', onupgrade); + + transport.open(); + +}; + +/** + * Called when connection is deemed open. + * + * @api public + */ + +Socket.prototype.onOpen = function () { + debug('socket open'); + this.readyState = 'open'; + Socket.priorWebsocketSuccess = 'websocket' == this.transport.name; + this.emit('open'); + this.flush(); + + // we check for `readyState` in case an `open` + // listener already closed the socket + if ('open' == this.readyState && this.upgrade && this.transport.pause) { + debug('starting upgrade probes'); + for (var i = 0, l = this.upgrades.length; i < l; i++) { + this.probe(this.upgrades[i]); + } + } +}; + +/** + * Handles a packet. + * + * @api private + */ + +Socket.prototype.onPacket = function (packet) { + if ('opening' == this.readyState || 'open' == this.readyState) { + debug('socket receive: type "%s", data "%s"', packet.type, packet.data); + + this.emit('packet', packet); + + // Socket is live - any packet counts + this.emit('heartbeat'); + + switch (packet.type) { + case 'open': + this.onHandshake(parsejson(packet.data)); + break; + + case 'pong': + this.setPing(); + this.emit('pong'); + break; + + case 'error': + var err = new Error('server error'); + err.code = packet.data; + this.onError(err); + break; + + case 'message': + this.emit('data', packet.data); + this.emit('message', packet.data); + break; + } + } else { + debug('packet received with socket readyState "%s"', this.readyState); + } +}; + +/** + * Called upon handshake completion. + * + * @param {Object} handshake obj + * @api private + */ + +Socket.prototype.onHandshake = function (data) { + this.emit('handshake', data); + this.id = data.sid; + this.transport.query.sid = data.sid; + this.upgrades = this.filterUpgrades(data.upgrades); + this.pingInterval = data.pingInterval; + this.pingTimeout = data.pingTimeout; + this.onOpen(); + // In case open handler closes socket + if ('closed' == this.readyState) return; + this.setPing(); + + // Prolong liveness of socket on heartbeat + this.removeListener('heartbeat', this.onHeartbeat); + this.on('heartbeat', this.onHeartbeat); +}; + +/** + * Resets ping timeout. + * + * @api private + */ + +Socket.prototype.onHeartbeat = function (timeout) { + clearTimeout(this.pingTimeoutTimer); + var self = this; + self.pingTimeoutTimer = setTimeout(function () { + if ('closed' == self.readyState) return; + self.onClose('ping timeout'); + }, timeout || (self.pingInterval + self.pingTimeout)); +}; + +/** + * Pings server every `this.pingInterval` and expects response + * within `this.pingTimeout` or closes connection. + * + * @api private + */ + +Socket.prototype.setPing = function () { + var self = this; + clearTimeout(self.pingIntervalTimer); + self.pingIntervalTimer = setTimeout(function () { + debug('writing ping packet - expecting pong within %sms', self.pingTimeout); + self.ping(); + self.onHeartbeat(self.pingTimeout); + }, self.pingInterval); +}; + +/** +* Sends a ping packet. +* +* @api private +*/ + +Socket.prototype.ping = function () { + var self = this; + this.sendPacket('ping', function(){ + self.emit('ping'); + }); +}; + +/** + * Called on `drain` event + * + * @api private + */ + +Socket.prototype.onDrain = function() { + this.writeBuffer.splice(0, this.prevBufferLen); + + // setting prevBufferLen = 0 is very important + // for example, when upgrading, upgrade packet is sent over, + // and a nonzero prevBufferLen could cause problems on `drain` + this.prevBufferLen = 0; + + if (0 === this.writeBuffer.length) { + this.emit('drain'); + } else { + this.flush(); + } +}; + +/** + * Flush write buffers. + * + * @api private + */ + +Socket.prototype.flush = function () { + if ('closed' != this.readyState && this.transport.writable && + !this.upgrading && this.writeBuffer.length) { + debug('flushing %d packets in socket', this.writeBuffer.length); + this.transport.send(this.writeBuffer); + // keep track of current length of writeBuffer + // splice writeBuffer and callbackBuffer on `drain` + this.prevBufferLen = this.writeBuffer.length; + this.emit('flush'); + } +}; + +/** + * Sends a message. + * + * @param {String} message. + * @param {Function} callback function. + * @param {Object} options. + * @return {Socket} for chaining. + * @api public + */ + +Socket.prototype.write = +Socket.prototype.send = function (msg, options, fn) { + this.sendPacket('message', msg, options, fn); + return this; +}; + +/** + * Sends a packet. + * + * @param {String} packet type. + * @param {String} data. + * @param {Object} options. + * @param {Function} callback function. + * @api private + */ + +Socket.prototype.sendPacket = function (type, data, options, fn) { + if('function' == typeof data) { + fn = data; + data = undefined; + } + + if ('function' == typeof options) { + fn = options; + options = null; + } + + if ('closing' == this.readyState || 'closed' == this.readyState) { + return; + } + + options = options || {}; + options.compress = false !== options.compress; + + var packet = { + type: type, + data: data, + options: options + }; + this.emit('packetCreate', packet); + this.writeBuffer.push(packet); + if (fn) this.once('flush', fn); + this.flush(); +}; + +/** + * Closes the connection. + * + * @api private + */ + +Socket.prototype.close = function () { + if ('opening' == this.readyState || 'open' == this.readyState) { + this.readyState = 'closing'; + + var self = this; + + if (this.writeBuffer.length) { + this.once('drain', function() { + if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + }); + } else if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + } + + function close() { + self.onClose('forced close'); + debug('socket closing - telling transport to close'); + self.transport.close(); + } + + function cleanupAndClose() { + self.removeListener('upgrade', cleanupAndClose); + self.removeListener('upgradeError', cleanupAndClose); + close(); + } + + function waitForUpgrade() { + // wait for upgrade to finish since we can't send packets while pausing a transport + self.once('upgrade', cleanupAndClose); + self.once('upgradeError', cleanupAndClose); + } + + return this; +}; + +/** + * Called upon transport error + * + * @api private + */ + +Socket.prototype.onError = function (err) { + debug('socket error %j', err); + Socket.priorWebsocketSuccess = false; + this.emit('error', err); + this.onClose('transport error', err); +}; + +/** + * Called upon transport close. + * + * @api private + */ + +Socket.prototype.onClose = function (reason, desc) { + if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) { + debug('socket close with reason: "%s"', reason); + var self = this; + + // clear timers + clearTimeout(this.pingIntervalTimer); + clearTimeout(this.pingTimeoutTimer); + + // stop event from firing again for transport + this.transport.removeAllListeners('close'); + + // ensure transport won't stay open + this.transport.close(); + + // ignore further transport communication + this.transport.removeAllListeners(); + + // set ready state + this.readyState = 'closed'; + + // clear session id + this.id = null; + + // emit close event + this.emit('close', reason, desc); + + // clean buffers after, so users can still + // grab the buffers on `close` event + self.writeBuffer = []; + self.prevBufferLen = 0; + } +}; + +/** + * Filters upgrades, returning only those matching client transports. + * + * @param {Array} server upgrades + * @api private + * + */ + +Socket.prototype.filterUpgrades = function (upgrades) { + var filteredUpgrades = []; + for (var i = 0, j = upgrades.length; i