1 | const SMALLEST_UNSAFE_INTEGER = 0x20000000000000;
|
2 | const LARGEST_SAFE_INTEGER = SMALLEST_UNSAFE_INTEGER - 1;
|
3 | const UINT32_MAX = -1 >>> 0;
|
4 | const UINT32_SIZE = UINT32_MAX + 1;
|
5 | const INT32_SIZE = UINT32_SIZE / 2;
|
6 | const INT32_MAX = INT32_SIZE - 1;
|
7 | const UINT21_SIZE = 1 << 21;
|
8 | const UINT21_MAX = UINT21_SIZE - 1;
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | function int32(engine) {
|
14 | return engine.next() | 0;
|
15 | }
|
16 |
|
17 | function add(distribution, addend) {
|
18 | if (addend === 0) {
|
19 | return distribution;
|
20 | }
|
21 | else {
|
22 | return engine => distribution(engine) + addend;
|
23 | }
|
24 | }
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | function int53(engine) {
|
30 | const high = engine.next() | 0;
|
31 | const low = engine.next() >>> 0;
|
32 | return ((high & UINT21_MAX) * UINT32_SIZE +
|
33 | low +
|
34 | (high & UINT21_SIZE ? -SMALLEST_UNSAFE_INTEGER : 0));
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | function int53Full(engine) {
|
41 | while (true) {
|
42 | const high = engine.next() | 0;
|
43 | if (high & 0x400000) {
|
44 | if ((high & 0x7fffff) === 0x400000 && (engine.next() | 0) === 0) {
|
45 | return SMALLEST_UNSAFE_INTEGER;
|
46 | }
|
47 | }
|
48 | else {
|
49 | const low = engine.next() >>> 0;
|
50 | return ((high & UINT21_MAX) * UINT32_SIZE +
|
51 | low +
|
52 | (high & UINT21_SIZE ? -SMALLEST_UNSAFE_INTEGER : 0));
|
53 | }
|
54 | }
|
55 | }
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | function uint32(engine) {
|
61 | return engine.next() >>> 0;
|
62 | }
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | function uint53(engine) {
|
68 | const high = engine.next() & UINT21_MAX;
|
69 | const low = engine.next() >>> 0;
|
70 | return high * UINT32_SIZE + low;
|
71 | }
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | function uint53Full(engine) {
|
77 | while (true) {
|
78 | const high = engine.next() | 0;
|
79 | if (high & UINT21_SIZE) {
|
80 | if ((high & UINT21_MAX) === 0 && (engine.next() | 0) === 0) {
|
81 | return SMALLEST_UNSAFE_INTEGER;
|
82 | }
|
83 | }
|
84 | else {
|
85 | const low = engine.next() >>> 0;
|
86 | return (high & UINT21_MAX) * UINT32_SIZE + low;
|
87 | }
|
88 | }
|
89 | }
|
90 |
|
91 | function isPowerOfTwoMinusOne(value) {
|
92 | return ((value + 1) & value) === 0;
|
93 | }
|
94 | function bitmask(masking) {
|
95 | return (engine) => engine.next() & masking;
|
96 | }
|
97 | function downscaleToLoopCheckedRange(range) {
|
98 | const extendedRange = range + 1;
|
99 | const maximum = extendedRange * Math.floor(UINT32_SIZE / extendedRange);
|
100 | return engine => {
|
101 | let value = 0;
|
102 | do {
|
103 | value = engine.next() >>> 0;
|
104 | } while (value >= maximum);
|
105 | return value % extendedRange;
|
106 | };
|
107 | }
|
108 | function downscaleToRange(range) {
|
109 | if (isPowerOfTwoMinusOne(range)) {
|
110 | return bitmask(range);
|
111 | }
|
112 | else {
|
113 | return downscaleToLoopCheckedRange(range);
|
114 | }
|
115 | }
|
116 | function isEvenlyDivisibleByMaxInt32(value) {
|
117 | return (value | 0) === 0;
|
118 | }
|
119 | function upscaleWithHighMasking(masking) {
|
120 | return engine => {
|
121 | const high = engine.next() & masking;
|
122 | const low = engine.next() >>> 0;
|
123 | return high * UINT32_SIZE + low;
|
124 | };
|
125 | }
|
126 | function upscaleToLoopCheckedRange(extendedRange) {
|
127 | const maximum = extendedRange * Math.floor(SMALLEST_UNSAFE_INTEGER / extendedRange);
|
128 | return engine => {
|
129 | let ret = 0;
|
130 | do {
|
131 | const high = engine.next() & UINT21_MAX;
|
132 | const low = engine.next() >>> 0;
|
133 | ret = high * UINT32_SIZE + low;
|
134 | } while (ret >= maximum);
|
135 | return ret % extendedRange;
|
136 | };
|
137 | }
|
138 | function upscaleWithinU53(range) {
|
139 | const extendedRange = range + 1;
|
140 | if (isEvenlyDivisibleByMaxInt32(extendedRange)) {
|
141 | const highRange = ((extendedRange / UINT32_SIZE) | 0) - 1;
|
142 | if (isPowerOfTwoMinusOne(highRange)) {
|
143 | return upscaleWithHighMasking(highRange);
|
144 | }
|
145 | }
|
146 | return upscaleToLoopCheckedRange(extendedRange);
|
147 | }
|
148 | function upscaleWithinI53AndLoopCheck(min, max) {
|
149 | return engine => {
|
150 | let ret = 0;
|
151 | do {
|
152 | const high = engine.next() | 0;
|
153 | const low = engine.next() >>> 0;
|
154 | ret =
|
155 | (high & UINT21_MAX) * UINT32_SIZE +
|
156 | low +
|
157 | (high & UINT21_SIZE ? -SMALLEST_UNSAFE_INTEGER : 0);
|
158 | } while (ret < min || ret > max);
|
159 | return ret;
|
160 | };
|
161 | }
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | function integer(min, max) {
|
168 | min = Math.floor(min);
|
169 | max = Math.floor(max);
|
170 | if (min < -SMALLEST_UNSAFE_INTEGER || !isFinite(min)) {
|
171 | throw new RangeError(`Expected min to be at least ${-SMALLEST_UNSAFE_INTEGER}`);
|
172 | }
|
173 | else if (max > SMALLEST_UNSAFE_INTEGER || !isFinite(max)) {
|
174 | throw new RangeError(`Expected max to be at most ${SMALLEST_UNSAFE_INTEGER}`);
|
175 | }
|
176 | const range = max - min;
|
177 | if (range <= 0 || !isFinite(range)) {
|
178 | return () => min;
|
179 | }
|
180 | else if (range === UINT32_MAX) {
|
181 | if (min === 0) {
|
182 | return uint32;
|
183 | }
|
184 | else {
|
185 | return add(int32, min + INT32_SIZE);
|
186 | }
|
187 | }
|
188 | else if (range < UINT32_MAX) {
|
189 | return add(downscaleToRange(range), min);
|
190 | }
|
191 | else if (range === LARGEST_SAFE_INTEGER) {
|
192 | return add(uint53, min);
|
193 | }
|
194 | else if (range < LARGEST_SAFE_INTEGER) {
|
195 | return add(upscaleWithinU53(range), min);
|
196 | }
|
197 | else if (max - 1 - min === LARGEST_SAFE_INTEGER) {
|
198 | return add(uint53Full, min);
|
199 | }
|
200 | else if (min === -SMALLEST_UNSAFE_INTEGER &&
|
201 | max === SMALLEST_UNSAFE_INTEGER) {
|
202 | return int53Full;
|
203 | }
|
204 | else if (min === -SMALLEST_UNSAFE_INTEGER && max === LARGEST_SAFE_INTEGER) {
|
205 | return int53;
|
206 | }
|
207 | else if (min === -LARGEST_SAFE_INTEGER && max === SMALLEST_UNSAFE_INTEGER) {
|
208 | return add(int53, 1);
|
209 | }
|
210 | else if (max === SMALLEST_UNSAFE_INTEGER) {
|
211 | return add(upscaleWithinI53AndLoopCheck(min - 1, max - 1), 1);
|
212 | }
|
213 | else {
|
214 | return upscaleWithinI53AndLoopCheck(min, max);
|
215 | }
|
216 | }
|
217 |
|
218 | function isLeastBitTrue(engine) {
|
219 | return (engine.next() & 1) === 1;
|
220 | }
|
221 | function lessThan(distribution, value) {
|
222 | return engine => distribution(engine) < value;
|
223 | }
|
224 | function probability(percentage) {
|
225 | if (percentage <= 0) {
|
226 | return () => false;
|
227 | }
|
228 | else if (percentage >= 1) {
|
229 | return () => true;
|
230 | }
|
231 | else {
|
232 | const scaled = percentage * UINT32_SIZE;
|
233 | if (scaled % 1 === 0) {
|
234 | return lessThan(int32, (scaled - INT32_SIZE) | 0);
|
235 | }
|
236 | else {
|
237 | return lessThan(uint53, Math.round(percentage * SMALLEST_UNSAFE_INTEGER));
|
238 | }
|
239 | }
|
240 | }
|
241 | function bool(numerator, denominator) {
|
242 | if (denominator == null) {
|
243 | if (numerator == null) {
|
244 | return isLeastBitTrue;
|
245 | }
|
246 | return probability(numerator);
|
247 | }
|
248 | else {
|
249 | if (numerator <= 0) {
|
250 | return () => false;
|
251 | }
|
252 | else if (numerator >= denominator) {
|
253 | return () => true;
|
254 | }
|
255 | return lessThan(integer(0, denominator - 1), numerator);
|
256 | }
|
257 | }
|
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 | function date(start, end) {
|
266 | const distribution = integer(+start, +end);
|
267 | return engine => new Date(distribution(engine));
|
268 | }
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 | function die(sideCount) {
|
275 | return integer(1, sideCount);
|
276 | }
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 | function dice(sideCount, dieCount) {
|
285 | const distribution = die(sideCount);
|
286 | return engine => {
|
287 | const result = [];
|
288 | for (let i = 0; i < dieCount; ++i) {
|
289 | result.push(distribution(engine));
|
290 | }
|
291 | return result;
|
292 | };
|
293 | }
|
294 |
|
295 |
|
296 |
|
297 | const DEFAULT_STRING_POOL = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
|
298 | function string(pool = DEFAULT_STRING_POOL) {
|
299 | const poolLength = pool.length;
|
300 | if (!poolLength) {
|
301 | throw new Error("Expected pool not to be an empty string");
|
302 | }
|
303 | const distribution = integer(0, poolLength - 1);
|
304 | return (engine, length) => {
|
305 | let result = "";
|
306 | for (let i = 0; i < length; ++i) {
|
307 | const j = distribution(engine);
|
308 | result += pool.charAt(j);
|
309 | }
|
310 | return result;
|
311 | };
|
312 | }
|
313 |
|
314 | const LOWER_HEX_POOL = "0123456789abcdef";
|
315 | const lowerHex = string(LOWER_HEX_POOL);
|
316 | const upperHex = string(LOWER_HEX_POOL.toUpperCase());
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 | function hex(uppercase) {
|
324 | if (uppercase) {
|
325 | return upperHex;
|
326 | }
|
327 | else {
|
328 | return lowerHex;
|
329 | }
|
330 | }
|
331 |
|
332 | function convertSliceArgument(value, length) {
|
333 | if (value < 0) {
|
334 | return Math.max(value + length, 0);
|
335 | }
|
336 | else {
|
337 | return Math.min(value, length);
|
338 | }
|
339 | }
|
340 |
|
341 | function toInteger(value) {
|
342 | const num = +value;
|
343 | if (num < 0) {
|
344 | return Math.ceil(num);
|
345 | }
|
346 | else {
|
347 | return Math.floor(num);
|
348 | }
|
349 | }
|
350 |
|
351 |
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 | function pick(engine, source, begin, end) {
|
359 | const length = source.length;
|
360 | if (length === 0) {
|
361 | throw new RangeError("Cannot pick from an empty array");
|
362 | }
|
363 | const start = begin == null ? 0 : convertSliceArgument(toInteger(begin), length);
|
364 | const finish = end === void 0 ? length : convertSliceArgument(toInteger(end), length);
|
365 | if (start >= finish) {
|
366 | throw new RangeError(`Cannot pick between bounds ${start} and ${finish}`);
|
367 | }
|
368 | const distribution = integer(start, finish - 1);
|
369 | return source[distribution(engine)];
|
370 | }
|
371 |
|
372 | function multiply(distribution, multiplier) {
|
373 | if (multiplier === 1) {
|
374 | return distribution;
|
375 | }
|
376 | else if (multiplier === 0) {
|
377 | return () => 0;
|
378 | }
|
379 | else {
|
380 | return engine => distribution(engine) * multiplier;
|
381 | }
|
382 | }
|
383 |
|
384 |
|
385 |
|
386 |
|
387 | function realZeroToOneExclusive(engine) {
|
388 | return uint53(engine) / SMALLEST_UNSAFE_INTEGER;
|
389 | }
|
390 |
|
391 |
|
392 |
|
393 |
|
394 | function realZeroToOneInclusive(engine) {
|
395 | return uint53Full(engine) / SMALLEST_UNSAFE_INTEGER;
|
396 | }
|
397 |
|
398 |
|
399 |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 | function real(min, max, inclusive = false) {
|
405 | if (!isFinite(min)) {
|
406 | throw new RangeError("Expected min to be a finite number");
|
407 | }
|
408 | else if (!isFinite(max)) {
|
409 | throw new RangeError("Expected max to be a finite number");
|
410 | }
|
411 | return add(multiply(inclusive ? realZeroToOneInclusive : realZeroToOneExclusive, max - min), min);
|
412 | }
|
413 |
|
414 | const sliceArray = Array.prototype.slice;
|
415 |
|
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 |
|
422 | function shuffle(engine, array, downTo = 0) {
|
423 | const length = array.length;
|
424 | if (length) {
|
425 | for (let i = (length - 1) >>> 0; i > downTo; --i) {
|
426 | const distribution = integer(0, i);
|
427 | const j = distribution(engine);
|
428 | if (i !== j) {
|
429 | const tmp = array[i];
|
430 | array[i] = array[j];
|
431 | array[j] = tmp;
|
432 | }
|
433 | }
|
434 | }
|
435 | return array;
|
436 | }
|
437 |
|
438 |
|
439 |
|
440 |
|
441 |
|
442 |
|
443 |
|
444 |
|
445 | function sample(engine, population, sampleSize) {
|
446 | if (sampleSize < 0 ||
|
447 | sampleSize > population.length ||
|
448 | !isFinite(sampleSize)) {
|
449 | throw new RangeError("Expected sampleSize to be within 0 and the length of the population");
|
450 | }
|
451 | if (sampleSize === 0) {
|
452 | return [];
|
453 | }
|
454 | const clone = sliceArray.call(population);
|
455 | const length = clone.length;
|
456 | if (length === sampleSize) {
|
457 | return shuffle(engine, clone, 0);
|
458 | }
|
459 | const tailLength = length - sampleSize;
|
460 | return shuffle(engine, clone, tailLength - 1).slice(tailLength);
|
461 | }
|
462 |
|
463 | const stringRepeat = (() => {
|
464 | try {
|
465 | if ("x".repeat(3) === "xxx") {
|
466 | return (pattern, count) => pattern.repeat(count);
|
467 | }
|
468 | }
|
469 | catch (_) {
|
470 |
|
471 | }
|
472 | return (pattern, count) => {
|
473 | let result = "";
|
474 | while (count > 0) {
|
475 | if (count & 1) {
|
476 | result += pattern;
|
477 | }
|
478 | count >>= 1;
|
479 | pattern += pattern;
|
480 | }
|
481 | return result;
|
482 | };
|
483 | })();
|
484 |
|
485 | function zeroPad(text, zeroCount) {
|
486 | return stringRepeat("0", zeroCount - text.length) + text;
|
487 | }
|
488 |
|
489 |
|
490 |
|
491 |
|
492 |
|
493 | function uuid4(engine) {
|
494 | const a = engine.next() >>> 0;
|
495 | const b = engine.next() | 0;
|
496 | const c = engine.next() | 0;
|
497 | const d = engine.next() >>> 0;
|
498 | return (zeroPad(a.toString(16), 8) +
|
499 | "-" +
|
500 | zeroPad((b & 0xffff).toString(16), 4) +
|
501 | "-" +
|
502 | zeroPad((((b >> 4) & 0x0fff) | 0x4000).toString(16), 4) +
|
503 | "-" +
|
504 | zeroPad(((c & 0x3fff) | 0x8000).toString(16), 4) +
|
505 | "-" +
|
506 | zeroPad(((c >> 4) & 0xffff).toString(16), 4) +
|
507 | zeroPad(d.toString(16), 8));
|
508 | }
|
509 |
|
510 |
|
511 |
|
512 |
|
513 | const nativeMath = {
|
514 | next() {
|
515 | return (Math.random() * UINT32_SIZE) | 0;
|
516 | }
|
517 | };
|
518 |
|
519 |
|
520 |
|
521 |
|
522 |
|
523 |
|
524 | class Random {
|
525 | |
526 |
|
527 |
|
528 |
|
529 | constructor(engine = nativeMath) {
|
530 | this.engine = engine;
|
531 | }
|
532 | |
533 |
|
534 |
|
535 | int32() {
|
536 | return int32(this.engine);
|
537 | }
|
538 | |
539 |
|
540 |
|
541 | uint32() {
|
542 | return uint32(this.engine);
|
543 | }
|
544 | |
545 |
|
546 |
|
547 | uint53() {
|
548 | return uint53(this.engine);
|
549 | }
|
550 | |
551 |
|
552 |
|
553 | uint53Full() {
|
554 | return uint53Full(this.engine);
|
555 | }
|
556 | |
557 |
|
558 |
|
559 | int53() {
|
560 | return int53(this.engine);
|
561 | }
|
562 | |
563 |
|
564 |
|
565 | int53Full() {
|
566 | return int53Full(this.engine);
|
567 | }
|
568 | |
569 |
|
570 |
|
571 |
|
572 |
|
573 | integer(min, max) {
|
574 | return integer(min, max)(this.engine);
|
575 | }
|
576 | |
577 |
|
578 |
|
579 | realZeroToOneInclusive() {
|
580 | return realZeroToOneInclusive(this.engine);
|
581 | }
|
582 | |
583 |
|
584 |
|
585 | realZeroToOneExclusive() {
|
586 | return realZeroToOneExclusive(this.engine);
|
587 | }
|
588 | |
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 | real(min, max, inclusive = false) {
|
595 | return real(min, max, inclusive)(this.engine);
|
596 | }
|
597 | bool(numerator, denominator) {
|
598 | return bool(numerator, denominator)(this.engine);
|
599 | }
|
600 | |
601 |
|
602 |
|
603 |
|
604 |
|
605 |
|
606 |
|
607 | pick(source, begin, end) {
|
608 | return pick(this.engine, source, begin, end);
|
609 | }
|
610 | |
611 |
|
612 |
|
613 |
|
614 | shuffle(array) {
|
615 | return shuffle(this.engine, array);
|
616 | }
|
617 | |
618 |
|
619 |
|
620 |
|
621 |
|
622 |
|
623 | sample(population, sampleSize) {
|
624 | return sample(this.engine, population, sampleSize);
|
625 | }
|
626 | |
627 |
|
628 |
|
629 |
|
630 | die(sideCount) {
|
631 | return die(sideCount)(this.engine);
|
632 | }
|
633 | |
634 |
|
635 |
|
636 |
|
637 |
|
638 | dice(sideCount, dieCount) {
|
639 | return dice(sideCount, dieCount)(this.engine);
|
640 | }
|
641 | |
642 |
|
643 |
|
644 |
|
645 |
|
646 | uuid4() {
|
647 | return uuid4(this.engine);
|
648 | }
|
649 | string(length, pool) {
|
650 | return string(pool)(this.engine, length);
|
651 | }
|
652 | |
653 |
|
654 |
|
655 |
|
656 |
|
657 |
|
658 | hex(length, uppercase) {
|
659 | return hex(uppercase)(this.engine, length);
|
660 | }
|
661 | |
662 |
|
663 |
|
664 |
|
665 |
|
666 | date(start, end) {
|
667 | return date(start, end)(this.engine);
|
668 | }
|
669 | }
|
670 |
|
671 |
|
672 |
|
673 |
|
674 | const I32Array = (() => {
|
675 | try {
|
676 | const buffer = new ArrayBuffer(4);
|
677 | const view = new Int32Array(buffer);
|
678 | view[0] = INT32_SIZE;
|
679 | if (view[0] === -INT32_SIZE) {
|
680 | return Int32Array;
|
681 | }
|
682 | }
|
683 | catch (_) {
|
684 |
|
685 | }
|
686 | return Array;
|
687 | })();
|
688 |
|
689 | let data = null;
|
690 | const COUNT = 128;
|
691 | let index = COUNT;
|
692 |
|
693 |
|
694 |
|
695 |
|
696 |
|
697 |
|
698 |
|
699 |
|
700 |
|
701 | const browserCrypto = {
|
702 | next() {
|
703 | if (index >= COUNT) {
|
704 | if (data === null) {
|
705 | data = new I32Array(COUNT);
|
706 | }
|
707 | crypto.getRandomValues(data);
|
708 | index = 0;
|
709 | }
|
710 | return data[index++] | 0;
|
711 | }
|
712 | };
|
713 |
|
714 |
|
715 |
|
716 |
|
717 |
|
718 |
|
719 |
|
720 |
|
721 | function createEntropy(engine = nativeMath, length = 16) {
|
722 | const array = [];
|
723 | array.push(new Date().getTime() | 0);
|
724 | for (let i = 1; i < length; ++i) {
|
725 | array[i] = engine.next() | 0;
|
726 | }
|
727 | return array;
|
728 | }
|
729 |
|
730 |
|
731 |
|
732 |
|
733 | const imul = (() => {
|
734 | try {
|
735 | if (Math.imul(UINT32_MAX, 5) === -5) {
|
736 | return Math.imul;
|
737 | }
|
738 | }
|
739 | catch (_) {
|
740 |
|
741 | }
|
742 | const UINT16_MAX = 0xffff;
|
743 | return (a, b) => {
|
744 | const ah = (a >>> 16) & UINT16_MAX;
|
745 | const al = a & UINT16_MAX;
|
746 | const bh = (b >>> 16) & UINT16_MAX;
|
747 | const bl = b & UINT16_MAX;
|
748 |
|
749 |
|
750 | return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) | 0;
|
751 | };
|
752 | })();
|
753 |
|
754 | const ARRAY_SIZE = 624;
|
755 | const ARRAY_MAX = ARRAY_SIZE - 1;
|
756 | const M = 397;
|
757 | const ARRAY_SIZE_MINUS_M = ARRAY_SIZE - M;
|
758 | const A = 0x9908b0df;
|
759 |
|
760 |
|
761 |
|
762 |
|
763 |
|
764 |
|
765 | class MersenneTwister19937 {
|
766 | |
767 |
|
768 |
|
769 |
|
770 | constructor() {
|
771 | this.data = new I32Array(ARRAY_SIZE);
|
772 | this.index = 0;
|
773 | this.uses = 0;
|
774 | }
|
775 | |
776 |
|
777 |
|
778 |
|
779 | static seed(initial) {
|
780 | return new MersenneTwister19937().seed(initial);
|
781 | }
|
782 | |
783 |
|
784 |
|
785 |
|
786 | static seedWithArray(source) {
|
787 | return new MersenneTwister19937().seedWithArray(source);
|
788 | }
|
789 | |
790 |
|
791 |
|
792 |
|
793 | static autoSeed() {
|
794 | return MersenneTwister19937.seedWithArray(createEntropy());
|
795 | }
|
796 | |
797 |
|
798 |
|
799 | next() {
|
800 | if ((this.index | 0) >= ARRAY_SIZE) {
|
801 | refreshData(this.data);
|
802 | this.index = 0;
|
803 | }
|
804 | const value = this.data[this.index];
|
805 | this.index = (this.index + 1) | 0;
|
806 | this.uses += 1;
|
807 | return temper(value) | 0;
|
808 | }
|
809 | |
810 |
|
811 |
|
812 |
|
813 |
|
814 |
|
815 | getUseCount() {
|
816 | return this.uses;
|
817 | }
|
818 | |
819 |
|
820 |
|
821 |
|
822 | discard(count) {
|
823 | if (count <= 0) {
|
824 | return this;
|
825 | }
|
826 | this.uses += count;
|
827 | if ((this.index | 0) >= ARRAY_SIZE) {
|
828 | refreshData(this.data);
|
829 | this.index = 0;
|
830 | }
|
831 | while (count + this.index > ARRAY_SIZE) {
|
832 | count -= ARRAY_SIZE - this.index;
|
833 | refreshData(this.data);
|
834 | this.index = 0;
|
835 | }
|
836 | this.index = (this.index + count) | 0;
|
837 | return this;
|
838 | }
|
839 | seed(initial) {
|
840 | let previous = 0;
|
841 | this.data[0] = previous = initial | 0;
|
842 | for (let i = 1; i < ARRAY_SIZE; i = (i + 1) | 0) {
|
843 | this.data[i] = previous =
|
844 | (imul(previous ^ (previous >>> 30), 0x6c078965) + i) | 0;
|
845 | }
|
846 | this.index = ARRAY_SIZE;
|
847 | this.uses = 0;
|
848 | return this;
|
849 | }
|
850 | seedWithArray(source) {
|
851 | this.seed(0x012bd6aa);
|
852 | seedWithArray(this.data, source);
|
853 | return this;
|
854 | }
|
855 | }
|
856 | function refreshData(data) {
|
857 | let k = 0;
|
858 | let tmp = 0;
|
859 | for (; (k | 0) < ARRAY_SIZE_MINUS_M; k = (k + 1) | 0) {
|
860 | tmp = (data[k] & INT32_SIZE) | (data[(k + 1) | 0] & INT32_MAX);
|
861 | data[k] = data[(k + M) | 0] ^ (tmp >>> 1) ^ (tmp & 0x1 ? A : 0);
|
862 | }
|
863 | for (; (k | 0) < ARRAY_MAX; k = (k + 1) | 0) {
|
864 | tmp = (data[k] & INT32_SIZE) | (data[(k + 1) | 0] & INT32_MAX);
|
865 | data[k] =
|
866 | data[(k - ARRAY_SIZE_MINUS_M) | 0] ^ (tmp >>> 1) ^ (tmp & 0x1 ? A : 0);
|
867 | }
|
868 | tmp = (data[ARRAY_MAX] & INT32_SIZE) | (data[0] & INT32_MAX);
|
869 | data[ARRAY_MAX] = data[M - 1] ^ (tmp >>> 1) ^ (tmp & 0x1 ? A : 0);
|
870 | }
|
871 | function temper(value) {
|
872 | value ^= value >>> 11;
|
873 | value ^= (value << 7) & 0x9d2c5680;
|
874 | value ^= (value << 15) & 0xefc60000;
|
875 | return value ^ (value >>> 18);
|
876 | }
|
877 | function seedWithArray(data, source) {
|
878 | let i = 1;
|
879 | let j = 0;
|
880 | const sourceLength = source.length;
|
881 | let k = Math.max(sourceLength, ARRAY_SIZE) | 0;
|
882 | let previous = data[0] | 0;
|
883 | for (; (k | 0) > 0; --k) {
|
884 | data[i] = previous =
|
885 | ((data[i] ^ imul(previous ^ (previous >>> 30), 0x0019660d)) +
|
886 | (source[j] | 0) +
|
887 | (j | 0)) |
|
888 | 0;
|
889 | i = (i + 1) | 0;
|
890 | ++j;
|
891 | if ((i | 0) > ARRAY_MAX) {
|
892 | data[0] = data[ARRAY_MAX];
|
893 | i = 1;
|
894 | }
|
895 | if (j >= sourceLength) {
|
896 | j = 0;
|
897 | }
|
898 | }
|
899 | for (k = ARRAY_MAX; (k | 0) > 0; --k) {
|
900 | data[i] = previous =
|
901 | ((data[i] ^ imul(previous ^ (previous >>> 30), 0x5d588b65)) - i) | 0;
|
902 | i = (i + 1) | 0;
|
903 | if ((i | 0) > ARRAY_MAX) {
|
904 | data[0] = data[ARRAY_MAX];
|
905 | i = 1;
|
906 | }
|
907 | }
|
908 | data[0] = INT32_SIZE;
|
909 | }
|
910 |
|
911 | let data$1 = null;
|
912 | const COUNT$1 = 128;
|
913 | let index$1 = COUNT$1;
|
914 |
|
915 |
|
916 |
|
917 |
|
918 |
|
919 |
|
920 |
|
921 |
|
922 |
|
923 | const nodeCrypto = {
|
924 | next() {
|
925 | if (index$1 >= COUNT$1) {
|
926 | data$1 = new Int32Array(new Int8Array(require("crypto").randomBytes(4 * COUNT$1)).buffer);
|
927 | index$1 = 0;
|
928 | }
|
929 | return data$1[index$1++] | 0;
|
930 | }
|
931 | };
|
932 |
|
933 |
|
934 |
|
935 |
|
936 |
|
937 |
|
938 |
|
939 |
|
940 | function picker(source, begin, end) {
|
941 | const clone = sliceArray.call(source, begin, end);
|
942 | if (clone.length === 0) {
|
943 | throw new RangeError(`Cannot pick from a source with no items`);
|
944 | }
|
945 | const distribution = integer(0, clone.length - 1);
|
946 | return engine => clone[distribution(engine)];
|
947 | }
|
948 |
|
949 | export { Random, browserCrypto, nativeMath, MersenneTwister19937, nodeCrypto, bool, date, dice, die, hex, int32, int53, int53Full, integer, pick, picker, real, realZeroToOneExclusive, realZeroToOneInclusive, sample, shuffle, string, uint32, uint53, uint53Full, uuid4, createEntropy };
|
950 |
|