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 @@ -