diff --git a/.eslintrc b/.eslintrc
index 8ae8c66..8dc3744 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -5,15 +5,14 @@
"ecmaVersion": 3,
},
"plugins": [ "html", "json" ],
+ "extends": "eslint:recommended",
"rules": {
- "no-use-before-define": [ 1, {
- "functions":false, "classes":true, "variables":true
- }],
- "no-bitwise": 0,
- "curly": 0,
"comma-style": [ 2, "last" ],
+ "comma-dangle": [ 2, "never" ],
+ "curly": 0,
+ "no-bitwise": 0,
+ "no-console": 0,
"no-trailing-spaces": 2,
- "semi": [ 2, "always" ],
- "comma-dangle": [ 2, "never" ]
+ "semi": [ 2, "always" ]
}
}
diff --git a/.npmignore b/.npmignore
index 874d256..59ecd7d 100644
--- a/.npmignore
+++ b/.npmignore
@@ -19,3 +19,4 @@ MANIFEST
*.tgz
*.py
*.html
+.spelling
diff --git a/.spelling b/.spelling
new file mode 100644
index 0000000..9563553
--- /dev/null
+++ b/.spelling
@@ -0,0 +1,8 @@
+# frac.js (C) 2012-present SheetJS -- http://sheetjs.com
+SheetJS
+frac
+
+Aberth
+CommonJS
+npm
+prepend
diff --git a/Makefile b/Makefile
index 59b031d..ce8065f 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,9 @@ ctest: ## Build browser test (into ctest/ subdirectory)
ctestserv: ## Start a test server on port 8000
@cd ctest && python -mSimpleHTTPServer
+.PHONY: fullint
+fullint: lint old-lint tslint flow mdlint ## Run all checks
+
.PHONY: lint
lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json
@@ -56,6 +59,12 @@ old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
@jscs $(TARGET) $(AUXTARGETS)
if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
+.PHONY: tslint
+tslint: $(TARGET) ## Run typescript checks
+ #@npm install dtslint typescript
+ #@npm run-script dtslint
+ dtslint types
+
.PHONY: flow
flow: lint ## Run flow checker
@flow check --all --show-all-errors
@@ -70,6 +79,12 @@ misc/coverage.html: $(TARGET) test.js
coveralls: ## Coverage Test + Send to coveralls.io
mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | node ./node_modules/coveralls/bin/coveralls.js
+MDLINT=README.md frac.md
+.PHONY: mdlint
+mdlint: $(MDLINT) ## Check markdown documents
+ alex $^
+ mdspell -a -n -x -r --en-us $^
+
.PHONY: dist
dist: dist-deps $(TARGET) ## Prepare JS files for distribution
cp $(TARGET) dist/
diff --git a/README.md b/README.md
index 7d2e531..3c982ec 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ replicate fraction formats.
### JS
-With [npm](https://www.npmjs.org/package/frac):
+With [`npm`](https://www.npmjs.org/package/frac):
```bash
$ npm install frac
@@ -25,13 +25,12 @@ In the browser:
```
-The script will manipulate `module.exports` if available (e.g. in a CommonJS
-`require` context). This is not always desirable. To prevent the behavior,
-define `DO_NOT_EXPORT_FRAC`
+The script will manipulate `module.exports` if available . This is not always
+desirable. To prevent the behavior, define `DO_NOT_EXPORT_FRAC`
### Python
-From [PyPI](https://pypi.python.org/pypi/frac):
+From [`PyPI`](https://pypi.python.org/pypi/frac):
```bash
$ pip install frac
diff --git a/ctest/frac.js b/ctest/frac.js
index 77f71d7..efd1a0d 100644
--- a/ctest/frac.js
+++ b/ctest/frac.js
@@ -38,4 +38,5 @@ frac.cont = function cont(x, D, mixed) {
var q = Math.floor(sgn * P/Q);
return [q, sgn*P - q*Q, Q];
};
+// eslint-disable-next-line no-undef
if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;
diff --git a/ctest/test.js b/ctest/test.js
index 51a01ce..f33350c 100644
--- a/ctest/test.js
+++ b/ctest/test.js
@@ -39,6 +39,7 @@ frac.cont = function cont(x, D, mixed) {
var q = Math.floor(sgn * P/Q);
return [q, sgn*P - q*Q, Q];
};
+// eslint-disable-next-line no-undef
if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;
},{}],2:[function(require,module,exports){
@@ -108,6 +109,51 @@ xltestfiles.forEach(function(x) {
});
},{"./":1,"assert":3}],3:[function(require,module,exports){
+(function (global){
+'use strict';
+
+// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
+// original notice:
+
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author Feross Aboukhadijeh
+ * @license MIT
+ */
+function compare(a, b) {
+ if (a === b) {
+ return 0;
+ }
+
+ var x = a.length;
+ var y = b.length;
+
+ for (var i = 0, len = Math.min(x, y); i < len; ++i) {
+ if (a[i] !== b[i]) {
+ x = a[i];
+ y = b[i];
+ break;
+ }
+ }
+
+ if (x < y) {
+ return -1;
+ }
+ if (y < x) {
+ return 1;
+ }
+ return 0;
+}
+function isBuffer(b) {
+ if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
+ return global.Buffer.isBuffer(b);
+ }
+ return !!(b != null && b._isBuffer);
+}
+
+// based on node assert, original notice:
+
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
@@ -132,14 +178,36 @@ xltestfiles.forEach(function(x) {
// 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.
-// when used in node, this will actually load the util module we depend on
-// versus loading the builtin util module as happens otherwise
-// this is a bug in node module loading as far as I am concerned
var util = require('util/');
-
-var pSlice = Array.prototype.slice;
var hasOwn = Object.prototype.hasOwnProperty;
-
+var pSlice = Array.prototype.slice;
+var functionsHaveNames = (function () {
+ return function foo() {}.name === 'foo';
+}());
+function pToString (obj) {
+ return Object.prototype.toString.call(obj);
+}
+function isView(arrbuf) {
+ if (isBuffer(arrbuf)) {
+ return false;
+ }
+ if (typeof global.ArrayBuffer !== 'function') {
+ return false;
+ }
+ if (typeof ArrayBuffer.isView === 'function') {
+ return ArrayBuffer.isView(arrbuf);
+ }
+ if (!arrbuf) {
+ return false;
+ }
+ if (arrbuf instanceof DataView) {
+ return true;
+ }
+ if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
+ return true;
+ }
+ return false;
+}
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.
@@ -151,6 +219,19 @@ var assert = module.exports = ok;
// actual: actual,
// expected: expected })
+var regex = /\s*function\s+([^\(\s]*)\s*/;
+// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
+function getName(func) {
+ if (!util.isFunction(func)) {
+ return;
+ }
+ if (functionsHaveNames) {
+ return func.name;
+ }
+ var str = func.toString();
+ var match = str.match(regex);
+ return match && match[1];
+}
assert.AssertionError = function AssertionError(options) {
this.name = 'AssertionError';
this.actual = options.actual;
@@ -164,18 +245,16 @@ assert.AssertionError = function AssertionError(options) {
this.generatedMessage = true;
}
var stackStartFunction = options.stackStartFunction || fail;
-
if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction);
- }
- else {
+ } else {
// non v8 browsers so we can have a stacktrace
var err = new Error();
if (err.stack) {
var out = err.stack;
// try to strip useless frames
- var fn_name = stackStartFunction.name;
+ var fn_name = getName(stackStartFunction);
var idx = out.indexOf('\n' + fn_name);
if (idx >= 0) {
// once we have located the function frame
@@ -192,31 +271,25 @@ assert.AssertionError = function AssertionError(options) {
// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);
-function replacer(key, value) {
- if (util.isUndefined(value)) {
- return '' + value;
- }
- if (util.isNumber(value) && !isFinite(value)) {
- return value.toString();
- }
- if (util.isFunction(value) || util.isRegExp(value)) {
- return value.toString();
- }
- return value;
-}
-
function truncate(s, n) {
- if (util.isString(s)) {
+ if (typeof s === 'string') {
return s.length < n ? s : s.slice(0, n);
} else {
return s;
}
}
-
+function inspect(something) {
+ if (functionsHaveNames || !util.isFunction(something)) {
+ return util.inspect(something);
+ }
+ var rawname = getName(something);
+ var name = rawname ? ': ' + rawname : '';
+ return '[Function' + name + ']';
+}
function getMessage(self) {
- return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
+ return truncate(inspect(self.actual), 128) + ' ' +
self.operator + ' ' +
- truncate(JSON.stringify(self.expected, replacer), 128);
+ truncate(inspect(self.expected), 128);
}
// At present only the three keys mentioned above are used and
@@ -276,24 +349,23 @@ assert.notEqual = function notEqual(actual, expected, message) {
// assert.deepEqual(actual, expected, message_opt);
assert.deepEqual = function deepEqual(actual, expected, message) {
- if (!_deepEqual(actual, expected)) {
+ if (!_deepEqual(actual, expected, false)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
-function _deepEqual(actual, expected) {
+assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
+ if (!_deepEqual(actual, expected, true)) {
+ fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
+ }
+};
+
+function _deepEqual(actual, expected, strict, memos) {
// 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) {
return true;
-
- } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
- if (actual.length != expected.length) return false;
-
- for (var i = 0; i < actual.length; i++) {
- if (actual[i] !== expected[i]) return false;
- }
-
- return true;
+ } else if (isBuffer(actual) && isBuffer(expected)) {
+ return compare(actual, expected) === 0;
// 7.2. If the expected value is a Date object, the actual value is
// equivalent if it is also a Date object that refers to the same time.
@@ -312,8 +384,22 @@ function _deepEqual(actual, expected) {
// 7.4. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==.
- } else if (!util.isObject(actual) && !util.isObject(expected)) {
- return actual == expected;
+ } else if ((actual === null || typeof actual !== 'object') &&
+ (expected === null || typeof expected !== 'object')) {
+ return strict ? actual === expected : actual == expected;
+
+ // If both values are instances of typed arrays, wrap their underlying
+ // ArrayBuffers in a Buffer each to increase performance
+ // This optimization requires the arrays to have the same type as checked by
+ // Object.prototype.toString (aka pToString). Never perform binary
+ // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
+ // bit patterns are not identical.
+ } else if (isView(actual) && isView(expected) &&
+ pToString(actual) === pToString(expected) &&
+ !(actual instanceof Float32Array ||
+ actual instanceof Float64Array)) {
+ return compare(new Uint8Array(actual.buffer),
+ new Uint8Array(expected.buffer)) === 0;
// 7.5 For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified
@@ -321,8 +407,22 @@ function _deepEqual(actual, expected) {
// (although not necessarily the same order), equivalent values for every
// corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays.
+ } else if (isBuffer(actual) !== isBuffer(expected)) {
+ return false;
} else {
- return objEquiv(actual, expected);
+ memos = memos || {actual: [], expected: []};
+
+ var actualIndex = memos.actual.indexOf(actual);
+ if (actualIndex !== -1) {
+ if (actualIndex === memos.expected.indexOf(expected)) {
+ return true;
+ }
+ }
+
+ memos.actual.push(actual);
+ memos.expected.push(expected);
+
+ return objEquiv(actual, expected, strict, memos);
}
}
@@ -330,44 +430,44 @@ function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]';
}
-function objEquiv(a, b) {
- if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
+function objEquiv(a, b, strict, actualVisitedObjects) {
+ if (a === null || a === undefined || b === null || b === undefined)
return false;
- // an identical 'prototype' property.
- if (a.prototype !== b.prototype) return false;
// if one is a primitive, the other must be same
- if (util.isPrimitive(a) || util.isPrimitive(b)) {
+ if (util.isPrimitive(a) || util.isPrimitive(b))
return a === b;
- }
- var aIsArgs = isArguments(a),
- bIsArgs = isArguments(b);
+ if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
+ return false;
+ var aIsArgs = isArguments(a);
+ var bIsArgs = isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
return false;
if (aIsArgs) {
a = pSlice.call(a);
b = pSlice.call(b);
- return _deepEqual(a, b);
+ return _deepEqual(a, b, strict);
}
- var ka = objectKeys(a),
- kb = objectKeys(b),
- key, i;
+ var ka = objectKeys(a);
+ var kb = objectKeys(b);
+ var key, i;
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
- if (ka.length != kb.length)
+ if (ka.length !== kb.length)
return false;
//the same set of keys (although not necessarily the same order),
ka.sort();
kb.sort();
//~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) {
- if (ka[i] != kb[i])
+ if (ka[i] !== kb[i])
return false;
}
//equivalent values for every corresponding key, and
//~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
- if (!_deepEqual(a[key], b[key])) return false;
+ if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
+ return false;
}
return true;
}
@@ -376,11 +476,19 @@ function objEquiv(a, b) {
// assert.notDeepEqual(actual, expected, message_opt);
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
- if (_deepEqual(actual, expected)) {
+ if (_deepEqual(actual, expected, false)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
}
};
+assert.notDeepStrictEqual = notDeepStrictEqual;
+function notDeepStrictEqual(actual, expected, message) {
+ if (_deepEqual(actual, expected, true)) {
+ fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
+ }
+}
+
+
// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);
@@ -406,28 +514,46 @@ function expectedException(actual, expected) {
if (Object.prototype.toString.call(expected) == '[object RegExp]') {
return expected.test(actual);
- } else if (actual instanceof expected) {
- return true;
- } else if (expected.call({}, actual) === true) {
- return true;
}
- return false;
+ try {
+ if (actual instanceof expected) {
+ return true;
+ }
+ } catch (e) {
+ // Ignore. The instanceof check doesn't work for arrow functions.
+ }
+
+ if (Error.isPrototypeOf(expected)) {
+ return false;
+ }
+
+ return expected.call({}, actual) === true;
+}
+
+function _tryBlock(block) {
+ var error;
+ try {
+ block();
+ } catch (e) {
+ error = e;
+ }
+ return error;
}
function _throws(shouldThrow, block, expected, message) {
var actual;
- if (util.isString(expected)) {
+ if (typeof block !== 'function') {
+ throw new TypeError('"block" argument must be a function');
+ }
+
+ if (typeof expected === 'string') {
message = expected;
expected = null;
}
- try {
- block();
- } catch (e) {
- actual = e;
- }
+ actual = _tryBlock(block);
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.');
@@ -436,7 +562,14 @@ function _throws(shouldThrow, block, expected, message) {
fail(actual, expected, 'Missing expected exception' + message);
}
- if (!shouldThrow && expectedException(actual, expected)) {
+ var userProvidedMessage = typeof message === 'string';
+ var isUnwantedException = !shouldThrow && util.isError(actual);
+ var isUnexpectedException = !shouldThrow && actual && !expected;
+
+ if ((isUnwantedException &&
+ userProvidedMessage &&
+ expectedException(actual, expected)) ||
+ isUnexpectedException) {
fail(actual, expected, 'Got unwanted exception' + message);
}
@@ -450,15 +583,15 @@ function _throws(shouldThrow, block, expected, message) {
// assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) {
- _throws.apply(this, [true].concat(pSlice.call(arguments)));
+ _throws(true, block, error, message);
};
// EXTENSION! This is annoying to write outside this module.
-assert.doesNotThrow = function(block, /*optional*/message) {
- _throws.apply(this, [false].concat(pSlice.call(arguments)));
+assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
+ _throws(false, block, error, message);
};
-assert.ifError = function(err) { if (err) {throw err;}};
+assert.ifError = function(err) { if (err) throw err; };
var objectKeys = Object.keys || function (obj) {
var keys = [];
@@ -468,6 +601,7 @@ var objectKeys = Object.keys || function (obj) {
return keys;
};
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"util/":7}],4:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
@@ -639,6 +773,10 @@ process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
diff --git a/dist/frac.js b/dist/frac.js
index 77f71d7..efd1a0d 100644
--- a/dist/frac.js
+++ b/dist/frac.js
@@ -38,4 +38,5 @@ frac.cont = function cont(x, D, mixed) {
var q = Math.floor(sgn * P/Q);
return [q, sgn*P - q*Q, Q];
};
+// eslint-disable-next-line no-undef
if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;
diff --git a/dist/frac.min.map b/dist/frac.min.map
index b48688f..b86417b 100644
--- a/dist/frac.min.map
+++ b/dist/frac.min.map
@@ -1 +1 @@
-{"version":3,"sources":["frac.js"],"names":["frac","x","D","mixed","n1","Math","floor","d1","n2","d2","m","q","cont","sgn","B","P_2","P_1","P","Q_2","Q_1","Q","A","module","DO_NOT_EXPORT_FRAC","exports"],"mappings":";AACA,GAAIA,MAAO,QAASA,MAAKC,EAAGC,EAAGC,OAC7B,GAAIC,IAAKC,KAAKC,MAAML,GAAIM,GAAK,CAC7B,IAAIC,IAAKJ,GAAG,EAAGK,GAAK,CACpB,IAAGR,IAAMG,GAAI,MAAMG,IAAML,GAAKO,IAAMP,EAAG,CACrC,GAAIQ,IAAKN,GAAKI,KAAOD,GAAKE,GAC1B,IAAGR,IAAMS,EAAG,CACV,GAAGH,GAAKE,IAAMP,EAAG,CAAEK,IAAIE,EAAIL,KAAII,EAAIC,IAAGP,EAAE,MACnC,IAAGK,GAAKE,GAAIA,GAAGP,EAAE,MACjBK,IAAGL,EAAE,CACV,WAEG,IAAGD,EAAIS,EAAG,CAAEF,GAAKJ,GAAGI,EAAIC,IAAKF,GAAGE,OAChC,CAAEL,GAAKA,GAAGI,EAAID,IAAKA,GAAGE,IAE7B,GAAGF,GAAKL,EAAG,CAAEK,GAAKE,EAAIL,IAAKI,GAC3B,IAAIL,MAAO,OAAQ,EAAGC,GAAIG,GAC1B,IAAII,GAAIN,KAAKC,MAAMF,GAAGG,GACtB,QAAQI,EAAGP,GAAKO,EAAEJ,GAAIA,IAExBP,MAAKY,KAAO,QAASA,MAAKX,EAAGC,EAAGC,OAC9B,GAAIU,KAAMZ,EAAI,GAAK,EAAI,CACvB,IAAIa,GAAIb,EAAIY,GACZ,IAAIE,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,GAAIhB,KAAKC,MAAMQ,EACnB,OAAMK,IAAMjB,EAAG,CACbmB,EAAIhB,KAAKC,MAAMQ,EACfG,GAAII,EAAIL,IAAMD,GACdK,GAAIC,EAAIF,IAAMD,GACd,IAAIJ,EAAIO,EAAK,KAAY,KACzBP,GAAI,GAAKA,EAAIO,EACbN,KAAMC,GAAKA,KAAMC,CACjBC,KAAMC,GAAKA,KAAMC,EAEnB,GAAGA,EAAIlB,EAAG,CAAE,GAAGiB,IAAMjB,EAAG,CAAEkB,EAAIF,GAAKD,GAAIF,QAAY,CAAEK,EAAID,GAAKF,GAAID,KAClE,IAAIb,MAAO,OAAQ,EAAGU,IAAMI,EAAGG,EAC/B,IAAIT,GAAIN,KAAKC,MAAMO,IAAMI,EAAEG,EAC3B,QAAQT,EAAGE,IAAII,EAAIN,EAAES,EAAGA,GAE1B,UAAUE,UAAW,mBAAsBC,sBAAuB,YAAaD,OAAOE,QAAUxB","file":"dist/frac.min.js"}
\ No newline at end of file
+{"version":3,"sources":["frac.js"],"names":["frac","x","D","mixed","n1","Math","floor","d1","n2","d2","m","q","cont","sgn","B","P_2","P_1","P","Q_2","Q_1","Q","A","module","DO_NOT_EXPORT_FRAC","exports"],"mappings":";AACA,GAAIA,MAAO,QAASA,MAAKC,EAAGC,EAAGC,OAC7B,GAAIC,IAAKC,KAAKC,MAAML,GAAIM,GAAK,CAC7B,IAAIC,IAAKJ,GAAG,EAAGK,GAAK,CACpB,IAAGR,IAAMG,GAAI,MAAMG,IAAML,GAAKO,IAAMP,EAAG,CACrC,GAAIQ,IAAKN,GAAKI,KAAOD,GAAKE,GAC1B,IAAGR,IAAMS,EAAG,CACV,GAAGH,GAAKE,IAAMP,EAAG,CAAEK,IAAIE,EAAIL,KAAII,EAAIC,IAAGP,EAAE,MACnC,IAAGK,GAAKE,GAAIA,GAAGP,EAAE,MACjBK,IAAGL,EAAE,CACV,WAEG,IAAGD,EAAIS,EAAG,CAAEF,GAAKJ,GAAGI,EAAIC,IAAKF,GAAGE,OAChC,CAAEL,GAAKA,GAAGI,EAAID,IAAKA,GAAGE,IAE7B,GAAGF,GAAKL,EAAG,CAAEK,GAAKE,EAAIL,IAAKI,GAC3B,IAAIL,MAAO,OAAQ,EAAGC,GAAIG,GAC1B,IAAII,GAAIN,KAAKC,MAAMF,GAAGG,GACtB,QAAQI,EAAGP,GAAKO,EAAEJ,GAAIA,IAExBP,MAAKY,KAAO,QAASA,MAAKX,EAAGC,EAAGC,OAC9B,GAAIU,KAAMZ,EAAI,GAAK,EAAI,CACvB,IAAIa,GAAIb,EAAIY,GACZ,IAAIE,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,GAAIhB,KAAKC,MAAMQ,EACnB,OAAMK,IAAMjB,EAAG,CACbmB,EAAIhB,KAAKC,MAAMQ,EACfG,GAAII,EAAIL,IAAMD,GACdK,GAAIC,EAAIF,IAAMD,GACd,IAAIJ,EAAIO,EAAK,KAAY,KACzBP,GAAI,GAAKA,EAAIO,EACbN,KAAMC,GAAKA,KAAMC,CACjBC,KAAMC,GAAKA,KAAMC,EAEnB,GAAGA,EAAIlB,EAAG,CAAE,GAAGiB,IAAMjB,EAAG,CAAEkB,EAAIF,GAAKD,GAAIF,QAAY,CAAEK,EAAID,GAAKF,GAAID,KAClE,IAAIb,MAAO,OAAQ,EAAGU,IAAMI,EAAGG,EAC/B,IAAIT,GAAIN,KAAKC,MAAMO,IAAMI,EAAEG,EAC3B,QAAQT,EAAGE,IAAII,EAAIN,EAAES,EAAGA,GAG1B,UAAUE,UAAW,mBAAsBC,sBAAuB,YAAaD,OAAOE,QAAUxB","file":"dist/frac.min.js"}
\ No newline at end of file
diff --git a/frac.flow.js b/frac.flow.js
index 7c8a745..c46be40 100644
--- a/frac.flow.js
+++ b/frac.flow.js
@@ -39,4 +39,5 @@ frac.cont = function cont(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Arra
return [q, sgn*P - q*Q, Q];
};
/*:: declare var DO_NOT_EXPORT_FRAC: any; */
+// eslint-disable-next-line no-undef
if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;
diff --git a/frac.js b/frac.js
index 77f71d7..efd1a0d 100644
--- a/frac.js
+++ b/frac.js
@@ -38,4 +38,5 @@ frac.cont = function cont(x, D, mixed) {
var q = Math.floor(sgn * P/Q);
return [q, sgn*P - q*Q, Q];
};
+// eslint-disable-next-line no-undef
if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;
diff --git a/frac.md b/frac.md
index 6e7354d..41539cf 100644
--- a/frac.md
+++ b/frac.md
@@ -43,7 +43,7 @@ our target:
if(x !== n1) while(d1 <= D && d2 <= D) {
```
-The mediant is the sum of the numerators divided by the sum of demoninators:
+The mediant is the sum of the numerators divided by the sum of denominators:
```
var m = (n1 + n2) / (d1 + d2);
@@ -118,7 +118,7 @@ is not correct for the range `B>=2**32`.
while(Q_1 < D) {
```
-> `a_k = [b_k]`, i.e., the greatest integer `<= b_k`
+> `a_k = [b_k]`, the greatest integer `<= b_k`
```
A = Math.floor(B);
@@ -166,6 +166,7 @@ Finally we put some export jazz:
```
/*:: declare var DO_NOT_EXPORT_FRAC: any; */
+// eslint-disable-next-line no-undef
if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;
```
@@ -243,27 +244,37 @@ xltestfiles.forEach(function(x) {
```json>package.json
{
"name": "frac",
- "version": "1.1.0",
+ "version": "1.1.1",
"author": "SheetJS",
"description": "Rational approximation with bounded denominator",
"keywords": [ "math", "fraction", "rational", "approximation" ],
- "main": "frac.js",
+ "main": "./frac",
+ "types": "types",
"dependencies": {
"voc":"~1.0.0"
},
"devDependencies": {
- "mocha":"~2.5.3"
+ "mocha":"~2.5.3",
+ "blanket": "~1.2.3",
+ "codepage":"~1.10.0",
+ "@sheetjs/uglify-js":"~2.7.3",
+ "@types/node":"^8.0.7",
+ "dtslint": "^0.1.2",
+ "typescript": "2.2.0"
},
"repository": { "type":"git", "url":"git://github.com/SheetJS/frac.git" },
"scripts": {
- "test": "make test"
+ "test": "make test",
+ "build": "make",
+ "lint": "make fullint",
+ "dtslint": "dtslint types"
},
"config": {
"blanket": {
"pattern": "frac.js"
}
},
- "homepage": "http://oss.sheetjs.com/frac",
+ "homepage": "http://sheetjs.com/opensource",
"bugs": { "url": "https://github.com/SheetJS/frac/issues" },
"license": "Apache-2.0",
"engines": { "node": ">=0.8" }
@@ -294,6 +305,7 @@ MANIFEST
*.tgz
*.py
*.html
+.spelling
```
Don't include the node modules in git:
diff --git a/index.html b/index.html
index 1553f29..02ffd1a 100644
--- a/index.html
+++ b/index.html
@@ -27,6 +27,8 @@ a { text-decoration: none }
-