// ==UserScript==
// @name GGn No-Intro Helper
// @description A GGn user script to help with No-Intro uploads/trumps
// @namespace http://tampermonkey.net/
// @version 3.0.4
// @author BestGrapeLeaves
// @license MIT
// @match *://gazellegames.net/upload.php?groupid=*
// @match *://gazellegames.net/torrents.php?id=*
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_listValues
// @grant GM_deleteValue
// @grant GM_setValue
// @grant GM_getValue
// @connect datomatic.no-intro.org
// @icon https://i.imgur.com/UFOk0Iu.png
// ==/UserScript==
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./node_modules/base64-js/index.js":
/***/ ((__unused_webpack_module, exports) => {
"use strict";
exports.byteLength = byteLength;
exports.toByteArray = toByteArray;
exports.fromByteArray = fromByteArray;
var lookup = [];
var revLookup = [];
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
for(var i = 0, len = code.length; i < len; ++i){
lookup[i] = code[i];
revLookup[code.charCodeAt(i)] = i;
}
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62;
revLookup['_'.charCodeAt(0)] = 63;
function getLens(b64) {
var len = b64.length;
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4');
}
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=');
if (validLen === -1) validLen = len;
var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
return [
validLen,
placeHoldersLen
];
}
// base64 is 4/3 + up to two characters of the original data
function byteLength(b64) {
var lens = getLens(b64);
var validLen = lens[0];
var placeHoldersLen = lens[1];
return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
}
function _byteLength(b64, validLen, placeHoldersLen) {
return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
}
function toByteArray(b64) {
var tmp;
var lens = getLens(b64);
var validLen = lens[0];
var placeHoldersLen = lens[1];
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
var curByte = 0;
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
var i;
for(i = 0; i < len; i += 4){
tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
arr[curByte++] = tmp >> 16 & 0xFF;
arr[curByte++] = tmp >> 8 & 0xFF;
arr[curByte++] = tmp & 0xFF;
}
if (placeHoldersLen === 2) {
tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
arr[curByte++] = tmp & 0xFF;
}
if (placeHoldersLen === 1) {
tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
arr[curByte++] = tmp >> 8 & 0xFF;
arr[curByte++] = tmp & 0xFF;
}
return arr;
}
function tripletToBase64(num) {
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F];
}
function encodeChunk(uint8, start, end) {
var tmp;
var output = [];
for(var i = start; i < end; i += 3){
tmp = (uint8[i] << 16 & 0xFF0000) + (uint8[i + 1] << 8 & 0xFF00) + (uint8[i + 2] & 0xFF);
output.push(tripletToBase64(tmp));
}
return output.join('');
}
function fromByteArray(uint8) {
var tmp;
var len = uint8.length;
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
;
var parts = [];
var maxChunkLength = 16383 // must be multiple of 3
;
// go through the array every three bytes, we'll deal with trailing stuff later
for(var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength){
parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1];
parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 0x3F] + '==');
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + uint8[len - 1];
parts.push(lookup[tmp >> 10] + lookup[tmp >> 4 & 0x3F] + lookup[tmp << 2 & 0x3F] + '=');
}
return parts.join('');
}
/***/ }),
/***/ "./node_modules/bencode/lib/decode.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* provided dependency */ var Buffer = __webpack_require__("./node_modules/buffer/index.js")["lW"];
const INTEGER_START = 0x69 // 'i'
;
const STRING_DELIM = 0x3A // ':'
;
const DICTIONARY_START = 0x64 // 'd'
;
const LIST_START = 0x6C // 'l'
;
const END_OF_TYPE = 0x65 // 'e'
;
/**
* replaces parseInt(buffer.toString('ascii', start, end)).
* For strings with less then ~30 charachters, this is actually a lot faster.
*
* @param {Buffer} data
* @param {Number} start
* @param {Number} end
* @return {Number} calculated number
*/ function getIntFromBuffer(buffer, start, end) {
let sum = 0;
let sign = 1;
for(let i = start; i < end; i++){
const num = buffer[i];
if (num < 58 && num >= 48) {
sum = sum * 10 + (num - 48);
continue;
}
if (i === start && num === 43) {
continue;
}
if (i === start && num === 45) {
sign = -1;
continue;
}
if (num === 46) {
break;
}
throw new Error('not a number: buffer[' + i + '] = ' + num);
}
return sum * sign;
}
/**
* Decodes bencoded data.
*
* @param {Buffer} data
* @param {Number} start (optional)
* @param {Number} end (optional)
* @param {String} encoding (optional)
* @return {Object|Array|Buffer|String|Number}
*/ function decode(data, start, end, encoding) {
if (data == null || data.length === 0) {
return null;
}
if (typeof start !== 'number' && encoding == null) {
encoding = start;
start = undefined;
}
if (typeof end !== 'number' && encoding == null) {
encoding = end;
end = undefined;
}
decode.position = 0;
decode.encoding = encoding || null;
decode.data = !Buffer.isBuffer(data) ? Buffer.from(data) : data.slice(start, end);
decode.bytes = decode.data.length;
return decode.next();
}
decode.bytes = 0;
decode.position = 0;
decode.data = null;
decode.encoding = null;
decode.next = function() {
switch(decode.data[decode.position]){
case DICTIONARY_START:
return decode.dictionary();
case LIST_START:
return decode.list();
case INTEGER_START:
return decode.integer();
default:
return decode.buffer();
}
};
decode.find = function(chr) {
let i = decode.position;
const c = decode.data.length;
const d = decode.data;
while(i < c){
if (d[i] === chr) return i;
i++;
}
throw new Error('Invalid data: Missing delimiter "' + String.fromCharCode(chr) + '" [0x' + chr.toString(16) + ']');
};
decode.dictionary = function() {
decode.position++;
const dict = {};
while(decode.data[decode.position] !== END_OF_TYPE){
dict[decode.buffer()] = decode.next();
}
decode.position++;
return dict;
};
decode.list = function() {
decode.position++;
const lst = [];
while(decode.data[decode.position] !== END_OF_TYPE){
lst.push(decode.next());
}
decode.position++;
return lst;
};
decode.integer = function() {
const end = decode.find(END_OF_TYPE);
const number = getIntFromBuffer(decode.data, decode.position + 1, end);
decode.position += end + 1 - decode.position;
return number;
};
decode.buffer = function() {
let sep = decode.find(STRING_DELIM);
const length = getIntFromBuffer(decode.data, decode.position, sep);
const end = ++sep + length;
decode.position = end;
return decode.encoding ? decode.data.toString(decode.encoding, sep, end) : decode.data.slice(sep, end);
};
module.exports = decode;
/***/ }),
/***/ "./node_modules/bencode/lib/encode.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* provided dependency */ var Buffer = __webpack_require__("./node_modules/buffer/index.js")["lW"];
const { getType } = __webpack_require__("./node_modules/bencode/lib/util.js");
/**
* Encodes data in bencode.
*
* @param {Buffer|Array|String|Object|Number|Boolean} data
* @return {Buffer}
*/ function encode(data, buffer, offset) {
const buffers = [];
let result = null;
encode._encode(buffers, data);
result = Buffer.concat(buffers);
encode.bytes = result.length;
if (Buffer.isBuffer(buffer)) {
result.copy(buffer, offset);
return buffer;
}
return result;
}
encode.bytes = -1;
encode._floatConversionDetected = false;
encode._encode = function(buffers, data) {
if (data == null) {
return;
}
switch(getType(data)){
case 'buffer':
encode.buffer(buffers, data);
break;
case 'object':
encode.dict(buffers, data);
break;
case 'map':
encode.dictMap(buffers, data);
break;
case 'array':
encode.list(buffers, data);
break;
case 'set':
encode.listSet(buffers, data);
break;
case 'string':
encode.string(buffers, data);
break;
case 'number':
encode.number(buffers, data);
break;
case 'boolean':
encode.number(buffers, data);
break;
case 'arraybufferview':
encode.buffer(buffers, Buffer.from(data.buffer, data.byteOffset, data.byteLength));
break;
case 'arraybuffer':
encode.buffer(buffers, Buffer.from(data));
break;
}
};
const buffE = Buffer.from('e');
const buffD = Buffer.from('d');
const buffL = Buffer.from('l');
encode.buffer = function(buffers, data) {
buffers.push(Buffer.from(data.length + ':'), data);
};
encode.string = function(buffers, data) {
buffers.push(Buffer.from(Buffer.byteLength(data) + ':' + data));
};
encode.number = function(buffers, data) {
const maxLo = 0x80000000;
const hi = data / maxLo << 0;
const lo = data % maxLo << 0;
const val = hi * maxLo + lo;
buffers.push(Buffer.from('i' + val + 'e'));
if (val !== data && !encode._floatConversionDetected) {
encode._floatConversionDetected = true;
console.warn('WARNING: Possible data corruption detected with value "' + data + '":', 'Bencoding only defines support for integers, value was converted to "' + val + '"');
console.trace();
}
};
encode.dict = function(buffers, data) {
buffers.push(buffD);
let j = 0;
let k;
// fix for issue #13 - sorted dicts
const keys = Object.keys(data).sort();
const kl = keys.length;
for(; j < kl; j++){
k = keys[j];
if (data[k] == null) continue;
encode.string(buffers, k);
encode._encode(buffers, data[k]);
}
buffers.push(buffE);
};
encode.dictMap = function(buffers, data) {
buffers.push(buffD);
const keys = Array.from(data.keys()).sort();
for (const key of keys){
if (data.get(key) == null) continue;
Buffer.isBuffer(key) ? encode._encode(buffers, key) : encode.string(buffers, String(key));
encode._encode(buffers, data.get(key));
}
buffers.push(buffE);
};
encode.list = function(buffers, data) {
let i = 0;
const c = data.length;
buffers.push(buffL);
for(; i < c; i++){
if (data[i] == null) continue;
encode._encode(buffers, data[i]);
}
buffers.push(buffE);
};
encode.listSet = function(buffers, data) {
buffers.push(buffL);
for (const item of data){
if (item == null) continue;
encode._encode(buffers, item);
}
buffers.push(buffE);
};
module.exports = encode;
/***/ }),
/***/ "./node_modules/bencode/lib/encoding-length.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* provided dependency */ var Buffer = __webpack_require__("./node_modules/buffer/index.js")["lW"];
const { digitCount , getType } = __webpack_require__("./node_modules/bencode/lib/util.js");
function listLength(list) {
let length = 1 + 1 // type marker + end-of-type marker
;
for (const value of list){
length += encodingLength(value);
}
return length;
}
function mapLength(map) {
let length = 1 + 1 // type marker + end-of-type marker
;
for (const [key, value] of map){
const keyLength = Buffer.byteLength(key);
length += digitCount(keyLength) + 1 + keyLength;
length += encodingLength(value);
}
return length;
}
function objectLength(value) {
let length = 1 + 1 // type marker + end-of-type marker
;
const keys = Object.keys(value);
for(let i = 0; i < keys.length; i++){
const keyLength = Buffer.byteLength(keys[i]);
length += digitCount(keyLength) + 1 + keyLength;
length += encodingLength(value[keys[i]]);
}
return length;
}
function stringLength(value) {
const length = Buffer.byteLength(value);
return digitCount(length) + 1 + length;
}
function arrayBufferLength(value) {
const length = value.byteLength - value.byteOffset;
return digitCount(length) + 1 + length;
}
function encodingLength(value) {
const length = 0;
if (value == null) return length;
const type = getType(value);
switch(type){
case 'buffer':
return digitCount(value.length) + 1 + value.length;
case 'arraybufferview':
return arrayBufferLength(value);
case 'string':
return stringLength(value);
case 'array':
case 'set':
return listLength(value);
case 'number':
return 1 + digitCount(Math.floor(value)) + 1;
case 'bigint':
return 1 + value.toString().length + 1;
case 'object':
return objectLength(value);
case 'map':
return mapLength(value);
default:
throw new TypeError(`Unsupported value of type "${type}"`);
}
}
module.exports = encodingLength;
/***/ }),
/***/ "./node_modules/bencode/lib/index.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const bencode = module.exports;
bencode.encode = __webpack_require__("./node_modules/bencode/lib/encode.js");
bencode.decode = __webpack_require__("./node_modules/bencode/lib/decode.js");
/**
* Determines the amount of bytes
* needed to encode the given value
* @param {Object|Array|Buffer|String|Number|Boolean} value
* @return {Number} byteCount
*/ bencode.byteLength = bencode.encodingLength = __webpack_require__("./node_modules/bencode/lib/encoding-length.js");
/***/ }),
/***/ "./node_modules/bencode/lib/util.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* provided dependency */ var Buffer = __webpack_require__("./node_modules/buffer/index.js")["lW"];
const util = module.exports;
util.digitCount = function digitCount(value) {
// Add a digit for negative numbers, as the sign will be prefixed
const sign = value < 0 ? 1 : 0;
// Guard against negative numbers & zero going into log10(),
// as that would return -Infinity
value = Math.abs(Number(value || 1));
return Math.floor(Math.log10(value)) + 1 + sign;
};
util.getType = function getType(value) {
if (Buffer.isBuffer(value)) return 'buffer';
if (ArrayBuffer.isView(value)) return 'arraybufferview';
if (Array.isArray(value)) return 'array';
if (value instanceof Number) return 'number';
if (value instanceof Boolean) return 'boolean';
if (value instanceof Set) return 'set';
if (value instanceof Map) return 'map';
if (value instanceof String) return 'string';
if (value instanceof ArrayBuffer) return 'arraybuffer';
return typeof value;
};
/***/ }),
/***/ "./node_modules/buffer/index.js":
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var __webpack_unused_export__;
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/ /* eslint-disable no-proto */
const base64 = __webpack_require__("./node_modules/base64-js/index.js");
const ieee754 = __webpack_require__("./node_modules/ieee754/index.js");
const customInspectSymbol = typeof Symbol === 'function' && typeof Symbol['for'] === 'function' // eslint-disable-line dot-notation
? Symbol['for']('nodejs.util.inspect.custom') // eslint-disable-line dot-notation
: null;
exports.lW = Buffer;
__webpack_unused_export__ = SlowBuffer;
exports.h2 = 50;
const K_MAX_LENGTH = 0x7fffffff;
__webpack_unused_export__ = K_MAX_LENGTH;
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Print warning and recommend using `buffer` v4.x which has an Object
* implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* We report that the browser does not support typed arrays if the are not subclassable
* using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
* (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
* for __proto__ and has a buggy typed array implementation.
*/ Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport();
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && typeof console.error === 'function') {
console.error('This browser lacks typed array (Uint8Array) support which is required by ' + '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.');
}
function typedArraySupport() {
// Can typed array instances can be augmented?
try {
const arr = new Uint8Array(1);
const proto = {
foo: function() {
return 42;
}
};
Object.setPrototypeOf(proto, Uint8Array.prototype);
Object.setPrototypeOf(arr, proto);
return arr.foo() === 42;
} catch (e) {
return false;
}
}
Object.defineProperty(Buffer.prototype, 'parent', {
enumerable: true,
get: function() {
if (!Buffer.isBuffer(this)) return undefined;
return this.buffer;
}
});
Object.defineProperty(Buffer.prototype, 'offset', {
enumerable: true,
get: function() {
if (!Buffer.isBuffer(this)) return undefined;
return this.byteOffset;
}
});
function createBuffer(length) {
if (length > K_MAX_LENGTH) {
throw new RangeError('The value "' + length + '" is invalid for option "size"');
}
// Return an augmented `Uint8Array` instance
const buf = new Uint8Array(length);
Object.setPrototypeOf(buf, Buffer.prototype);
return buf;
}
/**
* The Buffer constructor returns instances of `Uint8Array` that have their
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
* returns a single octet.
*
* The `Uint8Array` prototype remains unmodified.
*/ function Buffer(arg, encodingOrOffset, length) {
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new TypeError('The "string" argument must be of type string. Received type number');
}
return allocUnsafe(arg);
}
return from(arg, encodingOrOffset, length);
}
Buffer.poolSize = 8192 // not used by this implementation
;
function from(value, encodingOrOffset, length) {
if (typeof value === 'string') {
return fromString(value, encodingOrOffset);
}
if (ArrayBuffer.isView(value)) {
return fromArrayView(value);
}
if (value == null) {
throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + typeof value);
}
if (isInstance(value, ArrayBuffer) || value && isInstance(value.buffer, ArrayBuffer)) {
return fromArrayBuffer(value, encodingOrOffset, length);
}
if (typeof SharedArrayBuffer !== 'undefined' && (isInstance(value, SharedArrayBuffer) || value && isInstance(value.buffer, SharedArrayBuffer))) {
return fromArrayBuffer(value, encodingOrOffset, length);
}
if (typeof value === 'number') {
throw new TypeError('The "value" argument must not be of type number. Received type number');
}
const valueOf = value.valueOf && value.valueOf();
if (valueOf != null && valueOf !== value) {
return Buffer.from(valueOf, encodingOrOffset, length);
}
const b = fromObject(value);
if (b) return b;
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === 'function') {
return Buffer.from(value[Symbol.toPrimitive]('string'), encodingOrOffset, length);
}
throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + typeof value);
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/ Buffer.from = function(value, encodingOrOffset, length) {
return from(value, encodingOrOffset, length);
};
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
// https://github.com/feross/buffer/pull/148
Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
Object.setPrototypeOf(Buffer, Uint8Array);
function assertSize(size) {
if (typeof size !== 'number') {
throw new TypeError('"size" argument must be of type number');
} else if (size < 0) {
throw new RangeError('The value "' + size + '" is invalid for option "size"');
}
}
function alloc(size, fill, encoding) {
assertSize(size);
if (size <= 0) {
return createBuffer(size);
}
if (fill !== undefined) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpreted as a start offset.
return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill);
}
return createBuffer(size);
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/ Buffer.alloc = function(size, fill, encoding) {
return alloc(size, fill, encoding);
};
function allocUnsafe(size) {
assertSize(size);
return createBuffer(size < 0 ? 0 : checked(size) | 0);
}
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
* */ Buffer.allocUnsafe = function(size) {
return allocUnsafe(size);
};
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
*/ Buffer.allocUnsafeSlow = function(size) {
return allocUnsafe(size);
};
function fromString(string, encoding) {
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8';
}
if (!Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding);
}
const length = byteLength(string, encoding) | 0;
let buf = createBuffer(length);
const actual = buf.write(string, encoding);
if (actual !== length) {
// Writing a hex string, for example, that contains invalid characters will
// cause everything after the first invalid character to be ignored. (e.g.
// 'abxxcd' will be treated as 'ab')
buf = buf.slice(0, actual);
}
return buf;
}
function fromArrayLike(array) {
const length = array.length < 0 ? 0 : checked(array.length) | 0;
const buf = createBuffer(length);
for(let i = 0; i < length; i += 1){
buf[i] = array[i] & 255;
}
return buf;
}
function fromArrayView(arrayView) {
if (isInstance(arrayView, Uint8Array)) {
const copy = new Uint8Array(arrayView);
return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength);
}
return fromArrayLike(arrayView);
}
function fromArrayBuffer(array, byteOffset, length) {
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('"offset" is outside of buffer bounds');
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('"length" is outside of buffer bounds');
}
let buf;
if (byteOffset === undefined && length === undefined) {
buf = new Uint8Array(array);
} else if (length === undefined) {
buf = new Uint8Array(array, byteOffset);
} else {
buf = new Uint8Array(array, byteOffset, length);
}
// Return an augmented `Uint8Array` instance
Object.setPrototypeOf(buf, Buffer.prototype);
return buf;
}
function fromObject(obj) {
if (Buffer.isBuffer(obj)) {
const len = checked(obj.length) | 0;
const buf = createBuffer(len);
if (buf.length === 0) {
return buf;
}
obj.copy(buf, 0, 0, len);
return buf;
}
if (obj.length !== undefined) {
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
return createBuffer(0);
}
return fromArrayLike(obj);
}
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
return fromArrayLike(obj.data);
}
}
function checked(length) {
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= K_MAX_LENGTH) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes');
}
return length | 0;
}
function SlowBuffer(length) {
if (+length != length) {
length = 0;
}
return Buffer.alloc(+length);
}
Buffer.isBuffer = function isBuffer(b) {
return b != null && b._isBuffer === true && b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
;
};
Buffer.compare = function compare(a, b) {
if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength);
if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength);
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');
}
if (a === b) return 0;
let x = a.length;
let y = b.length;
for(let i = 0, len = Math.min(x, y); i < len; ++i){
if (a[i] !== b[i]) {
x = a[i];
y = b[i];
break;
}
}
if (x < y) return -1;
if (y < x) return 1;
return 0;
};
Buffer.isEncoding = function isEncoding(encoding) {
switch(String(encoding).toLowerCase()){
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'latin1':
case 'binary':
case 'base64':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true;
default:
return false;
}
};
Buffer.concat = function concat(list, length) {
if (!Array.isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers');
}
if (list.length === 0) {
return Buffer.alloc(0);
}
let i;
if (length === undefined) {
length = 0;
for(i = 0; i < list.length; ++i){
length += list[i].length;
}
}
const buffer = Buffer.allocUnsafe(length);
let pos = 0;
for(i = 0; i < list.length; ++i){
let buf = list[i];
if (isInstance(buf, Uint8Array)) {
if (pos + buf.length > buffer.length) {
if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf);
buf.copy(buffer, pos);
} else {
Uint8Array.prototype.set.call(buffer, buf, pos);
}
} else if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers');
} else {
buf.copy(buffer, pos);
}
pos += buf.length;
}
return buffer;
};
function byteLength(string, encoding) {
if (Buffer.isBuffer(string)) {
return string.length;
}
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
return string.byteLength;
}
if (typeof string !== 'string') {
throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + 'Received type ' + typeof string);
}
const len = string.length;
const mustMatch = arguments.length > 2 && arguments[2] === true;
if (!mustMatch && len === 0) return 0;
// Use a for loop to avoid recursion
let loweredCase = false;
for(;;){
switch(encoding){
case 'ascii':
case 'latin1':
case 'binary':
return len;
case 'utf8':
case 'utf-8':
return utf8ToBytes(string).length;
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2;
case 'hex':
return len >>> 1;
case 'base64':
return base64ToBytes(string).length;
default:
if (loweredCase) {
return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
;
}
encoding = ('' + encoding).toLowerCase();
loweredCase = true;
}
}
}
Buffer.byteLength = byteLength;
function slowToString(encoding, start, end) {
let loweredCase = false;
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0) {
start = 0;
}
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length) {
return '';
}
if (end === undefined || end > this.length) {
end = this.length;
}
if (end <= 0) {
return '';
}
// Force coercion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0;
start >>>= 0;
if (end <= start) {
return '';
}
if (!encoding) encoding = 'utf8';
while(true){
switch(encoding){
case 'hex':
return hexSlice(this, start, end);
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end);
case 'ascii':
return asciiSlice(this, start, end);
case 'latin1':
case 'binary':
return latin1Slice(this, start, end);
case 'base64':
return base64Slice(this, start, end);
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end);
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
encoding = (encoding + '').toLowerCase();
loweredCase = true;
}
}
}
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
// reliably in a browserify context because there could be multiple different
// copies of the 'buffer' package in use. This method works even for Buffer
// instances that were created from another copy of the `buffer` package.
// See: https://github.com/feross/buffer/issues/154
Buffer.prototype._isBuffer = true;
function swap(b, n, m) {
const i = b[n];
b[n] = b[m];
b[m] = i;
}
Buffer.prototype.swap16 = function swap16() {
const len = this.length;
if (len % 2 !== 0) {
throw new RangeError('Buffer size must be a multiple of 16-bits');
}
for(let i = 0; i < len; i += 2){
swap(this, i, i + 1);
}
return this;
};
Buffer.prototype.swap32 = function swap32() {
const len = this.length;
if (len % 4 !== 0) {
throw new RangeError('Buffer size must be a multiple of 32-bits');
}
for(let i = 0; i < len; i += 4){
swap(this, i, i + 3);
swap(this, i + 1, i + 2);
}
return this;
};
Buffer.prototype.swap64 = function swap64() {
const len = this.length;
if (len % 8 !== 0) {
throw new RangeError('Buffer size must be a multiple of 64-bits');
}
for(let i = 0; i < len; i += 8){
swap(this, i, i + 7);
swap(this, i + 1, i + 6);
swap(this, i + 2, i + 5);
swap(this, i + 3, i + 4);
}
return this;
};
Buffer.prototype.toString = function toString() {
const length = this.length;
if (length === 0) return '';
if (arguments.length === 0) return utf8Slice(this, 0, length);
return slowToString.apply(this, arguments);
};
Buffer.prototype.toLocaleString = Buffer.prototype.toString;
Buffer.prototype.equals = function equals(b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer');
if (this === b) return true;
return Buffer.compare(this, b) === 0;
};
Buffer.prototype.inspect = function inspect() {
let str = '';
const max = exports.h2;
str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim();
if (this.length > max) str += ' ... ';
return '<Buffer ' + str + '>';
};
if (customInspectSymbol) {
Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect;
}
Buffer.prototype.compare = function compare(target, start, end, thisStart, thisEnd) {
if (isInstance(target, Uint8Array)) {
target = Buffer.from(target, target.offset, target.byteLength);
}
if (!Buffer.isBuffer(target)) {
throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. ' + 'Received type ' + typeof target);
}
if (start === undefined) {
start = 0;
}
if (end === undefined) {
end = target ? target.length : 0;
}
if (thisStart === undefined) {
thisStart = 0;
}
if (thisEnd === undefined) {
thisEnd = this.length;
}
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
throw new RangeError('out of range index');
}
if (thisStart >= thisEnd && start >= end) {
return 0;
}
if (thisStart >= thisEnd) {
return -1;
}
if (start >= end) {
return 1;
}
start >>>= 0;
end >>>= 0;
thisStart >>>= 0;
thisEnd >>>= 0;
if (this === target) return 0;
let x = thisEnd - thisStart;
let y = end - start;
const len = Math.min(x, y);
const thisCopy = this.slice(thisStart, thisEnd);
const targetCopy = target.slice(start, end);
for(let i = 0; i < len; ++i){
if (thisCopy[i] !== targetCopy[i]) {
x = thisCopy[i];
y = targetCopy[i];
break;
}
}
if (x < y) return -1;
if (y < x) return 1;
return 0;
};
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
// Empty buffer means no match
if (buffer.length === 0) return -1;
// Normalize byteOffset
if (typeof byteOffset === 'string') {
encoding = byteOffset;
byteOffset = 0;
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff;
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000;
}
byteOffset = +byteOffset // Coerce to Number.
;
if (numberIsNaN(byteOffset)) {
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
byteOffset = dir ? 0 : buffer.length - 1;
}
// Normalize byteOffset: negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
if (byteOffset >= buffer.length) {
if (dir) return -1;
else byteOffset = buffer.length - 1;
} else if (byteOffset < 0) {
if (dir) byteOffset = 0;
else return -1;
}
// Normalize val
if (typeof val === 'string') {
val = Buffer.from(val, encoding);
}
// Finally, search either indexOf (if dir is true) or lastIndexOf
if (Buffer.isBuffer(val)) {
// Special case: looking for empty string/buffer always fails
if (val.length === 0) {
return -1;
}
return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
} else if (typeof val === 'number') {
val = val & 0xFF // Search for a byte value [0-255]
;
if (typeof Uint8Array.prototype.indexOf === 'function') {
if (dir) {
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
} else {
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
}
}
return arrayIndexOf(buffer, [
val
], byteOffset, encoding, dir);
}
throw new TypeError('val must be string, number or Buffer');
}
function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
let indexSize = 1;
let arrLength = arr.length;
let valLength = val.length;
if (encoding !== undefined) {
encoding = String(encoding).toLowerCase();
if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') {
if (arr.length < 2 || val.length < 2) {
return -1;
}
indexSize = 2;
arrLength /= 2;
valLength /= 2;
byteOffset /= 2;
}
}
function read(buf, i) {
if (indexSize === 1) {
return buf[i];
} else {
return buf.readUInt16BE(i * indexSize);
}
}
let i;
if (dir) {
let foundIndex = -1;
for(i = byteOffset; i < arrLength; i++){
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
if (foundIndex === -1) foundIndex = i;
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize;
} else {
if (foundIndex !== -1) i -= i - foundIndex;
foundIndex = -1;
}
}
} else {
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
for(i = byteOffset; i >= 0; i--){
let found = true;
for(let j = 0; j < valLength; j++){
if (read(arr, i + j) !== read(val, j)) {
found = false;
break;
}
}
if (found) return i;
}
}
return -1;
}
Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1;
};
Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
};
Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
};
function hexWrite(buf, string, offset, length) {
offset = Number(offset) || 0;
const remaining = buf.length - offset;
if (!length) {
length = remaining;
} else {
length = Number(length);
if (length > remaining) {
length = remaining;
}
}
const strLen = string.length;
if (length > strLen / 2) {
length = strLen / 2;
}
let i;
for(i = 0; i < length; ++i){
const parsed = parseInt(string.substr(i * 2, 2), 16);
if (numberIsNaN(parsed)) return i;
buf[offset + i] = parsed;
}
return i;
}
function utf8Write(buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length);
}
function asciiWrite(buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length);
}
function base64Write(buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length);
}
function ucs2Write(buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length);
}
Buffer.prototype.write = function write(string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8';
length = this.length;
offset = 0;
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset;
length = this.length;
offset = 0;
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset >>> 0;
if (isFinite(length)) {
length = length >>> 0;
if (encoding === undefined) encoding = 'utf8';
} else {
encoding = length;
length = undefined;
}
} else {
throw new Error('Buffer.write(string, encoding, offset[, length]) is no longer supported');
}
const remaining = this.length - offset;
if (length === undefined || length > remaining) length = remaining;
if (string.length > 0 && (length < 0 || offset < 0) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds');
}
if (!encoding) encoding = 'utf8';
let loweredCase = false;
for(;;){
switch(encoding){
case 'hex':
return hexWrite(this, string, offset, length);
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length);
case 'ascii':
case 'latin1':
case 'binary':
return asciiWrite(this, string, offset, length);
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length);
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length);
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
encoding = ('' + encoding).toLowerCase();
loweredCase = true;
}
}
};
Buffer.prototype.toJSON = function toJSON() {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
};
};
function base64Slice(buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf);
} else {
return base64.fromByteArray(buf.slice(start, end));
}
}
function utf8Slice(buf, start, end) {
end = Math.min(buf.length, end);
const res = [];
let i = start;
while(i < end){
const firstByte = buf[i];
let codePoint = null;
let bytesPerSequence = firstByte > 0xEF ? 4 : firstByte > 0xDF ? 3 : firstByte > 0xBF ? 2 : 1;
if (i + bytesPerSequence <= end) {
let secondByte, thirdByte, fourthByte, tempCodePoint;
switch(bytesPerSequence){
case 1:
if (firstByte < 0x80) {
codePoint = firstByte;
}
break;
case 2:
secondByte = buf[i + 1];
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | secondByte & 0x3F;
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint;
}
}
break;
case 3:
secondByte = buf[i + 1];
thirdByte = buf[i + 2];
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | thirdByte & 0x3F;
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint;
}
}
break;
case 4:
secondByte = buf[i + 1];
thirdByte = buf[i + 2];
fourthByte = buf[i + 3];
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | fourthByte & 0x3F;
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint;
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD;
bytesPerSequence = 1;
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000;
res.push(codePoint >>> 10 & 0x3FF | 0xD800);
codePoint = 0xDC00 | codePoint & 0x3FF;
}
res.push(codePoint);
i += bytesPerSequence;
}
return decodeCodePointsArray(res);
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
const MAX_ARGUMENTS_LENGTH = 0x1000;
function decodeCodePointsArray(codePoints) {
const len = codePoints.length;
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
;
}
// Decode in chunks to avoid "call stack size exceeded".
let res = '';
let i = 0;
while(i < len){
res += String.fromCharCode.apply(String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH));
}
return res;
}
function asciiSlice(buf, start, end) {
let ret = '';
end = Math.min(buf.length, end);
for(let i = start; i < end; ++i){
ret += String.fromCharCode(buf[i] & 0x7F);
}
return ret;
}
function latin1Slice(buf, start, end) {
let ret = '';
end = Math.min(buf.length, end);
for(let i = start; i < end; ++i){
ret += String.fromCharCode(buf[i]);
}
return ret;
}
function hexSlice(buf, start, end) {
const len = buf.length;
if (!start || start < 0) start = 0;
if (!end || end < 0 || end > len) end = len;
let out = '';
for(let i = start; i < end; ++i){
out += hexSliceLookupTable[buf[i]];
}
return out;
}
function utf16leSlice(buf, start, end) {
const bytes = buf.slice(start, end);
let res = '';
// If bytes.length is odd, the last 8 bits must be ignored (same as node.js)
for(let i = 0; i < bytes.length - 1; i += 2){
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256);
}
return res;
}
Buffer.prototype.slice = function slice(start, end) {
const len = this.length;
start = ~~start;
end = end === undefined ? len : ~~end;
if (start < 0) {
start += len;
if (start < 0) start = 0;
} else if (start > len) {
start = len;
}
if (end < 0) {
end += len;
if (end < 0) end = 0;
} else if (end > len) {
end = len;
}
if (end < start) end = start;
const newBuf = this.subarray(start, end);
// Return an augmented `Uint8Array` instance
Object.setPrototypeOf(newBuf, Buffer.prototype);
return newBuf;
};
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/ function checkOffset(offset, ext, length) {
if (offset % 1 !== 0 || offset < 0) throw new RangeError('offset is not uint');
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length');
}
Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) checkOffset(offset, byteLength, this.length);
let val = this[offset];
let mul = 1;
let i = 0;
while(++i < byteLength && (mul *= 0x100)){
val += this[offset + i] * mul;
}
return val;
};
Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) {
checkOffset(offset, byteLength, this.length);
}
let val = this[offset + --byteLength];
let mul = 1;
while(byteLength > 0 && (mul *= 0x100)){
val += this[offset + --byteLength] * mul;
}
return val;
};
Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 1, this.length);
return this[offset];
};
Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 2, this.length);
return this[offset] | this[offset + 1] << 8;
};
Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 2, this.length);
return this[offset] << 8 | this[offset + 1];
};
Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 4, this.length);
return (this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16) + this[offset + 3] * 0x1000000;
};
Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 4, this.length);
return this[offset] * 0x1000000 + (this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3]);
};
Buffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE(offset) {
offset = offset >>> 0;
validateNumber(offset, 'offset');
const first = this[offset];
const last = this[offset + 7];
if (first === undefined || last === undefined) {
boundsError(offset, this.length - 8);
}
const lo = first + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 24;
const hi = this[++offset] + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + last * 2 ** 24;
return BigInt(lo) + (BigInt(hi) << BigInt(32));
});
Buffer.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE(offset) {
offset = offset >>> 0;
validateNumber(offset, 'offset');
const first = this[offset];
const last = this[offset + 7];
if (first === undefined || last === undefined) {
boundsError(offset, this.length - 8);
}
const hi = first * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + this[++offset];
const lo = this[++offset] * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + last;
return (BigInt(hi) << BigInt(32)) + BigInt(lo);
});
Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) checkOffset(offset, byteLength, this.length);
let val = this[offset];
let mul = 1;
let i = 0;
while(++i < byteLength && (mul *= 0x100)){
val += this[offset + i] * mul;
}
mul *= 0x80;
if (val >= mul) val -= Math.pow(2, 8 * byteLength);
return val;
};
Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) checkOffset(offset, byteLength, this.length);
let i = byteLength;
let mul = 1;
let val = this[offset + --i];
while(i > 0 && (mul *= 0x100)){
val += this[offset + --i] * mul;
}
mul *= 0x80;
if (val >= mul) val -= Math.pow(2, 8 * byteLength);
return val;
};
Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 1, this.length);
if (!(this[offset] & 0x80)) return this[offset];
return (0xff - this[offset] + 1) * -1;
};
Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 2, this.length);
const val = this[offset] | this[offset + 1] << 8;
return val & 0x8000 ? val | 0xFFFF0000 : val;
};
Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 2, this.length);
const val = this[offset + 1] | this[offset] << 8;
return val & 0x8000 ? val | 0xFFFF0000 : val;
};
Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 4, this.length);
return this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16 | this[offset + 3] << 24;
};
Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 4, this.length);
return this[offset] << 24 | this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3];
};
Buffer.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE(offset) {
offset = offset >>> 0;
validateNumber(offset, 'offset');
const first = this[offset];
const last = this[offset + 7];
if (first === undefined || last === undefined) {
boundsError(offset, this.length - 8);
}
const val = this[offset + 4] + this[offset + 5] * 2 ** 8 + this[offset + 6] * 2 ** 16 + (last << 24) // Overflow
;
return (BigInt(val) << BigInt(32)) + BigInt(first + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 24);
});
Buffer.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE(offset) {
offset = offset >>> 0;
validateNumber(offset, 'offset');
const first = this[offset];
const last = this[offset + 7];
if (first === undefined || last === undefined) {
boundsError(offset, this.length - 8);
}
const val = (first << 24) + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + this[++offset];
return (BigInt(val) << BigInt(32)) + BigInt(this[++offset] * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + last);
});
Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 4, this.length);
return ieee754.read(this, offset, true, 23, 4);
};
Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 4, this.length);
return ieee754.read(this, offset, false, 23, 4);
};
Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 8, this.length);
return ieee754.read(this, offset, true, 52, 8);
};
Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert) checkOffset(offset, 8, this.length);
return ieee754.read(this, offset, false, 52, 8);
};
function checkInt(buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance');
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds');
if (offset + ext > buf.length) throw new RangeError('Index out of range');
}
Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) {
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
checkInt(this, value, offset, byteLength, maxBytes, 0);
}
let mul = 1;
let i = 0;
this[offset] = value & 0xFF;
while(++i < byteLength && (mul *= 0x100)){
this[offset + i] = value / mul & 0xFF;
}
return offset + byteLength;
};
Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) {
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
checkInt(this, value, offset, byteLength, maxBytes, 0);
}
let i = byteLength - 1;
let mul = 1;
this[offset + i] = value & 0xFF;
while(--i >= 0 && (mul *= 0x100)){
this[offset + i] = value / mul & 0xFF;
}
return offset + byteLength;
};
Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0);
this[offset] = value & 0xff;
return offset + 1;
};
Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
this[offset] = value & 0xff;
this[offset + 1] = value >>> 8;
return offset + 2;
};
Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
this[offset] = value >>> 8;
this[offset + 1] = value & 0xff;
return offset + 2;
};
Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
this[offset + 3] = value >>> 24;
this[offset + 2] = value >>> 16;
this[offset + 1] = value >>> 8;
this[offset] = value & 0xff;
return offset + 4;
};
Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
this[offset] = value >>> 24;
this[offset + 1] = value >>> 16;
this[offset + 2] = value >>> 8;
this[offset + 3] = value & 0xff;
return offset + 4;
};
function wrtBigUInt64LE(buf, value, offset, min, max) {
checkIntBI(value, min, max, buf, offset, 7);
let lo = Number(value & BigInt(0xffffffff));
buf[offset++] = lo;
lo = lo >> 8;
buf[offset++] = lo;
lo = lo >> 8;
buf[offset++] = lo;
lo = lo >> 8;
buf[offset++] = lo;
let hi = Number(value >> BigInt(32) & BigInt(0xffffffff));
buf[offset++] = hi;
hi = hi >> 8;
buf[offset++] = hi;
hi = hi >> 8;
buf[offset++] = hi;
hi = hi >> 8;
buf[offset++] = hi;
return offset;
}
function wrtBigUInt64BE(buf, value, offset, min, max) {
checkIntBI(value, min, max, buf, offset, 7);
let lo = Number(value & BigInt(0xffffffff));
buf[offset + 7] = lo;
lo = lo >> 8;
buf[offset + 6] = lo;
lo = lo >> 8;
buf[offset + 5] = lo;
lo = lo >> 8;
buf[offset + 4] = lo;
let hi = Number(value >> BigInt(32) & BigInt(0xffffffff));
buf[offset + 3] = hi;
hi = hi >> 8;
buf[offset + 2] = hi;
hi = hi >> 8;
buf[offset + 1] = hi;
hi = hi >> 8;
buf[offset] = hi;
return offset + 8;
}
Buffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE(value) {
let offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
return wrtBigUInt64LE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'));
});
Buffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE(value) {
let offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
return wrtBigUInt64BE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'));
});
Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) {
const limit = Math.pow(2, 8 * byteLength - 1);
checkInt(this, value, offset, byteLength, limit - 1, -limit);
}
let i = 0;
let mul = 1;
let sub = 0;
this[offset] = value & 0xFF;
while(++i < byteLength && (mul *= 0x100)){
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
sub = 1;
}
this[offset + i] = (value / mul >> 0) - sub & 0xFF;
}
return offset + byteLength;
};
Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) {
const limit = Math.pow(2, 8 * byteLength - 1);
checkInt(this, value, offset, byteLength, limit - 1, -limit);
}
let i = byteLength - 1;
let mul = 1;
let sub = 0;
this[offset + i] = value & 0xFF;
while(--i >= 0 && (mul *= 0x100)){
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
sub = 1;
}
this[offset + i] = (value / mul >> 0) - sub & 0xFF;
}
return offset + byteLength;
};
Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80);
if (value < 0) value = 0xff + value + 1;
this[offset] = value & 0xff;
return offset + 1;
};
Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
this[offset] = value & 0xff;
this[offset + 1] = value >>> 8;
return offset + 2;
};
Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
this[offset] = value >>> 8;
this[offset + 1] = value & 0xff;
return offset + 2;
};
Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
this[offset] = value & 0xff;
this[offset + 1] = value >>> 8;
this[offset + 2] = value >>> 16;
this[offset + 3] = value >>> 24;
return offset + 4;
};
Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1;
this[offset] = value >>> 24;
this[offset + 1] = value >>> 16;
this[offset + 2] = value >>> 8;
this[offset + 3] = value & 0xff;
return offset + 4;
};
Buffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE(value) {
let offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
return wrtBigUInt64LE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'));
});
Buffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE(value) {
let offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
return wrtBigUInt64BE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'));
});
function checkIEEE754(buf, value, offset, ext, max, min) {
if (offset + ext > buf.length) throw new RangeError('Index out of range');
if (offset < 0) throw new RangeError('Index out of range');
}
function writeFloat(buf, value, offset, littleEndian, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38);
}
ieee754.write(buf, value, offset, littleEndian, 23, 4);
return offset + 4;
}
Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert);
};
Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert);
};
function writeDouble(buf, value, offset, littleEndian, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308);
}
ieee754.write(buf, value, offset, littleEndian, 52, 8);
return offset + 8;
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert);
};
Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert);
};
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy(target, targetStart, start, end) {
if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer');
if (!start) start = 0;
if (!end && end !== 0) end = this.length;
if (targetStart >= target.length) targetStart = target.length;
if (!targetStart) targetStart = 0;
if (end > 0 && end < start) end = start;
// Copy 0 bytes; we're done
if (end === start) return 0;
if (target.length === 0 || this.length === 0) return 0;
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds');
}
if (start < 0 || start >= this.length) throw new RangeError('Index out of range');
if (end < 0) throw new RangeError('sourceEnd out of bounds');
// Are we oob?
if (end > this.length) end = this.length;
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start;
}
const len = end - start;
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
// Use built-in when available, missing from IE11
this.copyWithin(targetStart, start, end);
} else {
Uint8Array.prototype.set.call(target, this.subarray(start, end), targetStart);
}
return len;
};
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill(val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start;
start = 0;
end = this.length;
} else if (typeof end === 'string') {
encoding = end;
end = this.length;
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string');
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding);
}
if (val.length === 1) {
const code = val.charCodeAt(0);
if (encoding === 'utf8' && code < 128 || encoding === 'latin1') {
// Fast path: If `val` fits into a single byte, use that numeric value.
val = code;
}
}
} else if (typeof val === 'number') {
val = val & 255;
} else if (typeof val === 'boolean') {
val = Number(val);
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index');
}
if (end <= start) {
return this;
}
start = start >>> 0;
end = end === undefined ? this.length : end >>> 0;
if (!val) val = 0;
let i;
if (typeof val === 'number') {
for(i = start; i < end; ++i){
this[i] = val;
}
} else {
const bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding);
const len = bytes.length;
if (len === 0) {
throw new TypeError('The value "' + val + '" is invalid for argument "value"');
}
for(i = 0; i < end - start; ++i){
this[i + start] = bytes[i % len];
}
}
return this;
};
// CUSTOM ERRORS
// =============
// Simplified versions from Node, changed for Buffer-only usage
const errors = {};
function E(sym, getMessage, Base) {
errors[sym] = class NodeError extends Base {
get code() {
return sym;
}
set code(value) {
Object.defineProperty(this, 'code', {
configurable: true,
enumerable: true,
value,
writable: true
});
}
toString() {
return `${this.name} [${sym}]: ${this.message}`;
}
constructor(){
super();
Object.defineProperty(this, 'message', {
value: getMessage.apply(this, arguments),
writable: true,
configurable: true
});
// Add the error code to the name to include it in the stack trace.
this.name = `${this.name} [${sym}]`;
// Access the stack to generate the error message including the error code
// from the name.
this.stack // eslint-disable-line no-unused-expressions
;
// Reset the name to the actual name.
delete this.name;
}
};
}
E('ERR_BUFFER_OUT_OF_BOUNDS', function(name) {
if (name) {
return `${name} is outside of buffer bounds`;
}
return 'Attempt to access memory outside buffer bounds';
}, RangeError);
E('ERR_INVALID_ARG_TYPE', function(name, actual) {
return `The "${name}" argument must be of type number. Received type ${typeof actual}`;
}, TypeError);
E('ERR_OUT_OF_RANGE', function(str, range, input) {
let msg = `The value of "${str}" is out of range.`;
let received = input;
if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {
received = addNumericalSeparator(String(input));
} else if (typeof input === 'bigint') {
received = String(input);
if (input > BigInt(2) ** BigInt(32) || input < -(BigInt(2) ** BigInt(32))) {
received = addNumericalSeparator(received);
}
received += 'n';
}
msg += ` It must be ${range}. Received ${received}`;
return msg;
}, RangeError);
function addNumericalSeparator(val) {
let res = '';
let i = val.length;
const start = val[0] === '-' ? 1 : 0;
for(; i >= start + 4; i -= 3){
res = `_${val.slice(i - 3, i)}${res}`;
}
return `${val.slice(0, i)}${res}`;
}
// CHECK FUNCTIONS
// ===============
function checkBounds(buf, offset, byteLength) {
validateNumber(offset, 'offset');
if (buf[offset] === undefined || buf[offset + byteLength] === undefined) {
boundsError(offset, buf.length - (byteLength + 1));
}
}
function checkIntBI(value, min, max, buf, offset, byteLength) {
if (value > max || value < min) {
const n = typeof min === 'bigint' ? 'n' : '';
let range;
if (byteLength > 3) {
if (min === 0 || min === BigInt(0)) {
range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`;
} else {
range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` + `${(byteLength + 1) * 8 - 1}${n}`;
}
} else {
range = `>= ${min}${n} and <= ${max}${n}`;
}
throw new errors.ERR_OUT_OF_RANGE('value', range, value);
}
checkBounds(buf, offset, byteLength);
}
function validateNumber(value, name) {
if (typeof value !== 'number') {
throw new errors.ERR_INVALID_ARG_TYPE(name, 'number', value);
}
}
function boundsError(value, length, type) {
if (Math.floor(value) !== value) {
validateNumber(value, type);
throw new errors.ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value);
}
if (length < 0) {
throw new errors.ERR_BUFFER_OUT_OF_BOUNDS();
}
throw new errors.ERR_OUT_OF_RANGE(type || 'offset', `>= ${type ? 1 : 0} and <= ${length}`, value);
}
// HELPER FUNCTIONS
// ================
const INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g;
function base64clean(str) {
// Node takes equal signs as end of the Base64 encoding
str = str.split('=')[0];
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = str.trim().replace(INVALID_BASE64_RE, '');
// Node converts strings with length < 2 to ''
if (str.length < 2) return '';
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while(str.length % 4 !== 0){
str = str + '=';
}
return str;
}
function utf8ToBytes(string, units) {
units = units || Infinity;
let codePoint;
const length = string.length;
let leadSurrogate = null;
const bytes = [];
for(let i = 0; i < length; ++i){
codePoint = string.charCodeAt(i);
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
continue;
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
continue;
}
// valid lead
leadSurrogate = codePoint;
continue;
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
leadSurrogate = codePoint;
continue;
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000;
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
}
leadSurrogate = null;
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break;
bytes.push(codePoint);
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break;
bytes.push(codePoint >> 0x6 | 0xC0, codePoint & 0x3F | 0x80);
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break;
bytes.push(codePoint >> 0xC | 0xE0, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80);
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break;
bytes.push(codePoint >> 0x12 | 0xF0, codePoint >> 0xC & 0x3F | 0x80, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80);
} else {
throw new Error('Invalid code point');
}
}
return bytes;
}
function asciiToBytes(str) {
const byteArray = [];
for(let i = 0; i < str.length; ++i){
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF);
}
return byteArray;
}
function utf16leToBytes(str, units) {
let c, hi, lo;
const byteArray = [];
for(let i = 0; i < str.length; ++i){
if ((units -= 2) < 0) break;
c = str.charCodeAt(i);
hi = c >> 8;
lo = c % 256;
byteArray.push(lo);
byteArray.push(hi);
}
return byteArray;
}
function base64ToBytes(str) {
return base64.toByteArray(base64clean(str));
}
function blitBuffer(src, dst, offset, length) {
let i;
for(i = 0; i < length; ++i){
if (i + offset >= dst.length || i >= src.length) break;
dst[i + offset] = src[i];
}
return i;
}
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
// the `instanceof` check but they should be treated as of that type.
// See: https://github.com/feross/buffer/issues/166
function isInstance(obj, type) {
return obj instanceof type || obj != null && obj.constructor != null && obj.constructor.name != null && obj.constructor.name === type.name;
}
function numberIsNaN(obj) {
// For IE11 support
return obj !== obj // eslint-disable-line no-self-compare
;
}
// Create lookup table for `toString('hex')`
// See: https://github.com/feross/buffer/issues/219
const hexSliceLookupTable = function() {
const alphabet = '0123456789abcdef';
const table = new Array(256);
for(let i = 0; i < 16; ++i){
const i16 = i * 16;
for(let j = 0; j < 16; ++j){
table[i16 + j] = alphabet[i] + alphabet[j];
}
}
return table;
}();
// Return not function with Error if BigInt not supported
function defineBigIntMethod(fn) {
return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn;
}
function BufferBigIntNotDefined() {
throw new Error('BigInt not supported');
}
/***/ }),
/***/ "./node_modules/ieee754/index.js":
/***/ ((__unused_webpack_module, exports) => {
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */ exports.read = function(buffer, offset, isLE, mLen, nBytes) {
var e, m;
var eLen = nBytes * 8 - mLen - 1;
var eMax = (1 << eLen) - 1;
var eBias = eMax >> 1;
var nBits = -7;
var i = isLE ? nBytes - 1 : 0;
var d = isLE ? -1 : 1;
var s = buffer[offset + i];
i += d;
e = s & (1 << -nBits) - 1;
s >>= -nBits;
nBits += eLen;
for(; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8){}
m = e & (1 << -nBits) - 1;
e >>= -nBits;
nBits += mLen;
for(; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8){}
if (e === 0) {
e = 1 - eBias;
} else if (e === eMax) {
return m ? NaN : (s ? -1 : 1) * Infinity;
} else {
m = m + Math.pow(2, mLen);
e = e - eBias;
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
};
exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c;
var eLen = nBytes * 8 - mLen - 1;
var eMax = (1 << eLen) - 1;
var eBias = eMax >> 1;
var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
var i = isLE ? 0 : nBytes - 1;
var d = isLE ? 1 : -1;
var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
value = Math.abs(value);
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0;
e = eMax;
} else {
e = Math.floor(Math.log(value) / Math.LN2);
if (value * (c = Math.pow(2, -e)) < 1) {
e--;
c *= 2;
}
if (e + eBias >= 1) {
value += rt / c;
} else {
value += rt * Math.pow(2, 1 - eBias);
}
if (value * c >= 2) {
e++;
c /= 2;
}
if (e + eBias >= eMax) {
m = 0;
e = eMax;
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen);
e = e + eBias;
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
e = 0;
}
}
for(; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8){}
e = e << mLen | m;
eLen += mLen;
for(; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8){}
buffer[offset + i - d] |= s * 128;
};
/***/ }),
/***/ "./node_modules/path-browserify/index.js":
/***/ ((module) => {
"use strict";
// 'path' module extracted from Node.js v8.11.1 (only the posix part)
// transplited with Babel
// Copyright Joyent, Inc. and other Node contributors.
//
// 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 assertPath(path) {
if (typeof path !== 'string') {
throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
}
}
// Resolves . and .. elements in a path with directory names
function normalizeStringPosix(path, allowAboveRoot) {
var res = '';
var lastSegmentLength = 0;
var lastSlash = -1;
var dots = 0;
var code;
for(var i = 0; i <= path.length; ++i){
if (i < path.length) code = path.charCodeAt(i);
else if (code === 47 /*/*/ ) break;
else code = 47 /*/*/ ;
if (code === 47 /*/*/ ) {
if (lastSlash === i - 1 || dots === 1) {
// NOOP
} else if (lastSlash !== i - 1 && dots === 2) {
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/ ) {
if (res.length > 2) {
var lastSlashIndex = res.lastIndexOf('/');
if (lastSlashIndex !== res.length - 1) {
if (lastSlashIndex === -1) {
res = '';
lastSegmentLength = 0;
} else {
res = res.slice(0, lastSlashIndex);
lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
}
lastSlash = i;
dots = 0;
continue;
}
} else if (res.length === 2 || res.length === 1) {
res = '';
lastSegmentLength = 0;
lastSlash = i;
dots = 0;
continue;
}
}
if (allowAboveRoot) {
if (res.length > 0) res += '/..';
else res = '..';
lastSegmentLength = 2;
}
} else {
if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i);
else res = path.slice(lastSlash + 1, i);
lastSegmentLength = i - lastSlash - 1;
}
lastSlash = i;
dots = 0;
} else if (code === 46 /*.*/ && dots !== -1) {
++dots;
} else {
dots = -1;
}
}
return res;
}
function _format(sep, pathObject) {
var dir = pathObject.dir || pathObject.root;
var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
if (!dir) {
return base;
}
if (dir === pathObject.root) {
return dir + base;
}
return dir + sep + base;
}
var posix = {
// path.resolve([from ...], to)
resolve: function resolve() {
var resolvedPath = '';
var resolvedAbsolute = false;
var cwd;
for(var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--){
var path;
if (i >= 0) path = arguments[i];
else {
if (cwd === undefined) cwd = process.cwd();
path = cwd;
}
assertPath(path);
// Skip empty entries
if (path.length === 0) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/ ;
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
if (resolvedAbsolute) {
if (resolvedPath.length > 0) return '/' + resolvedPath;
else return '/';
} else if (resolvedPath.length > 0) {
return resolvedPath;
} else {
return '.';
}
},
normalize: function normalize(path) {
assertPath(path);
if (path.length === 0) return '.';
var isAbsolute = path.charCodeAt(0) === 47 /*/*/ ;
var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/ ;
// Normalize the path
path = normalizeStringPosix(path, !isAbsolute);
if (path.length === 0 && !isAbsolute) path = '.';
if (path.length > 0 && trailingSeparator) path += '/';
if (isAbsolute) return '/' + path;
return path;
},
isAbsolute: function isAbsolute(path) {
assertPath(path);
return path.length > 0 && path.charCodeAt(0) === 47 /*/*/ ;
},
join: function join() {
if (arguments.length === 0) return '.';
var joined;
for(var i = 0; i < arguments.length; ++i){
var arg = arguments[i];
assertPath(arg);
if (arg.length > 0) {
if (joined === undefined) joined = arg;
else joined += '/' + arg;
}
}
if (joined === undefined) return '.';
return posix.normalize(joined);
},
relative: function relative(from, to) {
assertPath(from);
assertPath(to);
if (from === to) return '';
from = posix.resolve(from);
to = posix.resolve(to);
if (from === to) return '';
// Trim any leading backslashes
var fromStart = 1;
for(; fromStart < from.length; ++fromStart){
if (from.charCodeAt(fromStart) !== 47 /*/*/ ) break;
}
var fromEnd = from.length;
var fromLen = fromEnd - fromStart;
// Trim any leading backslashes
var toStart = 1;
for(; toStart < to.length; ++toStart){
if (to.charCodeAt(toStart) !== 47 /*/*/ ) break;
}
var toEnd = to.length;
var toLen = toEnd - toStart;
// Compare paths to find the longest common path from root
var length = fromLen < toLen ? fromLen : toLen;
var lastCommonSep = -1;
var i = 0;
for(; i <= length; ++i){
if (i === length) {
if (toLen > length) {
if (to.charCodeAt(toStart + i) === 47 /*/*/ ) {
// We get here if `from` is the exact base path for `to`.
// For example: from='/foo/bar'; to='/foo/bar/baz'
return to.slice(toStart + i + 1);
} else if (i === 0) {
// We get here if `from` is the root
// For example: from='/'; to='/foo'
return to.slice(toStart + i);
}
} else if (fromLen > length) {
if (from.charCodeAt(fromStart + i) === 47 /*/*/ ) {
// We get here if `to` is the exact base path for `from`.
// For example: from='/foo/bar/baz'; to='/foo/bar'
lastCommonSep = i;
} else if (i === 0) {
// We get here if `to` is the root.
// For example: from='/foo'; to='/'
lastCommonSep = 0;
}
}
break;
}
var fromCode = from.charCodeAt(fromStart + i);
var toCode = to.charCodeAt(toStart + i);
if (fromCode !== toCode) break;
else if (fromCode === 47 /*/*/ ) lastCommonSep = i;
}
var out = '';
// Generate the relative path based on the path difference between `to`
// and `from`
for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){
if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/ ) {
if (out.length === 0) out += '..';
else out += '/..';
}
}
// Lastly, append the rest of the destination (`to`) path that comes after
// the common path parts
if (out.length > 0) return out + to.slice(toStart + lastCommonSep);
else {
toStart += lastCommonSep;
if (to.charCodeAt(toStart) === 47 /*/*/ ) ++toStart;
return to.slice(toStart);
}
},
_makeLong: function _makeLong(path) {
return path;
},
dirname: function dirname(path) {
assertPath(path);
if (path.length === 0) return '.';
var code = path.charCodeAt(0);
var hasRoot = code === 47 /*/*/ ;
var end = -1;
var matchedSlash = true;
for(var i = path.length - 1; i >= 1; --i){
code = path.charCodeAt(i);
if (code === 47 /*/*/ ) {
if (!matchedSlash) {
end = i;
break;
}
} else {
// We saw the first non-path separator
matchedSlash = false;
}
}
if (end === -1) return hasRoot ? '/' : '.';
if (hasRoot && end === 1) return '//';
return path.slice(0, end);
},
basename: function basename(path, ext) {
if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
assertPath(path);
var start = 0;
var end = -1;
var matchedSlash = true;
var i;
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
if (ext.length === path.length && ext === path) return '';
var extIdx = ext.length - 1;
var firstNonSlashEnd = -1;
for(i = path.length - 1; i >= 0; --i){
var code = path.charCodeAt(i);
if (code === 47 /*/*/ ) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
start = i + 1;
break;
}
} else {
if (firstNonSlashEnd === -1) {
// We saw the first non-path separator, remember this index in case
// we need it if the extension ends up not matching
matchedSlash = false;
firstNonSlashEnd = i + 1;
}
if (extIdx >= 0) {
// Try to match the explicit extension
if (code === ext.charCodeAt(extIdx)) {
if (--extIdx === -1) {
// We matched the extension, so mark this as the end of our path
// component
end = i;
}
} else {
// Extension does not match, so our result is the entire path
// component
extIdx = -1;
end = firstNonSlashEnd;
}
}
}
}
if (start === end) end = firstNonSlashEnd;
else if (end === -1) end = path.length;
return path.slice(start, end);
} else {
for(i = path.length - 1; i >= 0; --i){
if (path.charCodeAt(i) === 47 /*/*/ ) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
start = i + 1;
break;
}
} else if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// path component
matchedSlash = false;
end = i + 1;
}
}
if (end === -1) return '';
return path.slice(start, end);
}
},
extname: function extname(path) {
assertPath(path);
var startDot = -1;
var startPart = 0;
var end = -1;
var matchedSlash = true;
// Track the state of characters (if any) we see before our first dot and
// after any path separator we find
var preDotState = 0;
for(var i = path.length - 1; i >= 0; --i){
var code = path.charCodeAt(i);
if (code === 47 /*/*/ ) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
startPart = i + 1;
break;
}
continue;
}
if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// extension
matchedSlash = false;
end = i + 1;
}
if (code === 46 /*.*/ ) {
// If this is our first dot, mark it as the start of our extension
if (startDot === -1) startDot = i;
else if (preDotState !== 1) preDotState = 1;
} else if (startDot !== -1) {
// We saw a non-dot and non-path separator before our dot, so we should
// have a good chance at having a non-empty extension
preDotState = -1;
}
}
if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot
preDotState === 0 || // The (right-most) trimmed path component is exactly '..'
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
return '';
}
return path.slice(startDot, end);
},
format: function format(pathObject) {
if (pathObject === null || typeof pathObject !== 'object') {
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
}
return _format('/', pathObject);
},
parse: function parse(path) {
assertPath(path);
var ret = {
root: '',
dir: '',
base: '',
ext: '',
name: ''
};
if (path.length === 0) return ret;
var code = path.charCodeAt(0);
var isAbsolute = code === 47 /*/*/ ;
var start;
if (isAbsolute) {
ret.root = '/';
start = 1;
} else {
start = 0;
}
var startDot = -1;
var startPart = 0;
var end = -1;
var matchedSlash = true;
var i = path.length - 1;
// Track the state of characters (if any) we see before our first dot and
// after any path separator we find
var preDotState = 0;
// Get non-dir info
for(; i >= start; --i){
code = path.charCodeAt(i);
if (code === 47 /*/*/ ) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
startPart = i + 1;
break;
}
continue;
}
if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// extension
matchedSlash = false;
end = i + 1;
}
if (code === 46 /*.*/ ) {
// If this is our first dot, mark it as the start of our extension
if (startDot === -1) startDot = i;
else if (preDotState !== 1) preDotState = 1;
} else if (startDot !== -1) {
// We saw a non-dot and non-path separator before our dot, so we should
// have a good chance at having a non-empty extension
preDotState = -1;
}
}
if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot
preDotState === 0 || // The (right-most) trimmed path component is exactly '..'
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
if (end !== -1) {
if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);
else ret.base = ret.name = path.slice(startPart, end);
}
} else {
if (startPart === 0 && isAbsolute) {
ret.name = path.slice(1, startDot);
ret.base = path.slice(1, end);
} else {
ret.name = path.slice(startPart, startDot);
ret.base = path.slice(startPart, end);
}
ret.ext = path.slice(startDot, end);
}
if (startPart > 0) ret.dir = path.slice(0, startPart - 1);
else if (isAbsolute) ret.dir = '/';
return ret;
},
sep: '/',
delimiter: ':',
win32: null,
posix: null
};
posix.posix = posix;
module.exports = posix;
/***/ }),
/***/ "./node_modules/rusha/dist/rusha.js":
/***/ (function(module) {
(function webpackUniversalModuleDefinition(root, factory) {
if (true) module.exports = factory();
else {}
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ function(modules) {
/******/ // The module cache
/******/ var installedModules = {};
/******/ /******/ // The require function
/******/ function __nested_webpack_require_588__(moduleId) {
/******/ /******/ // Check if module is in cache
/******/ if (installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module1 = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
};
/******/ /******/ // Execute the module function
/******/ modules[moduleId].call(module1.exports, module1, module1.exports, __nested_webpack_require_588__);
/******/ /******/ // Flag the module as loaded
/******/ module1.l = true;
/******/ /******/ // Return the exports of the module
/******/ return module1.exports;
/******/ }
/******/ /******/ /******/ // expose the modules object (__webpack_modules__)
/******/ __nested_webpack_require_588__.m = modules;
/******/ /******/ // expose the module cache
/******/ __nested_webpack_require_588__.c = installedModules;
/******/ /******/ // define getter function for harmony exports
/******/ __nested_webpack_require_588__.d = function(exports1, name, getter) {
/******/ if (!__nested_webpack_require_588__.o(exports1, name)) {
/******/ Object.defineProperty(exports1, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
});
/******/ }
/******/ };
/******/ /******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __nested_webpack_require_588__.n = function(module1) {
/******/ var getter = module1 && module1.__esModule ? /******/ function getDefault() {
return module1['default'];
} : /******/ function getModuleExports() {
return module1;
};
/******/ __nested_webpack_require_588__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/ /******/ // Object.prototype.hasOwnProperty.call
/******/ __nested_webpack_require_588__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
/******/ /******/ // __webpack_public_path__
/******/ __nested_webpack_require_588__.p = "";
/******/ /******/ // Load entry module and return exports
/******/ return __nested_webpack_require_588__(__nested_webpack_require_588__.s = 3);
/******/ }([
/* 0 */ /***/ function(module1, exports1, __nested_webpack_require_3275__) {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
/* eslint-env commonjs, browser */ var RushaCore = __nested_webpack_require_3275__(5);
var _require = __nested_webpack_require_3275__(1), toHex = _require.toHex, ceilHeapSize = _require.ceilHeapSize;
var conv = __nested_webpack_require_3275__(6);
// Calculate the length of buffer that the sha1 routine uses
// including the padding.
var padlen = function(len) {
for(len += 9; len % 64 > 0; len += 1){}
return len;
};
var padZeroes = function(bin, len) {
var h8 = new Uint8Array(bin.buffer);
var om = len % 4, align = len - om;
switch(om){
case 0:
h8[align + 3] = 0;
case 1:
h8[align + 2] = 0;
case 2:
h8[align + 1] = 0;
case 3:
h8[align + 0] = 0;
}
for(var i = (len >> 2) + 1; i < bin.length; i++){
bin[i] = 0;
}
};
var padData = function(bin, chunkLen, msgLen) {
bin[chunkLen >> 2] |= 0x80 << 24 - (chunkLen % 4 << 3);
// To support msgLen >= 2 GiB, use a float division when computing the
// high 32-bits of the big-endian message length in bits.
bin[((chunkLen >> 2) + 2 & ~0x0f) + 14] = msgLen / (1 << 29) | 0;
bin[((chunkLen >> 2) + 2 & ~0x0f) + 15] = msgLen << 3;
};
var getRawDigest = function(heap, padMaxChunkLen) {
var io = new Int32Array(heap, padMaxChunkLen + 320, 5);
var out = new Int32Array(5);
var arr = new DataView(out.buffer);
arr.setInt32(0, io[0], false);
arr.setInt32(4, io[1], false);
arr.setInt32(8, io[2], false);
arr.setInt32(12, io[3], false);
arr.setInt32(16, io[4], false);
return out;
};
var Rusha = function() {
function Rusha(chunkSize) {
_classCallCheck(this, Rusha);
chunkSize = chunkSize || 64 * 1024;
if (chunkSize % 64 > 0) {
throw new Error('Chunk size must be a multiple of 128 bit');
}
this._offset = 0;
this._maxChunkLen = chunkSize;
this._padMaxChunkLen = padlen(chunkSize);
// The size of the heap is the sum of:
// 1. The padded input message size
// 2. The extended space the algorithm needs (320 byte)
// 3. The 160 bit state the algoritm uses
this._heap = new ArrayBuffer(ceilHeapSize(this._padMaxChunkLen + 320 + 20));
this._h32 = new Int32Array(this._heap);
this._h8 = new Int8Array(this._heap);
this._core = new RushaCore({
Int32Array: Int32Array
}, {}, this._heap);
}
Rusha.prototype._initState = function _initState(heap, padMsgLen) {
this._offset = 0;
var io = new Int32Array(heap, padMsgLen + 320, 5);
io[0] = 1732584193;
io[1] = -271733879;
io[2] = -1732584194;
io[3] = 271733878;
io[4] = -1009589776;
};
Rusha.prototype._padChunk = function _padChunk(chunkLen, msgLen) {
var padChunkLen = padlen(chunkLen);
var view = new Int32Array(this._heap, 0, padChunkLen >> 2);
padZeroes(view, chunkLen);
padData(view, chunkLen, msgLen);
return padChunkLen;
};
Rusha.prototype._write = function _write(data, chunkOffset, chunkLen, off) {
conv(data, this._h8, this._h32, chunkOffset, chunkLen, off || 0);
};
Rusha.prototype._coreCall = function _coreCall(data, chunkOffset, chunkLen, msgLen, finalize) {
var padChunkLen = chunkLen;
this._write(data, chunkOffset, chunkLen);
if (finalize) {
padChunkLen = this._padChunk(chunkLen, msgLen);
}
this._core.hash(padChunkLen, this._padMaxChunkLen);
};
Rusha.prototype.rawDigest = function rawDigest(str) {
var msgLen = str.byteLength || str.length || str.size || 0;
this._initState(this._heap, this._padMaxChunkLen);
var chunkOffset = 0, chunkLen = this._maxChunkLen;
for(chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen){
this._coreCall(str, chunkOffset, chunkLen, msgLen, false);
}
this._coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true);
return getRawDigest(this._heap, this._padMaxChunkLen);
};
Rusha.prototype.digest = function digest(str) {
return toHex(this.rawDigest(str).buffer);
};
Rusha.prototype.digestFromString = function digestFromString(str) {
return this.digest(str);
};
Rusha.prototype.digestFromBuffer = function digestFromBuffer(str) {
return this.digest(str);
};
Rusha.prototype.digestFromArrayBuffer = function digestFromArrayBuffer(str) {
return this.digest(str);
};
Rusha.prototype.resetState = function resetState() {
this._initState(this._heap, this._padMaxChunkLen);
return this;
};
Rusha.prototype.append = function append(chunk) {
var chunkOffset = 0;
var chunkLen = chunk.byteLength || chunk.length || chunk.size || 0;
var turnOffset = this._offset % this._maxChunkLen;
var inputLen = void 0;
this._offset += chunkLen;
while(chunkOffset < chunkLen){
inputLen = Math.min(chunkLen - chunkOffset, this._maxChunkLen - turnOffset);
this._write(chunk, chunkOffset, inputLen, turnOffset);
turnOffset += inputLen;
chunkOffset += inputLen;
if (turnOffset === this._maxChunkLen) {
this._core.hash(this._maxChunkLen, this._padMaxChunkLen);
turnOffset = 0;
}
}
return this;
};
Rusha.prototype.getState = function getState() {
var turnOffset = this._offset % this._maxChunkLen;
var heap = void 0;
if (!turnOffset) {
var io = new Int32Array(this._heap, this._padMaxChunkLen + 320, 5);
heap = io.buffer.slice(io.byteOffset, io.byteOffset + io.byteLength);
} else {
heap = this._heap.slice(0);
}
return {
offset: this._offset,
heap: heap
};
};
Rusha.prototype.setState = function setState(state) {
this._offset = state.offset;
if (state.heap.byteLength === 20) {
var io = new Int32Array(this._heap, this._padMaxChunkLen + 320, 5);
io.set(new Int32Array(state.heap));
} else {
this._h32.set(new Int32Array(state.heap));
}
return this;
};
Rusha.prototype.rawEnd = function rawEnd() {
var msgLen = this._offset;
var chunkLen = msgLen % this._maxChunkLen;
var padChunkLen = this._padChunk(chunkLen, msgLen);
this._core.hash(padChunkLen, this._padMaxChunkLen);
var result = getRawDigest(this._heap, this._padMaxChunkLen);
this._initState(this._heap, this._padMaxChunkLen);
return result;
};
Rusha.prototype.end = function end() {
return toHex(this.rawEnd().buffer);
};
return Rusha;
}();
module1.exports = Rusha;
module1.exports._core = RushaCore;
/***/ },
/* 1 */ /***/ function(module1, exports1) {
/* eslint-env commonjs, browser */ //
// toHex
//
var precomputedHex = new Array(256);
for(var i = 0; i < 256; i++){
precomputedHex[i] = (i < 0x10 ? '0' : '') + i.toString(16);
}
module1.exports.toHex = function(arrayBuffer) {
var binarray = new Uint8Array(arrayBuffer);
var res = new Array(arrayBuffer.byteLength);
for(var _i = 0; _i < res.length; _i++){
res[_i] = precomputedHex[binarray[_i]];
}
return res.join('');
};
//
// ceilHeapSize
//
module1.exports.ceilHeapSize = function(v) {
// The asm.js spec says:
// The heap object's byteLength must be either
// 2^n for n in [12, 24) or 2^24 * n for n ≥ 1.
// Also, byteLengths smaller than 2^16 are deprecated.
var p = 0;
// If v is smaller than 2^16, the smallest possible solution
// is 2^16.
if (v <= 65536) return 65536;
// If v < 2^24, we round up to 2^n,
// otherwise we round up to 2^24 * n.
if (v < 16777216) {
for(p = 1; p < v; p = p << 1){}
} else {
for(p = 16777216; p < v; p += 16777216){}
}
return p;
};
//
// isDedicatedWorkerScope
//
module1.exports.isDedicatedWorkerScope = function(self1) {
var isRunningInWorker = 'WorkerGlobalScope' in self1 && self1 instanceof self1.WorkerGlobalScope;
var isRunningInSharedWorker = 'SharedWorkerGlobalScope' in self1 && self1 instanceof self1.SharedWorkerGlobalScope;
var isRunningInServiceWorker = 'ServiceWorkerGlobalScope' in self1 && self1 instanceof self1.ServiceWorkerGlobalScope;
// Detects whether we run inside a dedicated worker or not.
//
// We can't just check for `DedicatedWorkerGlobalScope`, since IE11
// has a bug where it only supports `WorkerGlobalScope`.
//
// Therefore, we consider us as running inside a dedicated worker
// when we are running inside a worker, but not in a shared or service worker.
//
// When new types of workers are introduced, we will need to adjust this code.
return isRunningInWorker && !isRunningInSharedWorker && !isRunningInServiceWorker;
};
/***/ },
/* 2 */ /***/ function(module1, exports1, __nested_webpack_require_15381__) {
/* eslint-env commonjs, worker */ module1.exports = function() {
var Rusha = __nested_webpack_require_15381__(0);
var hashData = function(hasher, data, cb) {
try {
return cb(null, hasher.digest(data));
} catch (e) {
return cb(e);
}
};
var hashFile = function(hasher, readTotal, blockSize, file, cb) {
var reader = new self.FileReader();
reader.onloadend = function onloadend() {
if (reader.error) {
return cb(reader.error);
}
var buffer = reader.result;
readTotal += reader.result.byteLength;
try {
hasher.append(buffer);
} catch (e) {
cb(e);
return;
}
if (readTotal < file.size) {
hashFile(hasher, readTotal, blockSize, file, cb);
} else {
cb(null, hasher.end());
}
};
reader.readAsArrayBuffer(file.slice(readTotal, readTotal + blockSize));
};
var workerBehaviourEnabled = true;
self.onmessage = function(event) {
if (!workerBehaviourEnabled) {
return;
}
var data = event.data.data, file = event.data.file, id = event.data.id;
if (typeof id === 'undefined') return;
if (!file && !data) return;
var blockSize = event.data.blockSize || 4 * 1024 * 1024;
var hasher = new Rusha(blockSize);
hasher.resetState();
var done = function(err, hash) {
if (!err) {
self.postMessage({
id: id,
hash: hash
});
} else {
self.postMessage({
id: id,
error: err.name
});
}
};
if (data) hashData(hasher, data, done);
if (file) hashFile(hasher, 0, blockSize, file, done);
};
return function() {
workerBehaviourEnabled = false;
};
};
/***/ },
/* 3 */ /***/ function(module1, exports1, __nested_webpack_require_18245__) {
/* eslint-env commonjs, browser */ var work = __nested_webpack_require_18245__(4);
var Rusha = __nested_webpack_require_18245__(0);
var createHash = __nested_webpack_require_18245__(7);
var runWorker = __nested_webpack_require_18245__(2);
var _require = __nested_webpack_require_18245__(1), isDedicatedWorkerScope = _require.isDedicatedWorkerScope;
var isRunningInDedicatedWorker = typeof self !== 'undefined' && isDedicatedWorkerScope(self);
Rusha.disableWorkerBehaviour = isRunningInDedicatedWorker ? runWorker() : function() {};
Rusha.createWorker = function() {
var worker = work(/*require.resolve*/ (2));
var terminate = worker.terminate;
worker.terminate = function() {
URL.revokeObjectURL(worker.objectURL);
terminate.call(worker);
};
return worker;
};
Rusha.createHash = createHash;
module1.exports = Rusha;
/***/ },
/* 4 */ /***/ function(module1, exports1, __nested_webpack_require_19338__) {
function webpackBootstrapFunc(modules) {
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __nested_webpack_require_19585__(moduleId) {
/******/ // Check if module is in cache
/******/ if (installedModules[moduleId]) /******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module1 = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
};
/******/ // Execute the module function
/******/ modules[moduleId].call(module1.exports, module1, module1.exports, __nested_webpack_require_19585__);
/******/ // Flag the module as loaded
/******/ module1.l = true;
/******/ // Return the exports of the module
/******/ return module1.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __nested_webpack_require_19585__.m = modules;
/******/ // expose the module cache
/******/ __nested_webpack_require_19585__.c = installedModules;
/******/ // identity function for calling harmony imports with the correct context
/******/ __nested_webpack_require_19585__.i = function(value) {
return value;
};
/******/ // define getter function for harmony exports
/******/ __nested_webpack_require_19585__.d = function(exports1, name, getter) {
/******/ if (!__nested_webpack_require_19585__.o(exports1, name)) {
/******/ Object.defineProperty(exports1, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
});
/******/ }
/******/ };
/******/ // define __esModule on exports
/******/ __nested_webpack_require_19585__.r = function(exports1) {
/******/ Object.defineProperty(exports1, '__esModule', {
value: true
});
/******/ };
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __nested_webpack_require_19585__.n = function(module1) {
/******/ var getter = module1 && module1.__esModule ? /******/ function getDefault() {
return module1['default'];
} : /******/ function getModuleExports() {
return module1;
};
/******/ __nested_webpack_require_19585__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/ // Object.prototype.hasOwnProperty.call
/******/ __nested_webpack_require_19585__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
/******/ // __webpack_public_path__
/******/ __nested_webpack_require_19585__.p = "/";
/******/ // on error function for async loading
/******/ __nested_webpack_require_19585__.oe = function(err) {
console.error(err);
throw err;
};
var f = __nested_webpack_require_19585__(__nested_webpack_require_19585__.s = ENTRY_MODULE);
return f.default || f // try to call default if defined to also support babel esmodule exports
;
}
var moduleNameReqExp = '[\\.|\\-|\\+|\\w|\/|@]+';
var dependencyRegExp = '\\((\/\\*.*?\\*\/)?\s?.*?(' + moduleNameReqExp + ').*?\\)' // additional chars when output.pathinfo is true
;
// http://stackoverflow.com/a/2593661/130442
function quoteRegExp(str) {
return (str + '').replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
}
function getModuleDependencies(sources, module1, queueName) {
var retval = {};
retval[queueName] = [];
var fnString = module1.toString();
var wrapperSignature = fnString.match(/^function\s?\(\w+,\s*\w+,\s*(\w+)\)/);
if (!wrapperSignature) return retval;
var webpackRequireName = wrapperSignature[1];
// main bundle deps
var re = new RegExp('(\\\\n|\\W)' + quoteRegExp(webpackRequireName) + dependencyRegExp, 'g');
var match;
while(match = re.exec(fnString)){
if (match[3] === 'dll-reference') continue;
retval[queueName].push(match[3]);
}
// dll deps
re = new RegExp('\\(' + quoteRegExp(webpackRequireName) + '\\("(dll-reference\\s(' + moduleNameReqExp + '))"\\)\\)' + dependencyRegExp, 'g');
while(match = re.exec(fnString)){
if (!sources[match[2]]) {
retval[queueName].push(match[1]);
sources[match[2]] = __nested_webpack_require_19338__(match[1]).m;
}
retval[match[2]] = retval[match[2]] || [];
retval[match[2]].push(match[4]);
}
return retval;
}
function hasValuesInQueues(queues) {
var keys = Object.keys(queues);
return keys.reduce(function(hasValues, key) {
return hasValues || queues[key].length > 0;
}, false);
}
function getRequiredModules(sources, moduleId) {
var modulesQueue = {
main: [
moduleId
]
};
var requiredModules = {
main: []
};
var seenModules = {
main: {}
};
while(hasValuesInQueues(modulesQueue)){
var queues = Object.keys(modulesQueue);
for(var i = 0; i < queues.length; i++){
var queueName = queues[i];
var queue = modulesQueue[queueName];
var moduleToCheck = queue.pop();
seenModules[queueName] = seenModules[queueName] || {};
if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue;
seenModules[queueName][moduleToCheck] = true;
requiredModules[queueName] = requiredModules[queueName] || [];
requiredModules[queueName].push(moduleToCheck);
var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName);
var newModulesKeys = Object.keys(newModules);
for(var j = 0; j < newModulesKeys.length; j++){
modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || [];
modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]);
}
}
}
return requiredModules;
}
module1.exports = function(moduleId, options) {
options = options || {};
var sources = {
main: __nested_webpack_require_19338__.m
};
var requiredModules = options.all ? {
main: Object.keys(sources)
} : getRequiredModules(sources, moduleId);
var src = '';
Object.keys(requiredModules).filter(function(m) {
return m !== 'main';
}).forEach(function(module1) {
var entryModule = 0;
while(requiredModules[module1][entryModule]){
entryModule++;
}
requiredModules[module1].push(entryModule);
sources[module1][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })';
src = src + 'var ' + module1 + ' = (' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(entryModule)) + ')({' + requiredModules[module1].map(function(id) {
return '' + JSON.stringify(id) + ': ' + sources[module1][id].toString();
}).join(',') + '});\n';
});
src = src + '(' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(moduleId)) + ')({' + requiredModules.main.map(function(id) {
return '' + JSON.stringify(id) + ': ' + sources.main[id].toString();
}).join(',') + '})(self);';
var blob = new window.Blob([
src
], {
type: 'text/javascript'
});
if (options.bare) {
return blob;
}
var URL1 = window.URL || window.webkitURL || window.mozURL || window.msURL;
var workerUrl = URL1.createObjectURL(blob);
var worker = new window.Worker(workerUrl);
worker.objectURL = workerUrl;
return worker;
};
/***/ },
/* 5 */ /***/ function(module1, exports1) {
// The low-level RushCore module provides the heart of Rusha,
// a high-speed sha1 implementation working on an Int32Array heap.
// At first glance, the implementation seems complicated, however
// with the SHA1 spec at hand, it is obvious this almost a textbook
// implementation that has a few functions hand-inlined and a few loops
// hand-unrolled.
module1.exports = function RushaCore(stdlib$840, foreign$841, heap$842) {
'use asm';
var H$843 = new stdlib$840.Int32Array(heap$842);
function hash$844(k$845, x$846) {
// k in bytes
k$845 = k$845 | 0;
x$846 = x$846 | 0;
var i$847 = 0, j$848 = 0, y0$849 = 0, z0$850 = 0, y1$851 = 0, z1$852 = 0, y2$853 = 0, z2$854 = 0, y3$855 = 0, z3$856 = 0, y4$857 = 0, z4$858 = 0, t0$859 = 0, t1$860 = 0;
y0$849 = H$843[x$846 + 320 >> 2] | 0;
y1$851 = H$843[x$846 + 324 >> 2] | 0;
y2$853 = H$843[x$846 + 328 >> 2] | 0;
y3$855 = H$843[x$846 + 332 >> 2] | 0;
y4$857 = H$843[x$846 + 336 >> 2] | 0;
for(i$847 = 0; (i$847 | 0) < (k$845 | 0); i$847 = i$847 + 64 | 0){
z0$850 = y0$849;
z1$852 = y1$851;
z2$854 = y2$853;
z3$856 = y3$855;
z4$858 = y4$857;
for(j$848 = 0; (j$848 | 0) < 64; j$848 = j$848 + 4 | 0){
t1$860 = H$843[i$847 + j$848 >> 2] | 0;
t0$859 = ((y0$849 << 5 | y0$849 >>> 27) + (y1$851 & y2$853 | ~y1$851 & y3$855) | 0) + ((t1$860 + y4$857 | 0) + 1518500249 | 0) | 0;
y4$857 = y3$855;
y3$855 = y2$853;
y2$853 = y1$851 << 30 | y1$851 >>> 2;
y1$851 = y0$849;
y0$849 = t0$859;
H$843[k$845 + j$848 >> 2] = t1$860;
}
for(j$848 = k$845 + 64 | 0; (j$848 | 0) < (k$845 + 80 | 0); j$848 = j$848 + 4 | 0){
t1$860 = (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) << 1 | (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) >>> 31;
t0$859 = ((y0$849 << 5 | y0$849 >>> 27) + (y1$851 & y2$853 | ~y1$851 & y3$855) | 0) + ((t1$860 + y4$857 | 0) + 1518500249 | 0) | 0;
y4$857 = y3$855;
y3$855 = y2$853;
y2$853 = y1$851 << 30 | y1$851 >>> 2;
y1$851 = y0$849;
y0$849 = t0$859;
H$843[j$848 >> 2] = t1$860;
}
for(j$848 = k$845 + 80 | 0; (j$848 | 0) < (k$845 + 160 | 0); j$848 = j$848 + 4 | 0){
t1$860 = (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) << 1 | (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) >>> 31;
t0$859 = ((y0$849 << 5 | y0$849 >>> 27) + (y1$851 ^ y2$853 ^ y3$855) | 0) + ((t1$860 + y4$857 | 0) + 1859775393 | 0) | 0;
y4$857 = y3$855;
y3$855 = y2$853;
y2$853 = y1$851 << 30 | y1$851 >>> 2;
y1$851 = y0$849;
y0$849 = t0$859;
H$843[j$848 >> 2] = t1$860;
}
for(j$848 = k$845 + 160 | 0; (j$848 | 0) < (k$845 + 240 | 0); j$848 = j$848 + 4 | 0){
t1$860 = (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) << 1 | (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) >>> 31;
t0$859 = ((y0$849 << 5 | y0$849 >>> 27) + (y1$851 & y2$853 | y1$851 & y3$855 | y2$853 & y3$855) | 0) + ((t1$860 + y4$857 | 0) - 1894007588 | 0) | 0;
y4$857 = y3$855;
y3$855 = y2$853;
y2$853 = y1$851 << 30 | y1$851 >>> 2;
y1$851 = y0$849;
y0$849 = t0$859;
H$843[j$848 >> 2] = t1$860;
}
for(j$848 = k$845 + 240 | 0; (j$848 | 0) < (k$845 + 320 | 0); j$848 = j$848 + 4 | 0){
t1$860 = (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) << 1 | (H$843[j$848 - 12 >> 2] ^ H$843[j$848 - 32 >> 2] ^ H$843[j$848 - 56 >> 2] ^ H$843[j$848 - 64 >> 2]) >>> 31;
t0$859 = ((y0$849 << 5 | y0$849 >>> 27) + (y1$851 ^ y2$853 ^ y3$855) | 0) + ((t1$860 + y4$857 | 0) - 899497514 | 0) | 0;
y4$857 = y3$855;
y3$855 = y2$853;
y2$853 = y1$851 << 30 | y1$851 >>> 2;
y1$851 = y0$849;
y0$849 = t0$859;
H$843[j$848 >> 2] = t1$860;
}
y0$849 = y0$849 + z0$850 | 0;
y1$851 = y1$851 + z1$852 | 0;
y2$853 = y2$853 + z2$854 | 0;
y3$855 = y3$855 + z3$856 | 0;
y4$857 = y4$857 + z4$858 | 0;
}
H$843[x$846 + 320 >> 2] = y0$849;
H$843[x$846 + 324 >> 2] = y1$851;
H$843[x$846 + 328 >> 2] = y2$853;
H$843[x$846 + 332 >> 2] = y3$855;
H$843[x$846 + 336 >> 2] = y4$857;
}
return {
hash: hash$844
};
};
/***/ },
/* 6 */ /***/ function(module1, exports1) {
var _this = this;
/* eslint-env commonjs, browser */ var reader = void 0;
if (typeof self !== 'undefined' && typeof self.FileReaderSync !== 'undefined') {
reader = new self.FileReaderSync();
}
// Convert a binary string and write it to the heap.
// A binary string is expected to only contain char codes < 256.
var convStr = function(str, H8, H32, start, len, off) {
var i = void 0, om = off % 4, lm = (len + om) % 4, j = len - lm;
switch(om){
case 0:
H8[off] = str.charCodeAt(start + 3);
case 1:
H8[off + 1 - (om << 1) | 0] = str.charCodeAt(start + 2);
case 2:
H8[off + 2 - (om << 1) | 0] = str.charCodeAt(start + 1);
case 3:
H8[off + 3 - (om << 1) | 0] = str.charCodeAt(start);
}
if (len < lm + (4 - om)) {
return;
}
for(i = 4 - om; i < j; i = i + 4 | 0){
H32[off + i >> 2] = str.charCodeAt(start + i) << 24 | str.charCodeAt(start + i + 1) << 16 | str.charCodeAt(start + i + 2) << 8 | str.charCodeAt(start + i + 3);
}
switch(lm){
case 3:
H8[off + j + 1 | 0] = str.charCodeAt(start + j + 2);
case 2:
H8[off + j + 2 | 0] = str.charCodeAt(start + j + 1);
case 1:
H8[off + j + 3 | 0] = str.charCodeAt(start + j);
}
};
// Convert a buffer or array and write it to the heap.
// The buffer or array is expected to only contain elements < 256.
var convBuf = function(buf, H8, H32, start, len, off) {
var i = void 0, om = off % 4, lm = (len + om) % 4, j = len - lm;
switch(om){
case 0:
H8[off] = buf[start + 3];
case 1:
H8[off + 1 - (om << 1) | 0] = buf[start + 2];
case 2:
H8[off + 2 - (om << 1) | 0] = buf[start + 1];
case 3:
H8[off + 3 - (om << 1) | 0] = buf[start];
}
if (len < lm + (4 - om)) {
return;
}
for(i = 4 - om; i < j; i = i + 4 | 0){
H32[off + i >> 2 | 0] = buf[start + i] << 24 | buf[start + i + 1] << 16 | buf[start + i + 2] << 8 | buf[start + i + 3];
}
switch(lm){
case 3:
H8[off + j + 1 | 0] = buf[start + j + 2];
case 2:
H8[off + j + 2 | 0] = buf[start + j + 1];
case 1:
H8[off + j + 3 | 0] = buf[start + j];
}
};
var convBlob = function(blob, H8, H32, start, len, off) {
var i = void 0, om = off % 4, lm = (len + om) % 4, j = len - lm;
var buf = new Uint8Array(reader.readAsArrayBuffer(blob.slice(start, start + len)));
switch(om){
case 0:
H8[off] = buf[3];
case 1:
H8[off + 1 - (om << 1) | 0] = buf[2];
case 2:
H8[off + 2 - (om << 1) | 0] = buf[1];
case 3:
H8[off + 3 - (om << 1) | 0] = buf[0];
}
if (len < lm + (4 - om)) {
return;
}
for(i = 4 - om; i < j; i = i + 4 | 0){
H32[off + i >> 2 | 0] = buf[i] << 24 | buf[i + 1] << 16 | buf[i + 2] << 8 | buf[i + 3];
}
switch(lm){
case 3:
H8[off + j + 1 | 0] = buf[j + 2];
case 2:
H8[off + j + 2 | 0] = buf[j + 1];
case 1:
H8[off + j + 3 | 0] = buf[j];
}
};
module1.exports = function(data, H8, H32, start, len, off) {
if (typeof data === 'string') {
return convStr(data, H8, H32, start, len, off);
}
if (data instanceof Array) {
return convBuf(data, H8, H32, start, len, off);
}
// Safely doing a Buffer check using "this" to avoid Buffer polyfill to be included in the dist
if (_this && _this.Buffer && _this.Buffer.isBuffer(data)) {
return convBuf(data, H8, H32, start, len, off);
}
if (data instanceof ArrayBuffer) {
return convBuf(new Uint8Array(data), H8, H32, start, len, off);
}
if (data.buffer instanceof ArrayBuffer) {
return convBuf(new Uint8Array(data.buffer, data.byteOffset, data.byteLength), H8, H32, start, len, off);
}
if (data instanceof Blob) {
return convBlob(data, H8, H32, start, len, off);
}
throw new Error('Unsupported data type.');
};
/***/ },
/* 7 */ /***/ function(module1, exports1, __nested_webpack_require_41097__) {
var _createClass = function() {
function defineProperties(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
/* eslint-env commonjs, browser */ var Rusha = __nested_webpack_require_41097__(0);
var _require = __nested_webpack_require_41097__(1), toHex = _require.toHex;
var Hash = function() {
function Hash() {
_classCallCheck(this, Hash);
this._rusha = new Rusha();
this._rusha.resetState();
}
Hash.prototype.update = function update(data) {
this._rusha.append(data);
return this;
};
Hash.prototype.digest = function digest(encoding) {
var digest = this._rusha.rawEnd().buffer;
if (!encoding) {
return digest;
}
if (encoding === 'hex') {
return toHex(digest);
}
throw new Error('unsupported digest encoding');
};
_createClass(Hash, [
{
key: 'state',
get: function() {
return this._rusha.getState();
},
set: function(state) {
this._rusha.setState(state);
}
}
]);
return Hash;
}();
module1.exports = function() {
return new Hash();
};
/***/ }
]);
});
/***/ }),
/***/ "./node_modules/simple-sha1/browser.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* global self */ const Rusha = __webpack_require__("./node_modules/rusha/dist/rusha.js");
const rushaWorkerSha1 = __webpack_require__("./node_modules/simple-sha1/rusha-worker-sha1.js");
const rusha = new Rusha();
const scope = typeof window !== 'undefined' ? window : self;
const crypto = scope.crypto || scope.msCrypto || {};
let subtle = crypto.subtle || crypto.webkitSubtle;
function sha1sync(buf) {
return rusha.digest(buf);
}
// Browsers throw if they lack support for an algorithm.
// Promise will be rejected on non-secure origins. (http://goo.gl/lq4gCo)
try {
subtle.digest({
name: 'sha-1'
}, new Uint8Array()).catch(function() {
subtle = false;
});
} catch (err) {
subtle = false;
}
function sha1(buf, cb) {
if (!subtle) {
if (typeof window !== 'undefined') {
rushaWorkerSha1(buf, function onRushaWorkerSha1(err, hash) {
if (err) {
// On error, fallback to synchronous method which cannot fail
cb(sha1sync(buf));
return;
}
cb(hash);
});
} else {
queueMicrotask(()=>cb(sha1sync(buf)));
}
return;
}
if (typeof buf === 'string') {
buf = uint8array(buf);
}
subtle.digest({
name: 'sha-1'
}, buf).then(function succeed(result) {
cb(hex(new Uint8Array(result)));
}, function fail() {
// On error, fallback to synchronous method which cannot fail
cb(sha1sync(buf));
});
}
function uint8array(s) {
const l = s.length;
const array = new Uint8Array(l);
for(let i = 0; i < l; i++){
array[i] = s.charCodeAt(i);
}
return array;
}
function hex(buf) {
const l = buf.length;
const chars = [];
for(let i = 0; i < l; i++){
const bite = buf[i];
chars.push((bite >>> 4).toString(16));
chars.push((bite & 0x0f).toString(16));
}
return chars.join('');
}
module.exports = sha1;
module.exports.sync = sha1sync;
/***/ }),
/***/ "./node_modules/simple-sha1/rusha-worker-sha1.js":
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const Rusha = __webpack_require__("./node_modules/rusha/dist/rusha.js");
let worker;
let nextTaskId;
let cbs;
function init() {
worker = Rusha.createWorker();
nextTaskId = 1;
cbs = {} // taskId -> cb
;
worker.onmessage = function onRushaMessage(e) {
const taskId = e.data.id;
const cb = cbs[taskId];
delete cbs[taskId];
if (e.data.error != null) {
cb(new Error('Rusha worker error: ' + e.data.error));
} else {
cb(null, e.data.hash);
}
};
}
function sha1(buf, cb) {
if (!worker) init();
cbs[nextTaskId] = cb;
worker.postMessage({
id: nextTaskId,
data: buf
});
nextTaskId += 1;
}
module.exports = sha1;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
;// CONCATENATED MODULE: ./src/inserts/checkForTrumpsButton.ts
function checkForTrumpsButton() {
const existing = $("#check-for-no-intro-trumps-button");
const button = existing.length > 0 ? existing : $(`<input id="check-for-no-intro-trumps-button" type="button" value="Check for No-Intro Trumps" style="background: hotpink; color: black; font-weight: bold; margin-left: 10px;"/>`);
const progress = (text)=>{
button.val(text);
};
const disable = ()=>{
button.prop("disabled", true);
button.css("background-color", "pink");
button.css("color", "darkslategray");
button.css("box-shadow", "none");
};
const insert = ()=>{
button.detach();
$(".torrent_table > tbody > tr:first-child > td:first-child").first().append(button);
};
return {
disable,
progress,
insert,
button
};
}
;// CONCATENATED MODULE: ./src/utils/dom/extractNoIntroLinkFromDescription.ts
// Being strict here to avoid No-Intro IP bans
const NO_INTRO_ROM_LINK_REGEX = /^https?:\/\/datomatic\.no-intro\.org\/(index\.php)?\?page=show_record&s=\d+&n=[a-z]?\d+$/i;
const IN_DESC_NO_INTRO_ROM_LINK_REGEX = /https?:\/\/datomatic\.no-intro\.org\/(index\.php)?\?page=show_record&s=\d+&n=[a-z]?\d+/i;
function extractNoIntroLinkFromDescription(torrentId) {
const links = $(`#torrent_${torrentId} #description a`);
let found = links.map(function() {
return $(this).attr("href");
}).get().find((link)=>NO_INTRO_ROM_LINK_REGEX.test(link));
if (!found) {
// Try to find the link in the description,
// happens when the [url] bbcode tag is not used/botched
const description = $(`#torrent_${torrentId} #description`).text();
const match = description.match(IN_DESC_NO_INTRO_ROM_LINK_REGEX);
found = match ? match[0] : undefined;
}
// Normalize
try {
const url = new URL(found);
url.protocol = "https:"; // Rarely descriptions have the http protocol
url.pathname = "/index.php";
return url.toString();
} catch {
return undefined;
}
}
;// CONCATENATED MODULE: ./src/utils/dom/getNoIntroTorrentsOnPage.ts
function notFalse(x) {
return x !== false;
}
function getNoIntroTorrentsOnPage() {
return $('a[title="Permalink"]').map(function() {
const torrentId = new URLSearchParams($(this).attr("href").replace("torrents.php", "")).get("torrentid");
const noIntroLink = extractNoIntroLinkFromDescription(torrentId);
if (!noIntroLink) {
return false;
}
const reported = $(this).parent().parent().find(".reported_label").text() === "Reported";
return {
torrentId,
a: $(this),
noIntroLink,
reported,
permalink: window.location.origin + "/" + $(this).attr("href"),
platform: $("#groupplatform").text()
};
}).get().filter(notFalse);
}
;// CONCATENATED MODULE: ./src/inserts/insertAddCopyHelpers.ts
function addCopyHref(noIntroLink, edition) {
const groupId = new URLSearchParams(window.location.search).get("id");
const params = new URLSearchParams();
params.set("groupid", groupId);
params.set("no-intro", noIntroLink);
if (edition) {
params.set("edition", edition);
}
return `upload.php?${params.toString()}`;
}
function insertAddCopyHelpers() {
getNoIntroTorrentsOnPage().forEach((param)=>{
let { torrentId , a , noIntroLink } = param;
// Extract edition information
const editionInfo = a.parents(".group_torrent").parent().prev().find(".group_torrent > td > strong").text();
const [editionYear, ...rest] = editionInfo.split(" - ");
const editionName = rest.join(" - ");
const formatedEditionInfo = `${editionName} (${editionYear})`;
const addCopyButton = $(`<a href="${addCopyHref(noIntroLink, formatedEditionInfo)}" title="Add Copy" id="ac_${torrentId}">AC</a>`);
$([
" | ",
addCopyButton
]).insertAfter(a);
});
}
;// CONCATENATED MODULE: ./src/constants.ts
// REGEXES
const PARENS_TAGS_REGEX = /\(.*?\)/g;
const NO_INTRO_TAGS_REGEX = /\((Unl|Proto|Sample|Aftermarket|Homebrew)\)|\(Rev \d+\)|\(v[\d\.]+\)|\(Beta(?: \d+)?\)/;
// Aftermarket? Homebrew?
const NO_INTRO_EDITION_TAGS_REGEX = /\((Proto|Sample)\)||\(Beta(?: \d+)?\)/;
// LISTS
const GGN_REGIONS = [
"USA",
"Europe",
"Japan",
"Asia",
"Australia",
"France",
"Germany",
"Spain",
"Italy",
"UK",
"Netherlands",
"Sweden",
"Russia",
"China",
"Korea",
"Hong Kong",
"Taiwan",
"Brazil",
"Canada",
"Japan, USA",
"Japan, Europe",
"USA, Europe",
"Europe, Australia",
"Japan, Asia",
"UK, Australia",
"World",
"Region-Free",
"Other",
];
// TABLES
const REGION_TO_LANGUAGE = {
World: "English",
USA: "English",
Europe: "English",
Japan: "Japanese",
Australia: "English",
France: "French",
Germany: "German",
Italy: "Italian",
UK: "English",
Netherlands: "Other",
Sweden: "Other",
Russia: "Russian",
China: "Chinese",
Korea: "Korean",
Taiwan: "Chinese",
Spain: "Spanish",
"Hong Kong": "Chinese",
Brazil: "Portuguese",
Canada: "English",
"USA, Europe": "English",
"Europe, Australia": "English",
"UK, Australia": "English",
Other: "Other"
};
const TWO_LETTER_REGION_CODE_TO_NAME = {
en: "English",
de: "German",
fr: "French",
cz: "Czech",
zh: "Chinese",
it: "Italian",
ja: "Japanese",
ko: "Korean",
pl: "Polish",
pt: "Portuguese",
ru: "Russian",
es: "Spanish"
};
const PLATFORM_TO_ARCHIVE_TYPE = {
"Fairchild Channel F": "zip",
"Atari 2600": "zip",
"RCA Studio II": "zip",
"Atari 5200": "zip",
Vectrex: "zip",
"Mattel Intellivision": "zip",
ColecoVision: "zip",
"Emerson Arcadia 2001": "zip",
"Epoch Super Casette Vision": "zip",
"VTech CreatiVision": "zip",
"Casio PV-1000": "zip",
// "Commodore VIC-20 Cartridges & Tapes": "zip",
// "Commodore VIC-20 Floppies": "7z",
DOS: "7z",
// "Commodore 64 Cartridges & Tapes": "zip",
// "Commodore 64 Floppies": "7z",
MSX: "zip",
// "MSX Cartridges": "zip",
// "MSX Floppies": "7z",
// "MSX 2 Cartridges": "zip",
// "MSX 2 Floppies": "7z",
"Sinclair ZX Spectrum": "zip",
Windows: "7z",
// "Commodore 128 Cartridges": "zip",
// "Commodore 128 Floppies": "7z",
// "Commodore Plus/4 Cartridges": "zip",
// "Commodore Plus/4 Floppies": "7z",
// "Commodore Amiga": "7z",
"Amiga CD32": "7z",
"Philips Videopac+": "zip",
NES: "zip",
"SG-1000": "zip",
"Master System": "zip",
"Atari ST": "7z",
"Atari 7800": "zip",
Famicom: "zip",
"NEC TurboGrafx-16": "zip",
"Atari Lynx": "zip",
// "PC Engine SuperGrafx Cards": "zip",
// "PC Engine SuperGrafx CD": "7z",
"Game Boy": "zip",
"Amstrad SPC": "7z",
"Phillips CD-i": "7z",
"Hartung Game Master": "zip",
SNES: "zip",
"Mega Drive": "zip",
"Watara Supervision": "zip",
"Game Gear": "zip",
Pico: "zip",
"3DO": "7z",
"Atari Jaguar": "zip",
Saturn: "7z",
"NEC PC-FX": "7z",
"PlayStation 1": "7z",
"Casio Loopy": "zip",
"Funtech Super ACan": "zip",
"Virtual Boy": "zip",
"Nintendo 64": "zip",
"Apple Bandai Pippin": "7z",
"Game.com": "zip",
"Game Boy Color": "zip",
"SNK Neo Geo Pocket": "zip",
Dreamcast: "7z",
"Bandai Wonderswan Color": "zip",
"PlayStation 2": "7z",
"Nintendo GameCube": "7z",
"Game Boy Advance": "zip",
"GamePark GP32": "zip",
Xbox: "7z",
"Nokia N-Gage": "zip",
"NEC PC-98": "7z",
// "PlayStation 3": "7z/none",
"PlayStation Portable": "7z",
"Nintendo DS": "zip",
"V.Smile": "zip",
Gizmondo: "zip",
"Xbox 360": "7z",
"Nintendo 3DS": "zip",
// Wii: "None (if scrubbed)",
"Wii U": "7z",
Ouya: "zip",
"New Nintendo 3DS": "zip",
Switch: "7z"
};
// Zibzab is the best!!!!
const GGN_PLATFORM_TO_NO_INTRO_PLATFORM_CODE = {
"Apple Bandai Pippin": "276",
"Game Boy": "46",
"Game Boy Advance": "23",
"Game Boy Color": "47",
NES: "45",
"Family Computer Disk System": "31",
"Nintendo 64": "24",
"Nintendo 3DS": "64",
"New Nintendo 3DS": "81",
"Nintendo DS": "28",
"Nintendo GameCube": "261",
SNES: "49",
"Virtual Boy": "15",
"PlayStation Portable": "91",
"PlayStation Vita": "92",
"Game Gear": "25",
"Master System": "26",
"Mega Drive": "32",
Pico: "18",
"SG-1000": "19",
"Atari 2600": "88",
"Atari 5200": "1",
"Atari 7800": "74",
"Atari Jaguar": "2",
"Atari Lynx": "30",
"Atari ST": "68",
"Bandai WonderSwan": "50",
"Bandai WonderSwan Color": "51",
"Commodore 64": "42",
"Commodore Amiga": "40",
"Commodore VIC-20": "34",
"NEC PC-98": "243",
"NEC TurboGrafx-16": "12",
"ZX Spectrum": "73",
MSX: "10",
"MSX 2": "11",
"Game.com": "20",
"V.Smile": "76",
CreatiVision: "21",
"Casio Loopy": "48",
"Casio PV-1000": "59",
Colecovision: "3",
"Emerson Arcadia 2001": "4",
"Entex Adventure Vision": "5",
"Epoch Super Casette Vision": "60",
"Fairchild Channel F": "6",
"Funtech Super Acan": "56",
"GamePark GP32": "58",
"General Computer Vectrex": "7",
"Hartung Game Master": "8",
"Mattel Intellivision": "105",
Ouya: "130",
"Philips Videopac+": "16",
"RCA Studio II": "29",
"SNK Neo Geo Pocket": "35",
"Watara Supervision": "22"
};
;// CONCATENATED MODULE: ./src/utils/GMCache.ts
class GMCache {
getKeyName(key) {
return `cache${this.name}.${key}`;
}
get(key) {
const res = GM_getValue(this.getKeyName(key));
if (res === undefined) {
return undefined;
}
const { value , expires } = res;
if (expires && expires < Date.now()) {
this.delete(key);
return undefined;
}
return value;
}
set(key, value, ttl) {
const expires = Date.now() + ttl;
GM_setValue(this.getKeyName(key), {
value,
expires
});
}
delete(key) {
GM_deleteValue(this.getKeyName(key));
}
cleanUp() {
const keys = GM_listValues();
keys.forEach((key)=>{
if (key.startsWith(this.getKeyName(""))) {
const { expires } = GM_getValue(key);
if (expires < Date.now()) {
GM_deleteValue(key);
}
}
});
}
clear() {
const keys = GM_listValues();
keys.forEach((key)=>{
if (key.startsWith(this.getKeyName(""))) {
GM_deleteValue(key);
}
});
}
constructor(name){
this.name = name;
}
}
;// CONCATENATED MODULE: ./src/utils/identifyNoIntroTags.ts
function identifyNoIntroTags(title) {
const tags = title.match(/\(.+?\)/g).map((p)=>p.slice(1, -1));
let region = "";
let languages = [];
let edition = [];
let release = [];
tags.forEach((tag)=>{
console.log(`tag: ${tag}`);
// Region
if (GGN_REGIONS.includes(tag)) {
console.log("region", tag);
region = tag;
return;
}
// Language
const maybeTwoLetterCodes = tag.split(",").map((l)=>l.trim().toLowerCase());
const isLanguages = maybeTwoLetterCodes.every((l)=>/^[a-z]{2}$/.test(l));
if (isLanguages) {
languages = maybeTwoLetterCodes;
return;
}
// Edition
if ([
"Proto",
"Sample"
].includes(tag) || tag.startsWith("Beta") || tag.startsWith("Demo") || tag.endsWith("Virtual Console") || tag.includes("Edition") || tag.includes("Collection")) {
edition.push(tag);
return;
}
// None of the above
console.log("release tag", tag);
release.push(tag);
});
if (region === "") {
release.shift();
region = "Other";
}
let language;
if (languages.length === 0) {
language = REGION_TO_LANGUAGE[region];
} else if (languages.length === 1) {
language = TWO_LETTER_REGION_CODE_TO_NAME[languages[0]] || "Other";
} else {
language = "Multi-Language";
}
return {
language: language,
region: region,
edition,
release: release.map((t)=>`(${t})`).join(" ")
};
}
;// CONCATENATED MODULE: ./src/utils/fetchNoIntro.ts
const cache = new GMCache("no-intro");
// @ts-expect-error
unsafeWindow.GGN_NO_INTRO_HELPER_CACHE = cache;
function getRelationshipDetails(scraped) {
const findDataByTitle = (title)=>[
...scraped.querySelectorAll("td.TableData")
].filter((d)=>d.innerText.trim() === title)[0];
const nextOverText = (td)=>(td.nextElementSibling.innerText || "").trim();
const splitMerge = findDataByTitle("Split/Merge:");
if (!splitMerge) {
return;
}
// I don't know what other types of splits there are but better safe than sorry
const isParentSplit = nextOverText(splitMerge) === "Parent.";
if (!isParentSplit) {
return;
}
const relationship = findDataByTitle("P/C relationship:");
if (!relationship) {
return;
}
return relationship.nextElementSibling;
}
function determineParentUrl(scraped, scrapedUrl) {
const relationshipDetails = getRelationshipDetails(scraped);
if (!relationshipDetails) {
return;
}
if (relationshipDetails.innerText.trim().startsWith("Parent.")) {
return scrapedUrl;
}
if (relationshipDetails.innerText.trim().startsWith("Clone.")) {
const parentLink = relationshipDetails.querySelector("a");
if (!parentLink) {
return;
}
return "https://datomatic.no-intro.org/" + parentLink.getAttribute("href");
}
}
function getRomChildrenUrls(scraped, url) {
const relationshipDetails = getRelationshipDetails(scraped);
if (!relationshipDetails) {
return [];
}
if (!relationshipDetails.innerText.trim().startsWith("Parent.")) {
return [];
}
return [
...relationshipDetails.querySelectorAll("a")
].map((a)=>"https://datomatic.no-intro.org/" + a.getAttribute("href"));
}
function scrapeNoIntro(url) {
let method = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "GET", data = arguments.length > 2 ? arguments[2] : void 0;
return new Promise((resolve, reject)=>{
GM_xmlhttpRequest({
method,
url,
data,
timeout: 5000,
onload: (param)=>{
let { responseText } = param;
try {
const parser = new DOMParser();
const scraped = parser.parseFromString(responseText, "text/html");
resolve(scraped);
} catch (err) {
reject(err);
}
},
ontimeout: ()=>{
reject(new Error("Request to No-Intro timed out after 5 seconds"));
}
});
});
}
async function getRomInformationFromNoIntro(url) {
const cached = cache.get(url);
if (cached) {
return {
...cached,
cached: true
};
}
const scraped = await scrapeNoIntro(url);
try {
const dumpsTitle = [
...scraped.querySelectorAll("td.TableTitle")
].find((td)=>td.innerText.trim() === "Dump(s)" || td.innerText.trim() === "Scene dump(s)");
if (!dumpsTitle) {
// @ts-expect-error
unsafeWindow.GMPARSER = scraped;
console.error("GGn No-Intro Helper: dumps title not found, set parser as global: GMPARSER");
throw new Error("No dump's title found");
}
// hmmm
const filename = dumpsTitle.parentElement.parentElement.parentElement.nextElementSibling.querySelector("table > tbody > tr:nth-child(2) > td:last-child").innerText.trim();
const extension = filename.split(".").pop() || "";
let title = scraped.querySelector("tr.romname_section > td").innerText.trim();
const noIntroPlatform = scraped.querySelector("#content > div.standard > table:first-child").innerText.trim().split(" - ").slice(1).join(" - ");
const info = {
extension,
title: title,
cached: false,
noIntroPlatform,
noIntroUrl: url,
parentUrl: determineParentUrl(scraped, url),
childrenUrls: getRomChildrenUrls(scraped, url)
};
cache.set(url, info, 1000 * 60 * 60);
return info;
} catch (err) {
console.error("zibzab helper failed to parse no-intro:", err);
throw new Error("Failed to parse no-intro :/\nIf the No-Intro link in the torrent description is valid and working, please report to BestGrapeLeaves, including the error that was logged to the browser console");
}
}
async function searchNoIntro(title, platform, expectedExtension) {
const cached = cache.get(`search:${title}:${platform}`);
if (cached) {
return cached.map((rom)=>({
...rom,
cached: true
}));
}
// compose search url
const url = new URL("https://datomatic.no-intro.org/index.php");
url.searchParams.set("page", "search");
url.searchParams.set("s", platform);
// compose form data
const formData = new FormData();
formData.append("system_selection", platform);
formData.append("text", title);
formData.append("where", "1");
formData.append("sort", "Title");
formData.append("order", "Ascending");
const scraped = await scrapeNoIntro(url.toString(), "POST", formData);
try {
const romLinks = [
...scraped.querySelectorAll("#content > table.info-table .SearchLinkTitle > a"),
];
const results = romLinks.map((link)=>{
const url = "https://datomatic.no-intro.org/index.php" + link.getAttribute("href");
const rom = {
cached: false,
// @TODO: platformize
noIntroPlatform: "",
title: link.innerText.trim(),
extension: expectedExtension,
noIntroUrl: url,
childrenUrls: []
};
// cache.set(url, rom, 1000 * 60 * 60);
return rom;
});
cache.set(`search:${title}:${platform}`, results, 1000 * 60 * 60);
return results;
} catch (err) {
console.error("zibzab helper failed to parse no-intro:", err);
throw new Error("Failed to search no-intro :/\nIf you believe this is a bug in the script, please report to BestGrapeLeaves, including the error that was logged to the browser console");
}
}
function findNoIntroSiblings(url) {}
function populateNoIntroInformation(rom) {
// We stopped shipping entire filenames
// when zibzab reported that it varies from dump to dump
// like some can have a "bad" filename
// title is 100% accurate, and extension shouldn't vary
const title = rom.title.replace(/^[a-z]?\d+ - /, ""); // Remove 4 digit game code;
const filename = `${title}.${rom.extension}`;
// Region/Lang
const { language , region , edition , release } = identifyNoIntroTags(title);
return {
...rom,
filename,
language,
region,
releaseTags: release,
editionTags: edition,
title
};
}
async function fetchNoIntro(url) {
return populateNoIntroInformation(await getRomInformationFromNoIntro(url));
}
;// CONCATENATED MODULE: ./src/utils/dom/fetchTorrentFilelist.ts
// We are fetching files for checking,
// might as well reduce load on servers and save to dom (like the button does)
function fetchTorrentFilelist(torrentId) {
const parseFromDom = ()=>$(`#files_${torrentId} > table > tbody > tr:not(.colhead_dark) > td:first-child`).map(function() {
return $(this).text();
}).get();
return new Promise((resolve)=>{
// @ts-expect-error
if ($("#files_" + torrentId).raw().innerHTML === "") {
// $('#files_' + torrentId).gshow().raw().innerHTML = '<h4>Loading...</h4>';
ajax.get("torrents.php?action=torrentfilelist&torrentid=" + torrentId, function(response) {
// @ts-expect-error
$("#files_" + torrentId).ghide();
// @ts-expect-error
$("#files_" + torrentId).raw().innerHTML = response;
resolve(parseFromDom());
});
} else {
resolve(parseFromDom());
}
});
}
;// CONCATENATED MODULE: ./src/utils/dom/checkIfTrumpable.ts
async function checkIfTrumpable(torrent) {
try {
const { title , cached , extension , parentUrl } = await fetchNoIntro(torrent.noIntroLink);
const desiredExt = PLATFORM_TO_ARCHIVE_TYPE[torrent.platform];
const desiredFilename = title + "." + (desiredExt || "zip");
const files = await fetchTorrentFilelist(torrent.torrentId);
if (files.length !== 1) {
return {
trumpable: true,
cached,
inditermint: "\nMultiple/No files found in torrent"
};
}
const actualFilename = files[0];
return {
trumpable: desiredExt ? desiredFilename !== actualFilename : title !== actualFilename.split(".").slice(0, -1).join("."),
desiredFilename,
actualFilename,
cached,
desiredExt,
title,
romExtension: extension,
parentUrl
};
} catch (err) {
console.error("GGn No-Intro Helper: Error checking trumpability", err);
return {
trumpable: true,
cached: false,
inditermint: err.message
};
}
}
;// CONCATENATED MODULE: ./src/utils/massReporting.ts
// Whack whack
// So many shenanigans to avoid enslaving my self to using IDs for elems
let massReporting = false;
let reportFunctions = {};
function isMassReporting() {
return massReporting;
}
function setMassReporting(value) {
massReporting = value;
}
function registerReport(torrentId, report) {
reportFunctions[torrentId] = report;
}
function clearReportFunctions() {
reportFunctions = {};
}
async function reportTorrent(torrentId) {
if (reportFunctions[torrentId]) {
await reportFunctions[torrentId]();
reportFunctions[torrentId] = undefined;
} else {
throw new Error(`No report function registered for torrent ${torrentId}`);
}
}
async function reportAllTrumps() {
setMassReporting(true);
const torrentIds = Object.keys(reportFunctions);
for(let i = 0; i < torrentIds.length; i++){
const id = torrentIds[i];
if (i === torrentIds.length - 1) {
setMassReporting(false);
}
await reportTorrent(id);
await new Promise((resolve)=>setTimeout(resolve, 100));
}
}
;// CONCATENATED MODULE: ./src/inserts/smallPre.ts
function smallPre(text, bgColor) {
return `<pre style="
padding: 0px;
margin: 0;
background-color: ${bgColor};
color: black;
font-weight: bold;
font-size: 12px;
padding-left: 3px;
padding-right: 3px;
width: fit-content;
">${text}</pre>`;
}
;// CONCATENATED MODULE: ./src/inserts/insertTrumpNotice.ts
function inditermintNoticeInfo(param) {
let { inditermint } = param;
return {
title: "Couldn't determine if the torrent is trumpable:",
details: inditermint,
color: "pink"
};
}
function reportedNoticeInfo() {
return {
title: "Torrent was trumped and reported!",
details: "",
color: "var(--darkRed)"
};
}
function trumpableNoticeInfo(param) {
let { actualFilename , desiredFilename } = param;
return {
title: "This torrent is trumpable!",
details: `The filename in the torrent is: ${smallPre(actualFilename, "lightcoral")} but the desired filename, based on <i>No-Intro</i> is: ${smallPre(desiredFilename, "lightgreen")}`,
color: "hotpink"
};
}
function reportableNoticeInfo(param) {
let { fixedVersion , torrentId , actualFilename , desiredFilename , noIntroLink } = param;
const form = $("<div/></div>");
const trumpingTorrentInput = $(`<input type="text" value="${fixedVersion.permalink}" placeholder="https://gazellegames.net/torrents.php?id=xxxxx&torrentid=yyyyyy" style="width: 75%; background: #ffb952; color: black;"/>`);
const commentTextarea = $(`<textarea placeholder="Previous upload didn't like hummus" style="height: 100px; width: 90%; background: #ffb952; color: black; margin: 0;"/>`);
const reportReason = actualFilename.split(".").slice(0, -1).join(".") !== desiredFilename.split(".").slice(0, -1).join(".") ? "ROM name changed on No-Intro." : "Corrected archive type.";
commentTextarea.text(`${reportReason}
Reported filename : ${actualFilename}
Trumping filename : ${desiredFilename}
No-Intro for reference : ${noIntroLink}`);
const submitInputButton = $(`<input class="no-intro-helper-submit-trump-report-button" id="no-intro-helper-submit-trump-report-${torrentId}" type="button" value="REPORT" style="width: 70px; margin: 0; background: #ffb952; color: black; font-weight: bolder;"/>`);
const errorMessage = $("<div style='color: red; font-weight: bold; font-size: 13px; white-space: pre-line;'></div>").hide();
form.append(`<p style="font-size: 12px;">Trumping Torrent Permalink:</p>`, trumpingTorrentInput, `<p style="font-size: 12px;">Report Comment:</p>`, commentTextarea, `<p style="font-size: 12px;">Submit Report:</p>`, submitInputButton, errorMessage);
// can't read spagettelian, I'm sorry.
const report = async ()=>{
// If it's disabled this should in theory not trigger,
// but just in case jquery does some shenaningans
// when you manually trigger a click event
if (submitInputButton.prop("disabled") === true) {
return;
}
errorMessage.hide();
submitInputButton.prop("disabled", true);
$(`#trump-notice-links-${torrentId} > span:nth-child(2)`).hide();
$(`#trump-notice-title-${torrentId}`).css("color", "#ffb952").find(".trump-notice-title-span").text("Reporting...");
const data = new FormData();
data.append("submit", "true");
data.append("torrentid", torrentId);
data.append("categoryid", "1");
data.append("type", "trump");
data.append("sitelink", fixedVersion.permalink);
data.append("extra", commentTextarea.val());
data.append("id_token", new Date().getTime().toString());
try {
await new Promise((resolve)=>setTimeout(resolve, 3000));
await fetch("/reportsv2.php?action=takereport", {
method: "POST",
body: data
});
if (!isMassReporting()) {
window.location.reload();
} else {
$(`#trump-notice-title-${torrentId}`).text("Reported!");
}
} catch (err) {
console.error("Error submitting trump report", err);
console.error("Form data sent:", Object.fromEntries([
...data.entries()
]));
errorMessage.text(`An error occurred while submitting the trump report. If you believe this is a problem with the script, please report to BestGrapeLeaves (including console logs if you can).
Error Message:
${err.message}`);
errorMessage.show();
submitInputButton.prop("disabled", false);
$(`#trump-notice-links-${torrentId} > span:nth-child(2)`).show();
$(`#trump-notice-title-${torrentId}`).css("color", "#ff7600").find(".trump-notice-title-span").text("Torrent needs to be reported for trump!");
const toggleDetailsActionSpan = $(`#trump-notice-links-${torrentId} > span:first-child`);
const collapsed = toggleDetailsActionSpan.text() === "[Expand]";
if (collapsed) {
toggleDetailsActionSpan.text("[Collapse]");
$(`#trump-notice-title-${torrentId}`).next().show();
}
}
};
registerReport(torrentId, report);
submitInputButton.click(report);
return {
title: "Torrent needs to be reported for trump!",
details: form,
color: "#ff7600"
};
}
function insertTrumpNotice(torrent) {
const { inditermint , fixedVersion , torrentId , reported } = torrent;
// Settings
let info;
let type;
if (inditermint) {
type = "inditermint";
info = inditermintNoticeInfo(torrent);
} else if (fixedVersion) {
if (reported) {
type = "reported";
info = reportedNoticeInfo();
} else {
type = "reportable";
info = reportableNoticeInfo(torrent);
}
} else {
type = "trumpable";
info = trumpableNoticeInfo(torrent);
}
const { color , details , title } = info;
// Elements
const detailsDiv = $(`<div style="font-weight: normal; color: white; white-space: pre-line;"></div>`).hide();
detailsDiv.append(details);
const titleSpan = $(`
<span id="trump-notice-title-${torrentId}" style="color: ${color}; font-size: 14px; font-weight: bold;"><span class="trump-notice-title-span">${title}</span></span>`);
const actionsDiv = $(`<div id="trump-notice-links-${torrentId}" style="font-weight: normal; font-size: 11px; display: inline; margin: 5px; user-select: none;"></div>`);
// Toggle Details
if (type !== "reported") {
const toggleDetailsActionSpan = $(`<span style="cursor: pointer; margin-right: 5px;">[Expand]</span>`);
toggleDetailsActionSpan.click(()=>{
const collapsed = toggleDetailsActionSpan.text() === "[Expand]";
if (collapsed) {
toggleDetailsActionSpan.text("[Collapse]");
detailsDiv.show();
} else {
toggleDetailsActionSpan.text("[Expand]");
detailsDiv.hide();
}
});
actionsDiv.append(toggleDetailsActionSpan);
}
// Send Report
if (type === "reportable") {
const sendReportActionSpan = $(`<span style="cursor: pointer; margin-right: 5px;">[Send Report]</span>`);
sendReportActionSpan.click(()=>{
$(`#no-intro-helper-submit-trump-report-${torrentId}`).click();
});
actionsDiv.append(sendReportActionSpan);
}
// Cheer
if (type === "reported") {
const cheerActionSpan = $(`<span style="cursor: pointer; margin-right: 5px; position: absolute;">[Cheer]</span>`);
const randomAnimation = Math.random() > 0.5 ? "spin" : "grow";
cheerActionSpan.click(()=>{
cheerActionSpan.text("HOORAY!");
cheerActionSpan.animate({
opacity: 0
}, // @ts-expect-error
{
duration: 2000,
complete: ()=>{
// prevent huge animated text from blocking clicks
cheerActionSpan.detach();
},
step: function(now) {
if (randomAnimation === "spin") {
cheerActionSpan.css({
transform: "rotate(" + now * 360 * 5 + "deg)"
});
} else {
cheerActionSpan.css({
transform: "scale(" + (1 + (1 - now) * 28) + ")"
});
}
}
}, "swing");
});
actionsDiv.append(cheerActionSpan);
}
// Tree
const wrapper = $(`<div></div>`);
titleSpan.append(actionsDiv);
wrapper.append(titleSpan);
wrapper.append(detailsDiv);
// Place
let currentlyAdaptedToSmallScreen;
function placeTrumpNotice() {
console.log("adapting", window.innerWidth);
if (window.innerWidth <= 800) {
if (currentlyAdaptedToSmallScreen) {
return;
}
currentlyAdaptedToSmallScreen = true;
$(`#torrent${torrentId}`).css("border-bottom", "none");
wrapper.css("margin-left", "25px");
wrapper.detach();
wrapper.insertAfter(`#torrent${torrentId}`);
} else {
if (currentlyAdaptedToSmallScreen === false) {
return;
}
currentlyAdaptedToSmallScreen = false;
$(`#torrent${torrentId}`).css("border-bottom", "");
wrapper.css("margin-left", "0px");
wrapper.detach();
wrapper.appendTo(`#torrent${torrentId} > td:first-child`);
}
}
placeTrumpNotice();
$(window).resize(placeTrumpNotice);
// Call global hook (for other scripts)
// @ts-expect-error
if (typeof unsafeWindow.GM_GGN_NOINTRO_HELPER_ADDED_LINKS === "function") {
// @ts-expect-error
unsafeWindow.GM_GGN_NOINTRO_HELPER_ADDED_LINKS({
...torrent,
links: actionsDiv
});
}
}
;// CONCATENATED MODULE: ./src/inserts/reportAllTrumpsButton.ts
function reportAllTrumpsButton() {
const existing = $("#report-all-no-intro-trumps-button");
const button = existing.length > 0 ? existing : $(`<input id="report-all-no-intro-trumps-button" type="button" value="Report All Trumped" style="background: #ff7600; color: black; font-weight: bold; margin-left: 10px;"/>`);
const disable = ()=>{
button.prop("disabled", true);
button.css("background-color", "#ffb952");
button.css("color", "darkslategray");
button.css("box-shadow", "none");
};
const insert = ()=>{
button.detach();
$(".torrent_table > tbody > tr:first-child > td:first-child").first().append(button);
};
if (existing.length === 0) {
button.click(async (e)=>{
e.stopImmediatePropagation();
button.val("Reporting...");
disable();
reportAllTrumps();
});
}
return {
disable,
insert,
button
};
}
;// CONCATENATED MODULE: ./src/inserts/insertTrumpSuggestions.ts
async function checkForImproperlyNamedTorrents(torrents) {
const { disable , progress } = checkForTrumpsButton();
disable();
let prevCached = false;
// let alreadySearched = new Set<string>();
// let maybeNewVersions: BareNoIntroRomInformation[] = [];
let parentRomsUrls = new Set();
const trumpResults = [];
for(let i = 0; i < torrents.length; i++){
const torrent = torrents[i];
progress(`Checking For Trumps ${i + 1}/${torrents.length}...`);
// timeout to avoid rate limiting
if (!prevCached) {
await new Promise((resolve)=>setTimeout(resolve, 500));
}
// Check trump
const TrumpCheckResult = await checkIfTrumpable(torrent);
const { cached , parentUrl } = TrumpCheckResult;
prevCached = cached;
trumpResults.push({
...TrumpCheckResult,
...torrent
});
if (parentUrl) {
parentRomsUrls.add(parentUrl);
}
// Search for new versions
// if ($("#groupplatform").text() !== "MSX 2") {
// continue;
// }
// const gameName = title.replace(/\(.+?\)/g, "").trim();
// if (alreadySearched.has(gameName)) {
// continue;
// }
// // @TODO: platofrmify
// maybeNewVersions = [
// ...maybeNewVersions,
// ...(await searchNoIntro(gameName, "11", romExtension)),
// ];
// alreadySearched.add(gameName);
}
// Find actually new versions
// const newVersions: Record<string, BareNoIntroRomInformation> = {};
// maybeNewVersions.forEach((v) => {
// if (newVersions[v.noIntroUrl]) {
// return;
// }
// // naming consistency is life
// if (torrents.some((t) => t.noIntroLink === v.noIntroUrl)) {
// return;
// }
// newVersions[v.noIntroUrl] = v;
// });
const allRelatedRomsUrls = new Set(parentRomsUrls);
let newVersions = [];
try {
await Promise.all(Array.from(parentRomsUrls).map(async (url)=>{
const { childrenUrls } = await getRomInformationFromNoIntro(url);
childrenUrls.forEach((c)=>allRelatedRomsUrls.add(c));
}));
const newVersionsUrls = Array.from(allRelatedRomsUrls).filter((url)=>!torrents.some((t)=>t.noIntroLink === url));
newVersions = await Promise.all(newVersionsUrls.map((url)=>fetchNoIntro(url)));
} catch (err) {
// @TODO: display and handle properly in dom blah blah
console.error("Failed to get new versions", err);
}
return {
trumpResults,
newVersions
};
}
// Filter the torrents that have a trump uploaded
function attachFixedVersionsToTorrents(torrents) {
// Efficiency is not my greatest of concerns,
// if you want implement a graph theory solution in O(1) or something
return torrents.map((c)=>{
if (!c.trumpable || c.inditermint) {
return c;
}
return {
...c,
fixedVersion: torrents.find((v)=>!v.inditermint && !v.trumpable && v.noIntroLink === c.noIntroLink)
};
});
}
function insertTrumpSuggestions(results) {
const { progress } = checkForTrumpsButton();
let trumps = 0;
let reportable = 0;
clearReportFunctions();
results.forEach((torrent)=>{
if (!torrent.trumpable) {
return;
}
if (torrent.inditermint) {
insertTrumpNotice(torrent);
return;
}
if (torrent.fixedVersion && !torrent.reported) {
reportable++;
}
if (!torrent.fixedVersion) {
trumps++;
}
insertTrumpNotice(torrent);
});
if (trumps === 0) {
progress("No Trumps Found");
} else if (trumps === 1) {
progress("1 Trump Found");
} else {
progress(`${trumps} Trumps Found`);
}
const { button , insert } = reportAllTrumpsButton();
if (reportable > 0) {
insert();
} else {
button.detach();
}
}
function insertNewVersionSuggestions(newVersions) {
if (newVersions.length === 0) {
return;
}
const availableToUploadSectionTitle = $(`<tbody>
<tr class="group_torrent">
<td style="background-color: #662b2b;" colspan="6" class="edition_info" onclick="jQuery('#edition_new_versions').toggle();return false;">
<strong style="color: #ffdba6;">✭ New Versions Available To Upload</strong>
</td>
</tr>
</tbody>`);
const availableToUploadSection = $(`<tbody id="edition_new_versions" style=""></tbody>`);
const styles = $(`
<style>
#edition_new_versions > tr {
background-color: rgba(102, 43, 43, 0.4)
}
#edition_new_versions > tr:hover {
background-color: rgba(102, 43, 43)
}
</style>`);
newVersions.map(populateNoIntroInformation).forEach((v)=>{
availableToUploadSection.append(`<tr class="group_torrent" style="font-weight: normal" id="torrent378950">
<td>
<span
>[
<a style="color: blanchedalmond;" href="${addCopyHref(v.noIntroUrl)}" title="Add Copy">AC</a>
]</span
>
»
<a style="color: blanchedalmond;" target="_blank" href="${v.noIntroUrl}" class="friends_upload">${v.title}</a>
</td>
<td class="nobr">
<span class="time" title="Upload It!">hopefully today</span>
</td>
<td class="nobr">------</td>
<td>∞</td>
<td>∞</td>
<td>∞</td>
</tr>`);
});
// Insert to page
$(".torrent_table").append(availableToUploadSectionTitle, availableToUploadSection, styles);
}
async function findAndDisplayTrumps() {
const torrents = getNoIntroTorrentsOnPage();
const { trumpResults , newVersions } = await checkForImproperlyNamedTorrents(torrents);
const processed = attachFixedVersionsToTorrents(trumpResults);
console.log("GGn No-Intro Helper: Trumps", processed);
console.log("GGn No-Intro Helper: new versions", newVersions);
insertNewVersionSuggestions(newVersions);
insertTrumpSuggestions(processed);
}
;// CONCATENATED MODULE: ./src/pages/torrents.ts
function trumpSuggestions() {
const torrents = getNoIntroTorrentsOnPage();
if (torrents.length === 0) {
return;
}
const { button , insert } = checkForTrumpsButton();
insert();
if (torrents.length <= 4) {
findAndDisplayTrumps();
}
button.click((e)=>{
e.stopImmediatePropagation();
findAndDisplayTrumps();
});
}
function torrentsPageMain() {
insertAddCopyHelpers();
trumpSuggestions();
}
;// CONCATENATED MODULE: ./src/inserts/uploadLinkParserUI.ts
function uploadNoIntroLinkParserUI() {
// elements
const container = $(`<tr id="no-intro-url" name="no-intro-url">
<td class="label">No-Intro Link</td>
</tr>`);
const input = $('<input type="text" id="no-intro-url-input" name="no-intro-url-input" size="60%" class="input_tog" value="">');
// @TODO: Just make it one notice p, why seven different kinds why
const error = $('<p id="no-intro-url-error" name="no-intro-url-error" style="color: red; font-weight:bold; font-size: 15px; white-space:pre-line;"></p>').hide();
const loading = $('<p id="no-intro-url-loading" name="no-intro-url-loading" style="color: green;">Loading...</p>').hide();
const warning = $('<p id="no-intro-url-warning" name="no-intro-url-warning" style="color: yellow; white-space: pre-line;"></p>').hide();
const incorrectFilename = $('<div style="font-weight: normal; color: white; line-height: 1.5em;"></div>').hide();
const goButton = $('<input type="button" value="No-Intro"></input>');
// structure
const td = $("<td></td>");
td.append(input);
td.append(loading);
td.append(error);
td.append(incorrectFilename);
td.append(warning);
container.append(td);
// utils
const setError = (msg)=>{
error.html(msg);
error.show();
};
const setWarning = (msg)=>{
warning.text(msg);
warning.show();
};
const setLoading = (isLoading)=>{
if (isLoading) {
loading.show();
} else {
loading.hide();
}
};
const insert = ()=>{
container.insertAfter("#torrent_file");
};
// stuff
input.on("paste", (e)=>{
e.preventDefault();
const text = e.originalEvent.clipboardData.getData("text/plain");
input.val(text);
});
return {
loading,
error,
warning,
incorrectFilename,
container,
input,
goButton,
setError,
setWarning,
setLoading,
insert
};
}
;// CONCATENATED MODULE: ./src/utils/dom/setUploadEdition.ts
function setUploadEdition(edition) {
try {
$("#groupremasters").val(edition).change();
GroupRemaster();
} catch {
// group remaster always throws (regardless of the userscript)
}
}
;// CONCATENATED MODULE: ./src/utils/generateTorrentDescription.ts
const compressedWithZip = "[url=https://sourceforge.net/projects/trrntzip/]torrentzip.[/url]";
const compressedWith7z = "[url=https://github.com/BubblesInTheTub/torrent7z]torrent7z.[/url]";
const generateTorrentDescription = function() {
let url = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "xxx", filename = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "xxx", zip = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : true;
return `[align=center][b]${filename}[/b] matches [url=${url}]No-Intro checksum[/url].
Compressed with ${zip ? compressedWithZip : compressedWith7z}[/align]
`;
};
// EXTERNAL MODULE: ./node_modules/bencode/lib/index.js
var lib = __webpack_require__("./node_modules/bencode/lib/index.js");
var lib_default = /*#__PURE__*/__webpack_require__.n(lib);
// EXTERNAL MODULE: ./node_modules/path-browserify/index.js
var path_browserify = __webpack_require__("./node_modules/path-browserify/index.js");
var path_browserify_default = /*#__PURE__*/__webpack_require__.n(path_browserify);
// EXTERNAL MODULE: ./node_modules/simple-sha1/browser.js
var browser = __webpack_require__("./node_modules/simple-sha1/browser.js");
var browser_default = /*#__PURE__*/__webpack_require__.n(browser);
;// CONCATENATED MODULE: ./src/utils/parseTorrent.ts
/* provided dependency */ var Buffer = __webpack_require__("./node_modules/buffer/index.js")["lW"];
/*! parse-torrent. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */ /* global Blob */
function parseTorrent(torrentId) {
if (Buffer.isBuffer(torrentId) && torrentId.length === 20) {
// if info hash (buffer)
throw new Error("Magnet not implemented");
} else if (Buffer.isBuffer(torrentId)) {
// if .torrent file (buffer)
return decodeTorrentFile(torrentId); // might throw
} else {
throw new Error("Invalid torrent identifier");
}
}
/**
* Parse a torrent. Throws an exception if the torrent is missing required fields.
* @param {Buffer|Object} t
* @return {Object} parsed torrent
*/ function decodeTorrentFile(torrent) {
let t = Buffer.isBuffer(torrent) ? lib_default().decode(torrent) : torrent;
// sanity check
ensure(t.info, "info");
ensure(t.info["name.utf-8"] || t.info.name, "info.name");
ensure(t.info["piece length"], "info['piece length']");
ensure(t.info.pieces, "info.pieces");
if (t.info.files) {
t.info.files.forEach((file)=>{
ensure(typeof file.length === "number", "info.files[0].length");
ensure(file["path.utf-8"] || file.path, "info.files[0].path");
});
} else {
ensure(typeof t.info.length === "number", "info.length");
}
const result = {
info: t.info,
infoBuffer: lib_default().encode(t.info),
name: (t.info["name.utf-8"] || t.info.name).toString(),
announce: []
};
result.infoHash = browser_default().sync(result.infoBuffer);
result.infoHashBuffer = Buffer.from(result.infoHash, "hex");
if (t.info.private !== undefined) result.private = !!t.info.private;
if (t["creation date"]) result.created = new Date(t["creation date"] * 1000);
if (t["created by"]) result.createdBy = t["created by"].toString();
if (Buffer.isBuffer(t.comment)) result.comment = t.comment.toString();
// announce and announce-list will be missing if metadata fetched via ut_metadata
if (Array.isArray(t["announce-list"]) && t["announce-list"].length > 0) {
t["announce-list"].forEach((urls)=>{
urls.forEach((url)=>{
result.announce.push(url.toString());
});
});
} else if (t.announce) {
result.announce.push(t.announce.toString());
}
// handle url-list (BEP19 / web seeding)
if (Buffer.isBuffer(t["url-list"])) {
// some clients set url-list to empty string
t["url-list"] = t["url-list"].length > 0 ? [
t["url-list"]
] : [];
}
result.urlList = (t["url-list"] || []).map((url)=>url.toString());
// remove duplicates by converting to Set and back
result.announce = Array.from(new Set(result.announce));
result.urlList = Array.from(new Set(result.urlList));
const files = t.info.files || [
t.info
];
result.files = files.map((file, i)=>{
const parts = [].concat(result.name, file["path.utf-8"] || file.path || []).map((p)=>p.toString());
return {
path: path_browserify_default().join.apply(null, [
(path_browserify_default()).sep
].concat(parts)).slice(1),
name: parts[parts.length - 1],
length: file.length,
offset: files.slice(0, i).reduce(sumLength, 0)
};
});
result.length = files.reduce(sumLength, 0);
const lastFile = result.files[result.files.length - 1];
result.pieceLength = t.info["piece length"];
result.lastPieceLength = (lastFile.offset + lastFile.length) % result.pieceLength || result.pieceLength;
result.pieces = splitPieces(t.info.pieces);
return result;
}
function sumLength(sum, file) {
return sum + file.length;
}
function splitPieces(buf) {
const pieces = [];
for(let i = 0; i < buf.length; i += 20){
pieces.push(buf.slice(i, i + 20).toString("hex"));
}
return pieces;
}
function ensure(bool, fieldName) {
if (!bool) throw new Error(`Torrent is missing required field: ${fieldName}`);
}
// Workaround Browserify v13 bug
// https://github.com/substack/node-browserify/issues/1483
(()=>{
Buffer.alloc(0);
})();
;// CONCATENATED MODULE: ./src/pages/upload.ts
/* provided dependency */ var upload_Buffer = __webpack_require__("./node_modules/buffer/index.js")["lW"];
function toBuffer(ab) {
const buf = upload_Buffer.alloc(ab.byteLength);
const view = new Uint8Array(ab);
for(let i = 0; i < buf.length; ++i){
buf[i] = view[i];
}
return buf;
}
function highlightNeedsToBeVerified(selectors) {
selectors.forEach((s)=>{
console.log("Highlighting", s);
$(s).css("border", "yellow solid 1.5px");
});
}
// @TODO: Spaghetti nonsense, should have slept before
function uploadPageMain() {
// const filename = $("#file").val() as string;
const { goButton , error , warning , input , setError , setLoading , setWarning , insert , incorrectFilename , } = uploadNoIntroLinkParserUI();
insert();
goButton.insertAfter("#file");
// Pre-fill link if possible
const params = new URLSearchParams(window.location.search);
const noIntroLink = params.get("no-intro");
if (noIntroLink) {
$("#no-intro-url-input").val(noIntroLink).change();
}
goButton.click(async ()=>{
// Prechecks
incorrectFilename.hide();
incorrectFilename.empty();
error.hide();
warning.hide();
let link = input.val();
try {
if (!link) {
setError("Please enter the No-Intro link");
return;
}
const url = new URL(link);
url.protocol = "https:";
link = url.toString();
if (!link.startsWith("https://datomatic.no-intro.org/")) {
setError("Not a no-intro link");
return;
}
} catch {
setError("Invalid URL");
return;
}
// Fetch no intro
setLoading(true);
goButton.prop("disabled", true);
let info;
try {
info = await fetchNoIntro(link);
} catch (err) {
setError(err.message || err || "An unexpected error has occurred");
setLoading(false);
goButton.prop("disabled", false);
return;
}
const { filename , language , region , releaseTags , editionTags , title } = info;
// Call global hook (for other scripts)
const platform = $("#platform").val();
const desiredArchiveExt = PLATFORM_TO_ARCHIVE_TYPE[platform] || "zip";
// @ts-expect-error
if (typeof unsafeWindow.GM_GGN_NOINTRO_HELPER_ADDED_LINKS === "function") {
// @ts-expect-error
const res = await unsafeWindow.GM_GGN_NOINTRO_HELPER_BEFORE_MAGIC_BUTTON({
...info,
archiveName: title + "." + desiredArchiveExt
});
if (res) {
setError(res);
setLoading(false);
goButton.prop("disabled", false);
return;
}
}
// Parse torrent
// let parsedTorrent: Awaited<ReturnType<typeof parseTorrent>>;
// let filenameFromUploadedTorrent = "";
const file = $("#file").prop("files")[0];
if (!file) {
setError("No torrent file uploaded");
setLoading(false);
goButton.prop("disabled", false);
return;
}
try {
const parsedTorrent = parseTorrent(toBuffer(await file.arrayBuffer()));
if (!("files" in parsedTorrent)) {
console.log("nofiles");
throw new Error("No files in torrent");
}
// Check if torrent is a single file
if (parsedTorrent.files.length !== 1) {
setError("Can't compare the filenames in the torrent to No-Intro since the torrent has multiple files. If this is intentional, please ignore this error message.");
} else {
// @TODO: verify file not in subfolder
console.log("Parsed torrent file", parsedTorrent.files[0]);
const filenameFromUploadedTorrent = parsedTorrent.files[0].name.split(".").slice(0, -1).join(".");
if (filenameFromUploadedTorrent !== title) {
setError("The filename in the torrent does not match the No-Intro title");
incorrectFilename.show();
incorrectFilename.append(`The filename in the torrent is: ${smallPre(filenameFromUploadedTorrent, "lightcoral")} but the desired filename, based on <i>No-Intro</i> is: ${smallPre(title, "lightgreen")}
If this is intentional, please ignore this message.`);
}
}
} catch {
setError("Couldn't parse torrent file, continuing without verifying torrent");
}
const highlightForVerification = [];
// Release type = ROM
$("select#miscellaneous").val("ROM").change();
// Description
$("textarea#release_desc").val(generateTorrentDescription(link, filename, // @ts-expect-error hemummume
PLATFORM_TO_ARCHIVE_TYPE[$("#platform").val()] !== "7z"));
// Region
$("select#region").val(region);
highlightForVerification.push("select#region");
// Language
if (language) {
$("select#language").val(language);
}
highlightForVerification.push("select#language");
// It is a special edition (all no intro are)
if (!$("input#remaster").prop("checked")) {
$("input#remaster").prop("checked", true);
Remaster();
}
// Not a scene release
$("#ripsrc_home").prop("checked", true);
updateReleaseTitle(title.replace(/\(.+?\)/g, "").trim() + (releaseTags ? " " + releaseTags : ""));
highlightForVerification.push("input#release_title");
// Set correct edition from url params/edition
// @TODO: Compare from param to expected
// Sometimes editions are created wrong
// If so maybe let the user choose or just show a warning
let editionFromParam = params.get("edition");
let editionFromTags = "";
if (!editionFromParam) {
const postfix = editionTags.length === 0 ? "" : ` - ${editionTags.join(", ")}`;
editionFromTags = `No-Intro${postfix}`;
}
// Update edition select
let updatedEdition = false;
$("#groupremasters > option").each(function() {
const title = $(this).text().toLowerCase();
if (editionFromParam) {
if (title === editionFromParam.toLowerCase()) {
setUploadEdition($(this).val());
updatedEdition = true;
return false; // This breaks out of the jquery loop
}
return;
}
if (editionFromTags && title.replace(/ \(\d{4}\)/, "") === editionFromTags.toLowerCase()) {
setUploadEdition($(this).val());
updatedEdition = true;
return false;
}
});
// If edition does not exist, fill name at least
if (!updatedEdition) {
$("#remaster_title").val(editionFromTags);
highlightForVerification.push("#remaster_title");
}
highlightNeedsToBeVerified(highlightForVerification);
setWarning(`Make sure to verify everything before uploading, especially the highlighted details.\nEven scripts make mistakes.`);
// Wrap up
setLoading(false);
goButton.prop("disabled", false);
});
}
;// CONCATENATED MODULE: ./src/index.ts
async function main() {
console.log("GGn No-Intro Helper: Starting...");
if (window.location.pathname === "/torrents.php") {
torrentsPageMain();
} else if (window.location.pathname === "/upload.php") {
uploadPageMain();
}
// Blacklist no-intro URLs that lead to ban
$("a").click(function() {
if (NO_INTRO_ROM_LINK_REGEX.test($(this).attr("href"))) {
$(this).text("BLACKLISTED");
return false;
}
});
}
main().catch((e)=>{
console.log(e);
});
})();
/******/ })()
;