summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-08-20 13:31:07 +0200
committerFlorian Dold <florian@dold.me>2021-08-20 13:31:07 +0200
commita6a2b26c959ce763db3c5a8a5ed99cc6a689e2ba (patch)
treef36d7f1c7c5ea5b51a54f46ec58d159e3ad41e3d
parentc48a5acc8fe733d529606bc4b19bdad399abc4c9 (diff)
parent5694f6e9d4690992165a33bfe9174ed98f8c8522 (diff)
downloadnode-vendor-a6a2b26c959ce763db3c5a8a5ed99cc6a689e2ba.tar.gz
node-vendor-a6a2b26c959ce763db3c5a8a5ed99cc6a689e2ba.tar.bz2
node-vendor-a6a2b26c959ce763db3c5a8a5ed99cc6a689e2ba.zip
Merge commit '5694f6e9d4690992165a33bfe9174ed98f8c8522' as 'big-integer'
-rw-r--r--big-integer/.gitignore4
-rw-r--r--big-integer/.npmignore17
-rw-r--r--big-integer/.travis.yml11
-rw-r--r--big-integer/BigInteger.d.ts2388
-rw-r--r--big-integer/BigInteger.js1436
-rw-r--r--big-integer/BigInteger.min.js1
-rw-r--r--big-integer/LICENSE24
-rw-r--r--big-integer/README.md580
-rw-r--r--big-integer/benchmark/benchmark.js3919
-rw-r--r--big-integer/benchmark/index.html71
-rw-r--r--big-integer/benchmark/index.js204
-rw-r--r--big-integer/benchmark/testWorker.js70
-rw-r--r--big-integer/benchmark/tests.js192
-rw-r--r--big-integer/benchmark/wait.gifbin0 -> 16810 bytes
-rw-r--r--big-integer/bower.json29
-rw-r--r--big-integer/my.conf.js20
-rw-r--r--big-integer/package.json48
-rw-r--r--big-integer/spec/SpecRunner.html24
-rw-r--r--big-integer/spec/lib/jasmine-2.1.3/boot.js120
-rw-r--r--big-integer/spec/lib/jasmine-2.1.3/console.js190
-rw-r--r--big-integer/spec/lib/jasmine-2.1.3/jasmine-html.js404
-rw-r--r--big-integer/spec/lib/jasmine-2.1.3/jasmine.css62
-rw-r--r--big-integer/spec/lib/jasmine-2.1.3/jasmine.js2908
-rw-r--r--big-integer/spec/lib/jasmine-2.1.3/jasmine_favicon.pngbin0 -> 1486 bytes
-rw-r--r--big-integer/spec/spec.js1234
-rw-r--r--big-integer/spec/support/jasmine.json9
-rw-r--r--big-integer/spec/tsDefinitions.ts242
-rw-r--r--big-integer/tsconfig.json25
28 files changed, 14232 insertions, 0 deletions
diff --git a/big-integer/.gitignore b/big-integer/.gitignore
new file mode 100644
index 0000000..45621a3
--- /dev/null
+++ b/big-integer/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+*lock*
+coverage
+spec/tsDefinitions.js \ No newline at end of file
diff --git a/big-integer/.npmignore b/big-integer/.npmignore
new file mode 100644
index 0000000..31905cf
--- /dev/null
+++ b/big-integer/.npmignore
@@ -0,0 +1,17 @@
+/.travis.yml
+/.npmignore
+/.gitignore
+/spec
+/benchmark
+/big-integer*.tgz
+/my.conf.js
+/node_modules
+/*.csproj*
+/*.sh
+/*.suo
+/bin
+/coverage
+/*.bat
+/obj
+/Properties
+/Web.*
diff --git a/big-integer/.travis.yml b/big-integer/.travis.yml
new file mode 100644
index 0000000..66095ec
--- /dev/null
+++ b/big-integer/.travis.yml
@@ -0,0 +1,11 @@
+language: node_js
+node_js:
+ - "9"
+ - "8"
+ - "7"
+ - "6"
+ - "5"
+ - "4"
+script:
+ - npm test
+ - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
diff --git a/big-integer/BigInteger.d.ts b/big-integer/BigInteger.d.ts
new file mode 100644
index 0000000..76b8409
--- /dev/null
+++ b/big-integer/BigInteger.d.ts
@@ -0,0 +1,2388 @@
+/**
+ * Type definitions for BigInteger.js
+ * Definitions by: Tommy Frazier <https://github.com/toefraz>
+ */
+export = bigInt;
+export as namespace bigInt;
+
+declare var bigInt: bigInt.BigIntegerStatic;
+
+declare namespace bigInt {
+ type BigNumber = number | string | BigInteger;
+
+ interface BigIntegerStatic {
+ /**
+ * Equivalent to bigInt(0).
+ */
+ (): BigInteger;
+
+ /**
+ * Parse a Javascript number into a bigInt.
+ */
+ (number: number): BigInteger;
+
+ /**
+ * Parse a string into a bigInt.
+ * Default base is 10.
+ * Default alphabet is "0123456789abcdefghijklmnopqrstuvwxyz".
+ * caseSensitive defaults to false.
+ */
+ (string: string, base?: BigNumber, alphabet?: string, caseSensitive?: boolean): BigInteger;
+
+ /**
+ * no-op.
+ */
+ (bigInt: BigInteger): BigInteger;
+
+ /**
+ * Constructs a bigInt from an array of digits in specified base.
+ * The optional isNegative flag will make the number negative.
+ */
+ fromArray: (digits: BigNumber[], base?: BigNumber, isNegative?: boolean) => BigInteger;
+
+ /**
+ * Finds the greatest common denominator of a and b.
+ */
+ gcd: (a: BigNumber, b: BigNumber) => BigInteger;
+
+
+ /**
+ * Returns true if x is a BigInteger, false otherwise.
+ */
+ isInstance: (x: any) => x is BigInteger;
+
+ /**
+ * Finds the least common multiple of a and b.
+ */
+ lcm: (a: BigNumber, b: BigNumber) => BigInteger;
+
+ /**
+ * Returns the largest of a and b.
+ */
+ max: (a: BigNumber, b: BigNumber) => BigInteger;
+
+ /**
+ * Returns the smallest of a and b.
+ */
+ min: (a: BigNumber, b: BigNumber) => BigInteger;
+
+ /**
+ * Equivalent to bigInt(-1).
+ */
+ minusOne: BigInteger;
+
+ /**
+ * Equivalent to bigInt(1).
+ */
+ one: BigInteger;
+
+ /**
+ * Returns a random number between min and max.
+ */
+ randBetween: (min: BigNumber, max: BigNumber) => BigInteger;
+
+ /**
+ * Equivalent to bigInt(0).
+ */
+ zero: BigInteger;
+ }
+
+ interface BigInteger {
+ /**
+ * Returns the absolute value of a bigInt.
+ */
+ abs(): BigInteger;
+
+ /**
+ * Performs addition.
+ */
+ add(number: BigNumber): BigInteger;
+
+ /**
+ * Performs the bitwise AND operation.
+ */
+ and(number: BigNumber): BigInteger;
+
+ /**
+ * Returns the number of digits required to represent a bigInt in binary.
+ */
+ bitLength(): BigInteger;
+
+ /**
+ * Performs a comparison between two numbers. If the numbers are equal, it returns 0.
+ * If the first number is greater, it returns 1. If the first number is lesser, it returns -1.
+ */
+ compare(number: BigNumber): number;
+
+ /**
+ * Performs a comparison between the absolute value of two numbers.
+ */
+ compareAbs(number: BigNumber): number;
+
+ /**
+ * Alias for the compare method.
+ */
+ compareTo(number: BigNumber): number;
+
+ /**
+ * Performs integer division, disregarding the remainder.
+ */
+ divide(number: BigNumber): BigInteger;
+
+ /**
+ * Performs division and returns an object with two properties: quotient and remainder.
+ * The sign of the remainder will match the sign of the dividend.
+ */
+ divmod(number: BigNumber): { quotient: BigInteger, remainder: BigInteger };
+
+ /**
+ * Alias for the equals method.
+ */
+ eq(number: BigNumber): boolean;
+
+ /**
+ * Checks if two numbers are equal.
+ */
+ equals(number: BigNumber): boolean;
+
+ /**
+ * Alias for the greaterOrEquals method.
+ */
+ geq(number: BigNumber): boolean;
+
+ /**
+ * Checks if the first number is greater than the second.
+ */
+ greater(number: BigNumber): boolean;
+
+ /**
+ * Checks if the first number is greater than or equal to the second.
+ */
+ greaterOrEquals(number: BigNumber): boolean;
+
+ /**
+ * Alias for the greater method.
+ */
+ gt(number: BigNumber): boolean;
+
+ /**
+ * Returns true if the first number is divisible by the second number, false otherwise.
+ */
+ isDivisibleBy(number: BigNumber): boolean;
+
+ /**
+ * Returns true if the number is even, false otherwise.
+ */
+ isEven(): boolean;
+
+ /**
+ * Returns true if the number is negative, false otherwise.
+ * Returns false for 0 and true for -0.
+ */
+ isNegative(): boolean;
+
+ /**
+ * Returns true if the number is odd, false otherwise.
+ */
+ isOdd(): boolean;
+
+ /**
+ * Return true if the number is positive, false otherwise.
+ * Returns true for 0 and false for -0.
+ */
+ isPositive(): boolean;
+
+ /**
+ * Returns true if the number is prime, false otherwise.
+ */
+ isPrime(): boolean;
+
+ /**
+ * Returns true if the number is very likely to be prime, false otherwise.
+ */
+ isProbablePrime(iterations?: number): boolean;
+
+ /**
+ * Returns true if the number is 1 or -1, false otherwise.
+ */
+ isUnit(): boolean;
+
+ /**
+ * Return true if the number is 0 or -0, false otherwise.
+ */
+ isZero(): boolean;
+
+ /**
+ * Alias for the lesserOrEquals method.
+ */
+ leq(number: BigNumber): boolean;
+
+ /**
+ * Checks if the first number is lesser than the second.
+ */
+ lesser(number: BigNumber): boolean;
+
+ /**
+ * Checks if the first number is less than or equal to the second.
+ */
+ lesserOrEquals(number: BigNumber): boolean;
+
+ /**
+ * Alias for the lesser method.
+ */
+ lt(number: BigNumber): boolean;
+
+ /**
+ * Alias for the subtract method.
+ */
+ minus(number: BigNumber): BigInteger;
+
+ /**
+ * Performs division and returns the remainder, disregarding the quotient.
+ * The sign of the remainder will match the sign of the dividend.
+ */
+ mod(number: BigNumber): BigInteger;
+
+ /**
+ * Finds the multiplicative inverse of the number modulo mod.
+ */
+ modInv(number: BigNumber): BigInteger;
+
+ /**
+ * Takes the number to the power exp modulo mod.
+ */
+ modPow(exp: BigNumber, mod: BigNumber): BigInteger;
+
+ /**
+ * Performs multiplication.
+ */
+ multiply(number: BigNumber): BigInteger;
+
+ /**
+ * Reverses the sign of the number.
+ */
+ negate(): BigInteger;
+
+ /**
+ * Alias for the notEquals method.
+ */
+ neq(number: BigNumber): boolean;
+
+ /**
+ * Adds one to the number.
+ */
+ next(): BigInteger;
+
+ /**
+ * Performs the bitwise NOT operation.
+ */
+ not(): BigInteger;
+
+ /**
+ * Checks if two numbers are not equal.
+ */
+ notEquals(number: BigNumber): boolean;
+
+ /**
+ * Performs the bitwise OR operation.
+ */
+ or(number: BigNumber): BigInteger;
+
+ /**
+ * Alias for the divide method.
+ */
+ over(number: BigNumber): BigInteger;
+
+ /**
+ * Alias for the add method.
+ */
+ plus(number: BigNumber): BigInteger;
+
+ /**
+ * Performs exponentiation. If the exponent is less than 0, pow returns 0.
+ * bigInt.zero.pow(0) returns 1.
+ */
+ pow(number: BigNumber): BigInteger;
+
+ /**
+ * Subtracts one from the number.
+ */
+ prev(): BigInteger;
+
+ /**
+ * Alias for the mod method.
+ */
+ remainder(number: BigNumber): BigInteger;
+
+ /**
+ * Shifts the number left by n places in its binary representation.
+ * If a negative number is provided, it will shift right.
+ *
+ * Throws an error if number is outside of the range [-9007199254740992, 9007199254740992].
+ */
+ shiftLeft(number: BigNumber): BigInteger;
+
+ /**
+ * Shifts the number right by n places in its binary representation.
+ * If a negative number is provided, it will shift left.
+ *
+ * Throws an error if number is outside of the range [-9007199254740992, 9007199254740992].
+ */
+ shiftRight(number: BigNumber): BigInteger;
+
+ /**
+ * Squares the number.
+ */
+ square(): BigInteger;
+
+ /**
+ * Performs subtraction.
+ */
+ subtract(number: BigNumber): BigInteger;
+
+ /**
+ * Alias for the multiply method.
+ */
+ times(number: BigNumber): BigInteger;
+
+ /**
+ *
+ * Converts a bigInt to an object representing it as an array of integers module the given radix.
+ */
+ toArray(radix: number): BaseArray;
+
+ /**
+ * Converts a bigInt into a native Javascript number. Loses precision for numbers outside the range.
+ */
+ toJSNumber(): number;
+
+ /**
+ * Converts a bigInt to a string.
+ */
+ toString(radix?: number): string;
+
+ /**
+ * Converts a bigInt to a string. This method is called behind the scenes in JSON.stringify.
+ */
+ toJSON(): string;
+
+ /**
+ * Converts a bigInt to a native Javascript number. This override allows you to use native
+ * arithmetic operators without explicit conversion.
+ */
+ valueOf(): number;
+
+ /**
+ * Performs the bitwise XOR operation.
+ */
+ xor(number: BigNumber): BigInteger;
+ }
+
+ // Array constant accessors
+ interface BigIntegerStatic {
+ '-999': BigInteger;
+ '-998': BigInteger;
+ '-997': BigInteger;
+ '-996': BigInteger;
+ '-995': BigInteger;
+ '-994': BigInteger;
+ '-993': BigInteger;
+ '-992': BigInteger;
+ '-991': BigInteger;
+ '-990': BigInteger;
+ '-989': BigInteger;
+ '-988': BigInteger;
+ '-987': BigInteger;
+ '-986': BigInteger;
+ '-985': BigInteger;
+ '-984': BigInteger;
+ '-983': BigInteger;
+ '-982': BigInteger;
+ '-981': BigInteger;
+ '-980': BigInteger;
+ '-979': BigInteger;
+ '-978': BigInteger;
+ '-977': BigInteger;
+ '-976': BigInteger;
+ '-975': BigInteger;
+ '-974': BigInteger;
+ '-973': BigInteger;
+ '-972': BigInteger;
+ '-971': BigInteger;
+ '-970': BigInteger;
+ '-969': BigInteger;
+ '-968': BigInteger;
+ '-967': BigInteger;
+ '-966': BigInteger;
+ '-965': BigInteger;
+ '-964': BigInteger;
+ '-963': BigInteger;
+ '-962': BigInteger;
+ '-961': BigInteger;
+ '-960': BigInteger;
+ '-959': BigInteger;
+ '-958': BigInteger;
+ '-957': BigInteger;
+ '-956': BigInteger;
+ '-955': BigInteger;
+ '-954': BigInteger;
+ '-953': BigInteger;
+ '-952': BigInteger;
+ '-951': BigInteger;
+ '-950': BigInteger;
+ '-949': BigInteger;
+ '-948': BigInteger;
+ '-947': BigInteger;
+ '-946': BigInteger;
+ '-945': BigInteger;
+ '-944': BigInteger;
+ '-943': BigInteger;
+ '-942': BigInteger;
+ '-941': BigInteger;
+ '-940': BigInteger;
+ '-939': BigInteger;
+ '-938': BigInteger;
+ '-937': BigInteger;
+ '-936': BigInteger;
+ '-935': BigInteger;
+ '-934': BigInteger;
+ '-933': BigInteger;
+ '-932': BigInteger;
+ '-931': BigInteger;
+ '-930': BigInteger;
+ '-929': BigInteger;
+ '-928': BigInteger;
+ '-927': BigInteger;
+ '-926': BigInteger;
+ '-925': BigInteger;
+ '-924': BigInteger;
+ '-923': BigInteger;
+ '-922': BigInteger;
+ '-921': BigInteger;
+ '-920': BigInteger;
+ '-919': BigInteger;
+ '-918': BigInteger;
+ '-917': BigInteger;
+ '-916': BigInteger;
+ '-915': BigInteger;
+ '-914': BigInteger;
+ '-913': BigInteger;
+ '-912': BigInteger;
+ '-911': BigInteger;
+ '-910': BigInteger;
+ '-909': BigInteger;
+ '-908': BigInteger;
+ '-907': BigInteger;
+ '-906': BigInteger;
+ '-905': BigInteger;
+ '-904': BigInteger;
+ '-903': BigInteger;
+ '-902': BigInteger;
+ '-901': BigInteger;
+ '-900': BigInteger;
+ '-899': BigInteger;
+ '-898': BigInteger;
+ '-897': BigInteger;
+ '-896': BigInteger;
+ '-895': BigInteger;
+ '-894': BigInteger;
+ '-893': BigInteger;
+ '-892': BigInteger;
+ '-891': BigInteger;
+ '-890': BigInteger;
+ '-889': BigInteger;
+ '-888': BigInteger;
+ '-887': BigInteger;
+ '-886': BigInteger;
+ '-885': BigInteger;
+ '-884': BigInteger;
+ '-883': BigInteger;
+ '-882': BigInteger;
+ '-881': BigInteger;
+ '-880': BigInteger;
+ '-879': BigInteger;
+ '-878': BigInteger;
+ '-877': BigInteger;
+ '-876': BigInteger;
+ '-875': BigInteger;
+ '-874': BigInteger;
+ '-873': BigInteger;
+ '-872': BigInteger;
+ '-871': BigInteger;
+ '-870': BigInteger;
+ '-869': BigInteger;
+ '-868': BigInteger;
+ '-867': BigInteger;
+ '-866': BigInteger;
+ '-865': BigInteger;
+ '-864': BigInteger;
+ '-863': BigInteger;
+ '-862': BigInteger;
+ '-861': BigInteger;
+ '-860': BigInteger;
+ '-859': BigInteger;
+ '-858': BigInteger;
+ '-857': BigInteger;
+ '-856': BigInteger;
+ '-855': BigInteger;
+ '-854': BigInteger;
+ '-853': BigInteger;
+ '-852': BigInteger;
+ '-851': BigInteger;
+ '-850': BigInteger;
+ '-849': BigInteger;
+ '-848': BigInteger;
+ '-847': BigInteger;
+ '-846': BigInteger;
+ '-845': BigInteger;
+ '-844': BigInteger;
+ '-843': BigInteger;
+ '-842': BigInteger;
+ '-841': BigInteger;
+ '-840': BigInteger;
+ '-839': BigInteger;
+ '-838': BigInteger;
+ '-837': BigInteger;
+ '-836': BigInteger;
+ '-835': BigInteger;
+ '-834': BigInteger;
+ '-833': BigInteger;
+ '-832': BigInteger;
+ '-831': BigInteger;
+ '-830': BigInteger;
+ '-829': BigInteger;
+ '-828': BigInteger;
+ '-827': BigInteger;
+ '-826': BigInteger;
+ '-825': BigInteger;
+ '-824': BigInteger;
+ '-823': BigInteger;
+ '-822': BigInteger;
+ '-821': BigInteger;
+ '-820': BigInteger;
+ '-819': BigInteger;
+ '-818': BigInteger;
+ '-817': BigInteger;
+ '-816': BigInteger;
+ '-815': BigInteger;
+ '-814': BigInteger;
+ '-813': BigInteger;
+ '-812': BigInteger;
+ '-811': BigInteger;
+ '-810': BigInteger;
+ '-809': BigInteger;
+ '-808': BigInteger;
+ '-807': BigInteger;
+ '-806': BigInteger;
+ '-805': BigInteger;
+ '-804': BigInteger;
+ '-803': BigInteger;
+ '-802': BigInteger;
+ '-801': BigInteger;
+ '-800': BigInteger;
+ '-799': BigInteger;
+ '-798': BigInteger;
+ '-797': BigInteger;
+ '-796': BigInteger;
+ '-795': BigInteger;
+ '-794': BigInteger;
+ '-793': BigInteger;
+ '-792': BigInteger;
+ '-791': BigInteger;
+ '-790': BigInteger;
+ '-789': BigInteger;
+ '-788': BigInteger;
+ '-787': BigInteger;
+ '-786': BigInteger;
+ '-785': BigInteger;
+ '-784': BigInteger;
+ '-783': BigInteger;
+ '-782': BigInteger;
+ '-781': BigInteger;
+ '-780': BigInteger;
+ '-779': BigInteger;
+ '-778': BigInteger;
+ '-777': BigInteger;
+ '-776': BigInteger;
+ '-775': BigInteger;
+ '-774': BigInteger;
+ '-773': BigInteger;
+ '-772': BigInteger;
+ '-771': BigInteger;
+ '-770': BigInteger;
+ '-769': BigInteger;
+ '-768': BigInteger;
+ '-767': BigInteger;
+ '-766': BigInteger;
+ '-765': BigInteger;
+ '-764': BigInteger;
+ '-763': BigInteger;
+ '-762': BigInteger;
+ '-761': BigInteger;
+ '-760': BigInteger;
+ '-759': BigInteger;
+ '-758': BigInteger;
+ '-757': BigInteger;
+ '-756': BigInteger;
+ '-755': BigInteger;
+ '-754': BigInteger;
+ '-753': BigInteger;
+ '-752': BigInteger;
+ '-751': BigInteger;
+ '-750': BigInteger;
+ '-749': BigInteger;
+ '-748': BigInteger;
+ '-747': BigInteger;
+ '-746': BigInteger;
+ '-745': BigInteger;
+ '-744': BigInteger;
+ '-743': BigInteger;
+ '-742': BigInteger;
+ '-741': BigInteger;
+ '-740': BigInteger;
+ '-739': BigInteger;
+ '-738': BigInteger;
+ '-737': BigInteger;
+ '-736': BigInteger;
+ '-735': BigInteger;
+ '-734': BigInteger;
+ '-733': BigInteger;
+ '-732': BigInteger;
+ '-731': BigInteger;
+ '-730': BigInteger;
+ '-729': BigInteger;
+ '-728': BigInteger;
+ '-727': BigInteger;
+ '-726': BigInteger;
+ '-725': BigInteger;
+ '-724': BigInteger;
+ '-723': BigInteger;
+ '-722': BigInteger;
+ '-721': BigInteger;
+ '-720': BigInteger;
+ '-719': BigInteger;
+ '-718': BigInteger;
+ '-717': BigInteger;
+ '-716': BigInteger;
+ '-715': BigInteger;
+ '-714': BigInteger;
+ '-713': BigInteger;
+ '-712': BigInteger;
+ '-711': BigInteger;
+ '-710': BigInteger;
+ '-709': BigInteger;
+ '-708': BigInteger;
+ '-707': BigInteger;
+ '-706': BigInteger;
+ '-705': BigInteger;
+ '-704': BigInteger;
+ '-703': BigInteger;
+ '-702': BigInteger;
+ '-701': BigInteger;
+ '-700': BigInteger;
+ '-699': BigInteger;
+ '-698': BigInteger;
+ '-697': BigInteger;
+ '-696': BigInteger;
+ '-695': BigInteger;
+ '-694': BigInteger;
+ '-693': BigInteger;
+ '-692': BigInteger;
+ '-691': BigInteger;
+ '-690': BigInteger;
+ '-689': BigInteger;
+ '-688': BigInteger;
+ '-687': BigInteger;
+ '-686': BigInteger;
+ '-685': BigInteger;
+ '-684': BigInteger;
+ '-683': BigInteger;
+ '-682': BigInteger;
+ '-681': BigInteger;
+ '-680': BigInteger;
+ '-679': BigInteger;
+ '-678': BigInteger;
+ '-677': BigInteger;
+ '-676': BigInteger;
+ '-675': BigInteger;
+ '-674': BigInteger;
+ '-673': BigInteger;
+ '-672': BigInteger;
+ '-671': BigInteger;
+ '-670': BigInteger;
+ '-669': BigInteger;
+ '-668': BigInteger;
+ '-667': BigInteger;
+ '-666': BigInteger;
+ '-665': BigInteger;
+ '-664': BigInteger;
+ '-663': BigInteger;
+ '-662': BigInteger;
+ '-661': BigInteger;
+ '-660': BigInteger;
+ '-659': BigInteger;
+ '-658': BigInteger;
+ '-657': BigInteger;
+ '-656': BigInteger;
+ '-655': BigInteger;
+ '-654': BigInteger;
+ '-653': BigInteger;
+ '-652': BigInteger;
+ '-651': BigInteger;
+ '-650': BigInteger;
+ '-649': BigInteger;
+ '-648': BigInteger;
+ '-647': BigInteger;
+ '-646': BigInteger;
+ '-645': BigInteger;
+ '-644': BigInteger;
+ '-643': BigInteger;
+ '-642': BigInteger;
+ '-641': BigInteger;
+ '-640': BigInteger;
+ '-639': BigInteger;
+ '-638': BigInteger;
+ '-637': BigInteger;
+ '-636': BigInteger;
+ '-635': BigInteger;
+ '-634': BigInteger;
+ '-633': BigInteger;
+ '-632': BigInteger;
+ '-631': BigInteger;
+ '-630': BigInteger;
+ '-629': BigInteger;
+ '-628': BigInteger;
+ '-627': BigInteger;
+ '-626': BigInteger;
+ '-625': BigInteger;
+ '-624': BigInteger;
+ '-623': BigInteger;
+ '-622': BigInteger;
+ '-621': BigInteger;
+ '-620': BigInteger;
+ '-619': BigInteger;
+ '-618': BigInteger;
+ '-617': BigInteger;
+ '-616': BigInteger;
+ '-615': BigInteger;
+ '-614': BigInteger;
+ '-613': BigInteger;
+ '-612': BigInteger;
+ '-611': BigInteger;
+ '-610': BigInteger;
+ '-609': BigInteger;
+ '-608': BigInteger;
+ '-607': BigInteger;
+ '-606': BigInteger;
+ '-605': BigInteger;
+ '-604': BigInteger;
+ '-603': BigInteger;
+ '-602': BigInteger;
+ '-601': BigInteger;
+ '-600': BigInteger;
+ '-599': BigInteger;
+ '-598': BigInteger;
+ '-597': BigInteger;
+ '-596': BigInteger;
+ '-595': BigInteger;
+ '-594': BigInteger;
+ '-593': BigInteger;
+ '-592': BigInteger;
+ '-591': BigInteger;
+ '-590': BigInteger;
+ '-589': BigInteger;
+ '-588': BigInteger;
+ '-587': BigInteger;
+ '-586': BigInteger;
+ '-585': BigInteger;
+ '-584': BigInteger;
+ '-583': BigInteger;
+ '-582': BigInteger;
+ '-581': BigInteger;
+ '-580': BigInteger;
+ '-579': BigInteger;
+ '-578': BigInteger;
+ '-577': BigInteger;
+ '-576': BigInteger;
+ '-575': BigInteger;
+ '-574': BigInteger;
+ '-573': BigInteger;
+ '-572': BigInteger;
+ '-571': BigInteger;
+ '-570': BigInteger;
+ '-569': BigInteger;
+ '-568': BigInteger;
+ '-567': BigInteger;
+ '-566': BigInteger;
+ '-565': BigInteger;
+ '-564': BigInteger;
+ '-563': BigInteger;
+ '-562': BigInteger;
+ '-561': BigInteger;
+ '-560': BigInteger;
+ '-559': BigInteger;
+ '-558': BigInteger;
+ '-557': BigInteger;
+ '-556': BigInteger;
+ '-555': BigInteger;
+ '-554': BigInteger;
+ '-553': BigInteger;
+ '-552': BigInteger;
+ '-551': BigInteger;
+ '-550': BigInteger;
+ '-549': BigInteger;
+ '-548': BigInteger;
+ '-547': BigInteger;
+ '-546': BigInteger;
+ '-545': BigInteger;
+ '-544': BigInteger;
+ '-543': BigInteger;
+ '-542': BigInteger;
+ '-541': BigInteger;
+ '-540': BigInteger;
+ '-539': BigInteger;
+ '-538': BigInteger;
+ '-537': BigInteger;
+ '-536': BigInteger;
+ '-535': BigInteger;
+ '-534': BigInteger;
+ '-533': BigInteger;
+ '-532': BigInteger;
+ '-531': BigInteger;
+ '-530': BigInteger;
+ '-529': BigInteger;
+ '-528': BigInteger;
+ '-527': BigInteger;
+ '-526': BigInteger;
+ '-525': BigInteger;
+ '-524': BigInteger;
+ '-523': BigInteger;
+ '-522': BigInteger;
+ '-521': BigInteger;
+ '-520': BigInteger;
+ '-519': BigInteger;
+ '-518': BigInteger;
+ '-517': BigInteger;
+ '-516': BigInteger;
+ '-515': BigInteger;
+ '-514': BigInteger;
+ '-513': BigInteger;
+ '-512': BigInteger;
+ '-511': BigInteger;
+ '-510': BigInteger;
+ '-509': BigInteger;
+ '-508': BigInteger;
+ '-507': BigInteger;
+ '-506': BigInteger;
+ '-505': BigInteger;
+ '-504': BigInteger;
+ '-503': BigInteger;
+ '-502': BigInteger;
+ '-501': BigInteger;
+ '-500': BigInteger;
+ '-499': BigInteger;
+ '-498': BigInteger;
+ '-497': BigInteger;
+ '-496': BigInteger;
+ '-495': BigInteger;
+ '-494': BigInteger;
+ '-493': BigInteger;
+ '-492': BigInteger;
+ '-491': BigInteger;
+ '-490': BigInteger;
+ '-489': BigInteger;
+ '-488': BigInteger;
+ '-487': BigInteger;
+ '-486': BigInteger;
+ '-485': BigInteger;
+ '-484': BigInteger;
+ '-483': BigInteger;
+ '-482': BigInteger;
+ '-481': BigInteger;
+ '-480': BigInteger;
+ '-479': BigInteger;
+ '-478': BigInteger;
+ '-477': BigInteger;
+ '-476': BigInteger;
+ '-475': BigInteger;
+ '-474': BigInteger;
+ '-473': BigInteger;
+ '-472': BigInteger;
+ '-471': BigInteger;
+ '-470': BigInteger;
+ '-469': BigInteger;
+ '-468': BigInteger;
+ '-467': BigInteger;
+ '-466': BigInteger;
+ '-465': BigInteger;
+ '-464': BigInteger;
+ '-463': BigInteger;
+ '-462': BigInteger;
+ '-461': BigInteger;
+ '-460': BigInteger;
+ '-459': BigInteger;
+ '-458': BigInteger;
+ '-457': BigInteger;
+ '-456': BigInteger;
+ '-455': BigInteger;
+ '-454': BigInteger;
+ '-453': BigInteger;
+ '-452': BigInteger;
+ '-451': BigInteger;
+ '-450': BigInteger;
+ '-449': BigInteger;
+ '-448': BigInteger;
+ '-447': BigInteger;
+ '-446': BigInteger;
+ '-445': BigInteger;
+ '-444': BigInteger;
+ '-443': BigInteger;
+ '-442': BigInteger;
+ '-441': BigInteger;
+ '-440': BigInteger;
+ '-439': BigInteger;
+ '-438': BigInteger;
+ '-437': BigInteger;
+ '-436': BigInteger;
+ '-435': BigInteger;
+ '-434': BigInteger;
+ '-433': BigInteger;
+ '-432': BigInteger;
+ '-431': BigInteger;
+ '-430': BigInteger;
+ '-429': BigInteger;
+ '-428': BigInteger;
+ '-427': BigInteger;
+ '-426': BigInteger;
+ '-425': BigInteger;
+ '-424': BigInteger;
+ '-423': BigInteger;
+ '-422': BigInteger;
+ '-421': BigInteger;
+ '-420': BigInteger;
+ '-419': BigInteger;
+ '-418': BigInteger;
+ '-417': BigInteger;
+ '-416': BigInteger;
+ '-415': BigInteger;
+ '-414': BigInteger;
+ '-413': BigInteger;
+ '-412': BigInteger;
+ '-411': BigInteger;
+ '-410': BigInteger;
+ '-409': BigInteger;
+ '-408': BigInteger;
+ '-407': BigInteger;
+ '-406': BigInteger;
+ '-405': BigInteger;
+ '-404': BigInteger;
+ '-403': BigInteger;
+ '-402': BigInteger;
+ '-401': BigInteger;
+ '-400': BigInteger;
+ '-399': BigInteger;
+ '-398': BigInteger;
+ '-397': BigInteger;
+ '-396': BigInteger;
+ '-395': BigInteger;
+ '-394': BigInteger;
+ '-393': BigInteger;
+ '-392': BigInteger;
+ '-391': BigInteger;
+ '-390': BigInteger;
+ '-389': BigInteger;
+ '-388': BigInteger;
+ '-387': BigInteger;
+ '-386': BigInteger;
+ '-385': BigInteger;
+ '-384': BigInteger;
+ '-383': BigInteger;
+ '-382': BigInteger;
+ '-381': BigInteger;
+ '-380': BigInteger;
+ '-379': BigInteger;
+ '-378': BigInteger;
+ '-377': BigInteger;
+ '-376': BigInteger;
+ '-375': BigInteger;
+ '-374': BigInteger;
+ '-373': BigInteger;
+ '-372': BigInteger;
+ '-371': BigInteger;
+ '-370': BigInteger;
+ '-369': BigInteger;
+ '-368': BigInteger;
+ '-367': BigInteger;
+ '-366': BigInteger;
+ '-365': BigInteger;
+ '-364': BigInteger;
+ '-363': BigInteger;
+ '-362': BigInteger;
+ '-361': BigInteger;
+ '-360': BigInteger;
+ '-359': BigInteger;
+ '-358': BigInteger;
+ '-357': BigInteger;
+ '-356': BigInteger;
+ '-355': BigInteger;
+ '-354': BigInteger;
+ '-353': BigInteger;
+ '-352': BigInteger;
+ '-351': BigInteger;
+ '-350': BigInteger;
+ '-349': BigInteger;
+ '-348': BigInteger;
+ '-347': BigInteger;
+ '-346': BigInteger;
+ '-345': BigInteger;
+ '-344': BigInteger;
+ '-343': BigInteger;
+ '-342': BigInteger;
+ '-341': BigInteger;
+ '-340': BigInteger;
+ '-339': BigInteger;
+ '-338': BigInteger;
+ '-337': BigInteger;
+ '-336': BigInteger;
+ '-335': BigInteger;
+ '-334': BigInteger;
+ '-333': BigInteger;
+ '-332': BigInteger;
+ '-331': BigInteger;
+ '-330': BigInteger;
+ '-329': BigInteger;
+ '-328': BigInteger;
+ '-327': BigInteger;
+ '-326': BigInteger;
+ '-325': BigInteger;
+ '-324': BigInteger;
+ '-323': BigInteger;
+ '-322': BigInteger;
+ '-321': BigInteger;
+ '-320': BigInteger;
+ '-319': BigInteger;
+ '-318': BigInteger;
+ '-317': BigInteger;
+ '-316': BigInteger;
+ '-315': BigInteger;
+ '-314': BigInteger;
+ '-313': BigInteger;
+ '-312': BigInteger;
+ '-311': BigInteger;
+ '-310': BigInteger;
+ '-309': BigInteger;
+ '-308': BigInteger;
+ '-307': BigInteger;
+ '-306': BigInteger;
+ '-305': BigInteger;
+ '-304': BigInteger;
+ '-303': BigInteger;
+ '-302': BigInteger;
+ '-301': BigInteger;
+ '-300': BigInteger;
+ '-299': BigInteger;
+ '-298': BigInteger;
+ '-297': BigInteger;
+ '-296': BigInteger;
+ '-295': BigInteger;
+ '-294': BigInteger;
+ '-293': BigInteger;
+ '-292': BigInteger;
+ '-291': BigInteger;
+ '-290': BigInteger;
+ '-289': BigInteger;
+ '-288': BigInteger;
+ '-287': BigInteger;
+ '-286': BigInteger;
+ '-285': BigInteger;
+ '-284': BigInteger;
+ '-283': BigInteger;
+ '-282': BigInteger;
+ '-281': BigInteger;
+ '-280': BigInteger;
+ '-279': BigInteger;
+ '-278': BigInteger;
+ '-277': BigInteger;
+ '-276': BigInteger;
+ '-275': BigInteger;
+ '-274': BigInteger;
+ '-273': BigInteger;
+ '-272': BigInteger;
+ '-271': BigInteger;
+ '-270': BigInteger;
+ '-269': BigInteger;
+ '-268': BigInteger;
+ '-267': BigInteger;
+ '-266': BigInteger;
+ '-265': BigInteger;
+ '-264': BigInteger;
+ '-263': BigInteger;
+ '-262': BigInteger;
+ '-261': BigInteger;
+ '-260': BigInteger;
+ '-259': BigInteger;
+ '-258': BigInteger;
+ '-257': BigInteger;
+ '-256': BigInteger;
+ '-255': BigInteger;
+ '-254': BigInteger;
+ '-253': BigInteger;
+ '-252': BigInteger;
+ '-251': BigInteger;
+ '-250': BigInteger;
+ '-249': BigInteger;
+ '-248': BigInteger;
+ '-247': BigInteger;
+ '-246': BigInteger;
+ '-245': BigInteger;
+ '-244': BigInteger;
+ '-243': BigInteger;
+ '-242': BigInteger;
+ '-241': BigInteger;
+ '-240': BigInteger;
+ '-239': BigInteger;
+ '-238': BigInteger;
+ '-237': BigInteger;
+ '-236': BigInteger;
+ '-235': BigInteger;
+ '-234': BigInteger;
+ '-233': BigInteger;
+ '-232': BigInteger;
+ '-231': BigInteger;
+ '-230': BigInteger;
+ '-229': BigInteger;
+ '-228': BigInteger;
+ '-227': BigInteger;
+ '-226': BigInteger;
+ '-225': BigInteger;
+ '-224': BigInteger;
+ '-223': BigInteger;
+ '-222': BigInteger;
+ '-221': BigInteger;
+ '-220': BigInteger;
+ '-219': BigInteger;
+ '-218': BigInteger;
+ '-217': BigInteger;
+ '-216': BigInteger;
+ '-215': BigInteger;
+ '-214': BigInteger;
+ '-213': BigInteger;
+ '-212': BigInteger;
+ '-211': BigInteger;
+ '-210': BigInteger;
+ '-209': BigInteger;
+ '-208': BigInteger;
+ '-207': BigInteger;
+ '-206': BigInteger;
+ '-205': BigInteger;
+ '-204': BigInteger;
+ '-203': BigInteger;
+ '-202': BigInteger;
+ '-201': BigInteger;
+ '-200': BigInteger;
+ '-199': BigInteger;
+ '-198': BigInteger;
+ '-197': BigInteger;
+ '-196': BigInteger;
+ '-195': BigInteger;
+ '-194': BigInteger;
+ '-193': BigInteger;
+ '-192': BigInteger;
+ '-191': BigInteger;
+ '-190': BigInteger;
+ '-189': BigInteger;
+ '-188': BigInteger;
+ '-187': BigInteger;
+ '-186': BigInteger;
+ '-185': BigInteger;
+ '-184': BigInteger;
+ '-183': BigInteger;
+ '-182': BigInteger;
+ '-181': BigInteger;
+ '-180': BigInteger;
+ '-179': BigInteger;
+ '-178': BigInteger;
+ '-177': BigInteger;
+ '-176': BigInteger;
+ '-175': BigInteger;
+ '-174': BigInteger;
+ '-173': BigInteger;
+ '-172': BigInteger;
+ '-171': BigInteger;
+ '-170': BigInteger;
+ '-169': BigInteger;
+ '-168': BigInteger;
+ '-167': BigInteger;
+ '-166': BigInteger;
+ '-165': BigInteger;
+ '-164': BigInteger;
+ '-163': BigInteger;
+ '-162': BigInteger;
+ '-161': BigInteger;
+ '-160': BigInteger;
+ '-159': BigInteger;
+ '-158': BigInteger;
+ '-157': BigInteger;
+ '-156': BigInteger;
+ '-155': BigInteger;
+ '-154': BigInteger;
+ '-153': BigInteger;
+ '-152': BigInteger;
+ '-151': BigInteger;
+ '-150': BigInteger;
+ '-149': BigInteger;
+ '-148': BigInteger;
+ '-147': BigInteger;
+ '-146': BigInteger;
+ '-145': BigInteger;
+ '-144': BigInteger;
+ '-143': BigInteger;
+ '-142': BigInteger;
+ '-141': BigInteger;
+ '-140': BigInteger;
+ '-139': BigInteger;
+ '-138': BigInteger;
+ '-137': BigInteger;
+ '-136': BigInteger;
+ '-135': BigInteger;
+ '-134': BigInteger;
+ '-133': BigInteger;
+ '-132': BigInteger;
+ '-131': BigInteger;
+ '-130': BigInteger;
+ '-129': BigInteger;
+ '-128': BigInteger;
+ '-127': BigInteger;
+ '-126': BigInteger;
+ '-125': BigInteger;
+ '-124': BigInteger;
+ '-123': BigInteger;
+ '-122': BigInteger;
+ '-121': BigInteger;
+ '-120': BigInteger;
+ '-119': BigInteger;
+ '-118': BigInteger;
+ '-117': BigInteger;
+ '-116': BigInteger;
+ '-115': BigInteger;
+ '-114': BigInteger;
+ '-113': BigInteger;
+ '-112': BigInteger;
+ '-111': BigInteger;
+ '-110': BigInteger;
+ '-109': BigInteger;
+ '-108': BigInteger;
+ '-107': BigInteger;
+ '-106': BigInteger;
+ '-105': BigInteger;
+ '-104': BigInteger;
+ '-103': BigInteger;
+ '-102': BigInteger;
+ '-101': BigInteger;
+ '-100': BigInteger;
+ '-99': BigInteger;
+ '-98': BigInteger;
+ '-97': BigInteger;
+ '-96': BigInteger;
+ '-95': BigInteger;
+ '-94': BigInteger;
+ '-93': BigInteger;
+ '-92': BigInteger;
+ '-91': BigInteger;
+ '-90': BigInteger;
+ '-89': BigInteger;
+ '-88': BigInteger;
+ '-87': BigInteger;
+ '-86': BigInteger;
+ '-85': BigInteger;
+ '-84': BigInteger;
+ '-83': BigInteger;
+ '-82': BigInteger;
+ '-81': BigInteger;
+ '-80': BigInteger;
+ '-79': BigInteger;
+ '-78': BigInteger;
+ '-77': BigInteger;
+ '-76': BigInteger;
+ '-75': BigInteger;
+ '-74': BigInteger;
+ '-73': BigInteger;
+ '-72': BigInteger;
+ '-71': BigInteger;
+ '-70': BigInteger;
+ '-69': BigInteger;
+ '-68': BigInteger;
+ '-67': BigInteger;
+ '-66': BigInteger;
+ '-65': BigInteger;
+ '-64': BigInteger;
+ '-63': BigInteger;
+ '-62': BigInteger;
+ '-61': BigInteger;
+ '-60': BigInteger;
+ '-59': BigInteger;
+ '-58': BigInteger;
+ '-57': BigInteger;
+ '-56': BigInteger;
+ '-55': BigInteger;
+ '-54': BigInteger;
+ '-53': BigInteger;
+ '-52': BigInteger;
+ '-51': BigInteger;
+ '-50': BigInteger;
+ '-49': BigInteger;
+ '-48': BigInteger;
+ '-47': BigInteger;
+ '-46': BigInteger;
+ '-45': BigInteger;
+ '-44': BigInteger;
+ '-43': BigInteger;
+ '-42': BigInteger;
+ '-41': BigInteger;
+ '-40': BigInteger;
+ '-39': BigInteger;
+ '-38': BigInteger;
+ '-37': BigInteger;
+ '-36': BigInteger;
+ '-35': BigInteger;
+ '-34': BigInteger;
+ '-33': BigInteger;
+ '-32': BigInteger;
+ '-31': BigInteger;
+ '-30': BigInteger;
+ '-29': BigInteger;
+ '-28': BigInteger;
+ '-27': BigInteger;
+ '-26': BigInteger;
+ '-25': BigInteger;
+ '-24': BigInteger;
+ '-23': BigInteger;
+ '-22': BigInteger;
+ '-21': BigInteger;
+ '-20': BigInteger;
+ '-19': BigInteger;
+ '-18': BigInteger;
+ '-17': BigInteger;
+ '-16': BigInteger;
+ '-15': BigInteger;
+ '-14': BigInteger;
+ '-13': BigInteger;
+ '-12': BigInteger;
+ '-11': BigInteger;
+ '-10': BigInteger;
+ '-9': BigInteger;
+ '-8': BigInteger;
+ '-7': BigInteger;
+ '-6': BigInteger;
+ '-5': BigInteger;
+ '-4': BigInteger;
+ '-3': BigInteger;
+ '-2': BigInteger;
+ '-1': BigInteger;
+ '0': BigInteger;
+ '1': BigInteger;
+ '2': BigInteger;
+ '3': BigInteger;
+ '4': BigInteger;
+ '5': BigInteger;
+ '6': BigInteger;
+ '7': BigInteger;
+ '8': BigInteger;
+ '9': BigInteger;
+ '10': BigInteger;
+ '11': BigInteger;
+ '12': BigInteger;
+ '13': BigInteger;
+ '14': BigInteger;
+ '15': BigInteger;
+ '16': BigInteger;
+ '17': BigInteger;
+ '18': BigInteger;
+ '19': BigInteger;
+ '20': BigInteger;
+ '21': BigInteger;
+ '22': BigInteger;
+ '23': BigInteger;
+ '24': BigInteger;
+ '25': BigInteger;
+ '26': BigInteger;
+ '27': BigInteger;
+ '28': BigInteger;
+ '29': BigInteger;
+ '30': BigInteger;
+ '31': BigInteger;
+ '32': BigInteger;
+ '33': BigInteger;
+ '34': BigInteger;
+ '35': BigInteger;
+ '36': BigInteger;
+ '37': BigInteger;
+ '38': BigInteger;
+ '39': BigInteger;
+ '40': BigInteger;
+ '41': BigInteger;
+ '42': BigInteger;
+ '43': BigInteger;
+ '44': BigInteger;
+ '45': BigInteger;
+ '46': BigInteger;
+ '47': BigInteger;
+ '48': BigInteger;
+ '49': BigInteger;
+ '50': BigInteger;
+ '51': BigInteger;
+ '52': BigInteger;
+ '53': BigInteger;
+ '54': BigInteger;
+ '55': BigInteger;
+ '56': BigInteger;
+ '57': BigInteger;
+ '58': BigInteger;
+ '59': BigInteger;
+ '60': BigInteger;
+ '61': BigInteger;
+ '62': BigInteger;
+ '63': BigInteger;
+ '64': BigInteger;
+ '65': BigInteger;
+ '66': BigInteger;
+ '67': BigInteger;
+ '68': BigInteger;
+ '69': BigInteger;
+ '70': BigInteger;
+ '71': BigInteger;
+ '72': BigInteger;
+ '73': BigInteger;
+ '74': BigInteger;
+ '75': BigInteger;
+ '76': BigInteger;
+ '77': BigInteger;
+ '78': BigInteger;
+ '79': BigInteger;
+ '80': BigInteger;
+ '81': BigInteger;
+ '82': BigInteger;
+ '83': BigInteger;
+ '84': BigInteger;
+ '85': BigInteger;
+ '86': BigInteger;
+ '87': BigInteger;
+ '88': BigInteger;
+ '89': BigInteger;
+ '90': BigInteger;
+ '91': BigInteger;
+ '92': BigInteger;
+ '93': BigInteger;
+ '94': BigInteger;
+ '95': BigInteger;
+ '96': BigInteger;
+ '97': BigInteger;
+ '98': BigInteger;
+ '99': BigInteger;
+ '100': BigInteger;
+ '101': BigInteger;
+ '102': BigInteger;
+ '103': BigInteger;
+ '104': BigInteger;
+ '105': BigInteger;
+ '106': BigInteger;
+ '107': BigInteger;
+ '108': BigInteger;
+ '109': BigInteger;
+ '110': BigInteger;
+ '111': BigInteger;
+ '112': BigInteger;
+ '113': BigInteger;
+ '114': BigInteger;
+ '115': BigInteger;
+ '116': BigInteger;
+ '117': BigInteger;
+ '118': BigInteger;
+ '119': BigInteger;
+ '120': BigInteger;
+ '121': BigInteger;
+ '122': BigInteger;
+ '123': BigInteger;
+ '124': BigInteger;
+ '125': BigInteger;
+ '126': BigInteger;
+ '127': BigInteger;
+ '128': BigInteger;
+ '129': BigInteger;
+ '130': BigInteger;
+ '131': BigInteger;
+ '132': BigInteger;
+ '133': BigInteger;
+ '134': BigInteger;
+ '135': BigInteger;
+ '136': BigInteger;
+ '137': BigInteger;
+ '138': BigInteger;
+ '139': BigInteger;
+ '140': BigInteger;
+ '141': BigInteger;
+ '142': BigInteger;
+ '143': BigInteger;
+ '144': BigInteger;
+ '145': BigInteger;
+ '146': BigInteger;
+ '147': BigInteger;
+ '148': BigInteger;
+ '149': BigInteger;
+ '150': BigInteger;
+ '151': BigInteger;
+ '152': BigInteger;
+ '153': BigInteger;
+ '154': BigInteger;
+ '155': BigInteger;
+ '156': BigInteger;
+ '157': BigInteger;
+ '158': BigInteger;
+ '159': BigInteger;
+ '160': BigInteger;
+ '161': BigInteger;
+ '162': BigInteger;
+ '163': BigInteger;
+ '164': BigInteger;
+ '165': BigInteger;
+ '166': BigInteger;
+ '167': BigInteger;
+ '168': BigInteger;
+ '169': BigInteger;
+ '170': BigInteger;
+ '171': BigInteger;
+ '172': BigInteger;
+ '173': BigInteger;
+ '174': BigInteger;
+ '175': BigInteger;
+ '176': BigInteger;
+ '177': BigInteger;
+ '178': BigInteger;
+ '179': BigInteger;
+ '180': BigInteger;
+ '181': BigInteger;
+ '182': BigInteger;
+ '183': BigInteger;
+ '184': BigInteger;
+ '185': BigInteger;
+ '186': BigInteger;
+ '187': BigInteger;
+ '188': BigInteger;
+ '189': BigInteger;
+ '190': BigInteger;
+ '191': BigInteger;
+ '192': BigInteger;
+ '193': BigInteger;
+ '194': BigInteger;
+ '195': BigInteger;
+ '196': BigInteger;
+ '197': BigInteger;
+ '198': BigInteger;
+ '199': BigInteger;
+ '200': BigInteger;
+ '201': BigInteger;
+ '202': BigInteger;
+ '203': BigInteger;
+ '204': BigInteger;
+ '205': BigInteger;
+ '206': BigInteger;
+ '207': BigInteger;
+ '208': BigInteger;
+ '209': BigInteger;
+ '210': BigInteger;
+ '211': BigInteger;
+ '212': BigInteger;
+ '213': BigInteger;
+ '214': BigInteger;
+ '215': BigInteger;
+ '216': BigInteger;
+ '217': BigInteger;
+ '218': BigInteger;
+ '219': BigInteger;
+ '220': BigInteger;
+ '221': BigInteger;
+ '222': BigInteger;
+ '223': BigInteger;
+ '224': BigInteger;
+ '225': BigInteger;
+ '226': BigInteger;
+ '227': BigInteger;
+ '228': BigInteger;
+ '229': BigInteger;
+ '230': BigInteger;
+ '231': BigInteger;
+ '232': BigInteger;
+ '233': BigInteger;
+ '234': BigInteger;
+ '235': BigInteger;
+ '236': BigInteger;
+ '237': BigInteger;
+ '238': BigInteger;
+ '239': BigInteger;
+ '240': BigInteger;
+ '241': BigInteger;
+ '242': BigInteger;
+ '243': BigInteger;
+ '244': BigInteger;
+ '245': BigInteger;
+ '246': BigInteger;
+ '247': BigInteger;
+ '248': BigInteger;
+ '249': BigInteger;
+ '250': BigInteger;
+ '251': BigInteger;
+ '252': BigInteger;
+ '253': BigInteger;
+ '254': BigInteger;
+ '255': BigInteger;
+ '256': BigInteger;
+ '257': BigInteger;
+ '258': BigInteger;
+ '259': BigInteger;
+ '260': BigInteger;
+ '261': BigInteger;
+ '262': BigInteger;
+ '263': BigInteger;
+ '264': BigInteger;
+ '265': BigInteger;
+ '266': BigInteger;
+ '267': BigInteger;
+ '268': BigInteger;
+ '269': BigInteger;
+ '270': BigInteger;
+ '271': BigInteger;
+ '272': BigInteger;
+ '273': BigInteger;
+ '274': BigInteger;
+ '275': BigInteger;
+ '276': BigInteger;
+ '277': BigInteger;
+ '278': BigInteger;
+ '279': BigInteger;
+ '280': BigInteger;
+ '281': BigInteger;
+ '282': BigInteger;
+ '283': BigInteger;
+ '284': BigInteger;
+ '285': BigInteger;
+ '286': BigInteger;
+ '287': BigInteger;
+ '288': BigInteger;
+ '289': BigInteger;
+ '290': BigInteger;
+ '291': BigInteger;
+ '292': BigInteger;
+ '293': BigInteger;
+ '294': BigInteger;
+ '295': BigInteger;
+ '296': BigInteger;
+ '297': BigInteger;
+ '298': BigInteger;
+ '299': BigInteger;
+ '300': BigInteger;
+ '301': BigInteger;
+ '302': BigInteger;
+ '303': BigInteger;
+ '304': BigInteger;
+ '305': BigInteger;
+ '306': BigInteger;
+ '307': BigInteger;
+ '308': BigInteger;
+ '309': BigInteger;
+ '310': BigInteger;
+ '311': BigInteger;
+ '312': BigInteger;
+ '313': BigInteger;
+ '314': BigInteger;
+ '315': BigInteger;
+ '316': BigInteger;
+ '317': BigInteger;
+ '318': BigInteger;
+ '319': BigInteger;
+ '320': BigInteger;
+ '321': BigInteger;
+ '322': BigInteger;
+ '323': BigInteger;
+ '324': BigInteger;
+ '325': BigInteger;
+ '326': BigInteger;
+ '327': BigInteger;
+ '328': BigInteger;
+ '329': BigInteger;
+ '330': BigInteger;
+ '331': BigInteger;
+ '332': BigInteger;
+ '333': BigInteger;
+ '334': BigInteger;
+ '335': BigInteger;
+ '336': BigInteger;
+ '337': BigInteger;
+ '338': BigInteger;
+ '339': BigInteger;
+ '340': BigInteger;
+ '341': BigInteger;
+ '342': BigInteger;
+ '343': BigInteger;
+ '344': BigInteger;
+ '345': BigInteger;
+ '346': BigInteger;
+ '347': BigInteger;
+ '348': BigInteger;
+ '349': BigInteger;
+ '350': BigInteger;
+ '351': BigInteger;
+ '352': BigInteger;
+ '353': BigInteger;
+ '354': BigInteger;
+ '355': BigInteger;
+ '356': BigInteger;
+ '357': BigInteger;
+ '358': BigInteger;
+ '359': BigInteger;
+ '360': BigInteger;
+ '361': BigInteger;
+ '362': BigInteger;
+ '363': BigInteger;
+ '364': BigInteger;
+ '365': BigInteger;
+ '366': BigInteger;
+ '367': BigInteger;
+ '368': BigInteger;
+ '369': BigInteger;
+ '370': BigInteger;
+ '371': BigInteger;
+ '372': BigInteger;
+ '373': BigInteger;
+ '374': BigInteger;
+ '375': BigInteger;
+ '376': BigInteger;
+ '377': BigInteger;
+ '378': BigInteger;
+ '379': BigInteger;
+ '380': BigInteger;
+ '381': BigInteger;
+ '382': BigInteger;
+ '383': BigInteger;
+ '384': BigInteger;
+ '385': BigInteger;
+ '386': BigInteger;
+ '387': BigInteger;
+ '388': BigInteger;
+ '389': BigInteger;
+ '390': BigInteger;
+ '391': BigInteger;
+ '392': BigInteger;
+ '393': BigInteger;
+ '394': BigInteger;
+ '395': BigInteger;
+ '396': BigInteger;
+ '397': BigInteger;
+ '398': BigInteger;
+ '399': BigInteger;
+ '400': BigInteger;
+ '401': BigInteger;
+ '402': BigInteger;
+ '403': BigInteger;
+ '404': BigInteger;
+ '405': BigInteger;
+ '406': BigInteger;
+ '407': BigInteger;
+ '408': BigInteger;
+ '409': BigInteger;
+ '410': BigInteger;
+ '411': BigInteger;
+ '412': BigInteger;
+ '413': BigInteger;
+ '414': BigInteger;
+ '415': BigInteger;
+ '416': BigInteger;
+ '417': BigInteger;
+ '418': BigInteger;
+ '419': BigInteger;
+ '420': BigInteger;
+ '421': BigInteger;
+ '422': BigInteger;
+ '423': BigInteger;
+ '424': BigInteger;
+ '425': BigInteger;
+ '426': BigInteger;
+ '427': BigInteger;
+ '428': BigInteger;
+ '429': BigInteger;
+ '430': BigInteger;
+ '431': BigInteger;
+ '432': BigInteger;
+ '433': BigInteger;
+ '434': BigInteger;
+ '435': BigInteger;
+ '436': BigInteger;
+ '437': BigInteger;
+ '438': BigInteger;
+ '439': BigInteger;
+ '440': BigInteger;
+ '441': BigInteger;
+ '442': BigInteger;
+ '443': BigInteger;
+ '444': BigInteger;
+ '445': BigInteger;
+ '446': BigInteger;
+ '447': BigInteger;
+ '448': BigInteger;
+ '449': BigInteger;
+ '450': BigInteger;
+ '451': BigInteger;
+ '452': BigInteger;
+ '453': BigInteger;
+ '454': BigInteger;
+ '455': BigInteger;
+ '456': BigInteger;
+ '457': BigInteger;
+ '458': BigInteger;
+ '459': BigInteger;
+ '460': BigInteger;
+ '461': BigInteger;
+ '462': BigInteger;
+ '463': BigInteger;
+ '464': BigInteger;
+ '465': BigInteger;
+ '466': BigInteger;
+ '467': BigInteger;
+ '468': BigInteger;
+ '469': BigInteger;
+ '470': BigInteger;
+ '471': BigInteger;
+ '472': BigInteger;
+ '473': BigInteger;
+ '474': BigInteger;
+ '475': BigInteger;
+ '476': BigInteger;
+ '477': BigInteger;
+ '478': BigInteger;
+ '479': BigInteger;
+ '480': BigInteger;
+ '481': BigInteger;
+ '482': BigInteger;
+ '483': BigInteger;
+ '484': BigInteger;
+ '485': BigInteger;
+ '486': BigInteger;
+ '487': BigInteger;
+ '488': BigInteger;
+ '489': BigInteger;
+ '490': BigInteger;
+ '491': BigInteger;
+ '492': BigInteger;
+ '493': BigInteger;
+ '494': BigInteger;
+ '495': BigInteger;
+ '496': BigInteger;
+ '497': BigInteger;
+ '498': BigInteger;
+ '499': BigInteger;
+ '500': BigInteger;
+ '501': BigInteger;
+ '502': BigInteger;
+ '503': BigInteger;
+ '504': BigInteger;
+ '505': BigInteger;
+ '506': BigInteger;
+ '507': BigInteger;
+ '508': BigInteger;
+ '509': BigInteger;
+ '510': BigInteger;
+ '511': BigInteger;
+ '512': BigInteger;
+ '513': BigInteger;
+ '514': BigInteger;
+ '515': BigInteger;
+ '516': BigInteger;
+ '517': BigInteger;
+ '518': BigInteger;
+ '519': BigInteger;
+ '520': BigInteger;
+ '521': BigInteger;
+ '522': BigInteger;
+ '523': BigInteger;
+ '524': BigInteger;
+ '525': BigInteger;
+ '526': BigInteger;
+ '527': BigInteger;
+ '528': BigInteger;
+ '529': BigInteger;
+ '530': BigInteger;
+ '531': BigInteger;
+ '532': BigInteger;
+ '533': BigInteger;
+ '534': BigInteger;
+ '535': BigInteger;
+ '536': BigInteger;
+ '537': BigInteger;
+ '538': BigInteger;
+ '539': BigInteger;
+ '540': BigInteger;
+ '541': BigInteger;
+ '542': BigInteger;
+ '543': BigInteger;
+ '544': BigInteger;
+ '545': BigInteger;
+ '546': BigInteger;
+ '547': BigInteger;
+ '548': BigInteger;
+ '549': BigInteger;
+ '550': BigInteger;
+ '551': BigInteger;
+ '552': BigInteger;
+ '553': BigInteger;
+ '554': BigInteger;
+ '555': BigInteger;
+ '556': BigInteger;
+ '557': BigInteger;
+ '558': BigInteger;
+ '559': BigInteger;
+ '560': BigInteger;
+ '561': BigInteger;
+ '562': BigInteger;
+ '563': BigInteger;
+ '564': BigInteger;
+ '565': BigInteger;
+ '566': BigInteger;
+ '567': BigInteger;
+ '568': BigInteger;
+ '569': BigInteger;
+ '570': BigInteger;
+ '571': BigInteger;
+ '572': BigInteger;
+ '573': BigInteger;
+ '574': BigInteger;
+ '575': BigInteger;
+ '576': BigInteger;
+ '577': BigInteger;
+ '578': BigInteger;
+ '579': BigInteger;
+ '580': BigInteger;
+ '581': BigInteger;
+ '582': BigInteger;
+ '583': BigInteger;
+ '584': BigInteger;
+ '585': BigInteger;
+ '586': BigInteger;
+ '587': BigInteger;
+ '588': BigInteger;
+ '589': BigInteger;
+ '590': BigInteger;
+ '591': BigInteger;
+ '592': BigInteger;
+ '593': BigInteger;
+ '594': BigInteger;
+ '595': BigInteger;
+ '596': BigInteger;
+ '597': BigInteger;
+ '598': BigInteger;
+ '599': BigInteger;
+ '600': BigInteger;
+ '601': BigInteger;
+ '602': BigInteger;
+ '603': BigInteger;
+ '604': BigInteger;
+ '605': BigInteger;
+ '606': BigInteger;
+ '607': BigInteger;
+ '608': BigInteger;
+ '609': BigInteger;
+ '610': BigInteger;
+ '611': BigInteger;
+ '612': BigInteger;
+ '613': BigInteger;
+ '614': BigInteger;
+ '615': BigInteger;
+ '616': BigInteger;
+ '617': BigInteger;
+ '618': BigInteger;
+ '619': BigInteger;
+ '620': BigInteger;
+ '621': BigInteger;
+ '622': BigInteger;
+ '623': BigInteger;
+ '624': BigInteger;
+ '625': BigInteger;
+ '626': BigInteger;
+ '627': BigInteger;
+ '628': BigInteger;
+ '629': BigInteger;
+ '630': BigInteger;
+ '631': BigInteger;
+ '632': BigInteger;
+ '633': BigInteger;
+ '634': BigInteger;
+ '635': BigInteger;
+ '636': BigInteger;
+ '637': BigInteger;
+ '638': BigInteger;
+ '639': BigInteger;
+ '640': BigInteger;
+ '641': BigInteger;
+ '642': BigInteger;
+ '643': BigInteger;
+ '644': BigInteger;
+ '645': BigInteger;
+ '646': BigInteger;
+ '647': BigInteger;
+ '648': BigInteger;
+ '649': BigInteger;
+ '650': BigInteger;
+ '651': BigInteger;
+ '652': BigInteger;
+ '653': BigInteger;
+ '654': BigInteger;
+ '655': BigInteger;
+ '656': BigInteger;
+ '657': BigInteger;
+ '658': BigInteger;
+ '659': BigInteger;
+ '660': BigInteger;
+ '661': BigInteger;
+ '662': BigInteger;
+ '663': BigInteger;
+ '664': BigInteger;
+ '665': BigInteger;
+ '666': BigInteger;
+ '667': BigInteger;
+ '668': BigInteger;
+ '669': BigInteger;
+ '670': BigInteger;
+ '671': BigInteger;
+ '672': BigInteger;
+ '673': BigInteger;
+ '674': BigInteger;
+ '675': BigInteger;
+ '676': BigInteger;
+ '677': BigInteger;
+ '678': BigInteger;
+ '679': BigInteger;
+ '680': BigInteger;
+ '681': BigInteger;
+ '682': BigInteger;
+ '683': BigInteger;
+ '684': BigInteger;
+ '685': BigInteger;
+ '686': BigInteger;
+ '687': BigInteger;
+ '688': BigInteger;
+ '689': BigInteger;
+ '690': BigInteger;
+ '691': BigInteger;
+ '692': BigInteger;
+ '693': BigInteger;
+ '694': BigInteger;
+ '695': BigInteger;
+ '696': BigInteger;
+ '697': BigInteger;
+ '698': BigInteger;
+ '699': BigInteger;
+ '700': BigInteger;
+ '701': BigInteger;
+ '702': BigInteger;
+ '703': BigInteger;
+ '704': BigInteger;
+ '705': BigInteger;
+ '706': BigInteger;
+ '707': BigInteger;
+ '708': BigInteger;
+ '709': BigInteger;
+ '710': BigInteger;
+ '711': BigInteger;
+ '712': BigInteger;
+ '713': BigInteger;
+ '714': BigInteger;
+ '715': BigInteger;
+ '716': BigInteger;
+ '717': BigInteger;
+ '718': BigInteger;
+ '719': BigInteger;
+ '720': BigInteger;
+ '721': BigInteger;
+ '722': BigInteger;
+ '723': BigInteger;
+ '724': BigInteger;
+ '725': BigInteger;
+ '726': BigInteger;
+ '727': BigInteger;
+ '728': BigInteger;
+ '729': BigInteger;
+ '730': BigInteger;
+ '731': BigInteger;
+ '732': BigInteger;
+ '733': BigInteger;
+ '734': BigInteger;
+ '735': BigInteger;
+ '736': BigInteger;
+ '737': BigInteger;
+ '738': BigInteger;
+ '739': BigInteger;
+ '740': BigInteger;
+ '741': BigInteger;
+ '742': BigInteger;
+ '743': BigInteger;
+ '744': BigInteger;
+ '745': BigInteger;
+ '746': BigInteger;
+ '747': BigInteger;
+ '748': BigInteger;
+ '749': BigInteger;
+ '750': BigInteger;
+ '751': BigInteger;
+ '752': BigInteger;
+ '753': BigInteger;
+ '754': BigInteger;
+ '755': BigInteger;
+ '756': BigInteger;
+ '757': BigInteger;
+ '758': BigInteger;
+ '759': BigInteger;
+ '760': BigInteger;
+ '761': BigInteger;
+ '762': BigInteger;
+ '763': BigInteger;
+ '764': BigInteger;
+ '765': BigInteger;
+ '766': BigInteger;
+ '767': BigInteger;
+ '768': BigInteger;
+ '769': BigInteger;
+ '770': BigInteger;
+ '771': BigInteger;
+ '772': BigInteger;
+ '773': BigInteger;
+ '774': BigInteger;
+ '775': BigInteger;
+ '776': BigInteger;
+ '777': BigInteger;
+ '778': BigInteger;
+ '779': BigInteger;
+ '780': BigInteger;
+ '781': BigInteger;
+ '782': BigInteger;
+ '783': BigInteger;
+ '784': BigInteger;
+ '785': BigInteger;
+ '786': BigInteger;
+ '787': BigInteger;
+ '788': BigInteger;
+ '789': BigInteger;
+ '790': BigInteger;
+ '791': BigInteger;
+ '792': BigInteger;
+ '793': BigInteger;
+ '794': BigInteger;
+ '795': BigInteger;
+ '796': BigInteger;
+ '797': BigInteger;
+ '798': BigInteger;
+ '799': BigInteger;
+ '800': BigInteger;
+ '801': BigInteger;
+ '802': BigInteger;
+ '803': BigInteger;
+ '804': BigInteger;
+ '805': BigInteger;
+ '806': BigInteger;
+ '807': BigInteger;
+ '808': BigInteger;
+ '809': BigInteger;
+ '810': BigInteger;
+ '811': BigInteger;
+ '812': BigInteger;
+ '813': BigInteger;
+ '814': BigInteger;
+ '815': BigInteger;
+ '816': BigInteger;
+ '817': BigInteger;
+ '818': BigInteger;
+ '819': BigInteger;
+ '820': BigInteger;
+ '821': BigInteger;
+ '822': BigInteger;
+ '823': BigInteger;
+ '824': BigInteger;
+ '825': BigInteger;
+ '826': BigInteger;
+ '827': BigInteger;
+ '828': BigInteger;
+ '829': BigInteger;
+ '830': BigInteger;
+ '831': BigInteger;
+ '832': BigInteger;
+ '833': BigInteger;
+ '834': BigInteger;
+ '835': BigInteger;
+ '836': BigInteger;
+ '837': BigInteger;
+ '838': BigInteger;
+ '839': BigInteger;
+ '840': BigInteger;
+ '841': BigInteger;
+ '842': BigInteger;
+ '843': BigInteger;
+ '844': BigInteger;
+ '845': BigInteger;
+ '846': BigInteger;
+ '847': BigInteger;
+ '848': BigInteger;
+ '849': BigInteger;
+ '850': BigInteger;
+ '851': BigInteger;
+ '852': BigInteger;
+ '853': BigInteger;
+ '854': BigInteger;
+ '855': BigInteger;
+ '856': BigInteger;
+ '857': BigInteger;
+ '858': BigInteger;
+ '859': BigInteger;
+ '860': BigInteger;
+ '861': BigInteger;
+ '862': BigInteger;
+ '863': BigInteger;
+ '864': BigInteger;
+ '865': BigInteger;
+ '866': BigInteger;
+ '867': BigInteger;
+ '868': BigInteger;
+ '869': BigInteger;
+ '870': BigInteger;
+ '871': BigInteger;
+ '872': BigInteger;
+ '873': BigInteger;
+ '874': BigInteger;
+ '875': BigInteger;
+ '876': BigInteger;
+ '877': BigInteger;
+ '878': BigInteger;
+ '879': BigInteger;
+ '880': BigInteger;
+ '881': BigInteger;
+ '882': BigInteger;
+ '883': BigInteger;
+ '884': BigInteger;
+ '885': BigInteger;
+ '886': BigInteger;
+ '887': BigInteger;
+ '888': BigInteger;
+ '889': BigInteger;
+ '890': BigInteger;
+ '891': BigInteger;
+ '892': BigInteger;
+ '893': BigInteger;
+ '894': BigInteger;
+ '895': BigInteger;
+ '896': BigInteger;
+ '897': BigInteger;
+ '898': BigInteger;
+ '899': BigInteger;
+ '900': BigInteger;
+ '901': BigInteger;
+ '902': BigInteger;
+ '903': BigInteger;
+ '904': BigInteger;
+ '905': BigInteger;
+ '906': BigInteger;
+ '907': BigInteger;
+ '908': BigInteger;
+ '909': BigInteger;
+ '910': BigInteger;
+ '911': BigInteger;
+ '912': BigInteger;
+ '913': BigInteger;
+ '914': BigInteger;
+ '915': BigInteger;
+ '916': BigInteger;
+ '917': BigInteger;
+ '918': BigInteger;
+ '919': BigInteger;
+ '920': BigInteger;
+ '921': BigInteger;
+ '922': BigInteger;
+ '923': BigInteger;
+ '924': BigInteger;
+ '925': BigInteger;
+ '926': BigInteger;
+ '927': BigInteger;
+ '928': BigInteger;
+ '929': BigInteger;
+ '930': BigInteger;
+ '931': BigInteger;
+ '932': BigInteger;
+ '933': BigInteger;
+ '934': BigInteger;
+ '935': BigInteger;
+ '936': BigInteger;
+ '937': BigInteger;
+ '938': BigInteger;
+ '939': BigInteger;
+ '940': BigInteger;
+ '941': BigInteger;
+ '942': BigInteger;
+ '943': BigInteger;
+ '944': BigInteger;
+ '945': BigInteger;
+ '946': BigInteger;
+ '947': BigInteger;
+ '948': BigInteger;
+ '949': BigInteger;
+ '950': BigInteger;
+ '951': BigInteger;
+ '952': BigInteger;
+ '953': BigInteger;
+ '954': BigInteger;
+ '955': BigInteger;
+ '956': BigInteger;
+ '957': BigInteger;
+ '958': BigInteger;
+ '959': BigInteger;
+ '960': BigInteger;
+ '961': BigInteger;
+ '962': BigInteger;
+ '963': BigInteger;
+ '964': BigInteger;
+ '965': BigInteger;
+ '966': BigInteger;
+ '967': BigInteger;
+ '968': BigInteger;
+ '969': BigInteger;
+ '970': BigInteger;
+ '971': BigInteger;
+ '972': BigInteger;
+ '973': BigInteger;
+ '974': BigInteger;
+ '975': BigInteger;
+ '976': BigInteger;
+ '977': BigInteger;
+ '978': BigInteger;
+ '979': BigInteger;
+ '980': BigInteger;
+ '981': BigInteger;
+ '982': BigInteger;
+ '983': BigInteger;
+ '984': BigInteger;
+ '985': BigInteger;
+ '986': BigInteger;
+ '987': BigInteger;
+ '988': BigInteger;
+ '989': BigInteger;
+ '990': BigInteger;
+ '991': BigInteger;
+ '992': BigInteger;
+ '993': BigInteger;
+ '994': BigInteger;
+ '995': BigInteger;
+ '996': BigInteger;
+ '997': BigInteger;
+ '998': BigInteger;
+ '999': BigInteger;
+ }
+
+ interface BaseArray {
+ value: number[],
+ isNegative: boolean
+ }
+}
diff --git a/big-integer/BigInteger.js b/big-integer/BigInteger.js
new file mode 100644
index 0000000..228d36b
--- /dev/null
+++ b/big-integer/BigInteger.js
@@ -0,0 +1,1436 @@
+var bigInt = (function (undefined) {
+ "use strict";
+
+ var BASE = 1e7,
+ LOG_BASE = 7,
+ MAX_INT = 9007199254740992,
+ MAX_INT_ARR = smallToArray(MAX_INT),
+ DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ var supportsNativeBigInt = typeof BigInt === "function";
+
+ function Integer(v, radix, alphabet, caseSensitive) {
+ if (typeof v === "undefined") return Integer[0];
+ if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
+ return parseValue(v);
+ }
+
+ function BigInteger(value, sign) {
+ this.value = value;
+ this.sign = sign;
+ this.isSmall = false;
+ }
+ BigInteger.prototype = Object.create(Integer.prototype);
+
+ function SmallInteger(value) {
+ this.value = value;
+ this.sign = value < 0;
+ this.isSmall = true;
+ }
+ SmallInteger.prototype = Object.create(Integer.prototype);
+
+ function NativeBigInt(value) {
+ this.value = value;
+ }
+ NativeBigInt.prototype = Object.create(Integer.prototype);
+
+ function isPrecise(n) {
+ return -MAX_INT < n && n < MAX_INT;
+ }
+
+ function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
+ if (n < 1e7)
+ return [n];
+ if (n < 1e14)
+ return [n % 1e7, Math.floor(n / 1e7)];
+ return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
+ }
+
+ function arrayToSmall(arr) { // If BASE changes this function may need to change
+ trim(arr);
+ var length = arr.length;
+ if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
+ switch (length) {
+ case 0: return 0;
+ case 1: return arr[0];
+ case 2: return arr[0] + arr[1] * BASE;
+ default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
+ }
+ }
+ return arr;
+ }
+
+ function trim(v) {
+ var i = v.length;
+ while (v[--i] === 0);
+ v.length = i + 1;
+ }
+
+ function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
+ var x = new Array(length);
+ var i = -1;
+ while (++i < length) {
+ x[i] = 0;
+ }
+ return x;
+ }
+
+ function truncate(n) {
+ if (n > 0) return Math.floor(n);
+ return Math.ceil(n);
+ }
+
+ function add(a, b) { // assumes a and b are arrays with a.length >= b.length
+ var l_a = a.length,
+ l_b = b.length,
+ r = new Array(l_a),
+ carry = 0,
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l_b; i++) {
+ sum = a[i] + b[i] + carry;
+ carry = sum >= base ? 1 : 0;
+ r[i] = sum - carry * base;
+ }
+ while (i < l_a) {
+ sum = a[i] + carry;
+ carry = sum === base ? 1 : 0;
+ r[i++] = sum - carry * base;
+ }
+ if (carry > 0) r.push(carry);
+ return r;
+ }
+
+ function addAny(a, b) {
+ if (a.length >= b.length) return add(a, b);
+ return add(b, a);
+ }
+
+ function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l; i++) {
+ sum = a[i] - base + carry;
+ carry = Math.floor(sum / base);
+ r[i] = sum - carry * base;
+ carry += 1;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ BigInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall) {
+ return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
+ }
+ return new BigInteger(addAny(a, b), this.sign);
+ };
+ BigInteger.prototype.plus = BigInteger.prototype.add;
+
+ SmallInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ if (isPrecise(a + b)) return new SmallInteger(a + b);
+ b = smallToArray(Math.abs(b));
+ }
+ return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
+ };
+ SmallInteger.prototype.plus = SmallInteger.prototype.add;
+
+ NativeBigInt.prototype.add = function (v) {
+ return new NativeBigInt(this.value + parseValue(v).value);
+ }
+ NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
+
+ function subtract(a, b) { // assumes a and b are arrays with a >= b
+ var a_l = a.length,
+ b_l = b.length,
+ r = new Array(a_l),
+ borrow = 0,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < b_l; i++) {
+ difference = a[i] - borrow - b[i];
+ if (difference < 0) {
+ difference += base;
+ borrow = 1;
+ } else borrow = 0;
+ r[i] = difference;
+ }
+ for (i = b_l; i < a_l; i++) {
+ difference = a[i] - borrow;
+ if (difference < 0) difference += base;
+ else {
+ r[i++] = difference;
+ break;
+ }
+ r[i] = difference;
+ }
+ for (; i < a_l; i++) {
+ r[i] = a[i];
+ }
+ trim(r);
+ return r;
+ }
+
+ function subtractAny(a, b, sign) {
+ var value;
+ if (compareAbs(a, b) >= 0) {
+ value = subtract(a, b);
+ } else {
+ value = subtract(b, a);
+ sign = !sign;
+ }
+ value = arrayToSmall(value);
+ if (typeof value === "number") {
+ if (sign) value = -value;
+ return new SmallInteger(value);
+ }
+ return new BigInteger(value, sign);
+ }
+
+ function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ carry = -b,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < l; i++) {
+ difference = a[i] + carry;
+ carry = Math.floor(difference / base);
+ difference %= base;
+ r[i] = difference < 0 ? difference + base : difference;
+ }
+ r = arrayToSmall(r);
+ if (typeof r === "number") {
+ if (sign) r = -r;
+ return new SmallInteger(r);
+ } return new BigInteger(r, sign);
+ }
+
+ BigInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.add(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall)
+ return subtractSmall(a, Math.abs(b), this.sign);
+ return subtractAny(a, b, this.sign);
+ };
+ BigInteger.prototype.minus = BigInteger.prototype.subtract;
+
+ SmallInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.add(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ return new SmallInteger(a - b);
+ }
+ return subtractSmall(b, Math.abs(a), a >= 0);
+ };
+ SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
+
+ NativeBigInt.prototype.subtract = function (v) {
+ return new NativeBigInt(this.value - parseValue(v).value);
+ }
+ NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
+
+ BigInteger.prototype.negate = function () {
+ return new BigInteger(this.value, !this.sign);
+ };
+ SmallInteger.prototype.negate = function () {
+ var sign = this.sign;
+ var small = new SmallInteger(-this.value);
+ small.sign = !sign;
+ return small;
+ };
+ NativeBigInt.prototype.negate = function () {
+ return new NativeBigInt(-this.value);
+ }
+
+ BigInteger.prototype.abs = function () {
+ return new BigInteger(this.value, false);
+ };
+ SmallInteger.prototype.abs = function () {
+ return new SmallInteger(Math.abs(this.value));
+ };
+ NativeBigInt.prototype.abs = function () {
+ return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
+ }
+
+
+ function multiplyLong(a, b) {
+ var a_l = a.length,
+ b_l = b.length,
+ l = a_l + b_l,
+ r = createArray(l),
+ base = BASE,
+ product, carry, i, a_i, b_j;
+ for (i = 0; i < a_l; ++i) {
+ a_i = a[i];
+ for (var j = 0; j < b_l; ++j) {
+ b_j = b[j];
+ product = a_i * b_j + r[i + j];
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ r[i + j + 1] += carry;
+ }
+ }
+ trim(r);
+ return r;
+ }
+
+ function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ carry = 0,
+ product, i;
+ for (i = 0; i < l; i++) {
+ product = a[i] * b + carry;
+ carry = Math.floor(product / base);
+ r[i] = product - carry * base;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ function shiftLeft(x, n) {
+ var r = [];
+ while (n-- > 0) r.push(0);
+ return r.concat(x);
+ }
+
+ function multiplyKaratsuba(x, y) {
+ var n = Math.max(x.length, y.length);
+
+ if (n <= 30) return multiplyLong(x, y);
+ n = Math.ceil(n / 2);
+
+ var b = x.slice(n),
+ a = x.slice(0, n),
+ d = y.slice(n),
+ c = y.slice(0, n);
+
+ var ac = multiplyKaratsuba(a, c),
+ bd = multiplyKaratsuba(b, d),
+ abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
+
+ var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
+ trim(product);
+ return product;
+ }
+
+ // The following function is derived from a surface fit of a graph plotting the performance difference
+ // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
+ function useKaratsuba(l1, l2) {
+ return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
+ }
+
+ BigInteger.prototype.multiply = function (v) {
+ var n = parseValue(v),
+ a = this.value, b = n.value,
+ sign = this.sign !== n.sign,
+ abs;
+ if (n.isSmall) {
+ if (b === 0) return Integer[0];
+ if (b === 1) return this;
+ if (b === -1) return this.negate();
+ abs = Math.abs(b);
+ if (abs < BASE) {
+ return new BigInteger(multiplySmall(a, abs), sign);
+ }
+ b = smallToArray(abs);
+ }
+ if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
+ return new BigInteger(multiplyKaratsuba(a, b), sign);
+ return new BigInteger(multiplyLong(a, b), sign);
+ };
+
+ BigInteger.prototype.times = BigInteger.prototype.multiply;
+
+ function multiplySmallAndArray(a, b, sign) { // a >= 0
+ if (a < BASE) {
+ return new BigInteger(multiplySmall(b, a), sign);
+ }
+ return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
+ }
+ SmallInteger.prototype._multiplyBySmall = function (a) {
+ if (isPrecise(a.value * this.value)) {
+ return new SmallInteger(a.value * this.value);
+ }
+ return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
+ };
+ BigInteger.prototype._multiplyBySmall = function (a) {
+ if (a.value === 0) return Integer[0];
+ if (a.value === 1) return this;
+ if (a.value === -1) return this.negate();
+ return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
+ };
+ SmallInteger.prototype.multiply = function (v) {
+ return parseValue(v)._multiplyBySmall(this);
+ };
+ SmallInteger.prototype.times = SmallInteger.prototype.multiply;
+
+ NativeBigInt.prototype.multiply = function (v) {
+ return new NativeBigInt(this.value * parseValue(v).value);
+ }
+ NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
+
+ function square(a) {
+ //console.assert(2 * BASE * BASE < MAX_INT);
+ var l = a.length,
+ r = createArray(l + l),
+ base = BASE,
+ product, carry, i, a_i, a_j;
+ for (i = 0; i < l; i++) {
+ a_i = a[i];
+ carry = 0 - a_i * a_i;
+ for (var j = i; j < l; j++) {
+ a_j = a[j];
+ product = 2 * (a_i * a_j) + r[i + j] + carry;
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ }
+ r[i + l] = carry;
+ }
+ trim(r);
+ return r;
+ }
+
+ BigInteger.prototype.square = function () {
+ return new BigInteger(square(this.value), false);
+ };
+
+ SmallInteger.prototype.square = function () {
+ var value = this.value * this.value;
+ if (isPrecise(value)) return new SmallInteger(value);
+ return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
+ };
+
+ NativeBigInt.prototype.square = function (v) {
+ return new NativeBigInt(this.value * this.value);
+ }
+
+ function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ base = BASE,
+ result = createArray(b.length),
+ divisorMostSignificantDigit = b[b_l - 1],
+ // normalization
+ lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
+ remainder = multiplySmall(a, lambda),
+ divisor = multiplySmall(b, lambda),
+ quotientDigit, shift, carry, borrow, i, l, q;
+ if (remainder.length <= a_l) remainder.push(0);
+ divisor.push(0);
+ divisorMostSignificantDigit = divisor[b_l - 1];
+ for (shift = a_l - b_l; shift >= 0; shift--) {
+ quotientDigit = base - 1;
+ if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
+ quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
+ }
+ // quotientDigit <= base - 1
+ carry = 0;
+ borrow = 0;
+ l = divisor.length;
+ for (i = 0; i < l; i++) {
+ carry += quotientDigit * divisor[i];
+ q = Math.floor(carry / base);
+ borrow += remainder[shift + i] - (carry - q * base);
+ carry = q;
+ if (borrow < 0) {
+ remainder[shift + i] = borrow + base;
+ borrow = -1;
+ } else {
+ remainder[shift + i] = borrow;
+ borrow = 0;
+ }
+ }
+ while (borrow !== 0) {
+ quotientDigit -= 1;
+ carry = 0;
+ for (i = 0; i < l; i++) {
+ carry += remainder[shift + i] - base + divisor[i];
+ if (carry < 0) {
+ remainder[shift + i] = carry + base;
+ carry = 0;
+ } else {
+ remainder[shift + i] = carry;
+ carry = 1;
+ }
+ }
+ borrow += carry;
+ }
+ result[shift] = quotientDigit;
+ }
+ // denormalization
+ remainder = divModSmall(remainder, lambda)[0];
+ return [arrayToSmall(result), arrayToSmall(remainder)];
+ }
+
+ function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
+ // Performs faster than divMod1 on larger input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ result = [],
+ part = [],
+ base = BASE,
+ guess, xlen, highx, highy, check;
+ while (a_l) {
+ part.unshift(a[--a_l]);
+ trim(part);
+ if (compareAbs(part, b) < 0) {
+ result.push(0);
+ continue;
+ }
+ xlen = part.length;
+ highx = part[xlen - 1] * base + part[xlen - 2];
+ highy = b[b_l - 1] * base + b[b_l - 2];
+ if (xlen > b_l) {
+ highx = (highx + 1) * base;
+ }
+ guess = Math.ceil(highx / highy);
+ do {
+ check = multiplySmall(b, guess);
+ if (compareAbs(check, part) <= 0) break;
+ guess--;
+ } while (guess);
+ result.push(guess);
+ part = subtract(part, check);
+ }
+ result.reverse();
+ return [arrayToSmall(result), arrayToSmall(part)];
+ }
+
+ function divModSmall(value, lambda) {
+ var length = value.length,
+ quotient = createArray(length),
+ base = BASE,
+ i, q, remainder, divisor;
+ remainder = 0;
+ for (i = length - 1; i >= 0; --i) {
+ divisor = remainder * base + value[i];
+ q = truncate(divisor / lambda);
+ remainder = divisor - q * lambda;
+ quotient[i] = q | 0;
+ }
+ return [quotient, remainder | 0];
+ }
+
+ function divModAny(self, v) {
+ var value, n = parseValue(v);
+ if (supportsNativeBigInt) {
+ return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
+ }
+ var a = self.value, b = n.value;
+ var quotient;
+ if (b === 0) throw new Error("Cannot divide by zero");
+ if (self.isSmall) {
+ if (n.isSmall) {
+ return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
+ }
+ return [Integer[0], self];
+ }
+ if (n.isSmall) {
+ if (b === 1) return [self, Integer[0]];
+ if (b == -1) return [self.negate(), Integer[0]];
+ var abs = Math.abs(b);
+ if (abs < BASE) {
+ value = divModSmall(a, abs);
+ quotient = arrayToSmall(value[0]);
+ var remainder = value[1];
+ if (self.sign) remainder = -remainder;
+ if (typeof quotient === "number") {
+ if (self.sign !== n.sign) quotient = -quotient;
+ return [new SmallInteger(quotient), new SmallInteger(remainder)];
+ }
+ return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
+ }
+ b = smallToArray(abs);
+ }
+ var comparison = compareAbs(a, b);
+ if (comparison === -1) return [Integer[0], self];
+ if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
+
+ // divMod1 is faster on smaller input sizes
+ if (a.length + b.length <= 200)
+ value = divMod1(a, b);
+ else value = divMod2(a, b);
+
+ quotient = value[0];
+ var qSign = self.sign !== n.sign,
+ mod = value[1],
+ mSign = self.sign;
+ if (typeof quotient === "number") {
+ if (qSign) quotient = -quotient;
+ quotient = new SmallInteger(quotient);
+ } else quotient = new BigInteger(quotient, qSign);
+ if (typeof mod === "number") {
+ if (mSign) mod = -mod;
+ mod = new SmallInteger(mod);
+ } else mod = new BigInteger(mod, mSign);
+ return [quotient, mod];
+ }
+
+ BigInteger.prototype.divmod = function (v) {
+ var result = divModAny(this, v);
+ return {
+ quotient: result[0],
+ remainder: result[1]
+ };
+ };
+ NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
+
+
+ BigInteger.prototype.divide = function (v) {
+ return divModAny(this, v)[0];
+ };
+ NativeBigInt.prototype.over = NativeBigInt.prototype.divide = SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
+
+ BigInteger.prototype.mod = function (v) {
+ return divModAny(this, v)[1];
+ };
+ NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
+
+ BigInteger.prototype.pow = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value,
+ value, x, y;
+ if (b === 0) return Integer[1];
+ if (a === 0) return Integer[0];
+ if (a === 1) return Integer[1];
+ if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.sign) {
+ return Integer[0];
+ }
+ if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
+ if (this.isSmall) {
+ if (isPrecise(value = Math.pow(a, b)))
+ return new SmallInteger(truncate(value));
+ }
+ x = this;
+ y = Integer[1];
+ while (true) {
+ if (b & 1 === 1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === 0) break;
+ b /= 2;
+ x = x.square();
+ }
+ return y;
+ };
+ SmallInteger.prototype.pow = BigInteger.prototype.pow;
+
+ var pow;
+ if (supportsNativeBigInt) {
+ // forced to use eval because ** is a syntax error on pre-ECMAScript2017 environments.
+ pow = eval("(a,b)=>a**b");
+ }
+
+ NativeBigInt.prototype.pow = function (v) {
+ var n = parseValue(v);
+ var a = this.value, b = n.value;
+ if (b === BigInt(0)) return Integer[1];
+ if (a === BigInt(0)) return Integer[0];
+ if (a === BigInt(1)) return Integer[1];
+ if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.isNegative()) return new NativeBigInt(BigInt(0));
+ return new NativeBigInt(pow(a, b));
+ }
+
+ BigInteger.prototype.modPow = function (exp, mod) {
+ exp = parseValue(exp);
+ mod = parseValue(mod);
+ if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
+ var r = Integer[1],
+ base = this.mod(mod);
+ while (exp.isPositive()) {
+ if (base.isZero()) return Integer[0];
+ if (exp.isOdd()) r = r.multiply(base).mod(mod);
+ exp = exp.divide(2);
+ base = base.square().mod(mod);
+ }
+ return r;
+ };
+ NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
+
+ function compareAbs(a, b) {
+ if (a.length !== b.length) {
+ return a.length > b.length ? 1 : -1;
+ }
+ for (var i = a.length - 1; i >= 0; i--) {
+ if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
+ }
+ return 0;
+ }
+
+ BigInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) return 1;
+ return compareAbs(a, b);
+ };
+ SmallInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = Math.abs(this.value),
+ b = n.value;
+ if (n.isSmall) {
+ b = Math.abs(b);
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ return -1;
+ };
+ NativeBigInt.prototype.compareAbs = function (v) {
+ var a = this.value;
+ var b = parseValue(v).value;
+ a = a >= 0 ? a : -a;
+ b = b >= 0 ? b : -b;
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+
+ BigInteger.prototype.compare = function (v) {
+ // See discussion about comparison with Infinity:
+ // https://github.com/peterolson/BigInteger.js/issues/61
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (this.sign !== n.sign) {
+ return n.sign ? 1 : -1;
+ }
+ if (n.isSmall) {
+ return this.sign ? -1 : 1;
+ }
+ return compareAbs(a, b) * (this.sign ? -1 : 1);
+ };
+ BigInteger.prototype.compareTo = BigInteger.prototype.compare;
+
+ SmallInteger.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) {
+ return a == b ? 0 : a > b ? 1 : -1;
+ }
+ if (a < 0 !== n.sign) {
+ return a < 0 ? -1 : 1;
+ }
+ return a < 0 ? 1 : -1;
+ };
+ SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
+
+ NativeBigInt.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+ var a = this.value;
+ var b = parseValue(v).value;
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
+
+ BigInteger.prototype.equals = function (v) {
+ return this.compare(v) === 0;
+ };
+ NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
+
+ BigInteger.prototype.notEquals = function (v) {
+ return this.compare(v) !== 0;
+ };
+ NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
+
+ BigInteger.prototype.greater = function (v) {
+ return this.compare(v) > 0;
+ };
+ NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
+
+ BigInteger.prototype.lesser = function (v) {
+ return this.compare(v) < 0;
+ };
+ NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
+
+ BigInteger.prototype.greaterOrEquals = function (v) {
+ return this.compare(v) >= 0;
+ };
+ NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
+
+ BigInteger.prototype.lesserOrEquals = function (v) {
+ return this.compare(v) <= 0;
+ };
+ NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
+
+ BigInteger.prototype.isEven = function () {
+ return (this.value[0] & 1) === 0;
+ };
+ SmallInteger.prototype.isEven = function () {
+ return (this.value & 1) === 0;
+ };
+ NativeBigInt.prototype.isEven = function () {
+ return (this.value & BigInt(1)) === BigInt(0);
+ }
+
+ BigInteger.prototype.isOdd = function () {
+ return (this.value[0] & 1) === 1;
+ };
+ SmallInteger.prototype.isOdd = function () {
+ return (this.value & 1) === 1;
+ };
+ NativeBigInt.prototype.isOdd = function () {
+ return (this.value & BigInt(1)) === BigInt(1);
+ }
+
+ BigInteger.prototype.isPositive = function () {
+ return !this.sign;
+ };
+ SmallInteger.prototype.isPositive = function () {
+ return this.value > 0;
+ };
+ NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
+
+ BigInteger.prototype.isNegative = function () {
+ return this.sign;
+ };
+ SmallInteger.prototype.isNegative = function () {
+ return this.value < 0;
+ };
+ NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
+
+ BigInteger.prototype.isUnit = function () {
+ return false;
+ };
+ SmallInteger.prototype.isUnit = function () {
+ return Math.abs(this.value) === 1;
+ };
+ NativeBigInt.prototype.isUnit = function () {
+ return this.abs().value === BigInt(1);
+ }
+
+ BigInteger.prototype.isZero = function () {
+ return false;
+ };
+ SmallInteger.prototype.isZero = function () {
+ return this.value === 0;
+ };
+ NativeBigInt.prototype.isZero = function () {
+ return this.value === BigInt(0);
+ }
+
+ BigInteger.prototype.isDivisibleBy = function (v) {
+ var n = parseValue(v);
+ if (n.isZero()) return false;
+ if (n.isUnit()) return true;
+ if (n.compareAbs(2) === 0) return this.isEven();
+ return this.mod(n).isZero();
+ };
+ NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
+
+ function isBasicPrime(v) {
+ var n = v.abs();
+ if (n.isUnit()) return false;
+ if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
+ if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
+ if (n.lesser(49)) return true;
+ // we don't know if it's prime: let the other functions figure it out
+ }
+
+ function millerRabinTest(n, a) {
+ var nPrev = n.prev(),
+ b = nPrev,
+ r = 0,
+ d, t, i, x;
+ while (b.isEven()) b = b.divide(2), r++;
+ next: for (i = 0; i < a.length; i++) {
+ if (n.lesser(a[i])) continue;
+ x = bigInt(a[i]).modPow(b, n);
+ if (x.isUnit() || x.equals(nPrev)) continue;
+ for (d = r - 1; d != 0; d--) {
+ x = x.square().mod(n);
+ if (x.isUnit()) return false;
+ if (x.equals(nPrev)) continue next;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
+ BigInteger.prototype.isPrime = function (strict) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined) return isPrime;
+ var n = this.abs();
+ var bits = n.bitLength();
+ if (bits <= 64)
+ return millerRabinTest(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]);
+ var logN = Math.log(2) * bits.toJSNumber();
+ var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt(i + 2));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
+
+ BigInteger.prototype.isProbablePrime = function (iterations) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined) return isPrime;
+ var n = this.abs();
+ var t = iterations === undefined ? 5 : iterations;
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt.randBetween(2, n.minus(2)));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
+
+ BigInteger.prototype.modInv = function (n) {
+ var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
+ while (!newR.isZero()) {
+ q = r.divide(newR);
+ lastT = t;
+ lastR = r;
+ t = newT;
+ r = newR;
+ newT = lastT.subtract(q.multiply(newT));
+ newR = lastR.subtract(q.multiply(newR));
+ }
+ if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
+ if (t.compare(0) === -1) {
+ t = t.add(n);
+ }
+ if (this.isNegative()) {
+ return t.negate();
+ }
+ return t;
+ };
+
+ NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
+
+ BigInteger.prototype.next = function () {
+ var value = this.value;
+ if (this.sign) {
+ return subtractSmall(value, 1, this.sign);
+ }
+ return new BigInteger(addSmall(value, 1), this.sign);
+ };
+ SmallInteger.prototype.next = function () {
+ var value = this.value;
+ if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
+ return new BigInteger(MAX_INT_ARR, false);
+ };
+ NativeBigInt.prototype.next = function () {
+ return new NativeBigInt(this.value + BigInt(1));
+ }
+
+ BigInteger.prototype.prev = function () {
+ var value = this.value;
+ if (this.sign) {
+ return new BigInteger(addSmall(value, 1), true);
+ }
+ return subtractSmall(value, 1, this.sign);
+ };
+ SmallInteger.prototype.prev = function () {
+ var value = this.value;
+ if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
+ return new BigInteger(MAX_INT_ARR, true);
+ };
+ NativeBigInt.prototype.prev = function () {
+ return new NativeBigInt(this.value - BigInt(1));
+ }
+
+ var powersOfTwo = [1];
+ while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
+ var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
+
+ function shift_isSmall(n) {
+ return Math.abs(n) <= BASE;
+ }
+
+ BigInteger.prototype.shiftLeft = function (v) {
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftRight(-n);
+ var result = this;
+ if (result.isZero()) return result;
+ while (n >= powers2Length) {
+ result = result.multiply(highestPower2);
+ n -= powers2Length - 1;
+ }
+ return result.multiply(powersOfTwo[n]);
+ };
+ NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
+
+ BigInteger.prototype.shiftRight = function (v) {
+ var remQuo;
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftLeft(-n);
+ var result = this;
+ while (n >= powers2Length) {
+ if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
+ remQuo = divModAny(result, highestPower2);
+ result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ n -= powers2Length - 1;
+ }
+ remQuo = divModAny(result, powersOfTwo[n]);
+ return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ };
+ NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
+
+ function bitwise(x, y, fn) {
+ y = parseValue(y);
+ var xSign = x.isNegative(), ySign = y.isNegative();
+ var xRem = xSign ? x.not() : x,
+ yRem = ySign ? y.not() : y;
+ var xDigit = 0, yDigit = 0;
+ var xDivMod = null, yDivMod = null;
+ var result = [];
+ while (!xRem.isZero() || !yRem.isZero()) {
+ xDivMod = divModAny(xRem, highestPower2);
+ xDigit = xDivMod[1].toJSNumber();
+ if (xSign) {
+ xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
+ }
+
+ yDivMod = divModAny(yRem, highestPower2);
+ yDigit = yDivMod[1].toJSNumber();
+ if (ySign) {
+ yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
+ }
+
+ xRem = xDivMod[0];
+ yRem = yDivMod[0];
+ result.push(fn(xDigit, yDigit));
+ }
+ var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
+ for (var i = result.length - 1; i >= 0; i -= 1) {
+ sum = sum.multiply(highestPower2).add(bigInt(result[i]));
+ }
+ return sum;
+ }
+
+ BigInteger.prototype.not = function () {
+ return this.negate().prev();
+ };
+ NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
+
+ BigInteger.prototype.and = function (n) {
+ return bitwise(this, n, function (a, b) { return a & b; });
+ };
+ NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
+
+ BigInteger.prototype.or = function (n) {
+ return bitwise(this, n, function (a, b) { return a | b; });
+ };
+ NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
+
+ BigInteger.prototype.xor = function (n) {
+ return bitwise(this, n, function (a, b) { return a ^ b; });
+ };
+ NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
+
+ var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
+ function roughLOB(n) { // get lowestOneBit (rough)
+ // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
+ // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
+ var v = n.value,
+ x = typeof v === "number" ? v | LOBMASK_I :
+ typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
+ v[0] + v[1] * BASE | LOBMASK_BI;
+ return x & -x;
+ }
+
+ function integerLogarithm(value, base) {
+ if (base.compareTo(value) <= 0) {
+ var tmp = integerLogarithm(value, base.square(base));
+ var p = tmp.p;
+ var e = tmp.e;
+ var t = p.multiply(base);
+ return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
+ }
+ return { p: bigInt(1), e: 0 };
+ }
+
+ BigInteger.prototype.bitLength = function () {
+ var n = this;
+ if (n.compareTo(bigInt(0)) < 0) {
+ n = n.negate().subtract(bigInt(1));
+ }
+ if (n.compareTo(bigInt(0)) === 0) {
+ return bigInt(0);
+ }
+ return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
+ }
+ NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
+
+ function max(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.greater(b) ? a : b;
+ }
+ function min(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.lesser(b) ? a : b;
+ }
+ function gcd(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ if (a.equals(b)) return a;
+ if (a.isZero()) return b;
+ if (b.isZero()) return a;
+ var c = Integer[1], d, t;
+ while (a.isEven() && b.isEven()) {
+ d = min(roughLOB(a), roughLOB(b));
+ a = a.divide(d);
+ b = b.divide(d);
+ c = c.multiply(d);
+ }
+ while (a.isEven()) {
+ a = a.divide(roughLOB(a));
+ }
+ do {
+ while (b.isEven()) {
+ b = b.divide(roughLOB(b));
+ }
+ if (a.greater(b)) {
+ t = b; b = a; a = t;
+ }
+ b = b.subtract(a);
+ } while (!b.isZero());
+ return c.isUnit() ? a : a.multiply(c);
+ }
+ function lcm(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ return a.divide(gcd(a, b)).multiply(b);
+ }
+ function randBetween(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ var low = min(a, b), high = max(a, b);
+ var range = high.subtract(low).add(1);
+ if (range.isSmall) return low.add(Math.floor(Math.random() * range));
+ var digits = toBase(range, BASE).value;
+ var result = [], restricted = true;
+ for (var i = 0; i < digits.length; i++) {
+ var top = restricted ? digits[i] : BASE;
+ var digit = truncate(Math.random() * top);
+ result.push(digit);
+ if (digit < top) restricted = false;
+ }
+ return low.add(Integer.fromArray(result, BASE, false));
+ }
+
+ var parseBase = function (text, base, alphabet, caseSensitive) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ text = String(text);
+ if (!caseSensitive) {
+ text = text.toLowerCase();
+ alphabet = alphabet.toLowerCase();
+ }
+ var length = text.length;
+ var i;
+ var absBase = Math.abs(base);
+ var alphabetValues = {};
+ for (i = 0; i < alphabet.length; i++) {
+ alphabetValues[alphabet[i]] = i;
+ }
+ for (i = 0; i < length; i++) {
+ var c = text[i];
+ if (c === "-") continue;
+ if (c in alphabetValues) {
+ if (alphabetValues[c] >= absBase) {
+ if (c === "1" && absBase === 1) continue;
+ throw new Error(c + " is not a valid digit in base " + base + ".");
+ }
+ }
+ }
+ base = parseValue(base);
+ var digits = [];
+ var isNegative = text[0] === "-";
+ for (i = isNegative ? 1 : 0; i < text.length; i++) {
+ var c = text[i];
+ if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
+ else if (c === "<") {
+ var start = i;
+ do { i++; } while (text[i] !== ">" && i < text.length);
+ digits.push(parseValue(text.slice(start + 1, i)));
+ }
+ else throw new Error(c + " is not a valid character");
+ }
+ return parseBaseFromArray(digits, base, isNegative);
+ };
+
+ function parseBaseFromArray(digits, base, isNegative) {
+ var val = Integer[0], pow = Integer[1], i;
+ for (i = digits.length - 1; i >= 0; i--) {
+ val = val.add(digits[i].times(pow));
+ pow = pow.times(base);
+ }
+ return isNegative ? val.negate() : val;
+ }
+
+ function stringify(digit, alphabet) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ if (digit < alphabet.length) {
+ return alphabet[digit];
+ }
+ return "<" + digit + ">";
+ }
+
+ function toBase(n, base) {
+ base = bigInt(base);
+ if (base.isZero()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ throw new Error("Cannot convert nonzero numbers to base 0.");
+ }
+ if (base.equals(-1)) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ if (n.isNegative())
+ return {
+ value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
+ .map(Array.prototype.valueOf, [1, 0])
+ ),
+ isNegative: false
+ };
+
+ var arr = Array.apply(null, Array(n.toJSNumber() - 1))
+ .map(Array.prototype.valueOf, [0, 1]);
+ arr.unshift([1]);
+ return {
+ value: [].concat.apply([], arr),
+ isNegative: false
+ };
+ }
+
+ var neg = false;
+ if (n.isNegative() && base.isPositive()) {
+ neg = true;
+ n = n.abs();
+ }
+ if (base.isUnit()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+
+ return {
+ value: Array.apply(null, Array(n.toJSNumber()))
+ .map(Number.prototype.valueOf, 1),
+ isNegative: neg
+ };
+ }
+ var out = [];
+ var left = n, divmod;
+ while (left.isNegative() || left.compareAbs(base) >= 0) {
+ divmod = left.divmod(base);
+ left = divmod.quotient;
+ var digit = divmod.remainder;
+ if (digit.isNegative()) {
+ digit = base.minus(digit).abs();
+ left = left.next();
+ }
+ out.push(digit.toJSNumber());
+ }
+ out.push(left.toJSNumber());
+ return { value: out.reverse(), isNegative: neg };
+ }
+
+ function toBaseString(n, base, alphabet) {
+ var arr = toBase(n, base);
+ return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
+ return stringify(x, alphabet);
+ }).join('');
+ }
+
+ BigInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ SmallInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ NativeBigInt.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ BigInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined) radix = 10;
+ if (radix !== 10) return toBaseString(this, radix, alphabet);
+ var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
+ while (--l >= 0) {
+ digit = String(v[l]);
+ str += zeros.slice(digit.length) + digit;
+ }
+ var sign = this.sign ? "-" : "";
+ return sign + str;
+ };
+
+ SmallInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined) radix = 10;
+ if (radix != 10) return toBaseString(this, radix, alphabet);
+ return String(this.value);
+ };
+
+ NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
+
+ NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
+
+ BigInteger.prototype.valueOf = function () {
+ return parseInt(this.toString(), 10);
+ };
+ BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
+
+ SmallInteger.prototype.valueOf = function () {
+ return this.value;
+ };
+ SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
+ NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
+ return parseInt(this.toString(), 10);
+ }
+
+ function parseStringValue(v) {
+ if (isPrecise(+v)) {
+ var x = +v;
+ if (x === truncate(x))
+ return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
+ throw new Error("Invalid integer: " + v);
+ }
+ var sign = v[0] === "-";
+ if (sign) v = v.slice(1);
+ var split = v.split(/e/i);
+ if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
+ if (split.length === 2) {
+ var exp = split[1];
+ if (exp[0] === "+") exp = exp.slice(1);
+ exp = +exp;
+ if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
+ var text = split[0];
+ var decimalPlace = text.indexOf(".");
+ if (decimalPlace >= 0) {
+ exp -= text.length - decimalPlace - 1;
+ text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
+ }
+ if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
+ text += (new Array(exp + 1)).join("0");
+ v = text;
+ }
+ var isValid = /^([0-9][0-9]*)$/.test(v);
+ if (!isValid) throw new Error("Invalid integer: " + v);
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(sign ? "-" + v : v));
+ }
+ var r = [], max = v.length, l = LOG_BASE, min = max - l;
+ while (max > 0) {
+ r.push(+v.slice(min, max));
+ min -= l;
+ if (min < 0) min = 0;
+ max -= l;
+ }
+ trim(r);
+ return new BigInteger(r, sign);
+ }
+
+ function parseNumberValue(v) {
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(v));
+ }
+ if (isPrecise(v)) {
+ if (v !== truncate(v)) throw new Error(v + " is not an integer.");
+ return new SmallInteger(v);
+ }
+ return parseStringValue(v.toString());
+ }
+
+ function parseValue(v) {
+ if (typeof v === "number") {
+ return parseNumberValue(v);
+ }
+ if (typeof v === "string") {
+ return parseStringValue(v);
+ }
+ if (typeof v === "bigint") {
+ return new NativeBigInt(v);
+ }
+ return v;
+ }
+ // Pre-define numbers in range [-999,999]
+ for (var i = 0; i < 1000; i++) {
+ Integer[i] = parseValue(i);
+ if (i > 0) Integer[-i] = parseValue(-i);
+ }
+ // Backwards compatibility
+ Integer.one = Integer[1];
+ Integer.zero = Integer[0];
+ Integer.minusOne = Integer[-1];
+ Integer.max = max;
+ Integer.min = min;
+ Integer.gcd = gcd;
+ Integer.lcm = lcm;
+ Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
+ Integer.randBetween = randBetween;
+
+ Integer.fromArray = function (digits, base, isNegative) {
+ return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
+ };
+
+ return Integer;
+})();
+
+// Node.js check
+if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
+ module.exports = bigInt;
+}
+
+//amd check
+if (typeof define === "function" && define.amd) {
+ define("big-integer", [], function () {
+ return bigInt;
+ });
+}
diff --git a/big-integer/BigInteger.min.js b/big-integer/BigInteger.min.js
new file mode 100644
index 0000000..dd656e4
--- /dev/null
+++ b/big-integer/BigInteger.min.js
@@ -0,0 +1 @@
+var bigInt=function(undefined){"use strict";var BASE=1e7,LOG_BASE=7,MAX_INT=9007199254740992,MAX_INT_ARR=smallToArray(MAX_INT),DEFAULT_ALPHABET="0123456789abcdefghijklmnopqrstuvwxyz";var supportsNativeBigInt=typeof BigInt==="function";function Integer(v,radix,alphabet,caseSensitive){if(typeof v==="undefined")return Integer[0];if(typeof radix!=="undefined")return+radix===10&&!alphabet?parseValue(v):parseBase(v,radix,alphabet,caseSensitive);return parseValue(v)}function BigInteger(value,sign){this.value=value;this.sign=sign;this.isSmall=false}BigInteger.prototype=Object.create(Integer.prototype);function SmallInteger(value){this.value=value;this.sign=value<0;this.isSmall=true}SmallInteger.prototype=Object.create(Integer.prototype);function NativeBigInt(value){this.value=value}NativeBigInt.prototype=Object.create(Integer.prototype);function isPrecise(n){return-MAX_INT<n&&n<MAX_INT}function smallToArray(n){if(n<1e7)return[n];if(n<1e14)return[n%1e7,Math.floor(n/1e7)];return[n%1e7,Math.floor(n/1e7)%1e7,Math.floor(n/1e14)]}function arrayToSmall(arr){trim(arr);var length=arr.length;if(length<4&&compareAbs(arr,MAX_INT_ARR)<0){switch(length){case 0:return 0;case 1:return arr[0];case 2:return arr[0]+arr[1]*BASE;default:return arr[0]+(arr[1]+arr[2]*BASE)*BASE}}return arr}function trim(v){var i=v.length;while(v[--i]===0);v.length=i+1}function createArray(length){var x=new Array(length);var i=-1;while(++i<length){x[i]=0}return x}function truncate(n){if(n>0)return Math.floor(n);return Math.ceil(n)}function add(a,b){var l_a=a.length,l_b=b.length,r=new Array(l_a),carry=0,base=BASE,sum,i;for(i=0;i<l_b;i++){sum=a[i]+b[i]+carry;carry=sum>=base?1:0;r[i]=sum-carry*base}while(i<l_a){sum=a[i]+carry;carry=sum===base?1:0;r[i++]=sum-carry*base}if(carry>0)r.push(carry);return r}function addAny(a,b){if(a.length>=b.length)return add(a,b);return add(b,a)}function addSmall(a,carry){var l=a.length,r=new Array(l),base=BASE,sum,i;for(i=0;i<l;i++){sum=a[i]-base+carry;carry=Math.floor(sum/base);r[i]=sum-carry*base;carry+=1}while(carry>0){r[i++]=carry%base;carry=Math.floor(carry/base)}return r}BigInteger.prototype.add=function(v){var n=parseValue(v);if(this.sign!==n.sign){return this.subtract(n.negate())}var a=this.value,b=n.value;if(n.isSmall){return new BigInteger(addSmall(a,Math.abs(b)),this.sign)}return new BigInteger(addAny(a,b),this.sign)};BigInteger.prototype.plus=BigInteger.prototype.add;SmallInteger.prototype.add=function(v){var n=parseValue(v);var a=this.value;if(a<0!==n.sign){return this.subtract(n.negate())}var b=n.value;if(n.isSmall){if(isPrecise(a+b))return new SmallInteger(a+b);b=smallToArray(Math.abs(b))}return new BigInteger(addSmall(b,Math.abs(a)),a<0)};SmallInteger.prototype.plus=SmallInteger.prototype.add;NativeBigInt.prototype.add=function(v){return new NativeBigInt(this.value+parseValue(v).value)};NativeBigInt.prototype.plus=NativeBigInt.prototype.add;function subtract(a,b){var a_l=a.length,b_l=b.length,r=new Array(a_l),borrow=0,base=BASE,i,difference;for(i=0;i<b_l;i++){difference=a[i]-borrow-b[i];if(difference<0){difference+=base;borrow=1}else borrow=0;r[i]=difference}for(i=b_l;i<a_l;i++){difference=a[i]-borrow;if(difference<0)difference+=base;else{r[i++]=difference;break}r[i]=difference}for(;i<a_l;i++){r[i]=a[i]}trim(r);return r}function subtractAny(a,b,sign){var value;if(compareAbs(a,b)>=0){value=subtract(a,b)}else{value=subtract(b,a);sign=!sign}value=arrayToSmall(value);if(typeof value==="number"){if(sign)value=-value;return new SmallInteger(value)}return new BigInteger(value,sign)}function subtractSmall(a,b,sign){var l=a.length,r=new Array(l),carry=-b,base=BASE,i,difference;for(i=0;i<l;i++){difference=a[i]+carry;carry=Math.floor(difference/base);difference%=base;r[i]=difference<0?difference+base:difference}r=arrayToSmall(r);if(typeof r==="number"){if(sign)r=-r;return new SmallInteger(r)}return new BigInteger(r,sign)}BigInteger.prototype.subtract=function(v){var n=parseValue(v);if(this.sign!==n.sign){return this.add(n.negate())}var a=this.value,b=n.value;if(n.isSmall)return subtractSmall(a,Math.abs(b),this.sign);return subtractAny(a,b,this.sign)};BigInteger.prototype.minus=BigInteger.prototype.subtract;SmallInteger.prototype.subtract=function(v){var n=parseValue(v);var a=this.value;if(a<0!==n.sign){return this.add(n.negate())}var b=n.value;if(n.isSmall){return new SmallInteger(a-b)}return subtractSmall(b,Math.abs(a),a>=0)};SmallInteger.prototype.minus=SmallInteger.prototype.subtract;NativeBigInt.prototype.subtract=function(v){return new NativeBigInt(this.value-parseValue(v).value)};NativeBigInt.prototype.minus=NativeBigInt.prototype.subtract;BigInteger.prototype.negate=function(){return new BigInteger(this.value,!this.sign)};SmallInteger.prototype.negate=function(){var sign=this.sign;var small=new SmallInteger(-this.value);small.sign=!sign;return small};NativeBigInt.prototype.negate=function(){return new NativeBigInt(-this.value)};BigInteger.prototype.abs=function(){return new BigInteger(this.value,false)};SmallInteger.prototype.abs=function(){return new SmallInteger(Math.abs(this.value))};NativeBigInt.prototype.abs=function(){return new NativeBigInt(this.value>=0?this.value:-this.value)};function multiplyLong(a,b){var a_l=a.length,b_l=b.length,l=a_l+b_l,r=createArray(l),base=BASE,product,carry,i,a_i,b_j;for(i=0;i<a_l;++i){a_i=a[i];for(var j=0;j<b_l;++j){b_j=b[j];product=a_i*b_j+r[i+j];carry=Math.floor(product/base);r[i+j]=product-carry*base;r[i+j+1]+=carry}}trim(r);return r}function multiplySmall(a,b){var l=a.length,r=new Array(l),base=BASE,carry=0,product,i;for(i=0;i<l;i++){product=a[i]*b+carry;carry=Math.floor(product/base);r[i]=product-carry*base}while(carry>0){r[i++]=carry%base;carry=Math.floor(carry/base)}return r}function shiftLeft(x,n){var r=[];while(n-- >0)r.push(0);return r.concat(x)}function multiplyKaratsuba(x,y){var n=Math.max(x.length,y.length);if(n<=30)return multiplyLong(x,y);n=Math.ceil(n/2);var b=x.slice(n),a=x.slice(0,n),d=y.slice(n),c=y.slice(0,n);var ac=multiplyKaratsuba(a,c),bd=multiplyKaratsuba(b,d),abcd=multiplyKaratsuba(addAny(a,b),addAny(c,d));var product=addAny(addAny(ac,shiftLeft(subtract(subtract(abcd,ac),bd),n)),shiftLeft(bd,2*n));trim(product);return product}function useKaratsuba(l1,l2){return-.012*l1-.012*l2+15e-6*l1*l2>0}BigInteger.prototype.multiply=function(v){var n=parseValue(v),a=this.value,b=n.value,sign=this.sign!==n.sign,abs;if(n.isSmall){if(b===0)return Integer[0];if(b===1)return this;if(b===-1)return this.negate();abs=Math.abs(b);if(abs<BASE){return new BigInteger(multiplySmall(a,abs),sign)}b=smallToArray(abs)}if(useKaratsuba(a.length,b.length))return new BigInteger(multiplyKaratsuba(a,b),sign);return new BigInteger(multiplyLong(a,b),sign)};BigInteger.prototype.times=BigInteger.prototype.multiply;function multiplySmallAndArray(a,b,sign){if(a<BASE){return new BigInteger(multiplySmall(b,a),sign)}return new BigInteger(multiplyLong(b,smallToArray(a)),sign)}SmallInteger.prototype._multiplyBySmall=function(a){if(isPrecise(a.value*this.value)){return new SmallInteger(a.value*this.value)}return multiplySmallAndArray(Math.abs(a.value),smallToArray(Math.abs(this.value)),this.sign!==a.sign)};BigInteger.prototype._multiplyBySmall=function(a){if(a.value===0)return Integer[0];if(a.value===1)return this;if(a.value===-1)return this.negate();return multiplySmallAndArray(Math.abs(a.value),this.value,this.sign!==a.sign)};SmallInteger.prototype.multiply=function(v){return parseValue(v)._multiplyBySmall(this)};SmallInteger.prototype.times=SmallInteger.prototype.multiply;NativeBigInt.prototype.multiply=function(v){return new NativeBigInt(this.value*parseValue(v).value)};NativeBigInt.prototype.times=NativeBigInt.prototype.multiply;function square(a){var l=a.length,r=createArray(l+l),base=BASE,product,carry,i,a_i,a_j;for(i=0;i<l;i++){a_i=a[i];carry=0-a_i*a_i;for(var j=i;j<l;j++){a_j=a[j];product=2*(a_i*a_j)+r[i+j]+carry;carry=Math.floor(product/base);r[i+j]=product-carry*base}r[i+l]=carry}trim(r);return r}BigInteger.prototype.square=function(){return new BigInteger(square(this.value),false)};SmallInteger.prototype.square=function(){var value=this.value*this.value;if(isPrecise(value))return new SmallInteger(value);return new BigInteger(square(smallToArray(Math.abs(this.value))),false)};NativeBigInt.prototype.square=function(v){return new NativeBigInt(this.value*this.value)};function divMod1(a,b){var a_l=a.length,b_l=b.length,base=BASE,result=createArray(b.length),divisorMostSignificantDigit=b[b_l-1],lambda=Math.ceil(base/(2*divisorMostSignificantDigit)),remainder=multiplySmall(a,lambda),divisor=multiplySmall(b,lambda),quotientDigit,shift,carry,borrow,i,l,q;if(remainder.length<=a_l)remainder.push(0);divisor.push(0);divisorMostSignificantDigit=divisor[b_l-1];for(shift=a_l-b_l;shift>=0;shift--){quotientDigit=base-1;if(remainder[shift+b_l]!==divisorMostSignificantDigit){quotientDigit=Math.floor((remainder[shift+b_l]*base+remainder[shift+b_l-1])/divisorMostSignificantDigit)}carry=0;borrow=0;l=divisor.length;for(i=0;i<l;i++){carry+=quotientDigit*divisor[i];q=Math.floor(carry/base);borrow+=remainder[shift+i]-(carry-q*base);carry=q;if(borrow<0){remainder[shift+i]=borrow+base;borrow=-1}else{remainder[shift+i]=borrow;borrow=0}}while(borrow!==0){quotientDigit-=1;carry=0;for(i=0;i<l;i++){carry+=remainder[shift+i]-base+divisor[i];if(carry<0){remainder[shift+i]=carry+base;carry=0}else{remainder[shift+i]=carry;carry=1}}borrow+=carry}result[shift]=quotientDigit}remainder=divModSmall(remainder,lambda)[0];return[arrayToSmall(result),arrayToSmall(remainder)]}function divMod2(a,b){var a_l=a.length,b_l=b.length,result=[],part=[],base=BASE,guess,xlen,highx,highy,check;while(a_l){part.unshift(a[--a_l]);trim(part);if(compareAbs(part,b)<0){result.push(0);continue}xlen=part.length;highx=part[xlen-1]*base+part[xlen-2];highy=b[b_l-1]*base+b[b_l-2];if(xlen>b_l){highx=(highx+1)*base}guess=Math.ceil(highx/highy);do{check=multiplySmall(b,guess);if(compareAbs(check,part)<=0)break;guess--}while(guess);result.push(guess);part=subtract(part,check)}result.reverse();return[arrayToSmall(result),arrayToSmall(part)]}function divModSmall(value,lambda){var length=value.length,quotient=createArray(length),base=BASE,i,q,remainder,divisor;remainder=0;for(i=length-1;i>=0;--i){divisor=remainder*base+value[i];q=truncate(divisor/lambda);remainder=divisor-q*lambda;quotient[i]=q|0}return[quotient,remainder|0]}function divModAny(self,v){var value,n=parseValue(v);if(supportsNativeBigInt){return[new NativeBigInt(self.value/n.value),new NativeBigInt(self.value%n.value)]}var a=self.value,b=n.value;var quotient;if(b===0)throw new Error("Cannot divide by zero");if(self.isSmall){if(n.isSmall){return[new SmallInteger(truncate(a/b)),new SmallInteger(a%b)]}return[Integer[0],self]}if(n.isSmall){if(b===1)return[self,Integer[0]];if(b==-1)return[self.negate(),Integer[0]];var abs=Math.abs(b);if(abs<BASE){value=divModSmall(a,abs);quotient=arrayToSmall(value[0]);var remainder=value[1];if(self.sign)remainder=-remainder;if(typeof quotient==="number"){if(self.sign!==n.sign)quotient=-quotient;return[new SmallInteger(quotient),new SmallInteger(remainder)]}return[new BigInteger(quotient,self.sign!==n.sign),new SmallInteger(remainder)]}b=smallToArray(abs)}var comparison=compareAbs(a,b);if(comparison===-1)return[Integer[0],self];if(comparison===0)return[Integer[self.sign===n.sign?1:-1],Integer[0]];if(a.length+b.length<=200)value=divMod1(a,b);else value=divMod2(a,b);quotient=value[0];var qSign=self.sign!==n.sign,mod=value[1],mSign=self.sign;if(typeof quotient==="number"){if(qSign)quotient=-quotient;quotient=new SmallInteger(quotient)}else quotient=new BigInteger(quotient,qSign);if(typeof mod==="number"){if(mSign)mod=-mod;mod=new SmallInteger(mod)}else mod=new BigInteger(mod,mSign);return[quotient,mod]}BigInteger.prototype.divmod=function(v){var result=divModAny(this,v);return{quotient:result[0],remainder:result[1]}};NativeBigInt.prototype.divmod=SmallInteger.prototype.divmod=BigInteger.prototype.divmod;BigInteger.prototype.divide=function(v){return divModAny(this,v)[0]};NativeBigInt.prototype.over=NativeBigInt.prototype.divide=SmallInteger.prototype.over=SmallInteger.prototype.divide=BigInteger.prototype.over=BigInteger.prototype.divide;BigInteger.prototype.mod=function(v){return divModAny(this,v)[1]};NativeBigInt.prototype.mod=NativeBigInt.prototype.remainder=SmallInteger.prototype.remainder=SmallInteger.prototype.mod=BigInteger.prototype.remainder=BigInteger.prototype.mod;BigInteger.prototype.pow=function(v){var n=parseValue(v),a=this.value,b=n.value,value,x,y;if(b===0)return Integer[1];if(a===0)return Integer[0];if(a===1)return Integer[1];if(a===-1)return n.isEven()?Integer[1]:Integer[-1];if(n.sign){return Integer[0]}if(!n.isSmall)throw new Error("The exponent "+n.toString()+" is too large.");if(this.isSmall){if(isPrecise(value=Math.pow(a,b)))return new SmallInteger(truncate(value))}x=this;y=Integer[1];while(true){if(b&1===1){y=y.times(x);--b}if(b===0)break;b/=2;x=x.square()}return y};SmallInteger.prototype.pow=BigInteger.prototype.pow;var pow;if(supportsNativeBigInt){pow=eval("(a,b)=>a**b")}NativeBigInt.prototype.pow=function(v){var n=parseValue(v);var a=this.value,b=n.value;if(b===BigInt(0))return Integer[1];if(a===BigInt(0))return Integer[0];if(a===BigInt(1))return Integer[1];if(a===BigInt(-1))return n.isEven()?Integer[1]:Integer[-1];if(n.isNegative())return new NativeBigInt(BigInt(0));return new NativeBigInt(pow(a,b))};BigInteger.prototype.modPow=function(exp,mod){exp=parseValue(exp);mod=parseValue(mod);if(mod.isZero())throw new Error("Cannot take modPow with modulus 0");var r=Integer[1],base=this.mod(mod);while(exp.isPositive()){if(base.isZero())return Integer[0];if(exp.isOdd())r=r.multiply(base).mod(mod);exp=exp.divide(2);base=base.square().mod(mod)}return r};NativeBigInt.prototype.modPow=SmallInteger.prototype.modPow=BigInteger.prototype.modPow;function compareAbs(a,b){if(a.length!==b.length){return a.length>b.length?1:-1}for(var i=a.length-1;i>=0;i--){if(a[i]!==b[i])return a[i]>b[i]?1:-1}return 0}BigInteger.prototype.compareAbs=function(v){var n=parseValue(v),a=this.value,b=n.value;if(n.isSmall)return 1;return compareAbs(a,b)};SmallInteger.prototype.compareAbs=function(v){var n=parseValue(v),a=Math.abs(this.value),b=n.value;if(n.isSmall){b=Math.abs(b);return a===b?0:a>b?1:-1}return-1};NativeBigInt.prototype.compareAbs=function(v){var a=this.value;var b=parseValue(v).value;a=a>=0?a:-a;b=b>=0?b:-b;return a===b?0:a>b?1:-1};BigInteger.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var n=parseValue(v),a=this.value,b=n.value;if(this.sign!==n.sign){return n.sign?1:-1}if(n.isSmall){return this.sign?-1:1}return compareAbs(a,b)*(this.sign?-1:1)};BigInteger.prototype.compareTo=BigInteger.prototype.compare;SmallInteger.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var n=parseValue(v),a=this.value,b=n.value;if(n.isSmall){return a==b?0:a>b?1:-1}if(a<0!==n.sign){return a<0?-1:1}return a<0?1:-1};SmallInteger.prototype.compareTo=SmallInteger.prototype.compare;NativeBigInt.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var a=this.value;var b=parseValue(v).value;return a===b?0:a>b?1:-1};NativeBigInt.prototype.compareTo=NativeBigInt.prototype.compare;BigInteger.prototype.equals=function(v){return this.compare(v)===0};NativeBigInt.prototype.eq=NativeBigInt.prototype.equals=SmallInteger.prototype.eq=SmallInteger.prototype.equals=BigInteger.prototype.eq=BigInteger.prototype.equals;BigInteger.prototype.notEquals=function(v){return this.compare(v)!==0};NativeBigInt.prototype.neq=NativeBigInt.prototype.notEquals=SmallInteger.prototype.neq=SmallInteger.prototype.notEquals=BigInteger.prototype.neq=BigInteger.prototype.notEquals;BigInteger.prototype.greater=function(v){return this.compare(v)>0};NativeBigInt.prototype.gt=NativeBigInt.prototype.greater=SmallInteger.prototype.gt=SmallInteger.prototype.greater=BigInteger.prototype.gt=BigInteger.prototype.greater;BigInteger.prototype.lesser=function(v){return this.compare(v)<0};NativeBigInt.prototype.lt=NativeBigInt.prototype.lesser=SmallInteger.prototype.lt=SmallInteger.prototype.lesser=BigInteger.prototype.lt=BigInteger.prototype.lesser;BigInteger.prototype.greaterOrEquals=function(v){return this.compare(v)>=0};NativeBigInt.prototype.geq=NativeBigInt.prototype.greaterOrEquals=SmallInteger.prototype.geq=SmallInteger.prototype.greaterOrEquals=BigInteger.prototype.geq=BigInteger.prototype.greaterOrEquals;BigInteger.prototype.lesserOrEquals=function(v){return this.compare(v)<=0};NativeBigInt.prototype.leq=NativeBigInt.prototype.lesserOrEquals=SmallInteger.prototype.leq=SmallInteger.prototype.lesserOrEquals=BigInteger.prototype.leq=BigInteger.prototype.lesserOrEquals;BigInteger.prototype.isEven=function(){return(this.value[0]&1)===0};SmallInteger.prototype.isEven=function(){return(this.value&1)===0};NativeBigInt.prototype.isEven=function(){return(this.value&BigInt(1))===BigInt(0)};BigInteger.prototype.isOdd=function(){return(this.value[0]&1)===1};SmallInteger.prototype.isOdd=function(){return(this.value&1)===1};NativeBigInt.prototype.isOdd=function(){return(this.value&BigInt(1))===BigInt(1)};BigInteger.prototype.isPositive=function(){return!this.sign};SmallInteger.prototype.isPositive=function(){return this.value>0};NativeBigInt.prototype.isPositive=SmallInteger.prototype.isPositive;BigInteger.prototype.isNegative=function(){return this.sign};SmallInteger.prototype.isNegative=function(){return this.value<0};NativeBigInt.prototype.isNegative=SmallInteger.prototype.isNegative;BigInteger.prototype.isUnit=function(){return false};SmallInteger.prototype.isUnit=function(){return Math.abs(this.value)===1};NativeBigInt.prototype.isUnit=function(){return this.abs().value===BigInt(1)};BigInteger.prototype.isZero=function(){return false};SmallInteger.prototype.isZero=function(){return this.value===0};NativeBigInt.prototype.isZero=function(){return this.value===BigInt(0)};BigInteger.prototype.isDivisibleBy=function(v){var n=parseValue(v);if(n.isZero())return false;if(n.isUnit())return true;if(n.compareAbs(2)===0)return this.isEven();return this.mod(n).isZero()};NativeBigInt.prototype.isDivisibleBy=SmallInteger.prototype.isDivisibleBy=BigInteger.prototype.isDivisibleBy;function isBasicPrime(v){var n=v.abs();if(n.isUnit())return false;if(n.equals(2)||n.equals(3)||n.equals(5))return true;if(n.isEven()||n.isDivisibleBy(3)||n.isDivisibleBy(5))return false;if(n.lesser(49))return true}function millerRabinTest(n,a){var nPrev=n.prev(),b=nPrev,r=0,d,t,i,x;while(b.isEven())b=b.divide(2),r++;next:for(i=0;i<a.length;i++){if(n.lesser(a[i]))continue;x=bigInt(a[i]).modPow(b,n);if(x.isUnit()||x.equals(nPrev))continue;for(d=r-1;d!=0;d--){x=x.square().mod(n);if(x.isUnit())return false;if(x.equals(nPrev))continue next}return false}return true}BigInteger.prototype.isPrime=function(strict){var isPrime=isBasicPrime(this);if(isPrime!==undefined)return isPrime;var n=this.abs();var bits=n.bitLength();if(bits<=64)return millerRabinTest(n,[2,325,9375,28178,450775,9780504,1795265022]);var logN=Math.log(2)*bits.toJSNumber();var t=Math.ceil(strict===true?2*Math.pow(logN,2):logN);for(var a=[],i=0;i<t;i++){a.push(bigInt(i+2))}return millerRabinTest(n,a)};NativeBigInt.prototype.isPrime=SmallInteger.prototype.isPrime=BigInteger.prototype.isPrime;BigInteger.prototype.isProbablePrime=function(iterations){var isPrime=isBasicPrime(this);if(isPrime!==undefined)return isPrime;var n=this.abs();var t=iterations===undefined?5:iterations;for(var a=[],i=0;i<t;i++){a.push(bigInt.randBetween(2,n.minus(2)))}return millerRabinTest(n,a)};NativeBigInt.prototype.isProbablePrime=SmallInteger.prototype.isProbablePrime=BigInteger.prototype.isProbablePrime;BigInteger.prototype.modInv=function(n){var t=bigInt.zero,newT=bigInt.one,r=parseValue(n),newR=this.abs(),q,lastT,lastR;while(!newR.isZero()){q=r.divide(newR);lastT=t;lastR=r;t=newT;r=newR;newT=lastT.subtract(q.multiply(newT));newR=lastR.subtract(q.multiply(newR))}if(!r.isUnit())throw new Error(this.toString()+" and "+n.toString()+" are not co-prime");if(t.compare(0)===-1){t=t.add(n)}if(this.isNegative()){return t.negate()}return t};NativeBigInt.prototype.modInv=SmallInteger.prototype.modInv=BigInteger.prototype.modInv;BigInteger.prototype.next=function(){var value=this.value;if(this.sign){return subtractSmall(value,1,this.sign)}return new BigInteger(addSmall(value,1),this.sign)};SmallInteger.prototype.next=function(){var value=this.value;if(value+1<MAX_INT)return new SmallInteger(value+1);return new BigInteger(MAX_INT_ARR,false)};NativeBigInt.prototype.next=function(){return new NativeBigInt(this.value+BigInt(1))};BigInteger.prototype.prev=function(){var value=this.value;if(this.sign){return new BigInteger(addSmall(value,1),true)}return subtractSmall(value,1,this.sign)};SmallInteger.prototype.prev=function(){var value=this.value;if(value-1>-MAX_INT)return new SmallInteger(value-1);return new BigInteger(MAX_INT_ARR,true)};NativeBigInt.prototype.prev=function(){return new NativeBigInt(this.value-BigInt(1))};var powersOfTwo=[1];while(2*powersOfTwo[powersOfTwo.length-1]<=BASE)powersOfTwo.push(2*powersOfTwo[powersOfTwo.length-1]);var powers2Length=powersOfTwo.length,highestPower2=powersOfTwo[powers2Length-1];function shift_isSmall(n){return Math.abs(n)<=BASE}BigInteger.prototype.shiftLeft=function(v){var n=parseValue(v).toJSNumber();if(!shift_isSmall(n)){throw new Error(String(n)+" is too large for shifting.")}if(n<0)return this.shiftRight(-n);var result=this;if(result.isZero())return result;while(n>=powers2Length){result=result.multiply(highestPower2);n-=powers2Length-1}return result.multiply(powersOfTwo[n])};NativeBigInt.prototype.shiftLeft=SmallInteger.prototype.shiftLeft=BigInteger.prototype.shiftLeft;BigInteger.prototype.shiftRight=function(v){var remQuo;var n=parseValue(v).toJSNumber();if(!shift_isSmall(n)){throw new Error(String(n)+" is too large for shifting.")}if(n<0)return this.shiftLeft(-n);var result=this;while(n>=powers2Length){if(result.isZero()||result.isNegative()&&result.isUnit())return result;remQuo=divModAny(result,highestPower2);result=remQuo[1].isNegative()?remQuo[0].prev():remQuo[0];n-=powers2Length-1}remQuo=divModAny(result,powersOfTwo[n]);return remQuo[1].isNegative()?remQuo[0].prev():remQuo[0]};NativeBigInt.prototype.shiftRight=SmallInteger.prototype.shiftRight=BigInteger.prototype.shiftRight;function bitwise(x,y,fn){y=parseValue(y);var xSign=x.isNegative(),ySign=y.isNegative();var xRem=xSign?x.not():x,yRem=ySign?y.not():y;var xDigit=0,yDigit=0;var xDivMod=null,yDivMod=null;var result=[];while(!xRem.isZero()||!yRem.isZero()){xDivMod=divModAny(xRem,highestPower2);xDigit=xDivMod[1].toJSNumber();if(xSign){xDigit=highestPower2-1-xDigit}yDivMod=divModAny(yRem,highestPower2);yDigit=yDivMod[1].toJSNumber();if(ySign){yDigit=highestPower2-1-yDigit}xRem=xDivMod[0];yRem=yDivMod[0];result.push(fn(xDigit,yDigit))}var sum=fn(xSign?1:0,ySign?1:0)!==0?bigInt(-1):bigInt(0);for(var i=result.length-1;i>=0;i-=1){sum=sum.multiply(highestPower2).add(bigInt(result[i]))}return sum}BigInteger.prototype.not=function(){return this.negate().prev()};NativeBigInt.prototype.not=SmallInteger.prototype.not=BigInteger.prototype.not;BigInteger.prototype.and=function(n){return bitwise(this,n,function(a,b){return a&b})};NativeBigInt.prototype.and=SmallInteger.prototype.and=BigInteger.prototype.and;BigInteger.prototype.or=function(n){return bitwise(this,n,function(a,b){return a|b})};NativeBigInt.prototype.or=SmallInteger.prototype.or=BigInteger.prototype.or;BigInteger.prototype.xor=function(n){return bitwise(this,n,function(a,b){return a^b})};NativeBigInt.prototype.xor=SmallInteger.prototype.xor=BigInteger.prototype.xor;var LOBMASK_I=1<<30,LOBMASK_BI=(BASE&-BASE)*(BASE&-BASE)|LOBMASK_I;function roughLOB(n){var v=n.value,x=typeof v==="number"?v|LOBMASK_I:typeof v==="bigint"?v|BigInt(LOBMASK_I):v[0]+v[1]*BASE|LOBMASK_BI;return x&-x}function integerLogarithm(value,base){if(base.compareTo(value)<=0){var tmp=integerLogarithm(value,base.square(base));var p=tmp.p;var e=tmp.e;var t=p.multiply(base);return t.compareTo(value)<=0?{p:t,e:e*2+1}:{p:p,e:e*2}}return{p:bigInt(1),e:0}}BigInteger.prototype.bitLength=function(){var n=this;if(n.compareTo(bigInt(0))<0){n=n.negate().subtract(bigInt(1))}if(n.compareTo(bigInt(0))===0){return bigInt(0)}return bigInt(integerLogarithm(n,bigInt(2)).e).add(bigInt(1))};NativeBigInt.prototype.bitLength=SmallInteger.prototype.bitLength=BigInteger.prototype.bitLength;function max(a,b){a=parseValue(a);b=parseValue(b);return a.greater(b)?a:b}function min(a,b){a=parseValue(a);b=parseValue(b);return a.lesser(b)?a:b}function gcd(a,b){a=parseValue(a).abs();b=parseValue(b).abs();if(a.equals(b))return a;if(a.isZero())return b;if(b.isZero())return a;var c=Integer[1],d,t;while(a.isEven()&&b.isEven()){d=min(roughLOB(a),roughLOB(b));a=a.divide(d);b=b.divide(d);c=c.multiply(d)}while(a.isEven()){a=a.divide(roughLOB(a))}do{while(b.isEven()){b=b.divide(roughLOB(b))}if(a.greater(b)){t=b;b=a;a=t}b=b.subtract(a)}while(!b.isZero());return c.isUnit()?a:a.multiply(c)}function lcm(a,b){a=parseValue(a).abs();b=parseValue(b).abs();return a.divide(gcd(a,b)).multiply(b)}function randBetween(a,b){a=parseValue(a);b=parseValue(b);var low=min(a,b),high=max(a,b);var range=high.subtract(low).add(1);if(range.isSmall)return low.add(Math.floor(Math.random()*range));var digits=toBase(range,BASE).value;var result=[],restricted=true;for(var i=0;i<digits.length;i++){var top=restricted?digits[i]:BASE;var digit=truncate(Math.random()*top);result.push(digit);if(digit<top)restricted=false}return low.add(Integer.fromArray(result,BASE,false))}var parseBase=function(text,base,alphabet,caseSensitive){alphabet=alphabet||DEFAULT_ALPHABET;text=String(text);if(!caseSensitive){text=text.toLowerCase();alphabet=alphabet.toLowerCase()}var length=text.length;var i;var absBase=Math.abs(base);var alphabetValues={};for(i=0;i<alphabet.length;i++){alphabetValues[alphabet[i]]=i}for(i=0;i<length;i++){var c=text[i];if(c==="-")continue;if(c in alphabetValues){if(alphabetValues[c]>=absBase){if(c==="1"&&absBase===1)continue;throw new Error(c+" is not a valid digit in base "+base+".")}}}base=parseValue(base);var digits=[];var isNegative=text[0]==="-";for(i=isNegative?1:0;i<text.length;i++){var c=text[i];if(c in alphabetValues)digits.push(parseValue(alphabetValues[c]));else if(c==="<"){var start=i;do{i++}while(text[i]!==">"&&i<text.length);digits.push(parseValue(text.slice(start+1,i)))}else throw new Error(c+" is not a valid character")}return parseBaseFromArray(digits,base,isNegative)};function parseBaseFromArray(digits,base,isNegative){var val=Integer[0],pow=Integer[1],i;for(i=digits.length-1;i>=0;i--){val=val.add(digits[i].times(pow));pow=pow.times(base)}return isNegative?val.negate():val}function stringify(digit,alphabet){alphabet=alphabet||DEFAULT_ALPHABET;if(digit<alphabet.length){return alphabet[digit]}return"<"+digit+">"}function toBase(n,base){base=bigInt(base);if(base.isZero()){if(n.isZero())return{value:[0],isNegative:false};throw new Error("Cannot convert nonzero numbers to base 0.")}if(base.equals(-1)){if(n.isZero())return{value:[0],isNegative:false};if(n.isNegative())return{value:[].concat.apply([],Array.apply(null,Array(-n.toJSNumber())).map(Array.prototype.valueOf,[1,0])),isNegative:false};var arr=Array.apply(null,Array(n.toJSNumber()-1)).map(Array.prototype.valueOf,[0,1]);arr.unshift([1]);return{value:[].concat.apply([],arr),isNegative:false}}var neg=false;if(n.isNegative()&&base.isPositive()){neg=true;n=n.abs()}if(base.isUnit()){if(n.isZero())return{value:[0],isNegative:false};return{value:Array.apply(null,Array(n.toJSNumber())).map(Number.prototype.valueOf,1),isNegative:neg}}var out=[];var left=n,divmod;while(left.isNegative()||left.compareAbs(base)>=0){divmod=left.divmod(base);left=divmod.quotient;var digit=divmod.remainder;if(digit.isNegative()){digit=base.minus(digit).abs();left=left.next()}out.push(digit.toJSNumber())}out.push(left.toJSNumber());return{value:out.reverse(),isNegative:neg}}function toBaseString(n,base,alphabet){var arr=toBase(n,base);return(arr.isNegative?"-":"")+arr.value.map(function(x){return stringify(x,alphabet)}).join("")}BigInteger.prototype.toArray=function(radix){return toBase(this,radix)};SmallInteger.prototype.toArray=function(radix){return toBase(this,radix)};NativeBigInt.prototype.toArray=function(radix){return toBase(this,radix)};BigInteger.prototype.toString=function(radix,alphabet){if(radix===undefined)radix=10;if(radix!==10)return toBaseString(this,radix,alphabet);var v=this.value,l=v.length,str=String(v[--l]),zeros="0000000",digit;while(--l>=0){digit=String(v[l]);str+=zeros.slice(digit.length)+digit}var sign=this.sign?"-":"";return sign+str};SmallInteger.prototype.toString=function(radix,alphabet){if(radix===undefined)radix=10;if(radix!=10)return toBaseString(this,radix,alphabet);return String(this.value)};NativeBigInt.prototype.toString=SmallInteger.prototype.toString;NativeBigInt.prototype.toJSON=BigInteger.prototype.toJSON=SmallInteger.prototype.toJSON=function(){return this.toString()};BigInteger.prototype.valueOf=function(){return parseInt(this.toString(),10)};BigInteger.prototype.toJSNumber=BigInteger.prototype.valueOf;SmallInteger.prototype.valueOf=function(){return this.value};SmallInteger.prototype.toJSNumber=SmallInteger.prototype.valueOf;NativeBigInt.prototype.valueOf=NativeBigInt.prototype.toJSNumber=function(){return parseInt(this.toString(),10)};function parseStringValue(v){if(isPrecise(+v)){var x=+v;if(x===truncate(x))return supportsNativeBigInt?new NativeBigInt(BigInt(x)):new SmallInteger(x);throw new Error("Invalid integer: "+v)}var sign=v[0]==="-";if(sign)v=v.slice(1);var split=v.split(/e/i);if(split.length>2)throw new Error("Invalid integer: "+split.join("e"));if(split.length===2){var exp=split[1];if(exp[0]==="+")exp=exp.slice(1);exp=+exp;if(exp!==truncate(exp)||!isPrecise(exp))throw new Error("Invalid integer: "+exp+" is not a valid exponent.");var text=split[0];var decimalPlace=text.indexOf(".");if(decimalPlace>=0){exp-=text.length-decimalPlace-1;text=text.slice(0,decimalPlace)+text.slice(decimalPlace+1)}if(exp<0)throw new Error("Cannot include negative exponent part for integers");text+=new Array(exp+1).join("0");v=text}var isValid=/^([0-9][0-9]*)$/.test(v);if(!isValid)throw new Error("Invalid integer: "+v);if(supportsNativeBigInt){return new NativeBigInt(BigInt(sign?"-"+v:v))}var r=[],max=v.length,l=LOG_BASE,min=max-l;while(max>0){r.push(+v.slice(min,max));min-=l;if(min<0)min=0;max-=l}trim(r);return new BigInteger(r,sign)}function parseNumberValue(v){if(supportsNativeBigInt){return new NativeBigInt(BigInt(v))}if(isPrecise(v)){if(v!==truncate(v))throw new Error(v+" is not an integer.");return new SmallInteger(v)}return parseStringValue(v.toString())}function parseValue(v){if(typeof v==="number"){return parseNumberValue(v)}if(typeof v==="string"){return parseStringValue(v)}if(typeof v==="bigint"){return new NativeBigInt(v)}return v}for(var i=0;i<1e3;i++){Integer[i]=parseValue(i);if(i>0)Integer[-i]=parseValue(-i)}Integer.one=Integer[1];Integer.zero=Integer[0];Integer.minusOne=Integer[-1];Integer.max=max;Integer.min=min;Integer.gcd=gcd;Integer.lcm=lcm;Integer.isInstance=function(x){return x instanceof BigInteger||x instanceof SmallInteger||x instanceof NativeBigInt};Integer.randBetween=randBetween;Integer.fromArray=function(digits,base,isNegative){return parseBaseFromArray(digits.map(parseValue),parseValue(base||10),isNegative)};return Integer}();if(typeof module!=="undefined"&&module.hasOwnProperty("exports")){module.exports=bigInt}if(typeof define==="function"&&define.amd){define("big-integer",[],function(){return bigInt})} \ No newline at end of file
diff --git a/big-integer/LICENSE b/big-integer/LICENSE
new file mode 100644
index 0000000..cf1ab25
--- /dev/null
+++ b/big-integer/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org>
diff --git a/big-integer/README.md b/big-integer/README.md
new file mode 100644
index 0000000..0901973
--- /dev/null
+++ b/big-integer/README.md
@@ -0,0 +1,580 @@
+# BigInteger.js [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url] [![Monthly Downloads][downloads-img]][downloads-url]
+
+[travis-url]: https://travis-ci.org/peterolson/BigInteger.js
+[travis-img]: https://travis-ci.org/peterolson/BigInteger.js.svg?branch=master
+[coveralls-url]: https://coveralls.io/github/peterolson/BigInteger.js?branch=master
+[coveralls-img]: https://coveralls.io/repos/peterolson/BigInteger.js/badge.svg?branch=master&service=github
+[downloads-url]: https://www.npmjs.com/package/big-integer
+[downloads-img]: https://img.shields.io/npm/dm/big-integer.svg
+
+**BigInteger.js** is an arbitrary-length integer library for Javascript, allowing arithmetic operations on integers of unlimited size, notwithstanding memory and time limitations.
+
+**Update (December 2, 2018):** [`BigInt` is being added as a native feature of JavaScript](https://tc39.github.io/proposal-bigint/). This library now works as a polyfill: if the environment supports the native `BigInt`, this library acts as a thin wrapper over the native implementation.
+
+## Installation
+
+If you are using a browser, you can download [BigInteger.js from GitHub](http://peterolson.github.com/BigInteger.js/BigInteger.min.js) or just hotlink to it:
+
+ <script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
+
+If you are using node, you can install BigInteger with [npm](https://npmjs.org/).
+
+ npm install big-integer
+
+Then you can include it in your code:
+
+ var bigInt = require("big-integer");
+
+
+## Usage
+### `bigInt(number, [base], [alphabet], [caseSensitive])`
+
+You can create a bigInt by calling the `bigInt` function. You can pass in
+
+ - a string, which it will parse as an bigInt and throw an `"Invalid integer"` error if the parsing fails.
+ - a Javascript number, which it will parse as an bigInt and throw an `"Invalid integer"` error if the parsing fails.
+ - another bigInt.
+ - nothing, and it will return `bigInt.zero`.
+
+ If you provide a second parameter, then it will parse `number` as a number in base `base`. Note that `base` can be any bigInt (even negative or zero). The letters "a-z" and "A-Z" will be interpreted as the numbers 10 to 35. Higher digits can be specified in angle brackets (`<` and `>`). The default `base` is `10`.
+
+ You can specify a custom alphabet for base conversion with the third parameter. The default `alphabet` is `"0123456789abcdefghijklmnopqrstuvwxyz"`.
+
+ The fourth parameter specifies whether or not the number string should be case-sensitive, i.e. whether `a` and `A` should be treated as different digits. By default `caseSensitive` is `false`.
+
+Examples:
+
+ var zero = bigInt();
+ var ninetyThree = bigInt(93);
+ var largeNumber = bigInt("75643564363473453456342378564387956906736546456235345");
+ var googol = bigInt("1e100");
+ var bigNumber = bigInt(largeNumber);
+
+ var maximumByte = bigInt("FF", 16);
+ var fiftyFiveGoogol = bigInt("<55>0", googol);
+
+Note that Javascript numbers larger than `9007199254740992` and smaller than `-9007199254740992` are not precisely represented numbers and will not produce exact results. If you are dealing with numbers outside that range, it is better to pass in strings.
+
+### Method Chaining
+
+Note that bigInt operations return bigInts, which allows you to chain methods, for example:
+
+ var salary = bigInt(dollarsPerHour).times(hoursWorked).plus(randomBonuses)
+
+### Constants
+
+There are three named constants already stored that you do not have to construct with the `bigInt` function yourself:
+
+ - `bigInt.one`, equivalent to `bigInt(1)`
+ - `bigInt.zero`, equivalent to `bigInt(0)`
+ - `bigInt.minusOne`, equivalent to `bigInt(-1)`
+
+The numbers from -999 to 999 are also already prestored and can be accessed using `bigInt[index]`, for example:
+
+ - `bigInt[-999]`, equivalent to `bigInt(-999)`
+ - `bigInt[256]`, equivalent to `bigInt(256)`
+
+### Methods
+
+#### `abs()`
+
+Returns the absolute value of a bigInt.
+
+ - `bigInt(-45).abs()` => `45`
+ - `bigInt(45).abs()` => `45`
+
+#### `add(number)`
+
+Performs addition.
+
+ - `bigInt(5).add(7)` => `12`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Addition)
+
+#### `and(number)`
+
+Performs the bitwise AND operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
+
+ - `bigInt(6).and(3)` => `2`
+ - `bigInt(6).and(-3)` => `4`
+
+#### `bitLength()`
+
+Returns the number of digits required to represent a bigInt in binary.
+
+ - `bigInt(5)` => `3` (since 5 is `101` in binary, which is three digits long)
+
+#### `compare(number)`
+
+Performs a comparison between two numbers. If the numbers are equal, it returns `0`. If the first number is greater, it returns `1`. If the first number is lesser, it returns `-1`.
+
+ - `bigInt(5).compare(5)` => `0`
+ - `bigInt(5).compare(4)` => `1`
+ - `bigInt(4).compare(5)` => `-1`
+
+#### `compareAbs(number)`
+
+Performs a comparison between the absolute value of two numbers.
+
+ - `bigInt(5).compareAbs(-5)` => `0`
+ - `bigInt(5).compareAbs(4)` => `1`
+ - `bigInt(4).compareAbs(-5)` => `-1`
+
+#### `compareTo(number)`
+
+Alias for the `compare` method.
+
+#### `divide(number)`
+
+Performs integer division, disregarding the remainder.
+
+ - `bigInt(59).divide(5)` => `11`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
+
+#### `divmod(number)`
+
+Performs division and returns an object with two properties: `quotient` and `remainder`. The sign of the remainder will match the sign of the dividend.
+
+ - `bigInt(59).divmod(5)` => `{quotient: bigInt(11), remainder: bigInt(4) }`
+ - `bigInt(-5).divmod(2)` => `{quotient: bigInt(-2), remainder: bigInt(-1) }`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
+
+#### `eq(number)`
+
+Alias for the `equals` method.
+
+#### `equals(number)`
+
+Checks if two numbers are equal.
+
+ - `bigInt(5).equals(5)` => `true`
+ - `bigInt(4).equals(7)` => `false`
+
+#### `geq(number)`
+
+Alias for the `greaterOrEquals` method.
+
+
+#### `greater(number)`
+
+Checks if the first number is greater than the second.
+
+ - `bigInt(5).greater(6)` => `false`
+ - `bigInt(5).greater(5)` => `false`
+ - `bigInt(5).greater(4)` => `true`
+
+#### `greaterOrEquals(number)`
+
+Checks if the first number is greater than or equal to the second.
+
+ - `bigInt(5).greaterOrEquals(6)` => `false`
+ - `bigInt(5).greaterOrEquals(5)` => `true`
+ - `bigInt(5).greaterOrEquals(4)` => `true`
+
+#### `gt(number)`
+
+Alias for the `greater` method.
+
+#### `isDivisibleBy(number)`
+
+Returns `true` if the first number is divisible by the second number, `false` otherwise.
+
+ - `bigInt(999).isDivisibleBy(333)` => `true`
+ - `bigInt(99).isDivisibleBy(5)` => `false`
+
+#### `isEven()`
+
+Returns `true` if the number is even, `false` otherwise.
+
+ - `bigInt(6).isEven()` => `true`
+ - `bigInt(3).isEven()` => `false`
+
+#### `isNegative()`
+
+Returns `true` if the number is negative, `false` otherwise.
+Returns `false` for `0` and `-0`.
+
+ - `bigInt(-23).isNegative()` => `true`
+ - `bigInt(50).isNegative()` => `false`
+
+#### `isOdd()`
+
+Returns `true` if the number is odd, `false` otherwise.
+
+ - `bigInt(13).isOdd()` => `true`
+ - `bigInt(40).isOdd()` => `false`
+
+#### `isPositive()`
+
+Return `true` if the number is positive, `false` otherwise.
+Returns `false` for `0` and `-0`.
+
+ - `bigInt(54).isPositive()` => `true`
+ - `bigInt(-1).isPositive()` => `false`
+
+#### `isPrime()`
+
+Returns `true` if the number is prime, `false` otherwise.
+
+ - `bigInt(5).isPrime()` => `true`
+ - `bigInt(6).isPrime()` => `false`
+
+#### `isProbablePrime([iterations])`
+
+Returns `true` if the number is very likely to be prime, `false` otherwise.
+Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive.
+This uses the [Miller Rabin test](https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test).
+
+ - `bigInt(5).isProbablePrime()` => `true`
+ - `bigInt(49).isProbablePrime()` => `false`
+ - `bigInt(1729).isProbablePrime()` => `false`
+
+Note that this function is not deterministic, since it relies on random sampling of factors, so the result for some numbers is not always the same.
+If the number is composite then the Miller–Rabin primality test declares the number probably prime with a probability at most `4` to the power `−iterations`.
+If the number is prime, this function always returns `true`.
+
+#### `isUnit()`
+
+Returns `true` if the number is `1` or `-1`, `false` otherwise.
+
+ - `bigInt.one.isUnit()` => `true`
+ - `bigInt.minusOne.isUnit()` => `true`
+ - `bigInt(5).isUnit()` => `false`
+
+#### `isZero()`
+
+Return `true` if the number is `0` or `-0`, `false` otherwise.
+
+ - `bigInt.zero.isZero()` => `true`
+ - `bigInt("-0").isZero()` => `true`
+ - `bigInt(50).isZero()` => `false`
+
+#### `leq(number)`
+
+Alias for the `lesserOrEquals` method.
+
+#### `lesser(number)`
+
+Checks if the first number is lesser than the second.
+
+ - `bigInt(5).lesser(6)` => `true`
+ - `bigInt(5).lesser(5)` => `false`
+ - `bigInt(5).lesser(4)` => `false`
+
+#### `lesserOrEquals(number)`
+
+Checks if the first number is less than or equal to the second.
+
+ - `bigInt(5).lesserOrEquals(6)` => `true`
+ - `bigInt(5).lesserOrEquals(5)` => `true`
+ - `bigInt(5).lesserOrEquals(4)` => `false`
+
+#### `lt(number)`
+
+Alias for the `lesser` method.
+
+#### `minus(number)`
+
+Alias for the `subtract` method.
+
+ - `bigInt(3).minus(5)` => `-2`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Subtraction)
+
+#### `mod(number)`
+
+Performs division and returns the remainder, disregarding the quotient. The sign of the remainder will match the sign of the dividend.
+
+ - `bigInt(59).mod(5)` => `4`
+ - `bigInt(-5).mod(2)` => `-1`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
+
+#### `modInv(mod)`
+
+Finds the [multiplicative inverse](https://en.wikipedia.org/wiki/Modular_multiplicative_inverse) of the number modulo `mod`.
+
+ - `bigInt(3).modInv(11)` => `4`
+ - `bigInt(42).modInv(2017)` => `1969`
+
+#### `modPow(exp, mod)`
+
+Takes the number to the power `exp` modulo `mod`.
+
+ - `bigInt(10).modPow(3, 30)` => `10`
+
+#### `multiply(number)`
+
+Performs multiplication.
+
+ - `bigInt(111).multiply(111)` => `12321`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Multiplication)
+
+#### `neq(number)`
+
+Alias for the `notEquals` method.
+
+#### `next()`
+
+Adds one to the number.
+
+ - `bigInt(6).next()` => `7`
+
+#### `not()`
+
+Performs the bitwise NOT operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
+
+ - `bigInt(10).not()` => `-11`
+ - `bigInt(0).not()` => `-1`
+
+#### `notEquals(number)`
+
+Checks if two numbers are not equal.
+
+ - `bigInt(5).notEquals(5)` => `false`
+ - `bigInt(4).notEquals(7)` => `true`
+
+#### `or(number)`
+
+Performs the bitwise OR operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
+
+ - `bigInt(13).or(10)` => `15`
+ - `bigInt(13).or(-8)` => `-3`
+
+#### `over(number)`
+
+Alias for the `divide` method.
+
+ - `bigInt(59).over(5)` => `11`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
+
+#### `plus(number)`
+
+Alias for the `add` method.
+
+ - `bigInt(5).plus(7)` => `12`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Addition)
+
+#### `pow(number)`
+
+Performs exponentiation. If the exponent is less than `0`, `pow` returns `0`. `bigInt.zero.pow(0)` returns `1`.
+
+ - `bigInt(16).pow(16)` => `18446744073709551616`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Exponentiation)
+
+#### `prev(number)`
+
+Subtracts one from the number.
+
+ - `bigInt(6).prev()` => `5`
+
+#### `remainder(number)`
+
+Alias for the `mod` method.
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division)
+
+#### `shiftLeft(n)`
+
+Shifts the number left by `n` places in its binary representation. If a negative number is provided, it will shift right. Throws an error if `n` is outside of the range `[-9007199254740992, 9007199254740992]`.
+
+ - `bigInt(8).shiftLeft(2)` => `32`
+ - `bigInt(8).shiftLeft(-2)` => `2`
+
+#### `shiftRight(n)`
+
+Shifts the number right by `n` places in its binary representation. If a negative number is provided, it will shift left. Throws an error if `n` is outside of the range `[-9007199254740992, 9007199254740992]`.
+
+ - `bigInt(8).shiftRight(2)` => `2`
+ - `bigInt(8).shiftRight(-2)` => `32`
+
+#### `square()`
+
+Squares the number
+
+ - `bigInt(3).square()` => `9`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Squaring)
+
+#### `subtract(number)`
+
+Performs subtraction.
+
+ - `bigInt(3).subtract(5)` => `-2`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Subtraction)
+
+#### `times(number)`
+
+Alias for the `multiply` method.
+
+ - `bigInt(111).times(111)` => `12321`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Multiplication)
+
+#### `toArray(radix)`
+
+Converts a bigInt into an object with the properties "value" and "isNegative." "Value" is an array of integers modulo the given radix. "isNegative" is a boolean that represents the sign of the result.
+
+ - `bigInt("1e9").toArray(10)` => {
+ value: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ isNegative: false
+ }
+ - `bigInt("1e9").toArray(16)` => {
+ value: [3, 11, 9, 10, 12, 10, 0, 0],
+ isNegative: false
+ }
+ - `bigInt(567890).toArray(100)` => {
+ value: [56, 78, 90],
+ isNegative: false
+ }
+
+Negative bases are supported.
+
+ - `bigInt(12345).toArray(-10)` => {
+ value: [2, 8, 4, 6, 5],
+ isNegative: false
+ }
+
+Base 1 and base -1 are also supported.
+
+ - `bigInt(-15).toArray(1)` => {
+ value: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+ isNegative: true
+ }
+ - `bigInt(-15).toArray(-1)` => {
+ value: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
+ isNegative: false
+ }
+
+Base 0 is only allowed for the number zero.
+
+ - `bigInt(0).toArray(0)` => {
+ value: [0],
+ isNegative: false
+ }
+ - `bigInt(1).toArray(0)` => `Error: Cannot convert nonzero numbers to base 0.`
+
+#### `toJSNumber()`
+
+Converts a bigInt into a native Javascript number. Loses precision for numbers outside the range `[-9007199254740992, 9007199254740992]`.
+
+ - `bigInt("18446744073709551616").toJSNumber()` => `18446744073709552000`
+
+#### `xor(number)`
+
+Performs the bitwise XOR operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement).
+
+ - `bigInt(12).xor(5)` => `9`
+ - `bigInt(12).xor(-5)` => `-9`
+
+### Static Methods
+
+#### `fromArray(digits, base = 10, isNegative?)`
+
+Constructs a bigInt from an array of digits in base `base`. The optional `isNegative` flag will make the number negative.
+
+ - `bigInt.fromArray([1, 2, 3, 4, 5], 10)` => `12345`
+ - `bigInt.fromArray([1, 0, 0], 2, true)` => `-4`
+
+#### `gcd(a, b)`
+
+Finds the greatest common denominator of `a` and `b`.
+
+ - `bigInt.gcd(42,56)` => `14`
+
+#### `isInstance(x)`
+
+Returns `true` if `x` is a BigInteger, `false` otherwise.
+
+ - `bigInt.isInstance(bigInt(14))` => `true`
+ - `bigInt.isInstance(14)` => `false`
+
+#### `lcm(a,b)`
+
+Finds the least common multiple of `a` and `b`.
+
+ - `bigInt.lcm(21, 6)` => `42`
+
+#### `max(a,b)`
+
+Returns the largest of `a` and `b`.
+
+ - `bigInt.max(77, 432)` => `432`
+
+#### `min(a,b)`
+
+Returns the smallest of `a` and `b`.
+
+ - `bigInt.min(77, 432)` => `77`
+
+#### `randBetween(min, max)`
+
+Returns a random number between `min` and `max`.
+
+ - `bigInt.randBetween("-1e100", "1e100")` => (for example) `8494907165436643479673097939554427056789510374838494147955756275846226209006506706784609314471378745`
+
+
+### Override Methods
+
+#### `toString(radix = 10, [alphabet])`
+
+Converts a bigInt to a string. There is an optional radix parameter (which defaults to 10) that converts the number to the given radix. Digits in the range `10-35` will use the letters `a-z`.
+
+ - `bigInt("1e9").toString()` => `"1000000000"`
+ - `bigInt("1e9").toString(16)` => `"3b9aca00"`
+
+ You can use a custom base alphabet with the second parameter. The default `alphabet` is `"0123456789abcdefghijklmnopqrstuvwxyz"`.
+
+ - `bigInt("5").toString(2, "aA")` => `"AaA"`
+
+**Note that arithmetical operators will trigger the `valueOf` function rather than the `toString` function.** When converting a bigInteger to a string, you should use the `toString` method or the `String` function instead of adding the empty string.
+
+ - `bigInt("999999999999999999").toString()` => `"999999999999999999"`
+ - `String(bigInt("999999999999999999"))` => `"999999999999999999"`
+ - `bigInt("999999999999999999") + ""` => `1000000000000000000`
+
+Bases larger than 36 are supported. If a digit is greater than or equal to 36, it will be enclosed in angle brackets.
+
+ - `bigInt(567890).toString(100)` => `"<56><78><90>"`
+
+Negative bases are also supported.
+
+ - `bigInt(12345).toString(-10)` => `"28465"`
+
+Base 1 and base -1 are also supported.
+
+ - `bigInt(-15).toString(1)` => `"-111111111111111"`
+ - `bigInt(-15).toString(-1)` => `"101010101010101010101010101010"`
+
+Base 0 is only allowed for the number zero.
+
+ - `bigInt(0).toString(0)` => `0`
+ - `bigInt(1).toString(0)` => `Error: Cannot convert nonzero numbers to base 0.`
+
+[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#toString)
+
+#### `valueOf()`
+
+Converts a bigInt to a native Javascript number. This override allows you to use native arithmetic operators without explicit conversion:
+
+ - `bigInt("100") + bigInt("200") === 300; //true`
+
+## Contributors
+
+To contribute, just fork the project, make some changes, and submit a pull request. Please verify that the unit tests pass before submitting.
+
+The unit tests are contained in the `spec/spec.js` file. You can run them locally by opening the `spec/SpecRunner.html` or file or running `npm test`. You can also [run the tests online from GitHub](http://peterolson.github.io/BigInteger.js/spec/SpecRunner.html).
+
+There are performance benchmarks that can be viewed from the `benchmarks/index.html` page. You can [run them online from GitHub](http://peterolson.github.io/BigInteger.js/benchmark/).
+
+## License
+
+This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/).
diff --git a/big-integer/benchmark/benchmark.js b/big-integer/benchmark/benchmark.js
new file mode 100644
index 0000000..c17b365
--- /dev/null
+++ b/big-integer/benchmark/benchmark.js
@@ -0,0 +1,3919 @@
+/*!
+ * Benchmark.js v1.0.0 <http://benchmarkjs.com/>
+ * Copyright 2010-2012 Mathias Bynens <http://mths.be/>
+ * Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
+ * Modified by John-David Dalton <http://allyoucanleet.com/>
+ * Available under MIT license <http://mths.be/mit>
+ */
+;(function(window, undefined) {
+ 'use strict';
+
+ /** Used to assign each benchmark an incrimented id */
+ var counter = 0;
+
+ /** Detect DOM document object */
+ var doc = isHostType(window, 'document') && document;
+
+ /** Detect free variable `define` */
+ var freeDefine = typeof define == 'function' &&
+ typeof define.amd == 'object' && define.amd && define;
+
+ /** Detect free variable `exports` */
+ var freeExports = typeof exports == 'object' && exports &&
+ (typeof global == 'object' && global && global == global.global && (window = global), exports);
+
+ /** Detect free variable `require` */
+ var freeRequire = typeof require == 'function' && require;
+
+ /** Used to crawl all properties regardless of enumerability */
+ var getAllKeys = Object.getOwnPropertyNames;
+
+ /** Used to get property descriptors */
+ var getDescriptor = Object.getOwnPropertyDescriptor;
+
+ /** Used in case an object doesn't have its own method */
+ var hasOwnProperty = {}.hasOwnProperty;
+
+ /** Used to check if an object is extensible */
+ var isExtensible = Object.isExtensible || function() { return true; };
+
+ /** Used to access Wade Simmons' Node microtime module */
+ var microtimeObject = req('microtime');
+
+ /** Used to access the browser's high resolution timer */
+ var perfObject = isHostType(window, 'performance') && performance;
+
+ /** Used to call the browser's high resolution timer */
+ var perfName = perfObject && (
+ perfObject.now && 'now' ||
+ perfObject.webkitNow && 'webkitNow'
+ );
+
+ /** Used to access Node's high resolution timer */
+ var processObject = isHostType(window, 'process') && process;
+
+ /** Used to check if an own property is enumerable */
+ var propertyIsEnumerable = {}.propertyIsEnumerable;
+
+ /** Used to set property descriptors */
+ var setDescriptor = Object.defineProperty;
+
+ /** Used to resolve a value's internal [[Class]] */
+ var toString = {}.toString;
+
+ /** Used to prevent a `removeChild` memory leak in IE < 9 */
+ var trash = doc && doc.createElement('div');
+
+ /** Used to integrity check compiled tests */
+ var uid = 'uid' + (+new Date);
+
+ /** Used to avoid infinite recursion when methods call each other */
+ var calledBy = {};
+
+ /** Used to avoid hz of Infinity */
+ var divisors = {
+ '1': 4096,
+ '2': 512,
+ '3': 64,
+ '4': 8,
+ '5': 0
+ };
+
+ /**
+ * T-Distribution two-tailed critical values for 95% confidence
+ * http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
+ */
+ var tTable = {
+ '1': 12.706,'2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447,
+ '7': 2.365, '8': 2.306, '9': 2.262, '10': 2.228, '11': 2.201, '12': 2.179,
+ '13': 2.16, '14': 2.145, '15': 2.131, '16': 2.12, '17': 2.11, '18': 2.101,
+ '19': 2.093, '20': 2.086, '21': 2.08, '22': 2.074, '23': 2.069, '24': 2.064,
+ '25': 2.06, '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042,
+ 'infinity': 1.96
+ };
+
+ /**
+ * Critical Mann-Whitney U-values for 95% confidence
+ * http://www.saburchill.com/IBbiology/stats/003.html
+ */
+ var uTable = {
+ '5': [0, 1, 2],
+ '6': [1, 2, 3, 5],
+ '7': [1, 3, 5, 6, 8],
+ '8': [2, 4, 6, 8, 10, 13],
+ '9': [2, 4, 7, 10, 12, 15, 17],
+ '10': [3, 5, 8, 11, 14, 17, 20, 23],
+ '11': [3, 6, 9, 13, 16, 19, 23, 26, 30],
+ '12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37],
+ '13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45],
+ '14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55],
+ '15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64],
+ '16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75],
+ '17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87],
+ '18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99],
+ '19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113],
+ '20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127],
+ '21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142],
+ '22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158],
+ '23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175],
+ '24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192],
+ '25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211],
+ '26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230],
+ '27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250],
+ '28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272],
+ '29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294],
+ '30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317]
+ };
+
+ /**
+ * An object used to flag environments/features.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @type Object
+ */
+ var support = {};
+
+ (function() {
+
+ /**
+ * Detect Adobe AIR.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.air = isClassOf(window.runtime, 'ScriptBridgingProxyObject');
+
+ /**
+ * Detect if `arguments` objects have the correct internal [[Class]] value.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.argumentsClass = isClassOf(arguments, 'Arguments');
+
+ /**
+ * Detect if in a browser environment.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.browser = doc && isHostType(window, 'navigator');
+
+ /**
+ * Detect if strings support accessing characters by index.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.charByIndex =
+ // IE 8 supports indexes on string literals but not string objects
+ ('x'[0] + Object('x')[0]) == 'xx';
+
+ /**
+ * Detect if strings have indexes as own properties.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.charByOwnIndex =
+ // Narwhal, Rhino, RingoJS, IE 8, and Opera < 10.52 support indexes on
+ // strings but don't detect them as own properties
+ support.charByIndex && hasKey('x', '0');
+
+ /**
+ * Detect if Java is enabled/exposed.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.java = isClassOf(window.java, 'JavaPackage');
+
+ /**
+ * Detect if the Timers API exists.
+ *
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.timeout = isHostType(window, 'setTimeout') && isHostType(window, 'clearTimeout');
+
+ /**
+ * Detect if functions support decompilation.
+ *
+ * @name decompilation
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ try {
+ // Safari 2.x removes commas in object literals
+ // from Function#toString results
+ // http://webk.it/11609
+ // Firefox 3.6 and Opera 9.25 strip grouping
+ // parentheses from Function#toString results
+ // http://bugzil.la/559438
+ support.decompilation = Function(
+ 'return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')'
+ )()(0).x === '1';
+ } catch(e) {
+ support.decompilation = false;
+ }
+
+ /**
+ * Detect ES5+ property descriptor API.
+ *
+ * @name descriptors
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ try {
+ var o = {};
+ support.descriptors = (setDescriptor(o, o, o), 'value' in getDescriptor(o, o));
+ } catch(e) {
+ support.descriptors = false;
+ }
+
+ /**
+ * Detect ES5+ Object.getOwnPropertyNames().
+ *
+ * @name getAllKeys
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ try {
+ support.getAllKeys = /\bvalueOf\b/.test(getAllKeys(Object.prototype));
+ } catch(e) {
+ support.getAllKeys = false;
+ }
+
+ /**
+ * Detect if own properties are iterated before inherited properties (all but IE < 9).
+ *
+ * @name iteratesOwnLast
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ support.iteratesOwnFirst = (function() {
+ var props = [];
+ function ctor() { this.x = 1; }
+ ctor.prototype = { 'y': 1 };
+ for (var prop in new ctor) { props.push(prop); }
+ return props[0] == 'x';
+ }());
+
+ /**
+ * Detect if a node's [[Class]] is resolvable (all but IE < 9)
+ * and that the JS engine errors when attempting to coerce an object to a
+ * string without a `toString` property value of `typeof` "function".
+ *
+ * @name nodeClass
+ * @memberOf Benchmark.support
+ * @type Boolean
+ */
+ try {
+ support.nodeClass = ({ 'toString': 0 } + '', toString.call(doc || 0) != '[object Object]');
+ } catch(e) {
+ support.nodeClass = true;
+ }
+ }());
+
+ /**
+ * Timer object used by `clock()` and `Deferred#resolve`.
+ *
+ * @private
+ * @type Object
+ */
+ var timer = {
+
+ /**
+ * The timer namespace object or constructor.
+ *
+ * @private
+ * @memberOf timer
+ * @type Function|Object
+ */
+ 'ns': Date,
+
+ /**
+ * Starts the deferred timer.
+ *
+ * @private
+ * @memberOf timer
+ * @param {Object} deferred The deferred instance.
+ */
+ 'start': null, // lazy defined in `clock()`
+
+ /**
+ * Stops the deferred timer.
+ *
+ * @private
+ * @memberOf timer
+ * @param {Object} deferred The deferred instance.
+ */
+ 'stop': null // lazy defined in `clock()`
+ };
+
+ /** Shortcut for inverse results */
+ var noArgumentsClass = !support.argumentsClass,
+ noCharByIndex = !support.charByIndex,
+ noCharByOwnIndex = !support.charByOwnIndex;
+
+ /** Math shortcuts */
+ var abs = Math.abs,
+ floor = Math.floor,
+ max = Math.max,
+ min = Math.min,
+ pow = Math.pow,
+ sqrt = Math.sqrt;
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * The Benchmark constructor.
+ *
+ * @constructor
+ * @param {String} name A name to identify the benchmark.
+ * @param {Function|String} fn The test to benchmark.
+ * @param {Object} [options={}] Options object.
+ * @example
+ *
+ * // basic usage (the `new` operator is optional)
+ * var bench = new Benchmark(fn);
+ *
+ * // or using a name first
+ * var bench = new Benchmark('foo', fn);
+ *
+ * // or with options
+ * var bench = new Benchmark('foo', fn, {
+ *
+ * // displayed by Benchmark#toString if `name` is not available
+ * 'id': 'xyz',
+ *
+ * // called when the benchmark starts running
+ * 'onStart': onStart,
+ *
+ * // called after each run cycle
+ * 'onCycle': onCycle,
+ *
+ * // called when aborted
+ * 'onAbort': onAbort,
+ *
+ * // called when a test errors
+ * 'onError': onError,
+ *
+ * // called when reset
+ * 'onReset': onReset,
+ *
+ * // called when the benchmark completes running
+ * 'onComplete': onComplete,
+ *
+ * // compiled/called before the test loop
+ * 'setup': setup,
+ *
+ * // compiled/called after the test loop
+ * 'teardown': teardown
+ * });
+ *
+ * // or name and options
+ * var bench = new Benchmark('foo', {
+ *
+ * // a flag to indicate the benchmark is deferred
+ * 'defer': true,
+ *
+ * // benchmark test function
+ * 'fn': function(deferred) {
+ * // call resolve() when the deferred test is finished
+ * deferred.resolve();
+ * }
+ * });
+ *
+ * // or options only
+ * var bench = new Benchmark({
+ *
+ * // benchmark name
+ * 'name': 'foo',
+ *
+ * // benchmark test as a string
+ * 'fn': '[1,2,3,4].sort()'
+ * });
+ *
+ * // a test's `this` binding is set to the benchmark instance
+ * var bench = new Benchmark('foo', function() {
+ * 'My name is '.concat(this.name); // My name is foo
+ * });
+ */
+ function Benchmark(name, fn, options) {
+ var me = this;
+
+ // allow instance creation without the `new` operator
+ if (me == null || me.constructor != Benchmark) {
+ return new Benchmark(name, fn, options);
+ }
+ // juggle arguments
+ if (isClassOf(name, 'Object')) {
+ // 1 argument (options)
+ options = name;
+ }
+ else if (isClassOf(name, 'Function')) {
+ // 2 arguments (fn, options)
+ options = fn;
+ fn = name;
+ }
+ else if (isClassOf(fn, 'Object')) {
+ // 2 arguments (name, options)
+ options = fn;
+ fn = null;
+ me.name = name;
+ }
+ else {
+ // 3 arguments (name, fn [, options])
+ me.name = name;
+ }
+ setOptions(me, options);
+ me.id || (me.id = ++counter);
+ me.fn == null && (me.fn = fn);
+ me.stats = deepClone(me.stats);
+ me.times = deepClone(me.times);
+ }
+
+ /**
+ * The Deferred constructor.
+ *
+ * @constructor
+ * @memberOf Benchmark
+ * @param {Object} clone The cloned benchmark instance.
+ */
+ function Deferred(clone) {
+ var me = this;
+ if (me == null || me.constructor != Deferred) {
+ return new Deferred(clone);
+ }
+ me.benchmark = clone;
+ clock(me);
+ }
+
+ /**
+ * The Event constructor.
+ *
+ * @constructor
+ * @memberOf Benchmark
+ * @param {String|Object} type The event type.
+ */
+ function Event(type) {
+ var me = this;
+ return (me == null || me.constructor != Event)
+ ? new Event(type)
+ : (type instanceof Event)
+ ? type
+ : extend(me, { 'timeStamp': +new Date }, typeof type == 'string' ? { 'type': type } : type);
+ }
+
+ /**
+ * The Suite constructor.
+ *
+ * @constructor
+ * @memberOf Benchmark
+ * @param {String} name A name to identify the suite.
+ * @param {Object} [options={}] Options object.
+ * @example
+ *
+ * // basic usage (the `new` operator is optional)
+ * var suite = new Benchmark.Suite;
+ *
+ * // or using a name first
+ * var suite = new Benchmark.Suite('foo');
+ *
+ * // or with options
+ * var suite = new Benchmark.Suite('foo', {
+ *
+ * // called when the suite starts running
+ * 'onStart': onStart,
+ *
+ * // called between running benchmarks
+ * 'onCycle': onCycle,
+ *
+ * // called when aborted
+ * 'onAbort': onAbort,
+ *
+ * // called when a test errors
+ * 'onError': onError,
+ *
+ * // called when reset
+ * 'onReset': onReset,
+ *
+ * // called when the suite completes running
+ * 'onComplete': onComplete
+ * });
+ */
+ function Suite(name, options) {
+ var me = this;
+
+ // allow instance creation without the `new` operator
+ if (me == null || me.constructor != Suite) {
+ return new Suite(name, options);
+ }
+ // juggle arguments
+ if (isClassOf(name, 'Object')) {
+ // 1 argument (options)
+ options = name;
+ } else {
+ // 2 arguments (name [, options])
+ me.name = name;
+ }
+ setOptions(me, options);
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Note: Some array methods have been implemented in plain JavaScript to avoid
+ * bugs in IE, Opera, Rhino, and Mobile Safari.
+ *
+ * IE compatibility mode and IE < 9 have buggy Array `shift()` and `splice()`
+ * functions that fail to remove the last element, `object[0]`, of
+ * array-like-objects even though the `length` property is set to `0`.
+ * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
+ * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
+ *
+ * In Opera < 9.50 and some older/beta Mobile Safari versions using `unshift()`
+ * generically to augment the `arguments` object will pave the value at index 0
+ * without incrimenting the other values's indexes.
+ * https://github.com/documentcloud/underscore/issues/9
+ *
+ * Rhino and environments it powers, like Narwhal and RingoJS, may have
+ * buggy Array `concat()`, `reverse()`, `shift()`, `slice()`, `splice()` and
+ * `unshift()` functions that make sparse arrays non-sparse by assigning the
+ * undefined indexes a value of undefined.
+ * https://github.com/mozilla/rhino/commit/702abfed3f8ca043b2636efd31c14ba7552603dd
+ */
+
+ /**
+ * Creates an array containing the elements of the host array followed by the
+ * elements of each argument in order.
+ *
+ * @memberOf Benchmark.Suite
+ * @returns {Array} The new array.
+ */
+ function concat() {
+ var value,
+ j = -1,
+ length = arguments.length,
+ result = slice.call(this),
+ index = result.length;
+
+ while (++j < length) {
+ value = arguments[j];
+ if (isClassOf(value, 'Array')) {
+ for (var k = 0, l = value.length; k < l; k++, index++) {
+ if (k in value) {
+ result[index] = value[k];
+ }
+ }
+ } else {
+ result[index++] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Utility function used by `shift()`, `splice()`, and `unshift()`.
+ *
+ * @private
+ * @param {Number} start The index to start inserting elements.
+ * @param {Number} deleteCount The number of elements to delete from the insert point.
+ * @param {Array} elements The elements to insert.
+ * @returns {Array} An array of deleted elements.
+ */
+ function insert(start, deleteCount, elements) {
+ // `result` should have its length set to the `deleteCount`
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=332
+ var deleteEnd = start + deleteCount,
+ elementCount = elements ? elements.length : 0,
+ index = start - 1,
+ length = start + elementCount,
+ object = this,
+ result = Array(deleteCount),
+ tail = slice.call(object, deleteEnd);
+
+ // delete elements from the array
+ while (++index < deleteEnd) {
+ if (index in object) {
+ result[index - start] = object[index];
+ delete object[index];
+ }
+ }
+ // insert elements
+ index = start - 1;
+ while (++index < length) {
+ object[index] = elements[index - start];
+ }
+ // append tail elements
+ start = index--;
+ length = max(0, (object.length >>> 0) - deleteCount + elementCount);
+ while (++index < length) {
+ if ((index - start) in tail) {
+ object[index] = tail[index - start];
+ } else if (index in object) {
+ delete object[index];
+ }
+ }
+ // delete excess elements
+ deleteCount = deleteCount > elementCount ? deleteCount - elementCount : 0;
+ while (deleteCount--) {
+ index = length + deleteCount;
+ if (index in object) {
+ delete object[index];
+ }
+ }
+ object.length = length;
+ return result;
+ }
+
+ /**
+ * Rearrange the host array's elements in reverse order.
+ *
+ * @memberOf Benchmark.Suite
+ * @returns {Array} The reversed array.
+ */
+ function reverse() {
+ var upperIndex,
+ value,
+ index = -1,
+ object = Object(this),
+ length = object.length >>> 0,
+ middle = floor(length / 2);
+
+ if (length > 1) {
+ while (++index < middle) {
+ upperIndex = length - index - 1;
+ value = upperIndex in object ? object[upperIndex] : uid;
+ if (index in object) {
+ object[upperIndex] = object[index];
+ } else {
+ delete object[upperIndex];
+ }
+ if (value != uid) {
+ object[index] = value;
+ } else {
+ delete object[index];
+ }
+ }
+ }
+ return object;
+ }
+
+ /**
+ * Removes the first element of the host array and returns it.
+ *
+ * @memberOf Benchmark.Suite
+ * @returns {Mixed} The first element of the array.
+ */
+ function shift() {
+ return insert.call(this, 0, 1)[0];
+ }
+
+ /**
+ * Creates an array of the host array's elements from the start index up to,
+ * but not including, the end index.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Number} start The starting index.
+ * @param {Number} end The end index.
+ * @returns {Array} The new array.
+ */
+ function slice(start, end) {
+ var index = -1,
+ object = Object(this),
+ length = object.length >>> 0,
+ result = [];
+
+ start = toInteger(start);
+ start = start < 0 ? max(length + start, 0) : min(start, length);
+ start--;
+ end = end == null ? length : toInteger(end);
+ end = end < 0 ? max(length + end, 0) : min(end, length);
+
+ while ((++index, ++start) < end) {
+ if (start in object) {
+ result[index] = object[start];
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Allows removing a range of elements and/or inserting elements into the
+ * host array.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Number} start The start index.
+ * @param {Number} deleteCount The number of elements to delete.
+ * @param {Mixed} [val1, val2, ...] values to insert at the `start` index.
+ * @returns {Array} An array of removed elements.
+ */
+ function splice(start, deleteCount) {
+ var object = Object(this),
+ length = object.length >>> 0;
+
+ start = toInteger(start);
+ start = start < 0 ? max(length + start, 0) : min(start, length);
+
+ // support the de-facto SpiderMonkey extension
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice#Parameters
+ // https://bugs.ecmascript.org/show_bug.cgi?id=429
+ deleteCount = arguments.length == 1
+ ? length - start
+ : min(max(toInteger(deleteCount), 0), length - start);
+
+ return insert.call(object, start, deleteCount, slice.call(arguments, 2));
+ }
+
+ /**
+ * Converts the specified `value` to an integer.
+ *
+ * @private
+ * @param {Mixed} value The value to convert.
+ * @returns {Number} The resulting integer.
+ */
+ function toInteger(value) {
+ value = +value;
+ return value === 0 || !isFinite(value) ? value || 0 : value - (value % 1);
+ }
+
+ /**
+ * Appends arguments to the host array.
+ *
+ * @memberOf Benchmark.Suite
+ * @returns {Number} The new length.
+ */
+ function unshift() {
+ var object = Object(this);
+ insert.call(object, 0, 0, arguments);
+ return object.length;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * A generic `Function#bind` like method.
+ *
+ * @private
+ * @param {Function} fn The function to be bound to `thisArg`.
+ * @param {Mixed} thisArg The `this` binding for the given function.
+ * @returns {Function} The bound function.
+ */
+ function bind(fn, thisArg) {
+ return function() { fn.apply(thisArg, arguments); };
+ }
+
+ /**
+ * Creates a function from the given arguments string and body.
+ *
+ * @private
+ * @param {String} args The comma separated function arguments.
+ * @param {String} body The function body.
+ * @returns {Function} The new function.
+ */
+ function createFunction() {
+ // lazy define
+ createFunction = function(args, body) {
+ var result,
+ anchor = freeDefine ? define.amd : Benchmark,
+ prop = uid + 'createFunction';
+
+ runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}');
+ result = anchor[prop];
+ delete anchor[prop];
+ return result;
+ };
+ // fix JaegerMonkey bug
+ // http://bugzil.la/639720
+ createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || noop)() == uid ? createFunction : Function;
+ return createFunction.apply(null, arguments);
+ }
+
+ /**
+ * Delay the execution of a function based on the benchmark's `delay` property.
+ *
+ * @private
+ * @param {Object} bench The benchmark instance.
+ * @param {Object} fn The function to execute.
+ */
+ function delay(bench, fn) {
+ bench._timerId = setTimeout(fn, bench.delay * 1e3);
+ }
+
+ /**
+ * Destroys the given element.
+ *
+ * @private
+ * @param {Element} element The element to destroy.
+ */
+ function destroyElement(element) {
+ trash.appendChild(element);
+ trash.innerHTML = '';
+ }
+
+ /**
+ * Iterates over an object's properties, executing the `callback` for each.
+ * Callbacks may terminate the loop by explicitly returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} callback The function executed per own property.
+ * @param {Object} options The options object.
+ * @returns {Object} Returns the object iterated over.
+ */
+ function forProps() {
+ var forShadowed,
+ skipSeen,
+ forArgs = true,
+ shadowed = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];
+
+ (function(enumFlag, key) {
+ // must use a non-native constructor to catch the Safari 2 issue
+ function Klass() { this.valueOf = 0; };
+ Klass.prototype.valueOf = 0;
+ // check various for-in bugs
+ for (key in new Klass) {
+ enumFlag += key == 'valueOf' ? 1 : 0;
+ }
+ // check if `arguments` objects have non-enumerable indexes
+ for (key in arguments) {
+ key == '0' && (forArgs = false);
+ }
+ // Safari 2 iterates over shadowed properties twice
+ // http://replay.waybackmachine.org/20090428222941/http://tobielangel.com/2007/1/29/for-in-loop-broken-in-safari/
+ skipSeen = enumFlag == 2;
+ // IE < 9 incorrectly makes an object's properties non-enumerable if they have
+ // the same name as other non-enumerable properties in its prototype chain.
+ forShadowed = !enumFlag;
+ }(0));
+
+ // lazy define
+ forProps = function(object, callback, options) {
+ options || (options = {});
+
+ var result = object;
+ object = Object(object);
+
+ var ctor,
+ key,
+ keys,
+ skipCtor,
+ done = !result,
+ which = options.which,
+ allFlag = which == 'all',
+ index = -1,
+ iteratee = object,
+ length = object.length,
+ ownFlag = allFlag || which == 'own',
+ seen = {},
+ skipProto = isClassOf(object, 'Function'),
+ thisArg = options.bind;
+
+ if (thisArg !== undefined) {
+ callback = bind(callback, thisArg);
+ }
+ // iterate all properties
+ if (allFlag && support.getAllKeys) {
+ for (index = 0, keys = getAllKeys(object), length = keys.length; index < length; index++) {
+ key = keys[index];
+ if (callback(object[key], key, object) === false) {
+ break;
+ }
+ }
+ }
+ // else iterate only enumerable properties
+ else {
+ for (key in object) {
+ // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
+ // (if the prototype or a property on the prototype has been set)
+ // incorrectly set a function's `prototype` property [[Enumerable]] value
+ // to `true`. Because of this we standardize on skipping the `prototype`
+ // property of functions regardless of their [[Enumerable]] value.
+ if ((done =
+ !(skipProto && key == 'prototype') &&
+ !(skipSeen && (hasKey(seen, key) || !(seen[key] = true))) &&
+ (!ownFlag || ownFlag && hasKey(object, key)) &&
+ callback(object[key], key, object) === false)) {
+ break;
+ }
+ }
+ // in IE < 9 strings don't support accessing characters by index
+ if (!done && (forArgs && isArguments(object) ||
+ ((noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String') &&
+ (iteratee = noCharByIndex ? object.split('') : object)))) {
+ while (++index < length) {
+ if ((done =
+ callback(iteratee[index], String(index), object) === false)) {
+ break;
+ }
+ }
+ }
+ if (!done && forShadowed) {
+ // Because IE < 9 can't set the `[[Enumerable]]` attribute of an existing
+ // property and the `constructor` property of a prototype defaults to
+ // non-enumerable, we manually skip the `constructor` property when we
+ // think we are iterating over a `prototype` object.
+ ctor = object.constructor;
+ skipCtor = ctor && ctor.prototype && ctor.prototype.constructor === ctor;
+ for (index = 0; index < 7; index++) {
+ key = shadowed[index];
+ if (!(skipCtor && key == 'constructor') &&
+ hasKey(object, key) &&
+ callback(object[key], key, object) === false) {
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ };
+ return forProps.apply(null, arguments);
+ }
+
+ /**
+ * Gets the name of the first argument from a function's source.
+ *
+ * @private
+ * @param {Function} fn The function.
+ * @returns {String} The argument name.
+ */
+ function getFirstArgument(fn) {
+ return (!hasKey(fn, 'toString') &&
+ (/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || '';
+ }
+
+ /**
+ * Computes the arithmetic mean of a sample.
+ *
+ * @private
+ * @param {Array} sample The sample.
+ * @returns {Number} The mean.
+ */
+ function getMean(sample) {
+ return reduce(sample, function(sum, x) {
+ return sum + x;
+ }) / sample.length || 0;
+ }
+
+ /**
+ * Gets the source code of a function.
+ *
+ * @private
+ * @param {Function} fn The function.
+ * @param {String} altSource A string used when a function's source code is unretrievable.
+ * @returns {String} The function's source code.
+ */
+ function getSource(fn, altSource) {
+ var result = altSource;
+ if (isStringable(fn)) {
+ result = String(fn);
+ } else if (support.decompilation) {
+ // escape the `{` for Firefox 1
+ result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1];
+ }
+ // trim string
+ result = (result || '').replace(/^\s+|\s+$/g, '');
+
+ // detect strings containing only the "use strict" directive
+ return /^(?:\/\*+[\w|\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result)
+ ? ''
+ : result;
+ }
+
+ /**
+ * Checks if a value is an `arguments` object.
+ *
+ * @private
+ * @param {Mixed} value The value to check.
+ * @returns {Boolean} Returns `true` if the value is an `arguments` object, else `false`.
+ */
+ function isArguments() {
+ // lazy define
+ isArguments = function(value) {
+ return toString.call(value) == '[object Arguments]';
+ };
+ if (noArgumentsClass) {
+ isArguments = function(value) {
+ return hasKey(value, 'callee') &&
+ !(propertyIsEnumerable && propertyIsEnumerable.call(value, 'callee'));
+ };
+ }
+ return isArguments(arguments[0]);
+ }
+
+ /**
+ * Checks if an object is of the specified class.
+ *
+ * @private
+ * @param {Mixed} value The value to check.
+ * @param {String} name The name of the class.
+ * @returns {Boolean} Returns `true` if the value is of the specified class, else `false`.
+ */
+ function isClassOf(value, name) {
+ return value != null && toString.call(value) == '[object ' + name + ']';
+ }
+
+ /**
+ * Host objects can return type values that are different from their actual
+ * data type. The objects we are concerned with usually return non-primitive
+ * types of object, function, or unknown.
+ *
+ * @private
+ * @param {Mixed} object The owner of the property.
+ * @param {String} property The property to check.
+ * @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
+ */
+ function isHostType(object, property) {
+ var type = object != null ? typeof object[property] : 'number';
+ return !/^(?:boolean|number|string|undefined)$/.test(type) &&
+ (type == 'object' ? !!object[property] : true);
+ }
+
+ /**
+ * Checks if a given `value` is an object created by the `Object` constructor
+ * assuming objects created by the `Object` constructor have no inherited
+ * enumerable properties and that there are no `Object.prototype` extensions.
+ *
+ * @private
+ * @param {Mixed} value The value to check.
+ * @returns {Boolean} Returns `true` if the `value` is a plain `Object` object, else `false`.
+ */
+ function isPlainObject(value) {
+ // avoid non-objects and false positives for `arguments` objects in IE < 9
+ var result = false;
+ if (!(value && typeof value == 'object') || isArguments(value)) {
+ return result;
+ }
+ // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
+ // methods that are `typeof` "string" and still can coerce nodes to strings.
+ // Also check that the constructor is `Object` (i.e. `Object instanceof Object`)
+ var ctor = value.constructor;
+ if ((support.nodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) &&
+ (!isClassOf(ctor, 'Function') || ctor instanceof ctor)) {
+ // In most environments an object's own properties are iterated before
+ // its inherited properties. If the last iterated property is an object's
+ // own property then there are no inherited enumerable properties.
+ if (support.iteratesOwnFirst) {
+ forProps(value, function(subValue, subKey) {
+ result = subKey;
+ });
+ return result === false || hasKey(value, result);
+ }
+ // IE < 9 iterates inherited properties before own properties. If the first
+ // iterated property is an object's own property then there are no inherited
+ // enumerable properties.
+ forProps(value, function(subValue, subKey) {
+ result = !hasKey(value, subKey);
+ return false;
+ });
+ return result === false;
+ }
+ return result;
+ }
+
+ /**
+ * Checks if a value can be safely coerced to a string.
+ *
+ * @private
+ * @param {Mixed} value The value to check.
+ * @returns {Boolean} Returns `true` if the value can be coerced, else `false`.
+ */
+ function isStringable(value) {
+ return hasKey(value, 'toString') || isClassOf(value, 'String');
+ }
+
+ /**
+ * Wraps a function and passes `this` to the original function as the
+ * first argument.
+ *
+ * @private
+ * @param {Function} fn The function to be wrapped.
+ * @returns {Function} The new function.
+ */
+ function methodize(fn) {
+ return function() {
+ var args = [this];
+ args.push.apply(args, arguments);
+ return fn.apply(null, args);
+ };
+ }
+
+ /**
+ * A no-operation function.
+ *
+ * @private
+ */
+ function noop() {
+ // no operation performed
+ }
+
+ /**
+ * A wrapper around require() to suppress `module missing` errors.
+ *
+ * @private
+ * @param {String} id The module id.
+ * @returns {Mixed} The exported module or `null`.
+ */
+ function req(id) {
+ try {
+ var result = freeExports && freeRequire(id);
+ } catch(e) { }
+ return result || null;
+ }
+
+ /**
+ * Runs a snippet of JavaScript via script injection.
+ *
+ * @private
+ * @param {String} code The code to run.
+ */
+ function runScript(code) {
+ var anchor = freeDefine ? define.amd : Benchmark,
+ script = doc.createElement('script'),
+ sibling = doc.getElementsByTagName('script')[0],
+ parent = sibling.parentNode,
+ prop = uid + 'runScript',
+ prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();';
+
+ // Firefox 2.0.0.2 cannot use script injection as intended because it executes
+ // asynchronously, but that's OK because script injection is only used to avoid
+ // the previously commented JaegerMonkey bug.
+ try {
+ // remove the inserted script *before* running the code to avoid differences
+ // in the expected script element count/order of the document.
+ script.appendChild(doc.createTextNode(prefix + code));
+ anchor[prop] = function() { destroyElement(script); };
+ } catch(e) {
+ parent = parent.cloneNode(false);
+ sibling = null;
+ script.text = code;
+ }
+ parent.insertBefore(script, sibling);
+ delete anchor[prop];
+ }
+
+ /**
+ * A helper function for setting options/event handlers.
+ *
+ * @private
+ * @param {Object} bench The benchmark instance.
+ * @param {Object} [options={}] Options object.
+ */
+ function setOptions(bench, options) {
+ options = extend({}, bench.constructor.options, options);
+ bench.options = forOwn(options, function(value, key) {
+ if (value != null) {
+ // add event listeners
+ if (/^on[A-Z]/.test(key)) {
+ forEach(key.split(' '), function(key) {
+ bench.on(key.slice(2).toLowerCase(), value);
+ });
+ } else if (!hasKey(bench, key)) {
+ bench[key] = deepClone(value);
+ }
+ }
+ });
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Handles cycling/completing the deferred benchmark.
+ *
+ * @memberOf Benchmark.Deferred
+ */
+ function resolve() {
+ var me = this,
+ clone = me.benchmark,
+ bench = clone._original;
+
+ if (bench.aborted) {
+ // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete
+ me.teardown();
+ clone.running = false;
+ cycle(me);
+ }
+ else if (++me.cycles < clone.count) {
+ // continue the test loop
+ if (support.timeout) {
+ // use setTimeout to avoid a call stack overflow if called recursively
+ setTimeout(function() { clone.compiled.call(me, timer); }, 0);
+ } else {
+ clone.compiled.call(me, timer);
+ }
+ }
+ else {
+ timer.stop(me);
+ me.teardown();
+ delay(clone, function() { cycle(me); });
+ }
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * A deep clone utility.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Mixed} value The value to clone.
+ * @returns {Mixed} The cloned value.
+ */
+ function deepClone(value) {
+ var accessor,
+ circular,
+ clone,
+ ctor,
+ descriptor,
+ extensible,
+ key,
+ length,
+ markerKey,
+ parent,
+ result,
+ source,
+ subIndex,
+ data = { 'value': value },
+ index = 0,
+ marked = [],
+ queue = { 'length': 0 },
+ unmarked = [];
+
+ /**
+ * An easily detectable decorator for cloned values.
+ */
+ function Marker(object) {
+ this.raw = object;
+ }
+
+ /**
+ * The callback used by `forProps()`.
+ */
+ function forPropsCallback(subValue, subKey) {
+ // exit early to avoid cloning the marker
+ if (subValue && subValue.constructor == Marker) {
+ return;
+ }
+ // add objects to the queue
+ if (subValue === Object(subValue)) {
+ queue[queue.length++] = { 'key': subKey, 'parent': clone, 'source': value };
+ }
+ // assign non-objects
+ else {
+ try {
+ // will throw an error in strict mode if the property is read-only
+ clone[subKey] = subValue;
+ } catch(e) { }
+ }
+ }
+
+ /**
+ * Gets an available marker key for the given object.
+ */
+ function getMarkerKey(object) {
+ // avoid collisions with existing keys
+ var result = uid;
+ while (object[result] && object[result].constructor != Marker) {
+ result += 1;
+ }
+ return result;
+ }
+
+ do {
+ key = data.key;
+ parent = data.parent;
+ source = data.source;
+ clone = value = source ? source[key] : data.value;
+ accessor = circular = descriptor = false;
+
+ // create a basic clone to filter out functions, DOM elements, and
+ // other non `Object` objects
+ if (value === Object(value)) {
+ // use custom deep clone function if available
+ if (isClassOf(value.deepClone, 'Function')) {
+ clone = value.deepClone();
+ } else {
+ ctor = value.constructor;
+ switch (toString.call(value)) {
+ case '[object Array]':
+ clone = new ctor(value.length);
+ break;
+
+ case '[object Boolean]':
+ clone = new ctor(value == true);
+ break;
+
+ case '[object Date]':
+ clone = new ctor(+value);
+ break;
+
+ case '[object Object]':
+ isPlainObject(value) && (clone = {});
+ break;
+
+ case '[object Number]':
+ case '[object String]':
+ clone = new ctor(value);
+ break;
+
+ case '[object RegExp]':
+ clone = ctor(value.source,
+ (value.global ? 'g' : '') +
+ (value.ignoreCase ? 'i' : '') +
+ (value.multiline ? 'm' : ''));
+ }
+ }
+ // continue clone if `value` doesn't have an accessor descriptor
+ // http://es5.github.com/#x8.10.1
+ if (clone && clone != value &&
+ !(descriptor = source && support.descriptors && getDescriptor(source, key),
+ accessor = descriptor && (descriptor.get || descriptor.set))) {
+ // use an existing clone (circular reference)
+ if ((extensible = isExtensible(value))) {
+ markerKey = getMarkerKey(value);
+ if (value[markerKey]) {
+ circular = clone = value[markerKey].raw;
+ }
+ } else {
+ // for frozen/sealed objects
+ for (subIndex = 0, length = unmarked.length; subIndex < length; subIndex++) {
+ data = unmarked[subIndex];
+ if (data.object === value) {
+ circular = clone = data.clone;
+ break;
+ }
+ }
+ }
+ if (!circular) {
+ // mark object to allow quickly detecting circular references and tie it to its clone
+ if (extensible) {
+ value[markerKey] = new Marker(clone);
+ marked.push({ 'key': markerKey, 'object': value });
+ } else {
+ // for frozen/sealed objects
+ unmarked.push({ 'clone': clone, 'object': value });
+ }
+ // iterate over object properties
+ forProps(value, forPropsCallback, { 'which': 'all' });
+ }
+ }
+ }
+ if (parent) {
+ // for custom property descriptors
+ if (accessor || (descriptor && !(descriptor.configurable && descriptor.enumerable && descriptor.writable))) {
+ if ('value' in descriptor) {
+ descriptor.value = clone;
+ }
+ setDescriptor(parent, key, descriptor);
+ }
+ // for default property descriptors
+ else {
+ parent[key] = clone;
+ }
+ } else {
+ result = clone;
+ }
+ } while ((data = queue[index++]));
+
+ // remove markers
+ for (index = 0, length = marked.length; index < length; index++) {
+ data = marked[index];
+ delete data.object[data.key];
+ }
+ return result;
+ }
+
+ /**
+ * An iteration utility for arrays and objects.
+ * Callbacks may terminate the loop by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array|Object} object The object to iterate over.
+ * @param {Function} callback The function called per iteration.
+ * @param {Mixed} thisArg The `this` binding for the callback.
+ * @returns {Array|Object} Returns the object iterated over.
+ */
+ function each(object, callback, thisArg) {
+ var result = object;
+ object = Object(object);
+
+ var fn = callback,
+ index = -1,
+ length = object.length,
+ isSnapshot = !!(object.snapshotItem && (length = object.snapshotLength)),
+ isSplittable = (noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String'),
+ isConvertable = isSnapshot || isSplittable || 'item' in object,
+ origObject = object;
+
+ // in Opera < 10.5 `hasKey(object, 'length')` returns `false` for NodeLists
+ if (length === length >>> 0) {
+ if (isConvertable) {
+ // the third argument of the callback is the original non-array object
+ callback = function(value, index) {
+ return fn.call(this, value, index, origObject);
+ };
+ // in IE < 9 strings don't support accessing characters by index
+ if (isSplittable) {
+ object = object.split('');
+ } else {
+ object = [];
+ while (++index < length) {
+ // in Safari 2 `index in object` is always `false` for NodeLists
+ object[index] = isSnapshot ? result.snapshotItem(index) : result[index];
+ }
+ }
+ }
+ forEach(object, callback, thisArg);
+ } else {
+ forOwn(object, callback, thisArg);
+ }
+ return result;
+ }
+
+ /**
+ * Copies enumerable properties from the source(s) object to the destination object.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Object} destination The destination object.
+ * @param {Object} [source={}] The source object.
+ * @returns {Object} The destination object.
+ */
+ function extend(destination, source) {
+ // Chrome < 14 incorrectly sets `destination` to `undefined` when we `delete arguments[0]`
+ // http://code.google.com/p/v8/issues/detail?id=839
+ var result = destination;
+ delete arguments[0];
+
+ forEach(arguments, function(source) {
+ forProps(source, function(value, key) {
+ result[key] = value;
+ });
+ });
+ return result;
+ }
+
+ /**
+ * A generic `Array#filter` like method.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} array The array to iterate over.
+ * @param {Function|String} callback The function/alias called per iteration.
+ * @param {Mixed} thisArg The `this` binding for the callback.
+ * @returns {Array} A new array of values that passed callback filter.
+ * @example
+ *
+ * // get odd numbers
+ * Benchmark.filter([1, 2, 3, 4, 5], function(n) {
+ * return n % 2;
+ * }); // -> [1, 3, 5];
+ *
+ * // get fastest benchmarks
+ * Benchmark.filter(benches, 'fastest');
+ *
+ * // get slowest benchmarks
+ * Benchmark.filter(benches, 'slowest');
+ *
+ * // get benchmarks that completed without erroring
+ * Benchmark.filter(benches, 'successful');
+ */
+ function filter(array, callback, thisArg) {
+ var result;
+
+ if (callback == 'successful') {
+ // callback to exclude those that are errored, unrun, or have hz of Infinity
+ callback = function(bench) { return bench.cycles && isFinite(bench.hz); };
+ }
+ else if (callback == 'fastest' || callback == 'slowest') {
+ // get successful, sort by period + margin of error, and filter fastest/slowest
+ result = filter(array, 'successful').sort(function(a, b) {
+ a = a.stats; b = b.stats;
+ return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback == 'fastest' ? 1 : -1);
+ });
+ result = filter(result, function(bench) {
+ return result[0].compare(bench) == 0;
+ });
+ }
+ return result || reduce(array, function(result, value, index) {
+ return callback.call(thisArg, value, index, array) ? (result.push(value), result) : result;
+ }, []);
+ }
+
+ /**
+ * A generic `Array#forEach` like method.
+ * Callbacks may terminate the loop by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} array The array to iterate over.
+ * @param {Function} callback The function called per iteration.
+ * @param {Mixed} thisArg The `this` binding for the callback.
+ * @returns {Array} Returns the array iterated over.
+ */
+ function forEach(array, callback, thisArg) {
+ var index = -1,
+ length = (array = Object(array)).length >>> 0;
+
+ if (thisArg !== undefined) {
+ callback = bind(callback, thisArg);
+ }
+ while (++index < length) {
+ if (index in array &&
+ callback(array[index], index, array) === false) {
+ break;
+ }
+ }
+ return array;
+ }
+
+ /**
+ * Iterates over an object's own properties, executing the `callback` for each.
+ * Callbacks may terminate the loop by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Object} object The object to iterate over.
+ * @param {Function} callback The function executed per own property.
+ * @param {Mixed} thisArg The `this` binding for the callback.
+ * @returns {Object} Returns the object iterated over.
+ */
+ function forOwn(object, callback, thisArg) {
+ return forProps(object, callback, { 'bind': thisArg, 'which': 'own' });
+ }
+
+ /**
+ * Converts a number to a more readable comma-separated string representation.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Number} number The number to convert.
+ * @returns {String} The more readable string representation.
+ */
+ function formatNumber(number) {
+ number = String(number).split('.');
+ return number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') +
+ (number[1] ? '.' + number[1] : '');
+ }
+
+ /**
+ * Checks if an object has the specified key as a direct property.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Object} object The object to check.
+ * @param {String} key The key to check for.
+ * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
+ */
+ function hasKey() {
+ // lazy define for worst case fallback (not as accurate)
+ hasKey = function(object, key) {
+ var parent = object != null && (object.constructor || Object).prototype;
+ return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);
+ };
+ // for modern browsers
+ if (isClassOf(hasOwnProperty, 'Function')) {
+ hasKey = function(object, key) {
+ return object != null && hasOwnProperty.call(object, key);
+ };
+ }
+ // for Safari 2
+ else if ({}.__proto__ == Object.prototype) {
+ hasKey = function(object, key) {
+ var result = false;
+ if (object != null) {
+ object = Object(object);
+ object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
+ }
+ return result;
+ };
+ }
+ return hasKey.apply(this, arguments);
+ }
+
+ /**
+ * A generic `Array#indexOf` like method.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} array The array to iterate over.
+ * @param {Mixed} value The value to search for.
+ * @param {Number} [fromIndex=0] The index to start searching from.
+ * @returns {Number} The index of the matched value or `-1`.
+ */
+ function indexOf(array, value, fromIndex) {
+ var index = toInteger(fromIndex),
+ length = (array = Object(array)).length >>> 0;
+
+ index = (index < 0 ? max(0, length + index) : index) - 1;
+ while (++index < length) {
+ if (index in array && value === array[index]) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Modify a string by replacing named tokens with matching object property values.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {String} string The string to modify.
+ * @param {Object} object The template object.
+ * @returns {String} The modified string.
+ */
+ function interpolate(string, object) {
+ forOwn(object, function(value, key) {
+ // escape regexp special characters in `key`
+ string = string.replace(RegExp('#\\{' + key.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + '\\}', 'g'), value);
+ });
+ return string;
+ }
+
+ /**
+ * Invokes a method on all items in an array.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} benches Array of benchmarks to iterate over.
+ * @param {String|Object} name The name of the method to invoke OR options object.
+ * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
+ * @returns {Array} A new array of values returned from each method invoked.
+ * @example
+ *
+ * // invoke `reset` on all benchmarks
+ * Benchmark.invoke(benches, 'reset');
+ *
+ * // invoke `emit` with arguments
+ * Benchmark.invoke(benches, 'emit', 'complete', listener);
+ *
+ * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks
+ * Benchmark.invoke(benches, {
+ *
+ * // invoke the `run` method
+ * 'name': 'run',
+ *
+ * // pass a single argument
+ * 'args': true,
+ *
+ * // treat as queue, removing benchmarks from front of `benches` until empty
+ * 'queued': true,
+ *
+ * // called before any benchmarks have been invoked.
+ * 'onStart': onStart,
+ *
+ * // called between invoking benchmarks
+ * 'onCycle': onCycle,
+ *
+ * // called after all benchmarks have been invoked.
+ * 'onComplete': onComplete
+ * });
+ */
+ function invoke(benches, name) {
+ var args,
+ bench,
+ queued,
+ index = -1,
+ eventProps = { 'currentTarget': benches },
+ options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop },
+ result = map(benches, function(bench) { return bench; });
+
+ /**
+ * Invokes the method of the current object and if synchronous, fetches the next.
+ */
+ function execute() {
+ var listeners,
+ async = isAsync(bench);
+
+ if (async) {
+ // use `getNext` as the first listener
+ bench.on('complete', getNext);
+ listeners = bench.events.complete;
+ listeners.splice(0, 0, listeners.pop());
+ }
+ // execute method
+ result[index] = isClassOf(bench && bench[name], 'Function') ? bench[name].apply(bench, args) : undefined;
+ // if synchronous return true until finished
+ return !async && getNext();
+ }
+
+ /**
+ * Fetches the next bench or executes `onComplete` callback.
+ */
+ function getNext(event) {
+ var cycleEvent,
+ last = bench,
+ async = isAsync(last);
+
+ if (async) {
+ last.off('complete', getNext);
+ last.emit('complete');
+ }
+ // emit "cycle" event
+ eventProps.type = 'cycle';
+ eventProps.target = last;
+ cycleEvent = Event(eventProps);
+ options.onCycle.call(benches, cycleEvent);
+
+ // choose next benchmark if not exiting early
+ if (!cycleEvent.aborted && raiseIndex() !== false) {
+ bench = queued ? benches[0] : result[index];
+ if (isAsync(bench)) {
+ delay(bench, execute);
+ }
+ else if (async) {
+ // resume execution if previously asynchronous but now synchronous
+ while (execute()) { }
+ }
+ else {
+ // continue synchronous execution
+ return true;
+ }
+ } else {
+ // emit "complete" event
+ eventProps.type = 'complete';
+ options.onComplete.call(benches, Event(eventProps));
+ }
+ // When used as a listener `event.aborted = true` will cancel the rest of
+ // the "complete" listeners because they were already called above and when
+ // used as part of `getNext` the `return false` will exit the execution while-loop.
+ if (event) {
+ event.aborted = true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if invoking `Benchmark#run` with asynchronous cycles.
+ */
+ function isAsync(object) {
+ // avoid using `instanceof` here because of IE memory leak issues with host objects
+ var async = args[0] && args[0].async;
+ return Object(object).constructor == Benchmark && name == 'run' &&
+ ((async == null ? object.options.async : async) && support.timeout || object.defer);
+ }
+
+ /**
+ * Raises `index` to the next defined index or returns `false`.
+ */
+ function raiseIndex() {
+ var length = result.length;
+ if (queued) {
+ // if queued remove the previous bench and subsequent skipped non-entries
+ do {
+ ++index > 0 && shift.call(benches);
+ } while ((length = benches.length) && !('0' in benches));
+ }
+ else {
+ while (++index < length && !(index in result)) { }
+ }
+ // if we reached the last index then return `false`
+ return (queued ? length : index < length) ? index : (index = false);
+ }
+
+ // juggle arguments
+ if (isClassOf(name, 'String')) {
+ // 2 arguments (array, name)
+ args = slice.call(arguments, 2);
+ } else {
+ // 2 arguments (array, options)
+ options = extend(options, name);
+ name = options.name;
+ args = isClassOf(args = 'args' in options ? options.args : [], 'Array') ? args : [args];
+ queued = options.queued;
+ }
+
+ // start iterating over the array
+ if (raiseIndex() !== false) {
+ // emit "start" event
+ bench = result[index];
+ eventProps.type = 'start';
+ eventProps.target = bench;
+ options.onStart.call(benches, Event(eventProps));
+
+ // end early if the suite was aborted in an "onStart" listener
+ if (benches.aborted && benches.constructor == Suite && name == 'run') {
+ // emit "cycle" event
+ eventProps.type = 'cycle';
+ options.onCycle.call(benches, Event(eventProps));
+ // emit "complete" event
+ eventProps.type = 'complete';
+ options.onComplete.call(benches, Event(eventProps));
+ }
+ // else start
+ else {
+ if (isAsync(bench)) {
+ delay(bench, execute);
+ } else {
+ while (execute()) { }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates a string of joined array values or object key-value pairs.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array|Object} object The object to operate on.
+ * @param {String} [separator1=','] The separator used between key-value pairs.
+ * @param {String} [separator2=': '] The separator used between keys and values.
+ * @returns {String} The joined result.
+ */
+ function join(object, separator1, separator2) {
+ var result = [],
+ length = (object = Object(object)).length,
+ arrayLike = length === length >>> 0;
+
+ separator2 || (separator2 = ': ');
+ each(object, function(value, key) {
+ result.push(arrayLike ? value : key + separator2 + value);
+ });
+ return result.join(separator1 || ',');
+ }
+
+ /**
+ * A generic `Array#map` like method.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} array The array to iterate over.
+ * @param {Function} callback The function called per iteration.
+ * @param {Mixed} thisArg The `this` binding for the callback.
+ * @returns {Array} A new array of values returned by the callback.
+ */
+ function map(array, callback, thisArg) {
+ return reduce(array, function(result, value, index) {
+ result[index] = callback.call(thisArg, value, index, array);
+ return result;
+ }, Array(Object(array).length >>> 0));
+ }
+
+ /**
+ * Retrieves the value of a specified property from all items in an array.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} array The array to iterate over.
+ * @param {String} property The property to pluck.
+ * @returns {Array} A new array of property values.
+ */
+ function pluck(array, property) {
+ return map(array, function(object) {
+ return object == null ? undefined : object[property];
+ });
+ }
+
+ /**
+ * A generic `Array#reduce` like method.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @param {Array} array The array to iterate over.
+ * @param {Function} callback The function called per iteration.
+ * @param {Mixed} accumulator Initial value of the accumulator.
+ * @returns {Mixed} The accumulator.
+ */
+ function reduce(array, callback, accumulator) {
+ var noaccum = arguments.length < 3;
+ forEach(array, function(value, index) {
+ accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, array);
+ });
+ return accumulator;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Aborts all benchmarks in the suite.
+ *
+ * @name abort
+ * @memberOf Benchmark.Suite
+ * @returns {Object} The suite instance.
+ */
+ function abortSuite() {
+ var event,
+ me = this,
+ resetting = calledBy.resetSuite;
+
+ if (me.running) {
+ event = Event('abort');
+ me.emit(event);
+ if (!event.cancelled || resetting) {
+ // avoid infinite recursion
+ calledBy.abortSuite = true;
+ me.reset();
+ delete calledBy.abortSuite;
+
+ if (!resetting) {
+ me.aborted = true;
+ invoke(me, 'abort');
+ }
+ }
+ }
+ return me;
+ }
+
+ /**
+ * Adds a test to the benchmark suite.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {String} name A name to identify the benchmark.
+ * @param {Function|String} fn The test to benchmark.
+ * @param {Object} [options={}] Options object.
+ * @returns {Object} The benchmark instance.
+ * @example
+ *
+ * // basic usage
+ * suite.add(fn);
+ *
+ * // or using a name first
+ * suite.add('foo', fn);
+ *
+ * // or with options
+ * suite.add('foo', fn, {
+ * 'onCycle': onCycle,
+ * 'onComplete': onComplete
+ * });
+ *
+ * // or name and options
+ * suite.add('foo', {
+ * 'fn': fn,
+ * 'onCycle': onCycle,
+ * 'onComplete': onComplete
+ * });
+ *
+ * // or options only
+ * suite.add({
+ * 'name': 'foo',
+ * 'fn': fn,
+ * 'onCycle': onCycle,
+ * 'onComplete': onComplete
+ * });
+ */
+ function add(name, fn, options) {
+ var me = this,
+ bench = Benchmark(name, fn, options),
+ event = Event({ 'type': 'add', 'target': bench });
+
+ if (me.emit(event), !event.cancelled) {
+ me.push(bench);
+ }
+ return me;
+ }
+
+ /**
+ * Creates a new suite with cloned benchmarks.
+ *
+ * @name clone
+ * @memberOf Benchmark.Suite
+ * @param {Object} options Options object to overwrite cloned options.
+ * @returns {Object} The new suite instance.
+ */
+ function cloneSuite(options) {
+ var me = this,
+ result = new me.constructor(extend({}, me.options, options));
+
+ // copy own properties
+ forOwn(me, function(value, key) {
+ if (!hasKey(result, key)) {
+ result[key] = value && isClassOf(value.clone, 'Function')
+ ? value.clone()
+ : deepClone(value);
+ }
+ });
+ return result;
+ }
+
+ /**
+ * An `Array#filter` like method.
+ *
+ * @name filter
+ * @memberOf Benchmark.Suite
+ * @param {Function|String} callback The function/alias called per iteration.
+ * @returns {Object} A new suite of benchmarks that passed callback filter.
+ */
+ function filterSuite(callback) {
+ var me = this,
+ result = new me.constructor;
+
+ result.push.apply(result, filter(me, callback));
+ return result;
+ }
+
+ /**
+ * Resets all benchmarks in the suite.
+ *
+ * @name reset
+ * @memberOf Benchmark.Suite
+ * @returns {Object} The suite instance.
+ */
+ function resetSuite() {
+ var event,
+ me = this,
+ aborting = calledBy.abortSuite;
+
+ if (me.running && !aborting) {
+ // no worries, `resetSuite()` is called within `abortSuite()`
+ calledBy.resetSuite = true;
+ me.abort();
+ delete calledBy.resetSuite;
+ }
+ // reset if the state has changed
+ else if ((me.aborted || me.running) &&
+ (me.emit(event = Event('reset')), !event.cancelled)) {
+ me.running = false;
+ if (!aborting) {
+ invoke(me, 'reset');
+ }
+ }
+ return me;
+ }
+
+ /**
+ * Runs the suite.
+ *
+ * @name run
+ * @memberOf Benchmark.Suite
+ * @param {Object} [options={}] Options object.
+ * @returns {Object} The suite instance.
+ * @example
+ *
+ * // basic usage
+ * suite.run();
+ *
+ * // or with options
+ * suite.run({ 'async': true, 'queued': true });
+ */
+ function runSuite(options) {
+ var me = this;
+
+ me.reset();
+ me.running = true;
+ options || (options = {});
+
+ invoke(me, {
+ 'name': 'run',
+ 'args': options,
+ 'queued': options.queued,
+ 'onStart': function(event) {
+ me.emit(event);
+ },
+ 'onCycle': function(event) {
+ var bench = event.target;
+ if (bench.error) {
+ me.emit({ 'type': 'error', 'target': bench });
+ }
+ me.emit(event);
+ event.aborted = me.aborted;
+ },
+ 'onComplete': function(event) {
+ me.running = false;
+ me.emit(event);
+ }
+ });
+ return me;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Executes all registered listeners of the specified event type.
+ *
+ * @memberOf Benchmark, Benchmark.Suite
+ * @param {String|Object} type The event type or object.
+ * @returns {Mixed} Returns the return value of the last listener executed.
+ */
+ function emit(type) {
+ var listeners,
+ me = this,
+ event = Event(type),
+ events = me.events,
+ args = (arguments[0] = event, arguments);
+
+ event.currentTarget || (event.currentTarget = me);
+ event.target || (event.target = me);
+ delete event.result;
+
+ if (events && (listeners = hasKey(events, event.type) && events[event.type])) {
+ forEach(listeners.slice(), function(listener) {
+ if ((event.result = listener.apply(me, args)) === false) {
+ event.cancelled = true;
+ }
+ return !event.aborted;
+ });
+ }
+ return event.result;
+ }
+
+ /**
+ * Returns an array of event listeners for a given type that can be manipulated
+ * to add or remove listeners.
+ *
+ * @memberOf Benchmark, Benchmark.Suite
+ * @param {String} type The event type.
+ * @returns {Array} The listeners array.
+ */
+ function listeners(type) {
+ var me = this,
+ events = me.events || (me.events = {});
+
+ return hasKey(events, type) ? events[type] : (events[type] = []);
+ }
+
+ /**
+ * Unregisters a listener for the specified event type(s),
+ * or unregisters all listeners for the specified event type(s),
+ * or unregisters all listeners for all event types.
+ *
+ * @memberOf Benchmark, Benchmark.Suite
+ * @param {String} [type] The event type.
+ * @param {Function} [listener] The function to unregister.
+ * @returns {Object} The benchmark instance.
+ * @example
+ *
+ * // unregister a listener for an event type
+ * bench.off('cycle', listener);
+ *
+ * // unregister a listener for multiple event types
+ * bench.off('start cycle', listener);
+ *
+ * // unregister all listeners for an event type
+ * bench.off('cycle');
+ *
+ * // unregister all listeners for multiple event types
+ * bench.off('start cycle complete');
+ *
+ * // unregister all listeners for all event types
+ * bench.off();
+ */
+ function off(type, listener) {
+ var me = this,
+ events = me.events;
+
+ events && each(type ? type.split(' ') : events, function(listeners, type) {
+ var index;
+ if (typeof listeners == 'string') {
+ type = listeners;
+ listeners = hasKey(events, type) && events[type];
+ }
+ if (listeners) {
+ if (listener) {
+ index = indexOf(listeners, listener);
+ if (index > -1) {
+ listeners.splice(index, 1);
+ }
+ } else {
+ listeners.length = 0;
+ }
+ }
+ });
+ return me;
+ }
+
+ /**
+ * Registers a listener for the specified event type(s).
+ *
+ * @memberOf Benchmark, Benchmark.Suite
+ * @param {String} type The event type.
+ * @param {Function} listener The function to register.
+ * @returns {Object} The benchmark instance.
+ * @example
+ *
+ * // register a listener for an event type
+ * bench.on('cycle', listener);
+ *
+ * // register a listener for multiple event types
+ * bench.on('start cycle', listener);
+ */
+ function on(type, listener) {
+ var me = this,
+ events = me.events || (me.events = {});
+
+ forEach(type.split(' '), function(type) {
+ (hasKey(events, type)
+ ? events[type]
+ : (events[type] = [])
+ ).push(listener);
+ });
+ return me;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Aborts the benchmark without recording times.
+ *
+ * @memberOf Benchmark
+ * @returns {Object} The benchmark instance.
+ */
+ function abort() {
+ var event,
+ me = this,
+ resetting = calledBy.reset;
+
+ if (me.running) {
+ event = Event('abort');
+ me.emit(event);
+ if (!event.cancelled || resetting) {
+ // avoid infinite recursion
+ calledBy.abort = true;
+ me.reset();
+ delete calledBy.abort;
+
+ if (support.timeout) {
+ clearTimeout(me._timerId);
+ delete me._timerId;
+ }
+ if (!resetting) {
+ me.aborted = true;
+ me.running = false;
+ }
+ }
+ }
+ return me;
+ }
+
+ /**
+ * Creates a new benchmark using the same test and options.
+ *
+ * @memberOf Benchmark
+ * @param {Object} options Options object to overwrite cloned options.
+ * @returns {Object} The new benchmark instance.
+ * @example
+ *
+ * var bizarro = bench.clone({
+ * 'name': 'doppelganger'
+ * });
+ */
+ function clone(options) {
+ var me = this,
+ result = new me.constructor(extend({}, me, options));
+
+ // correct the `options` object
+ result.options = extend({}, me.options, options);
+
+ // copy own custom properties
+ forOwn(me, function(value, key) {
+ if (!hasKey(result, key)) {
+ result[key] = deepClone(value);
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Determines if a benchmark is faster than another.
+ *
+ * @memberOf Benchmark
+ * @param {Object} other The benchmark to compare.
+ * @returns {Number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate.
+ */
+ function compare(other) {
+ var critical,
+ zStat,
+ me = this,
+ sample1 = me.stats.sample,
+ sample2 = other.stats.sample,
+ size1 = sample1.length,
+ size2 = sample2.length,
+ maxSize = max(size1, size2),
+ minSize = min(size1, size2),
+ u1 = getU(sample1, sample2),
+ u2 = getU(sample2, sample1),
+ u = min(u1, u2);
+
+ function getScore(xA, sampleB) {
+ return reduce(sampleB, function(total, xB) {
+ return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5);
+ }, 0);
+ }
+
+ function getU(sampleA, sampleB) {
+ return reduce(sampleA, function(total, xA) {
+ return total + getScore(xA, sampleB);
+ }, 0);
+ }
+
+ function getZ(u) {
+ return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12);
+ }
+
+ // exit early if comparing the same benchmark
+ if (me == other) {
+ return 0;
+ }
+ // reject the null hyphothesis the two samples come from the
+ // same population (i.e. have the same median) if...
+ if (size1 + size2 > 30) {
+ // ...the z-stat is greater than 1.96 or less than -1.96
+ // http://www.statisticslectures.com/topics/mannwhitneyu/
+ zStat = getZ(u);
+ return abs(zStat) > 1.96 ? (zStat > 0 ? -1 : 1) : 0;
+ }
+ // ...the U value is less than or equal the critical U value
+ // http://www.geoib.com/mann-whitney-u-test.html
+ critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3];
+ return u <= critical ? (u == u1 ? 1 : -1) : 0;
+ }
+
+ /**
+ * Reset properties and abort if running.
+ *
+ * @memberOf Benchmark
+ * @returns {Object} The benchmark instance.
+ */
+ function reset() {
+ var data,
+ event,
+ me = this,
+ index = 0,
+ changes = { 'length': 0 },
+ queue = { 'length': 0 };
+
+ if (me.running && !calledBy.abort) {
+ // no worries, `reset()` is called within `abort()`
+ calledBy.reset = true;
+ me.abort();
+ delete calledBy.reset;
+ }
+ else {
+ // a non-recursive solution to check if properties have changed
+ // http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4
+ data = { 'destination': me, 'source': extend({}, me.constructor.prototype, me.options) };
+ do {
+ forOwn(data.source, function(value, key) {
+ var changed,
+ destination = data.destination,
+ currValue = destination[key];
+
+ if (value && typeof value == 'object') {
+ if (isClassOf(value, 'Array')) {
+ // check if an array value has changed to a non-array value
+ if (!isClassOf(currValue, 'Array')) {
+ changed = currValue = [];
+ }
+ // or has changed its length
+ if (currValue.length != value.length) {
+ changed = currValue = currValue.slice(0, value.length);
+ currValue.length = value.length;
+ }
+ }
+ // check if an object has changed to a non-object value
+ else if (!currValue || typeof currValue != 'object') {
+ changed = currValue = {};
+ }
+ // register a changed object
+ if (changed) {
+ changes[changes.length++] = { 'destination': destination, 'key': key, 'value': currValue };
+ }
+ queue[queue.length++] = { 'destination': currValue, 'source': value };
+ }
+ // register a changed primitive
+ else if (value !== currValue && !(value == null || isClassOf(value, 'Function'))) {
+ changes[changes.length++] = { 'destination': destination, 'key': key, 'value': value };
+ }
+ });
+ }
+ while ((data = queue[index++]));
+
+ // if changed emit the `reset` event and if it isn't cancelled reset the benchmark
+ if (changes.length && (me.emit(event = Event('reset')), !event.cancelled)) {
+ forEach(changes, function(data) {
+ data.destination[data.key] = data.value;
+ });
+ }
+ }
+ return me;
+ }
+
+ /**
+ * Displays relevant benchmark information when coerced to a string.
+ *
+ * @name toString
+ * @memberOf Benchmark
+ * @returns {String} A string representation of the benchmark instance.
+ */
+ function toStringBench() {
+ var me = this,
+ error = me.error,
+ hz = me.hz,
+ id = me.id,
+ stats = me.stats,
+ size = stats.sample.length,
+ pm = support.java ? '+/-' : '\xb1',
+ result = me.name || (isNaN(id) ? id : '<Test #' + id + '>');
+
+ if (error) {
+ result += ': ' + join(error);
+ } else {
+ result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm +
+ stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)';
+ }
+ return result;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Clocks the time taken to execute a test per cycle (secs).
+ *
+ * @private
+ * @param {Object} bench The benchmark instance.
+ * @returns {Number} The time taken.
+ */
+ function clock() {
+ var applet,
+ options = Benchmark.options,
+ template = { 'begin': 's$=new n$', 'end': 'r$=(new n$-s$)/1e3', 'uid': uid },
+ timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }];
+
+ // lazy define for hi-res timers
+ clock = function(clone) {
+ var deferred;
+ if (clone instanceof Deferred) {
+ deferred = clone;
+ clone = deferred.benchmark;
+ }
+
+ var bench = clone._original,
+ fn = bench.fn,
+ fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '',
+ stringable = isStringable(fn);
+
+ var source = {
+ 'setup': getSource(bench.setup, preprocess('m$.setup()')),
+ 'fn': getSource(fn, preprocess('m$.fn(' + fnArg + ')')),
+ 'fnArg': fnArg,
+ 'teardown': getSource(bench.teardown, preprocess('m$.teardown()'))
+ };
+
+ var count = bench.count = clone.count,
+ decompilable = support.decompilation || stringable,
+ id = bench.id,
+ isEmpty = !(source.fn || stringable),
+ name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id),
+ ns = timer.ns,
+ result = 0;
+
+ // init `minTime` if needed
+ clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime);
+
+ // repair nanosecond timer
+ // (some Chrome builds erase the `ns` variable after millions of executions)
+ if (applet) {
+ try {
+ ns.nanoTime();
+ } catch(e) {
+ // use non-element to avoid issues with libs that augment them
+ ns = timer.ns = new applet.Packages.nano;
+ }
+ }
+
+ // Compile in setup/teardown functions and the test loop.
+ // Create a new compiled test, instead of using the cached `bench.compiled`,
+ // to avoid potential engine optimizations enabled over the life of the test.
+ var compiled = bench.compiled = createFunction(preprocess('t$'), interpolate(
+ preprocess(deferred
+ ? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' +
+ // when `deferred.cycles` is `0` then...
+ 'if(!d$.cycles){' +
+ // set `deferred.fn`
+ 'd$.fn=function(){var #{fnArg}=d$;if(typeof f$=="function"){try{#{fn}\n}catch(e$){f$(d$)}}else{#{fn}\n}};' +
+ // set `deferred.teardown`
+ 'd$.teardown=function(){d$.cycles=0;if(typeof td$=="function"){try{#{teardown}\n}catch(e$){td$()}}else{#{teardown}\n}};' +
+ // execute the benchmark's `setup`
+ 'if(typeof su$=="function"){try{#{setup}\n}catch(e$){su$()}}else{#{setup}\n};' +
+ // start timer
+ 't$.start(d$);' +
+ // execute `deferred.fn` and return a dummy object
+ '}d$.fn();return{}'
+
+ : 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\n#{begin};' +
+ 'while(i$--){#{fn}\n}#{end};#{teardown}\nreturn{elapsed:r$,uid:"#{uid}"}'),
+ source
+ ));
+
+ try {
+ if (isEmpty) {
+ // Firefox may remove dead code from Function#toString results
+ // http://bugzil.la/536085
+ throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.');
+ }
+ else if (!deferred) {
+ // pretest to determine if compiled code is exits early, usually by a
+ // rogue `return` statement, by checking for a return object with the uid
+ bench.count = 1;
+ compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled;
+ bench.count = count;
+ }
+ } catch(e) {
+ compiled = null;
+ clone.error = e || new Error(String(e));
+ bench.count = count;
+ }
+ // fallback when a test exits early or errors during pretest
+ if (decompilable && !compiled && !deferred && !isEmpty) {
+ compiled = createFunction(preprocess('t$'), interpolate(
+ preprocess(
+ (clone.error && !stringable
+ ? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count'
+ : 'function f$(){#{fn}\n}var r$,s$,m$=this,i$=m$.count'
+ ) +
+ ',n$=t$.ns;#{setup}\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' +
+ 'delete m$.f$;#{teardown}\nreturn{elapsed:r$}'
+ ),
+ source
+ ));
+
+ try {
+ // pretest one more time to check for errors
+ bench.count = 1;
+ compiled.call(bench, timer);
+ bench.compiled = compiled;
+ bench.count = count;
+ delete clone.error;
+ }
+ catch(e) {
+ bench.count = count;
+ if (clone.error) {
+ compiled = null;
+ } else {
+ bench.compiled = compiled;
+ clone.error = e || new Error(String(e));
+ }
+ }
+ }
+ // assign `compiled` to `clone` before calling in case a deferred benchmark
+ // immediately calls `deferred.resolve()`
+ clone.compiled = compiled;
+ // if no errors run the full test loop
+ if (!clone.error) {
+ result = compiled.call(deferred || bench, timer).elapsed;
+ }
+ return result;
+ };
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Gets the current timer's minimum resolution (secs).
+ */
+ function getRes(unit) {
+ var measured,
+ begin,
+ count = 30,
+ divisor = 1e3,
+ ns = timer.ns,
+ sample = [];
+
+ // get average smallest measurable time
+ while (count--) {
+ if (unit == 'us') {
+ divisor = 1e6;
+ if (ns.stop) {
+ ns.start();
+ while (!(measured = ns.microseconds())) { }
+ } else if (ns[perfName]) {
+ divisor = 1e3;
+ measured = Function('n', 'var r,s=n.' + perfName + '();while(!(r=n.' + perfName + '()-s)){};return r')(ns);
+ } else {
+ begin = ns();
+ while (!(measured = ns() - begin)) { }
+ }
+ }
+ else if (unit == 'ns') {
+ divisor = 1e9;
+ if (ns.nanoTime) {
+ begin = ns.nanoTime();
+ while (!(measured = ns.nanoTime() - begin)) { }
+ } else {
+ begin = (begin = ns())[0] + (begin[1] / divisor);
+ while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) { }
+ divisor = 1;
+ }
+ }
+ else {
+ begin = new ns;
+ while (!(measured = new ns - begin)) { }
+ }
+ // check for broken timers (nanoTime may have issues)
+ // http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/
+ if (measured > 0) {
+ sample.push(measured);
+ } else {
+ sample.push(Infinity);
+ break;
+ }
+ }
+ // convert to seconds
+ return getMean(sample) / divisor;
+ }
+
+ /**
+ * Replaces all occurrences of `$` with a unique number and
+ * template tokens with content.
+ */
+ function preprocess(code) {
+ return interpolate(code, template).replace(/\$/g, /\d+/.exec(uid));
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ // detect nanosecond support from a Java applet
+ each(doc && doc.applets || [], function(element) {
+ return !(timer.ns = applet = 'nanoTime' in element && element);
+ });
+
+ // check type in case Safari returns an object instead of a number
+ try {
+ if (typeof timer.ns.nanoTime() == 'number') {
+ timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });
+ }
+ } catch(e) { }
+
+ // detect Chrome's microsecond timer:
+ // enable benchmarking via the --enable-benchmarking command
+ // line switch in at least Chrome 7 to use chrome.Interval
+ try {
+ if ((timer.ns = new (window.chrome || window.chromium).Interval)) {
+ timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
+ }
+ } catch(e) { }
+
+ // detect `performance.now` microsecond resolution timer
+ if ((timer.ns = perfName && perfObject)) {
+ timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
+ }
+
+ // detect Node's nanosecond resolution timer available in Node >= 0.8
+ if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') {
+ timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });
+ }
+
+ // detect Wade Simmons' Node microtime module
+ if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') {
+ timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
+ }
+
+ // pick timer with highest resolution
+ timer = reduce(timers, function(timer, other) {
+ return other.res < timer.res ? other : timer;
+ });
+
+ // remove unused applet
+ if (timer.unit != 'ns' && applet) {
+ applet = destroyElement(applet);
+ }
+ // error if there are no working timers
+ if (timer.res == Infinity) {
+ throw new Error('Benchmark.js was unable to find a working timer.');
+ }
+ // use API of chosen timer
+ if (timer.unit == 'ns') {
+ if (timer.ns.nanoTime) {
+ extend(template, {
+ 'begin': 's$=n$.nanoTime()',
+ 'end': 'r$=(n$.nanoTime()-s$)/1e9'
+ });
+ } else {
+ extend(template, {
+ 'begin': 's$=n$()',
+ 'end': 'r$=n$(s$);r$=r$[0]+(r$[1]/1e9)'
+ });
+ }
+ }
+ else if (timer.unit == 'us') {
+ if (timer.ns.stop) {
+ extend(template, {
+ 'begin': 's$=n$.start()',
+ 'end': 'r$=n$.microseconds()/1e6'
+ });
+ } else if (perfName) {
+ extend(template, {
+ 'begin': 's$=n$.' + perfName + '()',
+ 'end': 'r$=(n$.' + perfName + '()-s$)/1e3'
+ });
+ } else {
+ extend(template, {
+ 'begin': 's$=n$()',
+ 'end': 'r$=(n$()-s$)/1e6'
+ });
+ }
+ }
+
+ // define `timer` methods
+ timer.start = createFunction(preprocess('o$'),
+ preprocess('var n$=this.ns,#{begin};o$.elapsed=0;o$.timeStamp=s$'));
+
+ timer.stop = createFunction(preprocess('o$'),
+ preprocess('var n$=this.ns,s$=o$.timeStamp,#{end};o$.elapsed=r$'));
+
+ // resolve time span required to achieve a percent uncertainty of at most 1%
+ // http://spiff.rit.edu/classes/phys273/uncert/uncert.html
+ options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05));
+ return clock.apply(null, arguments);
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Computes stats on benchmark results.
+ *
+ * @private
+ * @param {Object} bench The benchmark instance.
+ * @param {Object} options The options object.
+ */
+ function compute(bench, options) {
+ options || (options = {});
+
+ var async = options.async,
+ elapsed = 0,
+ initCount = bench.initCount,
+ minSamples = bench.minSamples,
+ queue = [],
+ sample = bench.stats.sample;
+
+ /**
+ * Adds a clone to the queue.
+ */
+ function enqueue() {
+ queue.push(bench.clone({
+ '_original': bench,
+ 'events': {
+ 'abort': [update],
+ 'cycle': [update],
+ 'error': [update],
+ 'start': [update]
+ }
+ }));
+ }
+
+ /**
+ * Updates the clone/original benchmarks to keep their data in sync.
+ */
+ function update(event) {
+ var clone = this,
+ type = event.type;
+
+ if (bench.running) {
+ if (type == 'start') {
+ // Note: `clone.minTime` prop is inited in `clock()`
+ clone.count = bench.initCount;
+ }
+ else {
+ if (type == 'error') {
+ bench.error = clone.error;
+ }
+ if (type == 'abort') {
+ bench.abort();
+ bench.emit('cycle');
+ } else {
+ event.currentTarget = event.target = bench;
+ bench.emit(event);
+ }
+ }
+ } else if (bench.aborted) {
+ // clear abort listeners to avoid triggering bench's abort/cycle again
+ clone.events.abort.length = 0;
+ clone.abort();
+ }
+ }
+
+ /**
+ * Determines if more clones should be queued or if cycling should stop.
+ */
+ function evaluate(event) {
+ var critical,
+ df,
+ mean,
+ moe,
+ rme,
+ sd,
+ sem,
+ variance,
+ clone = event.target,
+ done = bench.aborted,
+ now = +new Date,
+ size = sample.push(clone.times.period),
+ maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime,
+ times = bench.times,
+ varOf = function(sum, x) { return sum + pow(x - mean, 2); };
+
+ // exit early for aborted or unclockable tests
+ if (done || clone.hz == Infinity) {
+ maxedOut = !(size = sample.length = queue.length = 0);
+ }
+
+ if (!done) {
+ // sample mean (estimate of the population mean)
+ mean = getMean(sample);
+ // sample variance (estimate of the population variance)
+ variance = reduce(sample, varOf, 0) / (size - 1) || 0;
+ // sample standard deviation (estimate of the population standard deviation)
+ sd = sqrt(variance);
+ // standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean)
+ sem = sd / sqrt(size);
+ // degrees of freedom
+ df = size - 1;
+ // critical value
+ critical = tTable[Math.round(df) || 1] || tTable.infinity;
+ // margin of error
+ moe = sem * critical;
+ // relative margin of error
+ rme = (moe / mean) * 100 || 0;
+
+ extend(bench.stats, {
+ 'deviation': sd,
+ 'mean': mean,
+ 'moe': moe,
+ 'rme': rme,
+ 'sem': sem,
+ 'variance': variance
+ });
+
+ // Abort the cycle loop when the minimum sample size has been collected
+ // and the elapsed time exceeds the maximum time allowed per benchmark.
+ // We don't count cycle delays toward the max time because delays may be
+ // increased by browsers that clamp timeouts for inactive tabs.
+ // https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs
+ if (maxedOut) {
+ // reset the `initCount` in case the benchmark is rerun
+ bench.initCount = initCount;
+ bench.running = false;
+ done = true;
+ times.elapsed = (now - times.timeStamp) / 1e3;
+ }
+ if (bench.hz != Infinity) {
+ bench.hz = 1 / mean;
+ times.cycle = mean * bench.count;
+ times.period = mean;
+ }
+ }
+ // if time permits, increase sample size to reduce the margin of error
+ if (queue.length < 2 && !maxedOut) {
+ enqueue();
+ }
+ // abort the invoke cycle when done
+ event.aborted = done;
+ }
+
+ // init queue and begin
+ enqueue();
+ invoke(queue, {
+ 'name': 'run',
+ 'args': { 'async': async },
+ 'queued': true,
+ 'onCycle': evaluate,
+ 'onComplete': function() { bench.emit('complete'); }
+ });
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Cycles a benchmark until a run `count` can be established.
+ *
+ * @private
+ * @param {Object} clone The cloned benchmark instance.
+ * @param {Object} options The options object.
+ */
+ function cycle(clone, options) {
+ options || (options = {});
+
+ var deferred;
+ if (clone instanceof Deferred) {
+ deferred = clone;
+ clone = clone.benchmark;
+ }
+
+ var clocked,
+ cycles,
+ divisor,
+ event,
+ minTime,
+ period,
+ async = options.async,
+ bench = clone._original,
+ count = clone.count,
+ times = clone.times;
+
+ // continue, if not aborted between cycles
+ if (clone.running) {
+ // `minTime` is set to `Benchmark.options.minTime` in `clock()`
+ cycles = ++clone.cycles;
+ clocked = deferred ? deferred.elapsed : clock(clone);
+ minTime = clone.minTime;
+
+ if (cycles > bench.cycles) {
+ bench.cycles = cycles;
+ }
+ if (clone.error) {
+ event = Event('error');
+ event.message = clone.error;
+ clone.emit(event);
+ if (!event.cancelled) {
+ clone.abort();
+ }
+ }
+ }
+
+ // continue, if not errored
+ if (clone.running) {
+ // time taken to complete last test cycle
+ bench.times.cycle = times.cycle = clocked;
+ // seconds per operation
+ period = bench.times.period = times.period = clocked / count;
+ // ops per second
+ bench.hz = clone.hz = 1 / period;
+ // avoid working our way up to this next time
+ bench.initCount = clone.initCount = count;
+ // do we need to do another cycle?
+ clone.running = clocked < minTime;
+
+ if (clone.running) {
+ // tests may clock at `0` when `initCount` is a small number,
+ // to avoid that we set its count to something a bit higher
+ if (!clocked && (divisor = divisors[clone.cycles]) != null) {
+ count = floor(4e6 / divisor);
+ }
+ // calculate how many more iterations it will take to achive the `minTime`
+ if (count <= clone.count) {
+ count += Math.ceil((minTime - clocked) / period);
+ }
+ clone.running = count != Infinity;
+ }
+ }
+ // should we exit early?
+ event = Event('cycle');
+ clone.emit(event);
+ if (event.aborted) {
+ clone.abort();
+ }
+ // figure out what to do next
+ if (clone.running) {
+ // start a new cycle
+ clone.count = count;
+ if (deferred) {
+ clone.compiled.call(deferred, timer);
+ } else if (async) {
+ delay(clone, function() { cycle(clone, options); });
+ } else {
+ cycle(clone);
+ }
+ }
+ else {
+ // fix TraceMonkey bug associated with clock fallbacks
+ // http://bugzil.la/509069
+ if (support.browser) {
+ runScript(uid + '=1;delete ' + uid);
+ }
+ // done
+ clone.emit('complete');
+ }
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Runs the benchmark.
+ *
+ * @memberOf Benchmark
+ * @param {Object} [options={}] Options object.
+ * @returns {Object} The benchmark instance.
+ * @example
+ *
+ * // basic usage
+ * bench.run();
+ *
+ * // or with options
+ * bench.run({ 'async': true });
+ */
+ function run(options) {
+ var me = this,
+ event = Event('start');
+
+ // set `running` to `false` so `reset()` won't call `abort()`
+ me.running = false;
+ me.reset();
+ me.running = true;
+
+ me.count = me.initCount;
+ me.times.timeStamp = +new Date;
+ me.emit(event);
+
+ if (!event.cancelled) {
+ options = { 'async': ((options = options && options.async) == null ? me.async : options) && support.timeout };
+
+ // for clones created within `compute()`
+ if (me._original) {
+ if (me.defer) {
+ Deferred(me);
+ } else {
+ cycle(me, options);
+ }
+ }
+ // for original benchmarks
+ else {
+ compute(me, options);
+ }
+ }
+ return me;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ // Firefox 1 erroneously defines variable and argument names of functions on
+ // the function itself as non-configurable properties with `undefined` values.
+ // The bugginess continues as the `Benchmark` constructor has an argument
+ // named `options` and Firefox 1 will not assign a value to `Benchmark.options`,
+ // making it non-writable in the process, unless it is the first property
+ // assigned by for-in loop of `extend()`.
+ extend(Benchmark, {
+
+ /**
+ * The default options copied by benchmark instances.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @type Object
+ */
+ 'options': {
+
+ /**
+ * A flag to indicate that benchmark cycles will execute asynchronously
+ * by default.
+ *
+ * @memberOf Benchmark.options
+ * @type Boolean
+ */
+ 'async': false,
+
+ /**
+ * A flag to indicate that the benchmark clock is deferred.
+ *
+ * @memberOf Benchmark.options
+ * @type Boolean
+ */
+ 'defer': false,
+
+ /**
+ * The delay between test cycles (secs).
+ * @memberOf Benchmark.options
+ * @type Number
+ */
+ 'delay': 0.005,
+
+ /**
+ * Displayed by Benchmark#toString when a `name` is not available
+ * (auto-generated if absent).
+ *
+ * @memberOf Benchmark.options
+ * @type String
+ */
+ 'id': undefined,
+
+ /**
+ * The default number of times to execute a test on a benchmark's first cycle.
+ *
+ * @memberOf Benchmark.options
+ * @type Number
+ */
+ 'initCount': 1,
+
+ /**
+ * The maximum time a benchmark is allowed to run before finishing (secs).
+ *
+ * Note: Cycle delays aren't counted toward the maximum time.
+ *
+ * @memberOf Benchmark.options
+ * @type Number
+ */
+ 'maxTime': 5,
+
+ /**
+ * The minimum sample size required to perform statistical analysis.
+ *
+ * @memberOf Benchmark.options
+ * @type Number
+ */
+ 'minSamples': 5,
+
+ /**
+ * The time needed to reduce the percent uncertainty of measurement to 1% (secs).
+ *
+ * @memberOf Benchmark.options
+ * @type Number
+ */
+ 'minTime': 0,
+
+ /**
+ * The name of the benchmark.
+ *
+ * @memberOf Benchmark.options
+ * @type String
+ */
+ 'name': undefined,
+
+ /**
+ * An event listener called when the benchmark is aborted.
+ *
+ * @memberOf Benchmark.options
+ * @type Function
+ */
+ 'onAbort': undefined,
+
+ /**
+ * An event listener called when the benchmark completes running.
+ *
+ * @memberOf Benchmark.options
+ * @type Function
+ */
+ 'onComplete': undefined,
+
+ /**
+ * An event listener called after each run cycle.
+ *
+ * @memberOf Benchmark.options
+ * @type Function
+ */
+ 'onCycle': undefined,
+
+ /**
+ * An event listener called when a test errors.
+ *
+ * @memberOf Benchmark.options
+ * @type Function
+ */
+ 'onError': undefined,
+
+ /**
+ * An event listener called when the benchmark is reset.
+ *
+ * @memberOf Benchmark.options
+ * @type Function
+ */
+ 'onReset': undefined,
+
+ /**
+ * An event listener called when the benchmark starts running.
+ *
+ * @memberOf Benchmark.options
+ * @type Function
+ */
+ 'onStart': undefined
+ },
+
+ /**
+ * Platform object with properties describing things like browser name,
+ * version, and operating system.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @type Object
+ */
+ 'platform': req('platform') || window.platform || {
+
+ /**
+ * The platform description.
+ *
+ * @memberOf Benchmark.platform
+ * @type String
+ */
+ 'description': window.navigator && navigator.userAgent || null,
+
+ /**
+ * The name of the browser layout engine.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'layout': null,
+
+ /**
+ * The name of the product hosting the browser.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'product': null,
+
+ /**
+ * The name of the browser/environment.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'name': null,
+
+ /**
+ * The name of the product's manufacturer.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'manufacturer': null,
+
+ /**
+ * The name of the operating system.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'os': null,
+
+ /**
+ * The alpha/beta release indicator.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'prerelease': null,
+
+ /**
+ * The browser/environment version.
+ *
+ * @memberOf Benchmark.platform
+ * @type String|Null
+ */
+ 'version': null,
+
+ /**
+ * Return platform description when the platform object is coerced to a string.
+ *
+ * @memberOf Benchmark.platform
+ * @type Function
+ * @returns {String} The platform description.
+ */
+ 'toString': function() {
+ return this.description || '';
+ }
+ },
+
+ /**
+ * The semantic version number.
+ *
+ * @static
+ * @memberOf Benchmark
+ * @type String
+ */
+ 'version': '1.0.0',
+
+ // an object of environment/feature detection flags
+ 'support': support,
+
+ // clone objects
+ 'deepClone': deepClone,
+
+ // iteration utility
+ 'each': each,
+
+ // augment objects
+ 'extend': extend,
+
+ // generic Array#filter
+ 'filter': filter,
+
+ // generic Array#forEach
+ 'forEach': forEach,
+
+ // generic own property iteration utility
+ 'forOwn': forOwn,
+
+ // converts a number to a comma-separated string
+ 'formatNumber': formatNumber,
+
+ // generic Object#hasOwnProperty
+ // (trigger hasKey's lazy define before assigning it to Benchmark)
+ 'hasKey': (hasKey(Benchmark, ''), hasKey),
+
+ // generic Array#indexOf
+ 'indexOf': indexOf,
+
+ // template utility
+ 'interpolate': interpolate,
+
+ // invokes a method on each item in an array
+ 'invoke': invoke,
+
+ // generic Array#join for arrays and objects
+ 'join': join,
+
+ // generic Array#map
+ 'map': map,
+
+ // retrieves a property value from each item in an array
+ 'pluck': pluck,
+
+ // generic Array#reduce
+ 'reduce': reduce
+ });
+
+ /*--------------------------------------------------------------------------*/
+
+ extend(Benchmark.prototype, {
+
+ /**
+ * The number of times a test was executed.
+ *
+ * @memberOf Benchmark
+ * @type Number
+ */
+ 'count': 0,
+
+ /**
+ * The number of cycles performed while benchmarking.
+ *
+ * @memberOf Benchmark
+ * @type Number
+ */
+ 'cycles': 0,
+
+ /**
+ * The number of executions per second.
+ *
+ * @memberOf Benchmark
+ * @type Number
+ */
+ 'hz': 0,
+
+ /**
+ * The compiled test function.
+ *
+ * @memberOf Benchmark
+ * @type Function|String
+ */
+ 'compiled': undefined,
+
+ /**
+ * The error object if the test failed.
+ *
+ * @memberOf Benchmark
+ * @type Object
+ */
+ 'error': undefined,
+
+ /**
+ * The test to benchmark.
+ *
+ * @memberOf Benchmark
+ * @type Function|String
+ */
+ 'fn': undefined,
+
+ /**
+ * A flag to indicate if the benchmark is aborted.
+ *
+ * @memberOf Benchmark
+ * @type Boolean
+ */
+ 'aborted': false,
+
+ /**
+ * A flag to indicate if the benchmark is running.
+ *
+ * @memberOf Benchmark
+ * @type Boolean
+ */
+ 'running': false,
+
+ /**
+ * Compiled into the test and executed immediately **before** the test loop.
+ *
+ * @memberOf Benchmark
+ * @type Function|String
+ * @example
+ *
+ * // basic usage
+ * var bench = Benchmark({
+ * 'setup': function() {
+ * var c = this.count,
+ * element = document.getElementById('container');
+ * while (c--) {
+ * element.appendChild(document.createElement('div'));
+ * }
+ * },
+ * 'fn': function() {
+ * element.removeChild(element.lastChild);
+ * }
+ * });
+ *
+ * // compiles to something like:
+ * var c = this.count,
+ * element = document.getElementById('container');
+ * while (c--) {
+ * element.appendChild(document.createElement('div'));
+ * }
+ * var start = new Date;
+ * while (count--) {
+ * element.removeChild(element.lastChild);
+ * }
+ * var end = new Date - start;
+ *
+ * // or using strings
+ * var bench = Benchmark({
+ * 'setup': '\
+ * var a = 0;\n\
+ * (function() {\n\
+ * (function() {\n\
+ * (function() {',
+ * 'fn': 'a += 1;',
+ * 'teardown': '\
+ * }())\n\
+ * }())\n\
+ * }())'
+ * });
+ *
+ * // compiles to something like:
+ * var a = 0;
+ * (function() {
+ * (function() {
+ * (function() {
+ * var start = new Date;
+ * while (count--) {
+ * a += 1;
+ * }
+ * var end = new Date - start;
+ * }())
+ * }())
+ * }())
+ */
+ 'setup': noop,
+
+ /**
+ * Compiled into the test and executed immediately **after** the test loop.
+ *
+ * @memberOf Benchmark
+ * @type Function|String
+ */
+ 'teardown': noop,
+
+ /**
+ * An object of stats including mean, margin or error, and standard deviation.
+ *
+ * @memberOf Benchmark
+ * @type Object
+ */
+ 'stats': {
+
+ /**
+ * The margin of error.
+ *
+ * @memberOf Benchmark#stats
+ * @type Number
+ */
+ 'moe': 0,
+
+ /**
+ * The relative margin of error (expressed as a percentage of the mean).
+ *
+ * @memberOf Benchmark#stats
+ * @type Number
+ */
+ 'rme': 0,
+
+ /**
+ * The standard error of the mean.
+ *
+ * @memberOf Benchmark#stats
+ * @type Number
+ */
+ 'sem': 0,
+
+ /**
+ * The sample standard deviation.
+ *
+ * @memberOf Benchmark#stats
+ * @type Number
+ */
+ 'deviation': 0,
+
+ /**
+ * The sample arithmetic mean.
+ *
+ * @memberOf Benchmark#stats
+ * @type Number
+ */
+ 'mean': 0,
+
+ /**
+ * The array of sampled periods.
+ *
+ * @memberOf Benchmark#stats
+ * @type Array
+ */
+ 'sample': [],
+
+ /**
+ * The sample variance.
+ *
+ * @memberOf Benchmark#stats
+ * @type Number
+ */
+ 'variance': 0
+ },
+
+ /**
+ * An object of timing data including cycle, elapsed, period, start, and stop.
+ *
+ * @memberOf Benchmark
+ * @type Object
+ */
+ 'times': {
+
+ /**
+ * The time taken to complete the last cycle (secs).
+ *
+ * @memberOf Benchmark#times
+ * @type Number
+ */
+ 'cycle': 0,
+
+ /**
+ * The time taken to complete the benchmark (secs).
+ *
+ * @memberOf Benchmark#times
+ * @type Number
+ */
+ 'elapsed': 0,
+
+ /**
+ * The time taken to execute the test once (secs).
+ *
+ * @memberOf Benchmark#times
+ * @type Number
+ */
+ 'period': 0,
+
+ /**
+ * A timestamp of when the benchmark started (ms).
+ *
+ * @memberOf Benchmark#times
+ * @type Number
+ */
+ 'timeStamp': 0
+ },
+
+ // aborts benchmark (does not record times)
+ 'abort': abort,
+
+ // creates a new benchmark using the same test and options
+ 'clone': clone,
+
+ // compares benchmark's hertz with another
+ 'compare': compare,
+
+ // executes listeners
+ 'emit': emit,
+
+ // get listeners
+ 'listeners': listeners,
+
+ // unregister listeners
+ 'off': off,
+
+ // register listeners
+ 'on': on,
+
+ // reset benchmark properties
+ 'reset': reset,
+
+ // runs the benchmark
+ 'run': run,
+
+ // pretty print benchmark info
+ 'toString': toStringBench
+ });
+
+ /*--------------------------------------------------------------------------*/
+
+ extend(Deferred.prototype, {
+
+ /**
+ * The deferred benchmark instance.
+ *
+ * @memberOf Benchmark.Deferred
+ * @type Object
+ */
+ 'benchmark': null,
+
+ /**
+ * The number of deferred cycles performed while benchmarking.
+ *
+ * @memberOf Benchmark.Deferred
+ * @type Number
+ */
+ 'cycles': 0,
+
+ /**
+ * The time taken to complete the deferred benchmark (secs).
+ *
+ * @memberOf Benchmark.Deferred
+ * @type Number
+ */
+ 'elapsed': 0,
+
+ /**
+ * A timestamp of when the deferred benchmark started (ms).
+ *
+ * @memberOf Benchmark.Deferred
+ * @type Number
+ */
+ 'timeStamp': 0,
+
+ // cycles/completes the deferred benchmark
+ 'resolve': resolve
+ });
+
+ /*--------------------------------------------------------------------------*/
+
+ extend(Event.prototype, {
+
+ /**
+ * A flag to indicate if the emitters listener iteration is aborted.
+ *
+ * @memberOf Benchmark.Event
+ * @type Boolean
+ */
+ 'aborted': false,
+
+ /**
+ * A flag to indicate if the default action is cancelled.
+ *
+ * @memberOf Benchmark.Event
+ * @type Boolean
+ */
+ 'cancelled': false,
+
+ /**
+ * The object whose listeners are currently being processed.
+ *
+ * @memberOf Benchmark.Event
+ * @type Object
+ */
+ 'currentTarget': undefined,
+
+ /**
+ * The return value of the last executed listener.
+ *
+ * @memberOf Benchmark.Event
+ * @type Mixed
+ */
+ 'result': undefined,
+
+ /**
+ * The object to which the event was originally emitted.
+ *
+ * @memberOf Benchmark.Event
+ * @type Object
+ */
+ 'target': undefined,
+
+ /**
+ * A timestamp of when the event was created (ms).
+ *
+ * @memberOf Benchmark.Event
+ * @type Number
+ */
+ 'timeStamp': 0,
+
+ /**
+ * The event type.
+ *
+ * @memberOf Benchmark.Event
+ * @type String
+ */
+ 'type': ''
+ });
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * The default options copied by suite instances.
+ *
+ * @static
+ * @memberOf Benchmark.Suite
+ * @type Object
+ */
+ Suite.options = {
+
+ /**
+ * The name of the suite.
+ *
+ * @memberOf Benchmark.Suite.options
+ * @type String
+ */
+ 'name': undefined
+ };
+
+ /*--------------------------------------------------------------------------*/
+
+ extend(Suite.prototype, {
+
+ /**
+ * The number of benchmarks in the suite.
+ *
+ * @memberOf Benchmark.Suite
+ * @type Number
+ */
+ 'length': 0,
+
+ /**
+ * A flag to indicate if the suite is aborted.
+ *
+ * @memberOf Benchmark.Suite
+ * @type Boolean
+ */
+ 'aborted': false,
+
+ /**
+ * A flag to indicate if the suite is running.
+ *
+ * @memberOf Benchmark.Suite
+ * @type Boolean
+ */
+ 'running': false,
+
+ /**
+ * An `Array#forEach` like method.
+ * Callbacks may terminate the loop by explicitly returning `false`.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Function} callback The function called per iteration.
+ * @returns {Object} The suite iterated over.
+ */
+ 'forEach': methodize(forEach),
+
+ /**
+ * An `Array#indexOf` like method.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Mixed} value The value to search for.
+ * @returns {Number} The index of the matched value or `-1`.
+ */
+ 'indexOf': methodize(indexOf),
+
+ /**
+ * Invokes a method on all benchmarks in the suite.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {String|Object} name The name of the method to invoke OR options object.
+ * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
+ * @returns {Array} A new array of values returned from each method invoked.
+ */
+ 'invoke': methodize(invoke),
+
+ /**
+ * Converts the suite of benchmarks to a string.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {String} [separator=','] A string to separate each element of the array.
+ * @returns {String} The string.
+ */
+ 'join': [].join,
+
+ /**
+ * An `Array#map` like method.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Function} callback The function called per iteration.
+ * @returns {Array} A new array of values returned by the callback.
+ */
+ 'map': methodize(map),
+
+ /**
+ * Retrieves the value of a specified property from all benchmarks in the suite.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {String} property The property to pluck.
+ * @returns {Array} A new array of property values.
+ */
+ 'pluck': methodize(pluck),
+
+ /**
+ * Removes the last benchmark from the suite and returns it.
+ *
+ * @memberOf Benchmark.Suite
+ * @returns {Mixed} The removed benchmark.
+ */
+ 'pop': [].pop,
+
+ /**
+ * Appends benchmarks to the suite.
+ *
+ * @memberOf Benchmark.Suite
+ * @returns {Number} The suite's new length.
+ */
+ 'push': [].push,
+
+ /**
+ * Sorts the benchmarks of the suite.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Function} [compareFn=null] A function that defines the sort order.
+ * @returns {Object} The sorted suite.
+ */
+ 'sort': [].sort,
+
+ /**
+ * An `Array#reduce` like method.
+ *
+ * @memberOf Benchmark.Suite
+ * @param {Function} callback The function called per iteration.
+ * @param {Mixed} accumulator Initial value of the accumulator.
+ * @returns {Mixed} The accumulator.
+ */
+ 'reduce': methodize(reduce),
+
+ // aborts all benchmarks in the suite
+ 'abort': abortSuite,
+
+ // adds a benchmark to the suite
+ 'add': add,
+
+ // creates a new suite with cloned benchmarks
+ 'clone': cloneSuite,
+
+ // executes listeners of a specified type
+ 'emit': emit,
+
+ // creates a new suite of filtered benchmarks
+ 'filter': filterSuite,
+
+ // get listeners
+ 'listeners': listeners,
+
+ // unregister listeners
+ 'off': off,
+
+ // register listeners
+ 'on': on,
+
+ // resets all benchmarks in the suite
+ 'reset': resetSuite,
+
+ // runs all benchmarks in the suite
+ 'run': runSuite,
+
+ // array methods
+ 'concat': concat,
+
+ 'reverse': reverse,
+
+ 'shift': shift,
+
+ 'slice': slice,
+
+ 'splice': splice,
+
+ 'unshift': unshift
+ });
+
+ /*--------------------------------------------------------------------------*/
+
+ // expose Deferred, Event and Suite
+ extend(Benchmark, {
+ 'Deferred': Deferred,
+ 'Event': Event,
+ 'Suite': Suite
+ });
+
+ // expose Benchmark
+ // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
+ if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+ // define as an anonymous module so, through path mapping, it can be aliased
+ define(function() {
+ return Benchmark;
+ });
+ }
+ // check for `exports` after `define` in case a build optimizer adds an `exports` object
+ else if (freeExports) {
+ // in Node.js or RingoJS v0.8.0+
+ if (typeof module == 'object' && module && module.exports == freeExports) {
+ (module.exports = Benchmark).Benchmark = Benchmark;
+ }
+ // in Narwhal or RingoJS v0.7.0-
+ else {
+ freeExports.Benchmark = Benchmark;
+ }
+ }
+ // in a browser or Rhino
+ else {
+ // use square bracket notation so Closure Compiler won't munge `Benchmark`
+ // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
+ window['Benchmark'] = Benchmark;
+ }
+
+ // trigger clock's lazy define early to avoid a security error
+ if (support.air) {
+ clock({ '_original': { 'fn': noop, 'count': 1, 'options': {} } });
+ }
+}(this)); \ No newline at end of file
diff --git a/big-integer/benchmark/index.html b/big-integer/benchmark/index.html
new file mode 100644
index 0000000..7dafd6a
--- /dev/null
+++ b/big-integer/benchmark/index.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Cache-control" content="no-cache">
+ <title>Big integer benchmarks</title>
+ <style>
+ img.wait {
+ width: 25px;
+ }
+ table {
+ border-collapse: collapse;
+ }
+ td, th {
+ border: 1px solid black;
+ padding: 0 5px 0 5px;
+ text-align: center;
+ }
+ td:last-child {
+ text-align: left;
+ }
+ body {
+ background-color: #eee;
+ }
+ #container {
+ border: 1px solid black;
+ border-radius: 15px 15px;
+ background-color: #fff;
+ width: 800px;
+ margin: 0 auto;
+ padding: 10px;
+ }
+ div.graph span {
+ display: inline-block;
+ height: 10px;
+ overflow: hidden;
+ background-color: #00AA00;
+ }
+ div.graph span.rme {
+ background-color: #FF8800;
+ }
+
+ #loading {
+ position: fixed;
+ left: 40%;
+ top: 40%;
+ width: 300px;
+ height: 100px;
+ line-height: 100px;
+ background-color: white;
+ border: 2px solid black;
+ text-align: center;
+ font-weight: bolder;
+ }
+
+ .indent {
+ margin-left: 20px;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="loading">Please wait for libraries to load... <span id="loaded">0</span>/<span id="total"></span></div>
+ <div id="container">
+ <h1>Big integer benchmarks</h1>
+ Some performance benchmarks for different libraries that do arbitrary precision integer arithmetic. Keep in mind that the results shown here are only a rough estimate of the relative performance and can change significantly from run to run, as well as across different runtime environments.<br />
+ <button id="btnRunAll">Run all benchmarks</button>
+ <div id="benchmarks"></div>
+ </div>
+ <script src="tests.js"></script>
+ <script src="index.js"></script>
+ </body>
+</html> \ No newline at end of file
diff --git a/big-integer/benchmark/index.js b/big-integer/benchmark/index.js
new file mode 100644
index 0000000..e4c760b
--- /dev/null
+++ b/big-integer/benchmark/index.js
@@ -0,0 +1,204 @@
+(function () {
+ var benchmarks = libraries["Peter Olson BigInteger.js"].tests,
+ _benchmarks = document.getElementById("benchmarks");
+ var group;
+ for (var i in benchmarks) {
+ var split = i.split(": "), thisGroup = split[0], title = split[1], html = "";
+ if (thisGroup != group) {
+ html += "<h2 id='" + thisGroup + "'>" + thisGroup + "<br><button class='btnBenchmarkGroup' title='" + thisGroup + "'>Run '" + thisGroup + "' benchmarks</button></h2>";
+ group = thisGroup;
+ }
+ html += "<div class='indent'><h3 title='" + i + "'>" + i + "<br><button class='btnBenchmark'>Run benchmark</button></h2>";
+ html += "<table><tr><th>Library</th><th>Code</th><th>Performance</th></tr>";
+ for (var j in libraries) {
+ var lib = libraries[j];
+ if (!lib.tests[i]) continue;
+ html += "<tr><td><a href='" + lib.projectURL + "'>" + j + "</a></td><td><pre>" + lib.tests[i] + "</pre></td><td>-</td></tr>";
+ }
+ html += "</table></div>";
+ _benchmarks.innerHTML += html;
+ }
+ var buttons = document.getElementsByClassName("btnBenchmark");
+ for (var i = 0; i < buttons.length; i++) {
+ buttons[i].onclick = btnBenchmark_click;
+ }
+ buttons = document.getElementsByClassName("btnBenchmarkGroup");
+ for (var i = 0; i < buttons.length; i++) {
+ buttons[i].onclick = btnBenchmarkGroup_click;
+ }
+
+ function btnBenchmark_click() {
+ var test = this.parentElement.title;
+ runTest(test);
+ }
+
+ function btnBenchmarkGroup_click() {
+ var group = this.title;
+ var tests = [];
+ for (var i in benchmarks) {
+ if (i.split(": ")[0] === group) tests.push(i);
+ }
+ runTests(tests);
+ }
+
+ document.getElementById("btnRunAll").onclick = function () {
+ var tests = [];
+ for (var i in benchmarks) tests.push(i);
+ runTests(tests);
+ }
+
+ function runTest(test, callback) {
+ var libs = [];
+ for (var i in libraries) {
+ if (libraries[i].tests[test]) libs.push(libraries[i]);
+ displayPerformance(libraries[i], {
+ name: test,
+ desc: "<img class='wait' src='wait.gif'>"
+ });
+ }
+ var i = 0;
+ (function f() {
+ if (i >= libs.length) {
+ if (callback) callback();
+ return;
+ }
+ testLibrary(libs[i++], [test], f);
+ })();
+ }
+
+ function runTests(tests) {
+ var i = 0;
+ (function f() {
+ if (i < tests.length) {
+ runTest(tests[i++], f);
+ }
+ })();
+ }
+
+ function displayPerformance(library, data) {
+ var test = data.name;
+ var h3s = document.getElementsByTagName("h3"), div;
+ for (var i = 0; i < h3s.length; i++) {
+ if (h3s[i].title === test) div = h3s[i].parentElement;
+ }
+ var table = div.getElementsByTagName("table")[0];
+ var trs = table.rows;
+ for (var i = 0; i < trs.length; i++) {
+ if (trs[i].innerHTML.indexOf(library.projectURL) !== -1) break;
+ }
+ if (i >= trs.length) return;
+ var td = trs[i].cells[2];
+ td.innerHTML = data.desc;
+ if (data.stats) {
+ td.innerHTML += "<div class='graph'></div>";
+ trs[i].stats = data.stats;
+ sortRows(table);
+ }
+ }
+
+ function sortRows(table) {
+ var rows = table.rows;
+ var newRows = [];
+ for (var i = 1; i < rows.length; i++) newRows.push({
+ stats: rows[i].stats,
+ HTML: rows[i].innerHTML
+ });
+ newRows.sort(function (a, b) {
+ if (a.stats && !b.stats) return -1;
+ if (b.stats && !a.stats) return 1;
+ if (!a.stats) return 0;
+ if (!a.stats.mean) return 1;
+ if (!b.stats.mean) return -1;
+ return a.stats.mean - b.stats.mean;
+ });
+ if (!newRows[0].stats) return;
+ var mean = 1 / newRows[0].stats.mean,
+ rme = newRows[0].stats.rme;
+ var max = mean;
+ for (var i = 1; i < rows.length; i++) {
+ rows[i].innerHTML = newRows[i - 1].HTML;
+ rows[i].stats = newRows[i - 1].stats;
+ }
+ for (var i = 1; i < rows.length; i++) {
+ showGraph(rows[i], max);
+ }
+ }
+
+ function showGraph(row, max) {
+ var cell = row.cells[2],
+ stats = row.stats,
+ div = cell.getElementsByTagName("div")[0];
+ if (!stats || !div || !stats.mean) return;
+ var mean = 1 / stats.mean,
+ rme = stats.rme;
+ var variance = (mean * rme / 100);
+ var left = Math.round(100 * (mean - variance) / max),
+ rme = Math.round(100 * variance / max);
+ left = left < 1 ? "1px" : left + "%";
+ div.innerHTML = "<span class='left' style='width:" + left + "'></span>" +
+ "<span class='rme' style='width:" + rme + "%'></span>";
+ }
+
+ var workers = {};
+ var loaded = 0, total = 0;
+ for (i in libraries) {
+ initWorker(libraries[i]);
+ total++;
+ }
+
+ function testLibrary(library, tests, fn) {
+ var url = library.projectURL, timeout;
+ var worker = workers[url];
+ library.testsToRun = tests;
+ library.timeout = 10000;
+ worker.postMessage(library);
+ worker.onmessage = function (e) {
+ clearTimeout(timeout);
+ var type = e.data.type;
+ if (type === "complete") {
+ fn();
+ return;
+ }
+ if (type === "cycle") {
+ displayPerformance(library, e.data);
+ }
+ };
+ timeout = setTimeout(function () {
+ worker.terminate();
+ library.testsToRun = null;
+ initWorker(library);
+ for (var i = 0; i < tests.length; i++) {
+ fn();
+ displayPerformance(library, {
+ name: tests[i],
+ stats: {
+ mean: 0
+ },
+ desc: "Test timed out."
+ });
+ }
+ }, library.timeout * 1.5);
+ }
+
+ function initWorker(library) {
+ var url = library.projectURL;
+ var worker = new Worker("testWorker.js?" + encodeURIComponent(url));
+ worker.postMessage(library);
+ worker.onmessage = function (e) {
+ if (e.data.type === "loaded") {
+ loaded++;
+ showLoaded();
+ }
+ }
+ workers[url] = worker;
+ }
+
+ function showLoaded() {
+ document.getElementById("loaded").innerHTML = loaded;
+ document.getElementById("total").innerHTML = total;
+ if (loaded === total) {
+ document.getElementById("loading").style.display = "none";
+ }
+ }
+ showLoaded();
+})(); \ No newline at end of file
diff --git a/big-integer/benchmark/testWorker.js b/big-integer/benchmark/testWorker.js
new file mode 100644
index 0000000..cd94762
--- /dev/null
+++ b/big-integer/benchmark/testWorker.js
@@ -0,0 +1,70 @@
+var haveScripts = false, timeout;
+function getScripts(msg) {
+ if (haveScripts) return;
+ importScripts.apply(null, ["benchmark.js"].concat(msg.url));
+ var start = new Function(msg.onStart);
+ start();
+ haveScripts = true;
+}
+
+onmessage = function (e) {
+ var msg = e.data;
+ getScripts(msg);
+ if (!msg.testsToRun) {
+ postMessage({
+ type: "loaded"
+ });
+ return;
+ }
+ Benchmark.options.minTime = 1 / 64;
+ Benchmark.options.maxTime = 1 / 2;
+ Benchmark.options.minSamples = 5;
+ var suite = new Benchmark.Suite();
+ for (var i = 0; i < msg.testsToRun.length; i++) {
+ var name = msg.testsToRun[i];
+ suite.add(name, msg.tests[name], {
+ onCycle: msg.onCycle ? new Function(msg.onCycle) : function () { }
+ });
+ }
+ suite.on("cycle", function (e) {
+ var target = e.target,
+ name = target.name,
+ stats = target.stats,
+ desc = createDescription(stats);
+ if (target.aborted) {
+ if (!stats.mean)
+ desc = "Test timed out.";
+ }
+ postMessage({
+ type: "cycle",
+ name: name,
+ stats: stats,
+ desc: desc
+ });
+ clearTimeout(timeout);
+ })
+ .on("complete", function (e) {
+ postMessage({
+ type: "complete"
+ });
+ }).run({
+ async: true
+ });
+ timeout = setTimeout(function () { // abort tests after 10 seconds
+ suite.abort();
+ }, msg.timeout);
+};
+
+function createDescription(stats) {
+ var runs = stats.sample.length;
+ var rme = stats.rme.toFixed(2);
+ var mean = 1 / stats.mean || 0;
+ if (mean >= 100) mean = Math.round(mean) + "";
+ else if (mean >= 10) mean = mean.toFixed(1);
+ else if (mean >= 1) mean = mean.toFixed(2);
+ else mean = mean.toFixed(3);
+ while (/(\d+)(\d{3})/.test(mean)) {
+ mean = mean.replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
+ }
+ return mean + " ops/sec &pm;" + rme + "% (" + runs + " samples)";
+} \ No newline at end of file
diff --git a/big-integer/benchmark/tests.js b/big-integer/benchmark/tests.js
new file mode 100644
index 0000000..e3395b5
--- /dev/null
+++ b/big-integer/benchmark/tests.js
@@ -0,0 +1,192 @@
+var libraries = (function () {
+ var a = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ b = "1234567890234567890134567890124567890123567890123467890123457890123456890123456790123456780123456789",
+ c = "98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241",
+ d = c + c + c + c + c + c + c + c + c + c,
+ e = d + d + d + d + d + d + d + d + d + d,
+ f = e + e + e,
+ c2 = a + b,
+ d2 = c2 + c2 + c2 + c2 + c2 + c2 + c2 + c2 + c2 + c2,
+ e2 = d2 + d2 + d2 + d2 + d2 + d2 + d2 + d2 + d2 + d2,
+ f2 = e2 + e2 + e2,
+ s1 = 12345,
+ s2 = 98765,
+ s3 = 5437654,
+ _5 = 5,
+ _22 = 22,
+ _23 = 23;
+ var vars = { a: a, b: b, c: c, d: d, e: e, f: f, c2: c2, d2: d2, e2: e2, f2: f2, s1: s1, s2: s2, s3: s3, _5: _5, _22: _22, _23: _23 };
+
+ var createInitialization = function (fName, radix) {
+ var str = "";
+ radix = radix || "";
+ for (var i in vars) {
+ str += i + "=" + fName + "('" + vars[i] + "'" + radix + ");" + i + "_str='" + vars[i] + "';";
+ }
+ return str;
+ };
+
+ var createOnCycle = function (f) {
+ var str = "";
+ for (var i in vars) {
+ str += f(i) + ";";
+ }
+ return str;
+ };
+
+ var tests = {
+ "Addition: large1 + large2": "a.add(b)",
+ "Addition: large + small": "a.add(s1)",
+ "Addition: small + large": "s1.add(a)",
+ "Addition: small1 + small2": "s1.add(s2)",
+ "Addition: 200 digits": "c.add(c2)",
+ "Addition: 2,000 digits": "d.add(d2)",
+ "Addition: 20,000 digits": "e.add(e2)",
+ "Addition: 60,000 digits": "f.add(f2)",
+ "Subtraction: large1 - large2": "b.minus(a)",
+ "Subtraction: large - small": "b.minus(s1)",
+ "Subtraction: small - large": "s1.minus(b)",
+ "Subtraction: small - small": "s2.minus(s1)",
+ "Subtraction: 200 digits": "c.minus(c2)",
+ "Subtraction: 2,000 digits": "d.minus(d2)",
+ "Subtraction: 20,000 digits": "e.minus(e2)",
+ "Subtraction: 60,000 digits": "f.minus(f2)",
+ "Multiplication: large * large": "a.times(b)",
+ "Multiplication: large * small": "a.times(s1)",
+ "Multiplication: small * large": "s1.times(a)",
+ "Multiplication: small1 * small2": "s1.times(s2)",
+ "Multiplication: 400 digits": "c.times(b)",
+ "Multiplication: 2,200 digits": "d.times(c)",
+ "Multiplication: 22,000 digits": "e.times(d)",
+ "Multiplication: 82,000 digits": "f.times(e)",
+ "Squaring: small": "s1.square()",
+ "Squaring: 200 digits": "a.square()",
+ "Squaring: 400 digits": "c.square()",
+ "Squaring: 4,000 digits": "d.square()",
+ "Squaring: 40,000 digits": "e.square()",
+ "Division: large1 / large2": "b.over(a)",
+ "Division: large / small": "a.over(s1)",
+ "Division: small / large": "s2.over(b)",
+ "Division: small / small": "s2.over(s1)",
+ "Division: 200 digits": "c.over(b)",
+ "Division: 2,000 digits": "d.over(c)",
+ "Division: 20,000 digits": "e.over(d)",
+ "Division: 60,000 digits": "f.over(e)",
+ "Exponentiation: 5 ^ 22": "_5.pow(_22)",
+ "Exponentiation: 5 ^ 23": "_5.pow(_23)",
+ "Exponentiation: 5 ^ 12345": "_5.pow(s1)",
+ "Exponentiation: 12345 ^ 12345": "s1.pow(s1)",
+ "parseInt: 5 decimal digits": "parseInt(s1_str, 10)",
+ "parseInt: 100 decimal digits": "parseInt(a_str, 10)",
+ "parseInt: 2,000 decimal digits": "parseInt(d_str, 10)",
+ "parseInt: 20,000 decimal digits": "parseInt(e_str, 10)",
+ "parseInt: 5 hex digits": "parseInt(s1_str, 16)",
+ "parseInt: 83 hex digits": "parseInt(a_str, 16)",
+ "parseInt: 1,661 hex digits": "parseInt(d_str, 16)",
+ "parseInt: 16,610 hex digits": "parseInt(e_str, 16)",
+ "toString: 5 decimal digits": "s1.toString(10)",
+ "toString: 100 decimal digits": "a.toString(10)",
+ "toString: 2,000 decimal digits": "d.toString(10)",
+ "toString: 20,000 decimal digits": "e.toString(10)",
+ "toString: 5 hex digits": "s2.toString(16)",
+ "toString: 83 hex digits": "a.toString(16)",
+ "toString: 1,661 hex digits": "d.toString(16)",
+ "toString: 16,610 hex digits": "e.toString(16)"
+ };
+
+ function generateTests(transformation, skip) {
+ skip = skip || [];
+ var t = {};
+ for (var i in tests) {
+ if (skip.indexOf(i.split(":")[0]) > -1) continue;
+ t[i] = transformation(tests[i]);
+ };
+ return t;
+ }
+
+ var libraries = {
+ "Peter Olson BigInteger.js": {
+ url: ["../BigInteger.js"],
+ projectURL: "https://github.com/peterolson/BigInteger.js",
+ onStart: createInitialization("bigInt"),
+ tests: generateTests(function (x) { return x.replace("parseInt", "bigInt"); })
+ },
+ "Yaffle BigInteger": {
+ url: ["https://rawgit.com/Yaffle/BigInteger/gh-pages/BigInteger.js"],
+ projectURL: "https://github.com/Yaffle/BigInteger",
+ onStart: createInitialization("BigInteger.parseInt"),
+ tests: generateTests(function (x) {
+ return x
+ .replace(/([_a-zA-Z0-9]+)\.add\(([_a-zA-Z0-9]+)\)/g, "BigInteger.add($1, $2)")
+ .replace(/([_a-zA-Z0-9]+)\.minus\(([_a-zA-Z0-9]+)\)/g, "BigInteger.subtract($1, $2)")
+ .replace(/([_a-zA-Z0-9]+)\.times\(([_a-zA-Z0-9]+)\)/g, "BigInteger.multiply($1, $2)")
+ .replace(/([_a-zA-Z0-9]+)\.over\(([_a-zA-Z0-9]+)\)/g, "BigInteger.divide($1, $2)")
+ .replace(/([_a-zA-Z0-9]+)\.square\(\)/g, "BigInteger.multiply($1, $1)")
+ .replace(/([_a-zA-Z0-9]+)\.toString\(([_a-zA-Z0-9]+)\)/g, "($1).toString($2)")
+ .replace("parseInt", "BigInteger.parseInt");
+ }, ["Exponentiation"])
+ },
+ "Silent Matt BigInteger": {
+ url: ["https://rawgit.com/silentmatt/javascript-biginteger/master/biginteger.js"],
+ projectURL: "http://silentmatt.com/biginteger/",
+ onStart: createInitialization("BigInteger.parse"),
+ tests: generateTests(function (x) {
+ return x.replace(/\.minus/g, ".subtract")
+ .replace(/\.times/g, ".multiply")
+ .replace(/\.over/g, ".divide")
+ .replace("parseInt", "BigInteger.parse");
+ })
+ },
+ "Tom Wu jsbn": {
+ url: ["http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js", "http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js"],
+ projectURL: "http://www-cs-students.stanford.edu/~tjw/jsbn/",
+ onStart: createInitialization("new BigInteger"),
+ tests: generateTests(function (x) {
+ return x.replace(/\.minus/g, ".subtract")
+ .replace(/\.times/g, ".multiply")
+ .replace(/\.over/g, ".divide")
+ .replace("parseInt", "new BigInteger");
+ })
+ },
+ "Fedor Indutny bn.js": {
+ url: ["https://rawgit.com/indutny/bn.js/master/lib/bn.js"],
+ projectURL: "https://github.com/indutny/bn.js",
+ onStart: createInitialization("new BN"),
+ tests: generateTests(function (x) {
+ return x.replace(/\.minus/g, ".sub")
+ .replace(/\.times/g, ".mul")
+ .replace(/(.+)\.square\(\)/g, "$1.mul($1)")
+ .replace(/\.over/g, ".div")
+ .replace("parseInt", "new BN");
+ }, ["Exponentiation"])
+ },
+ "MikeMcl bignumber.js": {
+ url: ["https://rawgit.com/MikeMcl/bignumber.js/master/bignumber.min.js"],
+ projectURL: "http://mikemcl.github.io/bignumber.js/",
+ onStart: createInitialization("new BigNumber") + "BigNumber.config({POW_PRECISION: 0});",
+ tests: generateTests(function (x) {
+ return x.replace(/\.over/g, ".div")
+ .replace(/(.+)\.square\(\)/g, "$1.times($1)")
+ .replace("parseInt", "new BigNumber");
+ })
+ }/*, // Leemon Baird library link is broken
+ "Leemon Baird BigInt.js": {
+ url: ["http://www.leemon.com/crypto/BigInt.js"],
+ projectURL: "http://www.leemon.com/crypto/BigInt.html",
+ onStart: createInitialization("str2bigInt", ",10"),
+ onCycle: createOnCycle(function (v) {
+ return v + "=" + v + ".concat()";
+ }),
+ tests: generateTests(function(x) {
+ return x.replace(/(\w+)\.add\(([^\)]*)\)/g, "add($1, $2)")
+ .replace(/(\w+)\.minus\(([^\)]*)\)/g, "sub($1, $2)")
+ .replace(/(\w+)\.times\(([^\)]*)\)/g, "mult($1, $2)")
+ .replace(/(\w+)\.over\(([^\)]*)\)/g, "divInt_($1, $2)")
+ .replace(/(\w+)\.square\(([^\)]*)\)/g, "mult($1, $1)")
+ .replace("parseInt", "str2bigInt")
+ .replace(/(\w+)\.toString\(([^\)]*)\)/g, "bigInt2str($1, $2)")
+ }, ["Exponentiation"])
+ }*/
+ };
+ return libraries;
+})();
diff --git a/big-integer/benchmark/wait.gif b/big-integer/benchmark/wait.gif
new file mode 100644
index 0000000..705a72b
--- /dev/null
+++ b/big-integer/benchmark/wait.gif
Binary files differ
diff --git a/big-integer/bower.json b/big-integer/bower.json
new file mode 100644
index 0000000..22dc58f
--- /dev/null
+++ b/big-integer/bower.json
@@ -0,0 +1,29 @@
+{
+ "name": "big-integer",
+ "description": "An arbitrary length integer library for Javascript",
+ "main": "./BigInteger.js",
+ "authors": [
+ "Peter Olson"
+ ],
+ "license": "Unlicense",
+ "keywords": [
+ "math",
+ "big",
+ "bignum",
+ "bigint",
+ "biginteger",
+ "integer",
+ "arbitrary",
+ "precision",
+ "arithmetic"
+ ],
+ "homepage": "https://github.com/peterolson/BigInteger.js",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "coverage",
+ "tests"
+ ]
+}
diff --git a/big-integer/my.conf.js b/big-integer/my.conf.js
new file mode 100644
index 0000000..c7fbdf2
--- /dev/null
+++ b/big-integer/my.conf.js
@@ -0,0 +1,20 @@
+module.exports = function(config) {
+ config.set({
+ basePath: '',
+ frameworks: ['jasmine'],
+ files: [
+ 'BigInteger.js',
+ 'spec/*spec.js'
+ ],
+ browsers: ['PhantomJS'],
+ singleRun: true,
+ reporters: ['progress', 'coverage'],
+ preprocessors: { '*.js': ['coverage'] },
+ coverageReporter: {
+ type : 'lcov',
+ dir : 'coverage/',
+ subdir: '.'
+ },
+ browserNoActivityTimeout: 60000
+ });
+}; \ No newline at end of file
diff --git a/big-integer/package.json b/big-integer/package.json
new file mode 100644
index 0000000..433de27
--- /dev/null
+++ b/big-integer/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "big-integer",
+ "version": "1.6.40",
+ "author": "Peter Olson <peter.e.c.olson+npm@gmail.com>",
+ "description": "An arbitrary length integer library for Javascript",
+ "contributors": [],
+ "bin": {},
+ "scripts": {
+ "test": "tsc && karma start my.conf.js && node spec/tsDefinitions.js",
+ "minify": "uglifyjs BigInteger.js -o BigInteger.min.js"
+ },
+ "main": "./BigInteger",
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:peterolson/BigInteger.js.git"
+ },
+ "keywords": [
+ "math",
+ "big",
+ "bignum",
+ "bigint",
+ "biginteger",
+ "integer",
+ "arbitrary",
+ "precision",
+ "arithmetic"
+ ],
+ "devDependencies": {
+ "@types/lodash": "^4.14.118",
+ "@types/node": "^7.10.2",
+ "coveralls": "^2.11.4",
+ "jasmine": "2.1.x",
+ "jasmine-core": "^2.3.4",
+ "karma": "^0.13.22",
+ "karma-cli": "^1.0.1",
+ "karma-coverage": "^0.4.2",
+ "karma-jasmine": "^0.3.6",
+ "karma-phantomjs-launcher": "^1.0.4",
+ "lodash": "^4.17.11",
+ "typescript": "^2.9.2",
+ "uglifyjs": "^2.4.10"
+ },
+ "license": "Unlicense",
+ "engines": {
+ "node": ">=0.6"
+ },
+ "typings": "./BigInteger.d.ts"
+} \ No newline at end of file
diff --git a/big-integer/spec/SpecRunner.html b/big-integer/spec/SpecRunner.html
new file mode 100644
index 0000000..89ddf5d
--- /dev/null
+++ b/big-integer/spec/SpecRunner.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>BigInteger Tests</title>
+
+ <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.1.3/jasmine_favicon.png">
+ <link rel="stylesheet" href="lib/jasmine-2.1.3/jasmine.css">
+
+ <script src="lib/jasmine-2.1.3/jasmine.js"></script>
+ <script src="lib/jasmine-2.1.3/jasmine-html.js"></script>
+ <script src="lib/jasmine-2.1.3/boot.js"></script>
+
+ <!-- include source files here... -->
+ <script src="../BigInteger.js"></script>
+
+ <!-- include spec files here... -->
+ <script src="spec.js"></script>
+
+</head>
+
+<body>
+</body>
+</html>
diff --git a/big-integer/spec/lib/jasmine-2.1.3/boot.js b/big-integer/spec/lib/jasmine-2.1.3/boot.js
new file mode 100644
index 0000000..164f068
--- /dev/null
+++ b/big-integer/spec/lib/jasmine-2.1.3/boot.js
@@ -0,0 +1,120 @@
+/**
+ Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
+
+ If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
+
+ The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
+
+ [jasmine-gem]: http://github.com/pivotal/jasmine-gem
+ */
+
+(function() {
+
+ /**
+ * ## Require &amp; Instantiate
+ *
+ * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
+ */
+ window.jasmine = jasmineRequire.core(jasmineRequire);
+
+ /**
+ * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
+ */
+ jasmineRequire.html(jasmine);
+
+ /**
+ * Create the Jasmine environment. This is used to run all specs in a project.
+ */
+ var env = jasmine.getEnv();
+
+ /**
+ * ## The Global Interface
+ *
+ * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
+ */
+ var jasmineInterface = jasmineRequire.interface(jasmine, env);
+
+ /**
+ * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
+ */
+ if (typeof window == "undefined" && typeof exports == "object") {
+ extend(exports, jasmineInterface);
+ } else {
+ extend(window, jasmineInterface);
+ }
+
+ /**
+ * ## Runner Parameters
+ *
+ * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
+ */
+
+ var queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return window.location; }
+ });
+
+ var catchingExceptions = queryString.getParam("catch");
+ env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
+
+ /**
+ * ## Reporters
+ * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
+ */
+ var htmlReporter = new jasmine.HtmlReporter({
+ env: env,
+ onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
+ getContainer: function() { return document.body; },
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); },
+ timer: new jasmine.Timer()
+ });
+
+ /**
+ * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
+ */
+ env.addReporter(jasmineInterface.jsApiReporter);
+ env.addReporter(htmlReporter);
+
+ /**
+ * Filter which specs will be run by matching the start of the full name against the `spec` query param.
+ */
+ var specFilter = new jasmine.HtmlSpecFilter({
+ filterString: function() { return queryString.getParam("spec"); }
+ });
+
+ env.specFilter = function(spec) {
+ return specFilter.matches(spec.getFullName());
+ };
+
+ /**
+ * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
+ */
+ window.setTimeout = window.setTimeout;
+ window.setInterval = window.setInterval;
+ window.clearTimeout = window.clearTimeout;
+ window.clearInterval = window.clearInterval;
+
+ /**
+ * ## Execution
+ *
+ * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
+ */
+ var currentWindowOnload = window.onload;
+
+ window.onload = function() {
+ if (currentWindowOnload) {
+ currentWindowOnload();
+ }
+ htmlReporter.initialize();
+ env.execute();
+ };
+
+ /**
+ * Helper function for readability above.
+ */
+ function extend(destination, source) {
+ for (var property in source) destination[property] = source[property];
+ return destination;
+ }
+
+}());
diff --git a/big-integer/spec/lib/jasmine-2.1.3/console.js b/big-integer/spec/lib/jasmine-2.1.3/console.js
new file mode 100644
index 0000000..a65876e
--- /dev/null
+++ b/big-integer/spec/lib/jasmine-2.1.3/console.js
@@ -0,0 +1,190 @@
+/*
+Copyright (c) 2008-2014 Pivotal Labs
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+function getJasmineRequireObj() {
+ if (typeof module !== 'undefined' && module.exports) {
+ return exports;
+ } else {
+ window.jasmineRequire = window.jasmineRequire || {};
+ return window.jasmineRequire;
+ }
+}
+
+getJasmineRequireObj().console = function(jRequire, j$) {
+ j$.ConsoleReporter = jRequire.ConsoleReporter();
+};
+
+getJasmineRequireObj().ConsoleReporter = function() {
+
+ var noopTimer = {
+ start: function(){},
+ elapsed: function(){ return 0; }
+ };
+
+ function ConsoleReporter(options) {
+ var print = options.print,
+ showColors = options.showColors || false,
+ onComplete = options.onComplete || function() {},
+ timer = options.timer || noopTimer,
+ specCount,
+ failureCount,
+ failedSpecs = [],
+ pendingCount,
+ ansi = {
+ green: '\x1B[32m',
+ red: '\x1B[31m',
+ yellow: '\x1B[33m',
+ none: '\x1B[0m'
+ },
+ failedSuites = [];
+
+ print('ConsoleReporter is deprecated and will be removed in a future version.');
+
+ this.jasmineStarted = function() {
+ specCount = 0;
+ failureCount = 0;
+ pendingCount = 0;
+ print('Started');
+ printNewline();
+ timer.start();
+ };
+
+ this.jasmineDone = function() {
+ printNewline();
+ for (var i = 0; i < failedSpecs.length; i++) {
+ specFailureDetails(failedSpecs[i]);
+ }
+
+ if(specCount > 0) {
+ printNewline();
+
+ var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
+ failureCount + ' ' + plural('failure', failureCount);
+
+ if (pendingCount) {
+ specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
+ }
+
+ print(specCounts);
+ } else {
+ print('No specs found');
+ }
+
+ printNewline();
+ var seconds = timer.elapsed() / 1000;
+ print('Finished in ' + seconds + ' ' + plural('second', seconds));
+ printNewline();
+
+ for(i = 0; i < failedSuites.length; i++) {
+ suiteFailureDetails(failedSuites[i]);
+ }
+
+ onComplete(failureCount === 0);
+ };
+
+ this.specDone = function(result) {
+ specCount++;
+
+ if (result.status == 'pending') {
+ pendingCount++;
+ print(colored('yellow', '*'));
+ return;
+ }
+
+ if (result.status == 'passed') {
+ print(colored('green', '.'));
+ return;
+ }
+
+ if (result.status == 'failed') {
+ failureCount++;
+ failedSpecs.push(result);
+ print(colored('red', 'F'));
+ }
+ };
+
+ this.suiteDone = function(result) {
+ if (result.failedExpectations && result.failedExpectations.length > 0) {
+ failureCount++;
+ failedSuites.push(result);
+ }
+ };
+
+ return this;
+
+ function printNewline() {
+ print('\n');
+ }
+
+ function colored(color, str) {
+ return showColors ? (ansi[color] + str + ansi.none) : str;
+ }
+
+ function plural(str, count) {
+ return count == 1 ? str : str + 's';
+ }
+
+ function repeat(thing, times) {
+ var arr = [];
+ for (var i = 0; i < times; i++) {
+ arr.push(thing);
+ }
+ return arr;
+ }
+
+ function indent(str, spaces) {
+ var lines = (str || '').split('\n');
+ var newArr = [];
+ for (var i = 0; i < lines.length; i++) {
+ newArr.push(repeat(' ', spaces).join('') + lines[i]);
+ }
+ return newArr.join('\n');
+ }
+
+ function specFailureDetails(result) {
+ printNewline();
+ print(result.fullName);
+
+ for (var i = 0; i < result.failedExpectations.length; i++) {
+ var failedExpectation = result.failedExpectations[i];
+ printNewline();
+ print(indent(failedExpectation.message, 2));
+ print(indent(failedExpectation.stack, 2));
+ }
+
+ printNewline();
+ }
+
+ function suiteFailureDetails(result) {
+ for (var i = 0; i < result.failedExpectations.length; i++) {
+ printNewline();
+ print(colored('red', 'An error was thrown in an afterAll'));
+ printNewline();
+ print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
+
+ }
+ printNewline();
+ }
+ }
+
+ return ConsoleReporter;
+};
diff --git a/big-integer/spec/lib/jasmine-2.1.3/jasmine-html.js b/big-integer/spec/lib/jasmine-2.1.3/jasmine-html.js
new file mode 100644
index 0000000..898108b
--- /dev/null
+++ b/big-integer/spec/lib/jasmine-2.1.3/jasmine-html.js
@@ -0,0 +1,404 @@
+/*
+Copyright (c) 2008-2014 Pivotal Labs
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+jasmineRequire.html = function(j$) {
+ j$.ResultsNode = jasmineRequire.ResultsNode();
+ j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
+ j$.QueryString = jasmineRequire.QueryString();
+ j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
+};
+
+jasmineRequire.HtmlReporter = function(j$) {
+
+ var noopTimer = {
+ start: function() {},
+ elapsed: function() { return 0; }
+ };
+
+ function HtmlReporter(options) {
+ var env = options.env || {},
+ getContainer = options.getContainer,
+ createElement = options.createElement,
+ createTextNode = options.createTextNode,
+ onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
+ timer = options.timer || noopTimer,
+ results = [],
+ specsExecuted = 0,
+ failureCount = 0,
+ pendingSpecCount = 0,
+ htmlReporterMain,
+ symbols,
+ failedSuites = [];
+
+ this.initialize = function() {
+ clearPrior();
+ htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
+ createDom('div', {className: 'banner'},
+ createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
+ createDom('span', {className: 'version'}, j$.version)
+ ),
+ createDom('ul', {className: 'symbol-summary'}),
+ createDom('div', {className: 'alert'}),
+ createDom('div', {className: 'results'},
+ createDom('div', {className: 'failures'})
+ )
+ );
+ getContainer().appendChild(htmlReporterMain);
+
+ symbols = find('.symbol-summary');
+ };
+
+ var totalSpecsDefined;
+ this.jasmineStarted = function(options) {
+ totalSpecsDefined = options.totalSpecsDefined || 0;
+ timer.start();
+ };
+
+ var summary = createDom('div', {className: 'summary'});
+
+ var topResults = new j$.ResultsNode({}, '', null),
+ currentParent = topResults;
+
+ this.suiteStarted = function(result) {
+ currentParent.addChild(result, 'suite');
+ currentParent = currentParent.last();
+ };
+
+ this.suiteDone = function(result) {
+ if (result.status == 'failed') {
+ failedSuites.push(result);
+ }
+
+ if (currentParent == topResults) {
+ return;
+ }
+
+ currentParent = currentParent.parent;
+ };
+
+ this.specStarted = function(result) {
+ currentParent.addChild(result, 'spec');
+ };
+
+ var failures = [];
+ this.specDone = function(result) {
+ if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
+ console.error('Spec \'' + result.fullName + '\' has no expectations.');
+ }
+
+ if (result.status != 'disabled') {
+ specsExecuted++;
+ }
+
+ symbols.appendChild(createDom('li', {
+ className: noExpectations(result) ? 'empty' : result.status,
+ id: 'spec_' + result.id,
+ title: result.fullName
+ }
+ ));
+
+ if (result.status == 'failed') {
+ failureCount++;
+
+ var failure =
+ createDom('div', {className: 'spec-detail failed'},
+ createDom('div', {className: 'description'},
+ createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
+ ),
+ createDom('div', {className: 'messages'})
+ );
+ var messages = failure.childNodes[1];
+
+ for (var i = 0; i < result.failedExpectations.length; i++) {
+ var expectation = result.failedExpectations[i];
+ messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
+ messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
+ }
+
+ failures.push(failure);
+ }
+
+ if (result.status == 'pending') {
+ pendingSpecCount++;
+ }
+ };
+
+ this.jasmineDone = function() {
+ var banner = find('.banner');
+ banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
+
+ var alert = find('.alert');
+
+ alert.appendChild(createDom('span', { className: 'exceptions' },
+ createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
+ createDom('input', {
+ className: 'raise',
+ id: 'raise-exceptions',
+ type: 'checkbox'
+ })
+ ));
+ var checkbox = find('#raise-exceptions');
+
+ checkbox.checked = !env.catchingExceptions();
+ checkbox.onclick = onRaiseExceptionsClick;
+
+ if (specsExecuted < totalSpecsDefined) {
+ var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
+ alert.appendChild(
+ createDom('span', {className: 'bar skipped'},
+ createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
+ )
+ );
+ }
+ var statusBarMessage = '';
+ var statusBarClassName = 'bar ';
+
+ if (totalSpecsDefined > 0) {
+ statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
+ if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
+ statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
+ } else {
+ statusBarClassName += 'skipped';
+ statusBarMessage += 'No specs found';
+ }
+
+ alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
+
+ for(i = 0; i < failedSuites.length; i++) {
+ var failedSuite = failedSuites[i];
+ for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
+ var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
+ var errorBarClassName = 'bar errored';
+ alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
+ }
+ }
+
+ var results = find('.results');
+ results.appendChild(summary);
+
+ summaryList(topResults, summary);
+
+ function summaryList(resultsTree, domParent) {
+ var specListNode;
+ for (var i = 0; i < resultsTree.children.length; i++) {
+ var resultNode = resultsTree.children[i];
+ if (resultNode.type == 'suite') {
+ var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id},
+ createDom('li', {className: 'suite-detail'},
+ createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
+ )
+ );
+
+ summaryList(resultNode, suiteListNode);
+ domParent.appendChild(suiteListNode);
+ }
+ if (resultNode.type == 'spec') {
+ if (domParent.getAttribute('class') != 'specs') {
+ specListNode = createDom('ul', {className: 'specs'});
+ domParent.appendChild(specListNode);
+ }
+ var specDescription = resultNode.result.description;
+ if(noExpectations(resultNode.result)) {
+ specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
+ }
+ specListNode.appendChild(
+ createDom('li', {
+ className: resultNode.result.status,
+ id: 'spec-' + resultNode.result.id
+ },
+ createDom('a', {href: specHref(resultNode.result)}, specDescription)
+ )
+ );
+ }
+ }
+ }
+
+ if (failures.length) {
+ alert.appendChild(
+ createDom('span', {className: 'menu bar spec-list'},
+ createDom('span', {}, 'Spec List | '),
+ createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
+ alert.appendChild(
+ createDom('span', {className: 'menu bar failure-list'},
+ createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
+ createDom('span', {}, ' | Failures ')));
+
+ find('.failures-menu').onclick = function() {
+ setMenuModeTo('failure-list');
+ };
+ find('.spec-list-menu').onclick = function() {
+ setMenuModeTo('spec-list');
+ };
+
+ setMenuModeTo('failure-list');
+
+ var failureNode = find('.failures');
+ for (var i = 0; i < failures.length; i++) {
+ failureNode.appendChild(failures[i]);
+ }
+ }
+ };
+
+ return this;
+
+ function find(selector) {
+ return getContainer().querySelector('.jasmine_html-reporter ' + selector);
+ }
+
+ function clearPrior() {
+ // return the reporter
+ var oldReporter = find('');
+
+ if(oldReporter) {
+ getContainer().removeChild(oldReporter);
+ }
+ }
+
+ function createDom(type, attrs, childrenVarArgs) {
+ var el = createElement(type);
+
+ for (var i = 2; i < arguments.length; i++) {
+ var child = arguments[i];
+
+ if (typeof child === 'string') {
+ el.appendChild(createTextNode(child));
+ } else {
+ if (child) {
+ el.appendChild(child);
+ }
+ }
+ }
+
+ for (var attr in attrs) {
+ if (attr == 'className') {
+ el[attr] = attrs[attr];
+ } else {
+ el.setAttribute(attr, attrs[attr]);
+ }
+ }
+
+ return el;
+ }
+
+ function pluralize(singular, count) {
+ var word = (count == 1 ? singular : singular + 's');
+
+ return '' + count + ' ' + word;
+ }
+
+ function specHref(result) {
+ return '?spec=' + encodeURIComponent(result.fullName);
+ }
+
+ function setMenuModeTo(mode) {
+ htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
+ }
+
+ function noExpectations(result) {
+ return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
+ result.status === 'passed';
+ }
+ }
+
+ return HtmlReporter;
+};
+
+jasmineRequire.HtmlSpecFilter = function() {
+ function HtmlSpecFilter(options) {
+ var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+ var filterPattern = new RegExp(filterString);
+
+ this.matches = function(specName) {
+ return filterPattern.test(specName);
+ };
+ }
+
+ return HtmlSpecFilter;
+};
+
+jasmineRequire.ResultsNode = function() {
+ function ResultsNode(result, type, parent) {
+ this.result = result;
+ this.type = type;
+ this.parent = parent;
+
+ this.children = [];
+
+ this.addChild = function(result, type) {
+ this.children.push(new ResultsNode(result, type, this));
+ };
+
+ this.last = function() {
+ return this.children[this.children.length - 1];
+ };
+ }
+
+ return ResultsNode;
+};
+
+jasmineRequire.QueryString = function() {
+ function QueryString(options) {
+
+ this.setParam = function(key, value) {
+ var paramMap = queryStringToParamMap();
+ paramMap[key] = value;
+ options.getWindowLocation().search = toQueryString(paramMap);
+ };
+
+ this.getParam = function(key) {
+ return queryStringToParamMap()[key];
+ };
+
+ return this;
+
+ function toQueryString(paramMap) {
+ var qStrPairs = [];
+ for (var prop in paramMap) {
+ qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
+ }
+ return '?' + qStrPairs.join('&');
+ }
+
+ function queryStringToParamMap() {
+ var paramStr = options.getWindowLocation().search.substring(1),
+ params = [],
+ paramMap = {};
+
+ if (paramStr.length > 0) {
+ params = paramStr.split('&');
+ for (var i = 0; i < params.length; i++) {
+ var p = params[i].split('=');
+ var value = decodeURIComponent(p[1]);
+ if (value === 'true' || value === 'false') {
+ value = JSON.parse(value);
+ }
+ paramMap[decodeURIComponent(p[0])] = value;
+ }
+ }
+
+ return paramMap;
+ }
+
+ }
+
+ return QueryString;
+};
diff --git a/big-integer/spec/lib/jasmine-2.1.3/jasmine.css b/big-integer/spec/lib/jasmine-2.1.3/jasmine.css
new file mode 100644
index 0000000..7ae5834
--- /dev/null
+++ b/big-integer/spec/lib/jasmine-2.1.3/jasmine.css
@@ -0,0 +1,62 @@
+body { overflow-y: scroll; }
+
+.jasmine_html-reporter { background-color: #eeeeee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
+.jasmine_html-reporter a { text-decoration: none; }
+.jasmine_html-reporter a:hover { text-decoration: underline; }
+.jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; }
+.jasmine_html-reporter .banner, .jasmine_html-reporter .symbol-summary, .jasmine_html-reporter .summary, .jasmine_html-reporter .result-message, .jasmine_html-reporter .spec .description, .jasmine_html-reporter .spec-detail .description, .jasmine_html-reporter .alert .bar, .jasmine_html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
+.jasmine_html-reporter .banner { position: relative; }
+.jasmine_html-reporter .banner .title { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAAZCAMAAACGusnyAAACdlBMVEX/////AP+AgICqVaqAQICZM5mAVYCSSZKAQICOOY6ATYCLRouAQICJO4mSSYCIRIiPQICHPIeOR4CGQ4aMQICGPYaLRoCFQ4WKQICPPYWJRYCOQoSJQICNPoSIRICMQoSHQICHRICKQoOHQICKPoOJO4OJQYOMQICMQ4CIQYKLQICIPoKLQ4CKQICNPoKJQISMQ4KJQoSLQYKJQISLQ4KIQoSKQYKIQICIQISMQoSKQYKLQIOLQoOJQYGLQIOKQIOMQoGKQYOLQYGKQIOLQoGJQYOJQIOKQYGJQIOKQoGKQIGLQIKLQ4KKQoGLQYKJQIGKQYKJQIGKQIKJQoGKQYKLQIGKQYKLQIOJQoKKQoOJQYKKQIOJQoKKQoOKQIOLQoKKQYOLQYKJQIOKQoKKQYKKQoKJQYOKQYKLQIOKQoKLQYOKQYKLQIOJQoGKQYKJQYGJQoGKQYKLQoGLQYGKQoGJQYKKQYGJQIKKQoGJQYKLQIKKQYGLQYKKQYGKQYGKQYKJQYOKQoKJQYOKQYKLQYOLQYOKQYKLQYOKQoKKQYKKQYOKQYOJQYKKQYKLQYKKQIKKQoKKQYKKQYKKQoKJQIKKQYKLQYKKQYKKQIKKQYKKQYKKQYKKQIKKQYKJQYGLQYGKQYKKQYKKQYGKQIKKQYGKQYOJQoKKQYOLQYKKQYOKQoKKQYKKQoKKQYKKQYKJQYKLQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKJQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKLQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKmIDpEAAAA0XRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAiIyQlJycoKissLS4wMTQ1Njc4OTo7PDw+P0BCQ0RISUpLTE1OUFNUVVdYWFlaW15fYGFiY2ZnaGlqa2xtb3BxcnN0dnh5ent8fX5/gIGChIWIioyNjo+QkZOUlZaYmZqbnJ2eoKGio6WmqKmsra6vsLGztre4ubq7vL2+wMHDxMjJysvNzs/Q0dLU1tfY2dvc3t/g4eLj5ebn6Onq6+zt7u/w8vP09fb3+Pn6+/z9/vkVQXAAAAMaSURBVHhe5dXxV1N1GMfxz2ABbDgIAm5VDJOyVDIJLUMaVpBWUZUaGbmqoGpZRSiGiRWp6KoZ5AB0ZY50RImZQIlahKkMYXv/R90dBvET/rJfOr3Ouc8v99zPec59zvf56j+vYKlViSf7250X4Mr3O29Tgq08BdGB4DhcekEJ5YkQKFsgWZdtj9JpV+I8xPjLFqkrsEIqO8PHSpis36jWazcqjEsfJjkvRssVU37SdIOu4XCf5vEJPsnwJpnRNU9JmxhMk8l1gehIrq7hTFjzOD+Vf88629qKMJVNltInFeRexRQyJlNeqd1iGDlSzrIUIyXbyFfm3RYprcQRe7lqtWyGYbfc6dT0R2vmdOOkX3u55C1rP37ftiH+tDby4r/RBT0w8TyEkr+epB9XgPDmSYYWbrhCuFYaIyw3fDQAXTnSkh+ANofiHmWf9l+FY1I90FdQTetstO00o23novzVsJ7uB3/C5TkbjRwZ5JerwV4iRWq9HFbFMaK/d0TYqayRiQPuIxxS3Bu8JWU90/60tKi7vkhaznez0a/TbVOKj5CaOZh6fWG6/Lyv9B/ZLR1gw/S/fpbeVD3MCW1li6SvWDOn65tr99/uvWtBS0XDm4s1t+sOHpG0kpBKx/l77wOSnxLpcx6TXmXLTPQOKYOf9Q1dfr8/SJ2mFdCvl1Yl93DiHUZvXeLJbGSzYu5gVJ2slbSakOR8dxCq5adQ2oFLqsE9Ex3L4qQO0eOPeU5x56bypXp4onSEb5OkICX6lDat55TeoztNKQcJaakrz9KCb95oD69IKq+yKW4XPjknaS52V0TZqE2cTtXjcHSCRmUO88e+85hj3EP74i9p8pylw7lxgMDyyl6OV7ZejnjNMfatu87LxRbH0IS35gt2a4ZjmGpVBdKK3Wr6INk8jWWSGqbA55CKgjBRC6E9w78ydTg3ABS3AFV1QN0Y4Aa2pgEjWnQURj9L0ayK6R2ysEqxHUKzYnLvvyU+i9KM2JHJzE4vyZOyDcOwOsySajeLPc8sNvPJkFlyJd20wpqAzZeAfZ3oWybxd+P/3j+SG3uSBdf2VQAAAABJRU5ErkJggg==') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -webkit-background-size: 100%; -moz-background-size: 100%; -o-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; }
+.jasmine_html-reporter .banner .version { margin-left: 14px; position: relative; top: 6px; }
+.jasmine_html-reporter .banner .duration { position: absolute; right: 14px; top: 6px; }
+.jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; }
+.jasmine_html-reporter .version { color: #aaaaaa; }
+.jasmine_html-reporter .banner { margin-top: 14px; }
+.jasmine_html-reporter .duration { color: #aaaaaa; float: right; }
+.jasmine_html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
+.jasmine_html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; }
+.jasmine_html-reporter .symbol-summary li.passed { font-size: 14px; }
+.jasmine_html-reporter .symbol-summary li.passed:before { color: #007069; content: "\02022"; }
+.jasmine_html-reporter .symbol-summary li.failed { line-height: 9px; }
+.jasmine_html-reporter .symbol-summary li.failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; }
+.jasmine_html-reporter .symbol-summary li.disabled { font-size: 14px; }
+.jasmine_html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
+.jasmine_html-reporter .symbol-summary li.pending { line-height: 17px; }
+.jasmine_html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
+.jasmine_html-reporter .symbol-summary li.empty { font-size: 14px; }
+.jasmine_html-reporter .symbol-summary li.empty:before { color: #ba9d37; content: "\02022"; }
+.jasmine_html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
+.jasmine_html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
+.jasmine_html-reporter .bar.failed { background-color: #ca3a11; }
+.jasmine_html-reporter .bar.passed { background-color: #007069; }
+.jasmine_html-reporter .bar.skipped { background-color: #bababa; }
+.jasmine_html-reporter .bar.errored { background-color: #ca3a11; }
+.jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
+.jasmine_html-reporter .bar.menu a { color: #333333; }
+.jasmine_html-reporter .bar a { color: white; }
+.jasmine_html-reporter.spec-list .bar.menu.failure-list, .jasmine_html-reporter.spec-list .results .failures { display: none; }
+.jasmine_html-reporter.failure-list .bar.menu.spec-list, .jasmine_html-reporter.failure-list .summary { display: none; }
+.jasmine_html-reporter .running-alert { background-color: #666666; }
+.jasmine_html-reporter .results { margin-top: 14px; }
+.jasmine_html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
+.jasmine_html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
+.jasmine_html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
+.jasmine_html-reporter.showDetails .summary { display: none; }
+.jasmine_html-reporter.showDetails #details { display: block; }
+.jasmine_html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
+.jasmine_html-reporter .summary { margin-top: 14px; }
+.jasmine_html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
+.jasmine_html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
+.jasmine_html-reporter .summary li.passed a { color: #007069; }
+.jasmine_html-reporter .summary li.failed a { color: #ca3a11; }
+.jasmine_html-reporter .summary li.empty a { color: #ba9d37; }
+.jasmine_html-reporter .summary li.pending a { color: #ba9d37; }
+.jasmine_html-reporter .description + .suite { margin-top: 0; }
+.jasmine_html-reporter .suite { margin-top: 14px; }
+.jasmine_html-reporter .suite a { color: #333333; }
+.jasmine_html-reporter .failures .spec-detail { margin-bottom: 28px; }
+.jasmine_html-reporter .failures .spec-detail .description { background-color: #ca3a11; }
+.jasmine_html-reporter .failures .spec-detail .description a { color: white; }
+.jasmine_html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
+.jasmine_html-reporter .result-message span.result { display: block; }
+.jasmine_html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
diff --git a/big-integer/spec/lib/jasmine-2.1.3/jasmine.js b/big-integer/spec/lib/jasmine-2.1.3/jasmine.js
new file mode 100644
index 0000000..1ccb640
--- /dev/null
+++ b/big-integer/spec/lib/jasmine-2.1.3/jasmine.js
@@ -0,0 +1,2908 @@
+/*
+Copyright (c) 2008-2014 Pivotal Labs
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+getJasmineRequireObj = (function (jasmineGlobal) {
+ var jasmineRequire;
+
+ if (typeof module !== 'undefined' && module.exports) {
+ jasmineGlobal = global;
+ jasmineRequire = exports;
+ } else {
+ jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {};
+ }
+
+ function getJasmineRequire() {
+ return jasmineRequire;
+ }
+
+ getJasmineRequire().core = function(jRequire) {
+ var j$ = {};
+
+ jRequire.base(j$, jasmineGlobal);
+ j$.util = jRequire.util();
+ j$.Any = jRequire.Any();
+ j$.CallTracker = jRequire.CallTracker();
+ j$.MockDate = jRequire.MockDate();
+ j$.Clock = jRequire.Clock();
+ j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
+ j$.Env = jRequire.Env(j$);
+ j$.ExceptionFormatter = jRequire.ExceptionFormatter();
+ j$.Expectation = jRequire.Expectation();
+ j$.buildExpectationResult = jRequire.buildExpectationResult();
+ j$.JsApiReporter = jRequire.JsApiReporter();
+ j$.matchersUtil = jRequire.matchersUtil(j$);
+ j$.ObjectContaining = jRequire.ObjectContaining(j$);
+ j$.pp = jRequire.pp(j$);
+ j$.QueueRunner = jRequire.QueueRunner(j$);
+ j$.ReportDispatcher = jRequire.ReportDispatcher();
+ j$.Spec = jRequire.Spec(j$);
+ j$.SpyRegistry = jRequire.SpyRegistry(j$);
+ j$.SpyStrategy = jRequire.SpyStrategy();
+ j$.Suite = jRequire.Suite();
+ j$.Timer = jRequire.Timer();
+ j$.version = jRequire.version();
+
+ j$.matchers = jRequire.requireMatchers(jRequire, j$);
+
+ return j$;
+ };
+
+ return getJasmineRequire;
+})(this);
+
+getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
+ var availableMatchers = [
+ 'toBe',
+ 'toBeCloseTo',
+ 'toBeDefined',
+ 'toBeFalsy',
+ 'toBeGreaterThan',
+ 'toBeLessThan',
+ 'toBeNaN',
+ 'toBeNull',
+ 'toBeTruthy',
+ 'toBeUndefined',
+ 'toContain',
+ 'toEqual',
+ 'toHaveBeenCalled',
+ 'toHaveBeenCalledWith',
+ 'toMatch',
+ 'toThrow',
+ 'toThrowError'
+ ],
+ matchers = {};
+
+ for (var i = 0; i < availableMatchers.length; i++) {
+ var name = availableMatchers[i];
+ matchers[name] = jRequire[name](j$);
+ }
+
+ return matchers;
+};
+
+getJasmineRequireObj().base = function(j$, jasmineGlobal) {
+ j$.unimplementedMethod_ = function() {
+ throw new Error('unimplemented method');
+ };
+
+ j$.MAX_PRETTY_PRINT_DEPTH = 40;
+ j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100;
+ j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
+
+ j$.getGlobal = function() {
+ return jasmineGlobal;
+ };
+
+ j$.getEnv = function(options) {
+ var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);
+ //jasmine. singletons in here (setTimeout blah blah).
+ return env;
+ };
+
+ j$.isArray_ = function(value) {
+ return j$.isA_('Array', value);
+ };
+
+ j$.isString_ = function(value) {
+ return j$.isA_('String', value);
+ };
+
+ j$.isNumber_ = function(value) {
+ return j$.isA_('Number', value);
+ };
+
+ j$.isA_ = function(typeName, value) {
+ return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
+ };
+
+ j$.isDomNode = function(obj) {
+ return obj.nodeType > 0;
+ };
+
+ j$.any = function(clazz) {
+ return new j$.Any(clazz);
+ };
+
+ j$.objectContaining = function(sample) {
+ return new j$.ObjectContaining(sample);
+ };
+
+ j$.createSpy = function(name, originalFn) {
+
+ var spyStrategy = new j$.SpyStrategy({
+ name: name,
+ fn: originalFn,
+ getSpy: function() { return spy; }
+ }),
+ callTracker = new j$.CallTracker(),
+ spy = function() {
+ var callData = {
+ object: this,
+ args: Array.prototype.slice.apply(arguments)
+ };
+
+ callTracker.track(callData);
+ var returnValue = spyStrategy.exec.apply(this, arguments);
+ callData.returnValue = returnValue;
+
+ return returnValue;
+ };
+
+ for (var prop in originalFn) {
+ if (prop === 'and' || prop === 'calls') {
+ throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon');
+ }
+
+ spy[prop] = originalFn[prop];
+ }
+
+ spy.and = spyStrategy;
+ spy.calls = callTracker;
+
+ return spy;
+ };
+
+ j$.isSpy = function(putativeSpy) {
+ if (!putativeSpy) {
+ return false;
+ }
+ return putativeSpy.and instanceof j$.SpyStrategy &&
+ putativeSpy.calls instanceof j$.CallTracker;
+ };
+
+ j$.createSpyObj = function(baseName, methodNames) {
+ if (!j$.isArray_(methodNames) || methodNames.length === 0) {
+ throw 'createSpyObj requires a non-empty array of method names to create spies for';
+ }
+ var obj = {};
+ for (var i = 0; i < methodNames.length; i++) {
+ obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);
+ }
+ return obj;
+ };
+};
+
+getJasmineRequireObj().util = function() {
+
+ var util = {};
+
+ util.inherit = function(childClass, parentClass) {
+ var Subclass = function() {
+ };
+ Subclass.prototype = parentClass.prototype;
+ childClass.prototype = new Subclass();
+ };
+
+ util.htmlEscape = function(str) {
+ if (!str) {
+ return str;
+ }
+ return str.replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;');
+ };
+
+ util.argsToArray = function(args) {
+ var arrayOfArgs = [];
+ for (var i = 0; i < args.length; i++) {
+ arrayOfArgs.push(args[i]);
+ }
+ return arrayOfArgs;
+ };
+
+ util.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ util.arrayContains = function(array, search) {
+ var i = array.length;
+ while (i--) {
+ if (array[i] === search) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ util.clone = function(obj) {
+ if (Object.prototype.toString.apply(obj) === '[object Array]') {
+ return obj.slice();
+ }
+
+ var cloned = {};
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ cloned[prop] = obj[prop];
+ }
+ }
+
+ return cloned;
+ };
+
+ return util;
+};
+
+getJasmineRequireObj().Spec = function(j$) {
+ function Spec(attrs) {
+ this.expectationFactory = attrs.expectationFactory;
+ this.resultCallback = attrs.resultCallback || function() {};
+ this.id = attrs.id;
+ this.description = attrs.description || '';
+ this.queueableFn = attrs.queueableFn;
+ this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
+ this.userContext = attrs.userContext || function() { return {}; };
+ this.onStart = attrs.onStart || function() {};
+ this.getSpecName = attrs.getSpecName || function() { return ''; };
+ this.expectationResultFactory = attrs.expectationResultFactory || function() { };
+ this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
+ this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
+
+ if (!this.queueableFn.fn) {
+ this.pend();
+ }
+
+ this.result = {
+ id: this.id,
+ description: this.description,
+ fullName: this.getFullName(),
+ failedExpectations: [],
+ passedExpectations: []
+ };
+ }
+
+ Spec.prototype.addExpectationResult = function(passed, data) {
+ var expectationResult = this.expectationResultFactory(data);
+ if (passed) {
+ this.result.passedExpectations.push(expectationResult);
+ } else {
+ this.result.failedExpectations.push(expectationResult);
+ }
+ };
+
+ Spec.prototype.expect = function(actual) {
+ return this.expectationFactory(actual, this);
+ };
+
+ Spec.prototype.execute = function(onComplete) {
+ var self = this;
+
+ this.onStart(this);
+
+ if (this.markedPending || this.disabled) {
+ complete();
+ return;
+ }
+
+ var fns = this.beforeAndAfterFns();
+ var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
+
+ this.queueRunnerFactory({
+ queueableFns: allFns,
+ onException: function() { self.onException.apply(self, arguments); },
+ onComplete: complete,
+ userContext: this.userContext()
+ });
+
+ function complete() {
+ self.result.status = self.status();
+ self.resultCallback(self.result);
+
+ if (onComplete) {
+ onComplete();
+ }
+ }
+ };
+
+ Spec.prototype.onException = function onException(e) {
+ if (Spec.isPendingSpecException(e)) {
+ this.pend();
+ return;
+ }
+
+ this.addExpectationResult(false, {
+ matcherName: '',
+ passed: false,
+ expected: '',
+ actual: '',
+ error: e
+ });
+ };
+
+ Spec.prototype.disable = function() {
+ this.disabled = true;
+ };
+
+ Spec.prototype.pend = function() {
+ this.markedPending = true;
+ };
+
+ Spec.prototype.status = function() {
+ if (this.disabled) {
+ return 'disabled';
+ }
+
+ if (this.markedPending) {
+ return 'pending';
+ }
+
+ if (this.result.failedExpectations.length > 0) {
+ return 'failed';
+ } else {
+ return 'passed';
+ }
+ };
+
+ Spec.prototype.isExecutable = function() {
+ return !this.disabled && !this.markedPending;
+ };
+
+ Spec.prototype.getFullName = function() {
+ return this.getSpecName(this);
+ };
+
+ Spec.pendingSpecExceptionMessage = '=> marked Pending';
+
+ Spec.isPendingSpecException = function(e) {
+ return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1);
+ };
+
+ return Spec;
+};
+
+if (typeof window == void 0 && typeof exports == 'object') {
+ exports.Spec = jasmineRequire.Spec;
+}
+
+getJasmineRequireObj().Env = function(j$) {
+ function Env(options) {
+ options = options || {};
+
+ var self = this;
+ var global = options.global || j$.getGlobal();
+
+ var totalSpecsDefined = 0;
+
+ var catchExceptions = true;
+
+ var realSetTimeout = j$.getGlobal().setTimeout;
+ var realClearTimeout = j$.getGlobal().clearTimeout;
+ this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global));
+
+ var runnableLookupTable = {};
+ var runnableResources = {};
+
+ var currentSpec = null;
+ var currentlyExecutingSuites = [];
+ var currentDeclarationSuite = null;
+
+ var currentSuite = function() {
+ return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
+ };
+
+ var currentRunnable = function() {
+ return currentSpec || currentSuite();
+ };
+
+ var reporter = new j$.ReportDispatcher([
+ 'jasmineStarted',
+ 'jasmineDone',
+ 'suiteStarted',
+ 'suiteDone',
+ 'specStarted',
+ 'specDone'
+ ]);
+
+ this.specFilter = function() {
+ return true;
+ };
+
+ this.addCustomEqualityTester = function(tester) {
+ if(!currentRunnable()) {
+ throw new Error('Custom Equalities must be added in a before function or a spec');
+ }
+ runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
+ };
+
+ this.addMatchers = function(matchersToAdd) {
+ if(!currentRunnable()) {
+ throw new Error('Matchers must be added in a before function or a spec');
+ }
+ var customMatchers = runnableResources[currentRunnable().id].customMatchers;
+ for (var matcherName in matchersToAdd) {
+ customMatchers[matcherName] = matchersToAdd[matcherName];
+ }
+ };
+
+ j$.Expectation.addCoreMatchers(j$.matchers);
+
+ var nextSpecId = 0;
+ var getNextSpecId = function() {
+ return 'spec' + nextSpecId++;
+ };
+
+ var nextSuiteId = 0;
+ var getNextSuiteId = function() {
+ return 'suite' + nextSuiteId++;
+ };
+
+ var expectationFactory = function(actual, spec) {
+ return j$.Expectation.Factory({
+ util: j$.matchersUtil,
+ customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
+ customMatchers: runnableResources[spec.id].customMatchers,
+ actual: actual,
+ addExpectationResult: addExpectationResult
+ });
+
+ function addExpectationResult(passed, result) {
+ return spec.addExpectationResult(passed, result);
+ }
+ };
+
+ var defaultResourcesForRunnable = function(id, parentRunnableId) {
+ var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
+
+ if(runnableResources[parentRunnableId]){
+ resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
+ resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
+ }
+
+ runnableResources[id] = resources;
+ };
+
+ var clearResourcesForRunnable = function(id) {
+ spyRegistry.clearSpies();
+ delete runnableResources[id];
+ };
+
+ var beforeAndAfterFns = function(suite, runnablesExplictlySet) {
+ return function() {
+ var befores = [],
+ afters = [],
+ beforeAlls = [],
+ afterAlls = [];
+
+ while(suite) {
+ befores = befores.concat(suite.beforeFns);
+ afters = afters.concat(suite.afterFns);
+
+ if (runnablesExplictlySet()) {
+ beforeAlls = beforeAlls.concat(suite.beforeAllFns);
+ afterAlls = afterAlls.concat(suite.afterAllFns);
+ }
+
+ suite = suite.parentSuite;
+ }
+ return {
+ befores: beforeAlls.reverse().concat(befores.reverse()),
+ afters: afters.concat(afterAlls)
+ };
+ };
+ };
+
+ var getSpecName = function(spec, suite) {
+ return suite.getFullName() + ' ' + spec.description;
+ };
+
+ // TODO: we may just be able to pass in the fn instead of wrapping here
+ var buildExpectationResult = j$.buildExpectationResult,
+ exceptionFormatter = new j$.ExceptionFormatter(),
+ expectationResultFactory = function(attrs) {
+ attrs.messageFormatter = exceptionFormatter.message;
+ attrs.stackFormatter = exceptionFormatter.stack;
+
+ return buildExpectationResult(attrs);
+ };
+
+ // TODO: fix this naming, and here's where the value comes in
+ this.catchExceptions = function(value) {
+ catchExceptions = !!value;
+ return catchExceptions;
+ };
+
+ this.catchingExceptions = function() {
+ return catchExceptions;
+ };
+
+ var maximumSpecCallbackDepth = 20;
+ var currentSpecCallbackDepth = 0;
+
+ function clearStack(fn) {
+ currentSpecCallbackDepth++;
+ if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {
+ currentSpecCallbackDepth = 0;
+ realSetTimeout(fn, 0);
+ } else {
+ fn();
+ }
+ }
+
+ var catchException = function(e) {
+ return j$.Spec.isPendingSpecException(e) || catchExceptions;
+ };
+
+ var queueRunnerFactory = function(options) {
+ options.catchException = catchException;
+ options.clearStack = options.clearStack || clearStack;
+ options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
+ options.fail = self.fail;
+
+ new j$.QueueRunner(options).execute();
+ };
+
+ var topSuite = new j$.Suite({
+ env: this,
+ id: getNextSuiteId(),
+ description: 'Jasmine__TopLevel__Suite',
+ queueRunner: queueRunnerFactory
+ });
+ runnableLookupTable[topSuite.id] = topSuite;
+ defaultResourcesForRunnable(topSuite.id);
+ currentDeclarationSuite = topSuite;
+
+ this.topSuite = function() {
+ return topSuite;
+ };
+
+ this.execute = function(runnablesToRun) {
+ if(runnablesToRun) {
+ runnablesExplictlySet = true;
+ } else if (focusedRunnables.length) {
+ runnablesExplictlySet = true;
+ runnablesToRun = focusedRunnables;
+ } else {
+ runnablesToRun = [topSuite.id];
+ }
+
+ var allFns = [];
+ for(var i = 0; i < runnablesToRun.length; i++) {
+ var runnable = runnableLookupTable[runnablesToRun[i]];
+ allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable));
+ }
+
+ reporter.jasmineStarted({
+ totalSpecsDefined: totalSpecsDefined
+ });
+
+ queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone});
+ };
+
+ this.addReporter = function(reporterToAdd) {
+ reporter.addReporter(reporterToAdd);
+ };
+
+ var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
+ if(!currentRunnable()) {
+ throw new Error('Spies must be created in a before function or a spec');
+ }
+ return runnableResources[currentRunnable().id].spies;
+ }});
+
+ this.spyOn = function() {
+ return spyRegistry.spyOn.apply(spyRegistry, arguments);
+ };
+
+ var suiteFactory = function(description) {
+ var suite = new j$.Suite({
+ env: self,
+ id: getNextSuiteId(),
+ description: description,
+ parentSuite: currentDeclarationSuite,
+ queueRunner: queueRunnerFactory,
+ onStart: suiteStarted,
+ expectationFactory: expectationFactory,
+ expectationResultFactory: expectationResultFactory,
+ resultCallback: function(attrs) {
+ if (!suite.disabled) {
+ clearResourcesForRunnable(suite.id);
+ currentlyExecutingSuites.pop();
+ }
+ reporter.suiteDone(attrs);
+ }
+ });
+
+ runnableLookupTable[suite.id] = suite;
+ return suite;
+
+ function suiteStarted(suite) {
+ currentlyExecutingSuites.push(suite);
+ defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
+ reporter.suiteStarted(suite.result);
+ }
+ };
+
+ this.describe = function(description, specDefinitions) {
+ var suite = suiteFactory(description);
+ addSpecsToSuite(suite, specDefinitions);
+ return suite;
+ };
+
+ this.xdescribe = function(description, specDefinitions) {
+ var suite = this.describe(description, specDefinitions);
+ suite.disable();
+ return suite;
+ };
+
+ var focusedRunnables = [];
+
+ this.fdescribe = function(description, specDefinitions) {
+ var suite = suiteFactory(description);
+ suite.isFocused = true;
+
+ focusedRunnables.push(suite.id);
+ unfocusAncestor();
+ addSpecsToSuite(suite, specDefinitions);
+
+ return suite;
+ };
+
+ function addSpecsToSuite(suite, specDefinitions) {
+ var parentSuite = currentDeclarationSuite;
+ parentSuite.addChild(suite);
+ currentDeclarationSuite = suite;
+
+ var declarationError = null;
+ try {
+ specDefinitions.call(suite);
+ } catch (e) {
+ declarationError = e;
+ }
+
+ if (declarationError) {
+ self.it('encountered a declaration exception', function() {
+ throw declarationError;
+ });
+ }
+
+ currentDeclarationSuite = parentSuite;
+ }
+
+ function findFocusedAncestor(suite) {
+ while (suite) {
+ if (suite.isFocused) {
+ return suite.id;
+ }
+ suite = suite.parentSuite;
+ }
+
+ return null;
+ }
+
+ function unfocusAncestor() {
+ var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
+ if (focusedAncestor) {
+ for (var i = 0; i < focusedRunnables.length; i++) {
+ if (focusedRunnables[i] === focusedAncestor) {
+ focusedRunnables.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ var runnablesExplictlySet = false;
+
+ var runnablesExplictlySetGetter = function(){
+ return runnablesExplictlySet;
+ };
+
+ var specFactory = function(description, fn, suite, timeout) {
+ totalSpecsDefined++;
+ var spec = new j$.Spec({
+ id: getNextSpecId(),
+ beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter),
+ expectationFactory: expectationFactory,
+ resultCallback: specResultCallback,
+ getSpecName: function(spec) {
+ return getSpecName(spec, suite);
+ },
+ onStart: specStarted,
+ description: description,
+ expectationResultFactory: expectationResultFactory,
+ queueRunnerFactory: queueRunnerFactory,
+ userContext: function() { return suite.clonedSharedUserContext(); },
+ queueableFn: {
+ fn: fn,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ }
+ });
+
+ runnableLookupTable[spec.id] = spec;
+
+ if (!self.specFilter(spec)) {
+ spec.disable();
+ }
+
+ return spec;
+
+ function specResultCallback(result) {
+ clearResourcesForRunnable(spec.id);
+ currentSpec = null;
+ reporter.specDone(result);
+ }
+
+ function specStarted(spec) {
+ currentSpec = spec;
+ defaultResourcesForRunnable(spec.id, suite.id);
+ reporter.specStarted(spec.result);
+ }
+ };
+
+ this.it = function(description, fn, timeout) {
+ var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
+ currentDeclarationSuite.addChild(spec);
+ return spec;
+ };
+
+ this.xit = function() {
+ var spec = this.it.apply(this, arguments);
+ spec.pend();
+ return spec;
+ };
+
+ this.fit = function(){
+ var spec = this.it.apply(this, arguments);
+
+ focusedRunnables.push(spec.id);
+ unfocusAncestor();
+ return spec;
+ };
+
+ this.expect = function(actual) {
+ if (!currentRunnable()) {
+ throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
+ }
+
+ return currentRunnable().expect(actual);
+ };
+
+ this.beforeEach = function(beforeEachFunction, timeout) {
+ currentDeclarationSuite.beforeEach({
+ fn: beforeEachFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.beforeAll = function(beforeAllFunction, timeout) {
+ currentDeclarationSuite.beforeAll({
+ fn: beforeAllFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.afterEach = function(afterEachFunction, timeout) {
+ currentDeclarationSuite.afterEach({
+ fn: afterEachFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.afterAll = function(afterAllFunction, timeout) {
+ currentDeclarationSuite.afterAll({
+ fn: afterAllFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.pending = function() {
+ throw j$.Spec.pendingSpecExceptionMessage;
+ };
+
+ this.fail = function(error) {
+ var message = 'Failed';
+ if (error) {
+ message += ': ';
+ message += error.message || error;
+ }
+
+ currentRunnable().addExpectationResult(false, {
+ matcherName: '',
+ passed: false,
+ expected: '',
+ actual: '',
+ message: message
+ });
+ };
+ }
+
+ return Env;
+};
+
+getJasmineRequireObj().JsApiReporter = function() {
+
+ var noopTimer = {
+ start: function(){},
+ elapsed: function(){ return 0; }
+ };
+
+ function JsApiReporter(options) {
+ var timer = options.timer || noopTimer,
+ status = 'loaded';
+
+ this.started = false;
+ this.finished = false;
+
+ this.jasmineStarted = function() {
+ this.started = true;
+ status = 'started';
+ timer.start();
+ };
+
+ var executionTime;
+
+ this.jasmineDone = function() {
+ this.finished = true;
+ executionTime = timer.elapsed();
+ status = 'done';
+ };
+
+ this.status = function() {
+ return status;
+ };
+
+ var suites = [],
+ suites_hash = {};
+
+ this.suiteStarted = function(result) {
+ suites_hash[result.id] = result;
+ };
+
+ this.suiteDone = function(result) {
+ storeSuite(result);
+ };
+
+ this.suiteResults = function(index, length) {
+ return suites.slice(index, index + length);
+ };
+
+ function storeSuite(result) {
+ suites.push(result);
+ suites_hash[result.id] = result;
+ }
+
+ this.suites = function() {
+ return suites_hash;
+ };
+
+ var specs = [];
+
+ this.specDone = function(result) {
+ specs.push(result);
+ };
+
+ this.specResults = function(index, length) {
+ return specs.slice(index, index + length);
+ };
+
+ this.specs = function() {
+ return specs;
+ };
+
+ this.executionTime = function() {
+ return executionTime;
+ };
+
+ }
+
+ return JsApiReporter;
+};
+
+getJasmineRequireObj().Any = function() {
+
+ function Any(expectedObject) {
+ this.expectedObject = expectedObject;
+ }
+
+ Any.prototype.jasmineMatches = function(other) {
+ if (this.expectedObject == String) {
+ return typeof other == 'string' || other instanceof String;
+ }
+
+ if (this.expectedObject == Number) {
+ return typeof other == 'number' || other instanceof Number;
+ }
+
+ if (this.expectedObject == Function) {
+ return typeof other == 'function' || other instanceof Function;
+ }
+
+ if (this.expectedObject == Object) {
+ return typeof other == 'object';
+ }
+
+ if (this.expectedObject == Boolean) {
+ return typeof other == 'boolean';
+ }
+
+ return other instanceof this.expectedObject;
+ };
+
+ Any.prototype.jasmineToString = function() {
+ return '<jasmine.any(' + this.expectedObject + ')>';
+ };
+
+ return Any;
+};
+
+getJasmineRequireObj().CallTracker = function() {
+
+ function CallTracker() {
+ var calls = [];
+
+ this.track = function(context) {
+ calls.push(context);
+ };
+
+ this.any = function() {
+ return !!calls.length;
+ };
+
+ this.count = function() {
+ return calls.length;
+ };
+
+ this.argsFor = function(index) {
+ var call = calls[index];
+ return call ? call.args : [];
+ };
+
+ this.all = function() {
+ return calls;
+ };
+
+ this.allArgs = function() {
+ var callArgs = [];
+ for(var i = 0; i < calls.length; i++){
+ callArgs.push(calls[i].args);
+ }
+
+ return callArgs;
+ };
+
+ this.first = function() {
+ return calls[0];
+ };
+
+ this.mostRecent = function() {
+ return calls[calls.length - 1];
+ };
+
+ this.reset = function() {
+ calls = [];
+ };
+ }
+
+ return CallTracker;
+};
+
+getJasmineRequireObj().Clock = function() {
+ function Clock(global, delayedFunctionScheduler, mockDate) {
+ var self = this,
+ realTimingFunctions = {
+ setTimeout: global.setTimeout,
+ clearTimeout: global.clearTimeout,
+ setInterval: global.setInterval,
+ clearInterval: global.clearInterval
+ },
+ fakeTimingFunctions = {
+ setTimeout: setTimeout,
+ clearTimeout: clearTimeout,
+ setInterval: setInterval,
+ clearInterval: clearInterval
+ },
+ installed = false,
+ timer;
+
+
+ self.install = function() {
+ replace(global, fakeTimingFunctions);
+ timer = fakeTimingFunctions;
+ installed = true;
+
+ return self;
+ };
+
+ self.uninstall = function() {
+ delayedFunctionScheduler.reset();
+ mockDate.uninstall();
+ replace(global, realTimingFunctions);
+
+ timer = realTimingFunctions;
+ installed = false;
+ };
+
+ self.mockDate = function(initialDate) {
+ mockDate.install(initialDate);
+ };
+
+ self.setTimeout = function(fn, delay, params) {
+ if (legacyIE()) {
+ if (arguments.length > 2) {
+ throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill');
+ }
+ return timer.setTimeout(fn, delay);
+ }
+ return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
+ };
+
+ self.setInterval = function(fn, delay, params) {
+ if (legacyIE()) {
+ if (arguments.length > 2) {
+ throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill');
+ }
+ return timer.setInterval(fn, delay);
+ }
+ return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
+ };
+
+ self.clearTimeout = function(id) {
+ return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
+ };
+
+ self.clearInterval = function(id) {
+ return Function.prototype.call.apply(timer.clearInterval, [global, id]);
+ };
+
+ self.tick = function(millis) {
+ if (installed) {
+ mockDate.tick(millis);
+ delayedFunctionScheduler.tick(millis);
+ } else {
+ throw new Error('Mock clock is not installed, use jasmine.clock().install()');
+ }
+ };
+
+ return self;
+
+ function legacyIE() {
+ //if these methods are polyfilled, apply will be present
+ return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
+ }
+
+ function replace(dest, source) {
+ for (var prop in source) {
+ dest[prop] = source[prop];
+ }
+ }
+
+ function setTimeout(fn, delay) {
+ return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
+ }
+
+ function clearTimeout(id) {
+ return delayedFunctionScheduler.removeFunctionWithId(id);
+ }
+
+ function setInterval(fn, interval) {
+ return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
+ }
+
+ function clearInterval(id) {
+ return delayedFunctionScheduler.removeFunctionWithId(id);
+ }
+
+ function argSlice(argsObj, n) {
+ return Array.prototype.slice.call(argsObj, n);
+ }
+ }
+
+ return Clock;
+};
+
+getJasmineRequireObj().DelayedFunctionScheduler = function() {
+ function DelayedFunctionScheduler() {
+ var self = this;
+ var scheduledLookup = [];
+ var scheduledFunctions = {};
+ var currentTime = 0;
+ var delayedFnCount = 0;
+
+ self.tick = function(millis) {
+ millis = millis || 0;
+ var endTime = currentTime + millis;
+
+ runScheduledFunctions(endTime);
+ currentTime = endTime;
+ };
+
+ self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
+ var f;
+ if (typeof(funcToCall) === 'string') {
+ /* jshint evil: true */
+ f = function() { return eval(funcToCall); };
+ /* jshint evil: false */
+ } else {
+ f = funcToCall;
+ }
+
+ millis = millis || 0;
+ timeoutKey = timeoutKey || ++delayedFnCount;
+ runAtMillis = runAtMillis || (currentTime + millis);
+
+ var funcToSchedule = {
+ runAtMillis: runAtMillis,
+ funcToCall: f,
+ recurring: recurring,
+ params: params,
+ timeoutKey: timeoutKey,
+ millis: millis
+ };
+
+ if (runAtMillis in scheduledFunctions) {
+ scheduledFunctions[runAtMillis].push(funcToSchedule);
+ } else {
+ scheduledFunctions[runAtMillis] = [funcToSchedule];
+ scheduledLookup.push(runAtMillis);
+ scheduledLookup.sort(function (a, b) {
+ return a - b;
+ });
+ }
+
+ return timeoutKey;
+ };
+
+ self.removeFunctionWithId = function(timeoutKey) {
+ for (var runAtMillis in scheduledFunctions) {
+ var funcs = scheduledFunctions[runAtMillis];
+ var i = indexOfFirstToPass(funcs, function (func) {
+ return func.timeoutKey === timeoutKey;
+ });
+
+ if (i > -1) {
+ if (funcs.length === 1) {
+ delete scheduledFunctions[runAtMillis];
+ deleteFromLookup(runAtMillis);
+ } else {
+ funcs.splice(i, 1);
+ }
+
+ // intervals get rescheduled when executed, so there's never more
+ // than a single scheduled function with a given timeoutKey
+ break;
+ }
+ }
+ };
+
+ self.reset = function() {
+ currentTime = 0;
+ scheduledLookup = [];
+ scheduledFunctions = {};
+ delayedFnCount = 0;
+ };
+
+ return self;
+
+ function indexOfFirstToPass(array, testFn) {
+ var index = -1;
+
+ for (var i = 0; i < array.length; ++i) {
+ if (testFn(array[i])) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+ }
+
+ function deleteFromLookup(key) {
+ var value = Number(key);
+ var i = indexOfFirstToPass(scheduledLookup, function (millis) {
+ return millis === value;
+ });
+
+ if (i > -1) {
+ scheduledLookup.splice(i, 1);
+ }
+ }
+
+ function reschedule(scheduledFn) {
+ self.scheduleFunction(scheduledFn.funcToCall,
+ scheduledFn.millis,
+ scheduledFn.params,
+ true,
+ scheduledFn.timeoutKey,
+ scheduledFn.runAtMillis + scheduledFn.millis);
+ }
+
+ function runScheduledFunctions(endTime) {
+ if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
+ return;
+ }
+
+ do {
+ currentTime = scheduledLookup.shift();
+
+ var funcsToRun = scheduledFunctions[currentTime];
+ delete scheduledFunctions[currentTime];
+
+ for (var i = 0; i < funcsToRun.length; ++i) {
+ var funcToRun = funcsToRun[i];
+
+ if (funcToRun.recurring) {
+ reschedule(funcToRun);
+ }
+
+ funcToRun.funcToCall.apply(null, funcToRun.params || []);
+ }
+ } while (scheduledLookup.length > 0 &&
+ // checking first if we're out of time prevents setTimeout(0)
+ // scheduled in a funcToRun from forcing an extra iteration
+ currentTime !== endTime &&
+ scheduledLookup[0] <= endTime);
+ }
+ }
+
+ return DelayedFunctionScheduler;
+};
+
+getJasmineRequireObj().ExceptionFormatter = function() {
+ function ExceptionFormatter() {
+ this.message = function(error) {
+ var message = '';
+
+ if (error.name && error.message) {
+ message += error.name + ': ' + error.message;
+ } else {
+ message += error.toString() + ' thrown';
+ }
+
+ if (error.fileName || error.sourceURL) {
+ message += ' in ' + (error.fileName || error.sourceURL);
+ }
+
+ if (error.line || error.lineNumber) {
+ message += ' (line ' + (error.line || error.lineNumber) + ')';
+ }
+
+ return message;
+ };
+
+ this.stack = function(error) {
+ return error ? error.stack : null;
+ };
+ }
+
+ return ExceptionFormatter;
+};
+
+getJasmineRequireObj().Expectation = function() {
+
+ function Expectation(options) {
+ this.util = options.util || { buildFailureMessage: function() {} };
+ this.customEqualityTesters = options.customEqualityTesters || [];
+ this.actual = options.actual;
+ this.addExpectationResult = options.addExpectationResult || function(){};
+ this.isNot = options.isNot;
+
+ var customMatchers = options.customMatchers || {};
+ for (var matcherName in customMatchers) {
+ this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
+ }
+ }
+
+ Expectation.prototype.wrapCompare = function(name, matcherFactory) {
+ return function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ expected = args.slice(0),
+ message = '';
+
+ args.unshift(this.actual);
+
+ var matcher = matcherFactory(this.util, this.customEqualityTesters),
+ matcherCompare = matcher.compare;
+
+ function defaultNegativeCompare() {
+ var result = matcher.compare.apply(null, args);
+ result.pass = !result.pass;
+ return result;
+ }
+
+ if (this.isNot) {
+ matcherCompare = matcher.negativeCompare || defaultNegativeCompare;
+ }
+
+ var result = matcherCompare.apply(null, args);
+
+ if (!result.pass) {
+ if (!result.message) {
+ args.unshift(this.isNot);
+ args.unshift(name);
+ message = this.util.buildFailureMessage.apply(null, args);
+ } else {
+ if (Object.prototype.toString.apply(result.message) === '[object Function]') {
+ message = result.message();
+ } else {
+ message = result.message;
+ }
+ }
+ }
+
+ if (expected.length == 1) {
+ expected = expected[0];
+ }
+
+ // TODO: how many of these params are needed?
+ this.addExpectationResult(
+ result.pass,
+ {
+ matcherName: name,
+ passed: result.pass,
+ message: message,
+ actual: this.actual,
+ expected: expected // TODO: this may need to be arrayified/sliced
+ }
+ );
+ };
+ };
+
+ Expectation.addCoreMatchers = function(matchers) {
+ var prototype = Expectation.prototype;
+ for (var matcherName in matchers) {
+ var matcher = matchers[matcherName];
+ prototype[matcherName] = prototype.wrapCompare(matcherName, matcher);
+ }
+ };
+
+ Expectation.Factory = function(options) {
+ options = options || {};
+
+ var expect = new Expectation(options);
+
+ // TODO: this would be nice as its own Object - NegativeExpectation
+ // TODO: copy instead of mutate options
+ options.isNot = true;
+ expect.not = new Expectation(options);
+
+ return expect;
+ };
+
+ return Expectation;
+};
+
+//TODO: expectation result may make more sense as a presentation of an expectation.
+getJasmineRequireObj().buildExpectationResult = function() {
+ function buildExpectationResult(options) {
+ var messageFormatter = options.messageFormatter || function() {},
+ stackFormatter = options.stackFormatter || function() {};
+
+ var result = {
+ matcherName: options.matcherName,
+ message: message(),
+ stack: stack(),
+ passed: options.passed
+ };
+
+ if(!result.passed) {
+ result.expected = options.expected;
+ result.actual = options.actual;
+ }
+
+ return result;
+
+ function message() {
+ if (options.passed) {
+ return 'Passed.';
+ } else if (options.message) {
+ return options.message;
+ } else if (options.error) {
+ return messageFormatter(options.error);
+ }
+ return '';
+ }
+
+ function stack() {
+ if (options.passed) {
+ return '';
+ }
+
+ var error = options.error;
+ if (!error) {
+ try {
+ throw new Error(message());
+ } catch (e) {
+ error = e;
+ }
+ }
+ return stackFormatter(error);
+ }
+ }
+
+ return buildExpectationResult;
+};
+
+getJasmineRequireObj().MockDate = function() {
+ function MockDate(global) {
+ var self = this;
+ var currentTime = 0;
+
+ if (!global || !global.Date) {
+ self.install = function() {};
+ self.tick = function() {};
+ self.uninstall = function() {};
+ return self;
+ }
+
+ var GlobalDate = global.Date;
+
+ self.install = function(mockDate) {
+ if (mockDate instanceof GlobalDate) {
+ currentTime = mockDate.getTime();
+ } else {
+ currentTime = new GlobalDate().getTime();
+ }
+
+ global.Date = FakeDate;
+ };
+
+ self.tick = function(millis) {
+ millis = millis || 0;
+ currentTime = currentTime + millis;
+ };
+
+ self.uninstall = function() {
+ currentTime = 0;
+ global.Date = GlobalDate;
+ };
+
+ createDateProperties();
+
+ return self;
+
+ function FakeDate() {
+ switch(arguments.length) {
+ case 0:
+ return new GlobalDate(currentTime);
+ case 1:
+ return new GlobalDate(arguments[0]);
+ case 2:
+ return new GlobalDate(arguments[0], arguments[1]);
+ case 3:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2]);
+ case 4:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]);
+ case 5:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
+ arguments[4]);
+ case 6:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
+ arguments[4], arguments[5]);
+ case 7:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
+ arguments[4], arguments[5], arguments[6]);
+ }
+ }
+
+ function createDateProperties() {
+ FakeDate.prototype = GlobalDate.prototype;
+
+ FakeDate.now = function() {
+ if (GlobalDate.now) {
+ return currentTime;
+ } else {
+ throw new Error('Browser does not support Date.now()');
+ }
+ };
+
+ FakeDate.toSource = GlobalDate.toSource;
+ FakeDate.toString = GlobalDate.toString;
+ FakeDate.parse = GlobalDate.parse;
+ FakeDate.UTC = GlobalDate.UTC;
+ }
+ }
+
+ return MockDate;
+};
+
+getJasmineRequireObj().ObjectContaining = function(j$) {
+
+ function ObjectContaining(sample) {
+ this.sample = sample;
+ }
+
+ ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
+ if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
+
+ mismatchKeys = mismatchKeys || [];
+ mismatchValues = mismatchValues || [];
+
+ var hasKey = function(obj, keyName) {
+ return obj !== null && !j$.util.isUndefined(obj[keyName]);
+ };
+
+ for (var property in this.sample) {
+ if (!hasKey(other, property) && hasKey(this.sample, property)) {
+ mismatchKeys.push('expected has key \'' + property + '\', but missing from actual.');
+ }
+ else if (!j$.matchersUtil.equals(other[property], this.sample[property])) {
+ mismatchValues.push('\'' + property + '\' was \'' + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + '\' in actual, but was \'' + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + '\' in expected.');
+ }
+ }
+
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+ };
+
+ ObjectContaining.prototype.jasmineToString = function() {
+ return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
+ };
+
+ return ObjectContaining;
+};
+
+getJasmineRequireObj().pp = function(j$) {
+
+ function PrettyPrinter() {
+ this.ppNestLevel_ = 0;
+ this.seen = [];
+ }
+
+ PrettyPrinter.prototype.format = function(value) {
+ this.ppNestLevel_++;
+ try {
+ if (j$.util.isUndefined(value)) {
+ this.emitScalar('undefined');
+ } else if (value === null) {
+ this.emitScalar('null');
+ } else if (value === 0 && 1/value === -Infinity) {
+ this.emitScalar('-0');
+ } else if (value === j$.getGlobal()) {
+ this.emitScalar('<global>');
+ } else if (value.jasmineToString) {
+ this.emitScalar(value.jasmineToString());
+ } else if (typeof value === 'string') {
+ this.emitString(value);
+ } else if (j$.isSpy(value)) {
+ this.emitScalar('spy on ' + value.and.identity());
+ } else if (value instanceof RegExp) {
+ this.emitScalar(value.toString());
+ } else if (typeof value === 'function') {
+ this.emitScalar('Function');
+ } else if (typeof value.nodeType === 'number') {
+ this.emitScalar('HTMLNode');
+ } else if (value instanceof Date) {
+ this.emitScalar('Date(' + value + ')');
+ } else if (j$.util.arrayContains(this.seen, value)) {
+ this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
+ } else if (j$.isArray_(value) || j$.isA_('Object', value)) {
+ this.seen.push(value);
+ if (j$.isArray_(value)) {
+ this.emitArray(value);
+ } else {
+ this.emitObject(value);
+ }
+ this.seen.pop();
+ } else {
+ this.emitScalar(value.toString());
+ }
+ } finally {
+ this.ppNestLevel_--;
+ }
+ };
+
+ PrettyPrinter.prototype.iterateObject = function(obj, fn) {
+ for (var property in obj) {
+ if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; }
+ fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) &&
+ obj.__lookupGetter__(property) !== null) : false);
+ }
+ };
+
+ PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;
+ PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;
+ PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;
+ PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;
+
+ function StringPrettyPrinter() {
+ PrettyPrinter.call(this);
+
+ this.string = '';
+ }
+
+ j$.util.inherit(StringPrettyPrinter, PrettyPrinter);
+
+ StringPrettyPrinter.prototype.emitScalar = function(value) {
+ this.append(value);
+ };
+
+ StringPrettyPrinter.prototype.emitString = function(value) {
+ this.append('\'' + value + '\'');
+ };
+
+ StringPrettyPrinter.prototype.emitArray = function(array) {
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
+ this.append('Array');
+ return;
+ }
+ var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
+ this.append('[ ');
+ for (var i = 0; i < length; i++) {
+ if (i > 0) {
+ this.append(', ');
+ }
+ this.format(array[i]);
+ }
+ if(array.length > length){
+ this.append(', ...');
+ }
+ this.append(' ]');
+ };
+
+ StringPrettyPrinter.prototype.emitObject = function(obj) {
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
+ this.append('Object');
+ return;
+ }
+
+ var self = this;
+ this.append('{ ');
+ var first = true;
+
+ this.iterateObject(obj, function(property, isGetter) {
+ if (first) {
+ first = false;
+ } else {
+ self.append(', ');
+ }
+
+ self.append(property);
+ self.append(': ');
+ if (isGetter) {
+ self.append('<getter>');
+ } else {
+ self.format(obj[property]);
+ }
+ });
+
+ this.append(' }');
+ };
+
+ StringPrettyPrinter.prototype.append = function(value) {
+ this.string += value;
+ };
+
+ return function(value) {
+ var stringPrettyPrinter = new StringPrettyPrinter();
+ stringPrettyPrinter.format(value);
+ return stringPrettyPrinter.string;
+ };
+};
+
+getJasmineRequireObj().QueueRunner = function(j$) {
+
+ function once(fn) {
+ var called = false;
+ return function() {
+ if (!called) {
+ called = true;
+ fn();
+ }
+ };
+ }
+
+ function QueueRunner(attrs) {
+ this.queueableFns = attrs.queueableFns || [];
+ this.onComplete = attrs.onComplete || function() {};
+ this.clearStack = attrs.clearStack || function(fn) {fn();};
+ this.onException = attrs.onException || function() {};
+ this.catchException = attrs.catchException || function() { return true; };
+ this.userContext = attrs.userContext || {};
+ this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
+ this.fail = attrs.fail || function() {};
+ }
+
+ QueueRunner.prototype.execute = function() {
+ this.run(this.queueableFns, 0);
+ };
+
+ QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
+ var length = queueableFns.length,
+ self = this,
+ iterativeIndex;
+
+
+ for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
+ var queueableFn = queueableFns[iterativeIndex];
+ if (queueableFn.fn.length > 0) {
+ return attemptAsync(queueableFn);
+ } else {
+ attemptSync(queueableFn);
+ }
+ }
+
+ var runnerDone = iterativeIndex >= length;
+
+ if (runnerDone) {
+ this.clearStack(this.onComplete);
+ }
+
+ function attemptSync(queueableFn) {
+ try {
+ queueableFn.fn.call(self.userContext);
+ } catch (e) {
+ handleException(e, queueableFn);
+ }
+ }
+
+ function attemptAsync(queueableFn) {
+ var clearTimeout = function () {
+ Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]);
+ },
+ next = once(function () {
+ clearTimeout(timeoutId);
+ self.run(queueableFns, iterativeIndex + 1);
+ }),
+ timeoutId;
+
+ next.fail = function() {
+ self.fail.apply(null, arguments);
+ next();
+ };
+
+ if (queueableFn.timeout) {
+ timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
+ var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
+ onException(error, queueableFn);
+ next();
+ }, queueableFn.timeout()]]);
+ }
+
+ try {
+ queueableFn.fn.call(self.userContext, next);
+ } catch (e) {
+ handleException(e, queueableFn);
+ next();
+ }
+ }
+
+ function onException(e, queueableFn) {
+ self.onException(e);
+ }
+
+ function handleException(e, queueableFn) {
+ onException(e, queueableFn);
+ if (!self.catchException(e)) {
+ //TODO: set a var when we catch an exception and
+ //use a finally block to close the loop in a nice way..
+ throw e;
+ }
+ }
+ };
+
+ return QueueRunner;
+};
+
+getJasmineRequireObj().ReportDispatcher = function() {
+ function ReportDispatcher(methods) {
+
+ var dispatchedMethods = methods || [];
+
+ for (var i = 0; i < dispatchedMethods.length; i++) {
+ var method = dispatchedMethods[i];
+ this[method] = (function(m) {
+ return function() {
+ dispatch(m, arguments);
+ };
+ }(method));
+ }
+
+ var reporters = [];
+
+ this.addReporter = function(reporter) {
+ reporters.push(reporter);
+ };
+
+ return this;
+
+ function dispatch(method, args) {
+ for (var i = 0; i < reporters.length; i++) {
+ var reporter = reporters[i];
+ if (reporter[method]) {
+ reporter[method].apply(reporter, args);
+ }
+ }
+ }
+ }
+
+ return ReportDispatcher;
+};
+
+
+getJasmineRequireObj().SpyRegistry = function(j$) {
+
+ function SpyRegistry(options) {
+ options = options || {};
+ var currentSpies = options.currentSpies || function() { return []; };
+
+ this.spyOn = function(obj, methodName) {
+ if (j$.util.isUndefined(obj)) {
+ throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
+ }
+
+ if (j$.util.isUndefined(obj[methodName])) {
+ throw new Error(methodName + '() method does not exist');
+ }
+
+ if (obj[methodName] && j$.isSpy(obj[methodName])) {
+ //TODO?: should this return the current spy? Downside: may cause user confusion about spy state
+ throw new Error(methodName + ' has already been spied upon');
+ }
+
+ var spy = j$.createSpy(methodName, obj[methodName]);
+
+ currentSpies().push({
+ spy: spy,
+ baseObj: obj,
+ methodName: methodName,
+ originalValue: obj[methodName]
+ });
+
+ obj[methodName] = spy;
+
+ return spy;
+ };
+
+ this.clearSpies = function() {
+ var spies = currentSpies();
+ for (var i = 0; i < spies.length; i++) {
+ var spyEntry = spies[i];
+ spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
+ }
+ };
+ }
+
+ return SpyRegistry;
+};
+
+getJasmineRequireObj().SpyStrategy = function() {
+
+ function SpyStrategy(options) {
+ options = options || {};
+
+ var identity = options.name || 'unknown',
+ originalFn = options.fn || function() {},
+ getSpy = options.getSpy || function() {},
+ plan = function() {};
+
+ this.identity = function() {
+ return identity;
+ };
+
+ this.exec = function() {
+ return plan.apply(this, arguments);
+ };
+
+ this.callThrough = function() {
+ plan = originalFn;
+ return getSpy();
+ };
+
+ this.returnValue = function(value) {
+ plan = function() {
+ return value;
+ };
+ return getSpy();
+ };
+
+ this.returnValues = function() {
+ var values = Array.prototype.slice.call(arguments);
+ plan = function () {
+ return values.shift();
+ };
+ return getSpy();
+ };
+
+ this.throwError = function(something) {
+ var error = (something instanceof Error) ? something : new Error(something);
+ plan = function() {
+ throw error;
+ };
+ return getSpy();
+ };
+
+ this.callFake = function(fn) {
+ plan = fn;
+ return getSpy();
+ };
+
+ this.stub = function(fn) {
+ plan = function() {};
+ return getSpy();
+ };
+ }
+
+ return SpyStrategy;
+};
+
+getJasmineRequireObj().Suite = function() {
+ function Suite(attrs) {
+ this.env = attrs.env;
+ this.id = attrs.id;
+ this.parentSuite = attrs.parentSuite;
+ this.description = attrs.description;
+ this.onStart = attrs.onStart || function() {};
+ this.resultCallback = attrs.resultCallback || function() {};
+ this.clearStack = attrs.clearStack || function(fn) {fn();};
+ this.expectationFactory = attrs.expectationFactory;
+ this.expectationResultFactory = attrs.expectationResultFactory;
+
+ this.beforeFns = [];
+ this.afterFns = [];
+ this.beforeAllFns = [];
+ this.afterAllFns = [];
+ this.queueRunner = attrs.queueRunner || function() {};
+ this.disabled = false;
+
+ this.children = [];
+
+ this.result = {
+ id: this.id,
+ description: this.description,
+ fullName: this.getFullName(),
+ failedExpectations: []
+ };
+ }
+
+ Suite.prototype.expect = function(actual) {
+ return this.expectationFactory(actual, this);
+ };
+
+ Suite.prototype.getFullName = function() {
+ var fullName = this.description;
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
+ if (parentSuite.parentSuite) {
+ fullName = parentSuite.description + ' ' + fullName;
+ }
+ }
+ return fullName;
+ };
+
+ Suite.prototype.disable = function() {
+ this.disabled = true;
+ };
+
+ Suite.prototype.beforeEach = function(fn) {
+ this.beforeFns.unshift(fn);
+ };
+
+ Suite.prototype.beforeAll = function(fn) {
+ this.beforeAllFns.push(fn);
+ };
+
+ Suite.prototype.afterEach = function(fn) {
+ this.afterFns.unshift(fn);
+ };
+
+ Suite.prototype.afterAll = function(fn) {
+ this.afterAllFns.push(fn);
+ };
+
+ Suite.prototype.addChild = function(child) {
+ this.children.push(child);
+ };
+
+ Suite.prototype.status = function() {
+ if (this.disabled) {
+ return 'disabled';
+ }
+
+ if (this.result.failedExpectations.length > 0) {
+ return 'failed';
+ } else {
+ return 'finished';
+ }
+ };
+
+ Suite.prototype.execute = function(onComplete) {
+ var self = this;
+
+ this.onStart(this);
+
+ if (this.disabled) {
+ complete();
+ return;
+ }
+
+ var allFns = [];
+
+ for (var i = 0; i < this.children.length; i++) {
+ allFns.push(wrapChildAsAsync(this.children[i]));
+ }
+
+ if (this.isExecutable()) {
+ allFns = this.beforeAllFns.concat(allFns);
+ allFns = allFns.concat(this.afterAllFns);
+ }
+
+ this.queueRunner({
+ queueableFns: allFns,
+ onComplete: complete,
+ userContext: this.sharedUserContext(),
+ onException: function() { self.onException.apply(self, arguments); }
+ });
+
+ function complete() {
+ self.result.status = self.status();
+ self.resultCallback(self.result);
+
+ if (onComplete) {
+ onComplete();
+ }
+ }
+
+ function wrapChildAsAsync(child) {
+ return { fn: function(done) { child.execute(done); } };
+ }
+ };
+
+ Suite.prototype.isExecutable = function() {
+ var foundActive = false;
+ for(var i = 0; i < this.children.length; i++) {
+ if(this.children[i].isExecutable()) {
+ foundActive = true;
+ break;
+ }
+ }
+ return foundActive;
+ };
+
+ Suite.prototype.sharedUserContext = function() {
+ if (!this.sharedContext) {
+ this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {};
+ }
+
+ return this.sharedContext;
+ };
+
+ Suite.prototype.clonedSharedUserContext = function() {
+ return clone(this.sharedUserContext());
+ };
+
+ Suite.prototype.onException = function() {
+ if(isAfterAll(this.children)) {
+ var data = {
+ matcherName: '',
+ passed: false,
+ expected: '',
+ actual: '',
+ error: arguments[0]
+ };
+ this.result.failedExpectations.push(this.expectationResultFactory(data));
+ } else {
+ for (var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ child.onException.apply(child, arguments);
+ }
+ }
+ };
+
+ Suite.prototype.addExpectationResult = function () {
+ if(isAfterAll(this.children) && isFailure(arguments)){
+ var data = arguments[1];
+ this.result.failedExpectations.push(this.expectationResultFactory(data));
+ } else {
+ for (var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ child.addExpectationResult.apply(child, arguments);
+ }
+ }
+ };
+
+ function isAfterAll(children) {
+ return children && children[0].result.status;
+ }
+
+ function isFailure(args) {
+ return !args[0];
+ }
+
+ function clone(obj) {
+ var clonedObj = {};
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ clonedObj[prop] = obj[prop];
+ }
+ }
+
+ return clonedObj;
+ }
+
+ return Suite;
+};
+
+if (typeof window == void 0 && typeof exports == 'object') {
+ exports.Suite = jasmineRequire.Suite;
+}
+
+getJasmineRequireObj().Timer = function() {
+ var defaultNow = (function(Date) {
+ return function() { return new Date().getTime(); };
+ })(Date);
+
+ function Timer(options) {
+ options = options || {};
+
+ var now = options.now || defaultNow,
+ startTime;
+
+ this.start = function() {
+ startTime = now();
+ };
+
+ this.elapsed = function() {
+ return now() - startTime;
+ };
+ }
+
+ return Timer;
+};
+
+getJasmineRequireObj().matchersUtil = function(j$) {
+ // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
+
+ return {
+ equals: function(a, b, customTesters) {
+ customTesters = customTesters || [];
+
+ return eq(a, b, [], [], customTesters);
+ },
+
+ contains: function(haystack, needle, customTesters) {
+ customTesters = customTesters || [];
+
+ if ((Object.prototype.toString.apply(haystack) === '[object Array]') ||
+ (!!haystack && !haystack.indexOf))
+ {
+ for (var i = 0; i < haystack.length; i++) {
+ if (eq(haystack[i], needle, [], [], customTesters)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return !!haystack && haystack.indexOf(needle) >= 0;
+ },
+
+ buildFailureMessage: function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ matcherName = args[0],
+ isNot = args[1],
+ actual = args[2],
+ expected = args.slice(3),
+ englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
+
+ var message = 'Expected ' +
+ j$.pp(actual) +
+ (isNot ? ' not ' : ' ') +
+ englishyPredicate;
+
+ if (expected.length > 0) {
+ for (var i = 0; i < expected.length; i++) {
+ if (i > 0) {
+ message += ',';
+ }
+ message += ' ' + j$.pp(expected[i]);
+ }
+ }
+
+ return message + '.';
+ }
+ };
+
+ // Equality function lovingly adapted from isEqual in
+ // [Underscore](http://underscorejs.org)
+ function eq(a, b, aStack, bStack, customTesters) {
+ var result = true;
+
+ for (var i = 0; i < customTesters.length; i++) {
+ var customTesterResult = customTesters[i](a, b);
+ if (!j$.util.isUndefined(customTesterResult)) {
+ return customTesterResult;
+ }
+ }
+
+ if (a instanceof j$.Any) {
+ result = a.jasmineMatches(b);
+ if (result) {
+ return true;
+ }
+ }
+
+ if (b instanceof j$.Any) {
+ result = b.jasmineMatches(a);
+ if (result) {
+ return true;
+ }
+ }
+
+ if (b instanceof j$.ObjectContaining) {
+ result = b.jasmineMatches(a);
+ if (result) {
+ return true;
+ }
+ }
+
+ if (a instanceof Error && b instanceof Error) {
+ return a.message == b.message;
+ }
+
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) { return a !== 0 || 1 / a == 1 / b; }
+ // A strict comparison is necessary because `null == undefined`.
+ if (a === null || b === null) { return a === b; }
+ var className = Object.prototype.toString.call(a);
+ if (className != Object.prototype.toString.call(b)) { return false; }
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') { return false; }
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] == a) { return bStack[length] == b; }
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size = 0;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ if (!(result = eq(a[size], b[size], aStack, bStack, customTesters))) { break; }
+ }
+ }
+ } else {
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) &&
+ isFunction(bCtor) && (bCtor instanceof bCtor))) {
+ return false;
+ }
+ // Deep compare objects.
+ for (var key in a) {
+ if (has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; }
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (has(b, key) && !(size--)) { break; }
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+
+ return result;
+
+ function has(obj, key) {
+ return obj.hasOwnProperty(key);
+ }
+
+ function isFunction(obj) {
+ return typeof obj === 'function';
+ }
+ }
+};
+
+getJasmineRequireObj().toBe = function() {
+ function toBe() {
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: actual === expected
+ };
+ }
+ };
+ }
+
+ return toBe;
+};
+
+getJasmineRequireObj().toBeCloseTo = function() {
+
+ function toBeCloseTo() {
+ return {
+ compare: function(actual, expected, precision) {
+ if (precision !== 0) {
+ precision = precision || 2;
+ }
+
+ return {
+ pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2)
+ };
+ }
+ };
+ }
+
+ return toBeCloseTo;
+};
+
+getJasmineRequireObj().toBeDefined = function() {
+ function toBeDefined() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: (void 0 !== actual)
+ };
+ }
+ };
+ }
+
+ return toBeDefined;
+};
+
+getJasmineRequireObj().toBeFalsy = function() {
+ function toBeFalsy() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: !!!actual
+ };
+ }
+ };
+ }
+
+ return toBeFalsy;
+};
+
+getJasmineRequireObj().toBeGreaterThan = function() {
+
+ function toBeGreaterThan() {
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: actual > expected
+ };
+ }
+ };
+ }
+
+ return toBeGreaterThan;
+};
+
+
+getJasmineRequireObj().toBeLessThan = function() {
+ function toBeLessThan() {
+ return {
+
+ compare: function(actual, expected) {
+ return {
+ pass: actual < expected
+ };
+ }
+ };
+ }
+
+ return toBeLessThan;
+};
+getJasmineRequireObj().toBeNaN = function(j$) {
+
+ function toBeNaN() {
+ return {
+ compare: function(actual) {
+ var result = {
+ pass: (actual !== actual)
+ };
+
+ if (result.pass) {
+ result.message = 'Expected actual not to be NaN.';
+ } else {
+ result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toBeNaN;
+};
+
+getJasmineRequireObj().toBeNull = function() {
+
+ function toBeNull() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: actual === null
+ };
+ }
+ };
+ }
+
+ return toBeNull;
+};
+
+getJasmineRequireObj().toBeTruthy = function() {
+
+ function toBeTruthy() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: !!actual
+ };
+ }
+ };
+ }
+
+ return toBeTruthy;
+};
+
+getJasmineRequireObj().toBeUndefined = function() {
+
+ function toBeUndefined() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: void 0 === actual
+ };
+ }
+ };
+ }
+
+ return toBeUndefined;
+};
+
+getJasmineRequireObj().toContain = function() {
+ function toContain(util, customEqualityTesters) {
+ customEqualityTesters = customEqualityTesters || [];
+
+ return {
+ compare: function(actual, expected) {
+
+ return {
+ pass: util.contains(actual, expected, customEqualityTesters)
+ };
+ }
+ };
+ }
+
+ return toContain;
+};
+
+getJasmineRequireObj().toEqual = function() {
+
+ function toEqual(util, customEqualityTesters) {
+ customEqualityTesters = customEqualityTesters || [];
+
+ return {
+ compare: function(actual, expected) {
+ var result = {
+ pass: false
+ };
+
+ result.pass = util.equals(actual, expected, customEqualityTesters);
+
+ return result;
+ }
+ };
+ }
+
+ return toEqual;
+};
+
+getJasmineRequireObj().toHaveBeenCalled = function(j$) {
+
+ function toHaveBeenCalled() {
+ return {
+ compare: function(actual) {
+ var result = {};
+
+ if (!j$.isSpy(actual)) {
+ throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
+ }
+
+ if (arguments.length > 1) {
+ throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
+ }
+
+ result.pass = actual.calls.any();
+
+ result.message = result.pass ?
+ 'Expected spy ' + actual.and.identity() + ' not to have been called.' :
+ 'Expected spy ' + actual.and.identity() + ' to have been called.';
+
+ return result;
+ }
+ };
+ }
+
+ return toHaveBeenCalled;
+};
+
+getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
+
+ function toHaveBeenCalledWith(util, customEqualityTesters) {
+ return {
+ compare: function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ actual = args[0],
+ expectedArgs = args.slice(1),
+ result = { pass: false };
+
+ if (!j$.isSpy(actual)) {
+ throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
+ }
+
+ if (!actual.calls.any()) {
+ result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; };
+ return result;
+ }
+
+ if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) {
+ result.pass = true;
+ result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; };
+ } else {
+ result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toHaveBeenCalledWith;
+};
+
+getJasmineRequireObj().toMatch = function() {
+
+ function toMatch() {
+ return {
+ compare: function(actual, expected) {
+ var regexp = new RegExp(expected);
+
+ return {
+ pass: regexp.test(actual)
+ };
+ }
+ };
+ }
+
+ return toMatch;
+};
+
+getJasmineRequireObj().toThrow = function(j$) {
+
+ function toThrow(util) {
+ return {
+ compare: function(actual, expected) {
+ var result = { pass: false },
+ threw = false,
+ thrown;
+
+ if (typeof actual != 'function') {
+ throw new Error('Actual is not a Function');
+ }
+
+ try {
+ actual();
+ } catch (e) {
+ threw = true;
+ thrown = e;
+ }
+
+ if (!threw) {
+ result.message = 'Expected function to throw an exception.';
+ return result;
+ }
+
+ if (arguments.length == 1) {
+ result.pass = true;
+ result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; };
+
+ return result;
+ }
+
+ if (util.equals(thrown, expected)) {
+ result.pass = true;
+ result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; };
+ } else {
+ result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toThrow;
+};
+
+getJasmineRequireObj().toThrowError = function(j$) {
+ function toThrowError (util) {
+ return {
+ compare: function(actual) {
+ var threw = false,
+ pass = {pass: true},
+ fail = {pass: false},
+ thrown;
+
+ if (typeof actual != 'function') {
+ throw new Error('Actual is not a Function');
+ }
+
+ var errorMatcher = getMatcher.apply(null, arguments);
+
+ try {
+ actual();
+ } catch (e) {
+ threw = true;
+ thrown = e;
+ }
+
+ if (!threw) {
+ fail.message = 'Expected function to throw an Error.';
+ return fail;
+ }
+
+ if (!(thrown instanceof Error)) {
+ fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; };
+ return fail;
+ }
+
+ if (errorMatcher.hasNoSpecifics()) {
+ pass.message = 'Expected function not to throw an Error, but it threw ' + fnNameFor(thrown) + '.';
+ return pass;
+ }
+
+ if (errorMatcher.matches(thrown)) {
+ pass.message = function() {
+ return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.';
+ };
+ return pass;
+ } else {
+ fail.message = function() {
+ return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() +
+ ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.';
+ };
+ return fail;
+ }
+ }
+ };
+
+ function getMatcher() {
+ var expected = null,
+ errorType = null;
+
+ if (arguments.length == 2) {
+ expected = arguments[1];
+ if (isAnErrorType(expected)) {
+ errorType = expected;
+ expected = null;
+ }
+ } else if (arguments.length > 2) {
+ errorType = arguments[1];
+ expected = arguments[2];
+ if (!isAnErrorType(errorType)) {
+ throw new Error('Expected error type is not an Error.');
+ }
+ }
+
+ if (expected && !isStringOrRegExp(expected)) {
+ if (errorType) {
+ throw new Error('Expected error message is not a string or RegExp.');
+ } else {
+ throw new Error('Expected is not an Error, string, or RegExp.');
+ }
+ }
+
+ function messageMatch(message) {
+ if (typeof expected == 'string') {
+ return expected == message;
+ } else {
+ return expected.test(message);
+ }
+ }
+
+ return {
+ errorTypeDescription: errorType ? fnNameFor(errorType) : 'an exception',
+ thrownDescription: function(thrown) {
+ var thrownName = errorType ? fnNameFor(thrown.constructor) : 'an exception',
+ thrownMessage = '';
+
+ if (expected) {
+ thrownMessage = ' with message ' + j$.pp(thrown.message);
+ }
+
+ return thrownName + thrownMessage;
+ },
+ messageDescription: function() {
+ if (expected === null) {
+ return '';
+ } else if (expected instanceof RegExp) {
+ return ' with a message matching ' + j$.pp(expected);
+ } else {
+ return ' with message ' + j$.pp(expected);
+ }
+ },
+ hasNoSpecifics: function() {
+ return expected === null && errorType === null;
+ },
+ matches: function(error) {
+ return (errorType === null || error.constructor === errorType) &&
+ (expected === null || messageMatch(error.message));
+ }
+ };
+ }
+
+ function fnNameFor(func) {
+ return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
+ }
+
+ function isStringOrRegExp(potential) {
+ return potential instanceof RegExp || (typeof potential == 'string');
+ }
+
+ function isAnErrorType(type) {
+ if (typeof type !== 'function') {
+ return false;
+ }
+
+ var Surrogate = function() {};
+ Surrogate.prototype = type.prototype;
+ return (new Surrogate()) instanceof Error;
+ }
+ }
+
+ return toThrowError;
+};
+
+getJasmineRequireObj().interface = function(jasmine, env) {
+ var jasmineInterface = {
+ describe: function(description, specDefinitions) {
+ return env.describe(description, specDefinitions);
+ },
+
+ xdescribe: function(description, specDefinitions) {
+ return env.xdescribe(description, specDefinitions);
+ },
+
+ fdescribe: function(description, specDefinitions) {
+ return env.fdescribe(description, specDefinitions);
+ },
+
+ it: function(desc, func) {
+ return env.it(desc, func);
+ },
+
+ xit: function(desc, func) {
+ return env.xit(desc, func);
+ },
+
+ fit: function(desc, func) {
+ return env.fit(desc, func);
+ },
+
+ beforeEach: function(beforeEachFunction) {
+ return env.beforeEach(beforeEachFunction);
+ },
+
+ afterEach: function(afterEachFunction) {
+ return env.afterEach(afterEachFunction);
+ },
+
+ beforeAll: function(beforeAllFunction) {
+ return env.beforeAll(beforeAllFunction);
+ },
+
+ afterAll: function(afterAllFunction) {
+ return env.afterAll(afterAllFunction);
+ },
+
+ expect: function(actual) {
+ return env.expect(actual);
+ },
+
+ pending: function() {
+ return env.pending();
+ },
+
+ fail: function() {
+ return env.fail.apply(env, arguments);
+ },
+
+ spyOn: function(obj, methodName) {
+ return env.spyOn(obj, methodName);
+ },
+
+ jsApiReporter: new jasmine.JsApiReporter({
+ timer: new jasmine.Timer()
+ }),
+
+ jasmine: jasmine
+ };
+
+ jasmine.addCustomEqualityTester = function(tester) {
+ env.addCustomEqualityTester(tester);
+ };
+
+ jasmine.addMatchers = function(matchers) {
+ return env.addMatchers(matchers);
+ };
+
+ jasmine.clock = function() {
+ return env.clock;
+ };
+
+ return jasmineInterface;
+};
+
+getJasmineRequireObj().version = function() {
+ return '2.1.3';
+};
diff --git a/big-integer/spec/lib/jasmine-2.1.3/jasmine_favicon.png b/big-integer/spec/lib/jasmine-2.1.3/jasmine_favicon.png
new file mode 100644
index 0000000..3b84583
--- /dev/null
+++ b/big-integer/spec/lib/jasmine-2.1.3/jasmine_favicon.png
Binary files differ
diff --git a/big-integer/spec/spec.js b/big-integer/spec/spec.js
new file mode 100644
index 0000000..4d01dd8
--- /dev/null
+++ b/big-integer/spec/spec.js
@@ -0,0 +1,1234 @@
+if (typeof require === "function") bigInt = require("../BigInteger.js");
+
+describe("BigInteger", function () {
+
+ var a = "1234567890",
+ b = a + a + a + a + a + a + a + a + a + a,
+ c = b + b + b + b + b + b + b + b + b + b,
+ d = c + c + c + c + c + c + c + c + c + c,
+ e = d + d + d;
+
+ beforeAll(function () {
+ jasmine.addMatchers({
+ toEqualBigInt: function () {
+ return {
+ compare: function (actual, expected) {
+ return { pass: bigInt(actual).equals(expected) };
+ }
+ };
+ }
+ });
+ });
+
+ it("can handle large numbers", function () {
+ var tenFactorial = "3628800",
+ hundredFactorial = "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000",
+ threeToTenThousand = "16313501853426258743032567291811547168121324535825379939348203261918257308143190787480155630847848309673252045223235795433405582999177203852381479145368112501453192355166224391025423628843556686559659645012014177448275529990373274425446425751235537341867387607813619937225616872862016504805593174059909520461668500663118926911571773452255850626968526251879139867085080472539640933730243410152186914328917354576854457274195562218013337745628502470673059426999114202540773175988199842487276183685299388927825296786440252999444785694183675323521704432195785806270123388382931770198990841300861506996108944782065015163410344894945809337689156807686673462563038164792190665340124344133980763205594364754963451564072340502606377790585114123814919001637177034457385019939060232925194471114235892978565322415628344142184842892083466227875760501276009801530703037525839157893875741192497705300469691062454369926795975456340236777734354667139072601574969834312769653557184396147587071260443947944862235744459711204473062937764153770030210332183635531818173456618022745975055313212598514429587545547296534609597194836036546870491771927625214352957503454948403635822345728774885175809500158451837389413798095329711993092101417428406774326126450005467888736546254948658602484494535938888656542746977424368385335496083164921318601934977025095780370104307980276356857350349205866078371806065542393536101673402017980951598946980664330391505845803674248348878071010412918667335823849899623486215050304052577789848512410263834811719236949311423411823585316405085306164936671137456985394285677324771775046050970865520893596151687017153855755197348199659070192954771308347627111052471134476325986362838585959552209645382089055182871854866744633737533217524880118401787595094060855717010144087136495532418544241489437080074716158404895914136451802032446707961058757633345691696743293869623745410870051851590672859347061212573446572045088465460616826082579731686004585218284333452396157730036306379421822435818001505905203918209206969662326706952623512427380240468784114535101496733983401240219840048956733689309620321613793757156727562461651933397540266795963865921590913322060572673349849253303397874242381960775337182730037783698708748781738419747698880321601186310506332869704931303076839444790968339306301273371014087248060946851793697973114432706759288546077622831002526800554849696867710280945946603669593797354642136622231192695027321229511912952940320879763123151760555959496961163141455688278842949587288399100273691880018774147568892650186152065335219113072582417699616901995530249937735219099786758954892534365835235843156112799728164123461219817343904782402517111603206575330527850752564642995318064985900815557979945885931124351303252811255254295797082281946658798705979077492469849644183166585950844953164726896146168297808178398470451561320526180542310840744843107469368959707726836608471817060598771730170755446473440774031371227437651048421606224757527085958515947273151027400662948161111284777828103531499488913672800783167888051177155427285103861736658069404797695900758820465238673970882660162285107599221418743657006872537842677883708807515850397691812433880561772652364847297019508025848964833883225165668986935081274596293983121864046277268590401580209059988500511262470167150495261908136688693861324081559046336288963037090312033522400722360882494928182809075406914319957044927504420797278117837677431446979085756432990753582588102440240611039084516401089948868433353748444104639734074519165067632941419347985624435567342072815910754484123812917487312938280670403228188813003978384081332242484646571417574404852962675165616101527367425654869508712001788393846171780457455963045764943565964887518396481296159902471996735508854292964536796779404377230965723361625182030798297734785854606060323419091646711138678490928840107449923456834763763114226000770316931243666699425694828181155048843161380832067845480569758457751090640996007242018255400627276908188082601795520167054701327802366989747082835481105543878446889896230696091881643547476154998574015907396059478684978574180486798918438643164618541351689258379042326487669479733384712996754251703808037828636599654447727795924596382283226723503386540591321268603222892807562509801015765174359627788357881606366119032951829868274617539946921221330284257027058653162292482686679275266764009881985590648534544939224296689791195355783205968492422636277656735338488299104238060289209390654467316291591219712866052661347026855261289381236881063068219249064767086495184176816629077103667131505064964190910450196502178972477361881300608688593782509793781457170396897496908861893034634895715117114601514654381347139092345833472226493656930996045016355808162984965203661519182202145414866559662218796964329217241498105206552200001";
+ function factorial(n) {
+ if (n.equals(bigInt.zero) || n.equals(bigInt.one)) {
+ return bigInt.one;
+ }
+ return factorial(n.prev()).times(n);
+ }
+ expect(factorial(bigInt(10))).toEqualBigInt(tenFactorial);
+ expect(factorial(bigInt(100))).toEqualBigInt(hundredFactorial);
+ expect(bigInt(3).pow(10000)).toEqualBigInt(threeToTenThousand);
+ });
+
+ // See issue #7
+ // https://github.com/peterolson/BigInteger.js/issues/7
+ it("is immutable", function () {
+ var n = bigInt(14930352);
+ n.add(9227465);
+ expect(n).toEqualBigInt(14930352);
+ n.subtract(123456);
+ expect(n).toEqualBigInt(14930352);
+ });
+
+ describe("Equality and comparison", function () {
+ it("works for positive numbers", function () {
+ expect(bigInt.one).toEqualBigInt(1);
+ expect(1).not.toEqualBigInt(2);
+ expect(0).not.toEqualBigInt(1);
+ expect(987).toEqualBigInt(987);
+ expect(987).not.toEqualBigInt(789);
+ expect(7895).not.toEqualBigInt(9875);
+ expect("98765432101234567890").toEqualBigInt("98765432101234567890");
+ expect("98765432101234567890").not.toEqualBigInt("98765432101234567999");
+ expect("98765432101234567890").not.toEqualBigInt("98765432101234567000");
+
+ expect(bigInt(54).greater(45)).toBe(true);
+ expect(bigInt(45).greater(54)).toBe(false);
+ expect(bigInt(45).greater(45)).toBe(false);
+ expect(bigInt("5498765432109876").greater("4598765432109876")).toBe(true);
+ expect(bigInt("4598765432109876").greater("5498765432109876")).toBe(false);
+ expect(bigInt("4598765432109876").greater("4598765432109876")).toBe(false);
+
+ expect(bigInt(32).greaterOrEquals(23)).toBe(true);
+ expect(bigInt(23).greaterOrEquals(32)).toBe(false);
+ expect(bigInt(23).greaterOrEquals(23)).toBe(true);
+ expect(bigInt("3298763232109876").greaterOrEquals("2398763232109876")).toBe(true);
+ expect(bigInt("2398763232109876").greaterOrEquals("3298763232109876")).toBe(false);
+ expect(bigInt("2398763232109876").greaterOrEquals("2398763232109876")).toBe(true);
+
+ expect(bigInt(987).lesser(789)).toBe(false);
+ expect(bigInt(789).lesser(987)).toBe(true);
+ expect(bigInt(789).lesser(789)).toBe(false);
+ expect(bigInt("987987698732109876").lesser("789987698732109876")).toBe(false);
+ expect(bigInt("789987698732109876").lesser("987987698732109876")).toBe(true);
+ expect(bigInt("789987698732109876").lesser("789987698732109876")).toBe(false);
+
+ expect(bigInt(6012).lesserOrEquals(1195)).toBe(false);
+ expect(bigInt(1195).lesserOrEquals(6012)).toBe(true);
+ expect(bigInt(1195).lesserOrEquals(1195)).toBe(true);
+ expect(bigInt("6012987660126012109876").lesserOrEquals("1195987660126012109876")).toBe(false);
+ expect(bigInt("1195987660126012109876").lesserOrEquals("6012987660126012109876")).toBe(true);
+ expect(bigInt("1195987660126012109876").lesserOrEquals("1195987660126012109876")).toBe(true);
+
+ expect(bigInt(54).notEquals(45)).toBe(true);
+ expect(bigInt(45).notEquals(54)).toBe(true);
+ expect(bigInt(45).notEquals(45)).toBe(false);
+ expect(bigInt("5498765432109876").notEquals("4598765432109876")).toBe(true);
+ expect(bigInt("4598765432109876").notEquals("5498765432109876")).toBe(true);
+ expect(bigInt("4598765432109876").notEquals("4598765432109876")).toBe(false);
+
+ expect(bigInt("306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000")).toEqualBigInt("306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000");
+ expect(bigInt("234345345345")).toEqualBigInt("234345345345");
+ expect(bigInt("1230000000")).toEqualBigInt("1230000000");
+ });
+
+ it("works for negative numbers", function () {
+ expect(bigInt.minusOne).toEqualBigInt(-1);
+ expect(-1).not.toEqualBigInt(-2);
+ expect(-0).not.toEqualBigInt(-1);
+ expect(-987).toEqualBigInt(-987);
+ expect(-987).not.toEqualBigInt(-789);
+ expect(-7895).not.toEqualBigInt(-9875);
+ expect("-98765432101234567890").toEqualBigInt("-98765432101234567890");
+ expect("-98765432101234567890").not.toEqualBigInt("-98765432101234567999");
+ expect("-98765432101234567890").not.toEqualBigInt("-98765432101234567000");
+
+ expect(bigInt(-54).greater(-45)).toBe(false);
+ expect(bigInt(-45).greater(-54)).toBe(true);
+ expect(bigInt(-45).greater(-45)).toBe(false);
+ expect(bigInt(45).greater("-549876540654065065132109876")).toBe(true);
+ expect(bigInt(-45).greater("-549876540654065065132109876")).toBe(true);
+ expect(bigInt(45).greater("549876540654065065132109876")).toBe(false);
+ expect(bigInt(-45).greater("549876540654065065132109876")).toBe(false);
+ expect(bigInt("-5498765432109876").greater("-4598765432109876")).toBe(false);
+ expect(bigInt("-4598765432109876").greater("-5498765432109876")).toBe(true);
+ expect(bigInt("-4598765432109876").greater("-4598765432109876")).toBe(false);
+
+ expect(bigInt(-32).greaterOrEquals(-23)).toBe(false);
+ expect(bigInt(-23).greaterOrEquals(-32)).toBe(true);
+ expect(bigInt(-23).greaterOrEquals(-23)).toBe(true);
+ expect(bigInt("-3298763232109876").greaterOrEquals("-2398763232109876")).toBe(false);
+ expect(bigInt("-2398763232109876").greaterOrEquals("-3298763232109876")).toBe(true);
+ expect(bigInt("-2398763232109876").greaterOrEquals("-2398763232109876")).toBe(true);
+
+ expect(bigInt(-987).lesser(-789)).toBe(true);
+ expect(bigInt(-789).lesser(-987)).toBe(false);
+ expect(bigInt(-789).lesser(-789)).toBe(false);
+ expect(bigInt("-987987698732109876").lesser(82)).toBe(true);
+ expect(bigInt("-987987698732109876").lesser(-82)).toBe(true);
+ expect(bigInt("-987987698732109876").lesser("-789987698732109876")).toBe(true);
+ expect(bigInt("-789987698732109876").lesser("-987987698732109876")).toBe(false);
+ expect(bigInt("-789987698732109876").lesser("-789987698732109876")).toBe(false);
+
+ expect(bigInt(-6012).lesserOrEquals(-1195)).toBe(true);
+ expect(bigInt(-1195).lesserOrEquals(-6012)).toBe(false);
+ expect(bigInt(-1195).lesserOrEquals(-1195)).toBe(true);
+ expect(bigInt("-6012987660126012109876").lesserOrEquals("-1195987660126012109876")).toBe(true);
+ expect(bigInt("-1195987660126012109876").lesserOrEquals("-6012987660126012109876")).toBe(false);
+ expect(bigInt("-1195987660126012109876").lesserOrEquals("-1195987660126012109876")).toBe(true);
+
+ expect(bigInt(-54).notEquals(-45)).toBe(true);
+ expect(bigInt(-45).notEquals(-54)).toBe(true);
+ expect(bigInt(-45).notEquals(-45)).toBe(false);
+ expect(bigInt("-5498765432109876").notEquals("-4598765432109876")).toBe(true);
+ expect(bigInt("-4598765432109876").notEquals("-5498765432109876")).toBe(true);
+ expect(bigInt("-4598765432109876").notEquals("-4598765432109876")).toBe(false);
+
+ expect(bigInt("-1")).toEqualBigInt("-1");
+ expect(bigInt("-10000000000000000")).toEqualBigInt("-10000000000000000");
+ });
+
+ it("treats negative and positive numbers differently", function () {
+ expect(54).not.toEqualBigInt(-54);
+ expect("-123456789876543210").not.toEqualBigInt("123456789876543210");
+ expect(bigInt(76).notEquals(-76)).toBe(true);
+
+ expect(bigInt(2).greater(-2)).toBe(true);
+ expect(bigInt(-2).greater(2)).toBe(false);
+ expect(bigInt(2).greater(-3)).toBe(true);
+ expect(bigInt(2).greater(-1)).toBe(true);
+ expect(bigInt(-2).greater(3)).toBe(false);
+ expect(bigInt(-2).greater(1)).toBe(false);
+
+ expect(bigInt(2).greaterOrEquals(-2)).toBe(true);
+ expect(bigInt(-2).greaterOrEquals(2)).toBe(false);
+ expect(bigInt(2).greaterOrEquals(-3)).toBe(true);
+ expect(bigInt(2).greaterOrEquals(-1)).toBe(true);
+ expect(bigInt(-2).greaterOrEquals(3)).toBe(false);
+ expect(bigInt(-2).greaterOrEquals(1)).toBe(false);
+
+ expect(bigInt(2).lesser(-2)).toBe(false);
+ expect(bigInt(-2).lesser(2)).toBe(true);
+ expect(bigInt(2).lesser(-3)).toBe(false);
+ expect(bigInt(2).lesser(-1)).toBe(false);
+ expect(bigInt(-2).lesser(3)).toBe(true);
+ expect(bigInt(-2).lesser(1)).toBe(true);
+
+ expect(bigInt(2).lesserOrEquals(-2)).toBe(false);
+ expect(bigInt(-2).lesserOrEquals(2)).toBe(true);
+ expect(bigInt(2).lesserOrEquals(-3)).toBe(false);
+ expect(bigInt(2).lesserOrEquals(-1)).toBe(false);
+ expect(bigInt(-2).lesserOrEquals(3)).toBe(true);
+ expect(bigInt(-2).lesserOrEquals(1)).toBe(true);
+ });
+
+ it("compareAbs treats negative and positive numbers the same", function () {
+ expect(bigInt(0).compareAbs(36)).toBe(-1);
+ expect(bigInt(0).compareAbs(-36)).toBe(-1);
+ expect(bigInt(36).compareAbs(5)).toBe(1);
+ expect(bigInt(36).compareAbs(-5)).toBe(1);
+ expect(bigInt(-36).compareAbs(5)).toBe(1);
+ expect(bigInt(-36).compareAbs(-5)).toBe(1);
+ expect(bigInt(5).compareAbs(36)).toBe(-1);
+ expect(bigInt(5).compareAbs(-36)).toBe(-1);
+ expect(bigInt(-5).compareAbs(36)).toBe(-1);
+ expect(bigInt(-5).compareAbs(-36)).toBe(-1);
+ expect(bigInt(36).compareAbs(36)).toBe(0);
+ expect(bigInt(36).compareAbs(-36)).toBe(0);
+ expect(bigInt(-36).compareAbs(36)).toBe(0);
+ expect(bigInt(-36).compareAbs(-36)).toBe(0);
+
+ expect(bigInt(0).compareAbs("9999999999999999999")).toBe(-1);
+ expect(bigInt(0).compareAbs("-9999999999999999999")).toBe(-1);
+ expect(bigInt("9999999999999999999").compareAbs("55555555555555555")).toBe(1);
+ expect(bigInt("9999999999999999999").compareAbs("-55555555555555555")).toBe(1);
+ expect(bigInt("-9999999999999999999").compareAbs("55555555555555555")).toBe(1);
+ expect(bigInt("-9999999999999999999").compareAbs("-55555555555555555")).toBe(1);
+ expect(bigInt("55555555555555555").compareAbs("9999999999999999999")).toBe(-1);
+ expect(bigInt("55555555555555555").compareAbs("-9999999999999999999")).toBe(-1);
+ expect(bigInt("-55555555555555555").compareAbs("9999999999999999999")).toBe(-1);
+ expect(bigInt("-55555555555555555").compareAbs("-9999999999999999999")).toBe(-1);
+ expect(bigInt("9999999999999999999").compareAbs("9999999999999999999")).toBe(0);
+ expect(bigInt("9999999999999999999").compareAbs("-9999999999999999999")).toBe(0);
+ expect(bigInt("-9999999999999999999").compareAbs("9999999999999999999")).toBe(0);
+ expect(bigInt("-9999999999999999999").compareAbs("-9999999999999999999")).toBe(0);
+ });
+
+ it("treats 0 and -0 the same", function () {
+ expect(0).toEqualBigInt("-0");
+ expect(bigInt.zero).toEqualBigInt("-0");
+ });
+
+ it("ignores leading zeros", function () {
+ expect("0000000000").toEqualBigInt("0");
+ expect("000000000000023").toEqualBigInt(23);
+ expect(bigInt("-0000000000000000000000123")).toEqualBigInt("-123");
+ });
+
+ it("treats numbers constructed different ways the same", function () {
+ expect("12e5").toEqualBigInt(12e5);
+ expect(12e5).toEqualBigInt("1200000");
+ expect("1").toEqualBigInt(1);
+ expect(bigInt(12345)).toEqualBigInt("12345");
+ expect(bigInt("9876543210")).toEqualBigInt(bigInt(9876543210));
+ });
+
+ it("allows Infinity and -Infinity", function () {
+ // See issue #61
+ // https://github.com/peterolson/BigInteger.js/issues/61
+ expect(bigInt(56).lesser(Infinity)).toBe(true);
+ expect(bigInt(56).greater(-Infinity)).toBe(true);
+ expect(bigInt("50e50").lesser(Infinity)).toBe(true);
+ expect(bigInt("50e50").greater(-Infinity)).toBe(true);
+ });
+ });
+
+ describe("Addition and subtraction", function () {
+ it("by 0 is the identity", function () {
+ expect(bigInt(1).add(0)).toEqualBigInt(1);
+ expect(bigInt(-1).add(0)).toEqualBigInt(-1);
+ expect(bigInt(0).add(-1)).toEqualBigInt(-1);
+ expect(bigInt(0).add(153)).toEqualBigInt(153);
+ expect(bigInt(153).add(0)).toEqualBigInt(153);
+ expect(bigInt(0).add(-153)).toEqualBigInt(-153);
+ expect(bigInt(-153).add(0)).toEqualBigInt(-153);
+ expect(bigInt(0).add("9844190321790980841789")).toEqualBigInt("9844190321790980841789");
+ expect(bigInt("9844190321790980841789").add(0)).toEqualBigInt("9844190321790980841789");
+ expect(bigInt(0).add("-9844190321790980841789")).toEqualBigInt("-9844190321790980841789");
+ expect(bigInt("-9844190321790980841789").add(0)).toEqualBigInt("-9844190321790980841789");
+
+ expect(bigInt(1).minus(0)).toEqualBigInt(1);
+ expect(bigInt(-1).minus(0)).toEqualBigInt(-1);
+ expect(bigInt(153).minus(0)).toEqualBigInt(153);
+ expect(bigInt(-153).minus(0)).toEqualBigInt(-153);
+ expect(bigInt("9844190321790980841789").minus(0)).toEqualBigInt("9844190321790980841789");
+ expect(bigInt("-9844190321790980841789").minus(0)).toEqualBigInt("-9844190321790980841789");
+ });
+
+ it("addition by inverse is 0, subtraction by self is 0", function () {
+ expect(bigInt("5").subtract(bigInt("5"))).toEqualBigInt(0);
+ expect(bigInt("5").add(bigInt("-5"))).toEqualBigInt(0);
+ expect(bigInt("10000000000000000").subtract(bigInt("10000000000000000"))).toEqualBigInt(0);
+ expect(bigInt("10000000000000000").add(bigInt("-10000000000000000"))).toEqualBigInt(0);
+ });
+
+ it("handles signs correctly", function () {
+ expect(bigInt(1).add(1)).toEqualBigInt(2);
+ expect(bigInt(1).add(-5)).toEqualBigInt(-4);
+ expect(bigInt(-1).add(5)).toEqualBigInt(4);
+ expect(bigInt(-1).add(-5)).toEqualBigInt(-6);
+ expect(bigInt(5).add(1)).toEqualBigInt(6);
+ expect(bigInt(5).add(-1)).toEqualBigInt(4);
+ expect(bigInt(-5).add(1)).toEqualBigInt(-4);
+ expect(bigInt(-5).add(-1)).toEqualBigInt(-6);
+
+ expect(bigInt(1).minus(1)).toEqualBigInt(0);
+ expect(bigInt(1).minus(-5)).toEqualBigInt(6);
+ expect(bigInt(-1).minus(5)).toEqualBigInt(-6);
+ expect(bigInt(-1).minus(-5)).toEqualBigInt(4);
+ expect(bigInt(5).minus(1)).toEqualBigInt(4);
+ expect(bigInt(5).minus(-1)).toEqualBigInt(6);
+ expect(bigInt(-5).minus(1)).toEqualBigInt(-6);
+ expect(bigInt(-5).minus(-1)).toEqualBigInt(-4);
+
+ expect(bigInt("1234698764971301").add(5)).toEqualBigInt("1234698764971306");
+ expect(bigInt("1234698764971301").add(-5)).toEqualBigInt("1234698764971296");
+ expect(bigInt("-1234698764971301").add(5)).toEqualBigInt("-1234698764971296");
+ expect(bigInt("-1234698764971301").add(-5)).toEqualBigInt("-1234698764971306");
+ expect(bigInt(5).add("1234698764971301")).toEqualBigInt("1234698764971306");
+ expect(bigInt(5).add("-1234698764971301")).toEqualBigInt("-1234698764971296");
+ expect(bigInt(-5).add("1234698764971301")).toEqualBigInt("1234698764971296");
+ expect(bigInt(-5).add("-1234698764971301")).toEqualBigInt("-1234698764971306");
+
+ expect(bigInt("1234698764971301").minus(5)).toEqualBigInt("1234698764971296");
+ expect(bigInt("1234698764971301").minus(-5)).toEqualBigInt("1234698764971306");
+ expect(bigInt("-1234698764971301").minus(5)).toEqualBigInt("-1234698764971306");
+ expect(bigInt("-1234698764971301").minus(-5)).toEqualBigInt("-1234698764971296");
+ expect(bigInt(5).minus("1234698764971301")).toEqualBigInt("-1234698764971296");
+ expect(bigInt(5).minus("-1234698764971301")).toEqualBigInt("1234698764971306");
+ expect(bigInt(-5).minus("1234698764971301")).toEqualBigInt("-1234698764971306");
+ expect(bigInt(-5).minus("-1234698764971301")).toEqualBigInt("1234698764971296");
+
+ expect(bigInt("1234567890987654321").plus("9876543210123456789")).toEqualBigInt("11111111101111111110");
+ expect(bigInt("1234567890987654321").plus("-9876543210123456789")).toEqualBigInt("-8641975319135802468");
+ expect(bigInt("-1234567890987654321").plus("9876543210123456789")).toEqualBigInt("8641975319135802468");
+ expect(bigInt("-1234567890987654321").plus("-9876543210123456789")).toEqualBigInt("-11111111101111111110");
+ expect(bigInt("9876543210123456789").plus("1234567890987654321")).toEqualBigInt("11111111101111111110");
+ expect(bigInt("9876543210123456789").plus("-1234567890987654321")).toEqualBigInt("8641975319135802468");
+ expect(bigInt("-9876543210123456789").plus("1234567890987654321")).toEqualBigInt("-8641975319135802468");
+ expect(bigInt("-9876543210123456789").plus("-1234567890987654321")).toEqualBigInt("-11111111101111111110");
+
+ expect(bigInt("1234567890987654321").minus("9876543210123456789")).toEqualBigInt("-8641975319135802468");
+ expect(bigInt("1234567890987654321").minus("-9876543210123456789")).toEqualBigInt("11111111101111111110");
+ expect(bigInt("-1234567890987654321").minus("9876543210123456789")).toEqualBigInt("-11111111101111111110");
+ expect(bigInt("-1234567890987654321").minus("-9876543210123456789")).toEqualBigInt("8641975319135802468");
+ expect(bigInt("9876543210123456789").minus("1234567890987654321")).toEqualBigInt("8641975319135802468");
+ expect(bigInt("9876543210123456789").minus("-1234567890987654321")).toEqualBigInt("11111111101111111110");
+ expect(bigInt("-9876543210123456789").minus("1234567890987654321")).toEqualBigInt("-11111111101111111110");
+ expect(bigInt("-9876543210123456789").minus("-1234567890987654321")).toEqualBigInt("-8641975319135802468");
+
+ expect(bigInt("-9007199254740991").add(bigInt("-1")).toString() === "-9007199254740992").toBe(true);
+ expect(bigInt("-5616421592529327000000000000000").minus("987682355516543").toString() === "-5616421592529327987682355516543").toBe(true);
+
+ expect(bigInt("0").negate().add("10000000000000000")).toEqualBigInt("10000000000000000");
+ expect(bigInt("0").negate().add(bigInt("-1"))).toEqualBigInt("-1");
+ });
+
+ it("carries over correctly", function () {
+ // Fibonacci; see issue #9
+ // https://github.com/peterolson/BigInteger.js/issues/9
+ var fibs = ["1", "1", "2", "3", "5", "8", "13", "21", "34", "55", "89", "144", "233", "377", "610", "987", "1597", "2584", "4181", "6765", "10946", "17711", "28657", "46368", "75025", "121393", "196418", "317811", "514229", "832040", "1346269", "2178309", "3524578", "5702887", "9227465", "14930352", "24157817", "39088169", "63245986", "102334155", "165580141", "267914296", "433494437", "701408733", "1134903170", "1836311903", "2971215073", "4807526976", "7778742049", "12586269025"];
+ var number = bigInt(1);
+ var last = bigInt(1);
+
+ for (i = 2; i < 50; i++) {
+ number = number.add(last);
+ last = number.minus(last);
+ expect(number).toEqualBigInt(fibs[i]);
+ }
+
+ expect(bigInt("9007199254740991").add(bigInt("1")).toString()).toBe("9007199254740992");
+ expect(bigInt("999999999999999999999000000000000000000000").add("1000000000000000000000")).toEqualBigInt("1e42");
+ expect(bigInt("1e20").add("9007199254740972")).toEqualBigInt("100009007199254740972");
+ expect(bigInt("-9007199254740983").add(bigInt("-9999999999999998")).toString() === "-19007199254740981").toBe(true); // issue #42
+
+ expect(bigInt(c).minus(bigInt(b).next())).toEqualBigInt("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678899999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+ expect(bigInt(b).minus(bigInt(c).next())).toEqualBigInt("-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ expect(bigInt("100000000000000000000000000000000000").minus("999999999999999999")).toEqualBigInt("99999999999999999000000000000000001");
+
+ expect(bigInt("10000000010000000").subtract("10000000")).toEqualBigInt("10000000000000000"); // issue #54
+ });
+
+ it("work", function () {
+ expect(bigInt("10").add("10")).toEqualBigInt("20");
+ expect(bigInt("-10000000000000000").add("0")).toEqualBigInt("-10000000000000000");
+ expect(bigInt("0").add("10000000000000000")).toEqualBigInt("10000000000000000");
+ expect(bigInt(9999999).add(1)).toEqualBigInt(10000000);
+ expect(bigInt(10000000).minus(1)).toEqualBigInt(9999999);
+ expect(bigInt("-1000000000000000000000000000000000001").add("1000000000000000000000000000000000000")).toEqualBigInt(-1);
+ expect(bigInt("100000000000000000002222222222222222222").minus("100000000000000000001111111111111111111")).toEqualBigInt("1111111111111111111");
+ expect(bigInt("1").add("0")).toEqualBigInt("1");
+ expect(bigInt("10").add("10000000000000000")).toEqualBigInt("10000000000000010");
+ expect(bigInt("10000000000000000").add("10")).toEqualBigInt("10000000000000010");
+ expect(bigInt("10000000000000000").add("10000000000000000")).toEqualBigInt("20000000000000000");
+ });
+ });
+
+ describe("Multiplication", function () {
+ it("by 0 equals 0", function () {
+ expect(bigInt(0).times(0)).toEqualBigInt(0);
+ expect(bigInt(0).times("-0")).toEqualBigInt(0);
+ expect(bigInt(1).times(0)).toEqualBigInt("-0");
+ expect(bigInt(-0).times(1)).toEqualBigInt(0);
+ expect(bigInt("1234567890987654321").times(0)).toEqualBigInt("-0");
+ expect(bigInt(-0).times("1234567890987654321")).toEqualBigInt(0);
+ expect(bigInt(0).times("-1234567890987654321")).toEqualBigInt(0);
+ });
+
+ it("by 1 is the identity", function () {
+ expect(bigInt(1).times(1)).toEqualBigInt(1);
+ expect(bigInt(-1).times(1)).toEqualBigInt(-1);
+ expect(bigInt(1).times(-1)).toEqualBigInt(-1);
+ expect(bigInt(1).times(153)).toEqualBigInt(153);
+ expect(bigInt(153).times(1)).toEqualBigInt(153);
+ expect(bigInt(1).times(-153)).toEqualBigInt(-153);
+ expect(bigInt(-153).times(1)).toEqualBigInt(-153);
+ expect(bigInt(1).times("9844190321790980841789")).toEqualBigInt("9844190321790980841789");
+ expect(bigInt("9844190321790980841789").times(1)).toEqualBigInt("9844190321790980841789");
+ expect(bigInt(1).times("-9844190321790980841789")).toEqualBigInt("-9844190321790980841789");
+ expect(bigInt("-9844190321790980841789").times(1)).toEqualBigInt("-9844190321790980841789");
+ });
+
+ it("handles signs correctly", function () {
+ expect(bigInt(100).times(100)).toEqualBigInt(10000);
+ expect(bigInt(100).times(-100)).toEqualBigInt(-10000);
+ expect(bigInt(-100).times(100)).toEqualBigInt(-10000);
+ expect(bigInt(-100).times(-100)).toEqualBigInt(10000);
+
+ expect(bigInt(13579).times("163500573666152634716420931676158")).toEqualBigInt("2220174289812686626814279831230549482");
+ expect(bigInt(13579).times("-163500573666152634716420931676158")).toEqualBigInt("-2220174289812686626814279831230549482");
+ expect(bigInt(-13579).times("163500573666152634716420931676158")).toEqualBigInt("-2220174289812686626814279831230549482");
+ expect(bigInt(-13579).times("-163500573666152634716420931676158")).toEqualBigInt("2220174289812686626814279831230549482");
+ expect(bigInt("163500573666152634716420931676158").times(13579)).toEqualBigInt("2220174289812686626814279831230549482");
+ expect(bigInt("163500573666152634716420931676158").times(-13579)).toEqualBigInt("-2220174289812686626814279831230549482");
+ expect(bigInt("-163500573666152634716420931676158").times(13579)).toEqualBigInt("-2220174289812686626814279831230549482");
+ expect(bigInt("-163500573666152634716420931676158").times(-13579)).toEqualBigInt("2220174289812686626814279831230549482");
+ expect(bigInt("163500573666152634716420931676158").times(-1)).toEqualBigInt("-163500573666152634716420931676158");
+
+ expect(bigInt("1234567890987654321").times("132435465768798")).toEqualBigInt("163500573666152634716420931676158");
+ expect(bigInt("1234567890987654321").times("-132435465768798")).toEqualBigInt("-163500573666152634716420931676158");
+ expect(bigInt("-1234567890987654321").times("132435465768798")).toEqualBigInt("-163500573666152634716420931676158");
+ expect(bigInt("-1234567890987654321").times("-132435465768798")).toEqualBigInt("163500573666152634716420931676158");
+ });
+
+ it("carries over correctly", function () {
+ expect(bigInt("50000005000000").times("10000001")).toEqualBigInt("500000100000005000000");
+
+ expect(bigInt(e).times(bigInt(e).times(3))).toEqualBigInt("45724736259716510251486054687700045835025148620128029265675354366933790580730004572476663008688032556012839881115687650663009131321444949757658898638317330230086877059634202109625971651328852309169510745320613625972427617741279387288531601280293526383173389263831742588934614625148605499140374953576588935723914037609016918164564243256822679469718893461375551897577921444901828770004586539551899020210333938646547797527206220118975766048523091008514860541217741198158399634219502514862316506630268276177430490169183415272062378152720641477823504514037494488029263852465477825612802926597905807063453132146711568358707782350274440786467810333790817658893485428440788909099222927535436696416095110007864655037411979907403749431106630087147288523118391403752205395519257165066329379058073304160951367041609540366712394402926383476918152751354366715501691815586794695962342021036600457247696671239173329675357699222679806547782384317329678797988111916424325595304983999896753544026300868806292638320995518976136177412017280292642094284408246053955228267946963193049840355930498439255601284291815272465807041650243255605390580704575683584861230909926489346136685560128072218564247588111568795436671283206218568686877000905313214494193872889785642433015189757705181527210884407865125066300916169181531983173297234942844127156835853081938729344819387338144490174180704161454695930549132144495279469593564572473760119798816378235025674449016971107453137477000457784325560182095107458575765889894202103393082761779674531322004078646604070416100773296754113955189815058070421872062186223831733026045724742970827618333708276237033379064069593050443584819448021033385168358482553461362659008687706267123914663337905869996342027365889346773214449080983996348464654778883090992291971650669563420210992967535502959304990662185643102844078713946959311760951075212720621924934613632859716507322597165135922267953958481939432473708346909922275057247371542350251557897576596156012803652226794768885230917254778235762103337979872885238353543667871979881190860539559452309099981856424401848193880551074532091732967612835848201649839964201609510823823502522748605396311486054034811156843847370828421362597245798811164946136260531239140456786465486044901692641115683667774119807143667124750992226878761774128242432556860868770089749428449341197988970745313300737082770439963421080621856511724737091538728853190498399722712391412637494285300374942933700045733736259717410251486144687700054835025149520128029355675354375933790581630004572566663008697032556013739881115777650663018131321445849757658988638317339230086877959634202199625971660328852310069510745410613625981427617742179387288621601280302526383174289263831832588934623625148606399140375043576588944723914038509016918254564243265822679470618893461465551897586921444902728770004676539551908020210334838646547887527206229118975766948523091098514860550217741199058399634309502514871316506631168276177520490169192415272063278152720731477823513514037495388029263942465477834612802927497905807153453132155711568359607782350364440786476810333791717658893575428440797909099223827535436786416095119007864655937411979997403749440106630088047288523208391403761205395520157165066419379058082304160952267041609630366712403402926384376918152841354366724501691816486794696052342021045600457248596671239263329675366699222680706547782474317329687797988112816424325685304984008896753544926300868896292638329995518977036177412107280292651094284409146053955318267946972193049841255930498529255601293291815273365807041740243255614390580705475683584951230909935489346137585560128162218564256588111569695436671373206218577686877001805313214584193872898785642433915189757795181527219884407866025066301006169181540983173298134942844217156835862081938730244819387428144490183180704162354695930639132144504279469594464572473850119798825378235026574449017061107453146477000458684325560272095107467575765890794202103483082761788674531322904078646694070416109773296755013955189905058070430872062187123831733116045724751970827619233708276327033379073069593051343584819538021033394168358483453461362749008687715267123915563337905959996342036365889347673214449170983996357464654779783090992381971650678563420211892967535592959304999662185644002844078803946959320760951076112720622014934613641859716508222597165225922267962958481940332473708436909922284057247372442350251647897576605156012804552226794858885230926254778236662103338069872885247353543668771979881280860539568452309100881856424491848193889551074532991732967702835848210649839965101609510913823502531748605397211486054124811156852847370829321362597335798811173946136261431239140546786465495044901693541115683757774119816143667125650992226968761774137242432557760868770179749428458341197989870745313390737082779439963421980621856601724737100538728854090498399812712391421637494286200374943023700045742736259718310251486234687700063835025150420128029445675354384933790582530004572656663008706032556014639881115867650663027131321446749757659078638317348230086878859634202289625971669328852310969510745500613625990427617743079387288711601280311526383175189263831922588934632625148607299140375133576588953723914039409016918344564243274822679471518893461555551897595921444903628770004766539551917020210335738646547977527206238118975767848523091188514860559217741199958399634399502514880316506632068276177610490169201415272064178152720821477823522514037496288029264032465477843612802928397905807243453132164711568360507782350454440786485810333792617658893665428440806909099224727535436876416095128007864656837411980087403749449106630088947288523298391403770205395521057165066509379058091304160953167041609720366712412402926385276918152931354366733501691817386794696142342021054600457249496671239353329675375699222681606547782564317329696797988113716424325775304984017896753545826300868986292638338995518977936177412197280292660094284410046053955408267946981193049842155930498619255601302291815274265807041830243255623390580706375683585041230909944489346138485560128252218564265588111570595436671463206218586686877002705313214674193872907785642434815189757885181527228884407866925066301096169181549983173299034942844307156835871081938731144819387518144490192180704163254695930729132144513279469595364572473940119798834378235027474449017151107453155477000459584325560362095107476575765891694202103573082761797674531323804078646784070416118773296755913955189995058070439872062188023831733206045724760970827620133708276417033379082069593052243584819628021033403168358484353461362839008687724267123916463337906049996342045365889348573214449260983996366464654780683090992471971650687563420212792967535682959305008662185644902844078893946959329760951077012720622104934613650859716509122597165315922267971958481941232473708526909922293057247373342350251737897576614156012805452226794948885230935254778237562103338159872885256353543669671979881370860539577452309101781856424581848193898551074533891732967792835848219649839966001609511003823502540748605398111486054214811156861847370830221362597425798811182946136262331239140636786465504044901694441115683847774119825143667126550992227058761774146242432558660868770269749428467341197990770745313480737082788439963422880621856691724737109538728854990498399902712391430637494287100374943113700045751736259719210251486324687700072835025151320128029535675354393933790583430004572746663008715032556015539881115957650663036131321447649757659168638317357230086879759634202379625971678328852311869510745590613625999427617743979387288801601280320526383176089263832012588934641625148608199140375223576588962723914040309016918434564243283822679472418893461645551897604921444904528770004856539551926020210336638646548067527206247118975768748523091278514860568217741200858399634489502514889316506632968276177700490169210415272065078152720911477823531514037497188029264122465477852612802929297905807333453132173711568361407782350544440786494810333793517658893755428440815909099225627535436966416095137007864657737411980177403749458106630089847288523388391403779205395521957165066599379058100304160954067041609810366712421402926386176918153021354366742501691818286794696232342021063600457250396671239443329675384699222682506547782654317329705797988114616424325865304984026896753546726300869076292638347995518978836177412287280292669094284410946053955498267946990193049843055930498709255601311291815275165807041920243255632390580707275683585131230909953489346139385560128342218564274588111571495436671553206218595686877003605313214764193872916785642435715189757975181527237884407867825066301186169181558983173299934942844397156835880081938732044819387608144490201180704164154695930819132144522279469596264572474030119798843378235028374449017241107453164477000460484325560452095107485575765892594202103663082761806674531324704078646874070416127773296756813955190085058070448872062188923831733296045724769970827621033708276507033379091069593053143584819718021033412168358485253461362929008687733267123917363337906139996342054365889349473214449350983996375464654781583090992561971650696563420213692967535772959305017662185645802844078983946959338760951077912720622194934613659859716510022597165405922267980958481942132473708616909922302057247374242350251827897576623156012806352226795038885230944254778238462103338249872885265353543670571979881460860539586452309102681856424671848193907551074534791732967882835848228649839966901609511093823502549748605399011486054304811156870847370831121362597515798811191946136263231239140726786465513044901695341115683937774119834143667127450992227148761774155242432559560868770359749428476341197991670745313570737082797439963423780621856781724737118538728855890498399992712391439637494288000374943203700045760736259720110251486414687700081835025152220128029625675354402933790584330004572836663008724032556016439881116047650663045131321448549757659258638317366230086880659634202469625971687328852312769510745680613626008427617744879387288891601280329526383176989263832102588934650625148609099140375313576588971723914041209016918524564243292822679473318893461735551897613921444905428770004946539551935020210337538646548157527206256118975769648523091368514860577217741201758399634579502514898316506633868276177790490169219415272065978152721001477823540514037498088029264212465477861612802930197905807423453132182711568362307782350634440786503810333794417658893845428440824909099226527535437056416095146007864658637411980267403749467106630090747288523478391403788205395522857165066689379058109304160954967041609900366712430402926387076918153111354366751501691819186794696322342021072600457251296671239533329675393699222683406547782744317329714797988115516424325955304984035896753547626300869166292638356995518979736177412377280292678094284411846053955588267946999193049843955930498799255601320291815276065807042010243255641390580708175683585221230909962489346140285560128432218564283588111572395436671643206218604686877004505313214854193872925785642436615189758065181527246884407868725066301276169181567983173300834942844487156835889081938732944819387698144490210180704165054695930909132144531279469597164572474120119798852378235029274449017331107453173477000461384325560542095107494575765893494202103753082761815674531325604078646964070416136773296757713955190175058070457872062189823831733386045724778970827621933708276597033379100069593054043584819808021033421168358486153461363019008687742267123918263337906229996342063365889350373214449440983996384464654782483090992651971650705563420214592967535862959305026662185646702844079073946959347760951078812720622284934613668859716510922597165495922267989958481943032473708706909922311057247375142350251917897576632156012807252226795128885230953254778239362103338339872885274353543671471979881550860539595452309103581856424761848193916551074535691732967972835848237649839967801609511183823502558748605399911486054394811156879847370832021362597605798811200946136264131239140816786465522044901696241115684027774119843143667128350992227238761774164242432560460868770449749428485341197992570745313660737082806439963424680621856871724737127538728856790498400082712391448637494288900374943293700045769736259721010251486504687700090835025153120128029715675354411933790585230004572926663008733032556017339881116137650663054131321449449757659348638317375230086881559634202559625971696328852313669510745770613626017427617745779387288981601280338526383177889263832192588934659625148609999140375403576588980723914042109016918614564243301822679474218893461825551897622921444906328770005036539551944020210338438646548247527206265118975770548523091458514860586217741202658399634669502514907316506634768276177880490169228415272066878152721091477823549514037498988029264302465477870612802931097905807513453132191711568363207782350724440786512810333795317658893935428440833909099227427535437146416095155007864659537411980357403749476106630091647288523568391403797205395523757165066779379058118304160955867041609990366712439402926387976918153201354366760501691820086794696412342021081600457252196671239623329675402699222684306547782834317329723797988116416424326045304984044896753548526300869256292638365995518980636177412467280292687094284412746053955678267947008193049844855930498889255601329291815276965807042100243255650390580709075683585311230909971489346141185560128522218564292588111573295436671733206218613686877005405313214944193872934785642437515189758155181527255884407869625066301366169181576983173301734942844577156835898081938733844819387788144490219180704165954695930999132144540279469598064572474210119798861378235030174449017421107453182477000462284325560632095107503575765894394202103843082761824674531326504078647054070416145773296758613955190265058070466872062190723831733476045724787970827622833708276687033379109069593054943584819898021033430168358487053461363109008687751267123919163337906319996342072365889351273214449530983996393464654783383090992741971650714563420215492967535952959305035662185647602844079163946959356760951079712720622374934613677859716511822597165585922267998958481943932473708796909922320057247376042350252007897576641156012808152226795218885230962254778240262103338429872885283353543672371979881640860539604452309104481856424851848193925551074536591732968062835848246649839968701609511273823502567748605400811486054484811156888847370832921362597695798811209946136265031239140906786465531044901697141115684117774119852143667129250992227328761774173242432561360868770539749428494341197993470745313750737082815439963425580621856961724737136538728857690498400172712391457637494289800374943383700045778736259721910251486594687700099835025154020128029805675354420933790586130004573016663008742032556018239881116227650663063131321450349757659438638317384230086882459634202649625971705328852314569510745860613626026427617746679387289071601280347526383178789263832282588934668625148610899140375493576588989723914043009016918704564243310822679475118893461915551897631921444907228770005126539551953020210339338646548337527206274118975771448523091548514860595217741203558399634759502514916316506635668276177970490169237415272067778152721181477823558514037499888029264392465477879612802931997905807603453132200711568364107782350814440786521810333796217658894025428440842909099228327535437236416095164007864660437411980447403749485106630092547288523658391403806205395524657165066869379058127304160956767041610080366712448402926388876918153291354366769501691820986794696502342021090600457253096671239713329675411699222685206547782924317329732797988117316424326135304984053896753549426300869346292638374995518981536177412557280292696094284413646053955768267947017193049845755930498979255601338291815277865807042190243255659390580709975683585401230909980489346142085560128612218564301588111574195436671823206218622686877006305313215034193872943785642438415189758245181527264884407870525066301456169181585983173302634942844667156835907081938734744819387878144490228180704166854695931089132144549279469598964572474300119798870378235031074449017511107453191477000463184325560722095107512575765895294202103933082761833674531327404078647144070416154773296759513955190355058070475872062191623831733566045724796970827623733708276777033379118069593055843584819988021033439168358487953461363199008687760267123920063337906409996342081365889352173214449620983996402464654784283090992831971650723563420216392967536042959305044662185648502844079253946959365760951080612720622464934613686859716512722597165675922268007958481944832473708886909922329057247376942350252097897576650156012809052226795308885230971254778241162103338519872885292353543673271979881730860539613452309105381856424941848193934551074537491732968152835848255649839969601609511363823502576748605401711486054574811156897847370833821362597785798811218946136265931239140996786465540044901698041115684207774119861143667130150992227418761774182242432562260868770629749428503341197994370745313840737082824439963426480621857051724737145538728858590498400262712391466637494290700374943473700045787736259722810251486684687700108835025154920128029895675354429933790587030004573106663008751032556019139881116317650663072131321451249757659528638317393230086883359634202739625971714328852315469510745950613626035427617747579387289161601280356526383179689263832372588934677625148611799140375583576588998723914043909016918794564243319822679476018893462005551897640921444908128770005216539551962020210340238646548427527206283118975772348523091638514860604217741204458399634849502514925316506636568276178060490169246415272068678152721271477823567514037500788029264482465477888612802932897905807693453132209711568365007782350904440786530810333797117658894115428440851909099229227535437326416095173007864661337411980537403749494106630093447288523748391403815205395525557165066959379058136304160957667041610170366712457402926389776918153381354366778501691821886794696592342021099600457253996671239803329675420699222686106547783014317329741797988118216424326225304984062896753550326300869436292638383995518982436177412647280292705094284414546053955858267947026193049846655930499069255601347291815278765807042280243255668390580710875683585491230909989489346142985560128702218564310588111575095436671913206218631686877007205313215124193872952785642439315189758335181527273884407871425066301546169181594983173303534942844757156835916081938735644819387968144490237180704167754695931179132144558279469599864572474390119798879378235031974449017601107453200477000464084325560812095107521575765896194202104023082761842674531328304078647234070416163773296760413955190445058070484872062192523831733656045724805970827624633708276867033379127069593056743584820078021033448168358488853461363289008687769267123920963337906499996342090365889353073214449710983996411464654785183090992921971650732563420217292967536132959305053662185649402844079343946959374760951081512720622554934613695859716513622597165765922268016958481945732473708976909922338057247377842350252187897576659156012809952226795398885230980254778242062103338609872885301353543674171979881820860539622452309106281856425031848193943551074538391732968242835848264649839970501609511453823502585748605402611486054664811156906847370834721362597875798811227946136266831239141086786465549044901698941115684297774119870143667131050992227508761774191242432563160868770719749428512341197995270745313930737082833439963427380621857141724737154538728859490498400352712391475637494291600374943563700045796736259723710251486774687700117835025155820128029985675354438933790587930004573196663008760032556020039881116407650663081131321452149757659618638317402230086884259634202829625971723328852316369510746040613626044427617748479387289251601280365526383180589263832462588934686625148612699140375673576589007723914044809016918884564243328822679476918893462095551897649921444909028770005306539551971020210341138646548517527206292118975773248523091728514860613217741205358399634939502514934316506637468276178150490169255415272069578152721361477823576514037501688029264572465477897612802933797905807783453132218711568365907782350994440786539810333798017658894205428440860909099230127535437416416095182007864662237411980627403749503106630094347288523838391403824205395526457165067049379058145304160958567041610260366712466402926390676918153471354366787501691822786794696682342021108600457254896671239893329675429699222687006547783104317329750797988119116424326315304984071896753551226300869526292638392995518983336177412737280292714094284415446053955948267947035193049847555930499159255601356291815279665807042370243255677390580711775683585581230909998489346143885560128792218564319588111575995436672003206218640686877008105313215214193872961785642440215189758425181527282884407872325066301636169181603983173304434942844847156835925081938736544819388058144490246180704168654695931269132144567279469600764572474480119798888378235032874449017691107453209477000464984325560902095107530575765897094202104113082761851674531329204078647324070416172773296761313955190535058070493872062193423831733746045724814970827625533708276957033379136069593057643584820168021033457168358489753461363379008687778267123921863337906589996342099365889353973214449800983996420464654786083090993011971650741563420218192967536222959305062662185650302844079433946959383760951082412720622644934613704859716514522597165855922268025958481946632473709066909922347057247378742350252277897576668156012810852226795488885230989254778242962103338699872885310353543675071979881910860539631452309107181856425121848193952551074539291732968332835848273649839971401609511543823502594748605403511486054754811156915847370835621362597965798811236946136267731239141176786465558044901699841115684387774119879143667131950992227598761774200242432564060868770809749428521341197996170745314020737082842439963428280621857231724737163538728860390498400442712391484637494292500374943653700045805736259724610251486864687700126835025156720128030075675354447933790588830004573286663008769032556020939881116497650663090131321453049757659708638317411230086885159634202919625971732328852317269510746130613626053427617749379387289341601280374526383181489263832552588934695625148613599140375763576589016723914045709016918974564243337822679477818893462185551897658921444909928770005396539551980020210342038646548607527206301118975774148523091818514860622217741206258399635029502514943316506638368276178240490169264415272070478152721451477823585514037502588029264662465477906612802934697905807873453132227711568366807782351084440786548810333798917658894295428440869909099231027535437506416095191007864663137411980717403749512106630095247288523928391403833205395527357165067139379058154304160959467041610350366712475402926391576918153561354366796501691823686794696772342021117600457255796671239983329675438699222687906547783194317329759797988120016424326405304984080896753552126300869616292638401995518984236177412827280292723094284416346053956038267947044193049848455930499249255601365291815280565807042460243255686390580712675683585671230910007489346144785560128882218564328588111576895436672093206218649686877009005313215304193872970785642441115189758515181527291884407873225066301726169181612983173305334942844937156835934081938737444819388148144490255180704169554695931359132144576279469601664572474570119798897378235033774449017781107453218477000465884325560992095107539575765897994202104203082761860674531330104078647414070416181773296762213955190625058070502872062194323831733836045724823970827626433708277047033379145069593058543584820258021033466168358490653461363469008687787267123922763337906679996342108365889354873214449890983996429464654786983090993101971650750563420219092967536312959305071662185651202844079523946959392760951083312720622734934613713859716515422597165945922268034958481947532473709156909922356057247379642350252367897576677156012811752226795578885230998254778243862103338789872885319353543675971979882000860539640452309108081856425211848193961551074540191732968422835848282649839972301609511633823502603748605404411486054844811156924847370836521362598055798811245946136268631239141266786465567044901700741115684477774119888143667132850992227688761774209242432564960868770899749428530341197997070745314110737082851439963429180621857321724737172538728861290498400532712391493637494293400374943743700045814736259725510251486954687700135835025157620128030165675354456933790589730004573376663008778032556021839881116587650663099131321453949757659798638317420230086886059634203009625971741328852318169510746220613626062427617750279387289431601280383526383182389263832642588934704625148614499140375853576589025723914046609016919064564243346822679478718893462275551897667921444910828770005486539551989020210342938646548697527206310118975775048523091908514860631217741207158399635119502514952316506639268276178330490169273415272071378152721541477823594514037503488029264752465477915612802935597905807963453132236711568367707782351174440786557810333799817658894385428440878909099231927535437596416095200007864664037411980807403749521106630096147288524018391403842205395528257165067229379058163304160960367041610440366712484402926392476918153651354366805501691824586794696862342021126600457256696671240073329675447699222688806547783284317329768797988120916424326495304984089896753553026300869706292638410995518985136177412917280292732094284417246053956128267947053193049849355930499339255601374291815281465807042550243255695390580713575683585761230910016489346145685560128972218564337588111577795436672183206218658686877009905313215394193872979785642442015189758605181527300884407874125066301816169181621983173306234942845027156835943081938738344819388238144490264180704170454695931449132144585279469602564572474660119798906378235034674449017871107453227477000466784325561082095107548575765898894202104293082761869674531331004078647504070416190773296763113955190715058070511872062195223831733926045724832970827627333708277137033379154069593059443584820348021033475168358491553461363559008687796267123923663337906769996342117365889355773214449980983996438464654787883090993191971650759563420219992967536402959305080662185652102844079613946959401760951084212720622824934613722859716516322597166035922268043958481948432473709246909922365057247380542350252457897576686156012812652226795668885231007254778244762103338879872885328353543676871979882090860539649452309108981856425301848193970551074541091732968512835848291649839973201609511723823502612748605405311486054934811156933847370837421362598145798811254946136269531239141356786465576044901701641115684567774119897143667133750992227778761774218242432565860868770989749428539341197997970745314200737082860439963430080621857411724737181538728862190498400622712391502637494294300374943833700045823736259726410251487044687700144835025158520128030255675354465933790590630004573466663008787032556022739881116677650663108131321454849757659888638317429230086886959634203099625971750328852319069510746310613626071427617751179387289521601280392526383183289263832732588934713625148615399140375943576589034723914047509016919154564243355822679479618893462365551897676921444911728770005576539551998020210343838646548787527206319118975775948523091998514860640217741208058399635209502514961316506640168276178420490169282415272072278152721631477823603514037504388029264842465477924612802936497905808053453132245711568368607782351264440786566810333800717658894475428440887909099232827535437686416095209007864664937411980897403749530106630097047288524108391403851205395529157165067319379058172304160961267041610530366712493402926393376918153741354366814501691825486794696952342021135600457257596671240163329675456699222689706547783374317329777797988121816424326585304984098896753553926300869796292638419995518986036177413007280292741094284418146053956218267947062193049850255930499429255601383291815282365807042640243255704390580714475683585851230910025489346146585560129062218564346588111578695436672273206218667686877010805313215484193872988785642442915189758695181527309884407875025066301906169181630983173307134942845117156835952081938739244819388328144490273180704171354695931539132144594279469603464572474750119798915378235035574449017961107453236477000467684325561172095107557575765899794202104383082761878674531331904078647594070416199773296764013955190805058070520872062196123831734016045724841970827628233708277227033379163069593060343584820438021033484168358492453461363649008687805267123924563337906859996342126365889356673214450070983996447464654788783090993281971650768563420220892967536492959305089662185653002844079703946959410760951085112720622914934613731859716517222597166125922268052958481949332473709336909922374057247381442350252547897576695156012813552226795758885231016254778245662103338969872885337353543677771979882180860539658452309109881856425391848193979551074541991732968602835848300649839974101609511813823502621748605406211486055024811156942847370838321362598235798811263946136270431239141446786465585044901702541115684657774119906143667134650992227868761774227242432566760868771079749428548341197998870745314290737082869439963430980621857501724737190538728863090498400712712391511637494295200374943923700045832736259727310251487134687700153835025159420128030345675354474933790591530004573556663008796032556023639881116767650663117131321455749757659978638317438230086887859634203189625971759328852319969510746400613626080427617752079387289611601280401526383184189263832822588934722625148616299140376033576589043723914048409016919244564243364822679480518893462455551897685921444912628770005666539552007020210344738646548877527206328118975776848523092088514860649217741208958399635299502514970316506641068276178510490169291415272073178152721721477823612514037505288029264932465477933612802937397905808143453132254711568369507782351354440786575810333801617658894565428440896909099233727535437776416095218007864665837411980987403749539106630097947288524198391403860205395530057165067409379058181304160962167041610620366712502402926394276918153831354275374029172393366291724932966621052930406961256415181721978966731831641529146538638510991312410732876097036662095300003658089634110664926785552089016003768535345232816909008878028349447436579800707032465667040695126337814368597155922456053040805239048936487279379245065386484140283504377402836034077732163041518072267526292823090077841942752640157649749612102423520843987208047773206401114769199745221775937896663190127114878646456343828020119979139460557547690911718143576768151806236448925479608267033557164151915350160047498390490346176497594251394615388513947135188843273152629183278637403924201188952053863751168760860713213534630955098319058884317502225880309856332886949007774291238225988757567454839131231080250571667658802022729254687869262917346560036590619378144658275263025461271158509501601447287608704362505726399625058236299954383263740294289748515025312300062164974862179871971814324645741066209430069995428603336991419967443997960118885392349337098868678565850242342181361682777769913133740365798970374028456671147701630489255759386374135572382269520612712548398719814473616837410736169337411065493374851405300859626126423411172276085973190983082915435756851177320541081106539704448102530078555108971229996493460448208979789676861353453282472793887881024244751476910071485139566782258812641600366860497485245683493380531723823649509830924584727948421847280438522176603485962516311970737227534522282387197084202094194016546867961288431652092217650805559213640189666219982341107594571559319090900787872464564383583904997992135355762588021172596250676893369923652711477961608596355794604491542834934750620942034695839059432958391539633287713597073627323081848328645633392498308195213205305117657979071399542763103328761906670324750300777330993452218695682670429202011898883575675484695016108103246466773699132273707361787004481034663822589062719707465905715602553946045851732053144806950170444069502640744398823708184738334192959429756744502609419306224316416218769090181510653874114439873007781435860411888442004563329796793781539313123009894686786585806127218214357577784810243374818472897115592145674933700163830818576016826713565057156952843164254918061281455180613741855509933819295849345304070530867855612720530417235427527319880201291621764985125550984108892546970522999553015674440897904892649424234120905797897686917238328325468688795921354475929584007226703256686044811264941929686127937824576168268053954275365029172392466291724842966621043930406960356415181631978966722831641528246538638420991312401732876096136662095210003658080634110664026785551999016003759535345231916909008788028349438436579799807032465577040695117337814367697155922366053040796239048935587279379155065386475140283503477402835944077732154041518071367526292733090077832942752639257649749522102423511843987207147773206311114769190745221775037896663100127114869646456342928020119889139460548547690910818143576678151806227448925478708267033467164151906350160046598390490256176497585251394614488513947045188843264152629182378637403834201188943053863750268760860623213534621955098318158884317412225880300856332886049007774201238225979757567453939131230990250571658658802021829254687779262917337560036589719378144568275263016461271157609501601357287608695362505725499625058146299954374263740293389748514935312300053164974861279871971724324645732066209429169995428513336991410967443997060118885302349337089868678564950242342091361682768769913132840365798880374028447671147700730489255669386374126572382268620612712458398719805473616836510736169247411065484374851404400859626036423411163276085972290983082825435756842177320540181106539614448102521078555108071229996403460448199979789675961353453192472793878881024243851476909981485139557782258811741600366770497485236683493379631723823559509830915584727947521847280348522176594485962515411970737137534522273387197083302094193926546867952288431651192217650715559213631189666219082341107504571559310090900786972464564293583904988992135354862588021082596250667893369922752711477871608596346794604490642834934660620942025695839058532958391449633287704597073626423081848238645633383498308194313205305027657979062399542762203328761816670324741300777330093452218605682670420202011897983575675394695016099103246465873699132183707361778004481033763822588972719707456905715601653946045761732053135806950169544069502550744398814708184737434192959339756744493609419305324316416128769090172510653873214439872917781435851411888441104563329706793781530313123008994686786495806127209214357576884810243284818472888115592144774933700073830818567016826712665057156862843164245918061280555180613651855509924819295848445304070440867855603720530416335427527229880201282621764984225550984018892546961522999552115674440807904892640424234120005797897596917238319325468687895921354385929583998226703255786044811174941929677127937823676168267963954275356029172391566291724752966621034930406959456415181541978966713831641527346538638330991312392732876095236662095120003658071634110663126785551909016003750535345231016909008698028349429436579798907032465487040695108337814366797155922276053040787239048934687279379065065386466140283502577402835854077732145041518070467526292643090077823942752638357649749432102423502843987206247773206221114769181745221774137896663010127114860646456342028020119799139460539547690909918143576588151806218448925477808267033377164151897350160045698390490166176497576251394613588513946955188843255152629181478637403744201188934053863749368760860533213534612955098317258884317322225880291856332885149007774111238225970757567453039131230900250571649658802020929254687689262917328560036588819378144478275263007461271156709501601267287608686362505724599625058056299954365263740292489748514845312300044164974860379871971634324645723066209428269995428423336991401967443996160118885212349337080868678564050242342001361682759769913131940365798790374028438671147699830489255579386374117572382267720612712368398719796473616835610736169157411065475374851403500859625946423411154276085971390983082735435756833177320539281106539524448102512078555107171229996313460448190979789675061353453102472793869881024242951476909891485139548782258810841600366680497485227683493378731723823469509830906584727946621847280258522176585485962514511970737047534522264387197082402094193836546867943288431650292217650625559213622189666218182341107414571559301090900786072464564203583904979992135353962588020992596250658893369921852711477781608596337794604489742834934570620942016695839057632958391359633287695597073625523081848148645633374498308193413205304937657979053399542761303328761726670324732300777329193452218515682670411202011897083575675304695016090103246464973699132093707361769004481032863822588882719707447905715600753946045671732053126806950168644069502460744398805708184736534192959249756744484609419304424316416038769090163510653872314439872827781435842411888440204563329616793781521313123008094686786405806127200214357575984810243194818472879115592143874933699983830818558016826711765057156772843164236918061279655180613561855509915819295847545304070350867855594720530415435427527139880201273621764983325550983928892546952522999551215674440717904892631424234119105797897506917238310325468686995921354295929583989226703254886044811084941929668127937822776168267873954275347029172390666291724662966621025930406958556415181451978966704831641526446538638240991312383732876094336662095030003658062634110662226785551819016003741535345230116909008608028349420436579798007032465397040695099337814365897155922186053040778239048933787279378975065386457140283501677402835764077732136041518069567526292553090077814942752637457649749342102423493843987205347773206131114769172745221773237896662920127114851646456341128020119709139460530547690909018143576498151806209448925476908267033287164151888350160044798390490076176497567251394612688513946865188843246152629180578637403654201188925053863748468760860443213534603955098316358884317232225880282856332884249007774021238225961757567452139131230810250571640658802020029254687599262917319560036587919378144388275262998461271155809501601177287608677362505723699625057966299954356263740291589748514755312300035164974859479871971544324645714066209427369995428333336991392967443995260118885122349337071868678563150242341911361682750769913131040365798700374028429671147698930489255489386374108572382266820612712278398719787473616834710736169067411065466374851402600859625856423411145276085970490983082645435756824177320538381106539434448102503078555106271229996223460448181979789674161353453012472793860881024242051476909801485139539782258809941600366590497485218683493377831723823379509830897584727945721847280168522176576485962513611970736957534522255387197081502094193746546867934288431649392217650535559213613189666217282341107324571559292090900785172464564113583904970992135353062588020902596250649893369920952711477691608596328794604488842834934480620942007695839056732958391269633287686597073624623081848058645633365498308192513205304847657979044399542760403328761636670324723300777328293452218425682670402202011896183575675214695016081103246464073699132003707361760004481031963822588792719707438905715599853946045581732053117806950167744069502370744398796708184735634192959159756744475609419303524316415948769090154510653871414439872737781435833411888439304563329526793781512313123007194686786315806127191214357575084810243104818472870115592142974933699893830818549016826710865057156682843164227918061278755180613471855509906819295846645304070260867855585720530414535427527049880201264621764982425550983838892546943522999550315674440627904892622424234118205797897416917238301325468686095921354205929583980226703253986044810994941929659127937821876168267783954275338029172389766291724572966621016930406957656415181361978966695831641525546538638150991312374732876093436662094940003658053634110661326785551729016003732535345229216909008518028349411436579797107032465307040695090337814364997155922096053040769239048932887279378885065386448140283500777402835674077732127041518068667526292463090077805942752636557649749252102423484843987204447773206041114769163745221772337896662830127114842646456340228020119619139460521547690908118143576408151806200448925476008267033197164151879350160043898390489986176497558251394611788513946775188843237152629179678637403564201188916053863747568760860353213534594955098315458884317142225880273856332883349007773931238225952757567451239131230720250571631658802019129254687509262917310560036587019378144298275262989461271154909501601087287608668362505722799625057876299954347263740290689748514665312300026164974858579871971454324645705066209426469995428243336991383967443994360118885032349337062868678562250242341821361682741769913130140365798610374028420671147698030489255399386374099572382265920612712188398719778473616833810736168977411065457374851401700859625766423411136276085969590983082555435756815177320537481106539344448102494078555105371229996133460448172979789673261353452922472793851881024241151476909711485139530782258809041600366500497485209683493376931723823289509830888584727944821847280078522176567485962512711970736867534522246387197080602094193656546867925288431648492217650445559213604189666216382341107234571559283090900784272464564023583904961992135352162588020812596250640893369920052711477601608596319794604487942834934390620941998695839055832958391179633287677597073623723081847968645633356498308191613205304757657979035399542759503328761546670324714300777327393452218335682670393202011895283575675124695016072103246463173699131913707361751004481031063822588702719707429905715598953946045491732053108806950166844069502280744398787708184734734192959069756744466609419302624316415858769090145510653870514439872647781435824411888438404563329436793781503313123006294686786225806127182214357574184810243014818472861115592142074933699803830818540016826709965057156592843164218918061277855180613381855509897819295845745304070170867855576720530413635427526959880201255621764981525550983748892546934522999549415674440537904892613424234117305797897326917238292325468685195921354115929583971226703253086044810904941929650127937820976168267693954275329029172388866291724482966621007930406956756415181271978966686831641524646538638060991312365732876092536662094850003658044634110660426785551639016003723535345228316909008428028349402436579796207032465217040695081337814364097155922006053040760239048931987279378795065386439140283499877402835584077732118041518067767526292373090077796942752635657649749162102423475843987203547773205951114769154745221771437896662740127114833646456339328020119529139460512547690907218143576318151806191448925475108267033107164151870350160042998390489896176497549251394610888513946685188843228152629178778637403474201188907053863746668760860263213534585955098314558884317052225880264856332882449007773841238225943757567450339131230630250571622658802018229254687419262917301560036586119378144208275262980461271154009501600997287608659362505721899625057786299954338263740289789748514575312300017164974857679871971364324645696066209425569995428153336991374967443993460118884942349337053868678561350242341731361682732769913129240365798520374028411671147697130489255309386374090572382265020612712098398719769473616832910736168887411065448374851400800859625676423411127276085968690983082465435756806177320536581106539254448102485078555104471229996043460448163979789672361353452832472793842881024240251476909621485139521782258808141600366410497485200683493376031723823199509830879584727943921847279988522176558485962511811970736777534522237387197079702094193566546867916288431647592217650355559213595189666215482341107144571559274090900783372464563933583904952992135351262588020722596250631893369919152711477511608596310794604487042834934300620941989695839054932958391089633287668597073622823081847878645633347498308190713205304667657979026399542758603328761456670324705300777326493452218245682670384202011894383575675034695016063103246462273699131823707361742004481030163822588612719707420905715598053946045401732053099806950165944069502190744398778708184733834192958979756744457609419301724316415768769090136510653869614439872557781435815411888437504563329346793781494313123005394686786135806127173214357573284810242924818472852115592141174933699713830818531016826709065057156502843164209918061276955180613291855509888819295844845304070080867855567720530412735427526869880201246621764980625550983658892546925522999548515674440447904892604424234116405797897236917238283325468684295921354025929583962226703252186044810814941929641127937820076168267603954275320029172387966291724392966620998930406955856415181181978966677831641523746538637970991312356732876091636662094760003658035634110659526785551549016003714535345227416909008338028349393436579795307032465127040695072337814363197155921916053040751239048931087279378705065386430140283498977402835494077732109041518066867526292283090077787942752634757649749072102423466843987202647773205861114769145745221770537896662650127114824646456338428020119439139460503547690906318143576228151806182448925474208267033017164151861350160042098390489806176497540251394609988513946595188843219152629177878637403384201188898053863745768760860173213534576955098313658884316962225880255856332881549007773751238225934757567449439131230540250571613658802017329254687329262917292560036585219378144118275262971461271153109501600907287608650362505720999625057696299954329263740288889748514485312300008164974856779871971274324645687066209424669995428063336991365967443992560118884852349337044868678560450242341641361682723769913128340365798430374028402671147696230489255219386374081572382264120612712008398719760473616832010736168797411065439374851399900859625586423411118276085967790983082375435756797177320535681106539164448102476078555103571229995953460448154979789671461353452742472793833881024239351476909531485139512782258807241600366320497485191683493375131723823109509830870584727943021847279898522176549485962510911970736687534522228387197078802094193476546867907288431646692217650265559213586189666214582341107054571559265090900782472464563843583904943992135350362588020632596250622893369918252711477421608596301794604486142834934210620941980695839054032958390999633287659597073621923081847788645633338498308189813205304577657979017399542757703328761366670324696300777325593452218155682670375202011893483575674944695016054103246461373699131733707361733004481029263822588522719707411905715597153946045311732053090806950165044069502100744398769708184732934192958889756744448609419300824316415678769090127510653868714439872467781435806411888436604563329256793781485313123004494686786045806127164214357572384810242834818472843115592140274933699623830818522016826708165057156412843164200918061276055180613201855509879819295843945304069990867855558720530411835427526779880201237621764979725550983568892546916522999547615674440357904892595424234115505797897146917238274325468683395921353935929583953226703251286044810724941929632127937819176168267513954275311029172387066291724302966620989930406954956415181091978966668831641522846538637880991312347732876090736662094670003658026634110658626785551459016003705535345226516909008248028349384436579794407032465037040695063337814362297155921826053040742239048930187279378615065386421140283498077402835404077732100041518065967526292193090077778942752633857649748982102423457843987201747773205771114769136745221769637896662560127114815646456337528020119349139460494547690905418143576138151806173448925473308267032927164151852350160041198390489716176497531251394609088513946505188843210152629176978637403294201188889053863744868760860083213534567955098312758884316872225880246856332880649007773661238225925757567448539131230450250571604658802016429254687239262917283560036584319378144028275262962461271152209501600817287608641362505720099625057606299954320263740287989748514395312299999164974855879871971184324645678066209423769995427973336991356967443991660118884762349337035868678559550242341551361682714769913127440365798340374028393671147695330489255129386374072572382263220612711918398719751473616831110736168707411065430374851399000859625496423411109276085966890983082285435756788177320534781106539074448102467078555102671229995863460448145979789670561353452652472793824881024238451476909441485139503782258806341600366230497485182683493374231723823019509830861584727942121847279808522176540485962510011970736597534522219387197077902094193386546867898288431645792217650175559213577189666213682341106964571559256090900781572464563753583904934992135349462588020542596250613893369917352711477331608596292794604485242834934120620941971695839053132958390909633287650597073621023081847698645633329498308188913205304487657979008399542756803328761276670324687300777324693452218065682670366202011892583575674854695016045103246460473699131643707361724004481028363822588432719707402905715596253946045221732053081806950164144069502010744398760708184732034192958799756744439609419299924316415588769090118510653867814439872377781435797411888435704563329166793781476313123003594686785955806127155214357571484810242744818472834115592139374933699533830818513016826707265057156322843164191918061275155180613111855509870819295843045304069900867855549720530410935427526689880201228621764978825550983478892546907522999546715674440267904892586424234114605797897056917238265325468682495921353845929583944226703250386044810634941929623127937818276168267423954275302029172386166291724212966620980930406954056415181001978966659831641521946538637790991312338732876089836662094580003658017634110657726785551369016003696535345225616909008158028349375436579793507032464947040695054337814361397155921736053040733239048929287279378525065386412140283497177402835314077732091041518065067526292103090077769942752632957649748892102423448843987200847773205681114769127745221768737896662470127114806646456336628020119259139460485547690904518143576048151806164448925472408267032837164151843350160040298390489626176497522251394608188513946415188843201152629176078637403204201188880053863743968760859993213534558955098311858884316782225880237856332879749007773571238225916757567447639131230360250571595658802015529254687149262917274560036583419378143938275262953461271151309501600727287608632362505719199625057516299954311263740287089748514305312299990164974854979871971094324645669066209422869995427883336991347967443990760118884672349337026868678558650242341461361682705769913126540365798250374028384671147694430489255039386374063572382262320612711828398719742473616830210736168617411065421374851398100859625406423411100276085965990983082195435756779177320533881106538984448102458078555101771229995773460448136979789669661353452562472793815881024237551476909351485139494782258805441600366140497485173683493373331723822929509830852584727941221847279718522176531485962509111970736507534522210387197077002094193296546867889288431644892217650085559213568189666212782341106874571559247090900780672464563663583904925992135348562588020452596250604893369916452711477241608596283794604484342834934030620941962695839052232958390819633287641597073620123081847608645633320498308188013205304397657978999399542755903328761186670324678300777323793452217975682670357202011891683575674764695016036103246459573699131553707361715004481027463822588342719707393905715595353946045131732053072806950163244069501920744398751708184731134192958709756744430609419299024316415498769090109510653866914439872287781435788411888434804563329076793781467313123002694686785865806127146214357570584810242654818472825115592138474933699443830818504016826706365057156232843164182918061274255180613021855509861819295842145304069810867855540720530410035427526599880201219621764977925550983388892546898522999545815674440177904892577424234113705797896966917238256325468681595921353755929583935226703249486044810544941929614127937817376168267333954275293029172385266291724122966620971930406953156415180911978966650831641521046538637700991312329732876088936662094490003658008634110656826785551279016003687535345224716909008068028349366436579792607032464857040695045337814360497155921646053040724239048928387279378435065386403140283496277402835224077732082041518064167526292013090077760942752632057649748802102423439843987199947773205591114769118745221767837896662380127114797646456335728020119169139460476547690903618143575958151806155448925471508267032747164151834350160039398390489536176497513251394607288513946325188843192152629175178637403114201188871053863743068760859903213534549955098310958884316692225880228856332878849007773481238225907757567446739131230270250571586658802014629254687059262917265560036582519378143848275262944461271150409501600637287608623362505718299625057426299954302263740286189748514215312299981164974854079871971004324645660066209421969995427793336991338967443989860118884582349337017868678557750242341371361682696769913125640365798160374028375671147693530489254949386374054572382261420612711738398719733473616829310736168527411065412374851397200859625316423411091276085965090983082105435756770177320532981106538894448102449078555100871229995683460448127979789668761353452472472793806881024236651476909261485139485782258804541600366050497485164683493372431723822839509830843584727940321847279628522176522485962508211970736417534522201387197076102094193206546867880288431643992217649995559213559189666211882341106784571559238090900779772464563573583904916992135347662588020362596250595893369915552711477151608596274794604483442834933940620941953695839051332958390729633287632597073619223081847518645633311498308187113205304307657978990399542755003328761096670324669300777322893452217885682670348202011890783575674674695016027103246458673699131463707361706004481026563822588252719707384905715594453946045041732053063806950162344069501830744398742708184730234192958619756744421609419298124316415408769090100510653866014439872197781435779411888433904563328986793781458313123001794686785775806127137214357569684810242564818472816115592137574933699353830818495016826705465057156142843164173918061273355180612931855509852819295841245304069720867855531720530409135427526509880201210621764977025550983298892546889522999544915674440087904892568424234112805797896876917238247325468680695921353665929583926226703248586044810454941929605127937816476168267243954275284029172384366291724032966620962930406952256415180821978966641831641520146538637610991312320732876088036662094400003657999634110655926785551189016003678535345223816909007978028349357436579791707032464767040695036337814359597155921556053040715239048927487279378345065386394140283495377402835134077732073041518063267526291923090077751942752631157649748712102423430843987199047773205501114769109745221766937896662290127114788646456334828020119079139460467547690902718143575868151806146448925470608267032657164151825350160038498390489446176497504251394606388513946235188843183152629174278637403024201188862053863742168760859813213534540955098310058884316602225880219856332877949007773391238225898757567445839131230180250571577658802013729254686969262917256560036581619378143758275262935461271149509501600547287608614362505717399625057336299954293263740285289748514125312299972164974853179871970914324645651066209421069995427703336991329967443988960118884492349337008868678556850242341281361682687769913124740365798070374028366671147692630489254859386374045572382260520612711648398719724473616828410736168437411065403374851396300859625226423411082276085964190983082015435756761177320532081106538804448102440078555099971229995593460448118979789667861353452382472793797881024235751476909171485139476782258803641600365960497485155683493371531723822749509830834584727939421847279538522176513485962507311970736327534522192387197075202094193116546867871288431643092217649905559213550189666210982341106694571559229090900778872464563483583904907992135346762588020272596250586893369914652711477061608596265794604482542834933850620941944695839050432958390639633287623597073618323081847428645633302498308186213205304217657978981399542754103328761006670324660300777321993452217795682670339202011889883575674584695016018103246457773699131373707361697004481025663822588162719707375905715593553946044951732053054806950161444069501740744398733708184729334192958529756744412609419297224316415318769090091510653865114439872107781435770411888433004563328896793781449313123000894686785685806127128214357568784810242474818472807115592136674933699263830818486016826704565057156052843164164918061272455180612841855509843819295840345304069630867855522720530408235427526419880201201621764976125550983208892546880522999544015674439997904892559424234111905797896786917238238325468679795921353575929583917226703247686044810364941929596127937815576168267153954275275029172383466291723942966620953930406951356415180731978966632831641519246538637520991312311732876087136662094310003657990634110655026785551099016003669535345222916909007888028349348436579790807032464677040695027337814358697155921466053040706239048926587279378255065386385140283494477402835044077732064041518062367526291833090077742942752630257649748622102423421843987198147773205411114769100745221766037896662200127114779646456333928020118989139460458547690901818143575778151806137448925469708267032567164151816350160037598390489356176497495251394605488513946145188843174152629173378637402934201188853053863741268760859723213534531955098309158884316512225880210856332877049007773301238225889757567444939131230090250571568658802012829254686879262917247560036580719378143668275262926461271148609501600457287608605362505716499625057246299954284263740284389748514035312299963164974852279871970824324645642066209420169995427613336991320967443988060118884402349336999868678555950242341191361682678769913123840365797980374028357671147691730489254769386374036572382259620612711558398719715473616827510736168347411065394374851395400859625136423411073276085963290983081925435756752177320531181106538714448102431078555099071229995503460448109979789666961353452292472793788881024234851476909081485139467782258802741600365870497485146683493370631723822659509830825584727938521847279448522176504485962506411970736237534522183387197074302094193026546867862288431642192217649815559213541189666210082341106604571559220090900777972464563393583904898992135345862588020182596250577893369913752711476971608596256794604481642834933760620941935695839049532958390549633287614597073617423081847338645633293498308185313205304127657978972399542753203328760916670324651300777321093452217705682670330202011888983575674494695016009103246456873699131283707361688004481024763822588072719707366905715592653946044861732053045806950160544069501650744398724708184728434192958439756744403609419296324316415228769090082510653864214439872017781435761411888432104563328806793781440313122999994686785595806127119214357567884810242384818472798115592135774933699173830818477016826703665057155962843164155918061271555180612751855509834819295839445304069540867855513720530407335427526329880201192621764975225550983118892546871522999543115674439907904892550424234111005797896696917238229325468678895921353485929583908226703246786044810274941929587127937814676168267063954275266029172382566291723852966620944930406950456415180641978966623831641518346538637430991312302732876086236662094220003657981634110654126785551009016003660535345222016909007798028349339436579789907032464587040695018337814357797155921376053040697239048925687279378165065386376140283493577402834954077732055041518061467526291743090077733942752629357649748532102423412843987197247773205321114769091745221765137896662110127114770646456333028020118899139460449547690900918143575688151806128448925468808267032477164151807350160036698390489266176497486251394604588513946055188843165152629172478637402844201188844053863740368760859633213534522955098308258884316422225880201856332876149007773211238225880757567444039131230000250571559658802011929254686789262917238560036579819378143578275262917461271147709501600367287608596362505715599625057156300");
+
+ // See pull request #21
+ // https://github.com/peterolson/BigInteger.js/pull/21
+ expect(bigInt("50000005000000").times("10000001")).toEqualBigInt("500000100000005000000");
+ });
+ });
+
+ describe("Division", function () {
+ it("by 1 is the identity", function () {
+ expect(bigInt(1).over(1)).toEqualBigInt(1);
+ expect(bigInt(-1).over(1)).toEqualBigInt(-1);
+ expect(bigInt(1).over(-1)).toEqualBigInt(-1);
+ expect(bigInt(153).over(1)).toEqualBigInt(153);
+ expect(bigInt(-153).over(1)).toEqualBigInt(-153);
+ expect(bigInt("9844190321790980841789").over(1)).toEqualBigInt("9844190321790980841789");
+ expect(bigInt("-9844190321790980841789").over(1)).toEqualBigInt("-9844190321790980841789");
+ });
+
+ it("by self is 1", function () {
+ expect(bigInt(5).over(5)).toEqualBigInt(1);
+ expect(bigInt(-5).over(-5)).toEqualBigInt(1);
+ expect(bigInt("20194965098495006574").over("20194965098495006574")).toEqualBigInt(1);
+ expect(bigInt("-20194965098495006574").over("-20194965098495006574")).toEqualBigInt(1);
+ });
+
+ it("by 0 throws an error", function () {
+ expect(function () {
+ bigInt(0).over(0);
+ }).toThrow();
+ expect(function () {
+ bigInt(-0).over(0);
+ }).toThrow();
+ expect(function () {
+ bigInt(5).over(0);
+ }).toThrow();
+ expect(function () {
+ bigInt(-5).over(0);
+ }).toThrow();
+ expect(function () {
+ bigInt("9549841598749874951041").over(0);
+ }).toThrow();
+ expect(function () {
+ bigInt("-20964918940987496110974948").over(0);
+ }).toThrow();
+ });
+
+ it("of 0 equals 0", function () {
+ expect(bigInt(0).over(1)).toEqualBigInt(0);
+ expect(bigInt(-0).over(1)).toEqualBigInt(0);
+ expect(bigInt(-0).over("1234567890987654321")).toEqualBigInt(0);
+ expect(bigInt(0).over("-1234567890987654321")).toEqualBigInt(0);
+ });
+
+ it("handles signs correctly", function () {
+ expect(bigInt(10000).over(100)).toEqualBigInt(100);
+ expect(bigInt(10000).over(-100)).toEqualBigInt(-100);
+ expect(bigInt(-10000).over(100)).toEqualBigInt(-100);
+ expect(bigInt(-10000).over(-100)).toEqualBigInt(100);
+ expect(bigInt(100).over(-1000)).toEqualBigInt(0);
+
+ expect(bigInt("163500573666152634716420931676158").over(13579)).toEqualBigInt("12040693251797086288859336598");
+ expect(bigInt("163500573666152634716420931676158").over(-13579)).toEqualBigInt("-12040693251797086288859336598");
+ expect(bigInt("-163500573666152634716420931676158").over(13579)).toEqualBigInt("-12040693251797086288859336598");
+ expect(bigInt("-163500573666152634716420931676158").over(-13579)).toEqualBigInt("12040693251797086288859336598");
+
+ expect(bigInt("1234567890987654321").over("132435465768798")).toEqualBigInt("9322");
+ expect(bigInt("1234567890987654321").over("-132435465768798")).toEqualBigInt("-9322");
+ expect(bigInt("-1234567890987654321").over("132435465768798")).toEqualBigInt("-9322");
+ expect(bigInt("-1234567890987654321").over("-132435465768798")).toEqualBigInt("9322");
+
+ expect(bigInt("786456456335437356436").over("-5423424653")).toEqualBigInt("-145011041298");
+ expect(bigInt("-93453764643534523").over("-2342")).toEqualBigInt("39903400787162");
+ expect(bigInt("10000000000000000").divide("-10000000000000000")).toEqualBigInt(-1);
+
+ expect(bigInt("98789789419609840614360398703968368740365403650364036403645046").over(-1)).toEqualBigInt("-98789789419609840614360398703968368740365403650364036403645046");
+ });
+
+ it("works", function () {
+ expect(bigInt("98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241").over("98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241")).toEqualBigInt("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ expect(bigInt(e).over(d)).toEqualBigInt("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ expect(bigInt("1e1050").over("1e1000")).toEqualBigInt("1e50");
+ expect(bigInt("650891045068740450350436540352434350243346254305240433565403624570436542564034355230360437856406345450735366803660233645540323657640436735034636550432635454032364560324366403643455063652403346540263364032643454530236455402336455640363263405423565405623454062354540326564062306456432664546654436564364556406435460643646363545606345066534456065340165344065234064564").over("2634565230452364554234565062345452365450236455423654456253445652344565423655423655462534506253450462354056523445062535462534052654350426355023654540625344056203455402635454026435501635446643754664546780646476442344654465764466744566754436556406235454066354570657548036545465")).toEqualBigInt("247058238507527885509216194910087226997858456323482112332514020694766925604284002588230023");
+ expect(bigInt("650891045068740450350436540352434350243346254305240433565403624570436542564034355230360437856406345450735366803660233645540323657640436735034636550432635454032364560324366403643455063652403346540263364032643454530236455402336455640363263405423565405623454062354540326564062306456432664546654436564364556406435460643646363545606345066534456065340165344065234064564000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").over("2634565230452364554234565062345452365450236455423654456253445652344565423655423655462534506253450462354056523445062535462534052654350426355023654540625344056203455402635454026435501635446643754664546780646476442344654465764466744566754436556406235454066354570657548036545465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")).toEqualBigInt("247058238507527885509216194910087226997858456323482112332514020694766925604284002588230023");
+ expect(bigInt("9999999999999900000000000000").divide("999999999999990000001")).toEqualBigInt("9999999"); // issue #58
+ expect(bigInt("1e9999").over("1e999")).toEqualBigInt("1e9000"); // issue #88
+ });
+ });
+
+ describe("Modulo", function () {
+ it("0 throws error", function () {
+ expect(function () {
+ bigInt(0).mod(0);
+ }).toThrow();
+ expect(function () {
+ bigInt(-0).mod(0);
+ }).toThrow();
+ expect(function () {
+ bigInt(5).mod(0);
+ }).toThrow();
+ expect(function () {
+ bigInt(-5).mod(0);
+ }).toThrow();
+ expect(function () {
+ bigInt("9549841598749874951041").mod(0);
+ }).toThrow();
+ expect(function () {
+ bigInt("-20964918940987496110974948").mod(0);
+ }).toThrow();
+ });
+
+ it("handles signs correctly", function () {
+ expect(bigInt(124234233).mod(2)).toEqualBigInt(1);
+ expect(bigInt(124234233).mod(-2)).toEqualBigInt(1);
+ expect(bigInt(-124234233).mod(2)).toEqualBigInt(-1);
+ expect(bigInt(-124234233).mod(-2)).toEqualBigInt(-1);
+ expect(bigInt(2).mod(-1243233)).toEqualBigInt(2);
+ expect(bigInt(-2).mod(-1243233)).toEqualBigInt(-2);
+
+ expect(bigInt("786456456335437356436").mod("-5423424653")).toEqualBigInt("2663036842");
+ expect(bigInt("93453764643534523").mod(-2342)).toEqualBigInt(1119);
+ expect(bigInt(-32542543).mod(100000000)).toEqualBigInt(-32542543);
+ });
+ });
+
+ describe("Power", function () {
+ it("of 0 to 0 is 1 (mathematically debatable, but matches JavaScript behavior)", function () {
+ expect(bigInt(0).pow(0)).toEqualBigInt(1);
+ expect(bigInt(0).pow("-0")).toEqualBigInt(1);
+ expect(bigInt("-0").pow(0)).toEqualBigInt(1);
+ expect(bigInt("-0").pow("-0")).toEqualBigInt(1);
+ });
+
+ it("to negative numbers is 0", function () {
+ expect(bigInt(0).pow(-298)).toEqualBigInt(0);
+ expect(bigInt(543).pow(-2)).toEqualBigInt(0);
+ expect(bigInt("323434643534523").pow(-1)).toEqualBigInt(0);
+ expect(bigInt(-54302).pow("-543624724341214223562")).toEqualBigInt(0);
+ expect(bigInt("-20199605604968").pow(-99)).toEqualBigInt(0);
+
+ expect(bigInt(1).pow(-1)).toEqualBigInt(1);
+ expect(bigInt(-1).pow(-1)).toEqualBigInt(-1);
+ expect(bigInt(-1).pow(-2)).toEqualBigInt(1);
+ });
+
+ it("handles signs correctly", function () {
+ expect(bigInt(2).pow(3)).toEqualBigInt(8);
+ expect(bigInt(-2).pow(3)).toEqualBigInt(-8);
+ expect(bigInt("1036350201654").pow(4)).toEqualBigInt("1153522698998527286707879497611725813209153232656");
+ expect(bigInt("-1036350201654").pow(4)).toEqualBigInt("1153522698998527286707879497611725813209153232656");
+ expect(bigInt("-154654987").pow(3)).toEqualBigInt("-3699063497752861435082803");
+
+ expect(bigInt(1).pow(1)).toEqualBigInt(1);
+ expect(bigInt(-1).pow(1)).toEqualBigInt(-1);
+ expect(bigInt(-1).pow(2)).toEqualBigInt(1);
+ });
+
+ it("carries over correctly", function () {
+ expect(bigInt("16").pow("13")).toEqualBigInt("4503599627370496");
+ expect(bigInt("123456789123456789").pow("10")).toEqualBigInt("822526267372365207989468699031914332476569003445489153619518989325083908083922133639704420166045905346960117046949453426283086050487204639652635846010822673782217799736601");
+ expect(bigInt("2").pow("63")).toEqualBigInt("9223372036854775808");
+ // See issue #5
+ // https://github.com/peterolson/BigInteger.js/issues/5
+ expect(bigInt(100).pow(56).toString()).not.toEqualBigInt("0");
+
+ });
+
+ it("throws an error when the exponent is too large", function () {
+ try {
+ bigInt(2).pow("1e100");
+ expect(true).toBe(false);
+ } catch (e) {
+ expect(true).toBe(true);
+ }
+ expect(bigInt(1).pow("1e100")).toEqualBigInt(1);
+ expect(bigInt(-1).pow("1e100")).toEqualBigInt(1);
+ expect(bigInt(0).pow("1e100")).toEqualBigInt(0);
+ });
+
+ it("throws an error when the exponent is not an integer", function () {
+ expect(function () {
+ bigInt(5).pow(1 / 2);
+ }).toThrow();
+ });
+ });
+
+ describe("Power modulo", function () {
+ it("works", function () {
+ expect(bigInt(4).modPow(13, 497)).toEqualBigInt(445);
+
+ // See Project Euler problem #97
+ // https://projecteuler.net/problem=97
+ expect(bigInt(28433).times(bigInt(2).modPow(7830457, "1e10")).plus(1).mod("1e10")).toEqualBigInt(8739992577);
+ expect(bigInt(0).modPow(4, 20)).toEqualBigInt(0);
+ expect(bigInt(0).modPow(0, 20)).toEqualBigInt(1);
+ try {
+ bigInt(4).modPow(9, 0);
+ expect(true).toBe(false);
+ } catch (e) {
+ expect(true).toBe(true);
+ }
+ });
+ });
+
+ describe("Modular multiplicative inverse", function () {
+ it("works", function () {
+ expect(bigInt(3).modInv(11)).toEqualBigInt(4);
+ expect(bigInt(42).modInv(2017)).toEqualBigInt(1969);
+ expect(bigInt(-50).modInv(83)).toEqualBigInt(-5); // issue #87
+ expect(function () {
+ bigInt(154).modInv(3311);
+ }).toThrow();
+ });
+ });
+
+ describe("Square", function () {
+ it("works", function () {
+ expect(bigInt(0).square()).toEqualBigInt(0);
+ expect(bigInt(16).square()).toEqualBigInt(256);
+ expect(bigInt(-16).square()).toEqualBigInt(256);
+ expect(bigInt("65536").square()).toEqualBigInt("4294967296");
+ });
+ });
+
+ describe("prev and next", function () {
+ it("work", function () {
+ expect(bigInt(0).next()).toEqualBigInt(1);
+ expect(bigInt(-1).next()).toEqualBigInt(0);
+ expect(bigInt(34).next()).toEqualBigInt(35);
+ expect(bigInt("9007199254740992").next()).toEqualBigInt("9007199254740993");
+ expect(bigInt("-9007199254740992").next()).toEqualBigInt("-9007199254740991");
+ expect(bigInt("9007199254740992999").next()).toEqualBigInt("9007199254740993000");
+ expect(bigInt("9007199254740991").next()).toEqualBigInt("9007199254740992");
+
+ expect(bigInt(0).prev()).toEqualBigInt(-1);
+ expect(bigInt(-1).prev()).toEqualBigInt(-2);
+ expect(bigInt(34).prev()).toEqualBigInt(33);
+ expect(bigInt("9007199254740992").prev()).toEqualBigInt("9007199254740991");
+ expect(bigInt("-9007199254740992").prev()).toEqualBigInt("-9007199254740993");
+ expect(bigInt("9007199254740992999").prev()).toEqualBigInt("9007199254740992998");
+ expect(bigInt("-9007199254740991").prev()).toEqualBigInt("-9007199254740992");
+ });
+ });
+
+ describe("min and max", function () {
+ it("work", function () {
+ expect(bigInt.max(6, 6)).toEqualBigInt(6);
+ expect(bigInt.max(77, 432)).toEqualBigInt(432);
+ expect(bigInt.max(432, 77)).toEqualBigInt(432);
+ expect(bigInt.max(77, -432)).toEqualBigInt(77);
+ expect(bigInt.max(432, -77)).toEqualBigInt(432);
+ expect(bigInt.max(-77, 432)).toEqualBigInt(432);
+ expect(bigInt.max(-432, 77)).toEqualBigInt(77);
+ expect(bigInt.max(-77, -432)).toEqualBigInt(-77);
+ expect(bigInt.max(-432, -77)).toEqualBigInt(-77);
+
+ expect(bigInt.min(6, 6)).toEqualBigInt(6);
+ expect(bigInt.min(77, 432)).toEqualBigInt(77);
+ expect(bigInt.min(432, 77)).toEqualBigInt(77);
+ expect(bigInt.min(77, -432)).toEqualBigInt(-432);
+ expect(bigInt.min(432, -77)).toEqualBigInt(-77);
+ expect(bigInt.min(-77, 432)).toEqualBigInt(-77);
+ expect(bigInt.min(-432, 77)).toEqualBigInt(-432);
+ expect(bigInt.min(-77, -432)).toEqualBigInt(-432);
+ expect(bigInt.min(-432, -77)).toEqualBigInt(-432);
+ });
+ });
+
+ describe("lcm and gcd", function () {
+ it("work", function () {
+ expect(bigInt.lcm(21, 6)).toEqualBigInt(42);
+ expect(bigInt.gcd(42, 56)).toEqualBigInt(14);
+ expect(bigInt.gcd(0, 56)).toEqualBigInt(56);
+ expect(bigInt.gcd(42, 0)).toEqualBigInt(42);
+ expect(bigInt.gcd(17, 103)).toEqualBigInt(1);
+ expect(bigInt.gcd(192, 84)).toEqualBigInt(12);
+ });
+ });
+
+ describe("Increment and decrement", function () {
+ it("works for small values", function () {
+ expect(bigInt(546).prev()).toEqualBigInt(545);
+ expect(bigInt(1).prev()).toEqualBigInt(0);
+ expect(bigInt(0).prev()).toEqualBigInt(-1);
+ expect(bigInt(-1).prev()).toEqualBigInt(-2);
+ expect(bigInt(-1987).prev()).toEqualBigInt(-1988);
+
+ expect(bigInt(546).next()).toEqualBigInt(547);
+ expect(bigInt(1).next()).toEqualBigInt(2);
+ expect(bigInt(0).next()).toEqualBigInt(1);
+ expect(bigInt(-1).next()).toEqualBigInt(0);
+ expect(bigInt(-1987).next()).toEqualBigInt(-1986);
+ });
+ it("works for large values", function () {
+ expect(bigInt("109874981950949849811049").prev()).toEqualBigInt("109874981950949849811048");
+ expect(bigInt("109874981950949849811049").next()).toEqualBigInt("109874981950949849811050");
+ expect(bigInt("-109874981950949849811049").prev()).toEqualBigInt("-109874981950949849811050");
+ expect(bigInt("-109874981950949849811049").next()).toEqualBigInt("-109874981950949849811048");
+ });
+ it("carries over correctly", function () {
+ expect(bigInt(9999999).next()).toEqualBigInt(10000000);
+ expect(bigInt(10000000).prev()).toEqualBigInt(9999999);
+ });
+ });
+
+ describe("Absolute value", function () {
+ it("works", function () {
+ expect(bigInt(0).abs()).toEqualBigInt(0);
+ expect(bigInt("-0").abs()).toEqualBigInt(0);
+ expect(bigInt(54).abs()).toEqualBigInt(54);
+ expect(bigInt(-54).abs()).toEqualBigInt(54);
+ expect(bigInt("13412564654613034984065434").abs()).toEqualBigInt("13412564654613034984065434");
+ expect(bigInt("-13412564654613034984065434").abs()).toEqualBigInt("13412564654613034984065434");
+ });
+ });
+
+ describe("isPositive and isNegative", function () {
+ it("return `false` for 0 and -0", function () {
+ expect(bigInt(0).isPositive()).toBe(false);
+ expect(bigInt(0).isNegative()).toBe(false);
+ expect(bigInt(-0).isPositive()).toBe(false);
+ expect(bigInt(-0).isNegative()).toBe(false);
+ });
+
+ it("work for small numbers", function () {
+ expect(bigInt(1).isPositive()).toBe(true);
+ expect(bigInt(543).isNegative()).toBe(false);
+ expect(bigInt(-1).isPositive()).toBe(false);
+ expect(bigInt(-765).isNegative()).toBe(true);
+ });
+
+ it("work for big numbers", function () {
+ expect(bigInt("651987498619879841").isPositive()).toBe(true);
+ expect(bigInt("0054984980098460").isNegative()).toBe(false);
+ expect(bigInt("-1961987984109078496").isPositive()).toBe(false);
+ expect(bigInt("-98800984196109540984").isNegative()).toBe(true);
+ });
+ });
+
+ describe("isEven and isOdd", function () {
+ it("work correctly", function () {
+ expect(bigInt(0).isEven()).toBe(true);
+ expect(bigInt(0).isOdd()).toBe(false);
+
+ expect(bigInt(654).isEven()).toBe(true);
+ expect(bigInt(654).isOdd()).toBe(false);
+
+ expect(bigInt(653).isOdd()).toBe(true);
+ expect(bigInt(653).isEven()).toBe(false);
+
+ expect(bigInt(-984).isEven()).toBe(true);
+ expect(bigInt(-984).isOdd()).toBe(false);
+
+ expect(bigInt(-987).isOdd()).toBe(true);
+ expect(bigInt(-987).isEven()).toBe(false);
+
+ expect(bigInt("9888651888888888").isEven()).toBe(true);
+ expect(bigInt("9888651888888888").isOdd()).toBe(false);
+
+ expect(bigInt("1026377777777777").isOdd()).toBe(true);
+ expect(bigInt("1026377777777777").isEven()).toBe(false);
+
+ expect(bigInt("-9888651888888888").isEven()).toBe(true);
+ expect(bigInt("-9888651888888888").isOdd()).toBe(false);
+
+ expect(bigInt("-1026377777777777").isOdd()).toBe(true);
+ expect(bigInt("-1026377777777777").isEven()).toBe(false);
+ });
+ });
+
+ describe("isDivisibleBy", function () {
+ it("works", function () {
+ expect(bigInt(999).isDivisibleBy(333)).toBe(true);
+ expect(bigInt(999).isDivisibleBy(331)).toBe(false);
+ expect(bigInt(999).isDivisibleBy(0)).toBe(false);
+ expect(bigInt(999).isDivisibleBy(1)).toBe(true);
+ expect(bigInt(999).isDivisibleBy(2)).toBe(false);
+ });
+ });
+
+ var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571];
+
+ describe("isPrime", function () {
+ it("correctly identifies prime numbers", function () {
+ for (var i = 0; i < primes.length; i++) {
+ expect(bigInt(primes[i]).isPrime()).toBe(true);
+ }
+ });
+ it("correctly identifies pseudo primes", function () {
+ var largePrimes = ["3825123056546413051", "3825123056546413051", "3825123056546413051", "318665857834031151167461"];
+ for (var i = 0; i < largePrimes.length; i++) {
+ expect(bigInt(largePrimes[i]).isPrime()).toBe(false);
+ }
+ });
+ it("correctly rejects nonprime numbers", function () {
+ var nonPrimes = [1, 4, 3 * 5, 4 * 7, 7 * 17, 3 * 103, 17 * 97, 7917];
+ for (var i = 0; i < nonPrimes.length; i++) {
+ expect(bigInt(nonPrimes[i]).isPrime()).toBe(false);
+ }
+ });
+ });
+
+ describe("isProbablePrime", function () {
+ it("returns true for any prime", function () {
+ for (var i = 0; i < primes.length; i++) {
+ expect(bigInt(primes[i]).isProbablePrime()).toBe(true);
+ }
+ });
+ it("returns false for any Carmichael number", function () {
+ var carmichaelNumbers = [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973, 75361, 101101, 115921, 126217, 162401, 172081, 188461, 252601, 278545, 294409, 314821, 334153, 340561, 399001, 410041, 449065, 488881, 512461];
+ for (var i = 0; i < carmichaelNumbers.length; i++) {
+ expect(bigInt(carmichaelNumbers[i]).isProbablePrime()).toBe(false);
+ }
+ });
+ it("has false positive rate less than 0.1%", function () {
+ var totalPrimes = 0, falsePrimes = 0;
+ for (var i = 1; i < 1e4; i++) {
+ var x = bigInt(i);
+ if (x.isPrime()) {
+ totalPrimes++;
+ } else if (x.isProbablePrime()) {
+ falsePrimes++;
+ }
+ }
+ expect(falsePrimes / totalPrimes < 0.001).toBe(true);
+ });
+ });
+
+ describe("isUnit", function () {
+ it("works", function () {
+ expect(bigInt.one.isUnit()).toBe(true);
+ expect(bigInt.minusOne.isUnit()).toBe(true);
+ expect(bigInt.zero.isUnit()).toBe(false);
+ expect(bigInt(5).isUnit()).toBe(false);
+ expect(bigInt(-5).isUnit()).toBe(false);
+ expect(bigInt("654609649089416160").isUnit()).toBe(false);
+ expect(bigInt("-98410980984981094").isUnit()).toBe(false);
+ });
+ });
+
+ describe("isZero", function () {
+ it("works", function () {
+ expect(bigInt.zero.isZero()).toBe(true);
+ expect(bigInt(0).isZero()).toBe(true);
+ expect(bigInt("-0").isZero()).toBe(true);
+ expect(bigInt(15).isZero()).toBe(false);
+ expect(bigInt(-15).isZero()).toBe(false);
+ expect(bigInt("63213098189462109840").isZero()).toBe(false);
+ expect(bigInt("-64343745644564564563").isZero()).toBe(false);
+ expect(bigInt().isZero()).toBe(true);
+ expect(bigInt(0, 10).isZero()).toBe(true);
+ });
+ });
+
+ describe("Throw error in input with", function () {
+ function test(input) {
+ expect(function () {
+ bigInt(input);
+ }).toThrow();
+ }
+ it("multiple minus signs at the beginning", function () {
+ test("--123");
+ test("---1423423");
+ });
+
+ it("non-numeric symbols", function () {
+ test("43a34");
+ test("4+7=11");
+ })
+
+ it("multiple exponents", function () {
+ test("43e4e6");
+ test("234234e43523e4354");
+ try {
+ bigInt("4e5e5");
+ } catch (e) {
+ expect(e instanceof TypeError).toBe(false);
+ }
+ });
+
+ it("decimal point when exponent is too small", function () {
+ test("1.24595e3");
+ })
+
+ describe("but not with", function () {
+ it("e or E for the exponent", function () {
+ expect(bigInt("2e7").equals("2E7")).toBe(true);
+ });
+
+ it("e+ or E+ for the exponent", function () {
+ expect(bigInt("2e7").equals("2E+7")).toBe(true);
+ expect(bigInt("1.7976931348623157e+308").equals("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")).toBe(true);
+ });
+
+ it("decimal point when exponent is large enough", function () {
+ expect(bigInt("1.32e2").equals("132")).toBe(true);
+ });
+ });
+ });
+
+ describe("toString", function () {
+ it("works for leading and trailing zeroes", function () {
+ expect(bigInt("10000000").toString() === "10000000").toBe(true);
+ expect(bigInt("100001010000000").toString() === "100001010000000").toBe(true);
+ expect(bigInt("00000000010000000").toString() === "10000000").toBe(true);
+ expect(bigInt("00000000100001010000000").toString() === "100001010000000").toBe(true);
+ });
+
+ // See issue #13
+ // https://github.com/peterolson/BigInteger.js/issues/13
+ it("of 0*-1 is '0'", function () {
+ expect(bigInt(0).multiply(-1).toString() === "0").toBe(true);
+ });
+
+ // See pull request #16
+ // https://github.com/peterolson/BigInteger.js/pull/16
+ it("of (0/1)-100 is '-100'", function () {
+ expect((bigInt("0")).divide(bigInt("1")).add(bigInt("-100")).toString() === "-100").toBe(true);
+ });
+ });
+
+ describe("valueOf and toJSNumber", function () {
+ it("works", function () {
+ expect(bigInt(100) + bigInt(200) == 300).toBe(true);
+ expect(bigInt("100000000000300") - bigInt("100000000000000") == 300).toBe(true);
+ expect(bigInt(100).valueOf() == 100).toBe(true);
+ expect(bigInt(43.9e30) == 43.9e30).toBe(true);
+ expect(bigInt("1.11e+30").toJSNumber() == 1.11e+30).toBe(true);
+ expect(bigInt(100).toJSNumber() === 100).toBe(true);
+ expect(bigInt("1e30").toJSNumber() === 1e30).toBe(true);
+ expect(bigInt("100000000000000008193").toJSNumber()).toBe(100000000000000016384);
+ });
+ });
+
+ describe("Base conversion", function () {
+ it("parses numbers correctly", function () {
+ expect(bigInt("10", 2).equals(2)).toBe(true);
+ expect(bigInt("FF", 16)).toEqualBigInt(255);
+ expect(bigInt("111100001111", -2)).toEqualBigInt(-1285);
+ expect(bigInt("<5><10>35<75><44><88><145735>", "-154654987")).toEqualBigInt("-10580775516023906041313915824083789618333601575504631498551");
+
+ // See pull request 16
+ // https://github.com/peterolson/BigInteger.js/pull/15
+ expect(bigInt("-1", 16)).toEqualBigInt(-1);
+ expect(bigInt("306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000")).toEqualBigInt(bigInt("9822997e35bb99bcf103a64299aa92b8446ab93879fba53349f1626f3c8f78a4ee1d8d9e7562538f8e374fdf64c8eff7481c63cde5ca9821abfb3df6fb3e2489d2f85d34cf347f3e89191a19cc6b6b8072a976a8f1bcf68d20f18a1c0efb023252ba2d0961428a5c282d2645f3f7fa160f7f84aca88e40a74066c4a787bed7d0082f7e45b1ffee532715f56bd5f8168eaf7eaae112ed1316371f047692631e70e6b85b290ef063845b364dad7e10b9deb9fcfb708f83b7c3c6b82ce16eb0034c030b332a58d637a7b547fd0527051d7de9e5004db2ea2bd75f5c5a280a1a9b93c3c83373b6dcf1b65c01197096e97d13076b6613bc2ebf47c91fbe1aefeea966134bfbbf5f850320f0f0c2d88888bd82d118a6aaf8df2b092cf5456eff7e209feb476bf3c01d6d2e7ca0b9f40d83b107b4def92f2927cf0a1bb6190c67a4da91478709262ed1f1ecb77fbaf1197ac238c246a63a697f51e8d539f850e790137e7fce5f764896fdfb4fc3787520608f0400e72aeea5737c36304c6887ec1a174564ecec63a57b1e0946dc311dd3aea7bfae197ff9c7fcbf17c97d9db303d231702ef502dde1b53896196dc2e5d30b2b6ec58fc3744f4de08109eb99aa9f22ffe2f12f3953f516f91d35a8852aff4a19e250410fbd8dbcdae99f92f88e2f94341fc1ecdff32733d194c0541f708a72c5b4c03e5515e1086d0903addca0e172968ff1dee87bbd4fee679e2ee5a52975807ae7212cc2a33e0821e2d9b44eaa7dc29536a94c6597eda41bdd1e5e618e7b388b53d38ef9542523bce888738db46c6706c3ee82cbc3655408071e9e422a44d309e3cfd31ec2135ee0cba32b0c6721c8bee4d076543b71c35a06087a007c14e51d1f0c4d0aa9aa0751dfd3776d2357a010e6b147aca40c7b669291e6defbf5ca77505c960f14b330e6c90dc2539431329ef78a1e9f26b2ead7d28a622e6b586bcee22bd0a495442c6a1235588988252cbd4d36975560fb8e7e5c8cf06f29aeb68659c5cb4cf8d011375b00000000000000000000000000000000000000000000000000000000000000000000000000", 16));
+ expect(bigInt("9223372036854775808")).toEqualBigInt(bigInt("1000000000000000000000000000000000000000000000000000000000000000", 2));
+ expect(bigInt("324AFCCC342342333CCD239998881232324AFCCC342342333CCD239998881232", 16)).toEqualBigInt("22748133857356174891035811692236022265357659892433333914058690475216129757746");
+ expect(bigInt("234345345345")).toEqualBigInt(bigInt("3690123141", 16));
+ expect(bigInt("-10", 16)).toEqualBigInt("-16");
+ });
+
+ it("errors on invalid input", function () {
+ expect(function () {
+ bigInt("$,%@#^", "55");
+ }).toThrow();
+ // See issue 101
+ // https://github.com/peterolson/BigInteger.js/issues/101
+ expect(function () {
+ bigInt("0x10000", 16);
+ }).toThrow();
+ expect(function () {
+ bigInt("a9", 10);
+ }).toThrow();
+ expect(function () {
+ bigInt("33", 2);
+ }).toThrow();
+ });
+
+ it("outputs numbers correctly", function () {
+ expect(bigInt("366900685503779409298642816707647664013657589336").toString(16) === "4044654fce69424a651af2825b37124c25094658").toBe(true);
+ expect(bigInt("111111111111111111111111111111111111111111111111111111", 2).toString(2) === "111111111111111111111111111111111111111111111111111111").toBe(true);
+ expect(bigInt("secretmessage000", -36).toString(-36) === "secretmessage000").toBe(true);
+ expect(bigInt(-256).toString(16) === "-100").toBe(true);
+ expect(bigInt(256).toString(1).length === 256).toBe(true);
+ expect(bigInt(bigInt(77).toString(-1), -1)).toEqualBigInt(77);
+ expect(function () {
+ bigInt(10).toString(0);
+ }).toThrow();
+
+ // see issue #67
+ // https://github.com/peterolson/BigInteger.js/issues/67
+ expect(bigInt(36).toString(40) === "<36>").toBe(true);
+ });
+
+ it("converts to arrays correctly", function () {
+ expect(bigInt("1e9").toArray(10)).toEqual({
+ value: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ isNegative: false
+ });
+
+ expect(bigInt("1e20").toArray(10)).toEqual({
+ value: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ isNegative: false
+ });
+
+ expect(bigInt("1e9").toArray(16)).toEqual({
+ value: [3, 11, 9, 10, 12, 10, 0, 0],
+ isNegative: false
+ });
+
+ expect(bigInt(567890).toArray(100)).toEqual({
+ value: [56, 78, 90],
+ isNegative: false
+ });
+
+ expect(bigInt(12345).toArray(-10)).toEqual({
+ value: [2, 8, 4, 6, 5],
+ isNegative: false
+ });
+
+ expect(bigInt(-15).toArray(1)).toEqual({
+ value: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+ isNegative: true
+ });
+
+ expect(bigInt(0).toArray(1)).toEqual({
+ value: [0],
+ isNegative: false
+ });
+
+ expect(bigInt(-15).toArray(-1)).toEqual({
+ value: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
+ isNegative: false
+ });
+
+ expect(bigInt(0).toArray(-1)).toEqual({
+ value: [0],
+ isNegative: false
+ });
+
+ expect(bigInt(0).toArray(0)).toEqual({
+ value: [0],
+ isNegative: false
+ });
+
+ expect(function () { return bigInt(1).toArray(0); }).toThrow();
+ });
+
+ it("allows custom alphabet", function () {
+ expect(bigInt("9786534201", 10, "9786534201")).toEqualBigInt("0123456789");
+ expect(bigInt("bC", 3, "abc")).toEqualBigInt("5");
+ expect(bigInt("AAa", 2, "aA", true)).toEqualBigInt("6");
+ expect(bigInt("10").toString(2, "Aa")).toEqual("aAaA");
+ });
+ });
+
+ describe("Bitwise operations", function () {
+ it("shifting left and right work", function () {
+ expect(bigInt(-5).shiftRight(2)).toEqualBigInt(-2);
+ expect(bigInt(5).shiftRight(-2)).toEqualBigInt(20);
+ expect(bigInt(5).shiftLeft(-2)).toEqualBigInt(1);
+ expect(bigInt(1024).shiftLeft(100)).toEqualBigInt("1298074214633706907132624082305024");
+ expect(bigInt("2596148429267413814265248164610049").shiftRight(100)).toEqualBigInt(2048);
+ expect(bigInt("8589934592").shiftRight(-50)).toEqualBigInt("9671406556917033397649408");
+ expect(bigInt("38685626227668133590597632").shiftLeft(-50)).toEqualBigInt("34359738368");
+ expect(bigInt("-1").shiftRight(25)).toEqualBigInt(-1);
+ expect(bigInt(1).shiftLeft(bigInt(1))).toEqualBigInt(2); // https://github.com/peterolson/BigInteger.js/issues/163
+ });
+
+ it("shifting left and right throw for large shifts", function () {
+ expect(function () {
+ bigInt(5).shiftLeft("5e10");
+ }).toThrow();
+ expect(function () {
+ bigInt(5).shiftRight("5e10");
+ }).toThrow();
+ });
+
+ it("and, or, xor, and not work", function () {
+ expect(bigInt("435783453").and("902345074")).toEqualBigInt("298352912");
+ expect(bigInt("435783453").or("902345074")).toEqualBigInt("1039775615");
+ expect(bigInt("435783453").xor("902345074")).toEqualBigInt("741422703");
+ expect(bigInt("94981987261387596").not()).toEqualBigInt("-94981987261387597");
+ expect(bigInt("-6931047708307681506").xor("25214903917")).toEqualBigInt("-6931047723896018573");
+ expect(bigInt("-6931047723896018573").and("281474976710655")).toEqualBigInt("273577603885427");
+ expect(bigInt("-65").xor("-42")).toEqualBigInt("105");
+ expect(bigInt("6").and("-3")).toEqualBigInt("4");
+ expect(bigInt("0").not()).toEqualBigInt("-1");
+ expect(bigInt("13").or(-8)).toEqualBigInt("-3");
+ expect(bigInt("12").xor(-5)).toEqualBigInt("-9");
+ });
+
+ it("bitLength works", function () {
+ expect(bigInt(0).bitLength()).toEqualBigInt(0);
+ expect(bigInt(1).bitLength()).toEqualBigInt(1);
+ expect(bigInt(3).bitLength()).toEqualBigInt(2);
+ expect(bigInt(16).bitLength()).toEqualBigInt(5);
+ expect(bigInt(2).pow(49).bitLength()).toEqualBigInt(50);
+ });
+ });
+
+ describe("randBetween", function () {
+ it("return numbers in correct range", function () {
+ expect(bigInt.randBetween(0, 10).leq(10)).toBe(true);
+ expect(bigInt.randBetween(0, 10).geq(0)).toBe(true);
+
+ expect(bigInt.randBetween(0, "9e99").leq("9e99")).toBe(true);
+ expect(bigInt.randBetween(0, "9e99").geq(0)).toBe(true);
+
+ expect(bigInt.randBetween("-9e99", 10).leq(10)).toBe(true);
+ expect(bigInt.randBetween("-9e99", 10).geq("-9e99")).toBe(true);
+
+ expect(bigInt.randBetween("-9e99", "9e99").leq("9e99")).toBe(true);
+ expect(bigInt.randBetween("-9e99", "9e99").geq("-9e99")).toBe(true);
+ });
+ it("always returns integers", function () {
+ expect(bigInt.randBetween(0, 127) % 1).toBe(0);
+
+ for (var i = 0; i < 20; i++) { // issue #60
+ expect(bigInt.randBetween(0, "11703780079612452").toString()).not.toBe("undefined");
+ }
+ });
+ it("is within 10% of uniform distribution (this test is probabilistic and has a small change of failing)", function () {
+ var buckets = new Array(25), N = 50000;
+ for (var i = 0; i < buckets.length; i++) buckets[i] = 0;
+ var min = bigInt[0], max = bigInt("1e25"), divisor = max.over(buckets.length);
+ for (var i = 0; i < N; i++) {
+ buckets[bigInt.randBetween(min, max).over(divisor)]++;
+ }
+ var ideal = N / buckets.length;
+ for (var i = 0; i < buckets.length; i++) {
+ expect(Math.abs(buckets[i] - ideal) / ideal < 0.1).toBe(true);
+ }
+ });
+ });
+
+ describe("isInstance", function () {
+ it("works", function () {
+ expect(bigInt.isInstance(bigInt(14))).toBe(true);
+ expect(bigInt.isInstance(14)).toBe(false);
+ expect(bigInt.isInstance(bigInt("2343345345345236243564564363546"))).toBe(true);
+ expect(bigInt.isInstance("3456356345634564356435643634564334")).toBe(false);
+ });
+ });
+
+ describe("fromArray", function () {
+ it("works", function () {
+ expect(bigInt.fromArray([1, 2, 3, 4, 5])).toEqualBigInt("12345");
+ expect(bigInt.fromArray([1, 2, 3, 4, 5], 10)).toEqualBigInt("12345");
+ expect(bigInt.fromArray([1, 2, 3, 4, 5], 10, true)).toEqualBigInt("-12345");
+ expect(bigInt.fromArray([1, 2, 3, 4, 5], 256)).toEqualBigInt("4328719365");
+ });
+ });
+
+ describe("Aliases", function () {
+ it("add, plus are the same", function () {
+ expect(bigInt.one.add === bigInt.one.plus).toBe(true);
+ });
+ it("compare, compareTo are the same", function () {
+ expect(bigInt.one.compare === bigInt.one.compareTo).toBe(true);
+ });
+ it("divide, over are the same", function () {
+ expect(bigInt.one.divide === bigInt.one.over).toBe(true);
+ });
+ it("equals, eq are the same", function () {
+ expect(bigInt.one.equals === bigInt.one.eq).toBe(true);
+ });
+ it("greater, gt are the same", function () {
+ expect(bigInt.one.greater === bigInt.one.gt).toBe(true);
+ });
+ it("greaterOrEquals, geq are the same", function () {
+ expect(bigInt.one.greaterOrEquals === bigInt.one.geq).toBe(true);
+ });
+ it("lesser, lt are the same", function () {
+ expect(bigInt.one.lesser === bigInt.one.lt).toBe(true);
+ });
+ it("lesserOrEquals, leq are the same", function () {
+ expect(bigInt.one.lesserOrEquals === bigInt.one.leq).toBe(true);
+ });
+ it("notEquals, neq are the same", function () {
+ expect(bigInt.one.notEquals === bigInt.one.neq).toBe(true);
+ });
+ it("subtract, minus are the same", function () {
+ expect(bigInt.one.subtract === bigInt.one.minus).toBe(true);
+ });
+ it("mod, remainder are the same", function () {
+ expect(bigInt.one.mod === bigInt.one.remainder).toBe(true);
+ });
+ it("multiply, times are the same", function () {
+ expect(bigInt.one.multiply === bigInt.one.times).toBe(true);
+ });
+ });
+
+ describe("Integer", function () {
+ it("prototype chain", function () {
+ expect(bigInt(14) instanceof bigInt).toBe(true);
+ expect(bigInt(10e20) instanceof bigInt).toBe(true);
+ });
+
+ it("object construction", function () {
+ expect((new bigInt(14)).add(new bigInt(7)).eq(21)).toBe(true);
+ });
+
+ it("JSON stringifiction", function () {
+ var x = JSON.parse(JSON.stringify({
+ a: bigInt(4),
+ b: bigInt("4e100")
+ }));
+ expect(x.a).toEqualBigInt("4");
+ expect(x.b).toEqualBigInt("4e100");
+ });
+ });
+});
diff --git a/big-integer/spec/support/jasmine.json b/big-integer/spec/support/jasmine.json
new file mode 100644
index 0000000..a5f2932
--- /dev/null
+++ b/big-integer/spec/support/jasmine.json
@@ -0,0 +1,9 @@
+{
+ "spec_dir": "spec",
+ "spec_files": [
+ "**/*[sS]pec.js"
+ ],
+ "helpers": [
+ "helpers/**/*.js"
+ ]
+}
diff --git a/big-integer/spec/tsDefinitions.ts b/big-integer/spec/tsDefinitions.ts
new file mode 100644
index 0000000..5e4b6d4
--- /dev/null
+++ b/big-integer/spec/tsDefinitions.ts
@@ -0,0 +1,242 @@
+import * as bigInt from '../BigInteger';
+import * as _ from 'lodash';
+
+const staticFns = _.keysIn(bigInt);
+const instanceFns = _(bigInt())
+ .functionsIn()
+ .reject((fn : string) => {
+ return (
+ fn === '_multiplyBySmall' // Filter out private function
+ );
+ })
+ .value();
+
+const testedStaticFns = [
+ 'fromArray',
+ 'gcd',
+ 'isInstance',
+ 'lcm',
+ 'max',
+ 'min',
+ 'minusOne',
+ 'one',
+ 'randBetween',
+ 'zero',
+].concat(_.range(-999, 1000).map((i : number) => i.toString()));
+
+const testedInstanceFns = [
+ 'abs',
+ 'add',
+ 'and',
+ 'bitLength',
+ 'compare',
+ 'compareAbs',
+ 'compareTo',
+ 'divide',
+ 'divmod',
+ 'eq',
+ 'equals',
+ 'geq',
+ 'greater',
+ 'greaterOrEquals',
+ 'gt',
+ 'isDivisibleBy',
+ 'isEven',
+ 'isNegative',
+ 'isOdd',
+ 'isPositive',
+ 'isPrime',
+ 'isProbablePrime',
+ 'isUnit',
+ 'isZero',
+ 'leq',
+ 'lesser',
+ 'lesserOrEquals',
+ 'lt',
+ 'minus',
+ 'mod',
+ 'modInv',
+ 'modPow',
+ 'multiply',
+ 'negate',
+ 'neq',
+ 'next',
+ 'not',
+ 'notEquals',
+ 'or',
+ 'over',
+ 'plus',
+ 'pow',
+ 'prev',
+ 'remainder',
+ 'shiftLeft',
+ 'shiftRight',
+ 'square',
+ 'subtract',
+ 'times',
+ 'toArray',
+ 'toJSNumber',
+ 'toString',
+ 'toJSON',
+ 'valueOf',
+ 'xor',
+];
+
+const untestedStaticFns = _.difference(staticFns, testedStaticFns);
+const removedStaticFns = _.difference(testedStaticFns, staticFns);
+const untestedInstanceFns = _.difference(instanceFns, testedInstanceFns);
+const removedInstanceFns = _.difference(testedInstanceFns, instanceFns);
+
+if (untestedStaticFns.length) {
+ throw new Error(`New static functions need to be added to the TS definition: ${untestedStaticFns}`);
+};
+
+if (untestedInstanceFns.length) {
+ throw new Error(`New instance functions need to be added to the TS definition: ${untestedInstanceFns}`);
+};
+
+if (removedStaticFns.length) {
+ throw new Error(`Static functions need to be removed from the TS definition: ${removedStaticFns}`);
+};
+
+if (removedInstanceFns.length) {
+ throw new Error(`Instance functions need to be removed from the TS definition: ${removedInstanceFns}`);
+};
+
+// constructor tests
+const noArgument = bigInt();
+const numberArgument = bigInt(93);
+const stringArgument = bigInt("75643564363473453456342378564387956906736546456235345");
+const baseArgumentInt = bigInt("101010", 2);
+const baseArgumentStr = bigInt("101010", "2");
+const baseArgumentBi = bigInt("101010", bigInt(2));
+const bigIntArgument = bigInt(noArgument);
+
+// method tests
+const x = bigInt(10);
+let isBigInteger: bigInt.BigInteger;
+let isNumber: number;
+let isBoolean: boolean;
+let isString: string;
+let isDivmod: {quotient: bigInt.BigInteger, remainder: bigInt.BigInteger};
+let isBaseArray: bigInt.BaseArray;
+
+// Static methods/properties
+isBigInteger = bigInt.minusOne;
+isBigInteger = bigInt.zero;
+isBigInteger = bigInt.one;
+
+isBigInteger = bigInt[-999];
+isBigInteger = bigInt[0];
+isBigInteger = bigInt[999];
+
+isBigInteger = bigInt.fromArray([1, 2, 3]);
+isBigInteger = bigInt.fromArray(['1', '2', '3']);
+isBigInteger = bigInt.fromArray([bigInt.one, bigInt.zero, bigInt(9)], 10, true);
+
+isBigInteger = bigInt.gcd(0, 1);
+isBoolean = bigInt.isInstance(x);
+isBigInteger = bigInt.lcm(0, 1);
+isBigInteger = bigInt.max(0, 1);
+isBigInteger = bigInt.gcd(0, 1);
+isBigInteger = bigInt.randBetween(0, 1);
+
+// Instance methods
+isBigInteger = x.abs();
+isBigInteger = x.add(0).add(x).add("100");
+isBigInteger = x.and(0).and(x).and("100");
+
+isNumber = x.compare(0);
+isNumber = x.compare(x);
+isNumber = x.compare("100");
+
+isNumber = x.compareAbs(0);
+isNumber = x.compareAbs(x);
+isNumber = x.compareAbs("100");
+
+isNumber = x.compareTo(0);
+isNumber = x.compareTo(x);
+isNumber = x.compareTo("100");
+
+isBigInteger = x.divide(10).divide(x).divide('10');
+
+isDivmod = x.divmod(10);
+isDivmod = x.divmod(x);
+isDivmod = x.divmod("100");
+
+isBoolean = x.eq(0);
+isBoolean = x.eq(x);
+isBoolean = x.eq("100");
+
+isBoolean = x.equals(0);
+isBoolean = x.equals(x);
+isBoolean = x.equals("100");
+
+isBoolean = x.geq(0);
+isBoolean = x.geq(x);
+isBoolean = x.geq("100");
+
+isBoolean = x.greater(0);
+isBoolean = x.greater(x);
+isBoolean = x.greater("100");
+
+isBoolean = x.greaterOrEquals(0);
+isBoolean = x.greaterOrEquals(x);
+isBoolean = x.greaterOrEquals("100");
+
+isBoolean = x.gt(0);
+isBoolean = x.gt(x);
+isBoolean = x.gt("100");
+
+isBoolean = x.isDivisibleBy(x);
+isBoolean = x.isEven();
+isBoolean = x.isNegative();
+isBoolean = x.isOdd();
+isBoolean = x.isPositive();
+isBoolean = x.isPrime();
+
+isBoolean = x.isProbablePrime();
+isBoolean = x.isProbablePrime(5);
+
+isBoolean = x.isUnit();
+isBoolean = x.isZero();
+isBoolean = x.leq(x);
+isBoolean = x.lesser(0);
+isBoolean = x.lesserOrEquals(0);
+isBoolean = x.lt(0);
+isBigInteger = x.minus(0).minus(x).minus('0');
+isBigInteger = x.mod(10).mod(x).mod('10');
+isBigInteger = bigInt(3).modInv(11);
+isBigInteger = x.modPow(10, 2).modPow(x, x).modPow('10', '2');
+isBigInteger = x.multiply(0).multiply(x).multiply('0');
+isBigInteger = x.negate();
+isBoolean = x.neq(x);
+isBigInteger = x.next();
+isBigInteger = x.not();
+
+isBoolean = x.notEquals(0);
+isBoolean = x.notEquals(x);
+isBoolean = x.notEquals("100");
+
+isBigInteger = x.or(10).or(x).or('10');
+isBigInteger = x.over(10).over(x).over('10');
+isBigInteger = x.plus(0).plus(x).plus('0');
+isBigInteger = x.pow(0).pow(x).pow('0');
+isBigInteger = x.prev();
+isBigInteger = x.remainder(10).remainder(x).remainder('10');
+isBigInteger = x.shiftLeft(0).shiftLeft('0');
+isBigInteger = x.shiftRight(0).shiftRight('0');
+isBigInteger = x.square();
+isBigInteger = x.subtract(0).subtract(x).subtract('0');
+isBigInteger = x.times(0).times(x).times('0');
+isNumber = x.toJSNumber();
+
+isBaseArray = x.toArray(10);
+isBaseArray = x.toArray(36);
+
+isString = x.toString();
+isString = x.toString(36);
+isString = x.toJSON();
+
+isNumber = x.valueOf();
+isBigInteger = x.xor(0).xor(x).xor('0');
diff --git a/big-integer/tsconfig.json b/big-integer/tsconfig.json
new file mode 100644
index 0000000..62636e8
--- /dev/null
+++ b/big-integer/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "lib": [
+ "es6"
+ ],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": false,
+ "baseUrl": "./",
+ "moduleResolution": "node",
+ "allowJs": true,
+ "typeRoots": [
+ "./"
+ ],
+ "types": [
+ "node"
+ ],
+ "forceConsistentCasingInFileNames": true
+ },
+ "files": [
+ "BigInteger.d.ts",
+ "spec/tsDefinitions.ts"
+ ]
+} \ No newline at end of file