added browser test
This commit is contained in:
parent
73ee33e402
commit
75ae1499db
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
node_modules
|
||||
misc/coverage.html
|
||||
ctest/sauce*
|
||||
|
11
Makefile
11
Makefile
@ -33,6 +33,17 @@ clean: ## Remove targets and build artifacts
|
||||
test mocha: test.js $(TARGET) ## Run test suite
|
||||
mocha -R spec -t 20000
|
||||
|
||||
.PHONY: ctest
|
||||
ctest: ## Build browser test (into ctest/ subdirectory)
|
||||
cp -f test.js ctest/test.js
|
||||
cp -f shim.js ctest/shim.js
|
||||
cp -f $(TARGET) ctest/
|
||||
|
||||
.PHONY: ctestserv
|
||||
ctestserv: ## Start a test server on port 8000
|
||||
@cd ctest && python -mSimpleHTTPServer
|
||||
|
||||
|
||||
## Code Checking
|
||||
|
||||
.PHONY: lint
|
||||
|
16
README.md
16
README.md
@ -47,14 +47,14 @@ The return value is a JS number. `NaN` signals an error in calculation.
|
||||
For example:
|
||||
|
||||
```js
|
||||
> // var BESSEL = require('bessel'); // uncomment this line if in node
|
||||
> BESSEL.besselj(1.5,0) // 0.5118276712499389
|
||||
> BESSEL.bessely(1.5,0) // 0.38244892476502895
|
||||
> BESSEL.besseli(1.5,0) // 1.6467232021476754
|
||||
> BESSEL.besselk(1.5,0) // 0.2138055693236539
|
||||
// var BESSEL = require('bessel'); // uncomment this line if in node
|
||||
BESSEL.besselj(1.5,0) // 0.5118276712499389
|
||||
BESSEL.bessely(1.5,0) // 0.38244892476502895
|
||||
BESSEL.besseli(1.5,0) // 1.6467232021476754
|
||||
BESSEL.besselk(1.5,0) // 0.2138055693236539
|
||||
|
||||
> var Y = BESSEL.bessely
|
||||
> Y(Math.PI, 5) + Y(Math.PI, 3) - (2 * 4 / Math.PI) * Y(Math.PI, 4) // 0
|
||||
var Y = BESSEL.bessely
|
||||
Y(Math.PI, 5) + Y(Math.PI, 3) - (2 * 4 / Math.PI) * Y(Math.PI, 4) // 0
|
||||
```
|
||||
|
||||
## Testing
|
||||
@ -85,6 +85,8 @@ granted by the MIT License are reserved by the Original Author.
|
||||
|
||||
## Badges
|
||||
|
||||
[![Build Status](https://saucelabs.com/browser-matrix/bessel.svg)](https://saucelabs.com/u/bessel)
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/bessel.svg?branch=master)](https://travis-ci.org/SheetJS/bessel)
|
||||
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/bessel/master.svg)](https://coveralls.io/r/SheetJS/bessel?branch=master)
|
||||
|
246
ctest/bessel.js
Normal file
246
ctest/bessel.js
Normal file
@ -0,0 +1,246 @@
|
||||
/* bessel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*exported BESSEL */
|
||||
var BESSEL;
|
||||
(function (factory) {
|
||||
/*jshint ignore:start */
|
||||
if(typeof DO_NOT_EXPORT_BESSEL === 'undefined') {
|
||||
if('object' === typeof exports) {
|
||||
factory(exports);
|
||||
} else if ('function' === typeof define && define.amd) {
|
||||
define(function () {
|
||||
var module = {};
|
||||
factory(module);
|
||||
return module;
|
||||
});
|
||||
} else {
|
||||
factory(BESSEL = {});
|
||||
}
|
||||
} else {
|
||||
factory(BESSEL = {});
|
||||
}
|
||||
/*jshint ignore:end */
|
||||
}(function(BESSEL) {
|
||||
BESSEL.version = '0.3.0';
|
||||
var M = Math;
|
||||
|
||||
function _horner(arr, v) { for(var i = 0, z = 0; i < arr.length; ++i) z = v * z + arr[i]; return z; }
|
||||
function _bessel_iter(x, n, f0, f1, sign) {
|
||||
if(n === 0) return f0;
|
||||
if(n === 1) return f1;
|
||||
var tdx = 2 / x, f2 = f1;
|
||||
for(var o = 1; o < n; ++o) {
|
||||
f2 = f1 * o * tdx + sign * f0;
|
||||
f0 = f1; f1 = f2;
|
||||
}
|
||||
return f2;
|
||||
}
|
||||
function _bessel_wrap(bessel0, bessel1, name, nonzero, sign) {
|
||||
return function bessel(x,n) {
|
||||
if(nonzero) {
|
||||
if(x === 0) return (nonzero == 1 ? -Infinity : Infinity);
|
||||
else if(x < 0) return NaN;
|
||||
}
|
||||
if(n === 0) return bessel0(x);
|
||||
if(n === 1) return bessel1(x);
|
||||
if(n < 0) return NaN;
|
||||
n|=0;
|
||||
var b0 = bessel0(x), b1 = bessel1(x);
|
||||
return _bessel_iter(x, n, b0, b1, sign);
|
||||
};
|
||||
}
|
||||
var besselj = (function() {
|
||||
var W = 0.636619772; // 2 / Math.PI
|
||||
|
||||
var b0_a1a = [57568490574.0, -13362590354.0, 651619640.7, -11214424.18, 77392.33017, -184.9052456].reverse();
|
||||
var b0_a2a = [57568490411.0, 1029532985.0, 9494680.718, 59272.64853, 267.8532712, 1.0].reverse();
|
||||
var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse();
|
||||
var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934935152e-7].reverse();
|
||||
|
||||
function bessel0(x) {
|
||||
var a=0, a1=0, a2=0, y = x * x;
|
||||
if(x < 8) {
|
||||
a1 = _horner(b0_a1a, y);
|
||||
a2 = _horner(b0_a2a, y);
|
||||
a = a1 / a2;
|
||||
} else {
|
||||
var xx = x - 0.785398164;
|
||||
y = 64 / y;
|
||||
a1 = _horner(b0_a1b, y);
|
||||
a2 = _horner(b0_a2b, y);
|
||||
a = M.sqrt(W/x)*(M.cos(xx)*a1-M.sin(xx)*a2*8/x);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var b1_a1a = [72362614232.0, -7895059235.0, 242396853.1, -2972611.439, 15704.48260, -30.16036606].reverse();
|
||||
var b1_a2a = [144725228442.0, 2300535178.0, 18583304.74, 99447.43394, 376.9991397, 1.0].reverse();
|
||||
var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse();
|
||||
var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse();
|
||||
|
||||
function bessel1(x) {
|
||||
var a=0, a1=0, a2=0, y = x*x, xx = M.abs(x) - 2.356194491;
|
||||
if(Math.abs(x)< 8) {
|
||||
a1 = x*_horner(b1_a1a, y);
|
||||
a2 = _horner(b1_a2a, y);
|
||||
a = a1 / a2;
|
||||
} else {
|
||||
y = 64 / y;
|
||||
a1=_horner(b1_a1b, y);
|
||||
a2=_horner(b1_a2b, y);
|
||||
a=M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x));
|
||||
if(x < 0) a = -a;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
return function besselj(x, n) {
|
||||
n = Math.round(n);
|
||||
if(!isFinite(x)) return isNaN(x) ? x : 0;
|
||||
if(n < 0) return ((n%2)?-1:1)*besselj(x, -n);
|
||||
if(x < 0) return ((n%2)?-1:1)*besselj(-x, n);
|
||||
if(n === 0) return bessel0(x);
|
||||
if(n === 1) return bessel1(x);
|
||||
if(x === 0) return 0;
|
||||
|
||||
var ret=0.0;
|
||||
if(x > n) {
|
||||
ret = _bessel_iter(x, n, bessel0(x), bessel1(x),-1);
|
||||
} else {
|
||||
var m=2*M.floor((n+M.floor(M.sqrt(40*n)))/2);
|
||||
var jsum=false;
|
||||
var bjp=0.0, sum=0.0;
|
||||
var bj=1.0, bjm = 0.0;
|
||||
var tox = 2 / x;
|
||||
for (var j=m;j>0;j--) {
|
||||
bjm=j*tox*bj-bjp;
|
||||
bjp=bj;
|
||||
bj=bjm;
|
||||
if (M.abs(bj) > 1E10) {
|
||||
bj *= 1E-10;
|
||||
bjp *= 1E-10;
|
||||
ret *= 1E-10;
|
||||
sum *= 1E-10;
|
||||
}
|
||||
if (jsum) sum += bj;
|
||||
jsum=!jsum;
|
||||
if (j == n) ret=bjp;
|
||||
}
|
||||
sum=2.0*sum-bj;
|
||||
ret /= sum;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
})();
|
||||
var bessely = (function() {
|
||||
var W = 0.636619772;
|
||||
|
||||
var b0_a1a = [-2957821389.0, 7062834065.0, -512359803.6, 10879881.29, -86327.92757, 228.4622733].reverse();
|
||||
var b0_a2a = [40076544269.0, 745249964.8, 7189466.438, 47447.26470, 226.1030244, 1.0].reverse();
|
||||
var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse();
|
||||
var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934945152e-7].reverse();
|
||||
|
||||
function bessel0(x) {
|
||||
var a=0, a1=0, a2=0, y = x * x, xx = x - 0.785398164;
|
||||
if(x < 8) {
|
||||
a1 = _horner(b0_a1a, y);
|
||||
a2 = _horner(b0_a2a, y);
|
||||
a = a1/a2 + W * besselj(x,0) * M.log(x);
|
||||
} else {
|
||||
y = 64 / y;
|
||||
a1 = _horner(b0_a1b, y);
|
||||
a2 = _horner(b0_a2b, y);
|
||||
a = M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var b1_a1a = [-0.4900604943e13, 0.1275274390e13, -0.5153438139e11, 0.7349264551e9, -0.4237922726e7, 0.8511937935e4].reverse();
|
||||
var b1_a2a = [0.2499580570e14, 0.4244419664e12, 0.3733650367e10, 0.2245904002e8, 0.1020426050e6, 0.3549632885e3, 1].reverse();
|
||||
var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse();
|
||||
var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse();
|
||||
|
||||
function bessel1(x) {
|
||||
var a=0, a1=0, a2=0, y = x*x, xx = x - 2.356194491;
|
||||
if(x < 8) {
|
||||
a1 = x*_horner(b1_a1a, y);
|
||||
a2 = _horner(b1_a2a, y);
|
||||
a = a1/a2 + W * (besselj(x,1) * M.log(x) - 1 / x);
|
||||
} else {
|
||||
y = 64 / y;
|
||||
a1=_horner(b1_a1b, y);
|
||||
a2=_horner(b1_a2b, y);
|
||||
a=M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
return _bessel_wrap(bessel0, bessel1, 'BESSELY', 1, -1);
|
||||
})();
|
||||
var besseli = (function() {
|
||||
var b0_a = [1.0, 3.5156229, 3.0899424, 1.2067492, 0.2659732, 0.360768e-1, 0.45813e-2].reverse();
|
||||
var b0_b = [0.39894228, 0.1328592e-1, 0.225319e-2, -0.157565e-2, 0.916281e-2, -0.2057706e-1, 0.2635537e-1, -0.1647633e-1, 0.392377e-2].reverse();
|
||||
|
||||
function bessel0(x) {
|
||||
if(x <= 3.75) return _horner(b0_a, x*x/(3.75*3.75));
|
||||
return M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b0_b, 3.75/M.abs(x));
|
||||
}
|
||||
|
||||
var b1_a = [0.5, 0.87890594, 0.51498869, 0.15084934, 0.2658733e-1, 0.301532e-2, 0.32411e-3].reverse();
|
||||
var b1_b = [0.39894228, -0.3988024e-1, -0.362018e-2, 0.163801e-2, -0.1031555e-1, 0.2282967e-1, -0.2895312e-1, 0.1787654e-1, -0.420059e-2].reverse();
|
||||
|
||||
function bessel1(x) {
|
||||
if(x < 3.75) return x * _horner(b1_a, x*x/(3.75*3.75));
|
||||
return (x < 0 ? -1 : 1) * M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b1_b, 3.75/M.abs(x));
|
||||
}
|
||||
|
||||
return function besseli(x, n) {
|
||||
n = Math.round(n);
|
||||
if(n === 0) return bessel0(x);
|
||||
if(n === 1) return bessel1(x);
|
||||
if(n < 0) return NaN;
|
||||
if(M.abs(x) === 0) return 0;
|
||||
if(x == Infinity) return Infinity;
|
||||
|
||||
var ret = 0.0, j, tox = 2 / M.abs(x), bip = 0.0, bi=1.0, bim=0.0;
|
||||
var m=2*M.round((n+M.round(M.sqrt(40*n)))/2);
|
||||
for (j=m;j>0;j--) {
|
||||
bim=j*tox*bi + bip;
|
||||
bip=bi; bi=bim;
|
||||
if (M.abs(bi) > 1E10) {
|
||||
bi *= 1E-10;
|
||||
bip *= 1E-10;
|
||||
ret *= 1E-10;
|
||||
}
|
||||
if(j == n) ret = bip;
|
||||
}
|
||||
ret *= besseli(x, 0) / bi;
|
||||
return x < 0 && (n%2) ? -ret : ret;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
var besselk = (function() {
|
||||
var b0_a = [-0.57721566, 0.42278420, 0.23069756, 0.3488590e-1, 0.262698e-2, 0.10750e-3, 0.74e-5].reverse();
|
||||
var b0_b = [1.25331414, -0.7832358e-1, 0.2189568e-1, -0.1062446e-1, 0.587872e-2, -0.251540e-2, 0.53208e-3].reverse();
|
||||
|
||||
function bessel0(x) {
|
||||
if(x <= 2) return -M.log(x/2) * besseli(x,0) + _horner(b0_a, x*x/4);
|
||||
return M.exp(-x) / M.sqrt(x) * _horner(b0_b, 2/x);
|
||||
}
|
||||
|
||||
var b1_a = [1.0, 0.15443144, -0.67278579, -0.18156897, -0.1919402e-1, -0.110404e-2, -0.4686e-4].reverse();
|
||||
var b1_b = [1.25331414, 0.23498619, -0.3655620e-1, 0.1504268e-1, -0.780353e-2, 0.325614e-2, -0.68245e-3].reverse();
|
||||
|
||||
function bessel1(x) {
|
||||
if(x <= 2) return M.log(x/2) * besseli(x,1) + (1/x) * _horner(b1_a, x*x/4);
|
||||
return M.exp(-x)/M.sqrt(x)*_horner(b1_b, 2/x);
|
||||
}
|
||||
|
||||
return _bessel_wrap(bessel0, bessel1, 'BESSELK', 2, 1);
|
||||
})();
|
||||
BESSEL.besselj = besselj;
|
||||
BESSEL.bessely = bessely;
|
||||
BESSEL.besseli = besseli;
|
||||
BESSEL.besselk = besselk;
|
||||
}));
|
2
ctest/fakeassert.js
Normal file
2
ctest/fakeassert.js
Normal file
@ -0,0 +1,2 @@
|
||||
var assert = {};
|
||||
assert.equal = function(x,y) { if(x !== y) throw new Error(x + " !== " + y); };
|
23
ctest/index.html
Normal file
23
ctest/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Mocha</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="mocha.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script src="shim.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
|
||||
<script src="bessel.js"></script>
|
||||
<script src="fakeassert.js"></script>
|
||||
<script src="mocha.js"></script>
|
||||
<script src="sauce-client.js"></script>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script src="test.js"></script>
|
||||
<script>
|
||||
mocha_sauce();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
305
ctest/mocha.css
Normal file
305
ctest/mocha.css
Normal file
@ -0,0 +1,305 @@
|
||||
@charset "utf-8";
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#mocha {
|
||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
margin: 60px 50px;
|
||||
}
|
||||
|
||||
#mocha ul,
|
||||
#mocha li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#mocha ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#mocha h1,
|
||||
#mocha h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#mocha h1 {
|
||||
margin-top: 15px;
|
||||
font-size: 1em;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
#mocha h1 a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha h1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#mocha .suite .suite h1 {
|
||||
margin-top: 0;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
#mocha .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mocha .suite {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test {
|
||||
margin-left: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#mocha .test.pending:hover h2::after {
|
||||
content: '(pending)';
|
||||
font-family: arial, sans-serif;
|
||||
}
|
||||
|
||||
#mocha .test.pass.medium .duration {
|
||||
background: #c09853;
|
||||
}
|
||||
|
||||
#mocha .test.pass.slow .duration {
|
||||
background: #b94a48;
|
||||
}
|
||||
|
||||
#mocha .test.pass::before {
|
||||
content: '✓';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #00d6b2;
|
||||
}
|
||||
|
||||
#mocha .test.pass .duration {
|
||||
font-size: 9px;
|
||||
margin-left: 5px;
|
||||
padding: 2px 5px;
|
||||
color: #fff;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#mocha .test.pass.fast .duration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha .test.pending {
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.pending::before {
|
||||
content: '◦';
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.fail {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test.fail pre {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha .test.fail::before {
|
||||
content: '✖';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test pre.error {
|
||||
color: #c00;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#mocha .test .html-error {
|
||||
overflow: auto;
|
||||
color: black;
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
float: left;
|
||||
clear: left;
|
||||
font: 12px/1.5 monaco, monospace;
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eee;
|
||||
max-width: 85%; /*(1)*/
|
||||
max-width: calc(100% - 42px); /*(2)*/
|
||||
max-height: 300px;
|
||||
word-wrap: break-word;
|
||||
border-bottom-color: #ddd;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-box-shadow: 0 1px 3px #eee;
|
||||
-moz-border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 3px #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#mocha .test .html-error pre.error {
|
||||
border: none;
|
||||
-webkit-border-radius: none;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-border-radius: none;
|
||||
-moz-box-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-top: 18px;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* (1): approximate for browsers not supporting calc
|
||||
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
|
||||
* ^^ seriously
|
||||
*/
|
||||
#mocha .test pre {
|
||||
display: block;
|
||||
float: left;
|
||||
clear: left;
|
||||
font: 12px/1.5 monaco, monospace;
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eee;
|
||||
max-width: 85%; /*(1)*/
|
||||
max-width: calc(100% - 42px); /*(2)*/
|
||||
word-wrap: break-word;
|
||||
border-bottom-color: #ddd;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-box-shadow: 0 1px 3px #eee;
|
||||
-moz-border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 3px #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#mocha .test h2 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#mocha .test a.replay {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 0;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
background: #eee;
|
||||
font-size: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
border-radius: 15px;
|
||||
-webkit-transition: opacity 200ms;
|
||||
-moz-transition: opacity 200ms;
|
||||
transition: opacity 200ms;
|
||||
opacity: 0.3;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#mocha .test:hover a.replay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#mocha-report.pass .test.fail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.fail .test.pass {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.pending .test.pass,
|
||||
#mocha-report.pending .test.fail {
|
||||
display: none;
|
||||
}
|
||||
#mocha-report.pending .test.pass.pending {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#mocha-error {
|
||||
color: #c00;
|
||||
font-size: 1.5em;
|
||||
font-weight: 100;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#mocha-stats {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: #888;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#mocha-stats .progress {
|
||||
float: right;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#mocha-stats em {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha-stats a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha-stats a:hover {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#mocha-stats li {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
list-style: none;
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
#mocha-stats canvas {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#mocha code .comment { color: #ddd; }
|
||||
#mocha code .init { color: #2f6fad; }
|
||||
#mocha code .string { color: #5890ad; }
|
||||
#mocha code .keyword { color: #8a6343; }
|
||||
#mocha code .number { color: #2f6fad; }
|
||||
|
||||
@media screen and (max-device-width: 480px) {
|
||||
#mocha {
|
||||
margin: 60px 0px;
|
||||
}
|
||||
|
||||
#mocha #stats {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
5842
ctest/mocha.js
Normal file
5842
ctest/mocha.js
Normal file
File diff suppressed because it is too large
Load Diff
237
ctest/shim.js
Normal file
237
ctest/shim.js
Normal file
@ -0,0 +1,237 @@
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||||
if (!Object.keys) {
|
||||
Object.keys = (function () {
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
|
||||
dontEnums = [
|
||||
'toString',
|
||||
'toLocaleString',
|
||||
'valueOf',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'constructor'
|
||||
],
|
||||
dontEnumsLength = dontEnums.length;
|
||||
|
||||
return function (obj) {
|
||||
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var prop in obj) {
|
||||
if (hasOwnProperty.call(obj, prop)) result.push(prop);
|
||||
}
|
||||
|
||||
if (hasDontEnumBug) {
|
||||
for (var i=0; i < dontEnumsLength; i++) {
|
||||
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
if (!Array.prototype.filter)
|
||||
{
|
||||
Array.prototype.filter = function(fun /*, thisp */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this == null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun != "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = [];
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
{
|
||||
var val = t[i]; // in case fun mutates this
|
||||
if (fun.call(thisp, val, i, t))
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
|
||||
if (!Array.prototype.forEach)
|
||||
{
|
||||
Array.prototype.forEach = function(fun /*, thisArg */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function")
|
||||
throw new TypeError();
|
||||
|
||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
fun.call(thisArg, t[i], i, t);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
||||
// Reference: http://es5.github.com/#x15.4.4.19
|
||||
if (!Array.prototype.map) {
|
||||
Array.prototype.map = function(callback, thisArg) {
|
||||
|
||||
var T, A, k;
|
||||
|
||||
if (this == null) {
|
||||
throw new TypeError(" this is null or not defined");
|
||||
}
|
||||
|
||||
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
|
||||
var O = Object(this);
|
||||
|
||||
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
|
||||
// 3. Let len be ToUint32(lenValue).
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||
// See: http://es5.github.com/#x9.11
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError(callback + " is not a function");
|
||||
}
|
||||
|
||||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
if (thisArg) {
|
||||
T = thisArg;
|
||||
}
|
||||
|
||||
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
|
||||
// the standard built-in constructor with that name and len is the value of len.
|
||||
A = new Array(len);
|
||||
|
||||
// 7. Let k be 0
|
||||
k = 0;
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
while(k < len) {
|
||||
|
||||
var kValue, mappedValue;
|
||||
|
||||
// a. Let Pk be ToString(k).
|
||||
// This is implicit for LHS operands of the in operator
|
||||
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
|
||||
// This step can be combined with c
|
||||
// c. If kPresent is true, then
|
||||
if (k in O) {
|
||||
|
||||
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
|
||||
kValue = O[ k ];
|
||||
|
||||
// ii. Let mappedValue be the result of calling the Call internal method of callback
|
||||
// with T as the this value and argument list containing kValue, k, and O.
|
||||
mappedValue = callback.call(T, kValue, k, O);
|
||||
|
||||
// iii. Call the DefineOwnProperty internal method of A with arguments
|
||||
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
|
||||
// and false.
|
||||
|
||||
// In browsers that support Object.defineProperty, use the following:
|
||||
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
|
||||
|
||||
// For best browser support, use the following:
|
||||
A[ k ] = mappedValue;
|
||||
}
|
||||
// d. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 9. return A
|
||||
return A;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function (searchElement, fromIndex) {
|
||||
if ( this === undefined || this === null ) {
|
||||
throw new TypeError( '"this" is null or not defined' );
|
||||
}
|
||||
|
||||
var length = this.length >>> 0; // Hack to convert object.length to a UInt32
|
||||
|
||||
fromIndex = +fromIndex || 0;
|
||||
|
||||
if (Math.abs(fromIndex) === Infinity) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
|
||||
if (fromIndex < 0) {
|
||||
fromIndex += length;
|
||||
if (fromIndex < 0) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (;fromIndex < length; fromIndex++) {
|
||||
if (this[fromIndex] === searchElement) {
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
||||
|
||||
if (! Array.isArray) {
|
||||
Array.isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/ttaubert/node-arraybuffer-slice
|
||||
// (c) 2013 Tim Taubert <tim@timtaubert.de>
|
||||
// arraybuffer-slice may be freely distributed under the MIT license.
|
||||
|
||||
"use strict";
|
||||
|
||||
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
|
||||
ArrayBuffer.prototype.slice = function (begin, end) {
|
||||
begin = (begin|0) || 0;
|
||||
var num = this.byteLength;
|
||||
end = end === (void 0) ? num : (end|0);
|
||||
|
||||
// Handle negative values.
|
||||
if (begin < 0) begin += num;
|
||||
if (end < 0) end += num;
|
||||
|
||||
if (num === 0 || begin >= num || begin >= end) {
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
|
||||
var length = Math.min(num - begin, end - begin);
|
||||
var target = new ArrayBuffer(length);
|
||||
var targetArray = new Uint8Array(target);
|
||||
targetArray.set(new Uint8Array(this, begin, length));
|
||||
return target;
|
||||
};
|
||||
}
|
124
ctest/test.js
Normal file
124
ctest/test.js
Normal file
@ -0,0 +1,124 @@
|
||||
/* vim: set ts=2: */
|
||||
var X;
|
||||
if(typeof require !== 'undefined') {
|
||||
assert = require('assert');
|
||||
describe('source',function(){
|
||||
it('should load',function(){X=require('./');});
|
||||
it('all bessel functions', function() {
|
||||
assert.equal(typeof X.besseli, 'function');
|
||||
assert.equal(typeof X.besselj, 'function');
|
||||
assert.equal(typeof X.besselk, 'function');
|
||||
assert.equal(typeof X.bessely, 'function');
|
||||
});
|
||||
});
|
||||
} else { X = BESSEL; }
|
||||
|
||||
function approx(a, b, t) { return Math.abs((a - b) / (Math.abs(a) + Math.abs(b))) <= t; }
|
||||
|
||||
function chk(func, x, n, v, F, t) {
|
||||
var V = func(x,n);
|
||||
if(!approx(V, v, t) && v != V && !(isNaN(v) && isNaN(V))) throw new Error(F + "(" + x + "," + n + ") = " + V + " !~ " + v);
|
||||
}
|
||||
|
||||
var funcs = ['besseli', 'besselj', 'besselk', 'bessely'];
|
||||
|
||||
var tests = {
|
||||
'besseli': [
|
||||
[1.5, 1, 0.981666],
|
||||
[1.9, 2, 0.603272435],
|
||||
[2.5, 1, 2.516716242]
|
||||
],
|
||||
'besselj': [
|
||||
[1.5, 1, 0.557936508],
|
||||
[1.9, 2, 0.329925829],
|
||||
[2.5, 1, 0.497094103]
|
||||
],
|
||||
'besselk': [
|
||||
[1.5, 1, 0.277388],
|
||||
[1.9, 2, 0.296909301],
|
||||
[2.5, 1, 0.073890816]
|
||||
],
|
||||
'bessely': [
|
||||
[1.5, 1, -0.412308627],
|
||||
[1.9, 2, -0.669878674],
|
||||
[2.5, 1, 0.14591814]
|
||||
] };
|
||||
|
||||
describe('correctness', function() {
|
||||
funcs.forEach(function(F) { it(F, function() {
|
||||
tests[F].forEach(function(t) { chk(X[F], t[0], t[1], t[2], F, 1e-6); });
|
||||
});});
|
||||
|
||||
if(typeof require != 'undefined') {
|
||||
var fs = require('fs');
|
||||
it('excel', function() {
|
||||
var xl = fs.readFileSync("test_files/excel.tsv", 'ascii').split("\n").map(function(l) { return l.split("\t");});
|
||||
xl.forEach(function(l) { if(l.length < 6) return;
|
||||
var x=Number(l[0]), n=Number(l[1]);
|
||||
var i=Number(l[2]), j=Number(l[3]), k=Number(l[4]), y=Number(l[5]);
|
||||
chk(X.besseli, x, n, i, 'besseli', 1e-4);
|
||||
chk(X.besselj, x, n, j, 'besselj', 1e-4);
|
||||
chk(X.besselk, x, n, k, 'besselk', 1e-4);
|
||||
chk(X.bessely, x, n, y, 'bessely', 1e-4);
|
||||
});
|
||||
});
|
||||
it('mma', function() {
|
||||
var mma = fs.readFileSync("test_files/mma.tsv", 'ascii').split("\n").map(function(l) { return l.split("\t");});
|
||||
mma.forEach(function(l) { if(l.length < 6) return;
|
||||
var x=Number(l[0]), n=Number(l[1]);
|
||||
var i=Number(l[2]), j=Number(l[3]), k=Number(l[4]), y=Number(l[5]);
|
||||
chk(X.besseli, x, n, i, 'besseli', 1e-5);
|
||||
chk(X.besselj, x, n, j, 'besselj', 1e-5);
|
||||
chk(X.besselk, x, n, k, 'besselk', 1e-5);
|
||||
chk(X.bessely, x, n, y, 'bessely', 1e-5);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var rand = [
|
||||
0.3946086812775882, 3.946086812775882, 39.46086812775882,
|
||||
0.03119419917289612, 0.3119419917289612, 3.119419917289612,
|
||||
0.18311903629136062, 1.8311903629136062, 18.311903629136062,
|
||||
0.5317681126599452, 5.317681126599452, 53.17681126599452,
|
||||
0.37724541457032235, 3.7724541457032235, 37.724541457032235,
|
||||
0.8287802926845655, 8.287802926845655, 82.87802926845655,
|
||||
0.7197724866379658, 7.197724866379658, 71.97724866379658
|
||||
];
|
||||
|
||||
describe('properties', function() {
|
||||
var t = 1e-4;
|
||||
it('limiting behavior', function() {
|
||||
chk(X.besselj, 0, 0, 1, 'besselj', 1e-6);
|
||||
chk(X.besseli, 0, 0, 1, 'besseli', 1e-6);
|
||||
chk(X.besselk, 0, 0, Infinity, 'besselk', 1e-6);
|
||||
chk(X.bessely, 0, 0, -Infinity, 'bessely', 1e-6);
|
||||
for(var i = 1; i < 20; ++i) {
|
||||
chk(X.besselj, 0, i, 0, 'besselj', 1e-6);
|
||||
chk(X.besseli, 0, i, 0, 'besseli', 1e-6);
|
||||
}
|
||||
});
|
||||
it('besselj', function() {
|
||||
var F = "BESSELJ", f = X.besselj;
|
||||
rand.forEach(function(r) {
|
||||
for(var n = 0; n < 20; ++n) {
|
||||
var pp = f( r, n), pn = f( r, -n), np = f(-r, n), nn = f(-r, -n);
|
||||
if((n%2)) {
|
||||
/* besselj odd if n is odd */
|
||||
if(!approx(np, -pp, t)) throw new Error(F + " np[" + np + "] != -pp[" + (-pp) + "] (" + r + "," + n + ")");
|
||||
if(!approx(nn, -pn, t)) throw new Error(F + " nn[" + nn + "] != -pn[" + (-pn) + "] (" + r + "," + n + ")");
|
||||
/* asymmetric in n */
|
||||
if(!approx(pn, -pp, t)) throw new Error(F + " pn[" + pn + "] != -pp[" + (-pp) + "] (" + r + "," + n + ")");
|
||||
if(!approx(nn, -np, t)) throw new Error(F + " nn[" + nn + "] != -pn[" + (-pn) + "] (" + r + "," + n + ")");
|
||||
} else {
|
||||
/* besselj even if n is even */
|
||||
if(!approx(np, pp, t)) throw new Error(F + " np[" + np + "] != pp[" + (pp) + "] (" + r + "," + n + ")");
|
||||
if(!approx(nn, pn, t)) throw new Error(F + " nn[" + nn + "] != pn[" + (pn) + "] (" + r + "," + n + ")");
|
||||
/* symmetric in n */
|
||||
if(!approx(pn, pp, t)) throw new Error(F + " pn[" + pn + "] != pp[" + (pp) + "] (" + r + "," + n + ")");
|
||||
if(!approx(nn, np, t)) throw new Error(F + " nn[" + nn + "] != pn[" + (pn) + "] (" + r + "," + n + ")");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
237
shim.js
Normal file
237
shim.js
Normal file
@ -0,0 +1,237 @@
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||||
if (!Object.keys) {
|
||||
Object.keys = (function () {
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
|
||||
dontEnums = [
|
||||
'toString',
|
||||
'toLocaleString',
|
||||
'valueOf',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'constructor'
|
||||
],
|
||||
dontEnumsLength = dontEnums.length;
|
||||
|
||||
return function (obj) {
|
||||
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var prop in obj) {
|
||||
if (hasOwnProperty.call(obj, prop)) result.push(prop);
|
||||
}
|
||||
|
||||
if (hasDontEnumBug) {
|
||||
for (var i=0; i < dontEnumsLength; i++) {
|
||||
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
if (!Array.prototype.filter)
|
||||
{
|
||||
Array.prototype.filter = function(fun /*, thisp */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this == null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun != "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = [];
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
{
|
||||
var val = t[i]; // in case fun mutates this
|
||||
if (fun.call(thisp, val, i, t))
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
|
||||
if (!Array.prototype.forEach)
|
||||
{
|
||||
Array.prototype.forEach = function(fun /*, thisArg */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function")
|
||||
throw new TypeError();
|
||||
|
||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
fun.call(thisArg, t[i], i, t);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
||||
// Reference: http://es5.github.com/#x15.4.4.19
|
||||
if (!Array.prototype.map) {
|
||||
Array.prototype.map = function(callback, thisArg) {
|
||||
|
||||
var T, A, k;
|
||||
|
||||
if (this == null) {
|
||||
throw new TypeError(" this is null or not defined");
|
||||
}
|
||||
|
||||
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
|
||||
var O = Object(this);
|
||||
|
||||
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
|
||||
// 3. Let len be ToUint32(lenValue).
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||
// See: http://es5.github.com/#x9.11
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError(callback + " is not a function");
|
||||
}
|
||||
|
||||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
if (thisArg) {
|
||||
T = thisArg;
|
||||
}
|
||||
|
||||
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
|
||||
// the standard built-in constructor with that name and len is the value of len.
|
||||
A = new Array(len);
|
||||
|
||||
// 7. Let k be 0
|
||||
k = 0;
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
while(k < len) {
|
||||
|
||||
var kValue, mappedValue;
|
||||
|
||||
// a. Let Pk be ToString(k).
|
||||
// This is implicit for LHS operands of the in operator
|
||||
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
|
||||
// This step can be combined with c
|
||||
// c. If kPresent is true, then
|
||||
if (k in O) {
|
||||
|
||||
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
|
||||
kValue = O[ k ];
|
||||
|
||||
// ii. Let mappedValue be the result of calling the Call internal method of callback
|
||||
// with T as the this value and argument list containing kValue, k, and O.
|
||||
mappedValue = callback.call(T, kValue, k, O);
|
||||
|
||||
// iii. Call the DefineOwnProperty internal method of A with arguments
|
||||
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
|
||||
// and false.
|
||||
|
||||
// In browsers that support Object.defineProperty, use the following:
|
||||
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
|
||||
|
||||
// For best browser support, use the following:
|
||||
A[ k ] = mappedValue;
|
||||
}
|
||||
// d. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 9. return A
|
||||
return A;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function (searchElement, fromIndex) {
|
||||
if ( this === undefined || this === null ) {
|
||||
throw new TypeError( '"this" is null or not defined' );
|
||||
}
|
||||
|
||||
var length = this.length >>> 0; // Hack to convert object.length to a UInt32
|
||||
|
||||
fromIndex = +fromIndex || 0;
|
||||
|
||||
if (Math.abs(fromIndex) === Infinity) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
|
||||
if (fromIndex < 0) {
|
||||
fromIndex += length;
|
||||
if (fromIndex < 0) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (;fromIndex < length; fromIndex++) {
|
||||
if (this[fromIndex] === searchElement) {
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
||||
|
||||
if (! Array.isArray) {
|
||||
Array.isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/ttaubert/node-arraybuffer-slice
|
||||
// (c) 2013 Tim Taubert <tim@timtaubert.de>
|
||||
// arraybuffer-slice may be freely distributed under the MIT license.
|
||||
|
||||
"use strict";
|
||||
|
||||
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
|
||||
ArrayBuffer.prototype.slice = function (begin, end) {
|
||||
begin = (begin|0) || 0;
|
||||
var num = this.byteLength;
|
||||
end = end === (void 0) ? num : (end|0);
|
||||
|
||||
// Handle negative values.
|
||||
if (begin < 0) begin += num;
|
||||
if (end < 0) end += num;
|
||||
|
||||
if (num === 0 || begin >= num || begin >= end) {
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
|
||||
var length = Math.min(num - begin, end - begin);
|
||||
var target = new ArrayBuffer(length);
|
||||
var targetArray = new Uint8Array(target);
|
||||
targetArray.set(new Uint8Array(this, begin, length));
|
||||
return target;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user