@barchart/portfolio-api-common 1.0.17 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/data/PositionSummaryFrame.js +83 -9
- package/lib/serialization/PortfolioSchema.js +23 -3
- package/lib/serialization/PositionSchema.js +10 -0
- package/lib/serialization/TransactionSchema.js +280 -0
- package/package.json +2 -1
- package/test/SpecRunner.js +3515 -1
- package/test/specs/data/PositionSummaryFrameSpec.js +228 -0
package/test/SpecRunner.js
CHANGED
|
@@ -1 +1,3515 @@
|
|
|
1
|
-
(function(){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<r.length;o++)s(r[o]);return s}return e})()({
|
|
1
|
+
(function(){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<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
|
|
2
|
+
const array = require('@barchart/common-js/lang/array'),
|
|
3
|
+
assert = require('@barchart/common-js/lang/assert'),
|
|
4
|
+
Day = require('@barchart/common-js/lang/Day'),
|
|
5
|
+
Enum = require('@barchart/common-js/lang/Enum'),
|
|
6
|
+
is = require('@barchart/common-js/lang/is');
|
|
7
|
+
|
|
8
|
+
module.exports = (() => {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An enumeration used to define timeframes for position summaries.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
* @extends {Enum}
|
|
16
|
+
* @param {String} code
|
|
17
|
+
* @param {String} description
|
|
18
|
+
* @param {Function} rangeCalculator
|
|
19
|
+
*/
|
|
20
|
+
class PositionSummaryFrame extends Enum {
|
|
21
|
+
constructor(code, description, rangeCalculator) {
|
|
22
|
+
super(code, description);
|
|
23
|
+
|
|
24
|
+
assert.argumentIsRequired(rangeCalculator, 'rangeCalculator', Function);
|
|
25
|
+
|
|
26
|
+
this._rangeCalculator = rangeCalculator;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getRanges(transactions) {
|
|
30
|
+
assert.argumentIsArray(transactions, 'transactions');
|
|
31
|
+
|
|
32
|
+
return this._rangeCalculator(transactions);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A summary for a calendar year.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
* @returns {PositionSummaryFrame}
|
|
40
|
+
*/
|
|
41
|
+
static get YEARLY() {
|
|
42
|
+
return yearly;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A summary for a quarter.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
* @returns {PositionSummaryFrame}
|
|
50
|
+
*/
|
|
51
|
+
static get QUARTERLY() {
|
|
52
|
+
return quarterly;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A summary for a calendar month.
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
* @returns {PositionSummaryFrame}
|
|
60
|
+
*/
|
|
61
|
+
static get MONTHLY() {
|
|
62
|
+
return monthly;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A summary the current year (to date).
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
* @returns {PositionSummaryFrame}
|
|
70
|
+
*/
|
|
71
|
+
static get YTD() {
|
|
72
|
+
return ytd;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
toString() {
|
|
76
|
+
return '[PositionSummaryFrame]';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges);
|
|
81
|
+
const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges);
|
|
82
|
+
const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges);
|
|
83
|
+
const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges);
|
|
84
|
+
|
|
85
|
+
function getRange(start, end) {
|
|
86
|
+
return {
|
|
87
|
+
start: start,
|
|
88
|
+
end: end
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getYearlyRanges(transactions) {
|
|
93
|
+
const ranges = [ ];
|
|
94
|
+
|
|
95
|
+
if (transactions.length !== 0) {
|
|
96
|
+
const first = array.first(transactions);
|
|
97
|
+
const last = array.last(transactions);
|
|
98
|
+
|
|
99
|
+
const firstDate = first.date;
|
|
100
|
+
const lastDate = last.date;
|
|
101
|
+
|
|
102
|
+
let lastYear;
|
|
103
|
+
|
|
104
|
+
if (last.snapshot.open.getIsZero()) {
|
|
105
|
+
lastYear = last.date.year + 1;
|
|
106
|
+
} else {
|
|
107
|
+
lastYear = Day.getToday().year;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
for (let end = new Day(firstDate.year, 12, 31); end.year < lastYear; end = end.addYears(1)) {
|
|
111
|
+
ranges.push(getRange(end.subtractYears(1), end));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return ranges;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function getQuarterlyRanges(transactions) {
|
|
119
|
+
return [ ];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function getMonthlyRanges(transactions) {
|
|
123
|
+
return [ ];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getYearToDateRanges(transactions) {
|
|
127
|
+
const ranges = [ ];
|
|
128
|
+
|
|
129
|
+
if (transactions.length !== 0) {
|
|
130
|
+
const first = array.first(transactions);
|
|
131
|
+
const last = array.last(transactions);
|
|
132
|
+
|
|
133
|
+
const currentYear = Day.getToday().year;
|
|
134
|
+
|
|
135
|
+
if (!last.snapshot.open.getIsZero() || last.date.year === currentYear) {
|
|
136
|
+
let end = new Day(Day.getToday().year, 12, 31);
|
|
137
|
+
let start = end.subtractYears(1);
|
|
138
|
+
|
|
139
|
+
ranges.push(getRange(start, end));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return ranges;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return PositionSummaryFrame;
|
|
147
|
+
})();
|
|
148
|
+
|
|
149
|
+
},{"@barchart/common-js/lang/Day":4,"@barchart/common-js/lang/Enum":6,"@barchart/common-js/lang/array":7,"@barchart/common-js/lang/assert":8,"@barchart/common-js/lang/is":9}],2:[function(require,module,exports){
|
|
150
|
+
'use strict';
|
|
151
|
+
|
|
152
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
153
|
+
|
|
154
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
155
|
+
|
|
156
|
+
var assert = require('./../../lang/assert'),
|
|
157
|
+
comparators = require('./comparators');
|
|
158
|
+
|
|
159
|
+
module.exports = function () {
|
|
160
|
+
'use strict';
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A builder for compound comparator functions (e.g. sort by last name,
|
|
164
|
+
* then by first name, then by social security number) that uses a fluent
|
|
165
|
+
* interface.
|
|
166
|
+
*
|
|
167
|
+
* @public
|
|
168
|
+
* @param {Function} comparator - The initial comparator.
|
|
169
|
+
* @param {Boolean=} invert - Indicates if the comparator should sort in descending order.
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
var ComparatorBuilder = function () {
|
|
173
|
+
function ComparatorBuilder(comparator, invert, previous) {
|
|
174
|
+
_classCallCheck(this, ComparatorBuilder);
|
|
175
|
+
|
|
176
|
+
assert.argumentIsRequired(comparator, 'comparator', Function);
|
|
177
|
+
assert.argumentIsOptional(invert, 'invert', Boolean);
|
|
178
|
+
|
|
179
|
+
this._comparator = comparator;
|
|
180
|
+
this._invert = invert || false;
|
|
181
|
+
this._previous = previous || null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Adds a new comparator to the list of comparators to use.
|
|
186
|
+
*
|
|
187
|
+
* @public
|
|
188
|
+
* @param {Function} comparator - The next comparator function.
|
|
189
|
+
* @param {Boolean=} invert - Indicates if the comparator should sort in descending order.
|
|
190
|
+
* @returns {ComparatorBuilder}
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
_createClass(ComparatorBuilder, [{
|
|
195
|
+
key: 'thenBy',
|
|
196
|
+
value: function thenBy(comparator, invert) {
|
|
197
|
+
assert.argumentIsRequired(comparator, 'comparator', Function);
|
|
198
|
+
assert.argumentIsOptional(invert, 'invert', Boolean);
|
|
199
|
+
|
|
200
|
+
return new ComparatorBuilder(comparator, invert, this);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Flips the order of the comparator (e.g. ascending to descending).
|
|
205
|
+
*
|
|
206
|
+
* @public
|
|
207
|
+
* @returns {ComparatorBuilder}
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
}, {
|
|
211
|
+
key: 'invert',
|
|
212
|
+
value: function invert() {
|
|
213
|
+
var previous = void 0;
|
|
214
|
+
|
|
215
|
+
if (this._previous) {
|
|
216
|
+
previous = this._previous.invert();
|
|
217
|
+
} else {
|
|
218
|
+
previous = null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return new ComparatorBuilder(this._comparator, !this._invert, previous);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Returns the comparator function.
|
|
226
|
+
*
|
|
227
|
+
* @public
|
|
228
|
+
* @returns {Function}
|
|
229
|
+
*/
|
|
230
|
+
|
|
231
|
+
}, {
|
|
232
|
+
key: 'toComparator',
|
|
233
|
+
value: function toComparator() {
|
|
234
|
+
var _this = this;
|
|
235
|
+
|
|
236
|
+
var previousComparator = void 0;
|
|
237
|
+
|
|
238
|
+
if (this._previous) {
|
|
239
|
+
previousComparator = this._previous.toComparator();
|
|
240
|
+
} else {
|
|
241
|
+
previousComparator = comparators.empty;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return function (a, b) {
|
|
245
|
+
var result = previousComparator(a, b);
|
|
246
|
+
|
|
247
|
+
if (result === 0) {
|
|
248
|
+
var sortA = void 0;
|
|
249
|
+
var sortB = void 0;
|
|
250
|
+
|
|
251
|
+
if (_this._invert) {
|
|
252
|
+
sortA = b;
|
|
253
|
+
sortB = a;
|
|
254
|
+
} else {
|
|
255
|
+
sortA = a;
|
|
256
|
+
sortB = b;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
result = _this._comparator(sortA, sortB);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return result;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}, {
|
|
266
|
+
key: 'toString',
|
|
267
|
+
value: function toString() {
|
|
268
|
+
return '[ComparatorBuilder]';
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Creates a {@link ComparatorBuilder}, given an initial comparator function.
|
|
273
|
+
*
|
|
274
|
+
* @public
|
|
275
|
+
* @param {Function} comparator - The initial comparator.
|
|
276
|
+
* @param {Boolean=} invert - Indicates if the comparator should sort in descending order.
|
|
277
|
+
* @returns {ComparatorBuilder}
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
}], [{
|
|
281
|
+
key: 'startWith',
|
|
282
|
+
value: function startWith(comparator, invert) {
|
|
283
|
+
return new ComparatorBuilder(comparator, invert);
|
|
284
|
+
}
|
|
285
|
+
}]);
|
|
286
|
+
|
|
287
|
+
return ComparatorBuilder;
|
|
288
|
+
}();
|
|
289
|
+
|
|
290
|
+
return ComparatorBuilder;
|
|
291
|
+
}();
|
|
292
|
+
|
|
293
|
+
},{"./../../lang/assert":8,"./comparators":3}],3:[function(require,module,exports){
|
|
294
|
+
'use strict';
|
|
295
|
+
|
|
296
|
+
var assert = require('./../../lang/assert');
|
|
297
|
+
|
|
298
|
+
module.exports = function () {
|
|
299
|
+
'use strict';
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Functions that can be used as comparators.
|
|
303
|
+
*
|
|
304
|
+
* @public
|
|
305
|
+
* @module collections/sorting/comparators
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
/**
|
|
310
|
+
* Compares two dates (in ascending order).
|
|
311
|
+
*
|
|
312
|
+
* @static
|
|
313
|
+
* @param {Date} a
|
|
314
|
+
* @param {Date} b
|
|
315
|
+
* @returns {Number}
|
|
316
|
+
*/
|
|
317
|
+
compareDates: function compareDates(a, b) {
|
|
318
|
+
assert.argumentIsRequired(a, 'a', Date);
|
|
319
|
+
assert.argumentIsRequired(b, 'b', Date);
|
|
320
|
+
|
|
321
|
+
return a - b;
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Compares two numbers (in ascending order).
|
|
326
|
+
*
|
|
327
|
+
* @static
|
|
328
|
+
* @param {Number} a
|
|
329
|
+
* @param {Number} b
|
|
330
|
+
* @returns {Number}
|
|
331
|
+
*/
|
|
332
|
+
compareNumbers: function compareNumbers(a, b) {
|
|
333
|
+
assert.argumentIsRequired(a, 'a', Number);
|
|
334
|
+
assert.argumentIsRequired(b, 'b', Number);
|
|
335
|
+
|
|
336
|
+
return a - b;
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Compares two strings (in ascending order), using {@link String#localeCompare}.
|
|
341
|
+
*
|
|
342
|
+
* @static
|
|
343
|
+
* @param {Number} a
|
|
344
|
+
* @param {Number} b
|
|
345
|
+
* @returns {Number}
|
|
346
|
+
*/
|
|
347
|
+
compareStrings: function compareStrings(a, b) {
|
|
348
|
+
assert.argumentIsRequired(a, 'a', String);
|
|
349
|
+
assert.argumentIsRequired(b, 'b', String);
|
|
350
|
+
|
|
351
|
+
return a.localeCompare(b);
|
|
352
|
+
},
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Compares two objects, always returning zero.
|
|
356
|
+
*
|
|
357
|
+
* @static
|
|
358
|
+
* @param {*} a
|
|
359
|
+
* @param {*} b
|
|
360
|
+
* @returns {Number}
|
|
361
|
+
*/
|
|
362
|
+
empty: function empty(a, b) {
|
|
363
|
+
return 0;
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}();
|
|
367
|
+
|
|
368
|
+
},{"./../../lang/assert":8}],4:[function(require,module,exports){
|
|
369
|
+
'use strict';
|
|
370
|
+
|
|
371
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
372
|
+
|
|
373
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
374
|
+
|
|
375
|
+
var assert = require('./assert'),
|
|
376
|
+
ComparatorBuilder = require('./../collections/sorting/ComparatorBuilder'),
|
|
377
|
+
comparators = require('./../collections/sorting/comparators'),
|
|
378
|
+
is = require('./is');
|
|
379
|
+
|
|
380
|
+
module.exports = function () {
|
|
381
|
+
'use strict';
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* A data structure that represents a day (year, month, and day)
|
|
385
|
+
* without consideration for time or timezone.
|
|
386
|
+
*
|
|
387
|
+
* @public
|
|
388
|
+
* @param {Number} year
|
|
389
|
+
* @param {Number} month
|
|
390
|
+
* @param {Number} day
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
var Day = function () {
|
|
394
|
+
function Day(year, month, day) {
|
|
395
|
+
_classCallCheck(this, Day);
|
|
396
|
+
|
|
397
|
+
if (!Day.validate(year, month, day)) {
|
|
398
|
+
throw new Error('Unable to instantiate Day, input is invalid [' + year + '], [' + month + '], [' + day + ']');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
this._year = year;
|
|
402
|
+
this._month = month;
|
|
403
|
+
this._day = day;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Calculates a new {@link Day} in the future (or past).
|
|
408
|
+
*
|
|
409
|
+
* @public
|
|
410
|
+
* @param {Number} days - The number of days to add (negative numbers can be used for subtraction).
|
|
411
|
+
* @param {Boolean=} inverse - If true, the sign of the "days" value will be flipped.
|
|
412
|
+
* @returns {Day}
|
|
413
|
+
*/
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
_createClass(Day, [{
|
|
417
|
+
key: 'addDays',
|
|
418
|
+
value: function addDays(days, inverse) {
|
|
419
|
+
assert.argumentIsRequired(days, 'days', Number);
|
|
420
|
+
assert.argumentIsOptional(inverse, inverse, Boolean);
|
|
421
|
+
assert.argumentIsValid(days, 'days', is.large, 'is an integer');
|
|
422
|
+
|
|
423
|
+
var totalDaysToShift = void 0;
|
|
424
|
+
|
|
425
|
+
if (is.boolean(inverse) && inverse) {
|
|
426
|
+
totalDaysToShift = days * -1;
|
|
427
|
+
} else {
|
|
428
|
+
totalDaysToShift = days;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
var positive = is.positive(totalDaysToShift);
|
|
432
|
+
|
|
433
|
+
var shiftedDay = this._day;
|
|
434
|
+
var shiftedMonth = this._month;
|
|
435
|
+
var shiftedYear = this._year;
|
|
436
|
+
|
|
437
|
+
while (totalDaysToShift !== 0) {
|
|
438
|
+
var monthDaysAvailable = void 0;
|
|
439
|
+
var monthDaysToShift = void 0;
|
|
440
|
+
|
|
441
|
+
if (positive) {
|
|
442
|
+
monthDaysAvailable = Day.getDaysInMonth(shiftedYear, shiftedMonth) - shiftedDay;
|
|
443
|
+
monthDaysToShift = Math.min(totalDaysToShift, monthDaysAvailable);
|
|
444
|
+
} else {
|
|
445
|
+
monthDaysAvailable = 1 - shiftedDay;
|
|
446
|
+
monthDaysToShift = Math.max(totalDaysToShift, monthDaysAvailable);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
totalDaysToShift = totalDaysToShift - monthDaysToShift;
|
|
450
|
+
|
|
451
|
+
if (totalDaysToShift === 0) {
|
|
452
|
+
shiftedDay = shiftedDay + monthDaysToShift;
|
|
453
|
+
} else if (positive) {
|
|
454
|
+
shiftedMonth++;
|
|
455
|
+
|
|
456
|
+
if (shiftedMonth > 12) {
|
|
457
|
+
shiftedYear++;
|
|
458
|
+
shiftedMonth = 1;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
shiftedDay = 0;
|
|
462
|
+
} else {
|
|
463
|
+
shiftedMonth--;
|
|
464
|
+
|
|
465
|
+
if (shiftedMonth < 1) {
|
|
466
|
+
shiftedYear--;
|
|
467
|
+
shiftedMonth = 12;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
shiftedDay = Day.getDaysInMonth(shiftedYear, shiftedMonth) + 1;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return new Day(shiftedYear, shiftedMonth, shiftedDay);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Calculates a new {@link Day} in the past (or future).
|
|
479
|
+
*
|
|
480
|
+
* @public
|
|
481
|
+
* @param {Number} days - The number of days to subtract (negative numbers can be used for addition).
|
|
482
|
+
* @returns {Day}
|
|
483
|
+
*/
|
|
484
|
+
|
|
485
|
+
}, {
|
|
486
|
+
key: 'subtractDays',
|
|
487
|
+
value: function subtractDays(days) {
|
|
488
|
+
return this.addDays(days, true);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Calculates a new {@link Day} in the future (or past). If the new date is at the end of
|
|
493
|
+
* the month and the new month has fewer days than the current month, days will be subtracted
|
|
494
|
+
* as necessary (e.g. adding one month to March 31 will return April 30).
|
|
495
|
+
*
|
|
496
|
+
* @public
|
|
497
|
+
* @param {Number} months - The number of months to add (negative numbers can be used for subtraction).
|
|
498
|
+
* @param {Boolean=} inverse - If true, the sign of the "days" value will be flipped.
|
|
499
|
+
* @returns {Day}
|
|
500
|
+
*/
|
|
501
|
+
|
|
502
|
+
}, {
|
|
503
|
+
key: 'addMonths',
|
|
504
|
+
value: function addMonths(months, inverse) {
|
|
505
|
+
assert.argumentIsRequired(months, 'months', Number);
|
|
506
|
+
assert.argumentIsOptional(inverse, inverse, Boolean);
|
|
507
|
+
assert.argumentIsValid(months, 'months', is.large, 'is an integer');
|
|
508
|
+
|
|
509
|
+
var totalMonthsToShift = void 0;
|
|
510
|
+
|
|
511
|
+
if (is.boolean(inverse) && inverse) {
|
|
512
|
+
totalMonthsToShift = months * -1;
|
|
513
|
+
} else {
|
|
514
|
+
totalMonthsToShift = months;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
var monthsToShift = totalMonthsToShift % 12;
|
|
518
|
+
var yearsToShift = (totalMonthsToShift - monthsToShift) / 12;
|
|
519
|
+
|
|
520
|
+
var shiftedYear = this.year + yearsToShift;
|
|
521
|
+
var shiftedMonth = this.month + monthsToShift;
|
|
522
|
+
var shiftedDay = this.day;
|
|
523
|
+
|
|
524
|
+
if (shiftedMonth > 12) {
|
|
525
|
+
shiftedYear = shiftedYear + 1;
|
|
526
|
+
shiftedMonth = shiftedMonth - 12;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (shiftedMonth < 1) {
|
|
530
|
+
shiftedYear = shiftedYear - 1;
|
|
531
|
+
shiftedMonth = shiftedMonth + 12;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
while (!Day.validate(shiftedYear, shiftedMonth, shiftedDay)) {
|
|
535
|
+
shiftedDay = shiftedDay - 1;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return new Day(shiftedYear, shiftedMonth, shiftedDay);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Calculates a new {@link Day} in the past (or future).
|
|
543
|
+
*
|
|
544
|
+
* @public
|
|
545
|
+
* @param {Number} months - The number of months to subtract (negative numbers can be used for addition).
|
|
546
|
+
* @returns {Day}
|
|
547
|
+
*/
|
|
548
|
+
|
|
549
|
+
}, {
|
|
550
|
+
key: 'subtractMonths',
|
|
551
|
+
value: function subtractMonths(months) {
|
|
552
|
+
return this.addMonths(months, true);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Calculates a new {@link Day} in the future (or past). If the new date is at the end of
|
|
557
|
+
* the month and the new month has fewer days than the current month, days will be subtracted
|
|
558
|
+
* as necessary (e.g. adding one year to February 29 will return February 28).
|
|
559
|
+
*
|
|
560
|
+
* @public
|
|
561
|
+
* @param {Number} years - The number of years to add (negative numbers can be used for subtraction).
|
|
562
|
+
* @param {Boolean=} inverse - If true, the sign of the "days" value will be flipped.
|
|
563
|
+
* @returns {Day}
|
|
564
|
+
*/
|
|
565
|
+
|
|
566
|
+
}, {
|
|
567
|
+
key: 'addYears',
|
|
568
|
+
value: function addYears(years, inverse) {
|
|
569
|
+
assert.argumentIsRequired(years, 'years', Number);
|
|
570
|
+
assert.argumentIsOptional(inverse, inverse, Boolean);
|
|
571
|
+
assert.argumentIsValid(years, 'years', is.large, 'is an integer');
|
|
572
|
+
|
|
573
|
+
var yearsToShift = void 0;
|
|
574
|
+
|
|
575
|
+
if (is.boolean(inverse) && inverse) {
|
|
576
|
+
yearsToShift = years * -1;
|
|
577
|
+
} else {
|
|
578
|
+
yearsToShift = years;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
var shiftedYear = this.year + yearsToShift;
|
|
582
|
+
var shiftedMonth = this.month;
|
|
583
|
+
var shiftedDay = this.day;
|
|
584
|
+
|
|
585
|
+
while (!Day.validate(shiftedYear, shiftedMonth, shiftedDay)) {
|
|
586
|
+
shiftedDay = shiftedDay - 1;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
return new Day(shiftedYear, shiftedMonth, shiftedDay);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Calculates a new {@link Day} in the past (or future).
|
|
594
|
+
*
|
|
595
|
+
* @public
|
|
596
|
+
* @param {Number} years - The number of years to subtract (negative numbers can be used for addition).
|
|
597
|
+
* @returns {Day}
|
|
598
|
+
*/
|
|
599
|
+
|
|
600
|
+
}, {
|
|
601
|
+
key: 'subtractYears',
|
|
602
|
+
value: function subtractYears(years) {
|
|
603
|
+
return this.addYears(years, true);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Indicates if another {@link Day} occurs before the current instance.
|
|
608
|
+
*
|
|
609
|
+
* @public
|
|
610
|
+
* @param {Day} other
|
|
611
|
+
* @returns {boolean}
|
|
612
|
+
*/
|
|
613
|
+
|
|
614
|
+
}, {
|
|
615
|
+
key: 'getIsBefore',
|
|
616
|
+
value: function getIsBefore(other) {
|
|
617
|
+
return Day.compareDays(this, other) < 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Indicates if another {@link Day} occurs after the current instance.
|
|
622
|
+
*
|
|
623
|
+
* @public
|
|
624
|
+
* @param {Day} other
|
|
625
|
+
* @returns {boolean}
|
|
626
|
+
*/
|
|
627
|
+
|
|
628
|
+
}, {
|
|
629
|
+
key: 'getIsAfter',
|
|
630
|
+
value: function getIsAfter(other) {
|
|
631
|
+
return Day.compareDays(this, other) > 0;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Indicates if another {@link Day} occurs after the current instance.
|
|
636
|
+
*
|
|
637
|
+
* @public
|
|
638
|
+
* @param {Day} other
|
|
639
|
+
* @returns {boolean}
|
|
640
|
+
*/
|
|
641
|
+
|
|
642
|
+
}, {
|
|
643
|
+
key: 'getIsEqual',
|
|
644
|
+
value: function getIsEqual(other) {
|
|
645
|
+
return Day.compareDays(this, other) === 0;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* The year.
|
|
650
|
+
*
|
|
651
|
+
* @public
|
|
652
|
+
* @returns {Number}
|
|
653
|
+
*/
|
|
654
|
+
|
|
655
|
+
}, {
|
|
656
|
+
key: 'format',
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Outputs the date as the formatted string: {year}-{month}-{day}.
|
|
661
|
+
*
|
|
662
|
+
* @public
|
|
663
|
+
* @returns {String}
|
|
664
|
+
*/
|
|
665
|
+
value: function format() {
|
|
666
|
+
return this._year + '-' + leftPad(this._month) + '-' + leftPad(this._day);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Returns the JSON representation.
|
|
671
|
+
*
|
|
672
|
+
* @public
|
|
673
|
+
* @returns {String}
|
|
674
|
+
*/
|
|
675
|
+
|
|
676
|
+
}, {
|
|
677
|
+
key: 'toJSON',
|
|
678
|
+
value: function toJSON() {
|
|
679
|
+
return this.format();
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Converts a string (which matches the output of {@link Day#format} into
|
|
684
|
+
* a {@link Day} instance.
|
|
685
|
+
*
|
|
686
|
+
* @public
|
|
687
|
+
* @static
|
|
688
|
+
* @param {String} value
|
|
689
|
+
* @returns {Day}
|
|
690
|
+
*/
|
|
691
|
+
|
|
692
|
+
}, {
|
|
693
|
+
key: 'toString',
|
|
694
|
+
value: function toString() {
|
|
695
|
+
return '[Day]';
|
|
696
|
+
}
|
|
697
|
+
}, {
|
|
698
|
+
key: 'year',
|
|
699
|
+
get: function get() {
|
|
700
|
+
return this._year;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* The month of the year (January is one, December is twelve).
|
|
705
|
+
*
|
|
706
|
+
* @public
|
|
707
|
+
* @returns {Number}
|
|
708
|
+
*/
|
|
709
|
+
|
|
710
|
+
}, {
|
|
711
|
+
key: 'month',
|
|
712
|
+
get: function get() {
|
|
713
|
+
return this._month;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* The day of the month.
|
|
718
|
+
*
|
|
719
|
+
* @public
|
|
720
|
+
* @returns {Number}
|
|
721
|
+
*/
|
|
722
|
+
|
|
723
|
+
}, {
|
|
724
|
+
key: 'day',
|
|
725
|
+
get: function get() {
|
|
726
|
+
return this._day;
|
|
727
|
+
}
|
|
728
|
+
}], [{
|
|
729
|
+
key: 'parse',
|
|
730
|
+
value: function parse(value) {
|
|
731
|
+
assert.argumentIsRequired(value, 'value', String);
|
|
732
|
+
|
|
733
|
+
var match = value.match(dayRegex);
|
|
734
|
+
|
|
735
|
+
if (match === null) {
|
|
736
|
+
throw new Error('Unable to parse value as Day [ ' + value + ' ]');
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return new Day(parseInt(match[1]), parseInt(match[2]), parseInt(match[3]));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Creates a {@link Day} from the year, month, and day properties (in local time)
|
|
744
|
+
* of the {@link Date} argument.
|
|
745
|
+
*
|
|
746
|
+
* @public
|
|
747
|
+
* @static
|
|
748
|
+
* @param {Date} date
|
|
749
|
+
* @returns {Day}
|
|
750
|
+
*/
|
|
751
|
+
|
|
752
|
+
}, {
|
|
753
|
+
key: 'fromDate',
|
|
754
|
+
value: function fromDate(date) {
|
|
755
|
+
assert.argumentIsRequired(date, 'date', Date);
|
|
756
|
+
|
|
757
|
+
return new Day(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Creates a {@link Day} from the year, month, and day properties (in UTC)
|
|
762
|
+
* of the {@link Date} argument.
|
|
763
|
+
*
|
|
764
|
+
* @public
|
|
765
|
+
* @static
|
|
766
|
+
* @param {Date} date
|
|
767
|
+
* @returns {Day}
|
|
768
|
+
*/
|
|
769
|
+
|
|
770
|
+
}, {
|
|
771
|
+
key: 'fromDateUtc',
|
|
772
|
+
value: function fromDateUtc(date) {
|
|
773
|
+
assert.argumentIsRequired(date, 'date', Date);
|
|
774
|
+
|
|
775
|
+
return new Day(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate());
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Returns a {@link Day} instance using today's local date.
|
|
780
|
+
*
|
|
781
|
+
* @static
|
|
782
|
+
* @public
|
|
783
|
+
* @return {Day}
|
|
784
|
+
*/
|
|
785
|
+
|
|
786
|
+
}, {
|
|
787
|
+
key: 'getToday',
|
|
788
|
+
value: function getToday() {
|
|
789
|
+
return Day.fromDate(new Date());
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Returns true if the year, month, and day combination is valid; otherwise false.
|
|
794
|
+
*
|
|
795
|
+
* @public
|
|
796
|
+
* @static
|
|
797
|
+
* @param {Number} year
|
|
798
|
+
* @param {Number} month
|
|
799
|
+
* @param {Number} day
|
|
800
|
+
* @returns {Boolean}
|
|
801
|
+
*/
|
|
802
|
+
|
|
803
|
+
}, {
|
|
804
|
+
key: 'validate',
|
|
805
|
+
value: function validate(year, month, day) {
|
|
806
|
+
return is.integer(year) && is.integer(month) && is.integer(day) && !(month < 1) && !(month > 12) && !(day < 1) && !(day > Day.getDaysInMonth(year, month));
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Returns the number of days in a given month.
|
|
811
|
+
*
|
|
812
|
+
* @public
|
|
813
|
+
* @static
|
|
814
|
+
* @param {number} year - The year number (e.g. 2017)
|
|
815
|
+
* @param {number} month - The month number (e.g. 2 is February)
|
|
816
|
+
*/
|
|
817
|
+
|
|
818
|
+
}, {
|
|
819
|
+
key: 'getDaysInMonth',
|
|
820
|
+
value: function getDaysInMonth(year, month) {
|
|
821
|
+
switch (month) {
|
|
822
|
+
case 1:
|
|
823
|
+
case 3:
|
|
824
|
+
case 5:
|
|
825
|
+
case 7:
|
|
826
|
+
case 8:
|
|
827
|
+
case 10:
|
|
828
|
+
case 12:
|
|
829
|
+
{
|
|
830
|
+
return 31;
|
|
831
|
+
}
|
|
832
|
+
case 4:
|
|
833
|
+
case 6:
|
|
834
|
+
case 9:
|
|
835
|
+
case 11:
|
|
836
|
+
{
|
|
837
|
+
return 30;
|
|
838
|
+
}
|
|
839
|
+
case 2:
|
|
840
|
+
{
|
|
841
|
+
if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
|
|
842
|
+
return 29;
|
|
843
|
+
} else {
|
|
844
|
+
return 28;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* A comparator function for {@link Day} instances.
|
|
852
|
+
*
|
|
853
|
+
* @public
|
|
854
|
+
* @static
|
|
855
|
+
* @param {Day} a
|
|
856
|
+
* @param {Day} b
|
|
857
|
+
* @returns {Number}
|
|
858
|
+
*/
|
|
859
|
+
|
|
860
|
+
}, {
|
|
861
|
+
key: 'compareDays',
|
|
862
|
+
value: function compareDays(a, b) {
|
|
863
|
+
assert.argumentIsRequired(a, 'a', Day, 'Day');
|
|
864
|
+
assert.argumentIsRequired(b, 'b', Day, 'Day');
|
|
865
|
+
|
|
866
|
+
return comparator(a, b);
|
|
867
|
+
}
|
|
868
|
+
}]);
|
|
869
|
+
|
|
870
|
+
return Day;
|
|
871
|
+
}();
|
|
872
|
+
|
|
873
|
+
var dayRegex = /^([0-9]{4}).?([0-9]{2}).?([0-9]{2})$/;
|
|
874
|
+
|
|
875
|
+
function leftPad(value) {
|
|
876
|
+
return value < 10 ? '0' + value : '' + value;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
var comparator = ComparatorBuilder.startWith(function (a, b) {
|
|
880
|
+
return comparators.compareNumbers(a.year, b.year);
|
|
881
|
+
}).thenBy(function (a, b) {
|
|
882
|
+
return comparators.compareNumbers(a.month, b.month);
|
|
883
|
+
}).thenBy(function (a, b) {
|
|
884
|
+
return comparators.compareNumbers(a.day, b.day);
|
|
885
|
+
}).toComparator();
|
|
886
|
+
|
|
887
|
+
return Day;
|
|
888
|
+
}();
|
|
889
|
+
|
|
890
|
+
},{"./../collections/sorting/ComparatorBuilder":2,"./../collections/sorting/comparators":3,"./assert":8,"./is":9}],5:[function(require,module,exports){
|
|
891
|
+
'use strict';
|
|
892
|
+
|
|
893
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
894
|
+
|
|
895
|
+
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
896
|
+
|
|
897
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
898
|
+
|
|
899
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
900
|
+
|
|
901
|
+
var assert = require('./assert'),
|
|
902
|
+
Enum = require('./Enum'),
|
|
903
|
+
is = require('./is');
|
|
904
|
+
|
|
905
|
+
var Big = require('big.js');
|
|
906
|
+
|
|
907
|
+
module.exports = function () {
|
|
908
|
+
'use strict';
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* An immutable object that allows for arbitrary-precision calculations.
|
|
912
|
+
*
|
|
913
|
+
* @public
|
|
914
|
+
* @param {Decimal|Number|String} value - The value.
|
|
915
|
+
*/
|
|
916
|
+
|
|
917
|
+
var Decimal = function () {
|
|
918
|
+
function Decimal(value) {
|
|
919
|
+
_classCallCheck(this, Decimal);
|
|
920
|
+
|
|
921
|
+
this._big = getBig(value);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Returns a new {@link Decimal} instance that is the sum of the
|
|
926
|
+
* current instance's value and the value supplied.
|
|
927
|
+
*
|
|
928
|
+
* @public
|
|
929
|
+
* @param {Decimal|Number|String} other - The value to add.
|
|
930
|
+
* @returns {Decimal}
|
|
931
|
+
*/
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
_createClass(Decimal, [{
|
|
935
|
+
key: 'add',
|
|
936
|
+
value: function add(other) {
|
|
937
|
+
return new Decimal(this._big.plus(getBig(other)));
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Returns a new {@link Decimal} instance with a value that results
|
|
942
|
+
* from the subtraction of the value supplied from the current instance's
|
|
943
|
+
* value.
|
|
944
|
+
*
|
|
945
|
+
* @public
|
|
946
|
+
* @param {Decimal|Number|String} other - The value to subtract.
|
|
947
|
+
* @returns {Decimal}
|
|
948
|
+
*/
|
|
949
|
+
|
|
950
|
+
}, {
|
|
951
|
+
key: 'subtract',
|
|
952
|
+
value: function subtract(other) {
|
|
953
|
+
return new Decimal(this._big.minus(getBig(other)));
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Returns a new {@link Decimal} instance that is the product of the
|
|
958
|
+
* current instance's value and the value supplied.
|
|
959
|
+
*
|
|
960
|
+
* @public
|
|
961
|
+
* @param {Decimal|Number|String} other - The value to add.
|
|
962
|
+
* @returns {Decimal}
|
|
963
|
+
*/
|
|
964
|
+
|
|
965
|
+
}, {
|
|
966
|
+
key: 'multiply',
|
|
967
|
+
value: function multiply(other) {
|
|
968
|
+
return new Decimal(this._big.times(getBig(other)));
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* Returns a new {@link Decimal} instance with a value that results
|
|
973
|
+
* from the division of the current instance's value by the value
|
|
974
|
+
* supplied.
|
|
975
|
+
*
|
|
976
|
+
* @public
|
|
977
|
+
* @param {Decimal|Number|String} other - The value to subtract.
|
|
978
|
+
* @returns {Decimal}
|
|
979
|
+
*/
|
|
980
|
+
|
|
981
|
+
}, {
|
|
982
|
+
key: 'divide',
|
|
983
|
+
value: function divide(other) {
|
|
984
|
+
return new Decimal(this._big.div(getBig(other)));
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Returns a new {@link Decimal} with a value resulting from a rounding
|
|
989
|
+
* operation on the current value.
|
|
990
|
+
*
|
|
991
|
+
* @public
|
|
992
|
+
* @param {Number} places - The number of decimal places to retain.
|
|
993
|
+
* @param {RoundingMode=} mode - The strategy to use for rounding.
|
|
994
|
+
* @returns {Decimal}
|
|
995
|
+
*/
|
|
996
|
+
|
|
997
|
+
}, {
|
|
998
|
+
key: 'round',
|
|
999
|
+
value: function round(places, mode) {
|
|
1000
|
+
assert.argumentIsRequired(places, 'places', Number);
|
|
1001
|
+
assert.argumentIsOptional(mode, 'mode', RoundingMode, 'RoundingMode');
|
|
1002
|
+
|
|
1003
|
+
var modeToUse = mode || RoundingMode.NORMAL;
|
|
1004
|
+
|
|
1005
|
+
return new Decimal(this._big.round(places, modeToUse.value));
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Returns a new {@link Decimal} instance having the absolute value of
|
|
1010
|
+
* the current instance's value.
|
|
1011
|
+
*
|
|
1012
|
+
* @public
|
|
1013
|
+
* @returns {Decimal}
|
|
1014
|
+
*/
|
|
1015
|
+
|
|
1016
|
+
}, {
|
|
1017
|
+
key: 'absolute',
|
|
1018
|
+
value: function absolute() {
|
|
1019
|
+
return new Decimal(this._big.abs());
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* Returns a new {@link Decimal} instance the opposite sign as the
|
|
1024
|
+
* current instance's value.
|
|
1025
|
+
*
|
|
1026
|
+
* @public
|
|
1027
|
+
* @returns {Decimal}
|
|
1028
|
+
*/
|
|
1029
|
+
|
|
1030
|
+
}, {
|
|
1031
|
+
key: 'opposite',
|
|
1032
|
+
value: function opposite() {
|
|
1033
|
+
return this.multiply(-1);
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* Returns a Boolean value, indicating if the current instance's value is
|
|
1038
|
+
* equal to zero (or approximately equal to zero).
|
|
1039
|
+
*
|
|
1040
|
+
* @public
|
|
1041
|
+
* @param {Boolean=} approximate
|
|
1042
|
+
* @returns {Boolean}
|
|
1043
|
+
*/
|
|
1044
|
+
|
|
1045
|
+
}, {
|
|
1046
|
+
key: 'getIsZero',
|
|
1047
|
+
value: function getIsZero(approximate) {
|
|
1048
|
+
assert.argumentIsOptional(approximate, 'approximate', Boolean);
|
|
1049
|
+
|
|
1050
|
+
return this._big.eq(zero) || is.boolean(approximate) && approximate && this.round(20, RoundingMode.NORMAL).getIsZero();
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Returns true if the current instance is positive; otherwise false.
|
|
1055
|
+
*
|
|
1056
|
+
* @public
|
|
1057
|
+
* @returns {Boolean}
|
|
1058
|
+
*/
|
|
1059
|
+
|
|
1060
|
+
}, {
|
|
1061
|
+
key: 'getIsPositive',
|
|
1062
|
+
value: function getIsPositive() {
|
|
1063
|
+
return this._big.gt(zero);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* Returns true if the current instance is negative; otherwise false.
|
|
1068
|
+
*
|
|
1069
|
+
* @public
|
|
1070
|
+
* @returns {Boolean}
|
|
1071
|
+
*/
|
|
1072
|
+
|
|
1073
|
+
}, {
|
|
1074
|
+
key: 'getIsNegative',
|
|
1075
|
+
value: function getIsNegative() {
|
|
1076
|
+
return this._big.lt(zero);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Returns true if the current instance is greater than the value.
|
|
1081
|
+
*
|
|
1082
|
+
* @public
|
|
1083
|
+
* @param {Decimal|Number|String} other - The value to compare.
|
|
1084
|
+
* @returns {Boolean}
|
|
1085
|
+
*/
|
|
1086
|
+
|
|
1087
|
+
}, {
|
|
1088
|
+
key: 'getIsGreaterThan',
|
|
1089
|
+
value: function getIsGreaterThan(other) {
|
|
1090
|
+
return this._big.gt(getBig(other));
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* Returns true if the current instance is less than the value.
|
|
1095
|
+
*
|
|
1096
|
+
* @public
|
|
1097
|
+
* @param {Decimal|Number|String} other - The value to compare.
|
|
1098
|
+
* @returns {Boolean}
|
|
1099
|
+
*/
|
|
1100
|
+
|
|
1101
|
+
}, {
|
|
1102
|
+
key: 'getIsLessThan',
|
|
1103
|
+
value: function getIsLessThan(other) {
|
|
1104
|
+
return this._big.lt(getBig(other));
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Returns true if the current instance is equal to the value.
|
|
1109
|
+
*
|
|
1110
|
+
* @public
|
|
1111
|
+
* @param {Decimal|Number|String} other - The value to compare.
|
|
1112
|
+
* @returns {Boolean}
|
|
1113
|
+
*/
|
|
1114
|
+
|
|
1115
|
+
}, {
|
|
1116
|
+
key: 'getIsEqual',
|
|
1117
|
+
value: function getIsEqual(other) {
|
|
1118
|
+
return this._big.eq(getBig(other));
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Emits a floating point value that approximates the value of the current
|
|
1123
|
+
* instance.
|
|
1124
|
+
*
|
|
1125
|
+
* @public
|
|
1126
|
+
* @param {Number=} places
|
|
1127
|
+
* @returns {Number}
|
|
1128
|
+
*/
|
|
1129
|
+
|
|
1130
|
+
}, {
|
|
1131
|
+
key: 'toFloat',
|
|
1132
|
+
value: function toFloat(places) {
|
|
1133
|
+
assert.argumentIsOptional(places, 'places', Number);
|
|
1134
|
+
|
|
1135
|
+
// Accepting places might be a mistake here; perhaps
|
|
1136
|
+
// the consumer should be forced to use the round
|
|
1137
|
+
// function.
|
|
1138
|
+
|
|
1139
|
+
return parseFloat(this._big.toFixed(places || 16));
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
/**
|
|
1143
|
+
* Returns a string-based representation of the instance's value.
|
|
1144
|
+
*
|
|
1145
|
+
* @public
|
|
1146
|
+
* @returns {String}
|
|
1147
|
+
*/
|
|
1148
|
+
|
|
1149
|
+
}, {
|
|
1150
|
+
key: 'toFixed',
|
|
1151
|
+
value: function toFixed() {
|
|
1152
|
+
return this._big.toFixed();
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Returns the JSON representation.
|
|
1157
|
+
*
|
|
1158
|
+
* @public
|
|
1159
|
+
* @returns {String}
|
|
1160
|
+
*/
|
|
1161
|
+
|
|
1162
|
+
}, {
|
|
1163
|
+
key: 'toJSON',
|
|
1164
|
+
value: function toJSON() {
|
|
1165
|
+
return this.toFixed();
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/**
|
|
1169
|
+
* Parses the value emitted by {@link Decimal#toJSON}.
|
|
1170
|
+
*
|
|
1171
|
+
* @public
|
|
1172
|
+
* @param {String} value
|
|
1173
|
+
* @returns {Decimal}
|
|
1174
|
+
*/
|
|
1175
|
+
|
|
1176
|
+
}, {
|
|
1177
|
+
key: 'toString',
|
|
1178
|
+
value: function toString() {
|
|
1179
|
+
return '[Decimal]';
|
|
1180
|
+
}
|
|
1181
|
+
}], [{
|
|
1182
|
+
key: 'parse',
|
|
1183
|
+
value: function parse(value) {
|
|
1184
|
+
return new Decimal(value);
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
/**
|
|
1188
|
+
* Returns an instance with the value of zero.
|
|
1189
|
+
*
|
|
1190
|
+
* @public
|
|
1191
|
+
* @returns {Decimal}
|
|
1192
|
+
*/
|
|
1193
|
+
|
|
1194
|
+
}, {
|
|
1195
|
+
key: 'getIsZero',
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Runs {@link Decimal#getIsZero} and returns the result.
|
|
1200
|
+
*
|
|
1201
|
+
* @public
|
|
1202
|
+
* @param {Decimal} instance
|
|
1203
|
+
* @return {Boolean}
|
|
1204
|
+
*/
|
|
1205
|
+
value: function getIsZero(instance) {
|
|
1206
|
+
assert.argumentIsRequired(instance, 'instance', Decimal, 'Decimal');
|
|
1207
|
+
|
|
1208
|
+
return instance.getIsZero();
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/**
|
|
1212
|
+
* Runs {@link Decimal#getIsZero} and returns the inverse.
|
|
1213
|
+
*
|
|
1214
|
+
* @public
|
|
1215
|
+
* @param {Decimal} instance
|
|
1216
|
+
* @return {Boolean}
|
|
1217
|
+
*/
|
|
1218
|
+
|
|
1219
|
+
}, {
|
|
1220
|
+
key: 'getIsNotZero',
|
|
1221
|
+
value: function getIsNotZero(instance) {
|
|
1222
|
+
assert.argumentIsRequired(instance, 'instance', Decimal, 'Decimal');
|
|
1223
|
+
|
|
1224
|
+
return !instance.getIsZero();
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* Runs {@link Decimal#getIsPositive} and returns the result.
|
|
1229
|
+
*
|
|
1230
|
+
* @public
|
|
1231
|
+
* @param {Decimal} instance
|
|
1232
|
+
* @return {Boolean}
|
|
1233
|
+
*/
|
|
1234
|
+
|
|
1235
|
+
}, {
|
|
1236
|
+
key: 'getIsPositive',
|
|
1237
|
+
value: function getIsPositive(instance) {
|
|
1238
|
+
assert.argumentIsRequired(instance, 'instance', Decimal, 'Decimal');
|
|
1239
|
+
|
|
1240
|
+
return instance.getIsPositive();
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Checks an instance to see if its negative or zero.
|
|
1245
|
+
*
|
|
1246
|
+
* @public
|
|
1247
|
+
* @param {Decimal} instance
|
|
1248
|
+
* @return {Boolean}
|
|
1249
|
+
*/
|
|
1250
|
+
|
|
1251
|
+
}, {
|
|
1252
|
+
key: 'getIsNotPositive',
|
|
1253
|
+
value: function getIsNotPositive(instance) {
|
|
1254
|
+
assert.argumentIsRequired(instance, 'instance', Decimal, 'Decimal');
|
|
1255
|
+
|
|
1256
|
+
return instance.getIsNegative() || instance.getIsZero();
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
/**
|
|
1260
|
+
* Runs {@link Decimal#getIsNegative} and returns the result.
|
|
1261
|
+
*
|
|
1262
|
+
* @public
|
|
1263
|
+
* @param {Decimal} instance
|
|
1264
|
+
* @return {Boolean}
|
|
1265
|
+
*/
|
|
1266
|
+
|
|
1267
|
+
}, {
|
|
1268
|
+
key: 'getIsNegative',
|
|
1269
|
+
value: function getIsNegative(instance) {
|
|
1270
|
+
assert.argumentIsRequired(instance, 'instance', Decimal, 'Decimal');
|
|
1271
|
+
|
|
1272
|
+
return instance.getIsNegative();
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/**
|
|
1276
|
+
* Checks an instance to see if its positive or zero.
|
|
1277
|
+
*
|
|
1278
|
+
* @public
|
|
1279
|
+
* @param {Decimal} instance
|
|
1280
|
+
* @return {Boolean}
|
|
1281
|
+
*/
|
|
1282
|
+
|
|
1283
|
+
}, {
|
|
1284
|
+
key: 'getIsNotNegative',
|
|
1285
|
+
value: function getIsNotNegative(instance) {
|
|
1286
|
+
assert.argumentIsRequired(instance, 'instance', Decimal, 'Decimal');
|
|
1287
|
+
|
|
1288
|
+
return instance.getIsPositive() || instance.getIsZero();
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
/**
|
|
1292
|
+
* A comparator function for {@link Decimal} instances.
|
|
1293
|
+
*
|
|
1294
|
+
* @public
|
|
1295
|
+
* @param {Decimal} a
|
|
1296
|
+
* @param {Decimal} b
|
|
1297
|
+
* @returns {Number}
|
|
1298
|
+
*/
|
|
1299
|
+
|
|
1300
|
+
}, {
|
|
1301
|
+
key: 'compareDecimals',
|
|
1302
|
+
value: function compareDecimals(a, b) {
|
|
1303
|
+
assert.argumentIsRequired(a, 'a', Decimal, 'Decimal');
|
|
1304
|
+
assert.argumentIsRequired(b, 'b', Decimal, 'Decimal');
|
|
1305
|
+
|
|
1306
|
+
if (a._big.gt(b)) {
|
|
1307
|
+
return 1;
|
|
1308
|
+
} else if (a._big.lt(b)) {
|
|
1309
|
+
return -1;
|
|
1310
|
+
} else {
|
|
1311
|
+
return 0;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
}, {
|
|
1315
|
+
key: 'ZERO',
|
|
1316
|
+
get: function get() {
|
|
1317
|
+
return decimalZero;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
/**
|
|
1321
|
+
* Returns an instance with the value of one.
|
|
1322
|
+
*
|
|
1323
|
+
* @public
|
|
1324
|
+
* @returns {Decimal}
|
|
1325
|
+
*/
|
|
1326
|
+
|
|
1327
|
+
}, {
|
|
1328
|
+
key: 'ONE',
|
|
1329
|
+
get: function get() {
|
|
1330
|
+
return decimalOne;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/**
|
|
1334
|
+
* Returns an instance with the value of one.
|
|
1335
|
+
*
|
|
1336
|
+
* @public
|
|
1337
|
+
* @returns {Decimal}
|
|
1338
|
+
*/
|
|
1339
|
+
|
|
1340
|
+
}, {
|
|
1341
|
+
key: 'NEGATIVE_ONE',
|
|
1342
|
+
get: function get() {
|
|
1343
|
+
return decimalNegativeOne;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
/**
|
|
1347
|
+
* Return the {@link RoundingMode} enumeration.
|
|
1348
|
+
*
|
|
1349
|
+
* @public
|
|
1350
|
+
* @returns {RoundingMode}
|
|
1351
|
+
*/
|
|
1352
|
+
|
|
1353
|
+
}, {
|
|
1354
|
+
key: 'ROUNDING_MODE',
|
|
1355
|
+
get: function get() {
|
|
1356
|
+
return RoundingMode;
|
|
1357
|
+
}
|
|
1358
|
+
}]);
|
|
1359
|
+
|
|
1360
|
+
return Decimal;
|
|
1361
|
+
}();
|
|
1362
|
+
|
|
1363
|
+
var zero = new Big(0);
|
|
1364
|
+
var positiveOne = new Big(1);
|
|
1365
|
+
var negativeOne = new Big(-1);
|
|
1366
|
+
|
|
1367
|
+
var decimalZero = new Decimal(zero);
|
|
1368
|
+
var decimalOne = new Decimal(positiveOne);
|
|
1369
|
+
var decimalNegativeOne = new Decimal(negativeOne);
|
|
1370
|
+
|
|
1371
|
+
function getBig(value) {
|
|
1372
|
+
if (value instanceof Big) {
|
|
1373
|
+
return value;
|
|
1374
|
+
} else if (value instanceof Decimal) {
|
|
1375
|
+
return value._big;
|
|
1376
|
+
} else {
|
|
1377
|
+
return new Big(value);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
/**
|
|
1382
|
+
* An enumeration of strategies for rouding a {@link Decimal} instance.
|
|
1383
|
+
*
|
|
1384
|
+
* @public
|
|
1385
|
+
* @inner
|
|
1386
|
+
* @extends {Enum}
|
|
1387
|
+
*/
|
|
1388
|
+
|
|
1389
|
+
var RoundingMode = function (_Enum) {
|
|
1390
|
+
_inherits(RoundingMode, _Enum);
|
|
1391
|
+
|
|
1392
|
+
function RoundingMode(value, description) {
|
|
1393
|
+
_classCallCheck(this, RoundingMode);
|
|
1394
|
+
|
|
1395
|
+
var _this = _possibleConstructorReturn(this, (RoundingMode.__proto__ || Object.getPrototypeOf(RoundingMode)).call(this, value.toString(), description));
|
|
1396
|
+
|
|
1397
|
+
_this._value = value;
|
|
1398
|
+
return _this;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
/**
|
|
1402
|
+
* The code used by the Big.js library.
|
|
1403
|
+
*
|
|
1404
|
+
* @ignore
|
|
1405
|
+
* @returns {Number}
|
|
1406
|
+
*/
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
_createClass(RoundingMode, [{
|
|
1410
|
+
key: 'toString',
|
|
1411
|
+
value: function toString() {
|
|
1412
|
+
return '[RoundingMode]';
|
|
1413
|
+
}
|
|
1414
|
+
}, {
|
|
1415
|
+
key: 'value',
|
|
1416
|
+
get: function get() {
|
|
1417
|
+
return this._value;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* Rounds away from zero.
|
|
1422
|
+
*
|
|
1423
|
+
* @public
|
|
1424
|
+
* @returns {RoundingMode}
|
|
1425
|
+
*/
|
|
1426
|
+
|
|
1427
|
+
}], [{
|
|
1428
|
+
key: 'UP',
|
|
1429
|
+
get: function get() {
|
|
1430
|
+
return up;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
/**
|
|
1434
|
+
* Rounds towards zero.
|
|
1435
|
+
*
|
|
1436
|
+
* @public
|
|
1437
|
+
* @returns {RoundingMode}
|
|
1438
|
+
*/
|
|
1439
|
+
|
|
1440
|
+
}, {
|
|
1441
|
+
key: 'DOWN',
|
|
1442
|
+
get: function get() {
|
|
1443
|
+
return down;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
/**
|
|
1447
|
+
* Rounds towards nearest neighbor. If equidistant, rounds away from zero.
|
|
1448
|
+
*
|
|
1449
|
+
* @public
|
|
1450
|
+
* @returns {RoundingMode}
|
|
1451
|
+
*/
|
|
1452
|
+
|
|
1453
|
+
}, {
|
|
1454
|
+
key: 'NORMAL',
|
|
1455
|
+
get: function get() {
|
|
1456
|
+
return normal;
|
|
1457
|
+
}
|
|
1458
|
+
}]);
|
|
1459
|
+
|
|
1460
|
+
return RoundingMode;
|
|
1461
|
+
}(Enum);
|
|
1462
|
+
|
|
1463
|
+
var up = new RoundingMode(3, 'up');
|
|
1464
|
+
var down = new RoundingMode(0, 'down');
|
|
1465
|
+
var normal = new RoundingMode(1, 'normal');
|
|
1466
|
+
|
|
1467
|
+
return Decimal;
|
|
1468
|
+
}();
|
|
1469
|
+
|
|
1470
|
+
},{"./Enum":6,"./assert":8,"./is":9,"big.js":10}],6:[function(require,module,exports){
|
|
1471
|
+
'use strict';
|
|
1472
|
+
|
|
1473
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
1474
|
+
|
|
1475
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
1476
|
+
|
|
1477
|
+
var assert = require('./assert');
|
|
1478
|
+
|
|
1479
|
+
module.exports = function () {
|
|
1480
|
+
'use strict';
|
|
1481
|
+
|
|
1482
|
+
var types = new Map();
|
|
1483
|
+
|
|
1484
|
+
/**
|
|
1485
|
+
* An enumeration. Must be inherited. Do not instantiate directly.
|
|
1486
|
+
* Also, this class uses the ES6 Map, therefore a polyfill must
|
|
1487
|
+
* be supplied.
|
|
1488
|
+
*
|
|
1489
|
+
* @public
|
|
1490
|
+
* @interface
|
|
1491
|
+
* @param {String} code - The unique code of the enumeration item.
|
|
1492
|
+
* @param {String} description - A description of the enumeration item.
|
|
1493
|
+
*/
|
|
1494
|
+
|
|
1495
|
+
var Enum = function () {
|
|
1496
|
+
function Enum(code, description) {
|
|
1497
|
+
_classCallCheck(this, Enum);
|
|
1498
|
+
|
|
1499
|
+
assert.argumentIsRequired(code, 'code', String);
|
|
1500
|
+
assert.argumentIsRequired(description, 'description', String);
|
|
1501
|
+
|
|
1502
|
+
this._code = code;
|
|
1503
|
+
this._description = description;
|
|
1504
|
+
|
|
1505
|
+
var c = this.constructor;
|
|
1506
|
+
|
|
1507
|
+
if (!types.has(c)) {
|
|
1508
|
+
types.set(c, []);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
var existing = Enum.fromCode(c, code);
|
|
1512
|
+
|
|
1513
|
+
if (existing === null) {
|
|
1514
|
+
types.get(c).push(this);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
/**
|
|
1519
|
+
* The unique code.
|
|
1520
|
+
*
|
|
1521
|
+
* @returns {String}
|
|
1522
|
+
*/
|
|
1523
|
+
|
|
1524
|
+
|
|
1525
|
+
_createClass(Enum, [{
|
|
1526
|
+
key: 'equals',
|
|
1527
|
+
|
|
1528
|
+
|
|
1529
|
+
/**
|
|
1530
|
+
* Returns true if the provided {@link Enum} argument is equal
|
|
1531
|
+
* to the instance.
|
|
1532
|
+
*
|
|
1533
|
+
* @param {Enum} other
|
|
1534
|
+
* @returns {boolean}
|
|
1535
|
+
*/
|
|
1536
|
+
value: function equals(other) {
|
|
1537
|
+
return other === this || other instanceof Enum && other.constructor === this.constructor && other.code === this.code;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
/**
|
|
1541
|
+
* Returns the JSON representation.
|
|
1542
|
+
*
|
|
1543
|
+
* @public
|
|
1544
|
+
* @returns {String}
|
|
1545
|
+
*/
|
|
1546
|
+
|
|
1547
|
+
}, {
|
|
1548
|
+
key: 'toJSON',
|
|
1549
|
+
value: function toJSON() {
|
|
1550
|
+
return this.code;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Looks up a enumeration item; given the enumeration type and the enumeration
|
|
1555
|
+
* item's value. If no matching item can be found, a null value is returned.
|
|
1556
|
+
*
|
|
1557
|
+
* @param {Function} type - The enumeration type.
|
|
1558
|
+
* @param {String} code - The enumeration item's code.
|
|
1559
|
+
* @returns {*|null}
|
|
1560
|
+
*/
|
|
1561
|
+
|
|
1562
|
+
}, {
|
|
1563
|
+
key: 'toString',
|
|
1564
|
+
value: function toString() {
|
|
1565
|
+
return '[Enum]';
|
|
1566
|
+
}
|
|
1567
|
+
}, {
|
|
1568
|
+
key: 'code',
|
|
1569
|
+
get: function get() {
|
|
1570
|
+
return this._code;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
/**
|
|
1574
|
+
* The description.
|
|
1575
|
+
*
|
|
1576
|
+
* @returns {String}
|
|
1577
|
+
*/
|
|
1578
|
+
|
|
1579
|
+
}, {
|
|
1580
|
+
key: 'description',
|
|
1581
|
+
get: function get() {
|
|
1582
|
+
return this._description;
|
|
1583
|
+
}
|
|
1584
|
+
}], [{
|
|
1585
|
+
key: 'fromCode',
|
|
1586
|
+
value: function fromCode(type, code) {
|
|
1587
|
+
return Enum.getItems(type).find(function (x) {
|
|
1588
|
+
return x.code === code;
|
|
1589
|
+
}) || null;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
/**
|
|
1593
|
+
* Returns all of the enumeration's items (given an enumeration type).
|
|
1594
|
+
*
|
|
1595
|
+
* @param {Function} type - The enumeration to list.
|
|
1596
|
+
* @returns {Array}
|
|
1597
|
+
*/
|
|
1598
|
+
|
|
1599
|
+
}, {
|
|
1600
|
+
key: 'getItems',
|
|
1601
|
+
value: function getItems(type) {
|
|
1602
|
+
return types.get(type) || [];
|
|
1603
|
+
}
|
|
1604
|
+
}]);
|
|
1605
|
+
|
|
1606
|
+
return Enum;
|
|
1607
|
+
}();
|
|
1608
|
+
|
|
1609
|
+
return Enum;
|
|
1610
|
+
}();
|
|
1611
|
+
|
|
1612
|
+
},{"./assert":8}],7:[function(require,module,exports){
|
|
1613
|
+
'use strict';
|
|
1614
|
+
|
|
1615
|
+
var assert = require('./assert'),
|
|
1616
|
+
is = require('./is');
|
|
1617
|
+
|
|
1618
|
+
module.exports = function () {
|
|
1619
|
+
'use strict';
|
|
1620
|
+
|
|
1621
|
+
/**
|
|
1622
|
+
* Utilities for working with arrays.
|
|
1623
|
+
*
|
|
1624
|
+
* @public
|
|
1625
|
+
* @module lang/array
|
|
1626
|
+
*/
|
|
1627
|
+
|
|
1628
|
+
return {
|
|
1629
|
+
/**
|
|
1630
|
+
* Returns the unique items from an array, where the unique
|
|
1631
|
+
* key is determined via a strict equality check.
|
|
1632
|
+
*
|
|
1633
|
+
* @static
|
|
1634
|
+
* @param {Array} a
|
|
1635
|
+
* @returns {Array}
|
|
1636
|
+
*/
|
|
1637
|
+
unique: function unique(a) {
|
|
1638
|
+
assert.argumentIsArray(a, 'a');
|
|
1639
|
+
|
|
1640
|
+
return a.filter(function (item, index, array) {
|
|
1641
|
+
return array.indexOf(item) === index;
|
|
1642
|
+
});
|
|
1643
|
+
},
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
/**
|
|
1647
|
+
* Returns the unique items from an array, where the unique
|
|
1648
|
+
* key is determined by a delegate.
|
|
1649
|
+
*
|
|
1650
|
+
* @static
|
|
1651
|
+
* @param {Array} a
|
|
1652
|
+
* @param {Function} keySelector - The function, when applied to an item yields a unique key.
|
|
1653
|
+
* @returns {Array}
|
|
1654
|
+
*/
|
|
1655
|
+
uniqueBy: function uniqueBy(a, keySelector) {
|
|
1656
|
+
assert.argumentIsArray(a, 'a');
|
|
1657
|
+
|
|
1658
|
+
return a.filter(function (item, index, array) {
|
|
1659
|
+
var key = keySelector(item);
|
|
1660
|
+
|
|
1661
|
+
return array.findIndex(function (candidate) {
|
|
1662
|
+
return key === keySelector(candidate);
|
|
1663
|
+
}) === index;
|
|
1664
|
+
});
|
|
1665
|
+
},
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* Splits array into groups and returns an object (where the properties have
|
|
1670
|
+
* arrays). Unlike the indexBy function, there can be many items
|
|
1671
|
+
* which share the same key.
|
|
1672
|
+
*
|
|
1673
|
+
* @static
|
|
1674
|
+
* @param {Array} a
|
|
1675
|
+
* @param {Function} keySelector - The function, when applied to an item yields a key.
|
|
1676
|
+
* @returns {Object}
|
|
1677
|
+
*/
|
|
1678
|
+
groupBy: function groupBy(a, keySelector) {
|
|
1679
|
+
assert.argumentIsArray(a, 'a');
|
|
1680
|
+
assert.argumentIsRequired(keySelector, 'keySelector', Function);
|
|
1681
|
+
|
|
1682
|
+
return a.reduce(function (groups, item) {
|
|
1683
|
+
var key = keySelector(item);
|
|
1684
|
+
|
|
1685
|
+
if (!groups.hasOwnProperty(key)) {
|
|
1686
|
+
groups[key] = [];
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
groups[key].push(item);
|
|
1690
|
+
|
|
1691
|
+
return groups;
|
|
1692
|
+
}, {});
|
|
1693
|
+
},
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
/**
|
|
1697
|
+
* Splits array into groups and returns an array of arrays where the items of each
|
|
1698
|
+
* nested array share a common key.
|
|
1699
|
+
*
|
|
1700
|
+
* @static
|
|
1701
|
+
* @param {Array} a
|
|
1702
|
+
* @param {Function} keySelector - The function, when applied to an item yields a key.
|
|
1703
|
+
* @returns {Array}
|
|
1704
|
+
*/
|
|
1705
|
+
batchBy: function batchBy(a, keySelector) {
|
|
1706
|
+
assert.argumentIsArray(a, 'a');
|
|
1707
|
+
assert.argumentIsRequired(keySelector, 'keySelector', Function);
|
|
1708
|
+
|
|
1709
|
+
var currentKey = null;
|
|
1710
|
+
var currentBatch = null;
|
|
1711
|
+
|
|
1712
|
+
return a.reduce(function (batches, item) {
|
|
1713
|
+
var key = keySelector(item);
|
|
1714
|
+
|
|
1715
|
+
if (currentBatch === null || currentKey !== key) {
|
|
1716
|
+
currentKey = key;
|
|
1717
|
+
|
|
1718
|
+
currentBatch = [];
|
|
1719
|
+
batches.push(currentBatch);
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
currentBatch.push(item);
|
|
1723
|
+
|
|
1724
|
+
return batches;
|
|
1725
|
+
}, []);
|
|
1726
|
+
},
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
/**
|
|
1730
|
+
* Splits array into groups and returns an object (where the properties are items from the
|
|
1731
|
+
* original array). Unlike the groupBy, Only one item can have a given key
|
|
1732
|
+
* value.
|
|
1733
|
+
*
|
|
1734
|
+
* @static
|
|
1735
|
+
* @param {Array} a
|
|
1736
|
+
* @param {Function} keySelector - The function, when applied to an item yields a unique key.
|
|
1737
|
+
* @returns {Object}
|
|
1738
|
+
*/
|
|
1739
|
+
indexBy: function indexBy(a, keySelector) {
|
|
1740
|
+
assert.argumentIsArray(a, 'a');
|
|
1741
|
+
assert.argumentIsRequired(keySelector, 'keySelector', Function);
|
|
1742
|
+
|
|
1743
|
+
return a.reduce(function (map, item) {
|
|
1744
|
+
var key = keySelector(item);
|
|
1745
|
+
|
|
1746
|
+
if (map.hasOwnProperty(key)) {
|
|
1747
|
+
throw new Error('Unable to index array. A duplicate key exists.');
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
map[key] = item;
|
|
1751
|
+
|
|
1752
|
+
return map;
|
|
1753
|
+
}, {});
|
|
1754
|
+
},
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
/**
|
|
1758
|
+
* Returns a new array containing all but the last item.
|
|
1759
|
+
*
|
|
1760
|
+
* @static
|
|
1761
|
+
* @param {Array} a
|
|
1762
|
+
* @returns {Array}
|
|
1763
|
+
*/
|
|
1764
|
+
dropRight: function dropRight(a) {
|
|
1765
|
+
assert.argumentIsArray(a, 'a');
|
|
1766
|
+
|
|
1767
|
+
var returnRef = Array.from(a);
|
|
1768
|
+
|
|
1769
|
+
if (returnRef.length !== 0) {
|
|
1770
|
+
returnRef.pop();
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
return returnRef;
|
|
1774
|
+
},
|
|
1775
|
+
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Returns the first item from an array, or an undefined value, if the
|
|
1779
|
+
* array is empty.
|
|
1780
|
+
*
|
|
1781
|
+
* @static
|
|
1782
|
+
* @param {Array} a
|
|
1783
|
+
* @returns {*|undefined}
|
|
1784
|
+
*/
|
|
1785
|
+
first: function first(a) {
|
|
1786
|
+
assert.argumentIsArray(a, 'a');
|
|
1787
|
+
|
|
1788
|
+
var returnRef = void 0;
|
|
1789
|
+
|
|
1790
|
+
if (a.length !== 0) {
|
|
1791
|
+
returnRef = a[0];
|
|
1792
|
+
} else {
|
|
1793
|
+
returnRef = undefined;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
return returnRef;
|
|
1797
|
+
},
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
/**
|
|
1801
|
+
* Returns the last item from an array, or an undefined value, if the
|
|
1802
|
+
* array is empty.
|
|
1803
|
+
*
|
|
1804
|
+
* @static
|
|
1805
|
+
* @param {Array} a
|
|
1806
|
+
* @returns {*|undefined}
|
|
1807
|
+
*/
|
|
1808
|
+
last: function last(a) {
|
|
1809
|
+
assert.argumentIsArray(a, 'a');
|
|
1810
|
+
|
|
1811
|
+
var returnRef = void 0;
|
|
1812
|
+
|
|
1813
|
+
if (a.length !== 0) {
|
|
1814
|
+
returnRef = a[a.length - 1];
|
|
1815
|
+
} else {
|
|
1816
|
+
returnRef = undefined;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
return returnRef;
|
|
1820
|
+
},
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
/**
|
|
1824
|
+
* Returns a copy of an array, replacing any item that is itself an array
|
|
1825
|
+
* with the item's items.
|
|
1826
|
+
*
|
|
1827
|
+
* @static
|
|
1828
|
+
* @param {Array} a
|
|
1829
|
+
* @param {Boolean=} recursive - If true, all nested arrays will be flattened.
|
|
1830
|
+
* @returns {Array}
|
|
1831
|
+
*/
|
|
1832
|
+
flatten: function flatten(a, recursive) {
|
|
1833
|
+
assert.argumentIsArray(a, 'a');
|
|
1834
|
+
assert.argumentIsOptional(recursive, 'recursive', Boolean);
|
|
1835
|
+
|
|
1836
|
+
var empty = [];
|
|
1837
|
+
|
|
1838
|
+
var flat = empty.concat.apply(empty, a);
|
|
1839
|
+
|
|
1840
|
+
if (recursive && flat.some(function (x) {
|
|
1841
|
+
return is.array(x);
|
|
1842
|
+
})) {
|
|
1843
|
+
flat = this.flatten(flat, true);
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
return flat;
|
|
1847
|
+
},
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
/**
|
|
1851
|
+
* Breaks an array into smaller arrays, returning an array of arrays.
|
|
1852
|
+
*
|
|
1853
|
+
* @static
|
|
1854
|
+
* @param {Array} a
|
|
1855
|
+
* @param {Number} size - The maximum number of items per partition.
|
|
1856
|
+
* @param {Array<Array>}
|
|
1857
|
+
*/
|
|
1858
|
+
partition: function partition(a, size) {
|
|
1859
|
+
assert.argumentIsArray(a, 'a');
|
|
1860
|
+
assert.argumentIsOptional(size, 'size', Number);
|
|
1861
|
+
|
|
1862
|
+
var copy = a.slice(0);
|
|
1863
|
+
var partitions = [];
|
|
1864
|
+
|
|
1865
|
+
while (copy.length !== 0) {
|
|
1866
|
+
partitions.push(copy.splice(0, size));
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
return partitions;
|
|
1870
|
+
},
|
|
1871
|
+
|
|
1872
|
+
|
|
1873
|
+
/**
|
|
1874
|
+
* Set difference operation (using strict equality).
|
|
1875
|
+
*
|
|
1876
|
+
* @static
|
|
1877
|
+
* @param {Array} a
|
|
1878
|
+
* @param {Array} b
|
|
1879
|
+
* @returns {Array}
|
|
1880
|
+
*/
|
|
1881
|
+
difference: function difference(a, b) {
|
|
1882
|
+
assert.argumentIsArray(a, 'a');
|
|
1883
|
+
assert.argumentIsArray(b, 'b');
|
|
1884
|
+
|
|
1885
|
+
var returnRef = [];
|
|
1886
|
+
|
|
1887
|
+
a.forEach(function (candidate) {
|
|
1888
|
+
var exclude = b.some(function (comparison) {
|
|
1889
|
+
return candidate === comparison;
|
|
1890
|
+
});
|
|
1891
|
+
|
|
1892
|
+
if (!exclude) {
|
|
1893
|
+
returnRef.push(candidate);
|
|
1894
|
+
}
|
|
1895
|
+
});
|
|
1896
|
+
|
|
1897
|
+
return returnRef;
|
|
1898
|
+
},
|
|
1899
|
+
|
|
1900
|
+
|
|
1901
|
+
/**
|
|
1902
|
+
* Set symmetric difference operation (using strict equality). In
|
|
1903
|
+
* other words, this is the union of the differences between the
|
|
1904
|
+
* sets.
|
|
1905
|
+
*
|
|
1906
|
+
* @static
|
|
1907
|
+
* @param {Array} a
|
|
1908
|
+
* @param {Array} b
|
|
1909
|
+
* @returns {Array}
|
|
1910
|
+
*/
|
|
1911
|
+
differenceSymmetric: function differenceSymmetric(a, b) {
|
|
1912
|
+
return this.union(this.difference(a, b), this.difference(b, a));
|
|
1913
|
+
},
|
|
1914
|
+
|
|
1915
|
+
|
|
1916
|
+
/**
|
|
1917
|
+
* Set union operation (using strict equality).
|
|
1918
|
+
*
|
|
1919
|
+
* @static
|
|
1920
|
+
* @param {Array} a
|
|
1921
|
+
* @param {Array} b
|
|
1922
|
+
* @returns {Array}
|
|
1923
|
+
*/
|
|
1924
|
+
union: function union(a, b) {
|
|
1925
|
+
assert.argumentIsArray(a, 'a');
|
|
1926
|
+
assert.argumentIsArray(b, 'b');
|
|
1927
|
+
|
|
1928
|
+
var returnRef = a.slice();
|
|
1929
|
+
|
|
1930
|
+
b.forEach(function (candidate) {
|
|
1931
|
+
var exclude = returnRef.some(function (comparison) {
|
|
1932
|
+
return candidate === comparison;
|
|
1933
|
+
});
|
|
1934
|
+
|
|
1935
|
+
if (!exclude) {
|
|
1936
|
+
returnRef.push(candidate);
|
|
1937
|
+
}
|
|
1938
|
+
});
|
|
1939
|
+
|
|
1940
|
+
return returnRef;
|
|
1941
|
+
},
|
|
1942
|
+
|
|
1943
|
+
|
|
1944
|
+
/**
|
|
1945
|
+
* Set intersection operation (using strict equality).
|
|
1946
|
+
*
|
|
1947
|
+
* @static
|
|
1948
|
+
* @param {Array} a
|
|
1949
|
+
* @param {Array} b
|
|
1950
|
+
* @returns {Array}
|
|
1951
|
+
*/
|
|
1952
|
+
intersection: function intersection(a, b) {
|
|
1953
|
+
assert.argumentIsArray(a, 'a');
|
|
1954
|
+
assert.argumentIsArray(b, 'b');
|
|
1955
|
+
|
|
1956
|
+
var returnRef = [];
|
|
1957
|
+
|
|
1958
|
+
a.forEach(function (candidate) {
|
|
1959
|
+
var include = b.some(function (comparison) {
|
|
1960
|
+
return candidate === comparison;
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
if (include) {
|
|
1964
|
+
returnRef.push(candidate);
|
|
1965
|
+
}
|
|
1966
|
+
});
|
|
1967
|
+
|
|
1968
|
+
return returnRef;
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
}();
|
|
1972
|
+
|
|
1973
|
+
},{"./assert":8,"./is":9}],8:[function(require,module,exports){
|
|
1974
|
+
'use strict';
|
|
1975
|
+
|
|
1976
|
+
var is = require('./is');
|
|
1977
|
+
|
|
1978
|
+
module.exports = function () {
|
|
1979
|
+
'use strict';
|
|
1980
|
+
|
|
1981
|
+
function checkArgumentType(variable, variableName, type, typeDescription, index) {
|
|
1982
|
+
if (type === String) {
|
|
1983
|
+
if (!is.string(variable)) {
|
|
1984
|
+
throwInvalidTypeError(variableName, 'string', index);
|
|
1985
|
+
}
|
|
1986
|
+
} else if (type === Number) {
|
|
1987
|
+
if (!is.number(variable)) {
|
|
1988
|
+
throwInvalidTypeError(variableName, 'number', index);
|
|
1989
|
+
}
|
|
1990
|
+
} else if (type === Function) {
|
|
1991
|
+
if (!is.fn(variable)) {
|
|
1992
|
+
throwInvalidTypeError(variableName, 'function', index);
|
|
1993
|
+
}
|
|
1994
|
+
} else if (type === Boolean) {
|
|
1995
|
+
if (!is.boolean(variable)) {
|
|
1996
|
+
throwInvalidTypeError(variableName, 'boolean', index);
|
|
1997
|
+
}
|
|
1998
|
+
} else if (type === Date) {
|
|
1999
|
+
if (!is.date(variable)) {
|
|
2000
|
+
throwInvalidTypeError(variableName, 'date', index);
|
|
2001
|
+
}
|
|
2002
|
+
} else if (type === Array) {
|
|
2003
|
+
if (!is.array(variable)) {
|
|
2004
|
+
throwInvalidTypeError(variableName, 'array', index);
|
|
2005
|
+
}
|
|
2006
|
+
} else if (!(variable instanceof (type || Object))) {
|
|
2007
|
+
throwInvalidTypeError(variableName, typeDescription, index);
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
function throwInvalidTypeError(variableName, typeDescription, index) {
|
|
2012
|
+
var message = void 0;
|
|
2013
|
+
|
|
2014
|
+
if (typeof index === 'number') {
|
|
2015
|
+
message = 'The argument [ ' + (variableName || 'unspecified') + ' ], at index [ ' + index.toString() + ' ] must be a [ ' + (typeDescription || 'unknown') + ' ]';
|
|
2016
|
+
} else {
|
|
2017
|
+
message = 'The argument [ ' + (variableName || 'unspecified') + ' ] must be a [ ' + (typeDescription || 'Object') + ' ]';
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
throw new Error(message);
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
function throwCustomValidationError(variableName, predicateDescription) {
|
|
2024
|
+
throw new Error('The argument [ ' + (variableName || 'unspecified') + ' ] failed a validation check [ ' + (predicateDescription || 'No description available') + ' ]');
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
/**
|
|
2028
|
+
* Utilities checking arguments.
|
|
2029
|
+
*
|
|
2030
|
+
* @public
|
|
2031
|
+
* @module lang/assert
|
|
2032
|
+
*/
|
|
2033
|
+
return {
|
|
2034
|
+
/**
|
|
2035
|
+
* Throws an error if an argument doesn't conform to the desired specification (as
|
|
2036
|
+
* determined by a type check).
|
|
2037
|
+
*
|
|
2038
|
+
* @static
|
|
2039
|
+
* @param {*} variable - The value to check.
|
|
2040
|
+
* @param {String} variableName - The name of the value (used for formatting an error message).
|
|
2041
|
+
* @param {*} type - The expected type of the argument.
|
|
2042
|
+
* @param {String=} typeDescription - The description of the expected type (used for formatting an error message).
|
|
2043
|
+
*/
|
|
2044
|
+
argumentIsRequired: function argumentIsRequired(variable, variableName, type, typeDescription) {
|
|
2045
|
+
checkArgumentType(variable, variableName, type, typeDescription);
|
|
2046
|
+
},
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
/**
|
|
2050
|
+
* A relaxed version of the "argumentIsRequired" function that will not throw if
|
|
2051
|
+
* the value is undefined or null.
|
|
2052
|
+
*
|
|
2053
|
+
* @static
|
|
2054
|
+
* @param {*} variable - The value to check.
|
|
2055
|
+
* @param {String} variableName - The name of the value (used for formatting an error message).
|
|
2056
|
+
* @param {*} type - The expected type of the argument.
|
|
2057
|
+
* @param {String=} typeDescription - The description of the expected type (used for formatting an error message).
|
|
2058
|
+
*/
|
|
2059
|
+
argumentIsOptional: function argumentIsOptional(variable, variableName, type, typeDescription, predicate, predicateDescription) {
|
|
2060
|
+
if (variable === null || variable === undefined) {
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
checkArgumentType(variable, variableName, type, typeDescription);
|
|
2065
|
+
|
|
2066
|
+
if (is.fn(predicate) && !predicate(variable)) {
|
|
2067
|
+
throwCustomValidationError(variableName, predicateDescription);
|
|
2068
|
+
}
|
|
2069
|
+
},
|
|
2070
|
+
argumentIsArray: function argumentIsArray(variable, variableName, itemConstraint, itemConstraintDescription) {
|
|
2071
|
+
this.argumentIsRequired(variable, variableName, Array);
|
|
2072
|
+
|
|
2073
|
+
if (itemConstraint) {
|
|
2074
|
+
var itemValidator = void 0;
|
|
2075
|
+
|
|
2076
|
+
if (typeof itemConstraint === 'function' && itemConstraint !== Function) {
|
|
2077
|
+
itemValidator = function itemValidator(value, index) {
|
|
2078
|
+
return value instanceof itemConstraint || itemConstraint(value, variableName + '[' + index + ']');
|
|
2079
|
+
};
|
|
2080
|
+
} else {
|
|
2081
|
+
itemValidator = function itemValidator(value, index) {
|
|
2082
|
+
return checkArgumentType(value, variableName, itemConstraint, itemConstraintDescription, index);
|
|
2083
|
+
};
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
variable.forEach(function (v, i) {
|
|
2087
|
+
itemValidator(v, i);
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
},
|
|
2091
|
+
|
|
2092
|
+
|
|
2093
|
+
/**
|
|
2094
|
+
* Throws an error if an argument doesn't conform to the desired specification
|
|
2095
|
+
* (as determined by a predicate).
|
|
2096
|
+
*
|
|
2097
|
+
* @static
|
|
2098
|
+
* @param {*} variable - The value to check.
|
|
2099
|
+
* @param {String} variableName - The name of the value (used for formatting an error message).
|
|
2100
|
+
* @param {Function=} predicate - A function used to validate the item (beyond type checking).
|
|
2101
|
+
* @param {String=} predicateDescription - A description of the assertion made by the predicate (e.g. "is an integer") that is used for formatting an error message.
|
|
2102
|
+
*/
|
|
2103
|
+
argumentIsValid: function argumentIsValid(variable, variableName, predicate, predicateDescription) {
|
|
2104
|
+
if (!predicate(variable)) {
|
|
2105
|
+
throwCustomValidationError(variableName, predicateDescription);
|
|
2106
|
+
}
|
|
2107
|
+
},
|
|
2108
|
+
areEqual: function areEqual(a, b, descriptionA, descriptionB) {
|
|
2109
|
+
if (a !== b) {
|
|
2110
|
+
throw new Error('The objects must be equal [' + (descriptionA || a.toString()) + '] and [' + (descriptionB || b.toString()) + ']');
|
|
2111
|
+
}
|
|
2112
|
+
},
|
|
2113
|
+
areNotEqual: function areNotEqual(a, b, descriptionA, descriptionB) {
|
|
2114
|
+
if (a === b) {
|
|
2115
|
+
throw new Error('The objects cannot be equal [' + (descriptionA || a.toString()) + '] and [' + (descriptionB || b.toString()) + ']');
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
};
|
|
2119
|
+
}();
|
|
2120
|
+
|
|
2121
|
+
},{"./is":9}],9:[function(require,module,exports){
|
|
2122
|
+
'use strict';
|
|
2123
|
+
|
|
2124
|
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
2125
|
+
|
|
2126
|
+
module.exports = function () {
|
|
2127
|
+
'use strict';
|
|
2128
|
+
|
|
2129
|
+
/**
|
|
2130
|
+
* Utilities for interrogating variables (e.g. checking data types).
|
|
2131
|
+
*
|
|
2132
|
+
* @public
|
|
2133
|
+
* @module lang/is
|
|
2134
|
+
*/
|
|
2135
|
+
|
|
2136
|
+
return {
|
|
2137
|
+
/**
|
|
2138
|
+
* Returns true, if the argument is a number. NaN will return false.
|
|
2139
|
+
*
|
|
2140
|
+
* @static
|
|
2141
|
+
* @public
|
|
2142
|
+
* @param candidate {*}
|
|
2143
|
+
* @returns {boolean}
|
|
2144
|
+
*/
|
|
2145
|
+
number: function number(candidate) {
|
|
2146
|
+
return typeof candidate === 'number' && !isNaN(candidate);
|
|
2147
|
+
},
|
|
2148
|
+
|
|
2149
|
+
|
|
2150
|
+
/**
|
|
2151
|
+
* Returns true, if the argument is NaN.
|
|
2152
|
+
*
|
|
2153
|
+
* @static
|
|
2154
|
+
* @public
|
|
2155
|
+
* @param {*} candidate
|
|
2156
|
+
* @returns {boolean}
|
|
2157
|
+
*/
|
|
2158
|
+
nan: function nan(candidate) {
|
|
2159
|
+
return typeof candidate === 'number' && isNaN(candidate);
|
|
2160
|
+
},
|
|
2161
|
+
|
|
2162
|
+
|
|
2163
|
+
/**
|
|
2164
|
+
* Returns true, if the argument is a valid 32-bit integer.
|
|
2165
|
+
*
|
|
2166
|
+
* @static
|
|
2167
|
+
* @public
|
|
2168
|
+
* @param {*} candidate
|
|
2169
|
+
* @returns {boolean}
|
|
2170
|
+
*/
|
|
2171
|
+
integer: function integer(candidate) {
|
|
2172
|
+
return typeof candidate === 'number' && !isNaN(candidate) && (candidate | 0) === candidate;
|
|
2173
|
+
},
|
|
2174
|
+
|
|
2175
|
+
|
|
2176
|
+
/**
|
|
2177
|
+
* Returns true, if the argument is a valid integer (which can exceed 32 bits); however,
|
|
2178
|
+
* the check can fail above the value of Number.MAX_SAFE_INTEGER.
|
|
2179
|
+
*
|
|
2180
|
+
* @static
|
|
2181
|
+
* @public
|
|
2182
|
+
* @param {*) candidate
|
|
2183
|
+
* @returns {boolean}
|
|
2184
|
+
*/
|
|
2185
|
+
large: function large(candidate) {
|
|
2186
|
+
return typeof candidate === 'number' && !isNaN(candidate) && isFinite(candidate) && Math.floor(candidate) === candidate;
|
|
2187
|
+
},
|
|
2188
|
+
|
|
2189
|
+
|
|
2190
|
+
/**
|
|
2191
|
+
* Returns true, if the argument is a number that is positive.
|
|
2192
|
+
*
|
|
2193
|
+
* @static
|
|
2194
|
+
* @public
|
|
2195
|
+
* @param candidate
|
|
2196
|
+
* @returns {boolean}
|
|
2197
|
+
*/
|
|
2198
|
+
positive: function positive(candidate) {
|
|
2199
|
+
return this.number(candidate) && candidate > 0;
|
|
2200
|
+
},
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
/**
|
|
2204
|
+
* Returns true, if the argument is a number that is negative.
|
|
2205
|
+
*
|
|
2206
|
+
* @static
|
|
2207
|
+
* @public
|
|
2208
|
+
* @param candidate
|
|
2209
|
+
* @returns {*|boolean}
|
|
2210
|
+
*/
|
|
2211
|
+
negative: function negative(candidate) {
|
|
2212
|
+
return this.number(candidate) && candidate < 0;
|
|
2213
|
+
},
|
|
2214
|
+
|
|
2215
|
+
|
|
2216
|
+
/**
|
|
2217
|
+
* Returns true, if the argument is a string.
|
|
2218
|
+
*
|
|
2219
|
+
* @static
|
|
2220
|
+
* @public
|
|
2221
|
+
* @param candidate
|
|
2222
|
+
* @returns {boolean}
|
|
2223
|
+
*/
|
|
2224
|
+
string: function string(candidate) {
|
|
2225
|
+
return typeof candidate === 'string';
|
|
2226
|
+
},
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
/**
|
|
2230
|
+
* Returns true, if the argument is a JavaScript Date instance.
|
|
2231
|
+
*
|
|
2232
|
+
* @static
|
|
2233
|
+
* @public
|
|
2234
|
+
* @param candidate
|
|
2235
|
+
* @returns {boolean}
|
|
2236
|
+
*/
|
|
2237
|
+
date: function date(candidate) {
|
|
2238
|
+
return candidate instanceof Date;
|
|
2239
|
+
},
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
/**
|
|
2243
|
+
* Returns true, if the argument is a function.
|
|
2244
|
+
*
|
|
2245
|
+
* @static
|
|
2246
|
+
* @public
|
|
2247
|
+
* @param candidate
|
|
2248
|
+
* @returns {boolean}
|
|
2249
|
+
*/
|
|
2250
|
+
fn: function fn(candidate) {
|
|
2251
|
+
return typeof candidate === 'function';
|
|
2252
|
+
},
|
|
2253
|
+
|
|
2254
|
+
|
|
2255
|
+
/**
|
|
2256
|
+
* Returns true, if the argument is an array.
|
|
2257
|
+
*
|
|
2258
|
+
* @static
|
|
2259
|
+
* @public
|
|
2260
|
+
* @param candidate
|
|
2261
|
+
* @returns {boolean}
|
|
2262
|
+
*/
|
|
2263
|
+
array: function array(candidate) {
|
|
2264
|
+
return Array.isArray(candidate);
|
|
2265
|
+
},
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
/**
|
|
2269
|
+
* Returns true, if the argument is a Boolean value.
|
|
2270
|
+
*
|
|
2271
|
+
* @static
|
|
2272
|
+
* @public
|
|
2273
|
+
* @param candidate
|
|
2274
|
+
* @returns {boolean}
|
|
2275
|
+
*/
|
|
2276
|
+
boolean: function boolean(candidate) {
|
|
2277
|
+
return typeof candidate === 'boolean';
|
|
2278
|
+
},
|
|
2279
|
+
|
|
2280
|
+
|
|
2281
|
+
/**
|
|
2282
|
+
* Returns true, if the argument is an object.
|
|
2283
|
+
*
|
|
2284
|
+
* @static
|
|
2285
|
+
* @public
|
|
2286
|
+
* @param candidate
|
|
2287
|
+
* @returns {boolean}
|
|
2288
|
+
*/
|
|
2289
|
+
object: function object(candidate) {
|
|
2290
|
+
return (typeof candidate === 'undefined' ? 'undefined' : _typeof(candidate)) === 'object' && candidate !== null;
|
|
2291
|
+
},
|
|
2292
|
+
|
|
2293
|
+
|
|
2294
|
+
/**
|
|
2295
|
+
* Returns true, if the argument is a null value.
|
|
2296
|
+
*
|
|
2297
|
+
* @static
|
|
2298
|
+
* @public
|
|
2299
|
+
* @param candidate
|
|
2300
|
+
* @returns {boolean}
|
|
2301
|
+
*/
|
|
2302
|
+
null: function _null(candidate) {
|
|
2303
|
+
return candidate === null;
|
|
2304
|
+
},
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
/**
|
|
2308
|
+
* Returns true, if the argument is an undefined value.
|
|
2309
|
+
*
|
|
2310
|
+
* @static
|
|
2311
|
+
* @public
|
|
2312
|
+
* @param candidate
|
|
2313
|
+
* @returns {boolean}
|
|
2314
|
+
*/
|
|
2315
|
+
undefined: function (_undefined) {
|
|
2316
|
+
function undefined(_x) {
|
|
2317
|
+
return _undefined.apply(this, arguments);
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
undefined.toString = function () {
|
|
2321
|
+
return _undefined.toString();
|
|
2322
|
+
};
|
|
2323
|
+
|
|
2324
|
+
return undefined;
|
|
2325
|
+
}(function (candidate) {
|
|
2326
|
+
return candidate === undefined;
|
|
2327
|
+
}),
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
/**
|
|
2331
|
+
* Given two classes, determines if the "child" class extends
|
|
2332
|
+
* the "parent" class (without instantiation).
|
|
2333
|
+
*
|
|
2334
|
+
* @param {Function} parent
|
|
2335
|
+
* @param {Function} child
|
|
2336
|
+
* @returns {Boolean}
|
|
2337
|
+
*/
|
|
2338
|
+
extension: function extension(parent, child) {
|
|
2339
|
+
return this.fn(parent) && this.fn(child) && child.prototype instanceof parent;
|
|
2340
|
+
}
|
|
2341
|
+
};
|
|
2342
|
+
}();
|
|
2343
|
+
|
|
2344
|
+
},{}],10:[function(require,module,exports){
|
|
2345
|
+
/*
|
|
2346
|
+
* big.js v5.0.3
|
|
2347
|
+
* A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
|
|
2348
|
+
* Copyright (c) 2017 Michael Mclaughlin <M8ch88l@gmail.com>
|
|
2349
|
+
* https://github.com/MikeMcl/big.js/LICENCE
|
|
2350
|
+
*/
|
|
2351
|
+
;(function (GLOBAL) {
|
|
2352
|
+
'use strict';
|
|
2353
|
+
var Big,
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
/************************************** EDITABLE DEFAULTS *****************************************/
|
|
2357
|
+
|
|
2358
|
+
|
|
2359
|
+
// The default values below must be integers within the stated ranges.
|
|
2360
|
+
|
|
2361
|
+
/*
|
|
2362
|
+
* The maximum number of decimal places (DP) of the results of operations involving division:
|
|
2363
|
+
* div and sqrt, and pow with negative exponents.
|
|
2364
|
+
*/
|
|
2365
|
+
DP = 20, // 0 to MAX_DP
|
|
2366
|
+
|
|
2367
|
+
/*
|
|
2368
|
+
* The rounding mode (RM) used when rounding to the above decimal places.
|
|
2369
|
+
*
|
|
2370
|
+
* 0 Towards zero (i.e. truncate, no rounding). (ROUND_DOWN)
|
|
2371
|
+
* 1 To nearest neighbour. If equidistant, round up. (ROUND_HALF_UP)
|
|
2372
|
+
* 2 To nearest neighbour. If equidistant, to even. (ROUND_HALF_EVEN)
|
|
2373
|
+
* 3 Away from zero. (ROUND_UP)
|
|
2374
|
+
*/
|
|
2375
|
+
RM = 1, // 0, 1, 2 or 3
|
|
2376
|
+
|
|
2377
|
+
// The maximum value of DP and Big.DP.
|
|
2378
|
+
MAX_DP = 1E6, // 0 to 1000000
|
|
2379
|
+
|
|
2380
|
+
// The maximum magnitude of the exponent argument to the pow method.
|
|
2381
|
+
MAX_POWER = 1E6, // 1 to 1000000
|
|
2382
|
+
|
|
2383
|
+
/*
|
|
2384
|
+
* The negative exponent (NE) at and beneath which toString returns exponential notation.
|
|
2385
|
+
* (JavaScript numbers: -7)
|
|
2386
|
+
* -1000000 is the minimum recommended exponent value of a Big.
|
|
2387
|
+
*/
|
|
2388
|
+
NE = -7, // 0 to -1000000
|
|
2389
|
+
|
|
2390
|
+
/*
|
|
2391
|
+
* The positive exponent (PE) at and above which toString returns exponential notation.
|
|
2392
|
+
* (JavaScript numbers: 21)
|
|
2393
|
+
* 1000000 is the maximum recommended exponent value of a Big.
|
|
2394
|
+
* (This limit is not enforced or checked.)
|
|
2395
|
+
*/
|
|
2396
|
+
PE = 21, // 0 to 1000000
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
/**************************************************************************************************/
|
|
2400
|
+
|
|
2401
|
+
|
|
2402
|
+
// Error messages.
|
|
2403
|
+
NAME = '[big.js] ',
|
|
2404
|
+
INVALID = NAME + 'Invalid ',
|
|
2405
|
+
INVALID_DP = INVALID + 'decimal places',
|
|
2406
|
+
INVALID_RM = INVALID + 'rounding mode',
|
|
2407
|
+
DIV_BY_ZERO = NAME + 'Division by zero',
|
|
2408
|
+
|
|
2409
|
+
// The shared prototype object.
|
|
2410
|
+
P = {},
|
|
2411
|
+
UNDEFINED = void 0,
|
|
2412
|
+
NUMERIC = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;
|
|
2413
|
+
|
|
2414
|
+
|
|
2415
|
+
/*
|
|
2416
|
+
* Create and return a Big constructor.
|
|
2417
|
+
*
|
|
2418
|
+
*/
|
|
2419
|
+
function _Big_() {
|
|
2420
|
+
|
|
2421
|
+
/*
|
|
2422
|
+
* The Big constructor and exported function.
|
|
2423
|
+
* Create and return a new instance of a Big number object.
|
|
2424
|
+
*
|
|
2425
|
+
* n {number|string|Big} A numeric value.
|
|
2426
|
+
*/
|
|
2427
|
+
function Big(n) {
|
|
2428
|
+
var x = this;
|
|
2429
|
+
|
|
2430
|
+
// Enable constructor usage without new.
|
|
2431
|
+
if (!(x instanceof Big)) return n === UNDEFINED ? _Big_() : new Big(n);
|
|
2432
|
+
|
|
2433
|
+
// Duplicate.
|
|
2434
|
+
if (n instanceof Big) {
|
|
2435
|
+
x.s = n.s;
|
|
2436
|
+
x.e = n.e;
|
|
2437
|
+
x.c = n.c.slice();
|
|
2438
|
+
} else {
|
|
2439
|
+
parse(x, n);
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
/*
|
|
2443
|
+
* Retain a reference to this Big constructor, and shadow Big.prototype.constructor which
|
|
2444
|
+
* points to Object.
|
|
2445
|
+
*/
|
|
2446
|
+
x.constructor = Big;
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
Big.prototype = P;
|
|
2450
|
+
Big.DP = DP;
|
|
2451
|
+
Big.RM = RM;
|
|
2452
|
+
Big.NE = NE;
|
|
2453
|
+
Big.PE = PE;
|
|
2454
|
+
Big.version = '5.0.2';
|
|
2455
|
+
|
|
2456
|
+
return Big;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
|
|
2460
|
+
/*
|
|
2461
|
+
* Parse the number or string value passed to a Big constructor.
|
|
2462
|
+
*
|
|
2463
|
+
* x {Big} A Big number instance.
|
|
2464
|
+
* n {number|string} A numeric value.
|
|
2465
|
+
*/
|
|
2466
|
+
function parse(x, n) {
|
|
2467
|
+
var e, i, nl;
|
|
2468
|
+
|
|
2469
|
+
// Minus zero?
|
|
2470
|
+
if (n === 0 && 1 / n < 0) n = '-0';
|
|
2471
|
+
else if (!NUMERIC.test(n += '')) throw Error(INVALID + 'number');
|
|
2472
|
+
|
|
2473
|
+
// Determine sign.
|
|
2474
|
+
x.s = n.charAt(0) == '-' ? (n = n.slice(1), -1) : 1;
|
|
2475
|
+
|
|
2476
|
+
// Decimal point?
|
|
2477
|
+
if ((e = n.indexOf('.')) > -1) n = n.replace('.', '');
|
|
2478
|
+
|
|
2479
|
+
// Exponential form?
|
|
2480
|
+
if ((i = n.search(/e/i)) > 0) {
|
|
2481
|
+
|
|
2482
|
+
// Determine exponent.
|
|
2483
|
+
if (e < 0) e = i;
|
|
2484
|
+
e += +n.slice(i + 1);
|
|
2485
|
+
n = n.substring(0, i);
|
|
2486
|
+
} else if (e < 0) {
|
|
2487
|
+
|
|
2488
|
+
// Integer.
|
|
2489
|
+
e = n.length;
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
nl = n.length;
|
|
2493
|
+
|
|
2494
|
+
// Determine leading zeros.
|
|
2495
|
+
for (i = 0; i < nl && n.charAt(i) == '0';) ++i;
|
|
2496
|
+
|
|
2497
|
+
if (i == nl) {
|
|
2498
|
+
|
|
2499
|
+
// Zero.
|
|
2500
|
+
x.c = [x.e = 0];
|
|
2501
|
+
} else {
|
|
2502
|
+
|
|
2503
|
+
// Determine trailing zeros.
|
|
2504
|
+
for (; nl > 0 && n.charAt(--nl) == '0';);
|
|
2505
|
+
x.e = e - i - 1;
|
|
2506
|
+
x.c = [];
|
|
2507
|
+
|
|
2508
|
+
// Convert string to array of digits without leading/trailing zeros.
|
|
2509
|
+
for (e = 0; i <= nl;) x.c[e++] = +n.charAt(i++);
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
return x;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
|
|
2516
|
+
/*
|
|
2517
|
+
* Round Big x to a maximum of dp decimal places using rounding mode rm.
|
|
2518
|
+
* Called by stringify, P.div, P.round and P.sqrt.
|
|
2519
|
+
*
|
|
2520
|
+
* x {Big} The Big to round.
|
|
2521
|
+
* dp {number} Integer, 0 to MAX_DP inclusive.
|
|
2522
|
+
* rm {number} 0, 1, 2 or 3 (DOWN, HALF_UP, HALF_EVEN, UP)
|
|
2523
|
+
* [more] {boolean} Whether the result of division was truncated.
|
|
2524
|
+
*/
|
|
2525
|
+
function round(x, dp, rm, more) {
|
|
2526
|
+
var xc = x.c,
|
|
2527
|
+
i = x.e + dp + 1;
|
|
2528
|
+
|
|
2529
|
+
if (i < xc.length) {
|
|
2530
|
+
if (rm === 1) {
|
|
2531
|
+
|
|
2532
|
+
// xc[i] is the digit after the digit that may be rounded up.
|
|
2533
|
+
more = xc[i] >= 5;
|
|
2534
|
+
} else if (rm === 2) {
|
|
2535
|
+
more = xc[i] > 5 || xc[i] == 5 &&
|
|
2536
|
+
(more || i < 0 || xc[i + 1] !== UNDEFINED || xc[i - 1] & 1);
|
|
2537
|
+
} else if (rm === 3) {
|
|
2538
|
+
more = more || xc[i] !== UNDEFINED || i < 0;
|
|
2539
|
+
} else {
|
|
2540
|
+
more = false;
|
|
2541
|
+
if (rm !== 0) throw Error(INVALID_RM);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
if (i < 1) {
|
|
2545
|
+
xc.length = 1;
|
|
2546
|
+
|
|
2547
|
+
if (more) {
|
|
2548
|
+
|
|
2549
|
+
// 1, 0.1, 0.01, 0.001, 0.0001 etc.
|
|
2550
|
+
x.e = -dp;
|
|
2551
|
+
xc[0] = 1;
|
|
2552
|
+
} else {
|
|
2553
|
+
|
|
2554
|
+
// Zero.
|
|
2555
|
+
xc[0] = x.e = 0;
|
|
2556
|
+
}
|
|
2557
|
+
} else {
|
|
2558
|
+
|
|
2559
|
+
// Remove any digits after the required decimal places.
|
|
2560
|
+
xc.length = i--;
|
|
2561
|
+
|
|
2562
|
+
// Round up?
|
|
2563
|
+
if (more) {
|
|
2564
|
+
|
|
2565
|
+
// Rounding up may mean the previous digit has to be rounded up.
|
|
2566
|
+
for (; ++xc[i] > 9;) {
|
|
2567
|
+
xc[i] = 0;
|
|
2568
|
+
if (!i--) {
|
|
2569
|
+
++x.e;
|
|
2570
|
+
xc.unshift(1);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
// Remove trailing zeros.
|
|
2576
|
+
for (i = xc.length; !xc[--i];) xc.pop();
|
|
2577
|
+
}
|
|
2578
|
+
} else if (rm < 0 || rm > 3 || rm !== ~~rm) {
|
|
2579
|
+
throw Error(INVALID_RM);
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
return x;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
|
|
2586
|
+
/*
|
|
2587
|
+
* Return a string representing the value of Big x in normal or exponential notation.
|
|
2588
|
+
* Handles P.toExponential, P.toFixed, P.toJSON, P.toPrecision, P.toString and P.valueOf.
|
|
2589
|
+
*
|
|
2590
|
+
* x {Big}
|
|
2591
|
+
* id? {number} Caller id.
|
|
2592
|
+
* 1 toExponential
|
|
2593
|
+
* 2 toFixed
|
|
2594
|
+
* 3 toPrecision
|
|
2595
|
+
* 4 valueOf
|
|
2596
|
+
* n? {number|undefined} Caller's argument.
|
|
2597
|
+
* k? {number|undefined}
|
|
2598
|
+
*/
|
|
2599
|
+
function stringify(x, id, n, k) {
|
|
2600
|
+
var e, s,
|
|
2601
|
+
Big = x.constructor,
|
|
2602
|
+
z = !x.c[0];
|
|
2603
|
+
|
|
2604
|
+
if (n !== UNDEFINED) {
|
|
2605
|
+
if (n !== ~~n || n < (id == 3) || n > MAX_DP) {
|
|
2606
|
+
throw Error(id == 3 ? INVALID + 'precision' : INVALID_DP);
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
x = new Big(x);
|
|
2610
|
+
|
|
2611
|
+
// The index of the digit that may be rounded up.
|
|
2612
|
+
n = k - x.e;
|
|
2613
|
+
|
|
2614
|
+
// Round?
|
|
2615
|
+
if (x.c.length > ++k) round(x, n, Big.RM);
|
|
2616
|
+
|
|
2617
|
+
// toFixed: recalculate k as x.e may have changed if value rounded up.
|
|
2618
|
+
if (id == 2) k = x.e + n + 1;
|
|
2619
|
+
|
|
2620
|
+
// Append zeros?
|
|
2621
|
+
for (; x.c.length < k;) x.c.push(0);
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
e = x.e;
|
|
2625
|
+
s = x.c.join('');
|
|
2626
|
+
n = s.length;
|
|
2627
|
+
|
|
2628
|
+
// Exponential notation?
|
|
2629
|
+
if (id != 2 && (id == 1 || id == 3 && k <= e || e <= Big.NE || e >= Big.PE)) {
|
|
2630
|
+
s = s.charAt(0) + (n > 1 ? '.' + s.slice(1) : '') + (e < 0 ? 'e' : 'e+') + e;
|
|
2631
|
+
|
|
2632
|
+
// Normal notation.
|
|
2633
|
+
} else if (e < 0) {
|
|
2634
|
+
for (; ++e;) s = '0' + s;
|
|
2635
|
+
s = '0.' + s;
|
|
2636
|
+
} else if (e > 0) {
|
|
2637
|
+
if (++e > n) for (e -= n; e--;) s += '0';
|
|
2638
|
+
else if (e < n) s = s.slice(0, e) + '.' + s.slice(e);
|
|
2639
|
+
} else if (n > 1) {
|
|
2640
|
+
s = s.charAt(0) + '.' + s.slice(1);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
return x.s < 0 && (!z || id == 4) ? '-' + s : s;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
|
|
2647
|
+
// Prototype/instance methods
|
|
2648
|
+
|
|
2649
|
+
|
|
2650
|
+
/*
|
|
2651
|
+
* Return a new Big whose value is the absolute value of this Big.
|
|
2652
|
+
*/
|
|
2653
|
+
P.abs = function () {
|
|
2654
|
+
var x = new this.constructor(this);
|
|
2655
|
+
x.s = 1;
|
|
2656
|
+
return x;
|
|
2657
|
+
};
|
|
2658
|
+
|
|
2659
|
+
|
|
2660
|
+
/*
|
|
2661
|
+
* Return 1 if the value of this Big is greater than the value of Big y,
|
|
2662
|
+
* -1 if the value of this Big is less than the value of Big y, or
|
|
2663
|
+
* 0 if they have the same value.
|
|
2664
|
+
*/
|
|
2665
|
+
P.cmp = function (y) {
|
|
2666
|
+
var isneg,
|
|
2667
|
+
x = this,
|
|
2668
|
+
xc = x.c,
|
|
2669
|
+
yc = (y = new x.constructor(y)).c,
|
|
2670
|
+
i = x.s,
|
|
2671
|
+
j = y.s,
|
|
2672
|
+
k = x.e,
|
|
2673
|
+
l = y.e;
|
|
2674
|
+
|
|
2675
|
+
// Either zero?
|
|
2676
|
+
if (!xc[0] || !yc[0]) return !xc[0] ? !yc[0] ? 0 : -j : i;
|
|
2677
|
+
|
|
2678
|
+
// Signs differ?
|
|
2679
|
+
if (i != j) return i;
|
|
2680
|
+
|
|
2681
|
+
isneg = i < 0;
|
|
2682
|
+
|
|
2683
|
+
// Compare exponents.
|
|
2684
|
+
if (k != l) return k > l ^ isneg ? 1 : -1;
|
|
2685
|
+
|
|
2686
|
+
j = (k = xc.length) < (l = yc.length) ? k : l;
|
|
2687
|
+
|
|
2688
|
+
// Compare digit by digit.
|
|
2689
|
+
for (i = -1; ++i < j;) {
|
|
2690
|
+
if (xc[i] != yc[i]) return xc[i] > yc[i] ^ isneg ? 1 : -1;
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2693
|
+
// Compare lengths.
|
|
2694
|
+
return k == l ? 0 : k > l ^ isneg ? 1 : -1;
|
|
2695
|
+
};
|
|
2696
|
+
|
|
2697
|
+
|
|
2698
|
+
/*
|
|
2699
|
+
* Return a new Big whose value is the value of this Big divided by the value of Big y, rounded,
|
|
2700
|
+
* if necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM.
|
|
2701
|
+
*/
|
|
2702
|
+
P.div = function (y) {
|
|
2703
|
+
var x = this,
|
|
2704
|
+
Big = x.constructor,
|
|
2705
|
+
a = x.c, // dividend
|
|
2706
|
+
b = (y = new Big(y)).c, // divisor
|
|
2707
|
+
k = x.s == y.s ? 1 : -1,
|
|
2708
|
+
dp = Big.DP;
|
|
2709
|
+
|
|
2710
|
+
if (dp !== ~~dp || dp < 0 || dp > MAX_DP) throw Error(INVALID_DP);
|
|
2711
|
+
|
|
2712
|
+
// Divisor is zero?
|
|
2713
|
+
if (!b[0]) throw Error(DIV_BY_ZERO);
|
|
2714
|
+
|
|
2715
|
+
// Dividend is 0? Return +-0.
|
|
2716
|
+
if (!a[0]) return new Big(k * 0);
|
|
2717
|
+
|
|
2718
|
+
var bl, bt, n, cmp, ri,
|
|
2719
|
+
bz = b.slice(),
|
|
2720
|
+
ai = bl = b.length,
|
|
2721
|
+
al = a.length,
|
|
2722
|
+
r = a.slice(0, bl), // remainder
|
|
2723
|
+
rl = r.length,
|
|
2724
|
+
q = y, // quotient
|
|
2725
|
+
qc = q.c = [],
|
|
2726
|
+
qi = 0,
|
|
2727
|
+
d = dp + (q.e = x.e - y.e) + 1; // number of digits of the result
|
|
2728
|
+
|
|
2729
|
+
q.s = k;
|
|
2730
|
+
k = d < 0 ? 0 : d;
|
|
2731
|
+
|
|
2732
|
+
// Create version of divisor with leading zero.
|
|
2733
|
+
bz.unshift(0);
|
|
2734
|
+
|
|
2735
|
+
// Add zeros to make remainder as long as divisor.
|
|
2736
|
+
for (; rl++ < bl;) r.push(0);
|
|
2737
|
+
|
|
2738
|
+
do {
|
|
2739
|
+
|
|
2740
|
+
// n is how many times the divisor goes into current remainder.
|
|
2741
|
+
for (n = 0; n < 10; n++) {
|
|
2742
|
+
|
|
2743
|
+
// Compare divisor and remainder.
|
|
2744
|
+
if (bl != (rl = r.length)) {
|
|
2745
|
+
cmp = bl > rl ? 1 : -1;
|
|
2746
|
+
} else {
|
|
2747
|
+
for (ri = -1, cmp = 0; ++ri < bl;) {
|
|
2748
|
+
if (b[ri] != r[ri]) {
|
|
2749
|
+
cmp = b[ri] > r[ri] ? 1 : -1;
|
|
2750
|
+
break;
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
// If divisor < remainder, subtract divisor from remainder.
|
|
2756
|
+
if (cmp < 0) {
|
|
2757
|
+
|
|
2758
|
+
// Remainder can't be more than 1 digit longer than divisor.
|
|
2759
|
+
// Equalise lengths using divisor with extra leading zero?
|
|
2760
|
+
for (bt = rl == bl ? b : bz; rl;) {
|
|
2761
|
+
if (r[--rl] < bt[rl]) {
|
|
2762
|
+
ri = rl;
|
|
2763
|
+
for (; ri && !r[--ri];) r[ri] = 9;
|
|
2764
|
+
--r[ri];
|
|
2765
|
+
r[rl] += 10;
|
|
2766
|
+
}
|
|
2767
|
+
r[rl] -= bt[rl];
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
for (; !r[0];) r.shift();
|
|
2771
|
+
} else {
|
|
2772
|
+
break;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
// Add the digit n to the result array.
|
|
2777
|
+
qc[qi++] = cmp ? n : ++n;
|
|
2778
|
+
|
|
2779
|
+
// Update the remainder.
|
|
2780
|
+
if (r[0] && cmp) r[rl] = a[ai] || 0;
|
|
2781
|
+
else r = [a[ai]];
|
|
2782
|
+
|
|
2783
|
+
} while ((ai++ < al || r[0] !== UNDEFINED) && k--);
|
|
2784
|
+
|
|
2785
|
+
// Leading zero? Do not remove if result is simply zero (qi == 1).
|
|
2786
|
+
if (!qc[0] && qi != 1) {
|
|
2787
|
+
|
|
2788
|
+
// There can't be more than one zero.
|
|
2789
|
+
qc.shift();
|
|
2790
|
+
q.e--;
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
// Round?
|
|
2794
|
+
if (qi > d) round(q, dp, Big.RM, r[0] !== UNDEFINED);
|
|
2795
|
+
|
|
2796
|
+
return q;
|
|
2797
|
+
};
|
|
2798
|
+
|
|
2799
|
+
|
|
2800
|
+
/*
|
|
2801
|
+
* Return true if the value of this Big is equal to the value of Big y, otherwise return false.
|
|
2802
|
+
*/
|
|
2803
|
+
P.eq = function (y) {
|
|
2804
|
+
return !this.cmp(y);
|
|
2805
|
+
};
|
|
2806
|
+
|
|
2807
|
+
|
|
2808
|
+
/*
|
|
2809
|
+
* Return true if the value of this Big is greater than the value of Big y, otherwise return
|
|
2810
|
+
* false.
|
|
2811
|
+
*/
|
|
2812
|
+
P.gt = function (y) {
|
|
2813
|
+
return this.cmp(y) > 0;
|
|
2814
|
+
};
|
|
2815
|
+
|
|
2816
|
+
|
|
2817
|
+
/*
|
|
2818
|
+
* Return true if the value of this Big is greater than or equal to the value of Big y, otherwise
|
|
2819
|
+
* return false.
|
|
2820
|
+
*/
|
|
2821
|
+
P.gte = function (y) {
|
|
2822
|
+
return this.cmp(y) > -1;
|
|
2823
|
+
};
|
|
2824
|
+
|
|
2825
|
+
|
|
2826
|
+
/*
|
|
2827
|
+
* Return true if the value of this Big is less than the value of Big y, otherwise return false.
|
|
2828
|
+
*/
|
|
2829
|
+
P.lt = function (y) {
|
|
2830
|
+
return this.cmp(y) < 0;
|
|
2831
|
+
};
|
|
2832
|
+
|
|
2833
|
+
|
|
2834
|
+
/*
|
|
2835
|
+
* Return true if the value of this Big is less than or equal to the value of Big y, otherwise
|
|
2836
|
+
* return false.
|
|
2837
|
+
*/
|
|
2838
|
+
P.lte = function (y) {
|
|
2839
|
+
return this.cmp(y) < 1;
|
|
2840
|
+
};
|
|
2841
|
+
|
|
2842
|
+
|
|
2843
|
+
/*
|
|
2844
|
+
* Return a new Big whose value is the value of this Big minus the value of Big y.
|
|
2845
|
+
*/
|
|
2846
|
+
P.minus = P.sub = function (y) {
|
|
2847
|
+
var i, j, t, xlty,
|
|
2848
|
+
x = this,
|
|
2849
|
+
Big = x.constructor,
|
|
2850
|
+
a = x.s,
|
|
2851
|
+
b = (y = new Big(y)).s;
|
|
2852
|
+
|
|
2853
|
+
// Signs differ?
|
|
2854
|
+
if (a != b) {
|
|
2855
|
+
y.s = -b;
|
|
2856
|
+
return x.plus(y);
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
var xc = x.c.slice(),
|
|
2860
|
+
xe = x.e,
|
|
2861
|
+
yc = y.c,
|
|
2862
|
+
ye = y.e;
|
|
2863
|
+
|
|
2864
|
+
// Either zero?
|
|
2865
|
+
if (!xc[0] || !yc[0]) {
|
|
2866
|
+
|
|
2867
|
+
// y is non-zero? x is non-zero? Or both are zero.
|
|
2868
|
+
return yc[0] ? (y.s = -b, y) : new Big(xc[0] ? x : 0);
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
// Determine which is the bigger number. Prepend zeros to equalise exponents.
|
|
2872
|
+
if (a = xe - ye) {
|
|
2873
|
+
|
|
2874
|
+
if (xlty = a < 0) {
|
|
2875
|
+
a = -a;
|
|
2876
|
+
t = xc;
|
|
2877
|
+
} else {
|
|
2878
|
+
ye = xe;
|
|
2879
|
+
t = yc;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
t.reverse();
|
|
2883
|
+
for (b = a; b--;) t.push(0);
|
|
2884
|
+
t.reverse();
|
|
2885
|
+
} else {
|
|
2886
|
+
|
|
2887
|
+
// Exponents equal. Check digit by digit.
|
|
2888
|
+
j = ((xlty = xc.length < yc.length) ? xc : yc).length;
|
|
2889
|
+
|
|
2890
|
+
for (a = b = 0; b < j; b++) {
|
|
2891
|
+
if (xc[b] != yc[b]) {
|
|
2892
|
+
xlty = xc[b] < yc[b];
|
|
2893
|
+
break;
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
// x < y? Point xc to the array of the bigger number.
|
|
2899
|
+
if (xlty) {
|
|
2900
|
+
t = xc;
|
|
2901
|
+
xc = yc;
|
|
2902
|
+
yc = t;
|
|
2903
|
+
y.s = -y.s;
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
/*
|
|
2907
|
+
* Append zeros to xc if shorter. No need to add zeros to yc if shorter as subtraction only
|
|
2908
|
+
* needs to start at yc.length.
|
|
2909
|
+
*/
|
|
2910
|
+
if ((b = (j = yc.length) - (i = xc.length)) > 0) for (; b--;) xc[i++] = 0;
|
|
2911
|
+
|
|
2912
|
+
// Subtract yc from xc.
|
|
2913
|
+
for (b = i; j > a;) {
|
|
2914
|
+
if (xc[--j] < yc[j]) {
|
|
2915
|
+
for (i = j; i && !xc[--i];) xc[i] = 9;
|
|
2916
|
+
--xc[i];
|
|
2917
|
+
xc[j] += 10;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
xc[j] -= yc[j];
|
|
2921
|
+
}
|
|
2922
|
+
|
|
2923
|
+
// Remove trailing zeros.
|
|
2924
|
+
for (; xc[--b] === 0;) xc.pop();
|
|
2925
|
+
|
|
2926
|
+
// Remove leading zeros and adjust exponent accordingly.
|
|
2927
|
+
for (; xc[0] === 0;) {
|
|
2928
|
+
xc.shift();
|
|
2929
|
+
--ye;
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
if (!xc[0]) {
|
|
2933
|
+
|
|
2934
|
+
// n - n = +0
|
|
2935
|
+
y.s = 1;
|
|
2936
|
+
|
|
2937
|
+
// Result must be zero.
|
|
2938
|
+
xc = [ye = 0];
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
y.c = xc;
|
|
2942
|
+
y.e = ye;
|
|
2943
|
+
|
|
2944
|
+
return y;
|
|
2945
|
+
};
|
|
2946
|
+
|
|
2947
|
+
|
|
2948
|
+
/*
|
|
2949
|
+
* Return a new Big whose value is the value of this Big modulo the value of Big y.
|
|
2950
|
+
*/
|
|
2951
|
+
P.mod = function (y) {
|
|
2952
|
+
var ygtx,
|
|
2953
|
+
x = this,
|
|
2954
|
+
Big = x.constructor,
|
|
2955
|
+
a = x.s,
|
|
2956
|
+
b = (y = new Big(y)).s;
|
|
2957
|
+
|
|
2958
|
+
if (!y.c[0]) throw Error(DIV_BY_ZERO);
|
|
2959
|
+
|
|
2960
|
+
x.s = y.s = 1;
|
|
2961
|
+
ygtx = y.cmp(x) == 1;
|
|
2962
|
+
x.s = a;
|
|
2963
|
+
y.s = b;
|
|
2964
|
+
|
|
2965
|
+
if (ygtx) return new Big(x);
|
|
2966
|
+
|
|
2967
|
+
a = Big.DP;
|
|
2968
|
+
b = Big.RM;
|
|
2969
|
+
Big.DP = Big.RM = 0;
|
|
2970
|
+
x = x.div(y);
|
|
2971
|
+
Big.DP = a;
|
|
2972
|
+
Big.RM = b;
|
|
2973
|
+
|
|
2974
|
+
return this.minus(x.times(y));
|
|
2975
|
+
};
|
|
2976
|
+
|
|
2977
|
+
|
|
2978
|
+
/*
|
|
2979
|
+
* Return a new Big whose value is the value of this Big plus the value of Big y.
|
|
2980
|
+
*/
|
|
2981
|
+
P.plus = P.add = function (y) {
|
|
2982
|
+
var t,
|
|
2983
|
+
x = this,
|
|
2984
|
+
Big = x.constructor,
|
|
2985
|
+
a = x.s,
|
|
2986
|
+
b = (y = new Big(y)).s;
|
|
2987
|
+
|
|
2988
|
+
// Signs differ?
|
|
2989
|
+
if (a != b) {
|
|
2990
|
+
y.s = -b;
|
|
2991
|
+
return x.minus(y);
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
var xe = x.e,
|
|
2995
|
+
xc = x.c,
|
|
2996
|
+
ye = y.e,
|
|
2997
|
+
yc = y.c;
|
|
2998
|
+
|
|
2999
|
+
// Either zero? y is non-zero? x is non-zero? Or both are zero.
|
|
3000
|
+
if (!xc[0] || !yc[0]) return yc[0] ? y : new Big(xc[0] ? x : a * 0);
|
|
3001
|
+
|
|
3002
|
+
xc = xc.slice();
|
|
3003
|
+
|
|
3004
|
+
// Prepend zeros to equalise exponents.
|
|
3005
|
+
// Note: Faster to use reverse then do unshifts.
|
|
3006
|
+
if (a = xe - ye) {
|
|
3007
|
+
if (a > 0) {
|
|
3008
|
+
ye = xe;
|
|
3009
|
+
t = yc;
|
|
3010
|
+
} else {
|
|
3011
|
+
a = -a;
|
|
3012
|
+
t = xc;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
t.reverse();
|
|
3016
|
+
for (; a--;) t.push(0);
|
|
3017
|
+
t.reverse();
|
|
3018
|
+
}
|
|
3019
|
+
|
|
3020
|
+
// Point xc to the longer array.
|
|
3021
|
+
if (xc.length - yc.length < 0) {
|
|
3022
|
+
t = yc;
|
|
3023
|
+
yc = xc;
|
|
3024
|
+
xc = t;
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
a = yc.length;
|
|
3028
|
+
|
|
3029
|
+
// Only start adding at yc.length - 1 as the further digits of xc can be left as they are.
|
|
3030
|
+
for (b = 0; a; xc[a] %= 10) b = (xc[--a] = xc[a] + yc[a] + b) / 10 | 0;
|
|
3031
|
+
|
|
3032
|
+
// No need to check for zero, as +x + +y != 0 && -x + -y != 0
|
|
3033
|
+
|
|
3034
|
+
if (b) {
|
|
3035
|
+
xc.unshift(b);
|
|
3036
|
+
++ye;
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
// Remove trailing zeros.
|
|
3040
|
+
for (a = xc.length; xc[--a] === 0;) xc.pop();
|
|
3041
|
+
|
|
3042
|
+
y.c = xc;
|
|
3043
|
+
y.e = ye;
|
|
3044
|
+
|
|
3045
|
+
return y;
|
|
3046
|
+
};
|
|
3047
|
+
|
|
3048
|
+
|
|
3049
|
+
/*
|
|
3050
|
+
* Return a Big whose value is the value of this Big raised to the power n.
|
|
3051
|
+
* If n is negative, round to a maximum of Big.DP decimal places using rounding
|
|
3052
|
+
* mode Big.RM.
|
|
3053
|
+
*
|
|
3054
|
+
* n {number} Integer, -MAX_POWER to MAX_POWER inclusive.
|
|
3055
|
+
*/
|
|
3056
|
+
P.pow = function (n) {
|
|
3057
|
+
var x = this,
|
|
3058
|
+
one = new x.constructor(1),
|
|
3059
|
+
y = one,
|
|
3060
|
+
isneg = n < 0;
|
|
3061
|
+
|
|
3062
|
+
if (n !== ~~n || n < -MAX_POWER || n > MAX_POWER) throw Error(INVALID + 'exponent');
|
|
3063
|
+
if (isneg) n = -n;
|
|
3064
|
+
|
|
3065
|
+
for (;;) {
|
|
3066
|
+
if (n & 1) y = y.times(x);
|
|
3067
|
+
n >>= 1;
|
|
3068
|
+
if (!n) break;
|
|
3069
|
+
x = x.times(x);
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
return isneg ? one.div(y) : y;
|
|
3073
|
+
};
|
|
3074
|
+
|
|
3075
|
+
|
|
3076
|
+
/*
|
|
3077
|
+
* Return a new Big whose value is the value of this Big rounded to a maximum of dp decimal
|
|
3078
|
+
* places using rounding mode rm.
|
|
3079
|
+
* If dp is not specified, round to 0 decimal places.
|
|
3080
|
+
* If rm is not specified, use Big.RM.
|
|
3081
|
+
*
|
|
3082
|
+
* dp? {number} Integer, 0 to MAX_DP inclusive.
|
|
3083
|
+
* rm? 0, 1, 2 or 3 (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_UP)
|
|
3084
|
+
*/
|
|
3085
|
+
P.round = function (dp, rm) {
|
|
3086
|
+
var Big = this.constructor;
|
|
3087
|
+
if (dp === UNDEFINED) dp = 0;
|
|
3088
|
+
else if (dp !== ~~dp || dp < 0 || dp > MAX_DP) throw Error(INVALID_DP);
|
|
3089
|
+
return round(new Big(this), dp, rm === UNDEFINED ? Big.RM : rm);
|
|
3090
|
+
};
|
|
3091
|
+
|
|
3092
|
+
|
|
3093
|
+
/*
|
|
3094
|
+
* Return a new Big whose value is the square root of the value of this Big, rounded, if
|
|
3095
|
+
* necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM.
|
|
3096
|
+
*/
|
|
3097
|
+
P.sqrt = function () {
|
|
3098
|
+
var r, c, t,
|
|
3099
|
+
x = this,
|
|
3100
|
+
Big = x.constructor,
|
|
3101
|
+
s = x.s,
|
|
3102
|
+
e = x.e,
|
|
3103
|
+
half = new Big(0.5);
|
|
3104
|
+
|
|
3105
|
+
// Zero?
|
|
3106
|
+
if (!x.c[0]) return new Big(x);
|
|
3107
|
+
|
|
3108
|
+
// Negative?
|
|
3109
|
+
if (s < 0) throw Error(NAME + 'No square root');
|
|
3110
|
+
|
|
3111
|
+
// Estimate.
|
|
3112
|
+
s = Math.sqrt(x.toString());
|
|
3113
|
+
|
|
3114
|
+
// Math.sqrt underflow/overflow?
|
|
3115
|
+
// Re-estimate: pass x to Math.sqrt as integer, then adjust the result exponent.
|
|
3116
|
+
if (s === 0 || s === 1 / 0) {
|
|
3117
|
+
c = x.c.join('');
|
|
3118
|
+
if (!(c.length + e & 1)) c += '0';
|
|
3119
|
+
r = new Big(Math.sqrt(c).toString());
|
|
3120
|
+
r.e = ((e + 1) / 2 | 0) - (e < 0 || e & 1);
|
|
3121
|
+
} else {
|
|
3122
|
+
r = new Big(s.toString());
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
e = r.e + (Big.DP += 4);
|
|
3126
|
+
|
|
3127
|
+
// Newton-Raphson iteration.
|
|
3128
|
+
do {
|
|
3129
|
+
t = r;
|
|
3130
|
+
r = half.times(t.plus(x.div(t)));
|
|
3131
|
+
} while (t.c.slice(0, e).join('') !== r.c.slice(0, e).join(''));
|
|
3132
|
+
|
|
3133
|
+
return round(r, Big.DP -= 4, Big.RM);
|
|
3134
|
+
};
|
|
3135
|
+
|
|
3136
|
+
|
|
3137
|
+
/*
|
|
3138
|
+
* Return a new Big whose value is the value of this Big times the value of Big y.
|
|
3139
|
+
*/
|
|
3140
|
+
P.times = P.mul = function (y) {
|
|
3141
|
+
var c,
|
|
3142
|
+
x = this,
|
|
3143
|
+
Big = x.constructor,
|
|
3144
|
+
xc = x.c,
|
|
3145
|
+
yc = (y = new Big(y)).c,
|
|
3146
|
+
a = xc.length,
|
|
3147
|
+
b = yc.length,
|
|
3148
|
+
i = x.e,
|
|
3149
|
+
j = y.e;
|
|
3150
|
+
|
|
3151
|
+
// Determine sign of result.
|
|
3152
|
+
y.s = x.s == y.s ? 1 : -1;
|
|
3153
|
+
|
|
3154
|
+
// Return signed 0 if either 0.
|
|
3155
|
+
if (!xc[0] || !yc[0]) return new Big(y.s * 0);
|
|
3156
|
+
|
|
3157
|
+
// Initialise exponent of result as x.e + y.e.
|
|
3158
|
+
y.e = i + j;
|
|
3159
|
+
|
|
3160
|
+
// If array xc has fewer digits than yc, swap xc and yc, and lengths.
|
|
3161
|
+
if (a < b) {
|
|
3162
|
+
c = xc;
|
|
3163
|
+
xc = yc;
|
|
3164
|
+
yc = c;
|
|
3165
|
+
j = a;
|
|
3166
|
+
a = b;
|
|
3167
|
+
b = j;
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
// Initialise coefficient array of result with zeros.
|
|
3171
|
+
for (c = new Array(j = a + b); j--;) c[j] = 0;
|
|
3172
|
+
|
|
3173
|
+
// Multiply.
|
|
3174
|
+
|
|
3175
|
+
// i is initially xc.length.
|
|
3176
|
+
for (i = b; i--;) {
|
|
3177
|
+
b = 0;
|
|
3178
|
+
|
|
3179
|
+
// a is yc.length.
|
|
3180
|
+
for (j = a + i; j > i;) {
|
|
3181
|
+
|
|
3182
|
+
// Current sum of products at this digit position, plus carry.
|
|
3183
|
+
b = c[j] + yc[i] * xc[j - i - 1] + b;
|
|
3184
|
+
c[j--] = b % 10;
|
|
3185
|
+
|
|
3186
|
+
// carry
|
|
3187
|
+
b = b / 10 | 0;
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
c[j] = (c[j] + b) % 10;
|
|
3191
|
+
}
|
|
3192
|
+
|
|
3193
|
+
// Increment result exponent if there is a final carry, otherwise remove leading zero.
|
|
3194
|
+
if (b) ++y.e;
|
|
3195
|
+
else c.shift();
|
|
3196
|
+
|
|
3197
|
+
// Remove trailing zeros.
|
|
3198
|
+
for (i = c.length; !c[--i];) c.pop();
|
|
3199
|
+
y.c = c;
|
|
3200
|
+
|
|
3201
|
+
return y;
|
|
3202
|
+
};
|
|
3203
|
+
|
|
3204
|
+
|
|
3205
|
+
/*
|
|
3206
|
+
* Return a string representing the value of this Big in exponential notation to dp fixed decimal
|
|
3207
|
+
* places and rounded using Big.RM.
|
|
3208
|
+
*
|
|
3209
|
+
* dp? {number} Integer, 0 to MAX_DP inclusive.
|
|
3210
|
+
*/
|
|
3211
|
+
P.toExponential = function (dp) {
|
|
3212
|
+
return stringify(this, 1, dp, dp);
|
|
3213
|
+
};
|
|
3214
|
+
|
|
3215
|
+
|
|
3216
|
+
/*
|
|
3217
|
+
* Return a string representing the value of this Big in normal notation to dp fixed decimal
|
|
3218
|
+
* places and rounded using Big.RM.
|
|
3219
|
+
*
|
|
3220
|
+
* dp? {number} Integer, 0 to MAX_DP inclusive.
|
|
3221
|
+
*
|
|
3222
|
+
* (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.
|
|
3223
|
+
* (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
|
|
3224
|
+
*/
|
|
3225
|
+
P.toFixed = function (dp) {
|
|
3226
|
+
return stringify(this, 2, dp, this.e + dp);
|
|
3227
|
+
};
|
|
3228
|
+
|
|
3229
|
+
|
|
3230
|
+
/*
|
|
3231
|
+
* Return a string representing the value of this Big rounded to sd significant digits using
|
|
3232
|
+
* Big.RM. Use exponential notation if sd is less than the number of digits necessary to represent
|
|
3233
|
+
* the integer part of the value in normal notation.
|
|
3234
|
+
*
|
|
3235
|
+
* sd {number} Integer, 1 to MAX_DP inclusive.
|
|
3236
|
+
*/
|
|
3237
|
+
P.toPrecision = function (sd) {
|
|
3238
|
+
return stringify(this, 3, sd, sd - 1);
|
|
3239
|
+
};
|
|
3240
|
+
|
|
3241
|
+
|
|
3242
|
+
/*
|
|
3243
|
+
* Return a string representing the value of this Big.
|
|
3244
|
+
* Return exponential notation if this Big has a positive exponent equal to or greater than
|
|
3245
|
+
* Big.PE, or a negative exponent equal to or less than Big.NE.
|
|
3246
|
+
* Omit the sign for negative zero.
|
|
3247
|
+
*/
|
|
3248
|
+
P.toString = function () {
|
|
3249
|
+
return stringify(this);
|
|
3250
|
+
};
|
|
3251
|
+
|
|
3252
|
+
|
|
3253
|
+
/*
|
|
3254
|
+
* Return a string representing the value of this Big.
|
|
3255
|
+
* Return exponential notation if this Big has a positive exponent equal to or greater than
|
|
3256
|
+
* Big.PE, or a negative exponent equal to or less than Big.NE.
|
|
3257
|
+
* Include the sign for negative zero.
|
|
3258
|
+
*/
|
|
3259
|
+
P.valueOf = P.toJSON = function () {
|
|
3260
|
+
return stringify(this, 4);
|
|
3261
|
+
};
|
|
3262
|
+
|
|
3263
|
+
|
|
3264
|
+
// Export
|
|
3265
|
+
|
|
3266
|
+
|
|
3267
|
+
Big = _Big_();
|
|
3268
|
+
|
|
3269
|
+
Big['default'] = Big.Big = Big;
|
|
3270
|
+
|
|
3271
|
+
//AMD.
|
|
3272
|
+
if (typeof define === 'function' && define.amd) {
|
|
3273
|
+
define(function () { return Big; });
|
|
3274
|
+
|
|
3275
|
+
// Node and other CommonJS-like environments that support module.exports.
|
|
3276
|
+
} else if (typeof module !== 'undefined' && module.exports) {
|
|
3277
|
+
module.exports = Big;
|
|
3278
|
+
|
|
3279
|
+
//Browser.
|
|
3280
|
+
} else {
|
|
3281
|
+
GLOBAL.Big = Big;
|
|
3282
|
+
}
|
|
3283
|
+
})(this);
|
|
3284
|
+
|
|
3285
|
+
},{}],11:[function(require,module,exports){
|
|
3286
|
+
const Day = require('@barchart/common-js/lang/Day'),
|
|
3287
|
+
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
3288
|
+
|
|
3289
|
+
const PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
|
|
3290
|
+
|
|
3291
|
+
describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
3292
|
+
'use strict';
|
|
3293
|
+
|
|
3294
|
+
describe('and yearly position summary ranges are processed for a transaction set that does not close', () => {
|
|
3295
|
+
let ranges;
|
|
3296
|
+
|
|
3297
|
+
beforeEach(() => {
|
|
3298
|
+
const transactions = [
|
|
3299
|
+
{
|
|
3300
|
+
date: new Day(2015, 10, 20)
|
|
3301
|
+
},
|
|
3302
|
+
{
|
|
3303
|
+
date: new Day(2016, 11, 21),
|
|
3304
|
+
snapshot: {
|
|
3305
|
+
open: new Decimal(1)
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
];
|
|
3309
|
+
|
|
3310
|
+
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
3311
|
+
});
|
|
3312
|
+
|
|
3313
|
+
it('should have three ranges (assuming the current year is 2018)', () => {
|
|
3314
|
+
expect(ranges.length).toEqual(3);
|
|
3315
|
+
});
|
|
3316
|
+
|
|
3317
|
+
it('the first range should be from 12-31-2014 to 12-31-2015', () => {
|
|
3318
|
+
expect(ranges[0].start.format()).toEqual('2014-12-31');
|
|
3319
|
+
expect(ranges[0].end.format()).toEqual('2015-12-31');
|
|
3320
|
+
});
|
|
3321
|
+
|
|
3322
|
+
it('the second range should be from 12-31-2015 to 12-31-2016', () => {
|
|
3323
|
+
expect(ranges[1].start.format()).toEqual('2015-12-31');
|
|
3324
|
+
expect(ranges[1].end.format()).toEqual('2016-12-31');
|
|
3325
|
+
});
|
|
3326
|
+
|
|
3327
|
+
it('the third range should be from 12-31-2016 to 12-31-2017', () => {
|
|
3328
|
+
expect(ranges[2].start.format()).toEqual('2016-12-31');
|
|
3329
|
+
expect(ranges[2].end.format()).toEqual('2017-12-31');
|
|
3330
|
+
});
|
|
3331
|
+
});
|
|
3332
|
+
|
|
3333
|
+
describe('and yearly position summary ranges are processed for a transaction set closes the same year', () => {
|
|
3334
|
+
let ranges;
|
|
3335
|
+
|
|
3336
|
+
beforeEach(() => {
|
|
3337
|
+
const transactions = [
|
|
3338
|
+
{
|
|
3339
|
+
date: new Day(2015, 10, 20)
|
|
3340
|
+
},
|
|
3341
|
+
{
|
|
3342
|
+
date: new Day(2015, 11, 21),
|
|
3343
|
+
snapshot: {
|
|
3344
|
+
open: new Decimal(0)
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
];
|
|
3348
|
+
|
|
3349
|
+
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
3350
|
+
});
|
|
3351
|
+
|
|
3352
|
+
it('should have one range', () => {
|
|
3353
|
+
expect(ranges.length).toEqual(1);
|
|
3354
|
+
});
|
|
3355
|
+
|
|
3356
|
+
it('the first range should be from 12-31-2014 to 12-31-2015', () => {
|
|
3357
|
+
expect(ranges[0].start.format()).toEqual('2014-12-31');
|
|
3358
|
+
expect(ranges[0].end.format()).toEqual('2015-12-31');
|
|
3359
|
+
});
|
|
3360
|
+
});
|
|
3361
|
+
|
|
3362
|
+
describe('and yearly position summary ranges are processed for a transaction set closes the next year', () => {
|
|
3363
|
+
let ranges;
|
|
3364
|
+
|
|
3365
|
+
beforeEach(() => {
|
|
3366
|
+
const transactions = [
|
|
3367
|
+
{
|
|
3368
|
+
date: new Day(2015, 10, 20)
|
|
3369
|
+
},
|
|
3370
|
+
{
|
|
3371
|
+
date: new Day(2016, 11, 21),
|
|
3372
|
+
snapshot: {
|
|
3373
|
+
open: new Decimal(0)
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
];
|
|
3377
|
+
|
|
3378
|
+
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
3379
|
+
});
|
|
3380
|
+
|
|
3381
|
+
it('should have two ranges', () => {
|
|
3382
|
+
expect(ranges.length).toEqual(2);
|
|
3383
|
+
});
|
|
3384
|
+
|
|
3385
|
+
it('the first range should be from 12-31-2014 to 12-31-2015', () => {
|
|
3386
|
+
expect(ranges[0].start.format()).toEqual('2014-12-31');
|
|
3387
|
+
expect(ranges[0].end.format()).toEqual('2015-12-31');
|
|
3388
|
+
});
|
|
3389
|
+
|
|
3390
|
+
it('the second range should be from 12-31-2015 to 12-31-2016', () => {
|
|
3391
|
+
expect(ranges[1].start.format()).toEqual('2015-12-31');
|
|
3392
|
+
expect(ranges[1].end.format()).toEqual('2016-12-31');
|
|
3393
|
+
});
|
|
3394
|
+
});
|
|
3395
|
+
|
|
3396
|
+
describe('and yearly position summary ranges are processed for a transaction set closes in the current next year -- assuming its 2018', () => {
|
|
3397
|
+
let ranges;
|
|
3398
|
+
|
|
3399
|
+
beforeEach(() => {
|
|
3400
|
+
const transactions = [
|
|
3401
|
+
{
|
|
3402
|
+
date: new Day(2015, 10, 20)
|
|
3403
|
+
},
|
|
3404
|
+
{
|
|
3405
|
+
date: new Day(2017, 11, 21),
|
|
3406
|
+
snapshot: {
|
|
3407
|
+
open: new Decimal(0)
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
];
|
|
3411
|
+
|
|
3412
|
+
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
3413
|
+
});
|
|
3414
|
+
|
|
3415
|
+
it('should have two ranges', () => {
|
|
3416
|
+
expect(ranges.length).toEqual(3);
|
|
3417
|
+
});
|
|
3418
|
+
|
|
3419
|
+
it('the first range should be from 12-31-2014 to 12-31-2015', () => {
|
|
3420
|
+
expect(ranges[0].start.format()).toEqual('2014-12-31');
|
|
3421
|
+
expect(ranges[0].end.format()).toEqual('2015-12-31');
|
|
3422
|
+
});
|
|
3423
|
+
|
|
3424
|
+
it('the second range should be from 12-31-2015 to 12-31-2016', () => {
|
|
3425
|
+
expect(ranges[1].start.format()).toEqual('2015-12-31');
|
|
3426
|
+
expect(ranges[1].end.format()).toEqual('2016-12-31');
|
|
3427
|
+
});
|
|
3428
|
+
|
|
3429
|
+
it('the third range should be from 12-31-2015 to 12-31-2016', () => {
|
|
3430
|
+
expect(ranges[2].start.format()).toEqual('2016-12-31');
|
|
3431
|
+
expect(ranges[2].end.format()).toEqual('2017-12-31');
|
|
3432
|
+
});
|
|
3433
|
+
});
|
|
3434
|
+
|
|
3435
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that closed last year', () => {
|
|
3436
|
+
let ranges;
|
|
3437
|
+
|
|
3438
|
+
beforeEach(() => {
|
|
3439
|
+
const transactions = [
|
|
3440
|
+
{
|
|
3441
|
+
date: new Day(2017, 1, 1)
|
|
3442
|
+
},
|
|
3443
|
+
{
|
|
3444
|
+
date: new Day(2017, 1, 2),
|
|
3445
|
+
snapshot: {
|
|
3446
|
+
open: new Decimal(0)
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
];
|
|
3450
|
+
|
|
3451
|
+
ranges = PositionSummaryFrame.YTD.getRanges(transactions);
|
|
3452
|
+
});
|
|
3453
|
+
|
|
3454
|
+
it('should have no ranges', () => {
|
|
3455
|
+
expect(ranges.length).toEqual(0);
|
|
3456
|
+
});
|
|
3457
|
+
});
|
|
3458
|
+
|
|
3459
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that opened this year and has not yet closed', () => {
|
|
3460
|
+
let ranges;
|
|
3461
|
+
|
|
3462
|
+
beforeEach(() => {
|
|
3463
|
+
const transactions = [
|
|
3464
|
+
{
|
|
3465
|
+
date: new Day(2018, 1, 1),
|
|
3466
|
+
snapshot: {
|
|
3467
|
+
open: new Decimal(0)
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
];
|
|
3471
|
+
|
|
3472
|
+
ranges = PositionSummaryFrame.YTD.getRanges(transactions);
|
|
3473
|
+
});
|
|
3474
|
+
|
|
3475
|
+
it('should have one range', () => {
|
|
3476
|
+
expect(ranges.length).toEqual(1);
|
|
3477
|
+
});
|
|
3478
|
+
|
|
3479
|
+
it('the first range should be from 12-31-2017 to 12-31-2015', () => {
|
|
3480
|
+
expect(ranges[0].start.format()).toEqual('2017-12-31');
|
|
3481
|
+
expect(ranges[0].end.format()).toEqual('2018-12-31');
|
|
3482
|
+
});
|
|
3483
|
+
});
|
|
3484
|
+
|
|
3485
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that opened and closed this year', () => {
|
|
3486
|
+
let ranges;
|
|
3487
|
+
|
|
3488
|
+
beforeEach(() => {
|
|
3489
|
+
const transactions = [
|
|
3490
|
+
{
|
|
3491
|
+
date: new Day(2018, 1, 1)
|
|
3492
|
+
},
|
|
3493
|
+
{
|
|
3494
|
+
date: new Day(2018, 1, 2),
|
|
3495
|
+
snapshot: {
|
|
3496
|
+
open: new Decimal(0)
|
|
3497
|
+
}
|
|
3498
|
+
}
|
|
3499
|
+
];
|
|
3500
|
+
|
|
3501
|
+
ranges = PositionSummaryFrame.YTD.getRanges(transactions);
|
|
3502
|
+
});
|
|
3503
|
+
|
|
3504
|
+
it('should have one range', () => {
|
|
3505
|
+
expect(ranges.length).toEqual(1);
|
|
3506
|
+
});
|
|
3507
|
+
|
|
3508
|
+
it('the first range should be from 12-31-2017 to 12-31-2015', () => {
|
|
3509
|
+
expect(ranges[0].start.format()).toEqual('2017-12-31');
|
|
3510
|
+
expect(ranges[0].end.format()).toEqual('2018-12-31');
|
|
3511
|
+
});
|
|
3512
|
+
});
|
|
3513
|
+
});
|
|
3514
|
+
|
|
3515
|
+
},{"./../../../lib/data/PositionSummaryFrame":1,"@barchart/common-js/lang/Day":4,"@barchart/common-js/lang/Decimal":5}]},{},[11]);
|