/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(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 module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ({ /***/ "./gulp/node_modules/base64-js/index.js": /*!**********************************************!*\ !*** ./gulp/node_modules/base64-js/index.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "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('') } /***/ }), /***/ "./gulp/node_modules/ieee754/index.js": /*!********************************************!*\ !*** ./gulp/node_modules/ieee754/index.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports) { 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 } /***/ }), /***/ "./gulp/node_modules/isarray/index.js": /*!********************************************!*\ !*** ./gulp/node_modules/isarray/index.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports) { var toString = {}.toString; module.exports = Array.isArray || function (arr) { return toString.call(arr) == '[object Array]'; }; /***/ }), /***/ "./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js": /*!**************************************************************************!*\ !*** ./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js ***! \**************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global) {/*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT */ /* eslint-disable no-proto */ var base64 = __webpack_require__(/*! base64-js */ "./gulp/node_modules/base64-js/index.js") var ieee754 = __webpack_require__(/*! ieee754 */ "./gulp/node_modules/ieee754/index.js") var isArray = __webpack_require__(/*! isarray */ "./gulp/node_modules/isarray/index.js") exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) * === false Use 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+. * * Due to various browser bugs, sometimes the Object implementation will be used even * when the browser supports typed arrays. * * Note: * * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. * * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. * * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of * incorrect length in some situations. * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they * get the Object implementation, which is slower but behaves correctly. */ Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined ? global.TYPED_ARRAY_SUPPORT : typedArraySupport() /* * Export kMaxLength after typed array support is determined. */ exports.kMaxLength = kMaxLength() function typedArraySupport () { try { var arr = new Uint8Array(1) arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} return arr.foo() === 42 && // typed array instances can be augmented typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` } catch (e) { return false } } function kMaxLength () { return Buffer.TYPED_ARRAY_SUPPORT ? 0x7fffffff : 0x3fffffff } function createBuffer (that, length) { if (kMaxLength() < length) { throw new RangeError('Invalid typed array length') } if (Buffer.TYPED_ARRAY_SUPPORT) { // Return an augmented `Uint8Array` instance, for best performance that = new Uint8Array(length) that.__proto__ = Buffer.prototype } else { // Fallback: Return an object instance of the Buffer class if (that === null) { that = new Buffer(length) } that.length = length } return that } /** * 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) { if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { return new Buffer(arg, encodingOrOffset, length) } // Common case. if (typeof arg === 'number') { if (typeof encodingOrOffset === 'string') { throw new Error( 'If encoding is specified then the first argument must be a string' ) } return allocUnsafe(this, arg) } return from(this, arg, encodingOrOffset, length) } Buffer.poolSize = 8192 // not used by this implementation // TODO: Legacy, not needed anymore. Remove in next major version. Buffer._augment = function (arr) { arr.__proto__ = Buffer.prototype return arr } function from (that, value, encodingOrOffset, length) { if (typeof value === 'number') { throw new TypeError('"value" argument must not be a number') } if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { return fromArrayBuffer(that, value, encodingOrOffset, length) } if (typeof value === 'string') { return fromString(that, value, encodingOrOffset) } return fromObject(that, 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(null, value, encodingOrOffset, length) } if (Buffer.TYPED_ARRAY_SUPPORT) { Buffer.prototype.__proto__ = Uint8Array.prototype Buffer.__proto__ = Uint8Array if (typeof Symbol !== 'undefined' && Symbol.species && Buffer[Symbol.species] === Buffer) { // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 Object.defineProperty(Buffer, Symbol.species, { value: null, configurable: true }) } } function assertSize (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be a number') } else if (size < 0) { throw new RangeError('"size" argument must not be negative') } } function alloc (that, size, fill, encoding) { assertSize(size) if (size <= 0) { return createBuffer(that, size) } if (fill !== undefined) { // Only pay attention to encoding if it's a string. This // prevents accidentally sending in a number that would // be interpretted as a start offset. return typeof encoding === 'string' ? createBuffer(that, size).fill(fill, encoding) : createBuffer(that, size).fill(fill) } return createBuffer(that, size) } /** * Creates a new filled Buffer instance. * alloc(size[, fill[, encoding]]) **/ Buffer.alloc = function (size, fill, encoding) { return alloc(null, size, fill, encoding) } function allocUnsafe (that, size) { assertSize(size) that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) if (!Buffer.TYPED_ARRAY_SUPPORT) { for (var i = 0; i < size; ++i) { that[i] = 0 } } return that } /** * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. * */ Buffer.allocUnsafe = function (size) { return allocUnsafe(null, size) } /** * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. */ Buffer.allocUnsafeSlow = function (size) { return allocUnsafe(null, size) } function fromString (that, string, encoding) { if (typeof encoding !== 'string' || encoding === '') { encoding = 'utf8' } if (!Buffer.isEncoding(encoding)) { throw new TypeError('"encoding" must be a valid string encoding') } var length = byteLength(string, encoding) | 0 that = createBuffer(that, length) var actual = that.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') that = that.slice(0, actual) } return that } function fromArrayLike (that, array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 that = createBuffer(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } function fromArrayBuffer (that, array, byteOffset, length) { array.byteLength // this throws if `array` is not a valid ArrayBuffer if (byteOffset < 0 || array.byteLength < byteOffset) { throw new RangeError('\'offset\' is out of bounds') } if (array.byteLength < byteOffset + (length || 0)) { throw new RangeError('\'length\' is out of bounds') } if (byteOffset === undefined && length === undefined) { array = new Uint8Array(array) } else if (length === undefined) { array = new Uint8Array(array, byteOffset) } else { array = new Uint8Array(array, byteOffset, length) } if (Buffer.TYPED_ARRAY_SUPPORT) { // Return an augmented `Uint8Array` instance, for best performance that = array that.__proto__ = Buffer.prototype } else { // Fallback: Return an object instance of the Buffer class that = fromArrayLike(that, array) } return that } function fromObject (that, obj) { if (Buffer.isBuffer(obj)) { var len = checked(obj.length) | 0 that = createBuffer(that, len) if (that.length === 0) { return that } obj.copy(that, 0, 0, len) return that } if (obj) { if ((typeof ArrayBuffer !== 'undefined' && obj.buffer instanceof ArrayBuffer) || 'length' in obj) { if (typeof obj.length !== 'number' || isnan(obj.length)) { return createBuffer(that, 0) } return fromArrayLike(that, obj) } if (obj.type === 'Buffer' && isArray(obj.data)) { return fromArrayLike(that, obj.data) } } throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') } function checked (length) { // Note: cannot use `length < kMaxLength()` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= kMaxLength()) { throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + kMaxLength().toString(16) + ' bytes') } return length | 0 } function SlowBuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return Buffer.alloc(+length) } Buffer.isBuffer = function isBuffer (b) { return !!(b != null && b._isBuffer) } Buffer.compare = function compare (a, b) { if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { throw new TypeError('Arguments must be Buffers') } if (a === b) return 0 var x = a.length var y = b.length for (var i = 0, len = Math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } 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 (!isArray(list)) { throw new TypeError('"list" argument must be an Array of Buffers') } if (list.length === 0) { return Buffer.alloc(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { length += list[i].length } } var buffer = Buffer.allocUnsafe(length) var pos = 0 for (i = 0; i < list.length; ++i) { var buf = list[i] if (!Buffer.isBuffer(buf)) { throw new TypeError('"list" argument must be an Array of Buffers') } buf.copy(buffer, pos) pos += buf.length } return buffer } function byteLength (string, encoding) { if (Buffer.isBuffer(string)) { return string.length } if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { return string.byteLength } if (typeof string !== 'string') { string = '' + string } var len = string.length if (len === 0) return 0 // Use a for loop to avoid recursion var loweredCase = false for (;;) { switch (encoding) { case 'ascii': case 'latin1': case 'binary': return len case 'utf8': case 'utf-8': case undefined: 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 utf8ToBytes(string).length // assume utf8 encoding = ('' + encoding).toLowerCase() loweredCase = true } } } Buffer.byteLength = byteLength function slowToString (encoding, start, end) { var 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 coersion 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 } } } // The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect // Buffer instances. Buffer.prototype._isBuffer = true function swap (b, n, m) { var i = b[n] b[n] = b[m] b[m] = i } Buffer.prototype.swap16 = function swap16 () { var len = this.length if (len % 2 !== 0) { throw new RangeError('Buffer size must be a multiple of 16-bits') } for (var i = 0; i < len; i += 2) { swap(this, i, i + 1) } return this } Buffer.prototype.swap32 = function swap32 () { var len = this.length if (len % 4 !== 0) { throw new RangeError('Buffer size must be a multiple of 32-bits') } for (var i = 0; i < len; i += 4) { swap(this, i, i + 3) swap(this, i + 1, i + 2) } return this } Buffer.prototype.swap64 = function swap64 () { var len = this.length if (len % 8 !== 0) { throw new RangeError('Buffer size must be a multiple of 64-bits') } for (var 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 () { var length = this.length | 0 if (length === 0) return '' if (arguments.length === 0) return utf8Slice(this, 0, length) return slowToString.apply(this, arguments) } 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 () { var str = '' var max = exports.INSPECT_MAX_BYTES if (this.length > 0) { str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') if (this.length > max) str += ' ... ' } return '' } Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { if (!Buffer.isBuffer(target)) { throw new TypeError('Argument must be a Buffer') } 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 var x = thisEnd - thisStart var y = end - start var len = Math.min(x, y) var thisCopy = this.slice(thisStart, thisEnd) var targetCopy = target.slice(start, end) for (var 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 (isNaN(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 (Buffer.TYPED_ARRAY_SUPPORT && 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) { var indexSize = 1 var arrLength = arr.length var 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) } } var i if (dir) { var 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--) { var found = true for (var 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 var remaining = buf.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } // must be an even number of digits var strLen = string.length if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') if (length > strLen / 2) { length = strLen / 2 } for (var i = 0; i < length; ++i) { var parsed = parseInt(string.substr(i * 2, 2), 16) if (isNaN(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 latin1Write (buf, string, offset, length) { return asciiWrite(buf, string, 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 } // legacy write(string, encoding, offset, length) - remove in v0.13 } else { throw new Error( 'Buffer.write(string, encoding, offset[, length]) is no longer supported' ) } var 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' var 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': return asciiWrite(this, string, offset, length) case 'latin1': case 'binary': return latin1Write(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) var res = [] var i = start while (i < end) { var firstByte = buf[i] var codePoint = null var bytesPerSequence = (firstByte > 0xEF) ? 4 : (firstByte > 0xDF) ? 3 : (firstByte > 0xBF) ? 2 : 1 if (i + bytesPerSequence <= end) { var 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 var MAX_ARGUMENTS_LENGTH = 0x1000 function decodeCodePointsArray (codePoints) { var 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". var res = '' var i = 0 while (i < len) { res += String.fromCharCode.apply( String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) ) } return res } function asciiSlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += String.fromCharCode(buf[i] & 0x7F) } return ret } function latin1Slice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += String.fromCharCode(buf[i]) } return ret } function hexSlice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len var out = '' for (var i = start; i < end; ++i) { out += toHex(buf[i]) } return out } function utf16leSlice (buf, start, end) { var bytes = buf.slice(start, end) var res = '' for (var i = 0; i < bytes.length; i += 2) { res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) } return res } Buffer.prototype.slice = function slice (start, end) { var 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 var newBuf if (Buffer.TYPED_ARRAY_SUPPORT) { newBuf = this.subarray(start, end) newBuf.__proto__ = Buffer.prototype } else { var sliceLen = end - start newBuf = new Buffer(sliceLen, undefined) for (var i = 0; i < sliceLen; ++i) { newBuf[i] = this[i + start] } } 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 = function readUIntLE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } return val } Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) { checkOffset(offset, byteLength, this.length) } var val = this[offset + --byteLength] var mul = 1 while (byteLength > 0 && (mul *= 0x100)) { val += this[offset + --byteLength] * mul } return val } Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { 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 = function readUInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) } Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var 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) var i = byteLength var mul = 1 var 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) { 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) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { 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) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] << 24) | (this[offset + 1] << 16) | (this[offset + 2] << 8) | (this[offset + 3]) } Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { 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 = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) { var maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } var mul = 1 var i = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) { var maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } var i = byteLength - 1 var mul = 1 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) this[offset] = (value & 0xff) return offset + 1 } function objectWriteUInt16 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> (littleEndian ? i : 1 - i) * 8 } } Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) } else { objectWriteUInt16(this, value, offset, true) } return offset + 2 } Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) } else { objectWriteUInt16(this, value, offset, false) } return offset + 2 } function objectWriteUInt32 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffffffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff } } Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) this[offset] = (value & 0xff) } else { objectWriteUInt32(this, value, offset, true) } return offset + 4 } Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) } else { objectWriteUInt32(this, value, offset, false) } return offset + 4 } Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 if (!noAssert) { var limit = Math.pow(2, 8 * byteLength - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = 0 var mul = 1 var 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) { var limit = Math.pow(2, 8 * byteLength - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = byteLength - 1 var mul = 1 var 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 (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 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) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) } else { objectWriteUInt16(this, value, offset, true) } 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) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) } else { objectWriteUInt16(this, value, offset, false) } 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) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) } else { objectWriteUInt32(this, value, offset, true) } 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 if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) } else { objectWriteUInt32(this, value, offset, false) } return offset + 4 } 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) { 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) { 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 (!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('sourceStart out of bounds') 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 } var len = end - start var i if (this === target && start < targetStart && targetStart < end) { // descending copy from end for (i = len - 1; i >= 0; --i) { target[i + targetStart] = this[i + start] } } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { // ascending copy from start for (i = 0; i < len; ++i) { target[i + targetStart] = this[i + start] } } else { Uint8Array.prototype.set.call( target, this.subarray(start, start + len), 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 (val.length === 1) { var code = val.charCodeAt(0) if (code < 256) { val = code } } 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) } } else if (typeof val === 'number') { val = val & 255 } // 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 var i if (typeof val === 'number') { for (i = start; i < end; ++i) { this[i] = val } } else { var bytes = Buffer.isBuffer(val) ? val : utf8ToBytes(new Buffer(val, encoding).toString()) var len = bytes.length for (i = 0; i < end - start; ++i) { this[i + start] = bytes[i % len] } } return this } // HELPER FUNCTIONS // ================ var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g function base64clean (str) { // Node strips out invalid characters like \n and \t from the string, base64-js does not str = stringtrim(str).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 stringtrim (str) { if (str.trim) return str.trim() return str.replace(/^\s+|\s+$/g, '') } function toHex (n) { if (n < 16) return '0' + n.toString(16) return n.toString(16) } function utf8ToBytes (string, units) { units = units || Infinity var codePoint var length = string.length var leadSurrogate = null var bytes = [] for (var 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) { var byteArray = [] for (var 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) { var c, hi, lo var byteArray = [] for (var 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) { for (var i = 0; i < length; ++i) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } return i } function isnan (val) { return val !== val // eslint-disable-line no-self-compare } /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ "./gulp/node_modules/webpack/buildin/global.js"))) /***/ }), /***/ "./gulp/node_modules/webpack/buildin/global.js": /*!***********************************!*\ !*** (webpack)/buildin/global.js ***! \***********************************/ /*! no static exports found */ /***/ (function(module, exports) { var g; // This works in non-strict mode g = (function() { return this; })(); try { // This works if eval is allowed (see CSP) g = g || new Function("return this")(); } catch (e) { // This works if the window reference is available if (typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /***/ "./node_modules/ajv/lib/ajv.js": /*!*************************************!*\ !*** ./node_modules/ajv/lib/ajv.js ***! \*************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var compileSchema = __webpack_require__(/*! ./compile */ "./node_modules/ajv/lib/compile/index.js") , resolve = __webpack_require__(/*! ./compile/resolve */ "./node_modules/ajv/lib/compile/resolve.js") , Cache = __webpack_require__(/*! ./cache */ "./node_modules/ajv/lib/cache.js") , SchemaObject = __webpack_require__(/*! ./compile/schema_obj */ "./node_modules/ajv/lib/compile/schema_obj.js") , stableStringify = __webpack_require__(/*! fast-json-stable-stringify */ "./node_modules/fast-json-stable-stringify/index.js") , formats = __webpack_require__(/*! ./compile/formats */ "./node_modules/ajv/lib/compile/formats.js") , rules = __webpack_require__(/*! ./compile/rules */ "./node_modules/ajv/lib/compile/rules.js") , $dataMetaSchema = __webpack_require__(/*! ./data */ "./node_modules/ajv/lib/data.js") , util = __webpack_require__(/*! ./compile/util */ "./node_modules/ajv/lib/compile/util.js"); module.exports = Ajv; Ajv.prototype.validate = validate; Ajv.prototype.compile = compile; Ajv.prototype.addSchema = addSchema; Ajv.prototype.addMetaSchema = addMetaSchema; Ajv.prototype.validateSchema = validateSchema; Ajv.prototype.getSchema = getSchema; Ajv.prototype.removeSchema = removeSchema; Ajv.prototype.addFormat = addFormat; Ajv.prototype.errorsText = errorsText; Ajv.prototype._addSchema = _addSchema; Ajv.prototype._compile = _compile; Ajv.prototype.compileAsync = __webpack_require__(/*! ./compile/async */ "./node_modules/ajv/lib/compile/async.js"); var customKeyword = __webpack_require__(/*! ./keyword */ "./node_modules/ajv/lib/keyword.js"); Ajv.prototype.addKeyword = customKeyword.add; Ajv.prototype.getKeyword = customKeyword.get; Ajv.prototype.removeKeyword = customKeyword.remove; Ajv.prototype.validateKeyword = customKeyword.validate; var errorClasses = __webpack_require__(/*! ./compile/error_classes */ "./node_modules/ajv/lib/compile/error_classes.js"); Ajv.ValidationError = errorClasses.Validation; Ajv.MissingRefError = errorClasses.MissingRef; Ajv.$dataMetaSchema = $dataMetaSchema; var META_SCHEMA_ID = 'http://json-schema.org/draft-07/schema'; var META_IGNORE_OPTIONS = [ 'removeAdditional', 'useDefaults', 'coerceTypes', 'strictDefaults' ]; var META_SUPPORT_DATA = ['/properties']; /** * Creates validator instance. * Usage: `Ajv(opts)` * @param {Object} opts optional options * @return {Object} ajv instance */ function Ajv(opts) { if (!(this instanceof Ajv)) return new Ajv(opts); opts = this._opts = util.copy(opts) || {}; setLogger(this); this._schemas = {}; this._refs = {}; this._fragments = {}; this._formats = formats(opts.format); this._cache = opts.cache || new Cache; this._loadingSchemas = {}; this._compilations = []; this.RULES = rules(); this._getId = chooseGetId(opts); opts.loopRequired = opts.loopRequired || Infinity; if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true; if (opts.serialize === undefined) opts.serialize = stableStringify; this._metaOpts = getMetaSchemaOptions(this); if (opts.formats) addInitialFormats(this); if (opts.keywords) addInitialKeywords(this); addDefaultMetaSchema(this); if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta); if (opts.nullable) this.addKeyword('nullable', {metaSchema: {type: 'boolean'}}); addInitialSchemas(this); } /** * Validate data using schema * Schema will be compiled and cached (using serialized JSON as key. [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used to serialize. * @this Ajv * @param {String|Object} schemaKeyRef key, ref or schema object * @param {Any} data to be validated * @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`). */ function validate(schemaKeyRef, data) { var v; if (typeof schemaKeyRef == 'string') { v = this.getSchema(schemaKeyRef); if (!v) throw new Error('no schema with key or ref "' + schemaKeyRef + '"'); } else { var schemaObj = this._addSchema(schemaKeyRef); v = schemaObj.validate || this._compile(schemaObj); } var valid = v(data); if (v.$async !== true) this.errors = v.errors; return valid; } /** * Create validating function for passed schema. * @this Ajv * @param {Object} schema schema object * @param {Boolean} _meta true if schema is a meta-schema. Used internally to compile meta schemas of custom keywords. * @return {Function} validating function */ function compile(schema, _meta) { var schemaObj = this._addSchema(schema, undefined, _meta); return schemaObj.validate || this._compile(schemaObj); } /** * Adds schema to the instance. * @this Ajv * @param {Object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored. * @param {String} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`. * @param {Boolean} _skipValidation true to skip schema validation. Used internally, option validateSchema should be used instead. * @param {Boolean} _meta true if schema is a meta-schema. Used internally, addMetaSchema should be used instead. * @return {Ajv} this for method chaining */ function addSchema(schema, key, _skipValidation, _meta) { if (Array.isArray(schema)){ for (var i=0; i} errors optional array of validation errors, if not passed errors from the instance are used. * @param {Object} options optional options with properties `separator` and `dataVar`. * @return {String} human readable string with all errors descriptions */ function errorsText(errors, options) { errors = errors || this.errors; if (!errors) return 'No errors'; options = options || {}; var separator = options.separator === undefined ? ', ' : options.separator; var dataVar = options.dataVar === undefined ? 'data' : options.dataVar; var text = ''; for (var i=0; i%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i; // For the source: https://gist.github.com/dperini/729294 // For test cases: https://mathiasbynens.be/demo/url-regex // @todo Delete current URL in favour of the commented out URL rule when this issue is fixed https://github.com/eslint/eslint/issues/7983. // var URL = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu; var URL = /^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i; var UUID = /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i; var JSON_POINTER = /^(?:\/(?:[^~/]|~0|~1)*)*$/; var JSON_POINTER_URI_FRAGMENT = /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i; var RELATIVE_JSON_POINTER = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/; module.exports = formats; function formats(mode) { mode = mode == 'full' ? 'full' : 'fast'; return util.copy(formats[mode]); } formats.fast = { // date: http://tools.ietf.org/html/rfc3339#section-5.6 date: /^\d\d\d\d-[0-1]\d-[0-3]\d$/, // date-time: http://tools.ietf.org/html/rfc3339#section-5.6 time: /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i, 'date-time': /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i, // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js uri: /^(?:[a-z][a-z0-9+-.]*:)(?:\/?\/)?[^\s]*$/i, 'uri-reference': /^(?:(?:[a-z][a-z0-9+-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i, 'uri-template': URITEMPLATE, url: URL, // email (sources from jsen validator): // http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363 // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'willful violation') email: /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i, hostname: HOSTNAME, // optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, // optimized http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i, regex: regex, // uuid: http://tools.ietf.org/html/rfc4122 uuid: UUID, // JSON-pointer: https://tools.ietf.org/html/rfc6901 // uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A 'json-pointer': JSON_POINTER, 'json-pointer-uri-fragment': JSON_POINTER_URI_FRAGMENT, // relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00 'relative-json-pointer': RELATIVE_JSON_POINTER }; formats.full = { date: date, time: time, 'date-time': date_time, uri: uri, 'uri-reference': URIREF, 'uri-template': URITEMPLATE, url: URL, email: /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i, hostname: HOSTNAME, ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i, regex: regex, uuid: UUID, 'json-pointer': JSON_POINTER, 'json-pointer-uri-fragment': JSON_POINTER_URI_FRAGMENT, 'relative-json-pointer': RELATIVE_JSON_POINTER }; function isLeapYear(year) { // https://tools.ietf.org/html/rfc3339#appendix-C return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); } function date(str) { // full-date from http://tools.ietf.org/html/rfc3339#section-5.6 var matches = str.match(DATE); if (!matches) return false; var year = +matches[1]; var month = +matches[2]; var day = +matches[3]; return month >= 1 && month <= 12 && day >= 1 && day <= (month == 2 && isLeapYear(year) ? 29 : DAYS[month]); } function time(str, full) { var matches = str.match(TIME); if (!matches) return false; var hour = matches[1]; var minute = matches[2]; var second = matches[3]; var timeZone = matches[5]; return ((hour <= 23 && minute <= 59 && second <= 59) || (hour == 23 && minute == 59 && second == 60)) && (!full || timeZone); } var DATE_TIME_SEPARATOR = /t|\s/i; function date_time(str) { // http://tools.ietf.org/html/rfc3339#section-5.6 var dateTime = str.split(DATE_TIME_SEPARATOR); return dateTime.length == 2 && date(dateTime[0]) && time(dateTime[1], true); } var NOT_URI_FRAGMENT = /\/|:/; function uri(str) { // http://jmrware.com/articles/2009/uri_regexp/URI_regex.html + optional protocol + required "." return NOT_URI_FRAGMENT.test(str) && URI.test(str); } var Z_ANCHOR = /[^\\]\\Z/; function regex(str) { if (Z_ANCHOR.test(str)) return false; try { new RegExp(str); return true; } catch(e) { return false; } } /***/ }), /***/ "./node_modules/ajv/lib/compile/index.js": /*!***********************************************!*\ !*** ./node_modules/ajv/lib/compile/index.js ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var resolve = __webpack_require__(/*! ./resolve */ "./node_modules/ajv/lib/compile/resolve.js") , util = __webpack_require__(/*! ./util */ "./node_modules/ajv/lib/compile/util.js") , errorClasses = __webpack_require__(/*! ./error_classes */ "./node_modules/ajv/lib/compile/error_classes.js") , stableStringify = __webpack_require__(/*! fast-json-stable-stringify */ "./node_modules/fast-json-stable-stringify/index.js"); var validateGenerator = __webpack_require__(/*! ../dotjs/validate */ "./node_modules/ajv/lib/dotjs/validate.js"); /** * Functions below are used inside compiled validations function */ var ucs2length = util.ucs2length; var equal = __webpack_require__(/*! fast-deep-equal */ "./node_modules/fast-deep-equal/index.js"); // this error is thrown by async schemas to return validation errors via exception var ValidationError = errorClasses.Validation; module.exports = compile; /** * Compiles schema to validation function * @this Ajv * @param {Object} schema schema object * @param {Object} root object with information about the root schema for this schema * @param {Object} localRefs the hash of local references inside the schema (created by resolve.id), used for inline resolution * @param {String} baseId base ID for IDs in the schema * @return {Function} validation function */ function compile(schema, root, localRefs, baseId) { /* jshint validthis: true, evil: true */ /* eslint no-shadow: 0 */ var self = this , opts = this._opts , refVal = [ undefined ] , refs = {} , patterns = [] , patternsHash = {} , defaults = [] , defaultsHash = {} , customRules = []; root = root || { schema: schema, refVal: refVal, refs: refs }; var c = checkCompiling.call(this, schema, root, baseId); var compilation = this._compilations[c.index]; if (c.compiling) return (compilation.callValidate = callValidate); var formats = this._formats; var RULES = this.RULES; try { var v = localCompile(schema, root, localRefs, baseId); compilation.validate = v; var cv = compilation.callValidate; if (cv) { cv.schema = v.schema; cv.errors = null; cv.refs = v.refs; cv.refVal = v.refVal; cv.root = v.root; cv.$async = v.$async; if (opts.sourceCode) cv.source = v.source; } return v; } finally { endCompiling.call(this, schema, root, baseId); } /* @this {*} - custom context, see passContext option */ function callValidate() { /* jshint validthis: true */ var validate = compilation.validate; var result = validate.apply(this, arguments); callValidate.errors = validate.errors; return result; } function localCompile(_schema, _root, localRefs, baseId) { var isRoot = !_root || (_root && _root.schema == _schema); if (_root.schema != root.schema) return compile.call(self, _schema, _root, localRefs, baseId); var $async = _schema.$async === true; var sourceCode = validateGenerator({ isTop: true, schema: _schema, isRoot: isRoot, baseId: baseId, root: _root, schemaPath: '', errSchemaPath: '#', errorPath: '""', MissingRefError: errorClasses.MissingRef, RULES: RULES, validate: validateGenerator, util: util, resolve: resolve, resolveRef: resolveRef, usePattern: usePattern, useDefault: useDefault, useCustomRule: useCustomRule, opts: opts, formats: formats, logger: self.logger, self: self }); sourceCode = vars(refVal, refValCode) + vars(patterns, patternCode) + vars(defaults, defaultCode) + vars(customRules, customRuleCode) + sourceCode; if (opts.processCode) sourceCode = opts.processCode(sourceCode); // console.log('\n\n\n *** \n', JSON.stringify(sourceCode)); var validate; try { var makeValidate = new Function( 'self', 'RULES', 'formats', 'root', 'refVal', 'defaults', 'customRules', 'equal', 'ucs2length', 'ValidationError', sourceCode ); validate = makeValidate( self, RULES, formats, root, refVal, defaults, customRules, equal, ucs2length, ValidationError ); refVal[0] = validate; } catch(e) { self.logger.error('Error compiling schema, function code:', sourceCode); throw e; } validate.schema = _schema; validate.errors = null; validate.refs = refs; validate.refVal = refVal; validate.root = isRoot ? validate : _root; if ($async) validate.$async = true; if (opts.sourceCode === true) { validate.source = { code: sourceCode, patterns: patterns, defaults: defaults }; } return validate; } function resolveRef(baseId, ref, isRoot) { ref = resolve.url(baseId, ref); var refIndex = refs[ref]; var _refVal, refCode; if (refIndex !== undefined) { _refVal = refVal[refIndex]; refCode = 'refVal[' + refIndex + ']'; return resolvedRef(_refVal, refCode); } if (!isRoot && root.refs) { var rootRefId = root.refs[ref]; if (rootRefId !== undefined) { _refVal = root.refVal[rootRefId]; refCode = addLocalRef(ref, _refVal); return resolvedRef(_refVal, refCode); } } refCode = addLocalRef(ref); var v = resolve.call(self, localCompile, root, ref); if (v === undefined) { var localSchema = localRefs && localRefs[ref]; if (localSchema) { v = resolve.inlineRef(localSchema, opts.inlineRefs) ? localSchema : compile.call(self, localSchema, root, localRefs, baseId); } } if (v === undefined) { removeLocalRef(ref); } else { replaceLocalRef(ref, v); return resolvedRef(v, refCode); } } function addLocalRef(ref, v) { var refId = refVal.length; refVal[refId] = v; refs[ref] = refId; return 'refVal' + refId; } function removeLocalRef(ref) { delete refs[ref]; } function replaceLocalRef(ref, v) { var refId = refs[ref]; refVal[refId] = v; } function resolvedRef(refVal, code) { return typeof refVal == 'object' || typeof refVal == 'boolean' ? { code: code, schema: refVal, inline: true } : { code: code, $async: refVal && !!refVal.$async }; } function usePattern(regexStr) { var index = patternsHash[regexStr]; if (index === undefined) { index = patternsHash[regexStr] = patterns.length; patterns[index] = regexStr; } return 'pattern' + index; } function useDefault(value) { switch (typeof value) { case 'boolean': case 'number': return '' + value; case 'string': return util.toQuotedString(value); case 'object': if (value === null) return 'null'; var valueStr = stableStringify(value); var index = defaultsHash[valueStr]; if (index === undefined) { index = defaultsHash[valueStr] = defaults.length; defaults[index] = value; } return 'default' + index; } } function useCustomRule(rule, schema, parentSchema, it) { if (self._opts.validateSchema !== false) { var deps = rule.definition.dependencies; if (deps && !deps.every(function(keyword) { return Object.prototype.hasOwnProperty.call(parentSchema, keyword); })) throw new Error('parent schema must have all required keywords: ' + deps.join(',')); var validateSchema = rule.definition.validateSchema; if (validateSchema) { var valid = validateSchema(schema); if (!valid) { var message = 'keyword schema is invalid: ' + self.errorsText(validateSchema.errors); if (self._opts.validateSchema == 'log') self.logger.error(message); else throw new Error(message); } } } var compile = rule.definition.compile , inline = rule.definition.inline , macro = rule.definition.macro; var validate; if (compile) { validate = compile.call(self, schema, parentSchema, it); } else if (macro) { validate = macro.call(self, schema, parentSchema, it); if (opts.validateSchema !== false) self.validateSchema(validate, true); } else if (inline) { validate = inline.call(self, it, rule.keyword, schema, parentSchema); } else { validate = rule.definition.validate; if (!validate) return; } if (validate === undefined) throw new Error('custom keyword "' + rule.keyword + '"failed to compile'); var index = customRules.length; customRules[index] = validate; return { code: 'customRule' + index, validate: validate }; } } /** * Checks if the schema is currently compiled * @this Ajv * @param {Object} schema schema to compile * @param {Object} root root object * @param {String} baseId base schema ID * @return {Object} object with properties "index" (compilation index) and "compiling" (boolean) */ function checkCompiling(schema, root, baseId) { /* jshint validthis: true */ var index = compIndex.call(this, schema, root, baseId); if (index >= 0) return { index: index, compiling: true }; index = this._compilations.length; this._compilations[index] = { schema: schema, root: root, baseId: baseId }; return { index: index, compiling: false }; } /** * Removes the schema from the currently compiled list * @this Ajv * @param {Object} schema schema to compile * @param {Object} root root object * @param {String} baseId base schema ID */ function endCompiling(schema, root, baseId) { /* jshint validthis: true */ var i = compIndex.call(this, schema, root, baseId); if (i >= 0) this._compilations.splice(i, 1); } /** * Index of schema compilation in the currently compiled list * @this Ajv * @param {Object} schema schema to compile * @param {Object} root root object * @param {String} baseId base schema ID * @return {Integer} compilation index */ function compIndex(schema, root, baseId) { /* jshint validthis: true */ for (var i=0; i= 0xD800 && value <= 0xDBFF && pos < len) { // high surrogate, and there is a next character value = str.charCodeAt(pos); if ((value & 0xFC00) == 0xDC00) pos++; // low surrogate } } return length; }; /***/ }), /***/ "./node_modules/ajv/lib/compile/util.js": /*!**********************************************!*\ !*** ./node_modules/ajv/lib/compile/util.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = { copy: copy, checkDataType: checkDataType, checkDataTypes: checkDataTypes, coerceToTypes: coerceToTypes, toHash: toHash, getProperty: getProperty, escapeQuotes: escapeQuotes, equal: __webpack_require__(/*! fast-deep-equal */ "./node_modules/fast-deep-equal/index.js"), ucs2length: __webpack_require__(/*! ./ucs2length */ "./node_modules/ajv/lib/compile/ucs2length.js"), varOccurences: varOccurences, varReplace: varReplace, cleanUpCode: cleanUpCode, finalCleanUpCode: finalCleanUpCode, schemaHasRules: schemaHasRules, schemaHasRulesExcept: schemaHasRulesExcept, schemaUnknownRules: schemaUnknownRules, toQuotedString: toQuotedString, getPathExpr: getPathExpr, getPath: getPath, getData: getData, unescapeFragment: unescapeFragment, unescapeJsonPointer: unescapeJsonPointer, escapeFragment: escapeFragment, escapeJsonPointer: escapeJsonPointer }; function copy(o, to) { to = to || {}; for (var key in o) to[key] = o[key]; return to; } function checkDataType(dataType, data, negate) { var EQUAL = negate ? ' !== ' : ' === ' , AND = negate ? ' || ' : ' && ' , OK = negate ? '!' : '' , NOT = negate ? '' : '!'; switch (dataType) { case 'null': return data + EQUAL + 'null'; case 'array': return OK + 'Array.isArray(' + data + ')'; case 'object': return '(' + OK + data + AND + 'typeof ' + data + EQUAL + '"object"' + AND + NOT + 'Array.isArray(' + data + '))'; case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND + NOT + '(' + data + ' % 1)' + AND + data + EQUAL + data + ')'; default: return 'typeof ' + data + EQUAL + '"' + dataType + '"'; } } function checkDataTypes(dataTypes, data) { switch (dataTypes.length) { case 1: return checkDataType(dataTypes[0], data, true); default: var code = ''; var types = toHash(dataTypes); if (types.array && types.object) { code = types.null ? '(': '(!' + data + ' || '; code += 'typeof ' + data + ' !== "object")'; delete types.null; delete types.array; delete types.object; } if (types.number) delete types.integer; for (var t in types) code += (code ? ' && ' : '' ) + checkDataType(t, data, true); return code; } } var COERCE_TO_TYPES = toHash([ 'string', 'number', 'integer', 'boolean', 'null' ]); function coerceToTypes(optionCoerceTypes, dataTypes) { if (Array.isArray(dataTypes)) { var types = []; for (var i=0; i= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl); return paths[lvl - up]; } if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl); data = 'data' + ((lvl - up) || ''); if (!jsonPointer) return data; } var expr = data; var segments = jsonPointer.split('/'); for (var i=0; i', $notOp = $isMax ? '>' : '<', $errorKeyword = undefined; if ($isDataExcl) { var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr), $exclusive = 'exclusive' + $lvl, $exclType = 'exclType' + $lvl, $exclIsNumber = 'exclIsNumber' + $lvl, $opExpr = 'op' + $lvl, $opStr = '\' + ' + $opExpr + ' + \''; out += ' var schemaExcl' + ($lvl) + ' = ' + ($schemaValueExcl) + '; '; $schemaValueExcl = 'schemaExcl' + $lvl; out += ' var ' + ($exclusive) + '; var ' + ($exclType) + ' = typeof ' + ($schemaValueExcl) + '; if (' + ($exclType) + ' != \'boolean\' && ' + ($exclType) + ' != \'undefined\' && ' + ($exclType) + ' != \'number\') { '; var $errorKeyword = $exclusiveKeyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_exclusiveLimit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'' + ($exclusiveKeyword) + ' should be boolean\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ' + ($exclType) + ' == \'number\' ? ( (' + ($exclusive) + ' = ' + ($schemaValue) + ' === undefined || ' + ($schemaValueExcl) + ' ' + ($op) + '= ' + ($schemaValue) + ') ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValueExcl) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) : ( (' + ($exclusive) + ' = ' + ($schemaValueExcl) + ' === true) ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValue) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) || ' + ($data) + ' !== ' + ($data) + ') { var op' + ($lvl) + ' = ' + ($exclusive) + ' ? \'' + ($op) + '\' : \'' + ($op) + '=\'; '; if ($schema === undefined) { $errorKeyword = $exclusiveKeyword; $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword; $schemaValue = $schemaValueExcl; $isData = $isDataExcl; } } else { var $exclIsNumber = typeof $schemaExcl == 'number', $opStr = $op; if ($exclIsNumber && $isData) { var $opExpr = '\'' + $opStr + '\''; out += ' if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ( ' + ($schemaValue) + ' === undefined || ' + ($schemaExcl) + ' ' + ($op) + '= ' + ($schemaValue) + ' ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaExcl) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) || ' + ($data) + ' !== ' + ($data) + ') { '; } else { if ($exclIsNumber && $schema === undefined) { $exclusive = true; $errorKeyword = $exclusiveKeyword; $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword; $schemaValue = $schemaExcl; $notOp += '='; } else { if ($exclIsNumber) $schemaValue = Math[$isMax ? 'min' : 'max']($schemaExcl, $schema); if ($schemaExcl === ($exclIsNumber ? $schemaValue : true)) { $exclusive = true; $errorKeyword = $exclusiveKeyword; $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword; $notOp += '='; } else { $exclusive = false; $opStr += '='; } } var $opExpr = '\'' + $opStr + '\''; out += ' if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' || ' + ($data) + ' !== ' + ($data) + ') { '; } } $errorKeyword = $errorKeyword || $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { comparison: ' + ($opExpr) + ', limit: ' + ($schemaValue) + ', exclusive: ' + ($exclusive) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be ' + ($opStr) + ' '; if ($isData) { out += '\' + ' + ($schemaValue); } else { out += '' + ($schemaValue) + '\''; } } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/_limitItems.js": /*!***************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/_limitItems.js ***! \***************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate__limitItems(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $op = $keyword == 'maxItems' ? '>' : '<'; out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ' + ($data) + '.length ' + ($op) + ' ' + ($schemaValue) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limitItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have '; if ($keyword == 'maxItems') { out += 'more'; } else { out += 'fewer'; } out += ' than '; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + ($schema); } out += ' items\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/_limitLength.js": /*!****************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/_limitLength.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate__limitLength(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $op = $keyword == 'maxLength' ? '>' : '<'; out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } if (it.opts.unicode === false) { out += ' ' + ($data) + '.length '; } else { out += ' ucs2length(' + ($data) + ') '; } out += ' ' + ($op) + ' ' + ($schemaValue) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limitLength') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT be '; if ($keyword == 'maxLength') { out += 'longer'; } else { out += 'shorter'; } out += ' than '; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + ($schema); } out += ' characters\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/_limitProperties.js": /*!********************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/_limitProperties.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate__limitProperties(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $op = $keyword == 'maxProperties' ? '>' : '<'; out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' Object.keys(' + ($data) + ').length ' + ($op) + ' ' + ($schemaValue) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limitProperties') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have '; if ($keyword == 'maxProperties') { out += 'more'; } else { out += 'fewer'; } out += ' than '; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + ($schema); } out += ' properties\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/allOf.js": /*!*********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/allOf.js ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_allOf(it, $keyword, $ruleType) { var out = ' '; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $currentBaseId = $it.baseId, $allSchemasEmpty = true; var arr1 = $schema; if (arr1) { var $sch, $i = -1, l1 = arr1.length - 1; while ($i < l1) { $sch = arr1[$i += 1]; if ((it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 0 : it.util.schemaHasRules($sch, it.RULES.all))) { $allSchemasEmpty = false; $it.schema = $sch; $it.schemaPath = $schemaPath + '[' + $i + ']'; $it.errSchemaPath = $errSchemaPath + '/' + $i; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } if ($breakOnError) { if ($allSchemasEmpty) { out += ' if (true) { '; } else { out += ' ' + ($closingBraces.slice(0, -1)) + ' '; } } out = it.util.cleanUpCode(out); return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/anyOf.js": /*!*********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/anyOf.js ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_anyOf(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $noEmptySchema = $schema.every(function($sch) { return (it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 0 : it.util.schemaHasRules($sch, it.RULES.all)); }); if ($noEmptySchema) { var $currentBaseId = $it.baseId; out += ' var ' + ($errs) + ' = errors; var ' + ($valid) + ' = false; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; var arr1 = $schema; if (arr1) { var $sch, $i = -1, l1 = arr1.length - 1; while ($i < l1) { $sch = arr1[$i += 1]; $it.schema = $sch; $it.schemaPath = $schemaPath + '[' + $i + ']'; $it.errSchemaPath = $errSchemaPath + '/' + $i; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; out += ' ' + ($valid) + ' = ' + ($valid) + ' || ' + ($nextValid) + '; if (!' + ($valid) + ') { '; $closingBraces += '}'; } } it.compositeRule = $it.compositeRule = $wasComposite; out += ' ' + ($closingBraces) + ' if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('anyOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should match some schema in anyOf\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError(vErrors); '; } else { out += ' validate.errors = vErrors; return false; '; } } out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; if (it.opts.allErrors) { out += ' } '; } out = it.util.cleanUpCode(out); } else { if ($breakOnError) { out += ' if (true) { '; } } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/comment.js": /*!***********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/comment.js ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_comment(it, $keyword, $ruleType) { var out = ' '; var $schema = it.schema[$keyword]; var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $comment = it.util.toQuotedString($schema); if (it.opts.$comment === true) { out += ' console.log(' + ($comment) + ');'; } else if (typeof it.opts.$comment == 'function') { out += ' self._opts.$comment(' + ($comment) + ', ' + (it.util.toQuotedString($errSchemaPath)) + ', validate.root.schema);'; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/const.js": /*!*********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/const.js ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_const(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } if (!$isData) { out += ' var schema' + ($lvl) + ' = validate.schema' + ($schemaPath) + ';'; } out += 'var ' + ($valid) + ' = equal(' + ($data) + ', schema' + ($lvl) + '); if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('const') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { allowedValue: schema' + ($lvl) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be equal to constant\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' }'; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/contains.js": /*!************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/contains.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_contains(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $idx = 'i' + $lvl, $dataNxt = $it.dataLevel = it.dataLevel + 1, $nextData = 'data' + $dataNxt, $currentBaseId = it.baseId, $nonEmptySchema = (it.opts.strictKeywords ? typeof $schema == 'object' && Object.keys($schema).length > 0 : it.util.schemaHasRules($schema, it.RULES.all)); out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';'; if ($nonEmptySchema) { var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; out += ' var ' + ($nextValid) + ' = false; for (var ' + ($idx) + ' = 0; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); var $passData = $data + '[' + $idx + ']'; $it.dataPathArr[$dataNxt] = $idx; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } out += ' if (' + ($nextValid) + ') break; } '; it.compositeRule = $it.compositeRule = $wasComposite; out += ' ' + ($closingBraces) + ' if (!' + ($nextValid) + ') {'; } else { out += ' if (' + ($data) + '.length == 0) {'; } var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('contains') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should contain a valid item\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { '; if ($nonEmptySchema) { out += ' errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; } if (it.opts.allErrors) { out += ' } '; } out = it.util.cleanUpCode(out); return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/custom.js": /*!**********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/custom.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_custom(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $rule = this, $definition = 'definition' + $lvl, $rDef = $rule.definition, $closingBraces = ''; var $compile, $inline, $macro, $ruleValidate, $validateCode; if ($isData && $rDef.$data) { $validateCode = 'keywordValidate' + $lvl; var $validateSchema = $rDef.validateSchema; out += ' var ' + ($definition) + ' = RULES.custom[\'' + ($keyword) + '\'].definition; var ' + ($validateCode) + ' = ' + ($definition) + '.validate;'; } else { $ruleValidate = it.useCustomRule($rule, $schema, it.schema, it); if (!$ruleValidate) return; $schemaValue = 'validate.schema' + $schemaPath; $validateCode = $ruleValidate.code; $compile = $rDef.compile; $inline = $rDef.inline; $macro = $rDef.macro; } var $ruleErrs = $validateCode + '.errors', $i = 'i' + $lvl, $ruleErr = 'ruleErr' + $lvl, $asyncKeyword = $rDef.async; if ($asyncKeyword && !it.async) throw new Error('async keyword in sync schema'); if (!($inline || $macro)) { out += '' + ($ruleErrs) + ' = null;'; } out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';'; if ($isData && $rDef.$data) { $closingBraces += '}'; out += ' if (' + ($schemaValue) + ' === undefined) { ' + ($valid) + ' = true; } else { '; if ($validateSchema) { $closingBraces += '}'; out += ' ' + ($valid) + ' = ' + ($definition) + '.validateSchema(' + ($schemaValue) + '); if (' + ($valid) + ') { '; } } if ($inline) { if ($rDef.statements) { out += ' ' + ($ruleValidate.validate) + ' '; } else { out += ' ' + ($valid) + ' = ' + ($ruleValidate.validate) + '; '; } } else if ($macro) { var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; $it.schema = $ruleValidate.validate; $it.schemaPath = ''; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; var $code = it.validate($it).replace(/validate\.schema/g, $validateCode); it.compositeRule = $it.compositeRule = $wasComposite; out += ' ' + ($code); } else { var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; out += ' ' + ($validateCode) + '.call( '; if (it.opts.passContext) { out += 'this'; } else { out += 'self'; } if ($compile || $rDef.schema === false) { out += ' , ' + ($data) + ' '; } else { out += ' , ' + ($schemaValue) + ' , ' + ($data) + ' , validate.schema' + (it.schemaPath) + ' '; } out += ' , (dataPath || \'\')'; if (it.errorPath != '""') { out += ' + ' + (it.errorPath); } var $parentData = $dataLvl ? 'data' + (($dataLvl - 1) || '') : 'parentData', $parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty'; out += ' , ' + ($parentData) + ' , ' + ($parentDataProperty) + ' , rootData ) '; var def_callRuleValidate = out; out = $$outStack.pop(); if ($rDef.errors === false) { out += ' ' + ($valid) + ' = '; if ($asyncKeyword) { out += 'await '; } out += '' + (def_callRuleValidate) + '; '; } else { if ($asyncKeyword) { $ruleErrs = 'customErrors' + $lvl; out += ' var ' + ($ruleErrs) + ' = null; try { ' + ($valid) + ' = await ' + (def_callRuleValidate) + '; } catch (e) { ' + ($valid) + ' = false; if (e instanceof ValidationError) ' + ($ruleErrs) + ' = e.errors; else throw e; } '; } else { out += ' ' + ($ruleErrs) + ' = null; ' + ($valid) + ' = ' + (def_callRuleValidate) + '; '; } } } if ($rDef.modifying) { out += ' if (' + ($parentData) + ') ' + ($data) + ' = ' + ($parentData) + '[' + ($parentDataProperty) + '];'; } out += '' + ($closingBraces); if ($rDef.valid) { if ($breakOnError) { out += ' if (true) { '; } } else { out += ' if ( '; if ($rDef.valid === undefined) { out += ' !'; if ($macro) { out += '' + ($nextValid); } else { out += '' + ($valid); } } else { out += ' ' + (!$rDef.valid) + ' '; } out += ') { '; $errorKeyword = $rule.keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'custom') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { keyword: \'' + ($rule.keyword) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should pass "' + ($rule.keyword) + '" keyword validation\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } var def_customError = out; out = $$outStack.pop(); if ($inline) { if ($rDef.errors) { if ($rDef.errors != 'full') { out += ' for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + ' 0 : it.util.schemaHasRules($sch, it.RULES.all))) { out += ' ' + ($nextValid) + ' = true; if ( ' + ($data) + (it.util.getProperty($property)) + ' !== undefined '; if ($ownProperties) { out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($property)) + '\') '; } out += ') { '; $it.schema = $sch; $it.schemaPath = $schemaPath + it.util.getProperty($property); $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($property); out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } if ($breakOnError) { out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; } out = it.util.cleanUpCode(out); return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/enum.js": /*!********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/enum.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_enum(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $i = 'i' + $lvl, $vSchema = 'schema' + $lvl; if (!$isData) { out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + ';'; } out += 'var ' + ($valid) + ';'; if ($isData) { out += ' if (schema' + ($lvl) + ' === undefined) ' + ($valid) + ' = true; else if (!Array.isArray(schema' + ($lvl) + ')) ' + ($valid) + ' = false; else {'; } out += '' + ($valid) + ' = false;for (var ' + ($i) + '=0; ' + ($i) + '<' + ($vSchema) + '.length; ' + ($i) + '++) if (equal(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + '])) { ' + ($valid) + ' = true; break; }'; if ($isData) { out += ' } '; } out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('enum') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { allowedValues: schema' + ($lvl) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be equal to one of the allowed values\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' }'; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/format.js": /*!**********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/format.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_format(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); if (it.opts.format === false) { if ($breakOnError) { out += ' if (true) { '; } return out; } var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $unknownFormats = it.opts.unknownFormats, $allowUnknown = Array.isArray($unknownFormats); if ($isData) { var $format = 'format' + $lvl, $isObject = 'isObject' + $lvl, $formatType = 'formatType' + $lvl; out += ' var ' + ($format) + ' = formats[' + ($schemaValue) + ']; var ' + ($isObject) + ' = typeof ' + ($format) + ' == \'object\' && !(' + ($format) + ' instanceof RegExp) && ' + ($format) + '.validate; var ' + ($formatType) + ' = ' + ($isObject) + ' && ' + ($format) + '.type || \'string\'; if (' + ($isObject) + ') { '; if (it.async) { out += ' var async' + ($lvl) + ' = ' + ($format) + '.async; '; } out += ' ' + ($format) + ' = ' + ($format) + '.validate; } if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || '; } out += ' ('; if ($unknownFormats != 'ignore') { out += ' (' + ($schemaValue) + ' && !' + ($format) + ' '; if ($allowUnknown) { out += ' && self._opts.unknownFormats.indexOf(' + ($schemaValue) + ') == -1 '; } out += ') || '; } out += ' (' + ($format) + ' && ' + ($formatType) + ' == \'' + ($ruleType) + '\' && !(typeof ' + ($format) + ' == \'function\' ? '; if (it.async) { out += ' (async' + ($lvl) + ' ? await ' + ($format) + '(' + ($data) + ') : ' + ($format) + '(' + ($data) + ')) '; } else { out += ' ' + ($format) + '(' + ($data) + ') '; } out += ' : ' + ($format) + '.test(' + ($data) + '))))) {'; } else { var $format = it.formats[$schema]; if (!$format) { if ($unknownFormats == 'ignore') { it.logger.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"'); if ($breakOnError) { out += ' if (true) { '; } return out; } else if ($allowUnknown && $unknownFormats.indexOf($schema) >= 0) { if ($breakOnError) { out += ' if (true) { '; } return out; } else { throw new Error('unknown format "' + $schema + '" is used in schema at path "' + it.errSchemaPath + '"'); } } var $isObject = typeof $format == 'object' && !($format instanceof RegExp) && $format.validate; var $formatType = $isObject && $format.type || 'string'; if ($isObject) { var $async = $format.async === true; $format = $format.validate; } if ($formatType != $ruleType) { if ($breakOnError) { out += ' if (true) { '; } return out; } if ($async) { if (!it.async) throw new Error('async format in sync schema'); var $formatRef = 'formats' + it.util.getProperty($schema) + '.validate'; out += ' if (!(await ' + ($formatRef) + '(' + ($data) + '))) { '; } else { out += ' if (! '; var $formatRef = 'formats' + it.util.getProperty($schema); if ($isObject) $formatRef += '.validate'; if (typeof $format == 'function') { out += ' ' + ($formatRef) + '(' + ($data) + ') '; } else { out += ' ' + ($formatRef) + '.test(' + ($data) + ') '; } out += ') { '; } } var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('format') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { format: '; if ($isData) { out += '' + ($schemaValue); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' } '; if (it.opts.messages !== false) { out += ' , message: \'should match format "'; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + (it.util.escapeQuotes($schema)); } out += '"\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/if.js": /*!******************************************!*\ !*** ./node_modules/ajv/lib/dotjs/if.js ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_if(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); $it.level++; var $nextValid = 'valid' + $it.level; var $thenSch = it.schema['then'], $elseSch = it.schema['else'], $thenPresent = $thenSch !== undefined && (it.opts.strictKeywords ? typeof $thenSch == 'object' && Object.keys($thenSch).length > 0 : it.util.schemaHasRules($thenSch, it.RULES.all)), $elsePresent = $elseSch !== undefined && (it.opts.strictKeywords ? typeof $elseSch == 'object' && Object.keys($elseSch).length > 0 : it.util.schemaHasRules($elseSch, it.RULES.all)), $currentBaseId = $it.baseId; if ($thenPresent || $elsePresent) { var $ifClause; $it.createErrors = false; $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; out += ' var ' + ($errs) + ' = errors; var ' + ($valid) + ' = true; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; $it.createErrors = true; out += ' errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; it.compositeRule = $it.compositeRule = $wasComposite; if ($thenPresent) { out += ' if (' + ($nextValid) + ') { '; $it.schema = it.schema['then']; $it.schemaPath = it.schemaPath + '.then'; $it.errSchemaPath = it.errSchemaPath + '/then'; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; out += ' ' + ($valid) + ' = ' + ($nextValid) + '; '; if ($thenPresent && $elsePresent) { $ifClause = 'ifClause' + $lvl; out += ' var ' + ($ifClause) + ' = \'then\'; '; } else { $ifClause = '\'then\''; } out += ' } '; if ($elsePresent) { out += ' else { '; } } else { out += ' if (!' + ($nextValid) + ') { '; } if ($elsePresent) { $it.schema = it.schema['else']; $it.schemaPath = it.schemaPath + '.else'; $it.errSchemaPath = it.errSchemaPath + '/else'; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; out += ' ' + ($valid) + ' = ' + ($nextValid) + '; '; if ($thenPresent && $elsePresent) { $ifClause = 'ifClause' + $lvl; out += ' var ' + ($ifClause) + ' = \'else\'; '; } else { $ifClause = '\'else\''; } out += ' } '; } out += ' if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('if') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { failingKeyword: ' + ($ifClause) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should match "\' + ' + ($ifClause) + ' + \'" schema\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError(vErrors); '; } else { out += ' validate.errors = vErrors; return false; '; } } out += ' } '; if ($breakOnError) { out += ' else { '; } out = it.util.cleanUpCode(out); } else { if ($breakOnError) { out += ' if (true) { '; } } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/index.js": /*!*********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/index.js ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; //all requires must be explicit because browserify won't work with dynamic requires module.exports = { '$ref': __webpack_require__(/*! ./ref */ "./node_modules/ajv/lib/dotjs/ref.js"), allOf: __webpack_require__(/*! ./allOf */ "./node_modules/ajv/lib/dotjs/allOf.js"), anyOf: __webpack_require__(/*! ./anyOf */ "./node_modules/ajv/lib/dotjs/anyOf.js"), '$comment': __webpack_require__(/*! ./comment */ "./node_modules/ajv/lib/dotjs/comment.js"), const: __webpack_require__(/*! ./const */ "./node_modules/ajv/lib/dotjs/const.js"), contains: __webpack_require__(/*! ./contains */ "./node_modules/ajv/lib/dotjs/contains.js"), dependencies: __webpack_require__(/*! ./dependencies */ "./node_modules/ajv/lib/dotjs/dependencies.js"), 'enum': __webpack_require__(/*! ./enum */ "./node_modules/ajv/lib/dotjs/enum.js"), format: __webpack_require__(/*! ./format */ "./node_modules/ajv/lib/dotjs/format.js"), 'if': __webpack_require__(/*! ./if */ "./node_modules/ajv/lib/dotjs/if.js"), items: __webpack_require__(/*! ./items */ "./node_modules/ajv/lib/dotjs/items.js"), maximum: __webpack_require__(/*! ./_limit */ "./node_modules/ajv/lib/dotjs/_limit.js"), minimum: __webpack_require__(/*! ./_limit */ "./node_modules/ajv/lib/dotjs/_limit.js"), maxItems: __webpack_require__(/*! ./_limitItems */ "./node_modules/ajv/lib/dotjs/_limitItems.js"), minItems: __webpack_require__(/*! ./_limitItems */ "./node_modules/ajv/lib/dotjs/_limitItems.js"), maxLength: __webpack_require__(/*! ./_limitLength */ "./node_modules/ajv/lib/dotjs/_limitLength.js"), minLength: __webpack_require__(/*! ./_limitLength */ "./node_modules/ajv/lib/dotjs/_limitLength.js"), maxProperties: __webpack_require__(/*! ./_limitProperties */ "./node_modules/ajv/lib/dotjs/_limitProperties.js"), minProperties: __webpack_require__(/*! ./_limitProperties */ "./node_modules/ajv/lib/dotjs/_limitProperties.js"), multipleOf: __webpack_require__(/*! ./multipleOf */ "./node_modules/ajv/lib/dotjs/multipleOf.js"), not: __webpack_require__(/*! ./not */ "./node_modules/ajv/lib/dotjs/not.js"), oneOf: __webpack_require__(/*! ./oneOf */ "./node_modules/ajv/lib/dotjs/oneOf.js"), pattern: __webpack_require__(/*! ./pattern */ "./node_modules/ajv/lib/dotjs/pattern.js"), properties: __webpack_require__(/*! ./properties */ "./node_modules/ajv/lib/dotjs/properties.js"), propertyNames: __webpack_require__(/*! ./propertyNames */ "./node_modules/ajv/lib/dotjs/propertyNames.js"), required: __webpack_require__(/*! ./required */ "./node_modules/ajv/lib/dotjs/required.js"), uniqueItems: __webpack_require__(/*! ./uniqueItems */ "./node_modules/ajv/lib/dotjs/uniqueItems.js"), validate: __webpack_require__(/*! ./validate */ "./node_modules/ajv/lib/dotjs/validate.js") }; /***/ }), /***/ "./node_modules/ajv/lib/dotjs/items.js": /*!*********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/items.js ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_items(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $idx = 'i' + $lvl, $dataNxt = $it.dataLevel = it.dataLevel + 1, $nextData = 'data' + $dataNxt, $currentBaseId = it.baseId; out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';'; if (Array.isArray($schema)) { var $additionalItems = it.schema.additionalItems; if ($additionalItems === false) { out += ' ' + ($valid) + ' = ' + ($data) + '.length <= ' + ($schema.length) + '; '; var $currErrSchemaPath = $errSchemaPath; $errSchemaPath = it.errSchemaPath + '/additionalItems'; out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('additionalItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schema.length) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have more than ' + ($schema.length) + ' items\' '; } if (it.opts.verbose) { out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; $errSchemaPath = $currErrSchemaPath; if ($breakOnError) { $closingBraces += '}'; out += ' else { '; } } var arr1 = $schema; if (arr1) { var $sch, $i = -1, l1 = arr1.length - 1; while ($i < l1) { $sch = arr1[$i += 1]; if ((it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 0 : it.util.schemaHasRules($sch, it.RULES.all))) { out += ' ' + ($nextValid) + ' = true; if (' + ($data) + '.length > ' + ($i) + ') { '; var $passData = $data + '[' + $i + ']'; $it.schema = $sch; $it.schemaPath = $schemaPath + '[' + $i + ']'; $it.errSchemaPath = $errSchemaPath + '/' + $i; $it.errorPath = it.util.getPathExpr(it.errorPath, $i, it.opts.jsonPointers, true); $it.dataPathArr[$dataNxt] = $i; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } if (typeof $additionalItems == 'object' && (it.opts.strictKeywords ? typeof $additionalItems == 'object' && Object.keys($additionalItems).length > 0 : it.util.schemaHasRules($additionalItems, it.RULES.all))) { $it.schema = $additionalItems; $it.schemaPath = it.schemaPath + '.additionalItems'; $it.errSchemaPath = it.errSchemaPath + '/additionalItems'; out += ' ' + ($nextValid) + ' = true; if (' + ($data) + '.length > ' + ($schema.length) + ') { for (var ' + ($idx) + ' = ' + ($schema.length) + '; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); var $passData = $data + '[' + $idx + ']'; $it.dataPathArr[$dataNxt] = $idx; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' } } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } else if ((it.opts.strictKeywords ? typeof $schema == 'object' && Object.keys($schema).length > 0 : it.util.schemaHasRules($schema, it.RULES.all))) { $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; out += ' for (var ' + ($idx) + ' = ' + (0) + '; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); var $passData = $data + '[' + $idx + ']'; $it.dataPathArr[$dataNxt] = $idx; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' }'; } if ($breakOnError) { out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; } out = it.util.cleanUpCode(out); return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/multipleOf.js": /*!**************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/multipleOf.js ***! \**************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_multipleOf(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } out += 'var division' + ($lvl) + ';if ('; if ($isData) { out += ' ' + ($schemaValue) + ' !== undefined && ( typeof ' + ($schemaValue) + ' != \'number\' || '; } out += ' (division' + ($lvl) + ' = ' + ($data) + ' / ' + ($schemaValue) + ', '; if (it.opts.multipleOfPrecision) { out += ' Math.abs(Math.round(division' + ($lvl) + ') - division' + ($lvl) + ') > 1e-' + (it.opts.multipleOfPrecision) + ' '; } else { out += ' division' + ($lvl) + ' !== parseInt(division' + ($lvl) + ') '; } out += ' ) '; if ($isData) { out += ' ) '; } out += ' ) { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('multipleOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { multipleOf: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be multiple of '; if ($isData) { out += '\' + ' + ($schemaValue); } else { out += '' + ($schemaValue) + '\''; } } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/not.js": /*!*******************************************!*\ !*** ./node_modules/ajv/lib/dotjs/not.js ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_not(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); $it.level++; var $nextValid = 'valid' + $it.level; if ((it.opts.strictKeywords ? typeof $schema == 'object' && Object.keys($schema).length > 0 : it.util.schemaHasRules($schema, it.RULES.all))) { $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; out += ' var ' + ($errs) + ' = errors; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; $it.createErrors = false; var $allErrorsOption; if ($it.opts.allErrors) { $allErrorsOption = $it.opts.allErrors; $it.opts.allErrors = false; } out += ' ' + (it.validate($it)) + ' '; $it.createErrors = true; if ($allErrorsOption) $it.opts.allErrors = $allErrorsOption; it.compositeRule = $it.compositeRule = $wasComposite; out += ' if (' + ($nextValid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('not') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should NOT be valid\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; if (it.opts.allErrors) { out += ' } '; } } else { out += ' var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('not') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should NOT be valid\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; if ($breakOnError) { out += ' if (false) { '; } } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/oneOf.js": /*!*********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/oneOf.js ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_oneOf(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $currentBaseId = $it.baseId, $prevValid = 'prevValid' + $lvl, $passingSchemas = 'passingSchemas' + $lvl; out += 'var ' + ($errs) + ' = errors , ' + ($prevValid) + ' = false , ' + ($valid) + ' = false , ' + ($passingSchemas) + ' = null; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; var arr1 = $schema; if (arr1) { var $sch, $i = -1, l1 = arr1.length - 1; while ($i < l1) { $sch = arr1[$i += 1]; if ((it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 0 : it.util.schemaHasRules($sch, it.RULES.all))) { $it.schema = $sch; $it.schemaPath = $schemaPath + '[' + $i + ']'; $it.errSchemaPath = $errSchemaPath + '/' + $i; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; } else { out += ' var ' + ($nextValid) + ' = true; '; } if ($i) { out += ' if (' + ($nextValid) + ' && ' + ($prevValid) + ') { ' + ($valid) + ' = false; ' + ($passingSchemas) + ' = [' + ($passingSchemas) + ', ' + ($i) + ']; } else { '; $closingBraces += '}'; } out += ' if (' + ($nextValid) + ') { ' + ($valid) + ' = ' + ($prevValid) + ' = true; ' + ($passingSchemas) + ' = ' + ($i) + '; }'; } } it.compositeRule = $it.compositeRule = $wasComposite; out += '' + ($closingBraces) + 'if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('oneOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { passingSchemas: ' + ($passingSchemas) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should match exactly one schema in oneOf\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError(vErrors); '; } else { out += ' validate.errors = vErrors; return false; '; } } out += '} else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; }'; if (it.opts.allErrors) { out += ' } '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/pattern.js": /*!***********************************************!*\ !*** ./node_modules/ajv/lib/dotjs/pattern.js ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_pattern(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $regexp = $isData ? '(new RegExp(' + $schemaValue + '))' : it.usePattern($schema); out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || '; } out += ' !' + ($regexp) + '.test(' + ($data) + ') ) { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('pattern') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { pattern: '; if ($isData) { out += '' + ($schemaValue); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' } '; if (it.opts.messages !== false) { out += ' , message: \'should match pattern "'; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + (it.util.escapeQuotes($schema)); } out += '"\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/properties.js": /*!**************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/properties.js ***! \**************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_properties(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $key = 'key' + $lvl, $idx = 'idx' + $lvl, $dataNxt = $it.dataLevel = it.dataLevel + 1, $nextData = 'data' + $dataNxt, $dataProperties = 'dataProperties' + $lvl; var $schemaKeys = Object.keys($schema || {}), $pProperties = it.schema.patternProperties || {}, $pPropertyKeys = Object.keys($pProperties), $aProperties = it.schema.additionalProperties, $someProperties = $schemaKeys.length || $pPropertyKeys.length, $noAdditional = $aProperties === false, $additionalIsSchema = typeof $aProperties == 'object' && Object.keys($aProperties).length, $removeAdditional = it.opts.removeAdditional, $checkAdditional = $noAdditional || $additionalIsSchema || $removeAdditional, $ownProperties = it.opts.ownProperties, $currentBaseId = it.baseId; var $required = it.schema.required; if ($required && !(it.opts.$data && $required.$data) && $required.length < it.opts.loopRequired) var $requiredHash = it.util.toHash($required); out += 'var ' + ($errs) + ' = errors;var ' + ($nextValid) + ' = true;'; if ($ownProperties) { out += ' var ' + ($dataProperties) + ' = undefined;'; } if ($checkAdditional) { if ($ownProperties) { out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; } else { out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; } if ($someProperties) { out += ' var isAdditional' + ($lvl) + ' = !(false '; if ($schemaKeys.length) { if ($schemaKeys.length > 8) { out += ' || validate.schema' + ($schemaPath) + '.hasOwnProperty(' + ($key) + ') '; } else { var arr1 = $schemaKeys; if (arr1) { var $propertyKey, i1 = -1, l1 = arr1.length - 1; while (i1 < l1) { $propertyKey = arr1[i1 += 1]; out += ' || ' + ($key) + ' == ' + (it.util.toQuotedString($propertyKey)) + ' '; } } } } if ($pPropertyKeys.length) { var arr2 = $pPropertyKeys; if (arr2) { var $pProperty, $i = -1, l2 = arr2.length - 1; while ($i < l2) { $pProperty = arr2[$i += 1]; out += ' || ' + (it.usePattern($pProperty)) + '.test(' + ($key) + ') '; } } } out += ' ); if (isAdditional' + ($lvl) + ') { '; } if ($removeAdditional == 'all') { out += ' delete ' + ($data) + '[' + ($key) + ']; '; } else { var $currentErrorPath = it.errorPath; var $additionalProperty = '\' + ' + $key + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); } if ($noAdditional) { if ($removeAdditional) { out += ' delete ' + ($data) + '[' + ($key) + ']; '; } else { out += ' ' + ($nextValid) + ' = false; '; var $currErrSchemaPath = $errSchemaPath; $errSchemaPath = it.errSchemaPath + '/additionalProperties'; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('additionalProperties') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { additionalProperty: \'' + ($additionalProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is an invalid additional property'; } else { out += 'should NOT have additional properties'; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } $errSchemaPath = $currErrSchemaPath; if ($breakOnError) { out += ' break; '; } } } else if ($additionalIsSchema) { if ($removeAdditional == 'failing') { out += ' var ' + ($errs) + ' = errors; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; $it.schema = $aProperties; $it.schemaPath = it.schemaPath + '.additionalProperties'; $it.errSchemaPath = it.errSchemaPath + '/additionalProperties'; $it.errorPath = it.opts._errorDataPathProperty ? it.errorPath : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } out += ' if (!' + ($nextValid) + ') { errors = ' + ($errs) + '; if (validate.errors !== null) { if (errors) validate.errors.length = errors; else validate.errors = null; } delete ' + ($data) + '[' + ($key) + ']; } '; it.compositeRule = $it.compositeRule = $wasComposite; } else { $it.schema = $aProperties; $it.schemaPath = it.schemaPath + '.additionalProperties'; $it.errSchemaPath = it.errSchemaPath + '/additionalProperties'; $it.errorPath = it.opts._errorDataPathProperty ? it.errorPath : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } } } it.errorPath = $currentErrorPath; } if ($someProperties) { out += ' } '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } var $useDefaults = it.opts.useDefaults && !it.compositeRule; if ($schemaKeys.length) { var arr3 = $schemaKeys; if (arr3) { var $propertyKey, i3 = -1, l3 = arr3.length - 1; while (i3 < l3) { $propertyKey = arr3[i3 += 1]; var $sch = $schema[$propertyKey]; if ((it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 0 : it.util.schemaHasRules($sch, it.RULES.all))) { var $prop = it.util.getProperty($propertyKey), $passData = $data + $prop, $hasDefault = $useDefaults && $sch.default !== undefined; $it.schema = $sch; $it.schemaPath = $schemaPath + $prop; $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($propertyKey); $it.errorPath = it.util.getPath(it.errorPath, $propertyKey, it.opts.jsonPointers); $it.dataPathArr[$dataNxt] = it.util.toQuotedString($propertyKey); var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { $code = it.util.varReplace($code, $nextData, $passData); var $useData = $passData; } else { var $useData = $nextData; out += ' var ' + ($nextData) + ' = ' + ($passData) + '; '; } if ($hasDefault) { out += ' ' + ($code) + ' '; } else { if ($requiredHash && $requiredHash[$propertyKey]) { out += ' if ( ' + ($useData) + ' === undefined '; if ($ownProperties) { out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; } out += ') { ' + ($nextValid) + ' = false; '; var $currentErrorPath = it.errorPath, $currErrSchemaPath = $errSchemaPath, $missingProperty = it.util.escapeQuotes($propertyKey); if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers); } $errSchemaPath = it.errSchemaPath + '/required'; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } $errSchemaPath = $currErrSchemaPath; it.errorPath = $currentErrorPath; out += ' } else { '; } else { if ($breakOnError) { out += ' if ( ' + ($useData) + ' === undefined '; if ($ownProperties) { out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; } out += ') { ' + ($nextValid) + ' = true; } else { '; } else { out += ' if (' + ($useData) + ' !== undefined '; if ($ownProperties) { out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; } out += ' ) { '; } } out += ' ' + ($code) + ' } '; } } if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } if ($pPropertyKeys.length) { var arr4 = $pPropertyKeys; if (arr4) { var $pProperty, i4 = -1, l4 = arr4.length - 1; while (i4 < l4) { $pProperty = arr4[i4 += 1]; var $sch = $pProperties[$pProperty]; if ((it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 0 : it.util.schemaHasRules($sch, it.RULES.all))) { $it.schema = $sch; $it.schemaPath = it.schemaPath + '.patternProperties' + it.util.getProperty($pProperty); $it.errSchemaPath = it.errSchemaPath + '/patternProperties/' + it.util.escapeFragment($pProperty); if ($ownProperties) { out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; } else { out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; } out += ' if (' + (it.usePattern($pProperty)) + '.test(' + ($key) + ')) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' } '; if ($breakOnError) { out += ' else ' + ($nextValid) + ' = true; '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } } if ($breakOnError) { out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; } out = it.util.cleanUpCode(out); return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/propertyNames.js": /*!*****************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/propertyNames.js ***! \*****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_propertyNames(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; out += 'var ' + ($errs) + ' = errors;'; if ((it.opts.strictKeywords ? typeof $schema == 'object' && Object.keys($schema).length > 0 : it.util.schemaHasRules($schema, it.RULES.all))) { $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; var $key = 'key' + $lvl, $idx = 'idx' + $lvl, $i = 'i' + $lvl, $invalidName = '\' + ' + $key + ' + \'', $dataNxt = $it.dataLevel = it.dataLevel + 1, $nextData = 'data' + $dataNxt, $dataProperties = 'dataProperties' + $lvl, $ownProperties = it.opts.ownProperties, $currentBaseId = it.baseId; if ($ownProperties) { out += ' var ' + ($dataProperties) + ' = undefined; '; } if ($ownProperties) { out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; } else { out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; } out += ' var startErrs' + ($lvl) + ' = errors; '; var $passData = $key; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } it.compositeRule = $it.compositeRule = $wasComposite; out += ' if (!' + ($nextValid) + ') { for (var ' + ($i) + '=startErrs' + ($lvl) + '; ' + ($i) + ' 0 : it.util.schemaHasRules($propertySch, it.RULES.all)))) { $required[$required.length] = $property; } } } } else { var $required = $schema; } } if ($isData || $required.length) { var $currentErrorPath = it.errorPath, $loopRequired = $isData || $required.length >= it.opts.loopRequired, $ownProperties = it.opts.ownProperties; if ($breakOnError) { out += ' var missing' + ($lvl) + '; '; if ($loopRequired) { if (!$isData) { out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; '; } var $i = 'i' + $lvl, $propertyPath = 'schema' + $lvl + '[' + $i + ']', $missingProperty = '\' + ' + $propertyPath + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers); } out += ' var ' + ($valid) + ' = true; '; if ($isData) { out += ' if (schema' + ($lvl) + ' === undefined) ' + ($valid) + ' = true; else if (!Array.isArray(schema' + ($lvl) + ')) ' + ($valid) + ' = false; else {'; } out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { ' + ($valid) + ' = ' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] !== undefined '; if ($ownProperties) { out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + ']) '; } out += '; if (!' + ($valid) + ') break; } '; if ($isData) { out += ' } '; } out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { '; } else { out += ' if ( '; var arr2 = $required; if (arr2) { var $propertyKey, $i = -1, l2 = arr2.length - 1; while ($i < l2) { $propertyKey = arr2[$i += 1]; if ($i) { out += ' || '; } var $prop = it.util.getProperty($propertyKey), $useData = $data + $prop; out += ' ( ( ' + ($useData) + ' === undefined '; if ($ownProperties) { out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; } out += ') && (missing' + ($lvl) + ' = ' + (it.util.toQuotedString(it.opts.jsonPointers ? $propertyKey : $prop)) + ') ) '; } } out += ') { '; var $propertyPath = 'missing' + $lvl, $missingProperty = '\' + ' + $propertyPath + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.opts.jsonPointers ? it.util.getPathExpr($currentErrorPath, $propertyPath, true) : $currentErrorPath + ' + ' + $propertyPath; } var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { '; } } else { if ($loopRequired) { if (!$isData) { out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; '; } var $i = 'i' + $lvl, $propertyPath = 'schema' + $lvl + '[' + $i + ']', $missingProperty = '\' + ' + $propertyPath + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers); } if ($isData) { out += ' if (' + ($vSchema) + ' && !Array.isArray(' + ($vSchema) + ')) { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else if (' + ($vSchema) + ' !== undefined) { '; } out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { if (' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] === undefined '; if ($ownProperties) { out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + ']) '; } out += ') { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } '; if ($isData) { out += ' } '; } } else { var arr3 = $required; if (arr3) { var $propertyKey, i3 = -1, l3 = arr3.length - 1; while (i3 < l3) { $propertyKey = arr3[i3 += 1]; var $prop = it.util.getProperty($propertyKey), $missingProperty = it.util.escapeQuotes($propertyKey), $useData = $data + $prop; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers); } out += ' if ( ' + ($useData) + ' === undefined '; if ($ownProperties) { out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; } out += ') { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } '; } } } } it.errorPath = $currentErrorPath; } else if ($breakOnError) { out += ' if (true) {'; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/uniqueItems.js": /*!***************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/uniqueItems.js ***! \***************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_uniqueItems(it, $keyword, $ruleType) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $isData = it.opts.$data && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } if (($schema || $isData) && it.opts.uniqueItems !== false) { if ($isData) { out += ' var ' + ($valid) + '; if (' + ($schemaValue) + ' === false || ' + ($schemaValue) + ' === undefined) ' + ($valid) + ' = true; else if (typeof ' + ($schemaValue) + ' != \'boolean\') ' + ($valid) + ' = false; else { '; } out += ' var i = ' + ($data) + '.length , ' + ($valid) + ' = true , j; if (i > 1) { '; var $itemType = it.schema.items && it.schema.items.type, $typeIsArray = Array.isArray($itemType); if (!$itemType || $itemType == 'object' || $itemType == 'array' || ($typeIsArray && ($itemType.indexOf('object') >= 0 || $itemType.indexOf('array') >= 0))) { out += ' outer: for (;i--;) { for (j = i; j--;) { if (equal(' + ($data) + '[i], ' + ($data) + '[j])) { ' + ($valid) + ' = false; break outer; } } } '; } else { out += ' var itemIndices = {}, item; for (;i--;) { var item = ' + ($data) + '[i]; '; var $method = 'checkDataType' + ($typeIsArray ? 's' : ''); out += ' if (' + (it.util[$method]($itemType, 'item', true)) + ') continue; '; if ($typeIsArray) { out += ' if (typeof item == \'string\') item = \'"\' + item; '; } out += ' if (typeof itemIndices[item] == \'number\') { ' + ($valid) + ' = false; j = itemIndices[item]; break; } itemIndices[item] = i; } '; } out += ' } '; if ($isData) { out += ' } '; } out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ('uniqueItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { i: i, j: j } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have duplicate items (items ## \' + j + \' and \' + i + \' are identical)\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($breakOnError) { out += ' else { '; } } else { if ($breakOnError) { out += ' if (true) { '; } } return out; } /***/ }), /***/ "./node_modules/ajv/lib/dotjs/validate.js": /*!************************************************!*\ !*** ./node_modules/ajv/lib/dotjs/validate.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function generate_validate(it, $keyword, $ruleType) { var out = ''; var $async = it.schema.$async === true, $refKeywords = it.util.schemaHasRulesExcept(it.schema, it.RULES.all, '$ref'), $id = it.self._getId(it.schema); if (it.opts.strictKeywords) { var $unknownKwd = it.util.schemaUnknownRules(it.schema, it.RULES.keywords); if ($unknownKwd) { var $keywordsMsg = 'unknown keyword: ' + $unknownKwd; if (it.opts.strictKeywords === 'log') it.logger.warn($keywordsMsg); else throw new Error($keywordsMsg); } } if (it.isTop) { out += ' var validate = '; if ($async) { it.async = true; out += 'async '; } out += 'function(data, dataPath, parentData, parentDataProperty, rootData) { \'use strict\'; '; if ($id && (it.opts.sourceCode || it.opts.processCode)) { out += ' ' + ('/\*# sourceURL=' + $id + ' */') + ' '; } } if (typeof it.schema == 'boolean' || !($refKeywords || it.schema.$ref)) { var $keyword = 'false schema'; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; if (it.schema === false) { if (it.isTop) { $breakOnError = true; } else { out += ' var ' + ($valid) + ' = false; '; } var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'false schema') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'boolean schema is false\' '; } if (it.opts.verbose) { out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } } else { if (it.isTop) { if ($async) { out += ' return data; '; } else { out += ' validate.errors = null; return true; '; } } else { out += ' var ' + ($valid) + ' = true; '; } } if (it.isTop) { out += ' }; return validate; '; } return out; } if (it.isTop) { var $top = it.isTop, $lvl = it.level = 0, $dataLvl = it.dataLevel = 0, $data = 'data'; it.rootId = it.resolve.fullPath(it.self._getId(it.root.schema)); it.baseId = it.baseId || it.rootId; delete it.isTop; it.dataPathArr = [undefined]; if (it.schema.default !== undefined && it.opts.useDefaults && it.opts.strictDefaults) { var $defaultMsg = 'default is ignored in the schema root'; if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); else throw new Error($defaultMsg); } out += ' var vErrors = null; '; out += ' var errors = 0; '; out += ' if (rootData === undefined) rootData = data; '; } else { var $lvl = it.level, $dataLvl = it.dataLevel, $data = 'data' + ($dataLvl || ''); if ($id) it.baseId = it.resolve.url(it.baseId, $id); if ($async && !it.async) throw new Error('async schema in sync schema'); out += ' var errs_' + ($lvl) + ' = errors;'; } var $valid = 'valid' + $lvl, $breakOnError = !it.opts.allErrors, $closingBraces1 = '', $closingBraces2 = ''; var $errorKeyword; var $typeSchema = it.schema.type, $typeIsArray = Array.isArray($typeSchema); if ($typeSchema && it.opts.nullable && it.schema.nullable === true) { if ($typeIsArray) { if ($typeSchema.indexOf('null') == -1) $typeSchema = $typeSchema.concat('null'); } else if ($typeSchema != 'null') { $typeSchema = [$typeSchema, 'null']; $typeIsArray = true; } } if ($typeIsArray && $typeSchema.length == 1) { $typeSchema = $typeSchema[0]; $typeIsArray = false; } if (it.schema.$ref && $refKeywords) { if (it.opts.extendRefs == 'fail') { throw new Error('$ref: validation keywords used in schema at path "' + it.errSchemaPath + '" (see option extendRefs)'); } else if (it.opts.extendRefs !== true) { $refKeywords = false; it.logger.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"'); } } if (it.schema.$comment && it.opts.$comment) { out += ' ' + (it.RULES.all.$comment.code(it, '$comment')); } if ($typeSchema) { if (it.opts.coerceTypes) { var $coerceToTypes = it.util.coerceToTypes(it.opts.coerceTypes, $typeSchema); } var $rulesGroup = it.RULES.types[$typeSchema]; if ($coerceToTypes || $typeIsArray || $rulesGroup === true || ($rulesGroup && !$shouldUseGroup($rulesGroup))) { var $schemaPath = it.schemaPath + '.type', $errSchemaPath = it.errSchemaPath + '/type'; var $schemaPath = it.schemaPath + '.type', $errSchemaPath = it.errSchemaPath + '/type', $method = $typeIsArray ? 'checkDataTypes' : 'checkDataType'; out += ' if (' + (it.util[$method]($typeSchema, $data, true)) + ') { '; if ($coerceToTypes) { var $dataType = 'dataType' + $lvl, $coerced = 'coerced' + $lvl; out += ' var ' + ($dataType) + ' = typeof ' + ($data) + '; '; if (it.opts.coerceTypes == 'array') { out += ' if (' + ($dataType) + ' == \'object\' && Array.isArray(' + ($data) + ')) ' + ($dataType) + ' = \'array\'; '; } out += ' var ' + ($coerced) + ' = undefined; '; var $bracesCoercion = ''; var arr1 = $coerceToTypes; if (arr1) { var $type, $i = -1, l1 = arr1.length - 1; while ($i < l1) { $type = arr1[$i += 1]; if ($i) { out += ' if (' + ($coerced) + ' === undefined) { '; $bracesCoercion += '}'; } if (it.opts.coerceTypes == 'array' && $type != 'array') { out += ' if (' + ($dataType) + ' == \'array\' && ' + ($data) + '.length == 1) { ' + ($coerced) + ' = ' + ($data) + ' = ' + ($data) + '[0]; ' + ($dataType) + ' = typeof ' + ($data) + '; } '; } if ($type == 'string') { out += ' if (' + ($dataType) + ' == \'number\' || ' + ($dataType) + ' == \'boolean\') ' + ($coerced) + ' = \'\' + ' + ($data) + '; else if (' + ($data) + ' === null) ' + ($coerced) + ' = \'\'; '; } else if ($type == 'number' || $type == 'integer') { out += ' if (' + ($dataType) + ' == \'boolean\' || ' + ($data) + ' === null || (' + ($dataType) + ' == \'string\' && ' + ($data) + ' && ' + ($data) + ' == +' + ($data) + ' '; if ($type == 'integer') { out += ' && !(' + ($data) + ' % 1)'; } out += ')) ' + ($coerced) + ' = +' + ($data) + '; '; } else if ($type == 'boolean') { out += ' if (' + ($data) + ' === \'false\' || ' + ($data) + ' === 0 || ' + ($data) + ' === null) ' + ($coerced) + ' = false; else if (' + ($data) + ' === \'true\' || ' + ($data) + ' === 1) ' + ($coerced) + ' = true; '; } else if ($type == 'null') { out += ' if (' + ($data) + ' === \'\' || ' + ($data) + ' === 0 || ' + ($data) + ' === false) ' + ($coerced) + ' = null; '; } else if (it.opts.coerceTypes == 'array' && $type == 'array') { out += ' if (' + ($dataType) + ' == \'string\' || ' + ($dataType) + ' == \'number\' || ' + ($dataType) + ' == \'boolean\' || ' + ($data) + ' == null) ' + ($coerced) + ' = [' + ($data) + ']; '; } } } out += ' ' + ($bracesCoercion) + ' if (' + ($coerced) + ' === undefined) { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'type') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { type: \''; if ($typeIsArray) { out += '' + ($typeSchema.join(",")); } else { out += '' + ($typeSchema); } out += '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should be '; if ($typeIsArray) { out += '' + ($typeSchema.join(",")); } else { out += '' + ($typeSchema); } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { '; var $parentData = $dataLvl ? 'data' + (($dataLvl - 1) || '') : 'parentData', $parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty'; out += ' ' + ($data) + ' = ' + ($coerced) + '; '; if (!$dataLvl) { out += 'if (' + ($parentData) + ' !== undefined)'; } out += ' ' + ($parentData) + '[' + ($parentDataProperty) + '] = ' + ($coerced) + '; } '; } else { var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'type') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { type: \''; if ($typeIsArray) { out += '' + ($typeSchema.join(",")); } else { out += '' + ($typeSchema); } out += '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should be '; if ($typeIsArray) { out += '' + ($typeSchema.join(",")); } else { out += '' + ($typeSchema); } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } } out += ' } '; } } if (it.schema.$ref && !$refKeywords) { out += ' ' + (it.RULES.all.$ref.code(it, '$ref')) + ' '; if ($breakOnError) { out += ' } if (errors === '; if ($top) { out += '0'; } else { out += 'errs_' + ($lvl); } out += ') { '; $closingBraces2 += '}'; } } else { var arr2 = it.RULES; if (arr2) { var $rulesGroup, i2 = -1, l2 = arr2.length - 1; while (i2 < l2) { $rulesGroup = arr2[i2 += 1]; if ($shouldUseGroup($rulesGroup)) { if ($rulesGroup.type) { out += ' if (' + (it.util.checkDataType($rulesGroup.type, $data)) + ') { '; } if (it.opts.useDefaults) { if ($rulesGroup.type == 'object' && it.schema.properties) { var $schema = it.schema.properties, $schemaKeys = Object.keys($schema); var arr3 = $schemaKeys; if (arr3) { var $propertyKey, i3 = -1, l3 = arr3.length - 1; while (i3 < l3) { $propertyKey = arr3[i3 += 1]; var $sch = $schema[$propertyKey]; if ($sch.default !== undefined) { var $passData = $data + it.util.getProperty($propertyKey); if (it.compositeRule) { if (it.opts.strictDefaults) { var $defaultMsg = 'default is ignored for: ' + $passData; if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); else throw new Error($defaultMsg); } } else { out += ' if (' + ($passData) + ' === undefined '; if (it.opts.useDefaults == 'empty') { out += ' || ' + ($passData) + ' === null || ' + ($passData) + ' === \'\' '; } out += ' ) ' + ($passData) + ' = '; if (it.opts.useDefaults == 'shared') { out += ' ' + (it.useDefault($sch.default)) + ' '; } else { out += ' ' + (JSON.stringify($sch.default)) + ' '; } out += '; '; } } } } } else if ($rulesGroup.type == 'array' && Array.isArray(it.schema.items)) { var arr4 = it.schema.items; if (arr4) { var $sch, $i = -1, l4 = arr4.length - 1; while ($i < l4) { $sch = arr4[$i += 1]; if ($sch.default !== undefined) { var $passData = $data + '[' + $i + ']'; if (it.compositeRule) { if (it.opts.strictDefaults) { var $defaultMsg = 'default is ignored for: ' + $passData; if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); else throw new Error($defaultMsg); } } else { out += ' if (' + ($passData) + ' === undefined '; if (it.opts.useDefaults == 'empty') { out += ' || ' + ($passData) + ' === null || ' + ($passData) + ' === \'\' '; } out += ' ) ' + ($passData) + ' = '; if (it.opts.useDefaults == 'shared') { out += ' ' + (it.useDefault($sch.default)) + ' '; } else { out += ' ' + (JSON.stringify($sch.default)) + ' '; } out += '; '; } } } } } } var arr5 = $rulesGroup.rules; if (arr5) { var $rule, i5 = -1, l5 = arr5.length - 1; while (i5 < l5) { $rule = arr5[i5 += 1]; if ($shouldUseRule($rule)) { var $code = $rule.code(it, $rule.keyword, $rulesGroup.type); if ($code) { out += ' ' + ($code) + ' '; if ($breakOnError) { $closingBraces1 += '}'; } } } } } if ($breakOnError) { out += ' ' + ($closingBraces1) + ' '; $closingBraces1 = ''; } if ($rulesGroup.type) { out += ' } '; if ($typeSchema && $typeSchema === $rulesGroup.type && !$coerceToTypes) { out += ' else { '; var $schemaPath = it.schemaPath + '.type', $errSchemaPath = it.errSchemaPath + '/type'; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'type') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { type: \''; if ($typeIsArray) { out += '' + ($typeSchema.join(",")); } else { out += '' + ($typeSchema); } out += '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should be '; if ($typeIsArray) { out += '' + ($typeSchema.join(",")); } else { out += '' + ($typeSchema); } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; } } if ($breakOnError) { out += ' if (errors === '; if ($top) { out += '0'; } else { out += 'errs_' + ($lvl); } out += ') { '; $closingBraces2 += '}'; } } } } } if ($breakOnError) { out += ' ' + ($closingBraces2) + ' '; } if ($top) { if ($async) { out += ' if (errors === 0) return data; '; out += ' else throw new ValidationError(vErrors); '; } else { out += ' validate.errors = vErrors; '; out += ' return errors === 0; '; } out += ' }; return validate;'; } else { out += ' var ' + ($valid) + ' = errors === errs_' + ($lvl) + ';'; } out = it.util.cleanUpCode(out); if ($top) { out = it.util.finalCleanUpCode(out, $async); } function $shouldUseGroup($rulesGroup) { var rules = $rulesGroup.rules; for (var i = 0; i < rules.length; i++) if ($shouldUseRule(rules[i])) return true; } function $shouldUseRule($rule) { return it.schema[$rule.keyword] !== undefined || ($rule.implements && $ruleImplementsSomeKeyword($rule)); } function $ruleImplementsSomeKeyword($rule) { var impl = $rule.implements; for (var i = 0; i < impl.length; i++) if (it.schema[impl[i]] !== undefined) return true; } return out; } /***/ }), /***/ "./node_modules/ajv/lib/keyword.js": /*!*****************************************!*\ !*** ./node_modules/ajv/lib/keyword.js ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var IDENTIFIER = /^[a-z_$][a-z0-9_$-]*$/i; var customRuleCode = __webpack_require__(/*! ./dotjs/custom */ "./node_modules/ajv/lib/dotjs/custom.js"); var definitionSchema = __webpack_require__(/*! ./definition_schema */ "./node_modules/ajv/lib/definition_schema.js"); module.exports = { add: addKeyword, get: getKeyword, remove: removeKeyword, validate: validateKeyword }; /** * Define custom keyword * @this Ajv * @param {String} keyword custom keyword, should be unique (including different from all standard, custom and macro keywords). * @param {Object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`. * @return {Ajv} this for method chaining */ function addKeyword(keyword, definition) { /* jshint validthis: true */ /* eslint no-shadow: 0 */ var RULES = this.RULES; if (RULES.keywords[keyword]) throw new Error('Keyword ' + keyword + ' is already defined'); if (!IDENTIFIER.test(keyword)) throw new Error('Keyword ' + keyword + ' is not a valid identifier'); if (definition) { this.validateKeyword(definition, true); var dataType = definition.type; if (Array.isArray(dataType)) { for (var i=0; i var span = document.createElement('span') span.textContent = text // Preserve consecutive spaces and newlines span.style.whiteSpace = 'pre' // Add the to the page document.body.appendChild(span) // Make a selection object representing the range of text selected by the user var selection = window.getSelection() var range = window.document.createRange() selection.removeAllRanges() range.selectNode(span) selection.addRange(range) // Copy text to the clipboard var success = false try { success = window.document.execCommand('copy') } catch (err) { console.log('error', err) } // Cleanup selection.removeAllRanges() window.document.body.removeChild(span) return success ? Promise.resolve() : Promise.reject(new DOMException('The request is not allowed', 'NotAllowedError')) } /***/ }), /***/ "./node_modules/crc/crc32.js": /*!***********************************!*\ !*** ./node_modules/crc/crc32.js ***! \***********************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! buffer */ "./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js"); /* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _create_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./create_buffer */ "./node_modules/crc/create_buffer.js"); /* harmony import */ var _define_crc__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./define_crc */ "./node_modules/crc/define_crc.js"); // Generated by `./pycrc.py --algorithm=table-driven --model=crc-32 --generate=c` // prettier-ignore let TABLE = [ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d ]; if (typeof Int32Array !== 'undefined') TABLE = new Int32Array(TABLE); const crc32 = Object(_define_crc__WEBPACK_IMPORTED_MODULE_2__["default"])('crc-32', function(buf, previous) { if (!buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"].isBuffer(buf)) buf = Object(_create_buffer__WEBPACK_IMPORTED_MODULE_1__["default"])(buf); let crc = previous === 0 ? 0 : ~~previous ^ -1; for (let index = 0; index < buf.length; index++) { const byte = buf[index]; crc = TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8); } return crc ^ -1; }); /* harmony default export */ __webpack_exports__["default"] = (crc32); /***/ }), /***/ "./node_modules/crc/create_buffer.js": /*!*******************************************!*\ !*** ./node_modules/crc/create_buffer.js ***! \*******************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! buffer */ "./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js"); /* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer__WEBPACK_IMPORTED_MODULE_0__); const createBuffer = buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"].from && buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"].alloc && buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"].allocUnsafe && buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"].allocUnsafeSlow ? buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"].from : // support for Node < 5.10 val => new buffer__WEBPACK_IMPORTED_MODULE_0__["Buffer"](val); /* harmony default export */ __webpack_exports__["default"] = (createBuffer); /***/ }), /***/ "./node_modules/crc/define_crc.js": /*!****************************************!*\ !*** ./node_modules/crc/define_crc.js ***! \****************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (function(model, calc) { const fn = (buf, previous) => calc(buf, previous) >>> 0; fn.signed = calc; fn.unsigned = fn; fn.model = model; return fn; }); /***/ }), /***/ "./node_modules/decode-uri-component/index.js": /*!****************************************************!*\ !*** ./node_modules/decode-uri-component/index.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var token = '%[a-f0-9]{2}'; var singleMatcher = new RegExp(token, 'gi'); var multiMatcher = new RegExp('(' + token + ')+', 'gi'); function decodeComponents(components, split) { try { // Try to decode the entire string first return decodeURIComponent(components.join('')); } catch (err) { // Do nothing } if (components.length === 1) { return components; } split = split || 1; // Split the array in 2 parts var left = components.slice(0, split); var right = components.slice(split); return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right)); } function decode(input) { try { return decodeURIComponent(input); } catch (err) { var tokens = input.match(singleMatcher); for (var i = 1; i < tokens.length; i++) { input = decodeComponents(tokens, i).join(''); tokens = input.match(singleMatcher); } return input; } } function customDecodeURIComponent(input) { // Keep track of all the replacements and prefill the map with the `BOM` var replaceMap = { '%FE%FF': '\uFFFD\uFFFD', '%FF%FE': '\uFFFD\uFFFD' }; var match = multiMatcher.exec(input); while (match) { try { // Decode as big chunks as possible replaceMap[match[0]] = decodeURIComponent(match[0]); } catch (err) { var result = decode(match[0]); if (result !== match[0]) { replaceMap[match[0]] = result; } } match = multiMatcher.exec(input); } // Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else replaceMap['%C2'] = '\uFFFD'; var entries = Object.keys(replaceMap); for (var i = 0; i < entries.length; i++) { // Replace all decoded components var key = entries[i]; input = input.replace(new RegExp(key, 'g'), replaceMap[key]); } return input; } module.exports = function (encodedURI) { if (typeof encodedURI !== 'string') { throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`'); } try { encodedURI = encodedURI.replace(/\+/g, ' '); // Try the built in decoder first return decodeURIComponent(encodedURI); } catch (err) { // Fallback to a more advanced decoder return customDecodeURIComponent(encodedURI); } }; /***/ }), /***/ "./node_modules/fast-deep-equal/index.js": /*!***********************************************!*\ !*** ./node_modules/fast-deep-equal/index.js ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // do not edit .js files directly - edit src/index.jst module.exports = function equal(a, b) { if (a === b) return true; if (a && b && typeof a == 'object' && typeof b == 'object') { if (a.constructor !== b.constructor) return false; var length, i, keys; if (Array.isArray(a)) { length = a.length; if (length != b.length) return false; for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false; return true; } if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); keys = Object.keys(a); length = keys.length; if (length !== Object.keys(b).length) return false; for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; for (i = length; i-- !== 0;) { var key = keys[i]; if (!equal(a[key], b[key])) return false; } return true; } // true if both NaN, false otherwise return a!==a && b!==b; }; /***/ }), /***/ "./node_modules/fast-json-stable-stringify/index.js": /*!**********************************************************!*\ !*** ./node_modules/fast-json-stable-stringify/index.js ***! \**********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function (data, opts) { if (!opts) opts = {}; if (typeof opts === 'function') opts = { cmp: opts }; var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; var cmp = opts.cmp && (function (f) { return function (node) { return function (a, b) { var aobj = { key: a, value: node[a] }; var bobj = { key: b, value: node[b] }; return f(aobj, bobj); }; }; })(opts.cmp); var seen = []; return (function stringify (node) { if (node && node.toJSON && typeof node.toJSON === 'function') { node = node.toJSON(); } if (node === undefined) return; if (typeof node == 'number') return isFinite(node) ? '' + node : 'null'; if (typeof node !== 'object') return JSON.stringify(node); var i, out; if (Array.isArray(node)) { out = '['; for (i = 0; i < node.length; i++) { if (i) out += ','; out += stringify(node[i]) || 'null'; } return out + ']'; } if (node === null) return 'null'; if (seen.indexOf(node) !== -1) { if (cycles) return JSON.stringify('__cycle__'); throw new TypeError('Converting circular structure to JSON'); } var seenIndex = seen.push(node) - 1; var keys = Object.keys(node).sort(cmp && cmp(node)); out = ''; for (i = 0; i < keys.length; i++) { var key = keys[i]; var value = stringify(node[key]); if (!value) continue; if (out) out += ','; out += JSON.stringify(key) + ':' + value; } seen.splice(seenIndex, 1); return '{' + out + '}'; })(data); }; /***/ }), /***/ "./node_modules/howler/dist/howler.js": /*!********************************************!*\ !*** ./node_modules/howler/dist/howler.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! * howler.js v2.1.3 * howlerjs.com * * (c) 2013-2019, James Simpson of GoldFire Studios * goldfirestudios.com * * MIT License */ (function() { 'use strict'; /** Global Methods **/ /***************************************************************************/ /** * Create the global controller. All contained methods and properties apply * to all sounds that are currently playing or will be in the future. */ var HowlerGlobal = function() { this.init(); }; HowlerGlobal.prototype = { /** * Initialize the global Howler object. * @return {Howler} */ init: function() { var self = this || Howler; // Create a global ID counter. self._counter = 1000; // Pool of unlocked HTML5 Audio objects. self._html5AudioPool = []; self.html5PoolSize = 10; // Internal properties. self._codecs = {}; self._howls = []; self._muted = false; self._volume = 1; self._canPlayEvent = 'canplaythrough'; self._navigator = (typeof window !== 'undefined' && window.navigator) ? window.navigator : null; // Public properties. self.masterGain = null; self.noAudio = false; self.usingWebAudio = true; self.autoSuspend = true; self.ctx = null; // Set to false to disable the auto audio unlocker. self.autoUnlock = true; // Setup the various state values for global tracking. self._setup(); return self; }, /** * Get/set the global volume for all sounds. * @param {Float} vol Volume from 0.0 to 1.0. * @return {Howler/Float} Returns self or current volume. */ volume: function(vol) { var self = this || Howler; vol = parseFloat(vol); // If we don't have an AudioContext created yet, run the setup. if (!self.ctx) { setupAudioContext(); } if (typeof vol !== 'undefined' && vol >= 0 && vol <= 1) { self._volume = vol; // Don't update any of the nodes if we are muted. if (self._muted) { return self; } // When using Web Audio, we just need to adjust the master gain. if (self.usingWebAudio) { self.masterGain.gain.setValueAtTime(vol, Howler.ctx.currentTime); } // Loop through and change volume for all HTML5 audio nodes. for (var i=0; i=0; i--) { self._howls[i].unload(); } // Create a new AudioContext to make sure it is fully reset. if (self.usingWebAudio && self.ctx && typeof self.ctx.close !== 'undefined') { self.ctx.close(); self.ctx = null; setupAudioContext(); } return self; }, /** * Check for codec support of specific extension. * @param {String} ext Audio file extention. * @return {Boolean} */ codecs: function(ext) { return (this || Howler)._codecs[ext.replace(/^x-/, '')]; }, /** * Setup various state values for global tracking. * @return {Howler} */ _setup: function() { var self = this || Howler; // Keeps track of the suspend/resume state of the AudioContext. self.state = self.ctx ? self.ctx.state || 'suspended' : 'suspended'; // Automatically begin the 30-second suspend process self._autoSuspend(); // Check if audio is available. if (!self.usingWebAudio) { // No audio is available on this system if noAudio is set to true. if (typeof Audio !== 'undefined') { try { var test = new Audio(); // Check if the canplaythrough event is available. if (typeof test.oncanplaythrough === 'undefined') { self._canPlayEvent = 'canplay'; } } catch(e) { self.noAudio = true; } } else { self.noAudio = true; } } // Test to make sure audio isn't disabled in Internet Explorer. try { var test = new Audio(); if (test.muted) { self.noAudio = true; } } catch (e) {} // Check for supported codecs. if (!self.noAudio) { self._setupCodecs(); } return self; }, /** * Check for browser support for various codecs and cache the results. * @return {Howler} */ _setupCodecs: function() { var self = this || Howler; var audioTest = null; // Must wrap in a try/catch because IE11 in server mode throws an error. try { audioTest = (typeof Audio !== 'undefined') ? new Audio() : null; } catch (err) { return self; } if (!audioTest || typeof audioTest.canPlayType !== 'function') { return self; } var mpegTest = audioTest.canPlayType('audio/mpeg;').replace(/^no$/, ''); // Opera version <33 has mixed MP3 support, so we need to check for and block it. var checkOpera = self._navigator && self._navigator.userAgent.match(/OPR\/([0-6].)/g); var isOldOpera = (checkOpera && parseInt(checkOpera[0].split('/')[1], 10) < 33); self._codecs = { mp3: !!(!isOldOpera && (mpegTest || audioTest.canPlayType('audio/mp3;').replace(/^no$/, ''))), mpeg: !!mpegTest, opus: !!audioTest.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/, ''), ogg: !!audioTest.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, ''), oga: !!audioTest.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, ''), wav: !!audioTest.canPlayType('audio/wav; codecs="1"').replace(/^no$/, ''), aac: !!audioTest.canPlayType('audio/aac;').replace(/^no$/, ''), caf: !!audioTest.canPlayType('audio/x-caf;').replace(/^no$/, ''), m4a: !!(audioTest.canPlayType('audio/x-m4a;') || audioTest.canPlayType('audio/m4a;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''), mp4: !!(audioTest.canPlayType('audio/x-mp4;') || audioTest.canPlayType('audio/mp4;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''), weba: !!audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, ''), webm: !!audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, ''), dolby: !!audioTest.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/, ''), flac: !!(audioTest.canPlayType('audio/x-flac;') || audioTest.canPlayType('audio/flac;')).replace(/^no$/, '') }; return self; }, /** * Some browsers/devices will only allow audio to be played after a user interaction. * Attempt to automatically unlock audio on the first user interaction. * Concept from: http://paulbakaus.com/tutorials/html5/web-audio-on-ios/ * @return {Howler} */ _unlockAudio: function() { var self = this || Howler; // Only run this if Web Audio is supported and it hasn't already been unlocked. if (self._audioUnlocked || !self.ctx) { return; } self._audioUnlocked = false; self.autoUnlock = false; // Some mobile devices/platforms have distortion issues when opening/closing tabs and/or web views. // Bugs in the browser (especially Mobile Safari) can cause the sampleRate to change from 44100 to 48000. // By calling Howler.unload(), we create a new AudioContext with the correct sampleRate. if (!self._mobileUnloaded && self.ctx.sampleRate !== 44100) { self._mobileUnloaded = true; self.unload(); } // Scratch buffer for enabling iOS to dispose of web audio buffers correctly, as per: // http://stackoverflow.com/questions/24119684 self._scratchBuffer = self.ctx.createBuffer(1, 1, 22050); // Call this method on touch start to create and play a buffer, // then check if the audio actually played to determine if // audio has now been unlocked on iOS, Android, etc. var unlock = function(e) { // Create a pool of unlocked HTML5 Audio objects that can // be used for playing sounds without user interaction. HTML5 // Audio objects must be individually unlocked, as opposed // to the WebAudio API which only needs a single activation. // This must occur before WebAudio setup or the source.onended // event will not fire. for (var i=0; i= 55. if (typeof self.ctx.resume === 'function') { self.ctx.resume(); } // Setup a timeout to check that we are unlocked on the next event loop. source.onended = function() { source.disconnect(0); // Update the unlocked state and prevent this check from happening again. self._audioUnlocked = true; // Remove the touch start listener. document.removeEventListener('touchstart', unlock, true); document.removeEventListener('touchend', unlock, true); document.removeEventListener('click', unlock, true); // Let all sounds know that audio has been unlocked. for (var i=0; i 0 ? sound._seek : self._sprite[sprite][0] / 1000); var duration = Math.max(0, ((self._sprite[sprite][0] + self._sprite[sprite][1]) / 1000) - seek); var timeout = (duration * 1000) / Math.abs(sound._rate); var start = self._sprite[sprite][0] / 1000; var stop = (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1000; sound._sprite = sprite; // Mark the sound as ended instantly so that this async playback // doesn't get grabbed by another call to play while this one waits to start. sound._ended = false; // Update the parameters of the sound. var setParams = function() { sound._paused = false; sound._seek = seek; sound._start = start; sound._stop = stop; sound._loop = !!(sound._loop || self._sprite[sprite][2]); }; // End the sound instantly if seek is at the end. if (seek >= stop) { self._ended(sound); return; } // Begin the actual playback. var node = sound._node; if (self._webAudio) { // Fire this when the sound is ready to play to begin Web Audio playback. var playWebAudio = function() { self._playLock = false; setParams(); self._refreshBuffer(sound); // Setup the playback params. var vol = (sound._muted || self._muted) ? 0 : sound._volume; node.gain.setValueAtTime(vol, Howler.ctx.currentTime); sound._playStart = Howler.ctx.currentTime; // Play the sound using the supported method. if (typeof node.bufferSource.start === 'undefined') { sound._loop ? node.bufferSource.noteGrainOn(0, seek, 86400) : node.bufferSource.noteGrainOn(0, seek, duration); } else { sound._loop ? node.bufferSource.start(0, seek, 86400) : node.bufferSource.start(0, seek, duration); } // Start a new timer if none is present. if (timeout !== Infinity) { self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout); } if (!internal) { setTimeout(function() { self._emit('play', sound._id); self._loadQueue(); }, 0); } }; if (Howler.state === 'running') { playWebAudio(); } else { self._playLock = true; // Wait for the audio context to resume before playing. self.once('resume', playWebAudio); // Cancel the end timer. self._clearTimer(sound._id); } } else { // Fire this when the sound is ready to play to begin HTML5 Audio playback. var playHtml5 = function() { node.currentTime = seek; node.muted = sound._muted || self._muted || Howler._muted || node.muted; node.volume = sound._volume * Howler.volume(); node.playbackRate = sound._rate; // Some browsers will throw an error if this is called without user interaction. try { var play = node.play(); // Support older browsers that don't support promises, and thus don't have this issue. if (play && typeof Promise !== 'undefined' && (play instanceof Promise || typeof play.then === 'function')) { // Implements a lock to prevent DOMException: The play() request was interrupted by a call to pause(). self._playLock = true; // Set param values immediately. setParams(); // Releases the lock and executes queued actions. play .then(function() { self._playLock = false; node._unlocked = true; if (!internal) { self._emit('play', sound._id); self._loadQueue(); } }) .catch(function() { self._playLock = false; self._emit('playerror', sound._id, 'Playback was unable to start. This is most commonly an issue ' + 'on mobile devices and Chrome where playback was not within a user interaction.'); // Reset the ended and paused values. sound._ended = true; sound._paused = true; }); } else if (!internal) { self._playLock = false; setParams(); self._emit('play', sound._id); self._loadQueue(); } // Setting rate before playing won't work in IE, so we set it again here. node.playbackRate = sound._rate; // If the node is still paused, then we can assume there was a playback issue. if (node.paused) { self._emit('playerror', sound._id, 'Playback was unable to start. This is most commonly an issue ' + 'on mobile devices and Chrome where playback was not within a user interaction.'); return; } // Setup the end timer on sprites or listen for the ended event. if (sprite !== '__default' || sound._loop) { self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout); } else { self._endTimers[sound._id] = function() { // Fire ended on this audio node. self._ended(sound); // Clear this listener. node.removeEventListener('ended', self._endTimers[sound._id], false); }; node.addEventListener('ended', self._endTimers[sound._id], false); } } catch (err) { self._emit('playerror', sound._id, err); } }; // If this is streaming audio, make sure the src is set and load again. if (node.src === 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA') { node.src = self._src; node.load(); } // Play immediately if ready, or wait for the 'canplaythrough'e vent. var loadedNoReadyState = (window && window.ejecta) || (!node.readyState && Howler._navigator.isCocoonJS); if (node.readyState >= 3 || loadedNoReadyState) { playHtml5(); } else { self._playLock = true; var listener = function() { // Begin playback. playHtml5(); // Clear this listener. node.removeEventListener(Howler._canPlayEvent, listener, false); }; node.addEventListener(Howler._canPlayEvent, listener, false); // Cancel the end timer. self._clearTimer(sound._id); } } return sound._id; }, /** * Pause playback and save current position. * @param {Number} id The sound ID (empty to pause all in group). * @return {Howl} */ pause: function(id) { var self = this; // If the sound hasn't loaded or a play() promise is pending, add it to the load queue to pause when capable. if (self._state !== 'loaded' || self._playLock) { self._queue.push({ event: 'pause', action: function() { self.pause(id); } }); return self; } // If no id is passed, get all ID's to be paused. var ids = self._getSoundIds(id); for (var i=0; i Returns the group's volume value. * volume(id) -> Returns the sound id's current volume. * volume(vol) -> Sets the volume of all sounds in this Howl group. * volume(vol, id) -> Sets the volume of passed sound id. * @return {Howl/Number} Returns self or current volume. */ volume: function() { var self = this; var args = arguments; var vol, id; // Determine the values based on arguments. if (args.length === 0) { // Return the value of the groups' volume. return self._volume; } else if (args.length === 1 || args.length === 2 && typeof args[1] === 'undefined') { // First check if this is an ID, and if not, assume it is a new volume. var ids = self._getSoundIds(); var index = ids.indexOf(args[0]); if (index >= 0) { id = parseInt(args[0], 10); } else { vol = parseFloat(args[0]); } } else if (args.length >= 2) { vol = parseFloat(args[0]); id = parseInt(args[1], 10); } // Update the volume or return the current volume. var sound; if (typeof vol !== 'undefined' && vol >= 0 && vol <= 1) { // If the sound hasn't loaded, add it to the load queue to change volume when capable. if (self._state !== 'loaded'|| self._playLock) { self._queue.push({ event: 'volume', action: function() { self.volume.apply(self, args); } }); return self; } // Set the group volume. if (typeof id === 'undefined') { self._volume = vol; } // Update one or all volumes. id = self._getSoundIds(id); for (var i=0; i 0) ? len / steps : len); var lastTick = Date.now(); // Store the value being faded to. sound._fadeTo = to; // Update the volume value on each interval tick. sound._interval = setInterval(function() { // Update the volume based on the time since the last tick. var tick = (Date.now() - lastTick) / len; lastTick = Date.now(); vol += diff * tick; // Make sure the volume is in the right bounds. vol = Math.max(0, vol); vol = Math.min(1, vol); // Round to within 2 decimal points. vol = Math.round(vol * 100) / 100; // Change the volume. if (self._webAudio) { sound._volume = vol; } else { self.volume(vol, sound._id, true); } // Set the group's volume. if (isGroup) { self._volume = vol; } // When the fade is complete, stop it and fire event. if ((to < from && vol <= to) || (to > from && vol >= to)) { clearInterval(sound._interval); sound._interval = null; sound._fadeTo = null; self.volume(to, sound._id); self._emit('fade', sound._id); } }, stepLen); }, /** * Internal method that stops the currently playing fade when * a new fade starts, volume is changed or the sound is stopped. * @param {Number} id The sound id. * @return {Howl} */ _stopFade: function(id) { var self = this; var sound = self._soundById(id); if (sound && sound._interval) { if (self._webAudio) { sound._node.gain.cancelScheduledValues(Howler.ctx.currentTime); } clearInterval(sound._interval); sound._interval = null; self.volume(sound._fadeTo, id); sound._fadeTo = null; self._emit('fade', id); } return self; }, /** * Get/set the loop parameter on a sound. This method can optionally take 0, 1 or 2 arguments. * loop() -> Returns the group's loop value. * loop(id) -> Returns the sound id's loop value. * loop(loop) -> Sets the loop value for all sounds in this Howl group. * loop(loop, id) -> Sets the loop value of passed sound id. * @return {Howl/Boolean} Returns self or current loop value. */ loop: function() { var self = this; var args = arguments; var loop, id, sound; // Determine the values for loop and id. if (args.length === 0) { // Return the grou's loop value. return self._loop; } else if (args.length === 1) { if (typeof args[0] === 'boolean') { loop = args[0]; self._loop = loop; } else { // Return this sound's loop value. sound = self._soundById(parseInt(args[0], 10)); return sound ? sound._loop : false; } } else if (args.length === 2) { loop = args[0]; id = parseInt(args[1], 10); } // If no id is passed, get all ID's to be looped. var ids = self._getSoundIds(id); for (var i=0; i Returns the first sound node's current playback rate. * rate(id) -> Returns the sound id's current playback rate. * rate(rate) -> Sets the playback rate of all sounds in this Howl group. * rate(rate, id) -> Sets the playback rate of passed sound id. * @return {Howl/Number} Returns self or the current playback rate. */ rate: function() { var self = this; var args = arguments; var rate, id; // Determine the values based on arguments. if (args.length === 0) { // We will simply return the current rate of the first node. id = self._sounds[0]._id; } else if (args.length === 1) { // First check if this is an ID, and if not, assume it is a new rate value. var ids = self._getSoundIds(); var index = ids.indexOf(args[0]); if (index >= 0) { id = parseInt(args[0], 10); } else { rate = parseFloat(args[0]); } } else if (args.length === 2) { rate = parseFloat(args[0]); id = parseInt(args[1], 10); } // Update the playback rate or return the current value. var sound; if (typeof rate === 'number') { // If the sound hasn't loaded, add it to the load queue to change playback rate when capable. if (self._state !== 'loaded' || self._playLock) { self._queue.push({ event: 'rate', action: function() { self.rate.apply(self, args); } }); return self; } // Set the group rate. if (typeof id === 'undefined') { self._rate = rate; } // Update one or all volumes. id = self._getSoundIds(id); for (var i=0; i Returns the first sound node's current seek position. * seek(id) -> Returns the sound id's current seek position. * seek(seek) -> Sets the seek position of the first sound node. * seek(seek, id) -> Sets the seek position of passed sound id. * @return {Howl/Number} Returns self or the current seek position. */ seek: function() { var self = this; var args = arguments; var seek, id; // Determine the values based on arguments. if (args.length === 0) { // We will simply return the current position of the first node. id = self._sounds[0]._id; } else if (args.length === 1) { // First check if this is an ID, and if not, assume it is a new seek position. var ids = self._getSoundIds(); var index = ids.indexOf(args[0]); if (index >= 0) { id = parseInt(args[0], 10); } else if (self._sounds.length) { id = self._sounds[0]._id; seek = parseFloat(args[0]); } } else if (args.length === 2) { seek = parseFloat(args[0]); id = parseInt(args[1], 10); } // If there is no ID, bail out. if (typeof id === 'undefined') { return self; } // If the sound hasn't loaded, add it to the load queue to seek when capable. if (self._state !== 'loaded' || self._playLock) { self._queue.push({ event: 'seek', action: function() { self.seek.apply(self, args); } }); return self; } // Get the sound. var sound = self._soundById(id); if (sound) { if (typeof seek === 'number' && seek >= 0) { // Pause the sound and update position for restarting playback. var playing = self.playing(id); if (playing) { self.pause(id, true); } // Move the position of the track and cancel timer. sound._seek = seek; sound._ended = false; self._clearTimer(id); // Update the seek position for HTML5 Audio. if (!self._webAudio && sound._node && !isNaN(sound._node.duration)) { sound._node.currentTime = seek; } // Seek and emit when ready. var seekAndEmit = function() { self._emit('seek', id); // Restart the playback if the sound was playing. if (playing) { self.play(id, true); } }; // Wait for the play lock to be unset before emitting (HTML5 Audio). if (playing && !self._webAudio) { var emitSeek = function() { if (!self._playLock) { seekAndEmit(); } else { setTimeout(emitSeek, 0); } }; setTimeout(emitSeek, 0); } else { seekAndEmit(); } } else { if (self._webAudio) { var realTime = self.playing(id) ? Howler.ctx.currentTime - sound._playStart : 0; var rateSeek = sound._rateSeek ? sound._rateSeek - sound._seek : 0; return sound._seek + (rateSeek + realTime * Math.abs(sound._rate)); } else { return sound._node.currentTime; } } } return self; }, /** * Check if a specific sound is currently playing or not (if id is provided), or check if at least one of the sounds in the group is playing or not. * @param {Number} id The sound id to check. If none is passed, the whole sound group is checked. * @return {Boolean} True if playing and false if not. */ playing: function(id) { var self = this; // Check the passed sound ID (if any). if (typeof id === 'number') { var sound = self._soundById(id); return sound ? !sound._paused : false; } // Otherwise, loop through all sounds and check if any are playing. for (var i=0; i= 0) { Howler._howls.splice(index, 1); } // Delete this sound from the cache (if no other Howl is using it). var remCache = true; for (i=0; i= 0) { remCache = false; break; } } if (cache && remCache) { delete cache[self._src]; } // Clear global errors. Howler.noAudio = false; // Clear out `self`. self._state = 'unloaded'; self._sounds = []; self = null; return null; }, /** * Listen to a custom event. * @param {String} event Event name. * @param {Function} fn Listener to call. * @param {Number} id (optional) Only listen to events for this sound. * @param {Number} once (INTERNAL) Marks event to fire only once. * @return {Howl} */ on: function(event, fn, id, once) { var self = this; var events = self['_on' + event]; if (typeof fn === 'function') { events.push(once ? {id: id, fn: fn, once: once} : {id: id, fn: fn}); } return self; }, /** * Remove a custom event. Call without parameters to remove all events. * @param {String} event Event name. * @param {Function} fn Listener to remove. Leave empty to remove all. * @param {Number} id (optional) Only remove events for this sound. * @return {Howl} */ off: function(event, fn, id) { var self = this; var events = self['_on' + event]; var i = 0; // Allow passing just an event and ID. if (typeof fn === 'number') { id = fn; fn = null; } if (fn || id) { // Loop through event store and remove the passed function. for (i=0; i=0; i--) { // Only fire the listener if the correct ID is used. if (!events[i].id || events[i].id === id || event === 'load') { setTimeout(function(fn) { fn.call(this, id, msg); }.bind(self, events[i].fn), 0); // If this event was setup with `once`, remove it. if (events[i].once) { self.off(event, events[i].fn, events[i].id); } } } // Pass the event type into load queue so that it can continue stepping. self._loadQueue(event); return self; }, /** * Queue of actions initiated before the sound has loaded. * These will be called in sequence, with the next only firing * after the previous has finished executing (even if async like play). * @return {Howl} */ _loadQueue: function(event) { var self = this; if (self._queue.length > 0) { var task = self._queue[0]; // Remove this task if a matching event was passed. if (task.event === event) { self._queue.shift(); self._loadQueue(); } // Run the task if no event type is passed. if (!event) { task.action(); } } return self; }, /** * Fired when playback ends at the end of the duration. * @param {Sound} sound The sound object to work with. * @return {Howl} */ _ended: function(sound) { var self = this; var sprite = sound._sprite; // If we are using IE and there was network latency we may be clipping // audio before it completes playing. Lets check the node to make sure it // believes it has completed, before ending the playback. if (!self._webAudio && sound._node && !sound._node.paused && !sound._node.ended && sound._node.currentTime < sound._stop) { setTimeout(self._ended.bind(self, sound), 100); return self; } // Should this sound loop? var loop = !!(sound._loop || self._sprite[sprite][2]); // Fire the ended event. self._emit('end', sound._id); // Restart the playback for HTML5 Audio loop. if (!self._webAudio && loop) { self.stop(sound._id, true).play(sound._id); } // Restart this timer if on a Web Audio loop. if (self._webAudio && loop) { self._emit('play', sound._id); sound._seek = sound._start || 0; sound._rateSeek = 0; sound._playStart = Howler.ctx.currentTime; var timeout = ((sound._stop - sound._start) * 1000) / Math.abs(sound._rate); self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout); } // Mark the node as paused. if (self._webAudio && !loop) { sound._paused = true; sound._ended = true; sound._seek = sound._start || 0; sound._rateSeek = 0; self._clearTimer(sound._id); // Clean up the buffer source. self._cleanBuffer(sound._node); // Attempt to auto-suspend AudioContext if no sounds are still playing. Howler._autoSuspend(); } // When using a sprite, end the track. if (!self._webAudio && !loop) { self.stop(sound._id, true); } return self; }, /** * Clear the end timer for a sound playback. * @param {Number} id The sound ID. * @return {Howl} */ _clearTimer: function(id) { var self = this; if (self._endTimers[id]) { // Clear the timeout or remove the ended listener. if (typeof self._endTimers[id] !== 'function') { clearTimeout(self._endTimers[id]); } else { var sound = self._soundById(id); if (sound && sound._node) { sound._node.removeEventListener('ended', self._endTimers[id], false); } } delete self._endTimers[id]; } return self; }, /** * Return the sound identified by this ID, or return null. * @param {Number} id Sound ID * @return {Object} Sound object or null. */ _soundById: function(id) { var self = this; // Loop through all sounds and find the one with this ID. for (var i=0; i=0; i--) { if (cnt <= limit) { return; } if (self._sounds[i]._ended) { // Disconnect the audio source when using Web Audio. if (self._webAudio && self._sounds[i]._node) { self._sounds[i]._node.disconnect(0); } // Remove sounds until we have the pool size. self._sounds.splice(i, 1); cnt--; } } }, /** * Get all ID's from the sounds pool. * @param {Number} id Only return one ID if one is passed. * @return {Array} Array of IDs. */ _getSoundIds: function(id) { var self = this; if (typeof id === 'undefined') { var ids = []; for (var i=0; i= 0; if (Howler._scratchBuffer && node.bufferSource) { node.bufferSource.onended = null; node.bufferSource.disconnect(0); if (isIOS) { try { node.bufferSource.buffer = Howler._scratchBuffer; } catch(e) {} } } node.bufferSource = null; return self; }, /** * Set the source to a 0-second silence to stop any downloading (except in IE). * @param {Object} node Audio node to clear. */ _clearSound: function(node) { var checkIE = /MSIE |Trident\//.test(Howler._navigator && Howler._navigator.userAgent); if (!checkIE) { node.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA'; } } }; /** Single Sound Methods **/ /***************************************************************************/ /** * Setup the sound object, which each node attached to a Howl group is contained in. * @param {Object} howl The Howl parent group. */ var Sound = function(howl) { this._parent = howl; this.init(); }; Sound.prototype = { /** * Initialize a new Sound object. * @return {Sound} */ init: function() { var self = this; var parent = self._parent; // Setup the default parameters. self._muted = parent._muted; self._loop = parent._loop; self._volume = parent._volume; self._rate = parent._rate; self._seek = 0; self._paused = true; self._ended = true; self._sprite = '__default'; // Generate a unique ID for this sound. self._id = ++Howler._counter; // Add itself to the parent's pool. parent._sounds.push(self); // Create the new node. self.create(); return self; }, /** * Create and setup a new sound object, whether HTML5 Audio or Web Audio. * @return {Sound} */ create: function() { var self = this; var parent = self._parent; var volume = (Howler._muted || self._muted || self._parent._muted) ? 0 : self._volume; if (parent._webAudio) { // Create the gain node for controlling volume (the source will connect to this). self._node = (typeof Howler.ctx.createGain === 'undefined') ? Howler.ctx.createGainNode() : Howler.ctx.createGain(); self._node.gain.setValueAtTime(volume, Howler.ctx.currentTime); self._node.paused = true; self._node.connect(Howler.masterGain); } else if (!Howler.noAudio) { // Get an unlocked Audio object from the pool. self._node = Howler._obtainHtml5Audio(); // Listen for errors (http://dev.w3.org/html5/spec-author-view/spec.html#mediaerror). self._errorFn = self._errorListener.bind(self); self._node.addEventListener('error', self._errorFn, false); // Listen for 'canplaythrough' event to let us know the sound is ready. self._loadFn = self._loadListener.bind(self); self._node.addEventListener(Howler._canPlayEvent, self._loadFn, false); // Setup the new audio node. self._node.src = parent._src; self._node.preload = 'auto'; self._node.volume = volume * Howler.volume(); // Begin loading the source. self._node.load(); } return self; }, /** * Reset the parameters of this sound to the original state (for recycle). * @return {Sound} */ reset: function() { var self = this; var parent = self._parent; // Reset all of the parameters of this sound. self._muted = parent._muted; self._loop = parent._loop; self._volume = parent._volume; self._rate = parent._rate; self._seek = 0; self._rateSeek = 0; self._paused = true; self._ended = true; self._sprite = '__default'; // Generate a new ID so that it isn't confused with the previous sound. self._id = ++Howler._counter; return self; }, /** * HTML5 Audio error listener callback. */ _errorListener: function() { var self = this; // Fire an error event and pass back the code. self._parent._emit('loaderror', self._id, self._node.error ? self._node.error.code : 0); // Clear the event listener. self._node.removeEventListener('error', self._errorFn, false); }, /** * HTML5 Audio canplaythrough listener callback. */ _loadListener: function() { var self = this; var parent = self._parent; // Round up the duration to account for the lower precision in HTML5 Audio. parent._duration = Math.ceil(self._node.duration * 10) / 10; // Setup a sprite if none is defined. if (Object.keys(parent._sprite).length === 0) { parent._sprite = {__default: [0, parent._duration * 1000]}; } if (parent._state !== 'loaded') { parent._state = 'loaded'; parent._emit('load'); parent._loadQueue(); } // Clear the event listener. self._node.removeEventListener(Howler._canPlayEvent, self._loadFn, false); } }; /** Helper Methods **/ /***************************************************************************/ var cache = {}; /** * Buffer a sound from URL, Data URI or cache and decode to audio source (Web Audio API). * @param {Howl} self */ var loadBuffer = function(self) { var url = self._src; // Check if the buffer has already been cached and use it instead. if (cache[url]) { // Set the duration from the cache. self._duration = cache[url].duration; // Load the sound into this Howl. loadSound(self); return; } if (/^data:[^;]+;base64,/.test(url)) { // Decode the base64 data URI without XHR, since some browsers don't support it. var data = atob(url.split(',')[1]); var dataView = new Uint8Array(data.length); for (var i=0; i 0) { cache[self._src] = buffer; loadSound(self, buffer); } else { error(); } }; // Decode the buffer into an audio source. if (typeof Promise !== 'undefined' && Howler.ctx.decodeAudioData.length === 1) { Howler.ctx.decodeAudioData(arraybuffer).then(success).catch(error); } else { Howler.ctx.decodeAudioData(arraybuffer, success, error); } } /** * Sound is now loaded, so finish setting everything up and fire the loaded event. * @param {Howl} self * @param {Object} buffer The decoded buffer sound source. */ var loadSound = function(self, buffer) { // Set the duration. if (buffer && !self._duration) { self._duration = buffer.duration; } // Setup a sprite if none is defined. if (Object.keys(self._sprite).length === 0) { self._sprite = {__default: [0, self._duration * 1000]}; } // Fire the loaded event. if (self._state !== 'loaded') { self._state = 'loaded'; self._emit('load'); self._loadQueue(); } }; /** * Setup the audio context when available, or switch to HTML5 Audio mode. */ var setupAudioContext = function() { // If we have already detected that Web Audio isn't supported, don't run this step again. if (!Howler.usingWebAudio) { return; } // Check if we are using Web Audio and setup the AudioContext if we are. try { if (typeof AudioContext !== 'undefined') { Howler.ctx = new AudioContext(); } else if (typeof webkitAudioContext !== 'undefined') { Howler.ctx = new webkitAudioContext(); } else { Howler.usingWebAudio = false; } } catch(e) { Howler.usingWebAudio = false; } // If the audio context creation still failed, set using web audio to false. if (!Howler.ctx) { Howler.usingWebAudio = false; } // Check if a webview is being used on iOS8 or earlier (rather than the browser). // If it is, disable Web Audio as it causes crashing. var iOS = (/iP(hone|od|ad)/.test(Howler._navigator && Howler._navigator.platform)); var appVersion = Howler._navigator && Howler._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); var version = appVersion ? parseInt(appVersion[1], 10) : null; if (iOS && version && version < 9) { var safari = /safari/.test(Howler._navigator && Howler._navigator.userAgent.toLowerCase()); if (Howler._navigator && Howler._navigator.standalone && !safari || Howler._navigator && !Howler._navigator.standalone && !safari) { Howler.usingWebAudio = false; } } // Create and expose the master GainNode when using Web Audio (useful for plugins or advanced usage). if (Howler.usingWebAudio) { Howler.masterGain = (typeof Howler.ctx.createGain === 'undefined') ? Howler.ctx.createGainNode() : Howler.ctx.createGain(); Howler.masterGain.gain.setValueAtTime(Howler._muted ? 0 : Howler._volume, Howler.ctx.currentTime); Howler.masterGain.connect(Howler.ctx.destination); } // Re-run the setup on Howler. Howler._setup(); }; // Add support for AMD (Asynchronous Module Definition) libraries such as require.js. if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { return { Howler: Howler, Howl: Howl }; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } // Add support for CommonJS libraries such as browserify. if (true) { exports.Howler = Howler; exports.Howl = Howl; } // Define globally in case AMD is not available or unused. if (typeof window !== 'undefined') { window.HowlerGlobal = HowlerGlobal; window.Howler = Howler; window.Howl = Howl; window.Sound = Sound; } else if (typeof global !== 'undefined') { // Add to global in Node.js (for testing, etc). global.HowlerGlobal = HowlerGlobal; global.Howler = Howler; global.Howl = Howl; global.Sound = Sound; } })(); /*! * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported. * * howler.js v2.1.3 * howlerjs.com * * (c) 2013-2019, James Simpson of GoldFire Studios * goldfirestudios.com * * MIT License */ (function() { 'use strict'; // Setup default properties. HowlerGlobal.prototype._pos = [0, 0, 0]; HowlerGlobal.prototype._orientation = [0, 0, -1, 0, 1, 0]; /** Global Methods **/ /***************************************************************************/ /** * Helper method to update the stereo panning position of all current Howls. * Future Howls will not use this value unless explicitly set. * @param {Number} pan A value of -1.0 is all the way left and 1.0 is all the way right. * @return {Howler/Number} Self or current stereo panning value. */ HowlerGlobal.prototype.stereo = function(pan) { var self = this; // Stop right here if not using Web Audio. if (!self.ctx || !self.ctx.listener) { return self; } // Loop through all Howls and update their stereo panning. for (var i=self._howls.length-1; i>=0; i--) { self._howls[i].stereo(pan); } return self; }; /** * Get/set the position of the listener in 3D cartesian space. Sounds using * 3D position will be relative to the listener's position. * @param {Number} x The x-position of the listener. * @param {Number} y The y-position of the listener. * @param {Number} z The z-position of the listener. * @return {Howler/Array} Self or current listener position. */ HowlerGlobal.prototype.pos = function(x, y, z) { var self = this; // Stop right here if not using Web Audio. if (!self.ctx || !self.ctx.listener) { return self; } // Set the defaults for optional 'y' & 'z'. y = (typeof y !== 'number') ? self._pos[1] : y; z = (typeof z !== 'number') ? self._pos[2] : z; if (typeof x === 'number') { self._pos = [x, y, z]; if (typeof self.ctx.listener.positionX !== 'undefined') { self.ctx.listener.positionX.setTargetAtTime(self._pos[0], Howler.ctx.currentTime, 0.1); self.ctx.listener.positionY.setTargetAtTime(self._pos[1], Howler.ctx.currentTime, 0.1); self.ctx.listener.positionZ.setTargetAtTime(self._pos[2], Howler.ctx.currentTime, 0.1); } else { self.ctx.listener.setPosition(self._pos[0], self._pos[1], self._pos[2]); } } else { return self._pos; } return self; }; /** * Get/set the direction the listener is pointing in the 3D cartesian space. * A front and up vector must be provided. The front is the direction the * face of the listener is pointing, and up is the direction the top of the * listener is pointing. Thus, these values are expected to be at right angles * from each other. * @param {Number} x The x-orientation of the listener. * @param {Number} y The y-orientation of the listener. * @param {Number} z The z-orientation of the listener. * @param {Number} xUp The x-orientation of the top of the listener. * @param {Number} yUp The y-orientation of the top of the listener. * @param {Number} zUp The z-orientation of the top of the listener. * @return {Howler/Array} Returns self or the current orientation vectors. */ HowlerGlobal.prototype.orientation = function(x, y, z, xUp, yUp, zUp) { var self = this; // Stop right here if not using Web Audio. if (!self.ctx || !self.ctx.listener) { return self; } // Set the defaults for optional 'y' & 'z'. var or = self._orientation; y = (typeof y !== 'number') ? or[1] : y; z = (typeof z !== 'number') ? or[2] : z; xUp = (typeof xUp !== 'number') ? or[3] : xUp; yUp = (typeof yUp !== 'number') ? or[4] : yUp; zUp = (typeof zUp !== 'number') ? or[5] : zUp; if (typeof x === 'number') { self._orientation = [x, y, z, xUp, yUp, zUp]; if (typeof self.ctx.listener.forwardX !== 'undefined') { self.ctx.listener.forwardX.setTargetAtTime(x, Howler.ctx.currentTime, 0.1); self.ctx.listener.forwardY.setTargetAtTime(y, Howler.ctx.currentTime, 0.1); self.ctx.listener.forwardZ.setTargetAtTime(z, Howler.ctx.currentTime, 0.1); self.ctx.listener.upX.setTargetAtTime(xUp, Howler.ctx.currentTime, 0.1); self.ctx.listener.upY.setTargetAtTime(yUp, Howler.ctx.currentTime, 0.1); self.ctx.listener.upZ.setTargetAtTime(zUp, Howler.ctx.currentTime, 0.1); } else { self.ctx.listener.setOrientation(x, y, z, xUp, yUp, zUp); } } else { return or; } return self; }; /** Group Methods **/ /***************************************************************************/ /** * Add new properties to the core init. * @param {Function} _super Core init method. * @return {Howl} */ Howl.prototype.init = (function(_super) { return function(o) { var self = this; // Setup user-defined default properties. self._orientation = o.orientation || [1, 0, 0]; self._stereo = o.stereo || null; self._pos = o.pos || null; self._pannerAttr = { coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : 360, coneOuterAngle: typeof o.coneOuterAngle !== 'undefined' ? o.coneOuterAngle : 360, coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : 0, distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : 'inverse', maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : 10000, panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : 'HRTF', refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : 1, rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : 1 }; // Setup event listeners. self._onstereo = o.onstereo ? [{fn: o.onstereo}] : []; self._onpos = o.onpos ? [{fn: o.onpos}] : []; self._onorientation = o.onorientation ? [{fn: o.onorientation}] : []; // Complete initilization with howler.js core's init function. return _super.call(this, o); }; })(Howl.prototype.init); /** * Get/set the stereo panning of the audio source for this sound or all in the group. * @param {Number} pan A value of -1.0 is all the way left and 1.0 is all the way right. * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated. * @return {Howl/Number} Returns self or the current stereo panning value. */ Howl.prototype.stereo = function(pan, id) { var self = this; // Stop right here if not using Web Audio. if (!self._webAudio) { return self; } // If the sound hasn't loaded, add it to the load queue to change stereo pan when capable. if (self._state !== 'loaded') { self._queue.push({ event: 'stereo', action: function() { self.stereo(pan, id); } }); return self; } // Check for PannerStereoNode support and fallback to PannerNode if it doesn't exist. var pannerType = (typeof Howler.ctx.createStereoPanner === 'undefined') ? 'spatial' : 'stereo'; // Setup the group's stereo panning if no ID is passed. if (typeof id === 'undefined') { // Return the group's stereo panning if no parameters are passed. if (typeof pan === 'number') { self._stereo = pan; self._pos = [pan, 0, 0]; } else { return self._stereo; } } // Change the streo panning of one or all sounds in group. var ids = self._getSoundIds(id); for (var i=0; i Returns the group's values. * pannerAttr(id) -> Returns the sound id's values. * pannerAttr(o) -> Set's the values of all sounds in this Howl group. * pannerAttr(o, id) -> Set's the values of passed sound id. * * Attributes: * coneInnerAngle - (360 by default) A parameter for directional audio sources, this is an angle, in degrees, * inside of which there will be no volume reduction. * coneOuterAngle - (360 by default) A parameter for directional audio sources, this is an angle, in degrees, * outside of which the volume will be reduced to a constant value of `coneOuterGain`. * coneOuterGain - (0 by default) A parameter for directional audio sources, this is the gain outside of the * `coneOuterAngle`. It is a linear value in the range `[0, 1]`. * distanceModel - ('inverse' by default) Determines algorithm used to reduce volume as audio moves away from * listener. Can be `linear`, `inverse` or `exponential. * maxDistance - (10000 by default) The maximum distance between source and listener, after which the volume * will not be reduced any further. * refDistance - (1 by default) A reference distance for reducing volume as source moves further from the listener. * This is simply a variable of the distance model and has a different effect depending on which model * is used and the scale of your coordinates. Generally, volume will be equal to 1 at this distance. * rolloffFactor - (1 by default) How quickly the volume reduces as source moves from listener. This is simply a * variable of the distance model and can be in the range of `[0, 1]` with `linear` and `[0, ∞]` * with `inverse` and `exponential`. * panningModel - ('HRTF' by default) Determines which spatialization algorithm is used to position audio. * Can be `HRTF` or `equalpower`. * * @return {Howl/Object} Returns self or current panner attributes. */ Howl.prototype.pannerAttr = function() { var self = this; var args = arguments; var o, id, sound; // Stop right here if not using Web Audio. if (!self._webAudio) { return self; } // Determine the values based on arguments. if (args.length === 0) { // Return the group's panner attribute values. return self._pannerAttr; } else if (args.length === 1) { if (typeof args[0] === 'object') { o = args[0]; // Set the grou's panner attribute values. if (typeof id === 'undefined') { if (!o.pannerAttr) { o.pannerAttr = { coneInnerAngle: o.coneInnerAngle, coneOuterAngle: o.coneOuterAngle, coneOuterGain: o.coneOuterGain, distanceModel: o.distanceModel, maxDistance: o.maxDistance, refDistance: o.refDistance, rolloffFactor: o.rolloffFactor, panningModel: o.panningModel }; } self._pannerAttr = { coneInnerAngle: typeof o.pannerAttr.coneInnerAngle !== 'undefined' ? o.pannerAttr.coneInnerAngle : self._coneInnerAngle, coneOuterAngle: typeof o.pannerAttr.coneOuterAngle !== 'undefined' ? o.pannerAttr.coneOuterAngle : self._coneOuterAngle, coneOuterGain: typeof o.pannerAttr.coneOuterGain !== 'undefined' ? o.pannerAttr.coneOuterGain : self._coneOuterGain, distanceModel: typeof o.pannerAttr.distanceModel !== 'undefined' ? o.pannerAttr.distanceModel : self._distanceModel, maxDistance: typeof o.pannerAttr.maxDistance !== 'undefined' ? o.pannerAttr.maxDistance : self._maxDistance, refDistance: typeof o.pannerAttr.refDistance !== 'undefined' ? o.pannerAttr.refDistance : self._refDistance, rolloffFactor: typeof o.pannerAttr.rolloffFactor !== 'undefined' ? o.pannerAttr.rolloffFactor : self._rolloffFactor, panningModel: typeof o.pannerAttr.panningModel !== 'undefined' ? o.pannerAttr.panningModel : self._panningModel }; } } else { // Return this sound's panner attribute values. sound = self._soundById(parseInt(args[0], 10)); return sound ? sound._pannerAttr : self._pannerAttr; } } else if (args.length === 2) { o = args[0]; id = parseInt(args[1], 10); } // Update the values of the specified sounds. var ids = self._getSoundIds(id); for (var i=0; i value === null || value === undefined; function encoderForArrayFormat(options) { switch (options.arrayFormat) { case 'index': return key => (result, value) => { const index = result.length; if ( value === undefined || (options.skipNull && value === null) || (options.skipEmptyString && value === '') ) { return result; } if (value === null) { return [...result, [encode(key, options), '[', index, ']'].join('')]; } return [ ...result, [encode(key, options), '[', encode(index, options), ']=', encode(value, options)].join('') ]; }; case 'bracket': return key => (result, value) => { if ( value === undefined || (options.skipNull && value === null) || (options.skipEmptyString && value === '') ) { return result; } if (value === null) { return [...result, [encode(key, options), '[]'].join('')]; } return [...result, [encode(key, options), '[]=', encode(value, options)].join('')]; }; case 'comma': case 'separator': return key => (result, value) => { if (value === null || value === undefined || value.length === 0) { return result; } if (result.length === 0) { return [[encode(key, options), '=', encode(value, options)].join('')]; } return [[result, encode(value, options)].join(options.arrayFormatSeparator)]; }; default: return key => (result, value) => { if ( value === undefined || (options.skipNull && value === null) || (options.skipEmptyString && value === '') ) { return result; } if (value === null) { return [...result, encode(key, options)]; } return [...result, [encode(key, options), '=', encode(value, options)].join('')]; }; } } function parserForArrayFormat(options) { let result; switch (options.arrayFormat) { case 'index': return (key, value, accumulator) => { result = /\[(\d*)\]$/.exec(key); key = key.replace(/\[\d*\]$/, ''); if (!result) { accumulator[key] = value; return; } if (accumulator[key] === undefined) { accumulator[key] = {}; } accumulator[key][result[1]] = value; }; case 'bracket': return (key, value, accumulator) => { result = /(\[\])$/.exec(key); key = key.replace(/\[\]$/, ''); if (!result) { accumulator[key] = value; return; } if (accumulator[key] === undefined) { accumulator[key] = [value]; return; } accumulator[key] = [].concat(accumulator[key], value); }; case 'comma': case 'separator': return (key, value, accumulator) => { const isArray = typeof value === 'string' && value.split('').indexOf(options.arrayFormatSeparator) > -1; const newValue = isArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : value === null ? value : decode(value, options); accumulator[key] = newValue; }; default: return (key, value, accumulator) => { if (accumulator[key] === undefined) { accumulator[key] = value; return; } accumulator[key] = [].concat(accumulator[key], value); }; } } function validateArrayFormatSeparator(value) { if (typeof value !== 'string' || value.length !== 1) { throw new TypeError('arrayFormatSeparator must be single character string'); } } function encode(value, options) { if (options.encode) { return options.strict ? strictUriEncode(value) : encodeURIComponent(value); } return value; } function decode(value, options) { if (options.decode) { return decodeComponent(value); } return value; } function keysSorter(input) { if (Array.isArray(input)) { return input.sort(); } if (typeof input === 'object') { return keysSorter(Object.keys(input)) .sort((a, b) => Number(a) - Number(b)) .map(key => input[key]); } return input; } function removeHash(input) { const hashStart = input.indexOf('#'); if (hashStart !== -1) { input = input.slice(0, hashStart); } return input; } function getHash(url) { let hash = ''; const hashStart = url.indexOf('#'); if (hashStart !== -1) { hash = url.slice(hashStart); } return hash; } function extract(input) { input = removeHash(input); const queryStart = input.indexOf('?'); if (queryStart === -1) { return ''; } return input.slice(queryStart + 1); } function parseValue(value, options) { if (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) { value = Number(value); } else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) { value = value.toLowerCase() === 'true'; } return value; } function parse(input, options) { options = Object.assign({ decode: true, sort: true, arrayFormat: 'none', arrayFormatSeparator: ',', parseNumbers: false, parseBooleans: false }, options); validateArrayFormatSeparator(options.arrayFormatSeparator); const formatter = parserForArrayFormat(options); // Create an object with no prototype const ret = Object.create(null); if (typeof input !== 'string') { return ret; } input = input.trim().replace(/^[?#&]/, ''); if (!input) { return ret; } for (const param of input.split('&')) { let [key, value] = splitOnFirst(options.decode ? param.replace(/\+/g, ' ') : param, '='); // Missing `=` should be `null`: // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters value = value === undefined ? null : ['comma', 'separator'].includes(options.arrayFormat) ? value : decode(value, options); formatter(decode(key, options), value, ret); } for (const key of Object.keys(ret)) { const value = ret[key]; if (typeof value === 'object' && value !== null) { for (const k of Object.keys(value)) { value[k] = parseValue(value[k], options); } } else { ret[key] = parseValue(value, options); } } if (options.sort === false) { return ret; } return (options.sort === true ? Object.keys(ret).sort() : Object.keys(ret).sort(options.sort)).reduce((result, key) => { const value = ret[key]; if (Boolean(value) && typeof value === 'object' && !Array.isArray(value)) { // Sort object keys, not values result[key] = keysSorter(value); } else { result[key] = value; } return result; }, Object.create(null)); } exports.extract = extract; exports.parse = parse; exports.stringify = (object, options) => { if (!object) { return ''; } options = Object.assign({ encode: true, strict: true, arrayFormat: 'none', arrayFormatSeparator: ',' }, options); validateArrayFormatSeparator(options.arrayFormatSeparator); const shouldFilter = key => ( (options.skipNull && isNullOrUndefined(object[key])) || (options.skipEmptyString && object[key] === '') ); const formatter = encoderForArrayFormat(options); const objectCopy = {}; for (const key of Object.keys(object)) { if (!shouldFilter(key)) { objectCopy[key] = object[key]; } } const keys = Object.keys(objectCopy); if (options.sort !== false) { keys.sort(options.sort); } return keys.map(key => { const value = object[key]; if (value === undefined) { return ''; } if (value === null) { return encode(key, options); } if (Array.isArray(value)) { return value .reduce(formatter(key), []) .join('&'); } return encode(key, options) + '=' + encode(value, options); }).filter(x => x.length > 0).join('&'); }; exports.parseUrl = (input, options) => { return { url: removeHash(input).split('?')[0] || '', query: parse(extract(input), options) }; }; exports.stringifyUrl = (input, options) => { const url = removeHash(input.url).split('?')[0] || ''; const queryFromUrl = exports.extract(input.url); const parsedQueryFromUrl = exports.parse(queryFromUrl); const hash = getHash(input.url); const query = Object.assign(parsedQueryFromUrl, input.query); let queryString = exports.stringify(query, options); if (queryString) { queryString = `?${queryString}`; } return `${url}${queryString}${hash}`; }; /***/ }), /***/ "./node_modules/rusha/dist/rusha.js": /*!******************************************!*\ !*** ./node_modules/rusha/dist/rusha.js ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { (function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(); else {} })(typeof self !== 'undefined' ? self : this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(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 module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 3); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* eslint-env commonjs, browser */ var RushaCore = __webpack_require__(5); var _require = __webpack_require__(1), toHex = _require.toHex, ceilHeapSize = _require.ceilHeapSize; var conv = __webpack_require__(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; }(); module.exports = Rusha; module.exports._core = RushaCore; /***/ }), /* 1 */ /***/ (function(module, exports) { /* 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); } module.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 // module.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 // module.exports.isDedicatedWorkerScope = function (self) { var isRunningInWorker = 'WorkerGlobalScope' in self && self instanceof self.WorkerGlobalScope; var isRunningInSharedWorker = 'SharedWorkerGlobalScope' in self && self instanceof self.SharedWorkerGlobalScope; var isRunningInServiceWorker = 'ServiceWorkerGlobalScope' in self && self instanceof self.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(module, exports, __webpack_require__) { /* eslint-env commonjs, worker */ module.exports = function () { var Rusha = __webpack_require__(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(module, exports, __webpack_require__) { /* eslint-env commonjs, browser */ var work = __webpack_require__(4); var Rusha = __webpack_require__(0); var createHash = __webpack_require__(7); var runWorker = __webpack_require__(2); var _require = __webpack_require__(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; module.exports = Rusha; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { function webpackBootstrapFunc (modules) { /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(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 module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.l = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/"; /******/ // on error function for async loading /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; var f = __webpack_require__(__webpack_require__.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, module, queueName) { var retval = {} retval[queueName] = [] var fnString = module.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]] = __webpack_require__(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 } module.exports = function (moduleId, options) { options = options || {} var sources = { main: __webpack_require__.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 (module) { var entryModule = 0 while (requiredModules[module][entryModule]) { entryModule++ } requiredModules[module].push(entryModule) sources[module][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })' src = src + 'var ' + module + ' = (' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(entryModule)) + ')({' + requiredModules[module].map(function (id) { return '' + JSON.stringify(id) + ': ' + sources[module][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 URL = window.URL || window.webkitURL || window.mozURL || window.msURL var workerUrl = URL.createObjectURL(blob) var worker = new window.Worker(workerUrl) worker.objectURL = workerUrl return worker } /***/ }), /* 5 */ /***/ (function(module, exports) { // 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. module.exports = function RushaCore(stdlib$846, foreign$847, heap$848) { 'use asm'; var H$849 = new stdlib$846.Int32Array(heap$848); function hash$850(k$851, x$852) { // k in bytes k$851 = k$851 | 0; x$852 = x$852 | 0; var i$853 = 0, j$854 = 0, y0$855 = 0, z0$856 = 0, y1$857 = 0, z1$858 = 0, y2$859 = 0, z2$860 = 0, y3$861 = 0, z3$862 = 0, y4$863 = 0, z4$864 = 0, t0$865 = 0, t1$866 = 0; y0$855 = H$849[x$852 + 320 >> 2] | 0; y1$857 = H$849[x$852 + 324 >> 2] | 0; y2$859 = H$849[x$852 + 328 >> 2] | 0; y3$861 = H$849[x$852 + 332 >> 2] | 0; y4$863 = H$849[x$852 + 336 >> 2] | 0; for (i$853 = 0; (i$853 | 0) < (k$851 | 0); i$853 = i$853 + 64 | 0) { z0$856 = y0$855; z1$858 = y1$857; z2$860 = y2$859; z3$862 = y3$861; z4$864 = y4$863; for (j$854 = 0; (j$854 | 0) < 64; j$854 = j$854 + 4 | 0) { t1$866 = H$849[i$853 + j$854 >> 2] | 0; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | ~y1$857 & y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1518500249 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[k$851 + j$854 >> 2] = t1$866; } for (j$854 = k$851 + 64 | 0; (j$854 | 0) < (k$851 + 80 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | ~y1$857 & y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1518500249 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } for (j$854 = k$851 + 80 | 0; (j$854 | 0) < (k$851 + 160 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 ^ y2$859 ^ y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1859775393 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } for (j$854 = k$851 + 160 | 0; (j$854 | 0) < (k$851 + 240 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | y1$857 & y3$861 | y2$859 & y3$861) | 0) + ((t1$866 + y4$863 | 0) - 1894007588 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } for (j$854 = k$851 + 240 | 0; (j$854 | 0) < (k$851 + 320 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 ^ y2$859 ^ y3$861) | 0) + ((t1$866 + y4$863 | 0) - 899497514 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } y0$855 = y0$855 + z0$856 | 0; y1$857 = y1$857 + z1$858 | 0; y2$859 = y2$859 + z2$860 | 0; y3$861 = y3$861 + z3$862 | 0; y4$863 = y4$863 + z4$864 | 0; } H$849[x$852 + 320 >> 2] = y0$855; H$849[x$852 + 324 >> 2] = y1$857; H$849[x$852 + 328 >> 2] = y2$859; H$849[x$852 + 332 >> 2] = y3$861; H$849[x$852 + 336 >> 2] = y4$863; } return { hash: hash$850 }; }; /***/ }), /* 6 */ /***/ (function(module, exports) { 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]; } }; module.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(module, exports, __webpack_require__) { function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* eslint-env commonjs, browser */ var Rusha = __webpack_require__(0); var _require = __webpack_require__(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'); }; return Hash; }(); module.exports = function () { return new Hash(); }; /***/ }) /******/ ]); }); /***/ }), /***/ "./node_modules/split-on-first/index.js": /*!**********************************************!*\ !*** ./node_modules/split-on-first/index.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = (string, separator) => { if (!(typeof string === 'string' && typeof separator === 'string')) { throw new TypeError('Expected the arguments to be of type `string`'); } if (separator === '') { return [string]; } const separatorIndex = string.indexOf(separator); if (separatorIndex === -1) { return [string]; } return [ string.slice(0, separatorIndex), string.slice(separatorIndex + separator.length) ]; }; /***/ }), /***/ "./node_modules/strict-uri-encode/index.js": /*!*************************************************!*\ !*** ./node_modules/strict-uri-encode/index.js ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = str => encodeURIComponent(str).replace(/[!'()*]/g, x => `%${x.charCodeAt(0).toString(16).toUpperCase()}`); /***/ }), /***/ "./node_modules/trim/index.js": /*!************************************!*\ !*** ./node_modules/trim/index.js ***! \************************************/ /*! no static exports found */ /***/ (function(module, exports) { exports = module.exports = trim; function trim(str){ return str.replace(/^\s*|\s*$/g, ''); } exports.left = function(str){ return str.replace(/^\s*/, ''); }; exports.right = function(str){ return str.replace(/\s*$/, ''); }; /***/ }), /***/ "./node_modules/uri-js/dist/es5/uri.all.js": /*!*************************************************!*\ !*** ./node_modules/uri-js/dist/es5/uri.all.js ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { /** @license URI.js v4.2.1 (c) 2011 Gary Court. License: http://github.com/garycourt/uri-js */ (function (global, factory) { true ? factory(exports) : undefined; }(this, (function (exports) { 'use strict'; function merge() { for (var _len = arguments.length, sets = Array(_len), _key = 0; _key < _len; _key++) { sets[_key] = arguments[_key]; } if (sets.length > 1) { sets[0] = sets[0].slice(0, -1); var xl = sets.length - 1; for (var x = 1; x < xl; ++x) { sets[x] = sets[x].slice(1, -1); } sets[xl] = sets[xl].slice(1); return sets.join(''); } else { return sets[0]; } } function subexp(str) { return "(?:" + str + ")"; } function typeOf(o) { return o === undefined ? "undefined" : o === null ? "null" : Object.prototype.toString.call(o).split(" ").pop().split("]").shift().toLowerCase(); } function toUpperCase(str) { return str.toUpperCase(); } function toArray(obj) { return obj !== undefined && obj !== null ? obj instanceof Array ? obj : typeof obj.length !== "number" || obj.split || obj.setInterval || obj.call ? [obj] : Array.prototype.slice.call(obj) : []; } function assign(target, source) { var obj = target; if (source) { for (var key in source) { obj[key] = source[key]; } } return obj; } function buildExps(isIRI) { var ALPHA$$ = "[A-Za-z]", CR$ = "[\\x0D]", DIGIT$$ = "[0-9]", DQUOTE$$ = "[\\x22]", HEXDIG$$ = merge(DIGIT$$, "[A-Fa-f]"), //case-insensitive LF$$ = "[\\x0A]", SP$$ = "[\\x20]", PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)), //expanded GEN_DELIMS$$ = "[\\:\\/\\?\\#\\[\\]\\@]", SUB_DELIMS$$ = "[\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=]", RESERVED$$ = merge(GEN_DELIMS$$, SUB_DELIMS$$), UCSCHAR$$ = isIRI ? "[\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]" : "[]", //subset, excludes bidi control characters IPRIVATE$$ = isIRI ? "[\\uE000-\\uF8FF]" : "[]", //subset UNRESERVED$$ = merge(ALPHA$$, DIGIT$$, "[\\-\\.\\_\\~]", UCSCHAR$$), SCHEME$ = subexp(ALPHA$$ + merge(ALPHA$$, DIGIT$$, "[\\+\\-\\.]") + "*"), USERINFO$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]")) + "*"), DEC_OCTET$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("[1-9]" + DIGIT$$) + "|" + DIGIT$$), DEC_OCTET_RELAXED$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("0?[1-9]" + DIGIT$$) + "|0?0?" + DIGIT$$), //relaxed parsing rules IPV4ADDRESS$ = subexp(DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$), H16$ = subexp(HEXDIG$$ + "{1,4}"), LS32$ = subexp(subexp(H16$ + "\\:" + H16$) + "|" + IPV4ADDRESS$), IPV6ADDRESS1$ = subexp(subexp(H16$ + "\\:") + "{6}" + LS32$), // 6( h16 ":" ) ls32 IPV6ADDRESS2$ = subexp("\\:\\:" + subexp(H16$ + "\\:") + "{5}" + LS32$), // "::" 5( h16 ":" ) ls32 IPV6ADDRESS3$ = subexp(subexp(H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{4}" + LS32$), //[ h16 ] "::" 4( h16 ":" ) ls32 IPV6ADDRESS4$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,1}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{3}" + LS32$), //[ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 IPV6ADDRESS5$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,2}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{2}" + LS32$), //[ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 IPV6ADDRESS6$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,3}" + H16$) + "?\\:\\:" + H16$ + "\\:" + LS32$), //[ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 IPV6ADDRESS7$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,4}" + H16$) + "?\\:\\:" + LS32$), //[ *4( h16 ":" ) h16 ] "::" ls32 IPV6ADDRESS8$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,5}" + H16$) + "?\\:\\:" + H16$), //[ *5( h16 ":" ) h16 ] "::" h16 IPV6ADDRESS9$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,6}" + H16$) + "?\\:\\:"), //[ *6( h16 ":" ) h16 ] "::" IPV6ADDRESS$ = subexp([IPV6ADDRESS1$, IPV6ADDRESS2$, IPV6ADDRESS3$, IPV6ADDRESS4$, IPV6ADDRESS5$, IPV6ADDRESS6$, IPV6ADDRESS7$, IPV6ADDRESS8$, IPV6ADDRESS9$].join("|")), ZONEID$ = subexp(subexp(UNRESERVED$$ + "|" + PCT_ENCODED$) + "+"), //RFC 6874 IPV6ADDRZ$ = subexp(IPV6ADDRESS$ + "\\%25" + ZONEID$), //RFC 6874 IPV6ADDRZ_RELAXED$ = subexp(IPV6ADDRESS$ + subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + ZONEID$), //RFC 6874, with relaxed parsing rules IPVFUTURE$ = subexp("[vV]" + HEXDIG$$ + "+\\." + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]") + "+"), IP_LITERAL$ = subexp("\\[" + subexp(IPV6ADDRZ_RELAXED$ + "|" + IPV6ADDRESS$ + "|" + IPVFUTURE$) + "\\]"), //RFC 6874 REG_NAME$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$)) + "*"), HOST$ = subexp(IP_LITERAL$ + "|" + IPV4ADDRESS$ + "(?!" + REG_NAME$ + ")" + "|" + REG_NAME$), PORT$ = subexp(DIGIT$$ + "*"), AUTHORITY$ = subexp(subexp(USERINFO$ + "@") + "?" + HOST$ + subexp("\\:" + PORT$) + "?"), PCHAR$ = subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@]")), SEGMENT$ = subexp(PCHAR$ + "*"), SEGMENT_NZ$ = subexp(PCHAR$ + "+"), SEGMENT_NZ_NC$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\@]")) + "+"), PATH_ABEMPTY$ = subexp(subexp("\\/" + SEGMENT$) + "*"), PATH_ABSOLUTE$ = subexp("\\/" + subexp(SEGMENT_NZ$ + PATH_ABEMPTY$) + "?"), //simplified PATH_NOSCHEME$ = subexp(SEGMENT_NZ_NC$ + PATH_ABEMPTY$), //simplified PATH_ROOTLESS$ = subexp(SEGMENT_NZ$ + PATH_ABEMPTY$), //simplified PATH_EMPTY$ = "(?!" + PCHAR$ + ")", PATH$ = subexp(PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), QUERY$ = subexp(subexp(PCHAR$ + "|" + merge("[\\/\\?]", IPRIVATE$$)) + "*"), FRAGMENT$ = subexp(subexp(PCHAR$ + "|[\\/\\?]") + "*"), HIER_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), RELATIVE_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$), RELATIVE$ = subexp(RELATIVE_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), URI_REFERENCE$ = subexp(URI$ + "|" + RELATIVE$), ABSOLUTE_URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?"), GENERIC_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", RELATIVE_REF$ = "^(){0}" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", ABSOLUTE_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?$", SAMEDOC_REF$ = "^" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", AUTHORITY_REF$ = "^" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?$"; return { NOT_SCHEME: new RegExp(merge("[^]", ALPHA$$, DIGIT$$, "[\\+\\-\\.]"), "g"), NOT_USERINFO: new RegExp(merge("[^\\%\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_HOST: new RegExp(merge("[^\\%\\[\\]\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_PATH: new RegExp(merge("[^\\%\\/\\:\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_PATH_NOSCHEME: new RegExp(merge("[^\\%\\/\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_QUERY: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]", IPRIVATE$$), "g"), NOT_FRAGMENT: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]"), "g"), ESCAPE: new RegExp(merge("[^]", UNRESERVED$$, SUB_DELIMS$$), "g"), UNRESERVED: new RegExp(UNRESERVED$$, "g"), OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$, RESERVED$$), "g"), PCT_ENCODED: new RegExp(PCT_ENCODED$, "g"), IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"), IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$") //RFC 6874, with relaxed parsing rules }; } var URI_PROTOCOL = buildExps(false); var IRI_PROTOCOL = buildExps(true); var slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; /** Highest positive signed 32-bit float value */ var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ var base = 36; var tMin = 1; var tMax = 26; var skew = 38; var damp = 700; var initialBias = 72; var initialN = 128; // 0x80 var delimiter = '-'; // '\x2D' /** Regular expressions */ var regexPunycode = /^xn--/; var regexNonASCII = /[^\0-\x7E]/; // non-ASCII chars var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators /** Error messages */ var errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }; /** Convenience shortcuts */ var baseMinusTMin = base - tMin; var floor = Math.floor; var stringFromCharCode = String.fromCharCode; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error$1(type) { throw new RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var result = []; var length = array.length; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = []; var counter = 0; var length = string.length; while (counter < length) { var value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // It's a high surrogate, and there is a next character. var extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // It's an unmatched surrogate; only append this code unit, in case the // next code unit is the high surrogate of a surrogate pair. output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ var ucs2encode = function ucs2encode(array) { return String.fromCodePoint.apply(String, toConsumableArray(array)); }; /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ var basicToDigit = function basicToDigit(codePoint) { if (codePoint - 0x30 < 0x0A) { return codePoint - 0x16; } if (codePoint - 0x41 < 0x1A) { return codePoint - 0x41; } if (codePoint - 0x61 < 0x1A) { return codePoint - 0x61; } return base; }; /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ var digitToBasic = function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); }; /** * Bias adaptation function as per section 3.4 of RFC 3492. * https://tools.ietf.org/html/rfc3492#section-3.4 * @private */ var adapt = function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (; /* no initialization */delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); }; /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ var decode = function decode(input) { // Don't use UCS-2. var output = []; var inputLength = input.length; var i = 0; var n = initialN; var bias = initialBias; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. var basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (var j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error$1('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (var index = basic > 0 ? basic + 1 : 0; index < inputLength;) /* no final expression */{ // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. var oldi = i; for (var w = 1, k = base;; /* no condition */k += base) { if (index >= inputLength) { error$1('invalid-input'); } var digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error$1('overflow'); } i += digit * w; var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; if (digit < t) { break; } var baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error$1('overflow'); } w *= baseMinusT; } var out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error$1('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output. output.splice(i++, 0, n); } return String.fromCodePoint.apply(String, output); }; /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ var encode = function encode(input) { var output = []; // Convert the input in UCS-2 to an array of Unicode code points. input = ucs2decode(input); // Cache the length. var inputLength = input.length; // Initialize the state. var n = initialN; var delta = 0; var bias = initialBias; // Handle the basic code points. var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = input[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _currentValue2 = _step.value; if (_currentValue2 < 0x80) { output.push(stringFromCharCode(_currentValue2)); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var basicLength = output.length; var handledCPCount = basicLength; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string with a delimiter unless it's empty. if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: var m = maxInt; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = input[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var currentValue = _step2.value; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow. } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } var handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error$1('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = input[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _currentValue = _step3.value; if (_currentValue < n && ++delta > maxInt) { error$1('overflow'); } if (_currentValue == n) { // Represent delta as a generalized variable-length integer. var q = delta; for (var k = base;; /* no condition */k += base) { var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; if (q < t) { break; } var qMinusT = q - t; var baseMinusT = base - t; output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } ++delta; ++n; } return output.join(''); }; /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ var toUnicode = function toUnicode(input) { return mapDomain(input, function (string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); }; /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ var toASCII = function toASCII(input) { return mapDomain(input, function (string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); }; /*--------------------------------------------------------------------------*/ /** Define the public API */ var punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '2.1.0', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** * URI.js * * @fileoverview An RFC 3986 compliant, scheme extendable URI parsing/validating/resolving library for JavaScript. * @author Gary Court * @see http://github.com/garycourt/uri-js */ /** * Copyright 2011 Gary Court. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY GARY COURT ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of Gary Court. */ var SCHEMES = {}; function pctEncChar(chr) { var c = chr.charCodeAt(0); var e = void 0; if (c < 16) e = "%0" + c.toString(16).toUpperCase();else if (c < 128) e = "%" + c.toString(16).toUpperCase();else if (c < 2048) e = "%" + (c >> 6 | 192).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase();else e = "%" + (c >> 12 | 224).toString(16).toUpperCase() + "%" + (c >> 6 & 63 | 128).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase(); return e; } function pctDecChars(str) { var newStr = ""; var i = 0; var il = str.length; while (i < il) { var c = parseInt(str.substr(i + 1, 2), 16); if (c < 128) { newStr += String.fromCharCode(c); i += 3; } else if (c >= 194 && c < 224) { if (il - i >= 6) { var c2 = parseInt(str.substr(i + 4, 2), 16); newStr += String.fromCharCode((c & 31) << 6 | c2 & 63); } else { newStr += str.substr(i, 6); } i += 6; } else if (c >= 224) { if (il - i >= 9) { var _c = parseInt(str.substr(i + 4, 2), 16); var c3 = parseInt(str.substr(i + 7, 2), 16); newStr += String.fromCharCode((c & 15) << 12 | (_c & 63) << 6 | c3 & 63); } else { newStr += str.substr(i, 9); } i += 9; } else { newStr += str.substr(i, 3); i += 3; } } return newStr; } function _normalizeComponentEncoding(components, protocol) { function decodeUnreserved(str) { var decStr = pctDecChars(str); return !decStr.match(protocol.UNRESERVED) ? str : decStr; } if (components.scheme) components.scheme = String(components.scheme).replace(protocol.PCT_ENCODED, decodeUnreserved).toLowerCase().replace(protocol.NOT_SCHEME, ""); if (components.userinfo !== undefined) components.userinfo = String(components.userinfo).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_USERINFO, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.host !== undefined) components.host = String(components.host).replace(protocol.PCT_ENCODED, decodeUnreserved).toLowerCase().replace(protocol.NOT_HOST, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.path !== undefined) components.path = String(components.path).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(components.scheme ? protocol.NOT_PATH : protocol.NOT_PATH_NOSCHEME, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.query !== undefined) components.query = String(components.query).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_QUERY, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.fragment !== undefined) components.fragment = String(components.fragment).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_FRAGMENT, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); return components; } function _stripLeadingZeros(str) { return str.replace(/^0*(.*)/, "$1") || "0"; } function _normalizeIPv4(host, protocol) { var matches = host.match(protocol.IPV4ADDRESS) || []; var _matches = slicedToArray(matches, 2), address = _matches[1]; if (address) { return address.split(".").map(_stripLeadingZeros).join("."); } else { return host; } } function _normalizeIPv6(host, protocol) { var matches = host.match(protocol.IPV6ADDRESS) || []; var _matches2 = slicedToArray(matches, 3), address = _matches2[1], zone = _matches2[2]; if (address) { var _address$toLowerCase$ = address.toLowerCase().split('::').reverse(), _address$toLowerCase$2 = slicedToArray(_address$toLowerCase$, 2), last = _address$toLowerCase$2[0], first = _address$toLowerCase$2[1]; var firstFields = first ? first.split(":").map(_stripLeadingZeros) : []; var lastFields = last.split(":").map(_stripLeadingZeros); var isLastFieldIPv4Address = protocol.IPV4ADDRESS.test(lastFields[lastFields.length - 1]); var fieldCount = isLastFieldIPv4Address ? 7 : 8; var lastFieldsStart = lastFields.length - fieldCount; var fields = Array(fieldCount); for (var x = 0; x < fieldCount; ++x) { fields[x] = firstFields[x] || lastFields[lastFieldsStart + x] || ''; } if (isLastFieldIPv4Address) { fields[fieldCount - 1] = _normalizeIPv4(fields[fieldCount - 1], protocol); } var allZeroFields = fields.reduce(function (acc, field, index) { if (!field || field === "0") { var lastLongest = acc[acc.length - 1]; if (lastLongest && lastLongest.index + lastLongest.length === index) { lastLongest.length++; } else { acc.push({ index: index, length: 1 }); } } return acc; }, []); var longestZeroFields = allZeroFields.sort(function (a, b) { return b.length - a.length; })[0]; var newHost = void 0; if (longestZeroFields && longestZeroFields.length > 1) { var newFirst = fields.slice(0, longestZeroFields.index); var newLast = fields.slice(longestZeroFields.index + longestZeroFields.length); newHost = newFirst.join(":") + "::" + newLast.join(":"); } else { newHost = fields.join(":"); } if (zone) { newHost += "%" + zone; } return newHost; } else { return host; } } var URI_PARSE = /^(?:([^:\/?#]+):)?(?:\/\/((?:([^\/?#@]*)@)?(\[[^\/?#\]]+\]|[^\/?#:]*)(?:\:(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i; var NO_MATCH_IS_UNDEFINED = "".match(/(){0}/)[1] === undefined; function parse(uriString) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var components = {}; var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL; if (options.reference === "suffix") uriString = (options.scheme ? options.scheme + ":" : "") + "//" + uriString; var matches = uriString.match(URI_PARSE); if (matches) { if (NO_MATCH_IS_UNDEFINED) { //store each component components.scheme = matches[1]; components.userinfo = matches[3]; components.host = matches[4]; components.port = parseInt(matches[5], 10); components.path = matches[6] || ""; components.query = matches[7]; components.fragment = matches[8]; //fix port number if (isNaN(components.port)) { components.port = matches[5]; } } else { //IE FIX for improper RegExp matching //store each component components.scheme = matches[1] || undefined; components.userinfo = uriString.indexOf("@") !== -1 ? matches[3] : undefined; components.host = uriString.indexOf("//") !== -1 ? matches[4] : undefined; components.port = parseInt(matches[5], 10); components.path = matches[6] || ""; components.query = uriString.indexOf("?") !== -1 ? matches[7] : undefined; components.fragment = uriString.indexOf("#") !== -1 ? matches[8] : undefined; //fix port number if (isNaN(components.port)) { components.port = uriString.match(/\/\/(?:.|\n)*\:(?:\/|\?|\#|$)/) ? matches[4] : undefined; } } if (components.host) { //normalize IP hosts components.host = _normalizeIPv6(_normalizeIPv4(components.host, protocol), protocol); } //determine reference type if (components.scheme === undefined && components.userinfo === undefined && components.host === undefined && components.port === undefined && !components.path && components.query === undefined) { components.reference = "same-document"; } else if (components.scheme === undefined) { components.reference = "relative"; } else if (components.fragment === undefined) { components.reference = "absolute"; } else { components.reference = "uri"; } //check for reference errors if (options.reference && options.reference !== "suffix" && options.reference !== components.reference) { components.error = components.error || "URI is not a " + options.reference + " reference."; } //find scheme handler var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()]; //check if scheme can't handle IRIs if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) { //if host component is a domain name if (components.host && (options.domainHost || schemeHandler && schemeHandler.domainHost)) { //convert Unicode IDN -> ASCII IDN try { components.host = punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()); } catch (e) { components.error = components.error || "Host's domain name can not be converted to ASCII via punycode: " + e; } } //convert IRI -> URI _normalizeComponentEncoding(components, URI_PROTOCOL); } else { //normalize encodings _normalizeComponentEncoding(components, protocol); } //perform scheme specific parsing if (schemeHandler && schemeHandler.parse) { schemeHandler.parse(components, options); } } else { components.error = components.error || "URI can not be parsed."; } return components; } function _recomposeAuthority(components, options) { var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL; var uriTokens = []; if (components.userinfo !== undefined) { uriTokens.push(components.userinfo); uriTokens.push("@"); } if (components.host !== undefined) { //normalize IP hosts, add brackets and escape zone separator for IPv6 uriTokens.push(_normalizeIPv6(_normalizeIPv4(String(components.host), protocol), protocol).replace(protocol.IPV6ADDRESS, function (_, $1, $2) { return "[" + $1 + ($2 ? "%25" + $2 : "") + "]"; })); } if (typeof components.port === "number") { uriTokens.push(":"); uriTokens.push(components.port.toString(10)); } return uriTokens.length ? uriTokens.join("") : undefined; } var RDS1 = /^\.\.?\//; var RDS2 = /^\/\.(\/|$)/; var RDS3 = /^\/\.\.(\/|$)/; var RDS5 = /^\/?(?:.|\n)*?(?=\/|$)/; function removeDotSegments(input) { var output = []; while (input.length) { if (input.match(RDS1)) { input = input.replace(RDS1, ""); } else if (input.match(RDS2)) { input = input.replace(RDS2, "/"); } else if (input.match(RDS3)) { input = input.replace(RDS3, "/"); output.pop(); } else if (input === "." || input === "..") { input = ""; } else { var im = input.match(RDS5); if (im) { var s = im[0]; input = input.slice(s.length); output.push(s); } else { throw new Error("Unexpected dot segment condition"); } } } return output.join(""); } function serialize(components) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var protocol = options.iri ? IRI_PROTOCOL : URI_PROTOCOL; var uriTokens = []; //find scheme handler var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()]; //perform scheme specific serialization if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(components, options); if (components.host) { //if host component is an IPv6 address if (protocol.IPV6ADDRESS.test(components.host)) {} //TODO: normalize IPv6 address as per RFC 5952 //if host component is a domain name else if (options.domainHost || schemeHandler && schemeHandler.domainHost) { //convert IDN via punycode try { components.host = !options.iri ? punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()) : punycode.toUnicode(components.host); } catch (e) { components.error = components.error || "Host's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e; } } } //normalize encoding _normalizeComponentEncoding(components, protocol); if (options.reference !== "suffix" && components.scheme) { uriTokens.push(components.scheme); uriTokens.push(":"); } var authority = _recomposeAuthority(components, options); if (authority !== undefined) { if (options.reference !== "suffix") { uriTokens.push("//"); } uriTokens.push(authority); if (components.path && components.path.charAt(0) !== "/") { uriTokens.push("/"); } } if (components.path !== undefined) { var s = components.path; if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) { s = removeDotSegments(s); } if (authority === undefined) { s = s.replace(/^\/\//, "/%2F"); //don't allow the path to start with "//" } uriTokens.push(s); } if (components.query !== undefined) { uriTokens.push("?"); uriTokens.push(components.query); } if (components.fragment !== undefined) { uriTokens.push("#"); uriTokens.push(components.fragment); } return uriTokens.join(""); //merge tokens into a string } function resolveComponents(base, relative) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var skipNormalization = arguments[3]; var target = {}; if (!skipNormalization) { base = parse(serialize(base, options), options); //normalize base components relative = parse(serialize(relative, options), options); //normalize relative components } options = options || {}; if (!options.tolerant && relative.scheme) { target.scheme = relative.scheme; //target.authority = relative.authority; target.userinfo = relative.userinfo; target.host = relative.host; target.port = relative.port; target.path = removeDotSegments(relative.path || ""); target.query = relative.query; } else { if (relative.userinfo !== undefined || relative.host !== undefined || relative.port !== undefined) { //target.authority = relative.authority; target.userinfo = relative.userinfo; target.host = relative.host; target.port = relative.port; target.path = removeDotSegments(relative.path || ""); target.query = relative.query; } else { if (!relative.path) { target.path = base.path; if (relative.query !== undefined) { target.query = relative.query; } else { target.query = base.query; } } else { if (relative.path.charAt(0) === "/") { target.path = removeDotSegments(relative.path); } else { if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) { target.path = "/" + relative.path; } else if (!base.path) { target.path = relative.path; } else { target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path; } target.path = removeDotSegments(target.path); } target.query = relative.query; } //target.authority = base.authority; target.userinfo = base.userinfo; target.host = base.host; target.port = base.port; } target.scheme = base.scheme; } target.fragment = relative.fragment; return target; } function resolve(baseURI, relativeURI, options) { var schemelessOptions = assign({ scheme: 'null' }, options); return serialize(resolveComponents(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true), schemelessOptions); } function normalize(uri, options) { if (typeof uri === "string") { uri = serialize(parse(uri, options), options); } else if (typeOf(uri) === "object") { uri = parse(serialize(uri, options), options); } return uri; } function equal(uriA, uriB, options) { if (typeof uriA === "string") { uriA = serialize(parse(uriA, options), options); } else if (typeOf(uriA) === "object") { uriA = serialize(uriA, options); } if (typeof uriB === "string") { uriB = serialize(parse(uriB, options), options); } else if (typeOf(uriB) === "object") { uriB = serialize(uriB, options); } return uriA === uriB; } function escapeComponent(str, options) { return str && str.toString().replace(!options || !options.iri ? URI_PROTOCOL.ESCAPE : IRI_PROTOCOL.ESCAPE, pctEncChar); } function unescapeComponent(str, options) { return str && str.toString().replace(!options || !options.iri ? URI_PROTOCOL.PCT_ENCODED : IRI_PROTOCOL.PCT_ENCODED, pctDecChars); } var handler = { scheme: "http", domainHost: true, parse: function parse(components, options) { //report missing host if (!components.host) { components.error = components.error || "HTTP URIs must have a host."; } return components; }, serialize: function serialize(components, options) { //normalize the default port if (components.port === (String(components.scheme).toLowerCase() !== "https" ? 80 : 443) || components.port === "") { components.port = undefined; } //normalize the empty path if (!components.path) { components.path = "/"; } //NOTE: We do not parse query strings for HTTP URIs //as WWW Form Url Encoded query strings are part of the HTML4+ spec, //and not the HTTP spec. return components; } }; var handler$1 = { scheme: "https", domainHost: handler.domainHost, parse: handler.parse, serialize: handler.serialize }; var O = {}; var isIRI = true; //RFC 3986 var UNRESERVED$$ = "[A-Za-z0-9\\-\\.\\_\\~" + (isIRI ? "\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF" : "") + "]"; var HEXDIG$$ = "[0-9A-Fa-f]"; //case-insensitive var PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)); //expanded //RFC 5322, except these symbols as per RFC 6068: @ : / ? # [ ] & ; = //const ATEXT$$ = "[A-Za-z0-9\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~]"; //const WSP$$ = "[\\x20\\x09]"; //const OBS_QTEXT$$ = "[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]"; //(%d1-8 / %d11-12 / %d14-31 / %d127) //const QTEXT$$ = merge("[\\x21\\x23-\\x5B\\x5D-\\x7E]", OBS_QTEXT$$); //%d33 / %d35-91 / %d93-126 / obs-qtext //const VCHAR$$ = "[\\x21-\\x7E]"; //const WSP$$ = "[\\x20\\x09]"; //const OBS_QP$ = subexp("\\\\" + merge("[\\x00\\x0D\\x0A]", OBS_QTEXT$$)); //%d0 / CR / LF / obs-qtext //const FWS$ = subexp(subexp(WSP$$ + "*" + "\\x0D\\x0A") + "?" + WSP$$ + "+"); //const QUOTED_PAIR$ = subexp(subexp("\\\\" + subexp(VCHAR$$ + "|" + WSP$$)) + "|" + OBS_QP$); //const QUOTED_STRING$ = subexp('\\"' + subexp(FWS$ + "?" + QCONTENT$) + "*" + FWS$ + "?" + '\\"'); var ATEXT$$ = "[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]"; var QTEXT$$ = "[\\!\\$\\%\\'\\(\\)\\*\\+\\,\\-\\.0-9\\<\\>A-Z\\x5E-\\x7E]"; var VCHAR$$ = merge(QTEXT$$, "[\\\"\\\\]"); var SOME_DELIMS$$ = "[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"; var UNRESERVED = new RegExp(UNRESERVED$$, "g"); var PCT_ENCODED = new RegExp(PCT_ENCODED$, "g"); var NOT_LOCAL_PART = new RegExp(merge("[^]", ATEXT$$, "[\\.]", '[\\"]', VCHAR$$), "g"); var NOT_HFNAME = new RegExp(merge("[^]", UNRESERVED$$, SOME_DELIMS$$), "g"); var NOT_HFVALUE = NOT_HFNAME; function decodeUnreserved(str) { var decStr = pctDecChars(str); return !decStr.match(UNRESERVED) ? str : decStr; } var handler$2 = { scheme: "mailto", parse: function parse$$1(components, options) { var mailtoComponents = components; var to = mailtoComponents.to = mailtoComponents.path ? mailtoComponents.path.split(",") : []; mailtoComponents.path = undefined; if (mailtoComponents.query) { var unknownHeaders = false; var headers = {}; var hfields = mailtoComponents.query.split("&"); for (var x = 0, xl = hfields.length; x < xl; ++x) { var hfield = hfields[x].split("="); switch (hfield[0]) { case "to": var toAddrs = hfield[1].split(","); for (var _x = 0, _xl = toAddrs.length; _x < _xl; ++_x) { to.push(toAddrs[_x]); } break; case "subject": mailtoComponents.subject = unescapeComponent(hfield[1], options); break; case "body": mailtoComponents.body = unescapeComponent(hfield[1], options); break; default: unknownHeaders = true; headers[unescapeComponent(hfield[0], options)] = unescapeComponent(hfield[1], options); break; } } if (unknownHeaders) mailtoComponents.headers = headers; } mailtoComponents.query = undefined; for (var _x2 = 0, _xl2 = to.length; _x2 < _xl2; ++_x2) { var addr = to[_x2].split("@"); addr[0] = unescapeComponent(addr[0]); if (!options.unicodeSupport) { //convert Unicode IDN -> ASCII IDN try { addr[1] = punycode.toASCII(unescapeComponent(addr[1], options).toLowerCase()); } catch (e) { mailtoComponents.error = mailtoComponents.error || "Email address's domain name can not be converted to ASCII via punycode: " + e; } } else { addr[1] = unescapeComponent(addr[1], options).toLowerCase(); } to[_x2] = addr.join("@"); } return mailtoComponents; }, serialize: function serialize$$1(mailtoComponents, options) { var components = mailtoComponents; var to = toArray(mailtoComponents.to); if (to) { for (var x = 0, xl = to.length; x < xl; ++x) { var toAddr = String(to[x]); var atIdx = toAddr.lastIndexOf("@"); var localPart = toAddr.slice(0, atIdx).replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_LOCAL_PART, pctEncChar); var domain = toAddr.slice(atIdx + 1); //convert IDN via punycode try { domain = !options.iri ? punycode.toASCII(unescapeComponent(domain, options).toLowerCase()) : punycode.toUnicode(domain); } catch (e) { components.error = components.error || "Email address's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e; } to[x] = localPart + "@" + domain; } components.path = to.join(","); } var headers = mailtoComponents.headers = mailtoComponents.headers || {}; if (mailtoComponents.subject) headers["subject"] = mailtoComponents.subject; if (mailtoComponents.body) headers["body"] = mailtoComponents.body; var fields = []; for (var name in headers) { if (headers[name] !== O[name]) { fields.push(name.replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFNAME, pctEncChar) + "=" + headers[name].replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFVALUE, pctEncChar)); } } if (fields.length) { components.query = fields.join("&"); } return components; } }; var URN_PARSE = /^([^\:]+)\:(.*)/; //RFC 2141 var handler$3 = { scheme: "urn", parse: function parse$$1(components, options) { var matches = components.path && components.path.match(URN_PARSE); var urnComponents = components; if (matches) { var scheme = options.scheme || urnComponents.scheme || "urn"; var nid = matches[1].toLowerCase(); var nss = matches[2]; var urnScheme = scheme + ":" + (options.nid || nid); var schemeHandler = SCHEMES[urnScheme]; urnComponents.nid = nid; urnComponents.nss = nss; urnComponents.path = undefined; if (schemeHandler) { urnComponents = schemeHandler.parse(urnComponents, options); } } else { urnComponents.error = urnComponents.error || "URN can not be parsed."; } return urnComponents; }, serialize: function serialize$$1(urnComponents, options) { var scheme = options.scheme || urnComponents.scheme || "urn"; var nid = urnComponents.nid; var urnScheme = scheme + ":" + (options.nid || nid); var schemeHandler = SCHEMES[urnScheme]; if (schemeHandler) { urnComponents = schemeHandler.serialize(urnComponents, options); } var uriComponents = urnComponents; var nss = urnComponents.nss; uriComponents.path = (nid || options.nid) + ":" + nss; return uriComponents; } }; var UUID = /^[0-9A-Fa-f]{8}(?:\-[0-9A-Fa-f]{4}){3}\-[0-9A-Fa-f]{12}$/; //RFC 4122 var handler$4 = { scheme: "urn:uuid", parse: function parse(urnComponents, options) { var uuidComponents = urnComponents; uuidComponents.uuid = uuidComponents.nss; uuidComponents.nss = undefined; if (!options.tolerant && (!uuidComponents.uuid || !uuidComponents.uuid.match(UUID))) { uuidComponents.error = uuidComponents.error || "UUID is not valid."; } return uuidComponents; }, serialize: function serialize(uuidComponents, options) { var urnComponents = uuidComponents; //normalize UUID urnComponents.nss = (uuidComponents.uuid || "").toLowerCase(); return urnComponents; } }; SCHEMES[handler.scheme] = handler; SCHEMES[handler$1.scheme] = handler$1; SCHEMES[handler$2.scheme] = handler$2; SCHEMES[handler$3.scheme] = handler$3; SCHEMES[handler$4.scheme] = handler$4; exports.SCHEMES = SCHEMES; exports.pctEncChar = pctEncChar; exports.pctDecChars = pctDecChars; exports.parse = parse; exports.removeDotSegments = removeDotSegments; exports.serialize = serialize; exports.resolveComponents = resolveComponents; exports.resolve = resolve; exports.normalize = normalize; exports.equal = equal; exports.escapeComponent = escapeComponent; exports.unescapeComponent = unescapeComponent; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=uri.all.js.map /***/ }), /***/ "./node_modules/whatwg-fetch/fetch.js": /*!********************************************!*\ !*** ./node_modules/whatwg-fetch/fetch.js ***! \********************************************/ /*! exports provided: Headers, Request, Response, DOMException, fetch */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Headers", function() { return Headers; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Request", function() { return Request; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Response", function() { return Response; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DOMException", function() { return DOMException; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fetch", function() { return fetch; }); var support = { searchParams: 'URLSearchParams' in self, iterable: 'Symbol' in self && 'iterator' in Symbol, blob: 'FileReader' in self && 'Blob' in self && (function() { try { new Blob() return true } catch (e) { return false } })(), formData: 'FormData' in self, arrayBuffer: 'ArrayBuffer' in self } function isDataView(obj) { return obj && DataView.prototype.isPrototypeOf(obj) } if (support.arrayBuffer) { var viewClasses = [ '[object Int8Array]', '[object Uint8Array]', '[object Uint8ClampedArray]', '[object Int16Array]', '[object Uint16Array]', '[object Int32Array]', '[object Uint32Array]', '[object Float32Array]', '[object Float64Array]' ] var isArrayBufferView = ArrayBuffer.isView || function(obj) { return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1 } } function normalizeName(name) { if (typeof name !== 'string') { name = String(name) } if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) { throw new TypeError('Invalid character in header field name') } return name.toLowerCase() } function normalizeValue(value) { if (typeof value !== 'string') { value = String(value) } return value } // Build a destructive iterator for the value list function iteratorFor(items) { var iterator = { next: function() { var value = items.shift() return {done: value === undefined, value: value} } } if (support.iterable) { iterator[Symbol.iterator] = function() { return iterator } } return iterator } function Headers(headers) { this.map = {} if (headers instanceof Headers) { headers.forEach(function(value, name) { this.append(name, value) }, this) } else if (Array.isArray(headers)) { headers.forEach(function(header) { this.append(header[0], header[1]) }, this) } else if (headers) { Object.getOwnPropertyNames(headers).forEach(function(name) { this.append(name, headers[name]) }, this) } } Headers.prototype.append = function(name, value) { name = normalizeName(name) value = normalizeValue(value) var oldValue = this.map[name] this.map[name] = oldValue ? oldValue + ', ' + value : value } Headers.prototype['delete'] = function(name) { delete this.map[normalizeName(name)] } Headers.prototype.get = function(name) { name = normalizeName(name) return this.has(name) ? this.map[name] : null } Headers.prototype.has = function(name) { return this.map.hasOwnProperty(normalizeName(name)) } Headers.prototype.set = function(name, value) { this.map[normalizeName(name)] = normalizeValue(value) } Headers.prototype.forEach = function(callback, thisArg) { for (var name in this.map) { if (this.map.hasOwnProperty(name)) { callback.call(thisArg, this.map[name], name, this) } } } Headers.prototype.keys = function() { var items = [] this.forEach(function(value, name) { items.push(name) }) return iteratorFor(items) } Headers.prototype.values = function() { var items = [] this.forEach(function(value) { items.push(value) }) return iteratorFor(items) } Headers.prototype.entries = function() { var items = [] this.forEach(function(value, name) { items.push([name, value]) }) return iteratorFor(items) } if (support.iterable) { Headers.prototype[Symbol.iterator] = Headers.prototype.entries } function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) } body.bodyUsed = true } function fileReaderReady(reader) { return new Promise(function(resolve, reject) { reader.onload = function() { resolve(reader.result) } reader.onerror = function() { reject(reader.error) } }) } function readBlobAsArrayBuffer(blob) { var reader = new FileReader() var promise = fileReaderReady(reader) reader.readAsArrayBuffer(blob) return promise } function readBlobAsText(blob) { var reader = new FileReader() var promise = fileReaderReady(reader) reader.readAsText(blob) return promise } function readArrayBufferAsText(buf) { var view = new Uint8Array(buf) var chars = new Array(view.length) for (var i = 0; i < view.length; i++) { chars[i] = String.fromCharCode(view[i]) } return chars.join('') } function bufferClone(buf) { if (buf.slice) { return buf.slice(0) } else { var view = new Uint8Array(buf.byteLength) view.set(new Uint8Array(buf)) return view.buffer } } function Body() { this.bodyUsed = false this._initBody = function(body) { this._bodyInit = body if (!body) { this._bodyText = '' } else if (typeof body === 'string') { this._bodyText = body } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { this._bodyBlob = body } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { this._bodyFormData = body } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { this._bodyText = body.toString() } else if (support.arrayBuffer && support.blob && isDataView(body)) { this._bodyArrayBuffer = bufferClone(body.buffer) // IE 10-11 can't handle a DataView body. this._bodyInit = new Blob([this._bodyArrayBuffer]) } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { this._bodyArrayBuffer = bufferClone(body) } else { this._bodyText = body = Object.prototype.toString.call(body) } if (!this.headers.get('content-type')) { if (typeof body === 'string') { this.headers.set('content-type', 'text/plain;charset=UTF-8') } else if (this._bodyBlob && this._bodyBlob.type) { this.headers.set('content-type', this._bodyBlob.type) } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8') } } } if (support.blob) { this.blob = function() { var rejected = consumed(this) if (rejected) { return rejected } if (this._bodyBlob) { return Promise.resolve(this._bodyBlob) } else if (this._bodyArrayBuffer) { return Promise.resolve(new Blob([this._bodyArrayBuffer])) } else if (this._bodyFormData) { throw new Error('could not read FormData body as blob') } else { return Promise.resolve(new Blob([this._bodyText])) } } this.arrayBuffer = function() { if (this._bodyArrayBuffer) { return consumed(this) || Promise.resolve(this._bodyArrayBuffer) } else { return this.blob().then(readBlobAsArrayBuffer) } } } this.text = function() { var rejected = consumed(this) if (rejected) { return rejected } if (this._bodyBlob) { return readBlobAsText(this._bodyBlob) } else if (this._bodyArrayBuffer) { return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)) } else if (this._bodyFormData) { throw new Error('could not read FormData body as text') } else { return Promise.resolve(this._bodyText) } } if (support.formData) { this.formData = function() { return this.text().then(decode) } } this.json = function() { return this.text().then(JSON.parse) } return this } // HTTP methods whose capitalization should be normalized var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'] function normalizeMethod(method) { var upcased = method.toUpperCase() return methods.indexOf(upcased) > -1 ? upcased : method } function Request(input, options) { options = options || {} var body = options.body if (input instanceof Request) { if (input.bodyUsed) { throw new TypeError('Already read') } this.url = input.url this.credentials = input.credentials if (!options.headers) { this.headers = new Headers(input.headers) } this.method = input.method this.mode = input.mode this.signal = input.signal if (!body && input._bodyInit != null) { body = input._bodyInit input.bodyUsed = true } } else { this.url = String(input) } this.credentials = options.credentials || this.credentials || 'same-origin' if (options.headers || !this.headers) { this.headers = new Headers(options.headers) } this.method = normalizeMethod(options.method || this.method || 'GET') this.mode = options.mode || this.mode || null this.signal = options.signal || this.signal this.referrer = null if ((this.method === 'GET' || this.method === 'HEAD') && body) { throw new TypeError('Body not allowed for GET or HEAD requests') } this._initBody(body) } Request.prototype.clone = function() { return new Request(this, {body: this._bodyInit}) } function decode(body) { var form = new FormData() body .trim() .split('&') .forEach(function(bytes) { if (bytes) { var split = bytes.split('=') var name = split.shift().replace(/\+/g, ' ') var value = split.join('=').replace(/\+/g, ' ') form.append(decodeURIComponent(name), decodeURIComponent(value)) } }) return form } function parseHeaders(rawHeaders) { var headers = new Headers() // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space // https://tools.ietf.org/html/rfc7230#section-3.2 var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ') preProcessedHeaders.split(/\r?\n/).forEach(function(line) { var parts = line.split(':') var key = parts.shift().trim() if (key) { var value = parts.join(':').trim() headers.append(key, value) } }) return headers } Body.call(Request.prototype) function Response(bodyInit, options) { if (!options) { options = {} } this.type = 'default' this.status = options.status === undefined ? 200 : options.status this.ok = this.status >= 200 && this.status < 300 this.statusText = 'statusText' in options ? options.statusText : 'OK' this.headers = new Headers(options.headers) this.url = options.url || '' this._initBody(bodyInit) } Body.call(Response.prototype) Response.prototype.clone = function() { return new Response(this._bodyInit, { status: this.status, statusText: this.statusText, headers: new Headers(this.headers), url: this.url }) } Response.error = function() { var response = new Response(null, {status: 0, statusText: ''}) response.type = 'error' return response } var redirectStatuses = [301, 302, 303, 307, 308] Response.redirect = function(url, status) { if (redirectStatuses.indexOf(status) === -1) { throw new RangeError('Invalid status code') } return new Response(null, {status: status, headers: {location: url}}) } var DOMException = self.DOMException try { new DOMException() } catch (err) { DOMException = function(message, name) { this.message = message this.name = name var error = Error(message) this.stack = error.stack } DOMException.prototype = Object.create(Error.prototype) DOMException.prototype.constructor = DOMException } function fetch(input, init) { return new Promise(function(resolve, reject) { var request = new Request(input, init) if (request.signal && request.signal.aborted) { return reject(new DOMException('Aborted', 'AbortError')) } var xhr = new XMLHttpRequest() function abortXhr() { xhr.abort() } xhr.onload = function() { var options = { status: xhr.status, statusText: xhr.statusText, headers: parseHeaders(xhr.getAllResponseHeaders() || '') } options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL') var body = 'response' in xhr ? xhr.response : xhr.responseText resolve(new Response(body, options)) } xhr.onerror = function() { reject(new TypeError('Network request failed')) } xhr.ontimeout = function() { reject(new TypeError('Network request failed')) } xhr.onabort = function() { reject(new DOMException('Aborted', 'AbortError')) } xhr.open(request.method, request.url, true) if (request.credentials === 'include') { xhr.withCredentials = true } else if (request.credentials === 'omit') { xhr.withCredentials = false } if ('responseType' in xhr && support.blob) { xhr.responseType = 'blob' } request.headers.forEach(function(value, name) { xhr.setRequestHeader(name, value) }) if (request.signal) { request.signal.addEventListener('abort', abortXhr) xhr.onreadystatechange = function() { // DONE (success or failure) if (xhr.readyState === 4) { request.signal.removeEventListener('abort', abortXhr) } } } xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit) }) } fetch.polyfill = true if (!self.fetch) { self.fetch = fetch self.Headers = Headers self.Request = Request self.Response = Response } /***/ }), /***/ "./node_modules/worker-loader/dist/workers/InlineWorker.js": /*!*****************************************************************!*\ !*** ./node_modules/worker-loader/dist/workers/InlineWorker.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // http://stackoverflow.com/questions/10343913/how-to-create-a-web-worker-from-a-string var URL = window.URL || window.webkitURL; module.exports = function (content, url) { try { try { var blob; try { // BlobBuilder = Deprecated, but widely implemented var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; blob = new BlobBuilder(); blob.append(content); blob = blob.getBlob(); } catch (e) { // The proposed API blob = new Blob([content]); } return new Worker(URL.createObjectURL(blob)); } catch (e) { return new Worker('data:application/javascript,' + encodeURIComponent(content)); } } catch (e) { if (!url) { throw Error('Inline worker is not supported'); } return new Worker(url); } }; /***/ }), /***/ "./res_built/atlas sync .*\\.json/": /*!*****************************************************!*\ !*** ./res_built/atlas sync nonrecursive .*\.json/ ***! \*****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var map = { "./atlas0_hq.json": "./res_built/atlas/atlas0_hq.json", "./atlas0_lq.json": "./res_built/atlas/atlas0_lq.json", "./atlas0_mq.json": "./res_built/atlas/atlas0_mq.json" }; function webpackContext(req) { var id = webpackContextResolve(req); return __webpack_require__(id); } function webpackContextResolve(req) { if(!__webpack_require__.o(map, req)) { var e = new Error("Cannot find module '" + req + "'"); e.code = 'MODULE_NOT_FOUND'; throw e; } return map[req]; } webpackContext.keys = function webpackContextKeys() { return Object.keys(map); }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; webpackContext.id = "./res_built/atlas sync .*\\.json/"; /***/ }), /***/ "./res_built/atlas sync recursive ^\\.\\/.*$": /*!***************************************!*\ !*** ./res_built/atlas sync ^\.\/.*$ ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var map = { "./adder.png": "./res_built/atlas/adder.png", "./atlas0_hq": "./res_built/atlas/atlas0_hq.json", "./atlas0_hq.atlas": "./res_built/atlas/atlas0_hq.atlas", "./atlas0_hq.json": "./res_built/atlas/atlas0_hq.json", "./atlas0_hq.png": "./res_built/atlas/atlas0_hq.png", "./atlas0_lq": "./res_built/atlas/atlas0_lq.json", "./atlas0_lq.atlas": "./res_built/atlas/atlas0_lq.atlas", "./atlas0_lq.json": "./res_built/atlas/atlas0_lq.json", "./atlas0_lq.png": "./res_built/atlas/atlas0_lq.png", "./atlas0_mq": "./res_built/atlas/atlas0_mq.json", "./atlas0_mq.atlas": "./res_built/atlas/atlas0_mq.atlas", "./atlas0_mq.json": "./res_built/atlas/atlas0_mq.json", "./atlas0_mq.png": "./res_built/atlas/atlas0_mq.png", "./combiner-bp.png": "./res_built/atlas/combiner-bp.png", "./combiner.png": "./res_built/atlas/combiner.png", "./counter-bp.png": "./res_built/atlas/counter-bp.png", "./counter.png": "./res_built/atlas/counter.png", "./inverter-bp.png": "./res_built/atlas/inverter-bp.png", "./inverter.png": "./res_built/atlas/inverter.png", "./quaduo.png": "./res_built/atlas/quaduo.png", "./unstacker-bp.png": "./res_built/atlas/unstacker-bp.png", "./unstacker.png": "./res_built/atlas/unstacker.png" }; function webpackContext(req) { var id = webpackContextResolve(req); return __webpack_require__(id); } function webpackContextResolve(req) { if(!__webpack_require__.o(map, req)) { var e = new Error("Cannot find module '" + req + "'"); e.code = 'MODULE_NOT_FOUND'; throw e; } return map[req]; } webpackContext.keys = function webpackContextKeys() { return Object.keys(map); }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; webpackContext.id = "./res_built/atlas sync recursive ^\\.\\/.*$"; /***/ }), /***/ "./res_built/atlas/adder.png": /*!***********************************!*\ !*** ./res_built/atlas/adder.png ***! \***********************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/atlas0_hq.atlas": /*!*****************************************!*\ !*** ./res_built/atlas/atlas0_hq.atlas ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports) { atlas0_hq.png size: 2048,2048 format: RGBA8888 filter: Nearest,Nearest repeat: none sprites/belt/built/forward_1 rotate: false xy: 1240, 1465 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_10 rotate: false xy: 829, 200 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_11 rotate: false xy: 829, 54 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_12 rotate: false xy: 947, 200 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_13 rotate: false xy: 947, 54 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_2 rotate: false xy: 675, 1078 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_3 rotate: false xy: 693, 932 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_4 rotate: false xy: 699, 786 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_5 rotate: false xy: 811, 941 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_6 rotate: false xy: 817, 795 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_7 rotate: false xy: 1237, 1182 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_8 rotate: false xy: 692, 624 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_9 rotate: false xy: 790, 478 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/left_1 rotate: false xy: 1308, 918 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_10 rotate: false xy: 1172, 567 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_11 rotate: false xy: 1086, 402 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_12 rotate: false xy: 1304, 522 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_13 rotate: false xy: 1065, 270 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_2 rotate: false xy: 1308, 786 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_3 rotate: false xy: 1544, 1048 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_4 rotate: false xy: 1308, 654 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_5 rotate: false xy: 1440, 629 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_6 rotate: false xy: 935, 666 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_7 rotate: false xy: 908, 534 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_8 rotate: false xy: 954, 402 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_9 rotate: false xy: 1040, 534 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/right_1 rotate: false xy: 1065, 138 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_10 rotate: false xy: 1489, 119 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_11 rotate: false xy: 1197, 13 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_12 rotate: false xy: 1544, 916 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_13 rotate: false xy: 1548, 784 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_2 rotate: false xy: 1065, 6 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_3 rotate: false xy: 1225, 277 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_4 rotate: false xy: 1357, 383 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_5 rotate: false xy: 1357, 251 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_6 rotate: false xy: 1489, 383 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_7 rotate: false xy: 1489, 251 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_8 rotate: false xy: 1225, 145 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_9 rotate: false xy: 1357, 119 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/blueprints/analyzer rotate: false xy: 841, 1612 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/blueprints/balancer rotate: false xy: 291, 1060 size: 257, 144 orig: 288, 144 offset: 17, 0 index: -1 sprites/blueprints/balancer-merger rotate: false xy: 396, 338 size: 139, 138 orig: 144, 144 offset: 5, 4 index: -1 sprites/blueprints/balancer-merger-inverse rotate: false xy: 394, 52 size: 142, 138 orig: 144, 144 offset: 0, 4 index: -1 sprites/blueprints/balancer-splitter rotate: false xy: 537, 338 size: 139, 138 orig: 144, 144 offset: 5, 4 index: -1 sprites/blueprints/balancer-splitter-inverse rotate: false xy: 678, 338 size: 142, 138 orig: 144, 144 offset: 0, 4 index: -1 sprites/blueprints/belt_left rotate: false xy: 1915, 1189 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/blueprints/belt_right rotate: false xy: 822, 346 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/blueprints/belt_top rotate: false xy: 1879, 1757 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/blueprints/comparator rotate: false xy: 250, 343 size: 144, 133 orig: 144, 144 offset: 0, 11 index: -1 sprites/blueprints/constant_signal rotate: false xy: 1440, 761 size: 106, 130 orig: 144, 144 offset: 19, 14 index: -1 sprites/blueprints/cutter rotate: false xy: 291, 914 size: 257, 144 orig: 288, 144 offset: 17, 0 index: -1 sprites/blueprints/cutter-quad rotate: false xy: 1, 1206 size: 526, 144 orig: 576, 144 offset: 24, 0 index: -1 sprites/blueprints/display rotate: false xy: 1495, 1192 size: 128, 136 orig: 144, 144 offset: 8, 0 index: -1 sprites/blueprints/filter rotate: false xy: 1077, 1757 size: 268, 144 orig: 288, 144 offset: 16, 0 index: -1 sprites/blueprints/item_producer rotate: false xy: 1916, 1321 size: 131, 142 orig: 144, 144 offset: 8, 2 index: -1 sprites/blueprints/lever rotate: false xy: 1067, 720 size: 100, 116 orig: 144, 144 offset: 22, 19 index: -1 sprites/blueprints/logic_gate rotate: false xy: 945, 1204 size: 144, 122 orig: 144, 144 offset: 0, 22 index: -1 sprites/blueprints/logic_gate-not rotate: false xy: 550, 1062 size: 123, 144 orig: 144, 144 offset: 11, 0 index: -1 sprites/blueprints/logic_gate-or rotate: false xy: 1091, 1202 size: 144, 124 orig: 144, 144 offset: 0, 20 index: -1 sprites/blueprints/logic_gate-xor rotate: false xy: 248, 66 size: 144, 129 orig: 144, 144 offset: 0, 15 index: -1 sprites/blueprints/miner rotate: false xy: 508, 478 size: 137, 143 orig: 144, 144 offset: 4, 1 index: -1 sprites/blueprints/miner-chainable rotate: false xy: 553, 623 size: 137, 143 orig: 144, 144 offset: 4, 1 index: -1 sprites/blueprints/mixer rotate: false xy: 1616, 1757 size: 261, 144 orig: 288, 144 offset: 13, 0 index: -1 sprites/blueprints/painter rotate: false xy: 1090, 1903 size: 288, 144 orig: 288, 144 offset: 0, 0 index: -1 sprites/blueprints/painter-double rotate: false xy: 1, 924 size: 288, 280 orig: 288, 288 offset: 0, 8 index: -1 sprites/blueprints/painter-mirrored rotate: false xy: 1380, 1903 size: 288, 144 orig: 288, 144 offset: 0, 0 index: -1 sprites/blueprints/painter-quad rotate: false xy: 1, 1352 size: 538, 144 orig: 576, 144 offset: 12, 0 index: -1 sprites/blueprints/reader rotate: false xy: 394, 192 size: 142, 144 orig: 144, 144 offset: 1, 0 index: -1 sprites/blueprints/rotater rotate: false xy: 554, 770 size: 143, 144 orig: 144, 144 offset: 1, 0 index: -1 sprites/blueprints/rotater-ccw rotate: false xy: 538, 192 size: 143, 144 orig: 144, 144 offset: 1, 0 index: -1 sprites/blueprints/rotater-rotate180 rotate: false xy: 538, 46 size: 143, 144 orig: 144, 144 offset: 1, 0 index: -1 sprites/blueprints/stacker rotate: false xy: 291, 768 size: 261, 144 orig: 288, 144 offset: 13, 0 index: -1 sprites/blueprints/storage rotate: false xy: 1, 354 size: 247, 287 orig: 288, 288 offset: 21, 0 index: -1 sprites/blueprints/transistor rotate: false xy: 1061, 984 size: 102, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/blueprints/transistor-mirrored rotate: false xy: 1442, 1039 size: 100, 144 orig: 144, 144 offset: 44, 0 index: -1 sprites/blueprints/trash rotate: false xy: 683, 46 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/blueprints/underground_belt_entry rotate: false xy: 917, 1090 size: 138, 112 orig: 144, 144 offset: 4, 0 index: -1 sprites/blueprints/underground_belt_entry-tier2 rotate: false xy: 1775, 1212 size: 138, 125 orig: 144, 144 offset: 4, 0 index: -1 sprites/blueprints/underground_belt_exit rotate: false xy: 1436, 515 size: 138, 112 orig: 144, 144 offset: 4, 32 index: -1 sprites/blueprints/underground_belt_exit-tier2 rotate: false xy: 529, 1208 size: 139, 112 orig: 144, 144 offset: 4, 32 index: -1 sprites/blueprints/virtual_processor rotate: false xy: 1483, 1614 size: 144, 141 orig: 144, 144 offset: 0, 0 index: -1 sprites/blueprints/virtual_processor-painter rotate: false xy: 1358, 1466 size: 131, 144 orig: 144, 144 offset: 13, 0 index: -1 sprites/blueprints/virtual_processor-rotater rotate: false xy: 1960, 1903 size: 58, 144 orig: 144, 144 offset: 44, 0 index: -1 sprites/blueprints/virtual_processor-stacker rotate: false xy: 929, 944 size: 130, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/blueprints/virtual_processor-unstacker rotate: false xy: 1191, 1611 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/blueprints/wire_tunnel rotate: false xy: 1355, 1185 size: 138, 135 orig: 144, 144 offset: 4, 5 index: -1 sprites/buildings/analyzer rotate: false xy: 813, 1466 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/buildings/balancer rotate: false xy: 541, 1322 size: 256, 143 orig: 288, 144 offset: 17, 1 index: -1 sprites/buildings/balancer-merger rotate: false xy: 1775, 1339 size: 139, 136 orig: 144, 144 offset: 5, 5 index: -1 sprites/buildings/balancer-merger-inverse rotate: false xy: 1629, 1477 size: 141, 136 orig: 144, 144 offset: 0, 5 index: -1 sprites/buildings/balancer-splitter rotate: false xy: 1089, 1328 size: 139, 136 orig: 144, 144 offset: 5, 5 index: -1 sprites/buildings/balancer-splitter-inverse rotate: false xy: 945, 1328 size: 142, 136 orig: 144, 144 offset: 0, 5 index: -1 sprites/buildings/belt_left rotate: false xy: 1915, 1057 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/belt/built/left_0 rotate: false xy: 1915, 1057 size: 130, 130 orig: 144, 144 offset: 0, 0 index: -1 sprites/buildings/belt_right rotate: false xy: 1310, 1050 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/right_0 rotate: false xy: 1310, 1050 size: 130, 130 orig: 144, 144 offset: 14, 0 index: -1 sprites/buildings/belt_top rotate: false xy: 1918, 1611 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/belt/built/forward_0 rotate: false xy: 1918, 1611 size: 116, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/buildings/comparator rotate: false xy: 1772, 1477 size: 143, 133 orig: 144, 144 offset: 1, 11 index: -1 sprites/buildings/constant_signal rotate: false xy: 1572, 653 size: 104, 129 orig: 144, 144 offset: 20, 15 index: -1 sprites/buildings/cutter rotate: false xy: 250, 478 size: 256, 143 orig: 288, 144 offset: 17, 1 index: -1 sprites/buildings/cutter-quad rotate: false xy: 551, 1758 size: 524, 143 orig: 576, 144 offset: 25, 1 index: -1 sprites/buildings/display rotate: false xy: 1230, 1328 size: 126, 135 orig: 144, 144 offset: 9, 0 index: -1 sprites/buildings/filter rotate: false xy: 1347, 1757 size: 267, 144 orig: 288, 144 offset: 17, 0 index: -1 sprites/buildings/hub rotate: false xy: 1, 1498 size: 548, 549 orig: 576, 576 offset: 14, 11 index: -1 sprites/buildings/item_producer rotate: false xy: 1358, 1322 size: 130, 142 orig: 144, 144 offset: 8, 2 index: -1 sprites/buildings/lever rotate: false xy: 1433, 3 size: 98, 114 orig: 144, 144 offset: 23, 20 index: -1 sprites/buildings/logic_gate rotate: false xy: 1625, 1180 size: 143, 121 orig: 144, 144 offset: 1, 23 index: -1 sprites/buildings/logic_gate-not rotate: false xy: 793, 1087 size: 122, 144 orig: 144, 144 offset: 12, 0 index: -1 sprites/buildings/logic_gate-or rotate: false xy: 1770, 1086 size: 143, 124 orig: 144, 144 offset: 1, 20 index: -1 sprites/buildings/logic_gate-xor rotate: false xy: 1165, 1051 size: 143, 129 orig: 144, 144 offset: 1, 15 index: -1 sprites/buildings/miner rotate: false xy: 1102, 1467 size: 136, 142 orig: 144, 144 offset: 5, 2 index: -1 sprites/buildings/miner-chainable rotate: false xy: 1491, 1470 size: 136, 142 orig: 144, 144 offset: 5, 2 index: -1 sprites/buildings/mixer rotate: false xy: 291, 623 size: 260, 143 orig: 288, 144 offset: 14, 1 index: -1 sprites/buildings/painter rotate: false xy: 551, 1612 size: 288, 144 orig: 288, 144 offset: 0, 0 index: -1 sprites/buildings/painter-double rotate: false xy: 1, 643 size: 288, 279 orig: 288, 288 offset: 0, 9 index: -1 sprites/buildings/painter-mirrored rotate: false xy: 1670, 1903 size: 288, 144 orig: 288, 144 offset: 0, 0 index: -1 sprites/buildings/painter-quad rotate: false xy: 551, 1903 size: 537, 144 orig: 576, 144 offset: 13, 0 index: -1 sprites/buildings/reader rotate: false xy: 550, 916 size: 141, 144 orig: 144, 144 offset: 2, 0 index: -1 sprites/buildings/rotater rotate: false xy: 647, 478 size: 141, 143 orig: 144, 144 offset: 2, 1 index: -1 sprites/buildings/rotater-ccw rotate: false xy: 1775, 1612 size: 141, 143 orig: 144, 144 offset: 2, 1 index: -1 sprites/buildings/rotater-rotate180 rotate: false xy: 959, 1466 size: 141, 143 orig: 144, 144 offset: 2, 1 index: -1 sprites/buildings/stacker rotate: false xy: 551, 1467 size: 260, 143 orig: 288, 144 offset: 14, 1 index: -1 sprites/buildings/storage rotate: false xy: 1, 66 size: 245, 286 orig: 288, 288 offset: 22, 0 index: -1 sprites/buildings/transistor rotate: false xy: 1067, 838 size: 100, 144 orig: 144, 144 offset: 1, 0 index: -1 sprites/buildings/transistor-mirrored rotate: false xy: 1440, 893 size: 99, 144 orig: 144, 144 offset: 45, 0 index: -1 sprites/buildings/trash rotate: false xy: 1045, 1611 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/buildings/underground_belt_entry rotate: false xy: 1169, 812 size: 137, 111 orig: 144, 144 offset: 5, 0 index: -1 sprites/buildings/underground_belt_entry-tier2 rotate: false xy: 1169, 925 size: 137, 124 orig: 144, 144 offset: 5, 0 index: -1 sprites/buildings/underground_belt_exit rotate: false xy: 1169, 699 size: 137, 111 orig: 144, 144 offset: 5, 33 index: -1 sprites/buildings/underground_belt_exit-tier2 rotate: false xy: 1218, 409 size: 137, 111 orig: 144, 144 offset: 5, 33 index: -1 sprites/buildings/virtual_processor rotate: false xy: 1629, 1615 size: 144, 140 orig: 144, 144 offset: 0, 0 index: -1 sprites/buildings/virtual_processor-painter rotate: false xy: 1917, 1465 size: 130, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/buildings/virtual_processor-rotater rotate: false xy: 987, 1612 size: 56, 144 orig: 144, 144 offset: 45, 0 index: -1 sprites/buildings/virtual_processor-stacker rotate: false xy: 935, 798 size: 130, 144 orig: 144, 144 offset: 14, 0 index: -1 sprites/buildings/virtual_processor-unstacker rotate: false xy: 1337, 1612 size: 144, 143 orig: 144, 144 offset: 0, 0 index: -1 sprites/buildings/wire_tunnel rotate: false xy: 1490, 1330 size: 137, 134 orig: 144, 144 offset: 5, 5 index: -1 sprites/colors/blue rotate: false xy: 1067, 669 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/cyan rotate: false xy: 954, 351 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/green rotate: false xy: 92, 15 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/purple rotate: false xy: 148, 15 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/red rotate: false xy: 204, 15 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/uncolored rotate: false xy: 260, 15 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/white rotate: false xy: 316, 15 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/colors/yellow rotate: false xy: 372, 1 size: 54, 49 orig: 54, 54 offset: 0, 1 index: -1 sprites/debug/acceptor_slot rotate: false xy: 372, 52 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 sprites/debug/ejector_slot rotate: false xy: 250, 629 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 sprites/misc/hub_direction_indicator rotate: false xy: 1010, 352 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/misc/processor_disabled rotate: false xy: 1676, 923 size: 78, 81 orig: 96, 96 offset: 10, 5 index: -1 sprites/misc/processor_disconnected rotate: false xy: 1763, 1000 size: 65, 84 orig: 96, 96 offset: 17, 4 index: -1 sprites/misc/reader_overlay rotate: false xy: 1057, 1130 size: 104, 70 orig: 144, 144 offset: 20, 36 index: -1 sprites/misc/slot_bad_arrow rotate: false xy: 527, 9 size: 35, 35 orig: 39, 39 offset: 2, 2 index: -1 sprites/misc/slot_good_arrow rotate: false xy: 1805, 916 size: 35, 39 orig: 39, 39 offset: 2, 0 index: -1 sprites/misc/storage_overlay rotate: false xy: 1, 20 size: 89, 44 orig: 90, 45 offset: 1, 0 index: -1 sprites/misc/waypoint rotate: false xy: 1123, 670 size: 38, 48 orig: 48, 48 offset: 5, 0 index: -1 sprites/wires/boolean_false rotate: false xy: 1805, 957 size: 31, 41 orig: 48, 48 offset: 9, 2 index: -1 sprites/wires/boolean_true rotate: false xy: 2025, 1860 size: 22, 41 orig: 48, 48 offset: 11, 2 index: -1 sprites/wires/display/blue rotate: false xy: 478, 3 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/display/cyan rotate: false xy: 1756, 951 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/display/green rotate: false xy: 1680, 766 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/display/purple rotate: false xy: 1678, 717 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/display/red rotate: false xy: 1678, 668 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/display/white rotate: false xy: 1744, 856 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/display/yellow rotate: false xy: 1744, 807 size: 47, 47 orig: 49, 49 offset: 1, 1 index: -1 sprites/wires/lever_on rotate: false xy: 1329, 3 size: 102, 114 orig: 144, 144 offset: 21, 20 index: -1 sprites/wires/logical_acceptor rotate: false xy: 1680, 815 size: 62, 106 orig: 144, 144 offset: 43, 38 index: -1 sprites/wires/logical_ejector rotate: false xy: 1830, 1017 size: 60, 67 orig: 144, 144 offset: 44, 77 index: -1 sprites/wires/network_conflict rotate: false xy: 1756, 905 size: 47, 44 orig: 48, 48 offset: 1, 2 index: -1 sprites/wires/network_empty rotate: false xy: 908, 484 size: 41, 48 orig: 48, 48 offset: 5, 0 index: -1 sprites/wires/overlay_tile rotate: false xy: 670, 1224 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/conflict_cross rotate: false xy: 799, 1320 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/wires/sets/conflict_forward rotate: false xy: 1997, 1757 size: 26, 144 orig: 144, 144 offset: 59, 0 index: -1 sprites/wires/sets/conflict_split rotate: false xy: 768, 1233 size: 144, 85 orig: 144, 144 offset: 0, 0 index: -1 sprites/wires/sets/conflict_turn rotate: false xy: 1676, 1093 size: 85, 85 orig: 144, 144 offset: 59, 0 index: -1 sprites/wires/sets/first_cross rotate: false xy: 248, 197 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/wires/sets/first_forward rotate: false xy: 2020, 1903 size: 26, 144 orig: 144, 144 offset: 59, 0 index: -1 sprites/wires/sets/first_split rotate: false xy: 1629, 1390 size: 144, 85 orig: 144, 144 offset: 0, 0 index: -1 sprites/wires/sets/first_turn rotate: false xy: 1533, 32 size: 85, 85 orig: 144, 144 offset: 59, 0 index: -1 sprites/wires/sets/second_cross rotate: false xy: 683, 192 size: 144, 144 orig: 144, 144 offset: 0, 0 index: -1 sprites/wires/sets/second_forward rotate: false xy: 1197, 256 size: 26, 144 orig: 144, 144 offset: 59, 0 index: -1 sprites/wires/sets/second_split rotate: false xy: 1629, 1303 size: 144, 85 orig: 144, 144 offset: 0, 0 index: -1 sprites/wires/sets/second_turn rotate: false xy: 1676, 1006 size: 85, 85 orig: 144, 144 offset: 59, 0 index: -1 sprites/wires/wires_preview rotate: false xy: 428, 2 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 /***/ }), /***/ "./res_built/atlas/atlas0_hq.json": /*!****************************************!*\ !*** ./res_built/atlas/atlas0_hq.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4IgZgTghgtgpgZxALgATALAChsgQBwgEsAXRAegCM4AbEqgVyLvLAHsIB3KCAEwH0ADADp8AOwDmKbJiwBIcNHgp0IAB4oALJsEAaEAE8UAdk0AmfZxQBGawDZ9ACxvaAvruwKIbElDK8VMCgaBDgPeRASYhh4ALQohjDPPEJSOABlNgYIAGMMogAvOBVQDWRrTX0jZD0QK3L7JxdNd2SELNz8opK65qbyt2xWrBTiMgQqWnpKJhZ2Lh4Ba1FJaSxZBUhYYrRSmwBWTX2qlABOU+tLG0aQZwGW8K8fPzg41CCQpIioohjXlQSXwUBDGGQ6eXShR2qjKFRONSuDQct2aw2B4K60NA9QqlRR91cQ3CozSE2oLBmzHo824fH4ZhWUmQMmSW2Uu3UKAAHGYufDrLzjr0kf1cWiQN5fP5AsFQo9ItFYgCIIl5SC0plshCoT1YXjqrUcTc7mK1RjId0OTjtKLBlhhiTxpMKbNqRxaQIAMyMtYbRTbXVaMzI6oVHmI2zIk1ueWSl5vD5y5I-P5vQFq1JkTWdC1YzkDeGG65R1FmrWYnrWvHRlpE3Dqp3k6au1juxb8TQ+5nrVlKPNlTTWPmGGx2T1FkX403JOPStCJoEK35K+IqxcNsHl3OBgsjhHCyO2h5tc06q19Kd2h0bslTRhU1sLOn7LssiJs-vcsy1UOaT2eiNjVLGdnjnd5ZUXFMV1QdM2kzTcczPGEXELQCSwJMtEMtVQqyPQl7WJG9nWbB8aXbOxXx7d8+x3QdLj3axjGMYcjXQ6cIlnf55wg+UoK4mC1wzUFs21bC9l3A00LwzDRLzXDL1rAj63g28XVIts6WMSi-Q-HcuThBj9n0qSFPFTiEx45NFX42CIg3ESKw5PVUIPICMJPLckOxC8a3w68VOI+85g0gQuW03sAyc7lBBDGxjDMU4TN82NQP4hdeOstNBLg4TTzE-MDMk1y2JjDysLknzUTrEYiKbIK3SfARTnC6jIuQ5BjHOfkuSYpLgI41KLM+DLlxs7K7PghztyiiSUAnQ9TJkxycMqglqsdCg6spYLGv4awRHEJk302GiZusQ4hVDaxPUS4rpJAqU0ss75MuVVUco1PLP1m-dWPuuyvsrVaxXW2q722hqPT25ZDt9CL2Xav8AIYwRPRY4t-qeR6hqTF7Rqy96Jtyzz8ucvd5rc9j0RJir7jw0GAq2lsyLpAUWpOtrxPMYx+SHZE-sWh74xlYarPxt710mwGzv1Oa+vcgGaaBunTIZ0FVJInaoeu9n-QRrng35f88QF5KhbA9KxdTCWhM+pWZZc03+up8rldxemlJqxnwZbGg4DAEghF13Szv2ejQ1RoUcXHUVxzMwaRdxhQ+IJyXiddmafxQg8Y6nOOlumlaVd8tXSUCiHyD9gO9uD072vO8Pi1u6PahNfPzae0W8et1dCeBKX7farPdxb2PBHFdpB+84uqs9jaNfqyv-cDhlYe7HS6-E5HQzsQR6NHvPx5S7HE8g17e7Tu2M6H-kTZsXO26PsrZLdm1VbnsG1JYKvA+9Nfjr1t9OwXJYoDE9Pve+rdIHxxPtxLuydz4CT7htKaXl8zDwMgfR+E9pZF3du-fy6ty6+2Xh2WunN8yHFAedcwEYH7QOPsLOBSclw9yQZfLMuDxIYLvuUehfCn6K2vtPfBJcP7ey-vQH+-AXz-yohzfW+YzC9QYsAqOkCx4wKYeBeBrDoK2X7unF+mdb50KgQInBU8DxvzEYQsuTMHzSIonIjeFDYSeh5gxYwQ4zGaMYRbZ6CDxYX1tpwqxZQeG+MPpY4R1jqyzzsY2H2jjSFaRcfDb6284qenUQIvxHccZn2Cew0JCFjE3wYrw665jqkxPKSImxCTCISM1lI0hYV0mtUUWUU4mhhyhnAZ4rBDCCmnxGmwgxKCuHoNMTnGp7chH1LiR7RJm1knf1Ic1TpCigFcgwfsOwuTqn5IGrAnRLCU42w+mE2JETZnDIsQXNB8lbHNKIQ4jZ1d9rkO6QcZRt9-lzJOVjbRltu76PGoYq+Sy7mVKidgp5+UXlNOUu89ZbSvkw1WOvDJO4G5G1RvCkZpzQWBL0WNZB9lpmwt-ESx5z9loNPiWtcRaLJFLy+avbFACQ7tV5LLco+ww50tqf4zuFzEGTKpeEuWcKgXRMRbTURKKvZstaRywOOttmALxX+fkRkqn8NFaM5hRSJmQqmTK-ctL5UIoZYXJlKy3n2PReQYgEhHCBwOty+ROqZr7DRvyOwxh+YaIVSa85ZqIWUoHrc7ONqHnGsWYy5ZBDnVJPZe6z1NdtW8vEsoxu5R9LNzDXaklATdGXJCdcspKayYJtLcSl2SzkUstWQvCuWaV4-KAfFINXVbVNolAnU14zo0cNrQ6gqArMGNvpcmqdraQaspdZmogHrf49p3AGwtQ59oioWSCitErilStjTC+N2dE2HrwNMpdV501rLXRushubN4FTMDcAZpx0Z5PDeW8VUaKUTtQaTS9I851JubSm+9il23EIfF2mRW6zqCFMLfU4yNr2CKPYBsdwHSmge+oVK9kGb2T1ibBvyj6O0tiQ84n1rjfnIEwzOoyRyjU3vMmMq247CPUvA7Ov9ZboOLuBg+1Fq71VIbSYx3FZ0ck8M0CW4TQ7uOjt4wRmtRHdX3LIzh29ViqOlwzdJ9d2aOlya6cR78-SDiegsIO+duHCn4dTvxq1JGIOqec4Zyj4m4M0YQywJDWyrM7LxTFOz5Q7CAuw1o49QH3PaYEz9ITxz-2ieeQF6jknTOLyQ98t9bj76eNDFyfYjn4titc5p5LRNoV1sE4a+ZBmKMtpyyZp9ZmX22BQ+1LJRa7AqYyyJ4dZywVBPNTGoxTW0steBX5jrM821BY+fQQrXKjq+rzQVQQ4YGI5JG5xgz6nI1uauQ1m5F75sHra3ezrK78udvM5qv+4W-XtV6Tw4VTmoPjdJZWyVFrpVxtu398jD2VvLvg5QGgiRUhiBIBrfgP9+viVY-ybxx3WsJbw3Vy7ULrtzciRD+7RnHuw-h3ARHyPiL8C7ej-MdhDndX-HdvHtXwVaau5OtB9bSM+f++1mDlO1vU9pyjkgbB8BM56dYW65WVFOwVi5nj3P6tE752Bn6FMSrHgXdl6HEnVX2Il8QJHEwchsDEAgXwSP+AIHXWIYIcubCYbKyYfYI3BBChNMozn6upt8ZS1a78jsbC+9FAHxVr9mUw-Fwji3dOcgMBIGQCAABaAAjgwKAvA3fIEG-i4UhxhxmwA1z4PPOtc6bOp736KAy+YyW6L5A+wQ1Ory5tc3RBLfkFT+nuAEBC9ck0A3hKv6zAHJb2dyb5LNeWrB4xCPyBp-67qW33k5eVXzyoL3-vvAiAEBoFAAwhfzrs4YryIZNheSxzsIHjTGvCdL5u9F39Aod98Mf7H88xvAtu8yQD86cwAqRh8L99oG8hVQ019gFZ8R1zsCdq1ec6965QEJxgxv8qZW8xM18uRsCTc984ck8+86c-YAA3CA4rZjIcMwQbYwBzQCGpewJ-JAl-FA2vVLFfLxZg0UVgv-PBRpVbIA-fUg-vGgNgCQIgHIfgCQF4TPMQHwC-C6eEMfLDO-ZGCvNXZ-avRfUHG7WwVfAULQ52XAo3ZVEQ03RsEAiYSQ6Q2Q+QsgTPDgC-MwZTeEH9EbYQkwtg+fKtEpUPMHYeeaHw+gzfPAywhPUQkgmnZPOwqQmQuQhQqIKAW3Y-aXEfGg4jHkYeU4YweaPeBAibMlAIs9WbKdGlWVHEIowWQ3JFMXGI2wyuRIxwhQtQVw7IncBKYeLkU4UI+PP8Pw0o4HGbRrSo2VIqe9T0CIiwnwog2qZo+wpIpwuANwjwvcCrKrYGf8YYoHU9EHc9EnYwnw3YwQx1NNJo8QunGAPvYfTPHIRwKAPvKAOHNYromWGdP8W-H-W0GYmrIPBfV-AwubS6ao++Eqf4+1OYwYwA6wnva4iYW4sQagj7XbMoYvI4Q1SEvYk9abEDVLMExvX4y8KE+opVeYuE4g5o24tQVE7bJjYjYNUBA1REYMeibQgHRLC7Tgt-Oba6VfdklvEXPA7fLveE4AxE8gfAZ4pHe43gLIN4i-YBQbDQ-A7-G-XEpLYEo4iY61cE9U-oTU844UMU-EbfXLCUsQuIsgiYGUsg+424iAbwCAV4QvIVIkyfNkgg4owHPE6CefEEvUkI70wgg3LLBow0y4q02IyXaU2UjPHPPPAvD4gbeENUg5GpUqSvQEsow4io-nJvVfTM4UqHDvDfLrSUm0-ve0uUrItE99DE+EBKFTM0zkufEY4pQM3Uws-U4ktsswkUo3Acqw6kqUziLPHIHITgZU1nBiBXT-PVOonQ9gvQnUgsnXQtUI0w1XcwyMqIhYxmZoiczPMAGgQvXpaLSMbwxzdsxA-w0Ygkq1EM6xW8wcqHA8qkxY8c1Keshk+TeuPoxXa4GfaxHcnAjs-Y-EjzZfE48C7MiMik2Ey0sc6sunE-UgRM63GAGUnIEgTPPvKgiAUIdYxzK6G4a0N8vhLkLUnkwI1A1LYebYgYKi66Gik04zJ7BEtCiYDCofSctgHCqAPCi-NGGdccH466W6NudiiNB8g4sY4nPUz0uhaS++WS8kuPcU1CuMvijPQvBKT0gdeodfX07k5A+irgzzBvTA0CzkocyMkc6ImM5ou3YSgAa3pLhms26NOCJO914SFOXK5Pxw4Msr5L1IFPJjZLsA5PfIpyjNeSuJ4vIFSIQEcEzztw4CgAkHeIbJK2QDH2gMwzZP2HMQtIBN0KBN5KDN7M-UFLKqNIINmMcp9PNOasrOtLjLSscAMtODIpMFoVTTvJKKgoDLJVqp1xfKow4saJcqlIYDEF4GHwkG8EWoECbH4DgCRwgAMEzxICIGHy228oi39W935FRlgLYuj32FoosvKPGN7JnWO2wOnxaqQu0u-JSvWpWrWqWv4E2u2qiHP1TPzQq15gO2jmwIFDurCoeqUqevTOYuuqnBhtmoAJQq+rjJ+ogFWqyH+sBrUFIH2sOogGOpxR8rOhZ13WUzVKkv4LMFhrXJqp7J1wFXmhugZveq0ujJ0viPIBxrxvWoBqmC2qJpIHdIDV5jnKhq5sqtXOqvCsmu+nZroWhsZvRs-MxqPKlIoKIAgBIDzxoH4EIDYDyAQHaCzzSOCAMCKD-JOs+y3jUJ6gjEpKZsVu7I3O+mmpy01rds6tjP5r1oNqNpNu8HNstszwnIv36qJP2n20AjDPdrzMUu12I1VtciTr9uQoDuaODsNuCDDrNsQEjvSqgHwDgGwplNdNEvyLUMq1dvjzOLks7OgqCJux9uh2bs0v-y1tzt1v1oLuNtNojo4Ez0WrcpyE8vtoptOvrn2kLQKKqTdvlvkrYU9seqmpOOQuzs+p1pSvztDpHpLs6PyuY0FAuo8UbttGsGTsfJgo7vTOvsvFvt3t5qxv5s4H1rgAeO8AtvWOAo6kEGXp3pbrGtCqsuCO3tLISr7q4qrLjK-tdMyvwBoFIFroby8OfruB5DvoUqfKgb3Fi2wa-G5t7v9vga6s-u-v2uyDEAv30mL1sF-QOxwY1rAf9Jrwit7OIaIeYtYdIbfqSvmpSqQbyv-MpvnrQ31QgTXyzPDJCqr0VvhrTp3F4amJQHD2Coco+vfv3sQe-v4ENrEBRJoAeLYD8D7wkAMqFXhGDR+KvzblutXtbpDwYqtVsb3F4UcfvmcehP3IoapylLEaMcWtMYYc8dDG91kZRqcbwbbvcbBwFUNWwJyTIaEJzsoe2iP0kBRzR1BoKl+wjhyQ5xcfAf0NZu9r0yF0h1gcCbW1mByYkBR0ZwKbKADSvOZNKY4e1JZq9t0zlWq38d0eEeIMaasalxl0L20GHlMGRspgQsUdzPvvbv5IzpVxwJ0Z5tGdqnGdyYHxtzcodydwkBd3PLafd0HDsfvwPGAej2MHibccgZuy0Y0fKDuanBj2Ge2d312eYCaatzT0TNz3z0lrjt+3qGb1JMea4eVrxRssRChejDJMQuVnLL3veT2eaYHyBa8tnsdvzCKvhG0FgNMuhbKc4Yqf6frwapxPRqcsPMxf+YmfICPxPzPxUKOHhCXojENjzj8ZzKqpToIZu0AZGz5biaEd+cZixYmDALoDxZ5UbNK0AZgJis8RGr9N6aVsqfhcFODRgf80SulaZZoABfIEcAYEoEgPASftLz6X6EOFOBhapc3vTqDURYdfxCdfSennRe9ZDW1tNfNcoMVZ22VaLXoPruRsEDUoaAUcgspfXLdbxSvM-1jf4IUa2fIcydh1lZaIcOSOcKUIlouZYz7U2PBoPDMFYsWcTe1ZUbQPEgFGMJrcNeWzgbzeZf2eWLaOcNPokbnubdjbjv2yOSXP9xRaWaFZWcScMLgujynezYyYxfsXzd7aLZ-tSPSKypnqVYKpL2qAIMksEHkZdeTYRs3OMNPfbbb07Yae7exY3dWMzw6L3fDYPb6Ib2qWXvgqnfrbosbe4IXfJe+ZzdXcbHXdaM3YvK9eKbponfvnYcFYVuFYfv5JA7bmQ9RfA70eDZZeRPuMeNlNeL9kL2ASvIvpzhKmw+ndQ9needBOMM9Bo99eGpNbXcfaRLuPfcZO3U0GoRuiupY9tFo4A-uvzJTf9WY9Y6ldHL+bNYI6IDpN44AvEhLL3ACpiqzP-fvNcdhd1YdmitNN3j+LY5Mrap2Zla4-jIdKzwVKtbI7LfsC5EGwSkCss80ZAXPb6ak4qTeZHN5F-zA6LkC46qyfzdrMTKdJdLdLLY9OJYE9DLMogY9omsM-84NIZazah2y6Dc48U-2ai-uJBZTLPu+gOQbwzNM+CvE7hsk8vYq+LJq-srLM7zw4K-NeK9U8kadq8fH2S9q70-KcBLhZMWM4s6zpC+njy4DvzZPKnJnOc9jZnU-WRqudA5Q7Xqee4Z1wGuJIqDirAXM7mrGZs5PLPNEraquhq+tCO4qF09GqTd88a7xROPu6GLk+crO8K+xejuc5Zzjs9CS+sQ+8e61cA4a9UZmn29CLB5O4xrm5s70qI8EtwvwsIuHxIuc-oMAYFCMldvu5Y5851epcy6L0J4fwR-vZiPzZR4EqEpEuc76LjqOBic5rzmC62-09dde+k73Dpo57bi55w5XY68g+R9QcwrDb45h78sS5+LJeRZJ6A+stpbM-pc8-k+s9+94t8Cnpl7U8oRq+qFMFkeDB05V6h6benX1ct816TqR919SugHSsysyJyvEYdvRJQEG291yXcI1OaopYbet9SzbYm80a9buAqum9NK14tKd-NZ6owe5Y+Zmp6boo3r5-J4GNvciPqdp5s8Fr+o2tFqBt2pJqOsL2Lwc2E41bvwTeG+e9J78-U+bI5ob-KHcOp8L5jPzZL-xrL7oC2p2pBvK7Ufl-nIKLoS79sFfsz4k9Tpt-afTMF7n9sF79zYfed8H+FsJuJoOur-i4G+v2Mhzg34X+55G5e+h-aiJM7-4Kv9F4uKs-w-2b34JvL-FoMqrd-BE4v5P8rey-Qksx0v5b8IOm0fNofULrH0LaY9a2jQFtqG9euBUYNESUYLrdQG1-Fvtnzv7cJoG2jD8n3x+7msYBw9cOifSzz-cJ+M0P8B-n6KAQ5+dbZvqHxAGeZ1m1wZgTlzqbb8i+zvcgUXVHpZ4y6FdKujwC974sfehVWovB1drgVu6K5bbgZzJ7NtMO98JdsQL4H98bOgguAZHQnr69p6NfS+uO0GLg9zK9XdgYQ1DAkNjuX3Rlp1xZZ6DKB8AnrkO3zBMNIa4mU7KwMh7WDH6XjOwRUHJxGsaeOg53mI1-psB-6APCtkez2TBCWBT3bVngJX6TEDSWtBwV+R17msohfFC-LGyvKns8++IfSMAJFbHEiGCHZlOUOyH5cJekQmhobQgD0NmeLba-On25BHc6hi-KwZUL1Jjg7Gapc-jg2f57kRmHHRoXkO-oGVBAgKcrFUim44C2BAwnhoNnmjLCX+7HbXu-2xYhNjGpjcxpY0kA2MiS+kWArazzhN8Uh-gtYTrlArVBckVwtuDwLCEkCFOMw10qExMa0Bf+cdL0oAOuEVD0OyleEBxjn7A8IB4vCgMtRmASByAwlPIPgEyKO5JCpbWgVIwbzaBJKrFMTn4IsppDGKrbaPNTzxENDYRcAeEeQDgAAArSuqiIQDojIC0jLxkMOrakiQ+WfdLqoJmSR9u+nIuPjiHJGdVbiCAHIBaytb8Aj8rpPCkQBtz8A+8R+HIH4AHbe8I2CuYwHHTHyIho+WgDSkoJ56jcMuBA-kXqOQB9IEe5oy0aKOPwSimRPgAGvnn4A8BvAS3TEfmkiYoAxwv6EpviDSZcil+9w76Pt2Yp+i7gAYoUb7zjY3QKR3HcUeQAdGBwJAbANgAIFdFsB3Rg7AlmUGnz+Up+9QcMdGJBGrM9SsPREEWKLzOt0aQvYsbaITG7tPe-ANgERVPzj9sx0ggotFh-QsM42yQiHkGNBG9ld0iIPov0EWbLtp4jA-EEcDjHkAxREo7gAYHwBsAyCMdOuqoiXKFjv8lowMf0KHEPDV8gaGcQaImHKxrRNFTqmIzJCpi-YaRfgAuDOGeFDgFYo7oOBLFzs5sqrV8eOPGGTjhQF4ucdeKoC3i4A94wEMqUaqadQKJlKiu+L3HM1W+OfZtoWgD5wS-xUOQCVeO-oTA2WqDM-NaRjpajmybVeoKfzuDj4PxjHSKvyF1Fd9KJ6NDYhROdbYTXSuE4-PhIMAD4DAaRIiUSX-AqZyJWgB5ghOUZh9PMtEgCfRJElRiLRfYliZQ2Al4S2x5AVanAG2p8T0y04sidJKom7diMkknSeOJkk90i4TErQApPgxKSOJKk-ANkFQaSD92tBfIkSW0CyMhJFokyYaJv5IT8BBUQycJOMlWj5JQEnCayxskETXSZXDsRqJcnEt+qdEoKaJLQ6ljhxAUzyUlNknmS5JoUtieFPZZcTOAjgNIJpM05bjApM4ryXR2UG88-JsIdKR5IYlZSQprE2ERFK4kGBaAkhLMeqM-YfMomb8IyZVL0ljd64DU3SYxJamKSwpobCAM2LaEeiComGUBH0UKJxtbANwgcfuNSmbk02EYDNqjTeEdsPhAUYCb20LpIiacmRUqdUDVK8MTQMUEaSaPzBLk3m90yPCLzPG4c3+ZcM6a0ULp0iGRaoqQbFOInzk7p5iYNE9N5EDhOByAFrt6Kqn-jOKVksKSiRICcAOA7lfgNbjEBnkZCGImKX1LYwFiKpFEzaZYMQmq9YKe4Zio1KOlt4sJ00vKejMxkQBsZcAHCiQHbG9TnJG4qJhcF1FvjTxdXKmeJLBwP8hZ4408cjP1HSzcpFAFscPjbFGNmAjkj9sxi7HO1f0pwdCLrJJ5Ejnyq+XWf0H1no0TZ+IfWa1N4pwAU8bASQnNJyB-0EALIwtFsSSEUzUuARQ2TYMyEr1ZJ4QvfMBNCB2yHZD4kKHML5a3SmCB4LYdVKNG390h8MjYRGDjmyzEezMigCHKtz2yOAjuKXoTN5nEYbo37NDGYP6C9CVhdwg8VU2qF2DK52wlGUFmDm2yc5YcloQtKJm0F9I+3L-CplGHdDoZbfZnINnZH1AB5hVDCbwMgETAW5dsvGWgzwo4znZo+dws7XLlDdbhhInkcPKqIHd-Zpk1-lMIoBzyc5C8gmeHMaiRzQEfSTYSlyUYpTPxgwlObHPz4wkZ55AU+Qc3PlLyChAPOchHBuatoG58cnydTMCHVAx5q0EBenMDlEQv5uM-GUvI7kMN90h2dDMKAnkgLRZYkgIXNnZGQKRhPQqee8O0FBywp2ct1HAAkAMBT8jsleXEP24EFShmrSmWl10SjTTRbzLIQHJOlEIv5rpGhXQsvkehI537HUa-M3lbSxZeC5+cYTTlaCP5Ai6hbQp4D5y0GhckGQeyKEXUb2Ow7BQSO2lPzeyw8KBSthgWKKYRs8iha3KoVCK1FKC9ob3O-C8IsF4wnBY-OonrDhho44hdCJ+lOgv5oguAMvJiEuz4uJvbkKRN9p9DEJPsiBX7OwGNzTu8CmxehSeIV0RFiwFkRPmMo2A45HihjvpLUYvycQCi6eVYs-lpLeKGSkJX-MWmwhAevMKKsAvcWGKZFwYncKYpqEVySFx0shakrymULgloTVoagp+z9y-FyUopZwpHk+LMFUy3hQMtOlhTrxYdOAHrTgA9StFzksGdUHoKwFAJ0yrsjvOQl8i3mRyrKTuMvH2gHQ8AXwCUGSDl18AKgW4OnnwAIBkA5AT+ZwBnLW5lqaRXgJwCpHCBsKqVOAGoBaE04PKw+EAPKCIpO4bcry5YIIDhXJBfgnvV5X4FPwIBBA-ARwNnh9Dyh5gMAPwK8oABKAAcQABCAAQQIIEE0VdkYcsAw1KsqJ4Kov2K8pEBaimVwIUlSHXwC8AXgrygACQAAVCFVCoAAKMKiAMgHSACqSAAAVSFUvA18lAT0LwB5CT5-YPUawGAC5A5BPQUAOADFEYh2AoAYALVTkF4DWBkAUATQGBP2BQAmIYAANExAKI5AtR+2SgGADsBgBeAdgb1dYFNVcgWMvqvou6pVFcgwAYARgnAH-ChqckUAT0JQAqC8AYowDUVSACGB5qsAQAA")); })() /***/ }), /***/ "./res_built/atlas/atlas0_hq.png": /*!***************************************!*\ !*** ./res_built/atlas/atlas0_hq.png ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/atlas0_lq.atlas": /*!*****************************************!*\ !*** ./res_built/atlas/atlas0_lq.atlas ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports) { atlas0_lq.png size: 2048,256 format: RGBA8888 filter: Nearest,Nearest repeat: none sprites/belt/built/forward_1 rotate: false xy: 565, 10 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_10 rotate: false xy: 1724, 14 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_11 rotate: false xy: 1777, 111 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_12 rotate: false xy: 1994, 119 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_13 rotate: false xy: 1766, 14 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_2 rotate: false xy: 607, 11 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_3 rotate: false xy: 1726, 160 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_4 rotate: false xy: 1768, 161 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_5 rotate: false xy: 661, 12 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_6 rotate: false xy: 1723, 110 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_7 rotate: false xy: 1640, 65 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_8 rotate: false xy: 1640, 15 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_9 rotate: false xy: 1682, 11 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/left_1 rotate: false xy: 1084, 61 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_10 rotate: false xy: 1856, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_11 rotate: false xy: 1902, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_12 rotate: false xy: 1948, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_13 rotate: false xy: 1654, 115 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_2 rotate: false xy: 1130, 61 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_3 rotate: false xy: 1176, 61 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_4 rotate: false xy: 481, 13 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_5 rotate: false xy: 1504, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_6 rotate: false xy: 1550, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_7 rotate: false xy: 1596, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_8 rotate: false xy: 1642, 161 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_9 rotate: false xy: 1810, 163 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/right_1 rotate: false xy: 1502, 84 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_10 rotate: false xy: 1902, 115 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_11 rotate: false xy: 1948, 115 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_12 rotate: false xy: 1765, 64 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_13 rotate: false xy: 1808, 15 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_2 rotate: false xy: 1548, 84 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_3 rotate: false xy: 1594, 84 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_4 rotate: false xy: 1456, 64 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_5 rotate: false xy: 1502, 38 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_6 rotate: false xy: 1548, 38 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_7 rotate: false xy: 1594, 38 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_8 rotate: false xy: 1719, 64 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_9 rotate: false xy: 1856, 115 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/blueprints/analyzer rotate: false xy: 826, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/balancer rotate: false xy: 747, 157 size: 87, 48 orig: 96, 48 offset: 5, 0 index: -1 sprites/blueprints/balancer-merger rotate: false xy: 1176, 107 size: 47, 48 orig: 48, 48 offset: 1, 0 index: -1 sprites/blueprints/balancer-merger-inverse rotate: false xy: 925, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/balancer-splitter rotate: false xy: 1275, 157 size: 47, 48 orig: 48, 48 offset: 1, 0 index: -1 sprites/blueprints/balancer-splitter-inverse rotate: false xy: 876, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/belt_left rotate: false xy: 854, 61 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/belt_right rotate: false xy: 946, 61 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/blueprints/belt_top rotate: false xy: 1324, 157 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/blueprints/comparator rotate: false xy: 555, 60 size: 48, 45 orig: 48, 48 offset: 0, 3 index: -1 sprites/blueprints/constant_signal rotate: false xy: 527, 13 size: 36, 44 orig: 48, 48 offset: 6, 4 index: -1 sprites/blueprints/cutter rotate: false xy: 926, 207 size: 87, 48 orig: 96, 48 offset: 5, 0 index: -1 sprites/blueprints/cutter-quad rotate: false xy: 187, 157 size: 177, 48 orig: 192, 48 offset: 7, 0 index: -1 sprites/blueprints/display rotate: false xy: 1456, 110 size: 44, 46 orig: 48, 48 offset: 2, 0 index: -1 sprites/blueprints/filter rotate: false xy: 562, 157 size: 92, 48 orig: 96, 48 offset: 4, 0 index: -1 sprites/blueprints/item_producer rotate: false xy: 1859, 207 size: 45, 48 orig: 48, 48 offset: 2, 0 index: -1 sprites/blueprints/lever rotate: false xy: 1883, 72 size: 35, 41 orig: 48, 48 offset: 6, 5 index: -1 sprites/blueprints/logic_gate rotate: false xy: 1999, 213 size: 48, 42 orig: 48, 48 offset: 0, 6 index: -1 sprites/blueprints/logic_gate-not rotate: false xy: 1366, 108 size: 43, 48 orig: 48, 48 offset: 3, 0 index: -1 sprites/blueprints/logic_gate-or rotate: false xy: 1999, 169 size: 48, 42 orig: 48, 48 offset: 0, 6 index: -1 sprites/blueprints/logic_gate-xor rotate: false xy: 605, 61 size: 48, 44 orig: 48, 48 offset: 0, 4 index: -1 sprites/blueprints/miner rotate: false xy: 1514, 207 size: 47, 48 orig: 48, 48 offset: 1, 0 index: -1 sprites/blueprints/miner-chainable rotate: false xy: 1612, 207 size: 47, 48 orig: 48, 48 offset: 1, 0 index: -1 sprites/blueprints/mixer rotate: false xy: 745, 207 size: 89, 48 orig: 96, 48 offset: 3, 0 index: -1 sprites/blueprints/painter rotate: false xy: 366, 157 size: 96, 48 orig: 96, 48 offset: 0, 0 index: -1 sprites/blueprints/painter-double rotate: false xy: 187, 61 size: 96, 94 orig: 96, 96 offset: 0, 2 index: -1 sprites/blueprints/painter-mirrored rotate: false xy: 464, 157 size: 96, 48 orig: 96, 48 offset: 0, 0 index: -1 sprites/blueprints/painter-quad rotate: false xy: 1, 20 size: 181, 48 orig: 192, 48 offset: 3, 0 index: -1 sprites/blueprints/reader rotate: false xy: 926, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/rotater rotate: false xy: 1025, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/rotater-ccw rotate: false xy: 1165, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/rotater-rotate180 rotate: false xy: 1026, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/stacker rotate: false xy: 656, 157 size: 89, 48 orig: 96, 48 offset: 3, 0 index: -1 sprites/blueprints/storage rotate: false xy: 383, 59 size: 84, 96 orig: 96, 96 offset: 6, 0 index: -1 sprites/blueprints/transistor rotate: false xy: 1682, 61 size: 35, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/transistor-mirrored rotate: false xy: 1811, 61 size: 34, 48 orig: 48, 48 offset: 14, 0 index: -1 sprites/blueprints/trash rotate: false xy: 1076, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/underground_belt_entry rotate: false xy: 184, 21 size: 48, 38 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/underground_belt_entry-tier2 rotate: false xy: 655, 62 size: 48, 43 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/underground_belt_exit rotate: false xy: 234, 21 size: 48, 38 orig: 48, 48 offset: 0, 10 index: -1 sprites/blueprints/underground_belt_exit-tier2 rotate: false xy: 284, 21 size: 48, 38 orig: 48, 48 offset: 0, 10 index: -1 sprites/blueprints/virtual_processor rotate: false xy: 1175, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/virtual_processor-painter rotate: false xy: 1953, 207 size: 44, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/blueprints/virtual_processor-rotater rotate: false xy: 1700, 111 size: 21, 48 orig: 48, 48 offset: 14, 0 index: -1 sprites/blueprints/virtual_processor-stacker rotate: false xy: 1412, 158 size: 44, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/blueprints/virtual_processor-unstacker rotate: false xy: 1315, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/blueprints/wire_tunnel rotate: false xy: 1415, 208 size: 48, 47 orig: 48, 48 offset: 0, 1 index: -1 sprites/buildings/analyzer rotate: false xy: 1015, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/balancer rotate: false xy: 737, 107 size: 87, 48 orig: 96, 48 offset: 5, 0 index: -1 sprites/buildings/balancer-merger rotate: false xy: 1275, 108 size: 47, 47 orig: 48, 48 offset: 1, 1 index: -1 sprites/buildings/balancer-merger-inverse rotate: false xy: 1365, 208 size: 48, 47 orig: 48, 48 offset: 0, 1 index: -1 sprites/buildings/balancer-splitter rotate: false xy: 1465, 208 size: 47, 47 orig: 48, 48 offset: 1, 1 index: -1 sprites/buildings/balancer-splitter-inverse rotate: false xy: 1225, 108 size: 48, 47 orig: 48, 48 offset: 0, 1 index: -1 sprites/buildings/belt_left rotate: false xy: 900, 61 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/belt/built/left_0 rotate: false xy: 900, 61 size: 44, 44 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/belt_right rotate: false xy: 992, 61 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/right_0 rotate: false xy: 992, 61 size: 44, 44 orig: 48, 48 offset: 4, 0 index: -1 sprites/buildings/belt_top rotate: false xy: 1324, 107 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/belt/built/forward_0 rotate: false xy: 1324, 107 size: 40, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/buildings/comparator rotate: false xy: 1710, 210 size: 48, 45 orig: 48, 48 offset: 0, 3 index: -1 sprites/buildings/constant_signal rotate: false xy: 1688, 161 size: 36, 44 orig: 48, 48 offset: 6, 4 index: -1 sprites/buildings/cutter rotate: false xy: 836, 157 size: 87, 48 orig: 96, 48 offset: 5, 0 index: -1 sprites/buildings/cutter-quad rotate: false xy: 370, 207 size: 177, 48 orig: 192, 48 offset: 7, 0 index: -1 sprites/buildings/display rotate: false xy: 1038, 59 size: 44, 46 orig: 48, 48 offset: 2, 0 index: -1 sprites/buildings/filter rotate: false xy: 555, 107 size: 90, 48 orig: 96, 48 offset: 5, 0 index: -1 sprites/buildings/hub rotate: false xy: 1, 70 size: 184, 185 orig: 192, 192 offset: 4, 3 index: -1 sprites/buildings/item_producer rotate: false xy: 1906, 207 size: 45, 48 orig: 48, 48 offset: 2, 0 index: -1 sprites/buildings/lever rotate: false xy: 1958, 73 size: 34, 40 orig: 48, 48 offset: 7, 6 index: -1 sprites/buildings/logic_gate rotate: false xy: 755, 64 size: 48, 41 orig: 48, 48 offset: 0, 7 index: -1 sprites/buildings/logic_gate-not rotate: false xy: 1411, 108 size: 43, 48 orig: 48, 48 offset: 3, 0 index: -1 sprites/buildings/logic_gate-or rotate: false xy: 705, 63 size: 48, 42 orig: 48, 48 offset: 0, 6 index: -1 sprites/buildings/logic_gate-xor rotate: false xy: 1760, 211 size: 48, 44 orig: 48, 48 offset: 0, 4 index: -1 sprites/buildings/miner rotate: false xy: 1563, 207 size: 47, 48 orig: 48, 48 offset: 1, 0 index: -1 sprites/buildings/miner-chainable rotate: false xy: 1661, 207 size: 47, 48 orig: 48, 48 offset: 1, 0 index: -1 sprites/buildings/mixer rotate: false xy: 647, 107 size: 88, 48 orig: 96, 48 offset: 4, 0 index: -1 sprites/buildings/painter rotate: false xy: 549, 207 size: 96, 48 orig: 96, 48 offset: 0, 0 index: -1 sprites/buildings/painter-double rotate: false xy: 285, 61 size: 96, 94 orig: 96, 96 offset: 0, 2 index: -1 sprites/buildings/painter-mirrored rotate: false xy: 647, 207 size: 96, 48 orig: 96, 48 offset: 0, 0 index: -1 sprites/buildings/painter-quad rotate: false xy: 187, 207 size: 181, 48 orig: 192, 48 offset: 3, 0 index: -1 sprites/buildings/reader rotate: false xy: 1115, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/rotater rotate: false xy: 976, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/rotater-ccw rotate: false xy: 1075, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/rotater-rotate180 rotate: false xy: 1215, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/stacker rotate: false xy: 836, 207 size: 88, 48 orig: 96, 48 offset: 4, 0 index: -1 sprites/buildings/storage rotate: false xy: 469, 59 size: 84, 96 orig: 96, 96 offset: 6, 0 index: -1 sprites/buildings/transistor rotate: false xy: 1819, 113 size: 35, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/transistor-mirrored rotate: false xy: 1847, 63 size: 34, 48 orig: 48, 48 offset: 14, 0 index: -1 sprites/buildings/trash rotate: false xy: 1265, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/underground_belt_entry rotate: false xy: 334, 21 size: 47, 38 orig: 48, 48 offset: 1, 0 index: -1 sprites/buildings/underground_belt_entry-tier2 rotate: false xy: 805, 63 size: 47, 42 orig: 48, 48 offset: 1, 0 index: -1 sprites/buildings/underground_belt_exit rotate: false xy: 383, 19 size: 47, 38 orig: 48, 48 offset: 1, 10 index: -1 sprites/buildings/underground_belt_exit-tier2 rotate: false xy: 432, 19 size: 47, 38 orig: 48, 48 offset: 1, 10 index: -1 sprites/buildings/virtual_processor rotate: false xy: 1126, 107 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/virtual_processor-painter rotate: false xy: 1366, 158 size: 44, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/buildings/virtual_processor-rotater rotate: false xy: 1994, 69 size: 21, 48 orig: 48, 48 offset: 14, 0 index: -1 sprites/buildings/virtual_processor-stacker rotate: false xy: 1458, 158 size: 44, 48 orig: 48, 48 offset: 4, 0 index: -1 sprites/buildings/virtual_processor-unstacker rotate: false xy: 1225, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/buildings/wire_tunnel rotate: false xy: 1810, 209 size: 47, 46 orig: 48, 48 offset: 1, 1 index: -1 sprites/colors/blue rotate: false xy: 184, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/cyan rotate: false xy: 204, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/green rotate: false xy: 224, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/purple rotate: false xy: 244, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/red rotate: false xy: 264, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/uncolored rotate: false xy: 284, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/white rotate: false xy: 304, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/colors/yellow rotate: false xy: 324, 1 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 sprites/debug/acceptor_slot rotate: false xy: 1640, 124 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 sprites/debug/ejector_slot rotate: false xy: 1854, 19 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 sprites/misc/hub_direction_indicator rotate: false xy: 362, 3 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/misc/processor_disabled rotate: false xy: 2017, 40 size: 28, 29 orig: 32, 32 offset: 2, 1 index: -1 sprites/misc/processor_disconnected rotate: false xy: 1879, 13 size: 23, 30 orig: 32, 32 offset: 5, 0 index: -1 sprites/misc/reader_overlay rotate: false xy: 1883, 45 size: 36, 25 orig: 48, 48 offset: 6, 11 index: -1 sprites/misc/slot_bad_arrow rotate: false xy: 85, 5 size: 13, 13 orig: 13, 13 offset: 0, 0 index: -1 sprites/misc/slot_good_arrow rotate: false xy: 100, 5 size: 13, 13 orig: 13, 13 offset: 0, 0 index: -1 sprites/misc/storage_overlay rotate: false xy: 2017, 102 size: 30, 15 orig: 30, 15 offset: 0, 0 index: -1 sprites/misc/waypoint rotate: false xy: 55, 2 size: 14, 16 orig: 16, 16 offset: 1, 0 index: -1 sprites/wires/boolean_false rotate: false xy: 71, 3 size: 12, 15 orig: 16, 16 offset: 2, 0 index: -1 sprites/wires/boolean_true rotate: false xy: 470, 2 size: 9, 15 orig: 16, 16 offset: 3, 0 index: -1 sprites/wires/display/blue rotate: false xy: 1, 2 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/display/cyan rotate: false xy: 344, 3 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/display/green rotate: false xy: 19, 2 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/display/purple rotate: false xy: 398, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/display/red rotate: false xy: 416, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/display/white rotate: false xy: 434, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/display/yellow rotate: false xy: 37, 2 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/lever_on rotate: false xy: 1920, 73 size: 36, 40 orig: 48, 48 offset: 6, 6 index: -1 sprites/wires/logical_acceptor rotate: false xy: 1854, 25 size: 23, 36 orig: 48, 48 offset: 13, 12 index: -1 sprites/wires/logical_ejector rotate: false xy: 1921, 14 size: 22, 23 orig: 48, 48 offset: 14, 25 index: -1 sprites/wires/network_conflict rotate: false xy: 380, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 sprites/wires/network_empty rotate: false xy: 1904, 27 size: 15, 16 orig: 16, 16 offset: 1, 0 index: -1 sprites/wires/overlay_tile rotate: false xy: 1921, 39 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 sprites/wires/sets/conflict_cross rotate: false xy: 1065, 207 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/wires/sets/conflict_forward rotate: false xy: 649, 11 size: 10, 48 orig: 48, 48 offset: 19, 0 index: -1 sprites/wires/sets/conflict_split rotate: false xy: 1504, 130 size: 48, 29 orig: 48, 48 offset: 0, 0 index: -1 sprites/wires/sets/conflict_turn rotate: false xy: 2017, 71 size: 29, 29 orig: 48, 48 offset: 19, 0 index: -1 sprites/wires/sets/first_cross rotate: false xy: 975, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/wires/sets/first_forward rotate: false xy: 1765, 110 size: 10, 48 orig: 48, 48 offset: 19, 0 index: -1 sprites/wires/sets/first_split rotate: false xy: 1554, 130 size: 48, 29 orig: 48, 48 offset: 0, 0 index: -1 sprites/wires/sets/first_turn rotate: false xy: 1955, 42 size: 29, 29 orig: 48, 48 offset: 19, 0 index: -1 sprites/wires/sets/second_cross rotate: false xy: 1125, 157 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sprites/wires/sets/second_forward rotate: false xy: 2036, 119 size: 10, 48 orig: 48, 48 offset: 19, 0 index: -1 sprites/wires/sets/second_split rotate: false xy: 1604, 130 size: 48, 29 orig: 48, 48 offset: 0, 0 index: -1 sprites/wires/sets/second_turn rotate: false xy: 1986, 38 size: 29, 29 orig: 48, 48 offset: 19, 0 index: -1 sprites/wires/wires_preview rotate: false xy: 452, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 /***/ }), /***/ "./res_built/atlas/atlas0_lq.json": /*!****************************************!*\ !*** ./res_built/atlas/atlas0_lq.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4IgZgTghgtgpgZxALgATALAChsgQBwgEsAXRAegCM4AbEqgVyLvLAHsIB3KCAEwH0ADADp8AOwDmKbJiwBIcNHgp0IAB4oAnADYANCACeWgOyD9nFABYzIABZWAHAF9d2BRDYkoZXirBQaBDhXeRASYhh4XzRwhmC3PEJSOABlNgYIAGNUogAvOBVQDWRLfSNkGwsSm3sS5xCFBHSsnPzCkCrLB31arqdsF1wCYjIEKlp6SiYWdi4eAQBGUUlpLFkFSFgCtCKUBesyk0qrGsdB0I8vHz8AoIawiKiVWPjQ4eS0jOyUvO3VYtKhhQx2qPTO9yaX1af1AnW6djOAxCiRGFGoLCmzHos24fH4ACZllJkDIEptlDt1Ch8fjNIdkA5tABmcwnMF1c7uTzeODRVD+QKvBThIiRXnPCBxCFJMifFo-NqUgH0kEHBEciHNb6-dpw9l9JFDGVoiaMLGsDi4gRMomrdaKLbtYr44z4+maBYAVlZoPVfXulx5fIFdwSIrFfJe0tRcu1iv+VhVPrVvXqCUh8p1lL1fuchqwKOSY3Rk2m2Mt834lltJLWZKUMKpyBdbqByB0xmTpw1CUD1zQIaFD1FTxikqH71lWuhTsTbdV3f96enCsbOdT-Sw50Lo3GGLLFrmeM9NdJoXJjedxhZbYcTO9HTZuc5ID74oHtyH4dHqCj6eNsYzkqc7lAu+ppm8K5Zqo66IluyKTia+7mjilbaKedbng2s7VA+5TGJ6YHPgG3L9vyn73N+76-uO0YfFB8a7CUSaPr6G6alCq66o44GbtuiHFqamIzBWeLGBh9oXjh943vh2hEexvakdRg6UY81F-m8AEMZeIHAl2vEcZmjGsV0vH5juSGlihokCA4En1o6wElJYdJtgRCngkpVwqRRYbqZGtH-jGOk4YCoEGcRy6cdBsI8c+FkCXu1kiUeAiaA5WFOQmyBMpona3oIradIuEFcj5wZ+aEVGBVKwX0TFJnKvOkWKZBjVrvFG6JcagnIalVr8AsIjiMSZ4bNhzn7As7oLAVJWGd5QY3IKakjhpQVaSFHVhSxC1Re1xmdXU5nwUaqJ9Sl5ZpUNSyjXajkUjlCwOOFWjaG5+1teVy0fqt-nrbVE7aTtzlvRUrVeYdcbHWZCVnQWSUlmaA2VgshL3bWkmTc9Dh4SgDgepDPYXMplX-dVAUSnVW0NUdu0taZpUvhmMPcSd8P8b1yUo9dg0LDamPjQ6T1MTS8LlJolg3l9UM-WRqkAxG1PA9t9Ng3tT7fXgoXZl1cFcxdPPCfQNBwGAJBCJlE3ZUxskoK6D6dICvSWC+b7k6GlOAyrdFTqDOU2OUgLO-qbtGWzesc91COWZdvPkGbFtDdbIu6bl9LGNeyYu1Y4dLQrVXClTY4040IPq4H9Ih3nYcs7rMH6xyPVG8jJuJ+blsYysWOPenXrg8YljzbXfr56TFUrV7xc+6Xqt05HVdtjXLl1xHQGN9HBsIdzbcHknluCz3wtSVNRWZ9npm5y57tk1PX4lzRZeWYBXHOUHc6h2P9cB3FW-N7HJGQl96dyrKnU+OVPQzXckPHOa8C6+QpjPZWc8-apAbkxD+zEr7wOhhvP+cMY6GyLMbEBycTxC0wjbUWTZ7YMnxNAr+rtb6Tz+tPYcKCn7z39pXTB1c4Hf3Xm-TehDt7nRIXvc0B9+DoUodjW2TZLAC3pNoT0K9LDXw0Sw365EkEcJ-JpcuatF58OXgI5hQjYqmXhEQnerdgFSNAeJORfdpLaGgeUbQ2h1GaPHvLRB7Caq+3qjwkxTYsE+NwY0DB1jTrEN3JIlg0j7IuKyjQ4oTJBBuXwsNcxedtGFz0UE1BIT0G-3CfwnBgjoq8NiZzOxEiHFJNARlVJ1D074k9AVfCeU8k3xIqw3RgTH6GJfjE4oES+laMsSZWCAD4lWQTtI4a4CcZ21USohYegqkWIQZ7B+s8uFoNflYiZlSmH5JmbDGxYjEa7yaabUBCw7rHyoWnaSyi2xeOKqPXZE8dGK29pw0ZiETlNX0mYnZlyalhLmQaQB9z+qPOTujVZCjnTuJUUTKF-S9n3zWsCzaRiF74IqZCi5uK8HCIITc+ZDSEkPI7iio+Y03kQLFlkzOCxPq-Ohf8wpwzDkgormEs55LeWUuieUuFeYEX2KReQYgEhbCWxGq8+R6SrCYq+WoqZfjXx3zYQcwlz9QXjL0tgil0yYWkplXxeliz25KpVSnNp7znL4nPu5bQI9V7VP5QE41BiiVjPKc1YOeqf61LtS3RpCrnVdzRZq6o2SHZeqtfqj2+KlbBtNSK0l4bP4SutVSqxMa5VxquoqogyrD5JvTvebpDt0aRoGQCou+iNp5uMQWi1kT-VSujU3eFCz45OprS66sbr2W0MEPjZABF4QZoKYGglubuFlNqYWy1xb9Ws1tcO2Vo7SHmgTfwCh6rXEesIpnBwvqNFRINYMwFyD13HPNdgiNOKS2DthYe+14iGXxonZbWRl60n900BLAmXpW14qNWurtG6wXp3Bv2v5v6D3-xHQ6sdB4z3OPA+0nC+wm0MmlnBgN+zENA3fWGvtlHMPUrqbYwDjr8Mgf4Ckoj7qcqaFTQyD6jGn3tqKSMkNZr6OfqLX6jDOtpX-tjUBqtZ7Wk8ZncUKB9I72ql8Su6jOakN0a3Qx79e6YnluPYk+gZ6VnTrWU2L0WDjCaCdru-T2agVvtKShhmX7l1XPZqIulbG8Ons488+tOF+PaYYcJrNCHDO0Z8x+tDwn93Mcs7hk9LBbPd1ZRq9OWnbw0ni4aoZQajMpak2lszUa-3YaPdl6z1ba1DRZQ9CD0ltNCbq22gVlXku01Cb26TO7ZN8qY2WxTFaEk0DiEkMQJBLr8APlF5ydCPT3r0-11dSXgnDc3aKiF-n3OBajsFnDoWqDzbgIt5byV+AJvWzlSwXTM7prO-BirNGDvEpG8x7d6HJvyaHY1gDdzW63fuytkgbB8AvaYhojxBNPtsTliJgbv2SmHd8xrRmssSZTdmTNqz0PiBLbGJkNgYgEBeCW-wBANaxABER7Q2k9I8ogiZNs3oTIPOJa81V3HH7tkRVYjz-U-PzsiNpVdyHEjydEEp+QTIDASBkAgAAWgAI4MCgLwNnxRuUo+QJ6NzyAXqaLKpjvbQuhv-aO6N+dIIreLVLSTy3mhWysYV3NhbFOHtq413ACARu9h3s57B1ikeDr+IM-bv7oaTNm81gyAq2sMvTfbLz25ccbsB+Vw93gRACA0CgAYcPlvBBi4dviGWxbtAC5+-tnHju8c5VbOUH5E2ShN5lzSuJzWlcq7AFiUPVe6H4gfaxbF2sEst8T235Px2xsgjnxjrPnudBD+u5QEfD2zYADcJ-2fRVYUw9JOm+qZHLwQzeX2dodyv539ILe3-1PfgfLG89IwP2MGgNgCQIgTIfgCQHkLXMQTwKvG9NsHQC3SwH3DHBfR-YpI5arFPOhVUJAonUHBrS7JrPff-ROIAkAsAiAjgKvYaMjc3HvS7fEB-DtNA4VHtQHE7CFOFBg7-LLIgwvFXQA4A0A8AsgLXcIKAWnUvOHMPM-ZNfYNDOGKoe8d3ePTzV9YXdvD9LBbnB8TPCzUnYfPgw-UgoQiAtQSgmQjpbFcoL0HlcHXbBPNQhwl-NgiGAnf9bg-Q3gu7QPAA4w8gsgSfaPcoT0H1ZMOXT0RgsTIVCTfNFwrQsI-UCIjw8HJTNEYgmAZXUPLXTIWwKAZXKAffOAKvSwbQLvFAJkN7ZMDPZA8rVA8TbtElFw03VUao3Arfa5XfP3NIwwsYDIsQU-dTBzDFOhT0fKKo5Q23Jw5gmI1g05PYNPYeCY9ooLOXQgro4sdIogNQAYgrK9PjaDZsGfKoQmCYlApg+o5DD9LAn0E4uPPArDHfepLwmHcgfAPIpbLI3gdIQoyfWPcoBvHPdkHQSIwVThR-STFPeI2fXPHPerB4mE4E1IjYno1494zXLXDIiADwCAXkKgqwvYUYn0R4+fWo84w5cE2IuY1w8XKoYkzfPQwEp49YgvbwovMYN4ovLIvXA3SfTnH0F6VYkEwbJPCE1fZo-khwQU5I7lHA+XfPffFEjkj46QwY8-XKAiK-QQAEuk3As4qIsEjtUU0bKE2kmEpcD3Y6HUuUv-FEt8bXTITITgKvWkU3BhRhdw77Oo8kw0yk8Fakjgj0i0lYzo+U4gu0rXMAGgZ0vGK-ZkBIu4vU0En8Ck2Yv0k0wM4nDopk0M205SFU3YrrMGeSTnMYn-XU0k-U5Mn01M9OdMuwm1TLTw5khU1klXMvUgdE6nGAN4zIEgLXZXE-CAIIKgu8TnUIss80lQwXRw1Q5wqkusgguExslI2bbo1sh7dskPe0tgbsqAXsqgwQMjH1Og1o4eIU7HdAkXKTcU0yU84wJc7PRcpElkl4zczXZ04wA4pkD-GPU8m3RM4U5fI0lwl3G4v8h87fM0tYnM9csYOnPcgAax2M62Iw2163+MPJuLchJOfTJJNUuKk2uJj2wvpIU0ZN9xgpeLEIQFsC1zpw4CgAkCKIsOi3BgqKXQJh0PenPNb0vI0Kk1r1cOOK4thOSJ1MRNXORNgvIGotsA-LIy53jJwtEyTLt34shIWKlIbMfMFOfJbJeIYDEF4FDwkA8EMoEBLH4DgCWwgAMFEKIFD3yxQt4yYnNzf09DoLl2l09Lwu8yvI0rbAQK8ogqzIoptOkvMpMrMqMv4EsusvCErxYrPhoKgyUvKP-IrNUuf2AvnPpFyTLNvxCuDOzPCoMqMqivSBirirUFIHsscpgPnVGNsOC0KvsNnOmIaIB1yrcP-lau0s9yfMkpfJ8PIEiogFMsqosomCspqpIF5K+UEHdN6oytwsrPULnLTM0vZD6qDIu10qGv0pGqPyIAgBIH1xoH4EIDYGyAQCaG13EICAMHyHzOco0wjzoSUWaq0qo3asfhTMaO6ppIzPuOXMGrJxROOtOvOsuo8Buruq1ztOKKCK1QBKUVOMysAr4o2tQwWOgV0LIrBoMOkshrOoCBhuusQHhpoqgHwDgC7LeJxMn3HOCPHLhSSJ8rWuyt9NrK2r9HZt2tlxDNKqOpOtJouqurho4C10MvgsyCQpet7kLL4zKJcg4vrJ+unKf1nJys2p6sXOSMJueJFqhrJolspvMNVOTR5wEyUSWv1o5qyu1u5pwgXO+szOKrCt3mIM4BOrgGyI8FuuKOLOXlcjSvLNWsds1p1p5r1rdpBp0qFq9pRJ9pxLovwBoFIGdOeTf00FRtpXxBWpUsxpYIBt1u71VHzpt2WL2sTqh2Tt9tEIyDEGKJczyo51YgLvZALp4qXyxujpwk9U1J9E7vVG7oNv2vBukpTuYstobXezbALu2WOPRojuLpmNLo6TrLjursFpKqTqnt9v4DOrEH6JoGyLYG8GVwkGdKUOXk9DVs+V6HvLas1o6oIpTzmjT0fovyKprr3rroPpxKPsMtPqztNzUU8v1GfodrXs6qdziN5qft-t3s9tbmmBL0kBWzWySpyjoUdjK1XovJLq6rLpkxnzkx3sH3-okXQavpW2exwaR21U8V1T6xgaIfXpIZxvFV7x-XjoGonua1ocwcezhwR0YabEeMlkvyZhXqLo4bgY7yRwWOZnHtrpoeYAwYkCpxp3goZyZwkBZyjIkedFvuDmzolzNO8o1sXxnKAuduckEu5yseQaodQY0ZoC0ap3V3RO5MNxMb2HxOr19TdwTIxoUfftX1AtYlCfxrBxlPUYSWEe0dVx8eQsVtQtwfQvKMJN-Lkax14uIfgapOieOPArEqgoh3lOSbGBLzLwrxgMHmnymX73YcKc4eKb9JVroM0VaYFrcd-13hqdYHHwVpPiGMCddLjNn1Ubad7qKaUabFKa0Fmf6ehMSbRGGdsAYEoHmuCIt1iYj35qnNsa1vsZrL8xk0OctzxlcZie93ZBlKqaRmGeP3SfGbVOHiwUySWp-N6C-zmbsb7occgTfx9D+ZODuZ4ObNeb8OEL9qgLmoCYzjgI2VMhvGUoKfmY6cWYyQWIxdIrB0Nphc0boZIMEP8L9otoLMyaYhsLfw1InK4MBbOeBYuffkQasGZbWeheqdJZEYELIPhdEOgAkPorGbZQmZKDi2XgscUJEsnMmN+uiMUc0LT1vrifwMEb31hYpeFbMIlcKwHsZeDkQLDsVYAovP+q4Zds5baIZOJb5c8bJcFZMICORc+pUTnXNeOaVdfouOM1X1dsSKhabKda8fID6KyJyPeIKLNjAZUU6XGLCcIfadVevIWPKf6tCsGbQf5ZSajcNb2LpdyZYdRqzZsa9PwsDdGxvM6Arfdr-vcaSfzd6K2PeclbVKn0eOOLjstbTcidG3BhBElKWIZKtOgpedbdRM5O1y+J2fjeRaZFbrbGGm1IRL6ZOararL0X7o5Z6vEs3f4ctI3eeaGenaVPRMxOxNxORZNyvzlfenybUtZetc6ZjqBvIsJYawnbPbzedZEcva5P138dnpI1cz5JidHZTfkYHZraaK-ug81awwSeoZbYA5SaA6LaVrthke7zcvWZg6xaBbfdxfYKEqfbuMocI+bc2enfDIdKdLvdHOXmMDtr7fCd4tI7VdjrHYJu1ZJYw7GHDMjOdO0AONcnUQ49Td7u46k2Dao4dYE-DbJcRqXemeDmmbtRftObQLk4Cs-ftp5bDanaE-IDfOjZ3J7L7IHND2HORfxA05QDUSXuHWgcrd8vWr3aXkM7l3c8bZQdzY8YjYs+3N3P3ORYI88UvnragZ7qBYWY-TrYvzi7UbQ7o7M9C72fKIUIJgbb9d04DYwKibT1j2Q+XN-b0uGdlvlqrwg4Xp7YJmk9g+xfTZT2HZuO3vHcqaq+ndkroqkMYpnppZctoWrkEBHZEuBJ0+3a85BaYicZuKm6Peo9NKBKb167M9kqDqwUInY+famL+urI3ttd48U-442eLGGbGomvMtiumvitsrqogCcoydG4yX2E2Vc5KFPO5a3c865vZeehUWTd6D++PY9qC-Q4jZu+iqmroCspssSrA49VKJUVDtvO2sLuI9ZcS4zdXZaKx9DZXKs2u-KvGrh-u4R7gFmue9e4+eTQYSwR9XvVaJ2v+85pFPm8c0zaJ7S9o6u+ndh8mqp8thp8zrvfvo+wQLZ+x5fbfvg6pOS5+75+zch5C0E4jZJuhrNtuqloepoCeo7aNY2yZBVqgSCoO+VYNN3e57FV8746JeU9M619Fp19hvNu1zU5R740Eo9DVrRqI-l6K-8tXw69Mjxu-aw0dZd7Je19No971+12ptpvpp4GG9eqlZGI8p9fi9x5xZ44d75uJ5j-PbM-j-FsT-hplq8DluN+LdoVejf2j205Zb0+O5tf3aL-K4TvS8F-L7d4T4pqT+KMl0Cs9Dzqt-9e9Nt6B9MW76j9Bud7L4jenv9rYEDqXbfwm-Nbl8O5n-YW8-n4DPVoC4GY15U5EbX83KoNLZQFKP29Hr3+t78vUqDaHrLLHrV6bah4y9X4brOoQBm6HrFdtYW1RVAR6tQL-h5057nMTuHqLBIPQ7qV0S+y-f9v-0ZpLsXQ1ceesvSD779q2xXUbEgM-ZdcLuffFGBgLgDAMT6tAc+pfUkDOkc+y8B5jE1lJHt+2rXQdk0QOJLUW0foFbkp0u6UCyW09GgaAy35fJGWsXAQXnwV5ECEOq7UHlqlQHCDjKUwCQOQD3LZB8AUhRnIASRY+9cOAmAjp0H1ByCjus-eAT5xP6aIS+5g58uoIYCaC4AAAKzpp6CEABgyfKAPv6o1zBM3AHk7Tn5kpDOAQ7-iIgcFDUMiCATIOQG2aUB+AJeHEr2SIA05+AyuEvJkG8DUtM+nzP4uUVdwwktkFgg-twMBon8tkjzQQWRSqHqgShz5GIXEK8GeBYqBufgDwA8BMcjBTYTpCrTewP0CWluaxhz0jqnMj+oQyoUMIFjE9v6wwv9iQiaHmcDBYBNgGwAECdC2A3Qkbm9WbDMDg40gvYNMJGEFdZuThCYfbymGPMThq3I4dcIWG7glh4rIbvwDYCDly8yPHYVK2HgCZnk3ObsF6FKE29D+dvcjv8Mea+tbhuUAEREUaGl44h3AAwPgDYBF5J8GPYOMu35LXwShgQ2AWy2sF0sv62ImofE2KEbchq09YsGsLNjiF+Ag4G+o1U5RsCIRQI1-tjQHp5V+SOBQEdKTJEPCKAlIqgNSLgC0iXgk+eet3lZpaAWRuIsYXj0wKcjZ8MoiIX-DqG1AGhFI32rU1Lzp0K8LJYogULNxFDqhrIl9hcLBH8k+RvIk0c+UFF1NdRBgVXAYHEIGiyMMjKoGqL2AcDOOsnDvu+1O6ftPRluEkQ1iDEajj0donUR8PICmU4A1lV0e6GNH1DvRMnEjn6LI7+kKOwYk0daOTH8ixgkY+po6PwAZB06GfN7rsO-JkZHOITK0W30sEgiQhlwrMWGJDEoc+RtorUeQHtHRicSoHL4V20xEL1Y8HousTALGH6d3+PVVsbMI7GaicS2ooseQE4C2Bkgk+IcRhVrE5j6xZQxXqQxbFjiz+MTOcRGK7E9i9RBgWgIAW2F5DGen5KPAc0PGnCghUdUEZmKTHqi2xy5GcZ2IXEdxByrw4AT0NMbzoecN+O-KaMB4EilmYLCXBBP56-8CxXY11mTW0F3YpCaIqfNgI7pDCeckErnk2LuE9V6821L8b3wF7LjkJxhMmm4I8G5CKx3ww0QCVKyj0ThnAhLgX2vLh8IBOBevKoIoGCj+iJATgBwAQr8BqcYgSMiAUMEDjGeqVNsEyBb5ejtx44zGpOONJf0nxUIn8fOIoBCSRJEAMSXAG7IkBPht4htC9AfH8kRKOIncYQND61sv6NksiZ7h0mni-xbw0PB8KPrMByxDPBtBRlXa5NFCOBM3vhNfGET3x4LUKeDyhFm9tqDBX8RQCCBB42AgBCAOJIDoIAGq2-CulP0K67iFBFQrMUZyPG8skogolKTo3Sl0jbI64m2rgIJj5SzhBE6Cc6C3qO8tWwgyqXAFSk1Sb+d7TCl8jVBzJoBow2BuUP3FIDRpVdIQQJK7FVTVcaUjgMAyAEt1fhudYeigNlETS9xm9D-hAO2kqiJyk7bmD1NSmSSM6vZTKRv2ymDSaCO-E6eFPGFviFOPfARt1IWm9SdGl06SbVLSjijTcb2X1M1xx7yCHJLhEgSfzIFO9Ppf4xaRJKknXSBpwE5zvOm8SP8oBz-afvZLf4aSF6eUp-vxIonnSfpSMy2IAKAmySApdCblBbkgHUhsZBU3GeyIQEHTGZXdWaeQJJlfSHsOJCQAwHLwZTMgWU7LkaMJmYtg+hUiGcVIlmL9yJiEyifDO+mKo4AAsoWf9KtCT5sJwcRqQyGakvj8RnfTvB1PO6wz5pysvmWrMFk8BGc6dCXqjMtx39kAD-MOmNOfF4j5RU48um7K5nmyeZls4TtbI1mUz1peVcARzKJk7SIme0geogJBAMzmwfsrqRbOSkqyU+1AkWbdNv4mCSJT06OVx3TGF9bBMMlOQHLTkblcitNTWfMG1m7cmReAyWQQLZHmjmwps96Tmwv4VTeZcFKudQJRnUzusw0yflHLsktzXp7M-+O7KhGl8jYpM8zn3NWlUzzJYUE1tSCTbIDOZz0r2cQPjlbSt5CEruWdK7GUiYacAY6nABvEMSu27dDEVuLzEFzfRVg42cfwPEqSypykvMQMG3DwAvAhQBIDTXwAqA7AGufAAgGQDkBlxnAJ0tTmMriFeAnAOALsy7IyUaegAu7IhVDwgB7gg5JnDTmAVLBBA2ChIKKCG7ALvA5eBAIIFWw65bQ9wWYDAG8DAKAASgAHEAAQgAEFJSkpYhW8GzxQJuRRUPdNkLNjAKRAnSPhY0EYVQ18AvAHkMAoAAkAAFTQUZA4AAABUwUQBkAKQGRSQAACqcinkM2EoBMheADgGkFBnNh3oFgYABwJkCZBQA4ANeOaNoCgBgBzFmQXgAsGQBQBLAIoz0FACzhgAJ+WcUwJkA8gOBKAYAbQGAF4DaBIlCwZxQ4HbCCBolhMUJdkIcBgAwA14OAN+WSX3goATISgPsF4A15BAlgRRSAAGB1KsAQAA")); })() /***/ }), /***/ "./res_built/atlas/atlas0_lq.png": /*!***************************************!*\ !*** ./res_built/atlas/atlas0_lq.png ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/atlas0_mq.atlas": /*!*****************************************!*\ !*** ./res_built/atlas/atlas0_mq.atlas ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports) { atlas0_mq.png size: 2048,1024 format: RGBA8888 filter: Nearest,Nearest repeat: none sprites/belt/built/forward_1 rotate: false xy: 823, 127 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_10 rotate: false xy: 1672, 531 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_11 rotate: false xy: 1752, 531 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_12 rotate: false xy: 898, 287 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_13 rotate: false xy: 903, 189 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_2 rotate: false xy: 875, 29 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_3 rotate: false xy: 893, 533 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_4 rotate: false xy: 973, 535 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_5 rotate: false xy: 1053, 535 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_6 rotate: false xy: 1133, 535 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_7 rotate: false xy: 1213, 535 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_8 rotate: false xy: 1293, 535 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_9 rotate: false xy: 1592, 530 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/left_1 rotate: false xy: 625, 127 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_10 rotate: false xy: 964, 444 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_11 rotate: false xy: 1053, 446 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_12 rotate: false xy: 1142, 446 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_13 rotate: false xy: 1231, 446 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_2 rotate: false xy: 714, 125 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_3 rotate: false xy: 624, 38 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_4 rotate: false xy: 713, 36 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_5 rotate: false xy: 1414, 539 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_6 rotate: false xy: 1503, 539 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_7 rotate: false xy: 875, 444 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_8 rotate: false xy: 1852, 519 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_9 rotate: false xy: 1941, 468 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/right_1 rotate: false xy: 1320, 446 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_10 rotate: false xy: 1044, 70 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_11 rotate: false xy: 1144, 179 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_12 rotate: false xy: 1233, 179 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_13 rotate: false xy: 1322, 179 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_2 rotate: false xy: 955, 71 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_3 rotate: false xy: 1117, 357 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_4 rotate: false xy: 1206, 357 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_5 rotate: false xy: 1295, 357 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_6 rotate: false xy: 1121, 268 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_7 rotate: false xy: 1210, 268 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_8 rotate: false xy: 1299, 268 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_9 rotate: false xy: 1055, 159 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/blueprints/analyzer rotate: false xy: 1446, 824 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/balancer rotate: false xy: 922, 726 size: 172, 96 orig: 192, 96 offset: 11, 0 index: -1 sprites/blueprints/balancer-merger rotate: false xy: 761, 631 size: 93, 93 orig: 96, 96 offset: 3, 2 index: -1 sprites/blueprints/balancer-merger-inverse rotate: false xy: 1952, 729 size: 95, 93 orig: 96, 96 offset: 0, 2 index: -1 sprites/blueprints/balancer-splitter rotate: false xy: 856, 631 size: 93, 93 orig: 96, 96 offset: 3, 2 index: -1 sprites/blueprints/balancer-splitter-inverse rotate: false xy: 1952, 634 size: 95, 93 orig: 96, 96 offset: 0, 2 index: -1 sprites/blueprints/belt_left rotate: false xy: 723, 273 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/belt_right rotate: false xy: 446, 89 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/blueprints/belt_top rotate: false xy: 723, 362 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/blueprints/comparator rotate: false xy: 369, 635 size: 96, 89 orig: 96, 96 offset: 0, 7 index: -1 sprites/blueprints/constant_signal rotate: false xy: 802, 27 size: 71, 87 orig: 96, 96 offset: 13, 9 index: -1 sprites/blueprints/cutter rotate: false xy: 1272, 824 size: 172, 96 orig: 192, 96 offset: 11, 0 index: -1 sprites/blueprints/cutter-quad rotate: false xy: 1, 455 size: 351, 96 orig: 384, 96 offset: 16, 0 index: -1 sprites/blueprints/display rotate: false xy: 540, 270 size: 86, 91 orig: 96, 96 offset: 5, 0 index: -1 sprites/blueprints/filter rotate: false xy: 563, 726 size: 180, 96 orig: 192, 96 offset: 10, 0 index: -1 sprites/blueprints/item_producer rotate: false xy: 1803, 629 size: 88, 95 orig: 96, 96 offset: 5, 1 index: -1 sprites/blueprints/lever rotate: false xy: 739, 464 size: 68, 79 orig: 96, 96 offset: 14, 12 index: -1 sprites/blueprints/logic_gate rotate: false xy: 362, 551 size: 96, 82 orig: 96, 96 offset: 0, 14 index: -1 sprites/blueprints/logic_gate-not rotate: false xy: 361, 93 size: 83, 96 orig: 96, 96 offset: 7, 0 index: -1 sprites/blueprints/logic_gate-or rotate: false xy: 460, 550 size: 96, 83 orig: 96, 96 offset: 0, 13 index: -1 sprites/blueprints/logic_gate-xor rotate: false xy: 354, 463 size: 96, 86 orig: 96, 96 offset: 0, 10 index: -1 sprites/blueprints/miner rotate: false xy: 1429, 628 size: 92, 96 orig: 96, 96 offset: 3, 0 index: -1 sprites/blueprints/miner-chainable rotate: false xy: 1523, 628 size: 92, 96 orig: 96, 96 offset: 3, 0 index: -1 sprites/blueprints/mixer rotate: false xy: 1118, 922 size: 175, 96 orig: 192, 96 offset: 8, 0 index: -1 sprites/blueprints/painter rotate: false xy: 730, 922 size: 192, 96 orig: 192, 96 offset: 0, 0 index: -1 sprites/blueprints/painter-double rotate: false xy: 1, 266 size: 192, 187 orig: 192, 192 offset: 0, 5 index: -1 sprites/blueprints/painter-mirrored rotate: false xy: 721, 824 size: 192, 96 orig: 192, 96 offset: 0, 0 index: -1 sprites/blueprints/painter-quad rotate: false xy: 1, 553 size: 359, 96 orig: 384, 96 offset: 8, 0 index: -1 sprites/blueprints/reader rotate: false xy: 1838, 824 size: 95, 96 orig: 96, 96 offset: 1, 0 index: -1 sprites/blueprints/rotater rotate: false xy: 1742, 922 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/rotater-ccw rotate: false xy: 1367, 726 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/rotater-rotate180 rotate: false xy: 1642, 824 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/stacker rotate: false xy: 745, 726 size: 175, 96 orig: 192, 96 offset: 8, 0 index: -1 sprites/blueprints/storage rotate: false xy: 195, 261 size: 165, 192 orig: 192, 192 offset: 14, 0 index: -1 sprites/blueprints/transistor rotate: false xy: 978, 346 size: 68, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/transistor-mirrored rotate: false xy: 1048, 346 size: 67, 96 orig: 96, 96 offset: 29, 0 index: -1 sprites/blueprints/trash rotate: false xy: 1465, 726 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/underground_belt_entry rotate: false xy: 97, 1 size: 93, 75 orig: 96, 96 offset: 2, 0 index: -1 sprites/blueprints/underground_belt_entry-tier2 rotate: false xy: 550, 461 size: 93, 84 orig: 96, 96 offset: 2, 0 index: -1 sprites/blueprints/underground_belt_exit rotate: false xy: 1952, 557 size: 93, 75 orig: 96, 96 offset: 2, 21 index: -1 sprites/blueprints/underground_belt_exit-tier2 rotate: false xy: 1, 1 size: 94, 75 orig: 96, 96 offset: 2, 21 index: -1 sprites/blueprints/virtual_processor rotate: false xy: 565, 630 size: 96, 94 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/virtual_processor-painter rotate: false xy: 362, 365 size: 87, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/blueprints/virtual_processor-rotater rotate: false xy: 1373, 535 size: 39, 96 orig: 96, 96 offset: 29, 0 index: -1 sprites/blueprints/virtual_processor-stacker rotate: false xy: 451, 364 size: 87, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/blueprints/virtual_processor-unstacker rotate: false xy: 1938, 922 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/blueprints/wire_tunnel rotate: false xy: 1334, 633 size: 93, 91 orig: 96, 96 offset: 2, 3 index: -1 sprites/buildings/analyzer rotate: false xy: 1644, 922 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/buildings/balancer rotate: false xy: 1471, 922 size: 171, 96 orig: 192, 96 offset: 11, 0 index: -1 sprites/buildings/balancer-merger rotate: false xy: 1144, 633 size: 93, 91 orig: 96, 96 offset: 3, 3 index: -1 sprites/buildings/balancer-merger-inverse rotate: false xy: 1048, 633 size: 94, 91 orig: 96, 96 offset: 0, 3 index: -1 sprites/buildings/balancer-splitter rotate: false xy: 1239, 633 size: 93, 91 orig: 96, 96 offset: 3, 3 index: -1 sprites/buildings/balancer-splitter-inverse rotate: false xy: 951, 633 size: 95, 91 orig: 96, 96 offset: 0, 3 index: -1 sprites/buildings/belt_left rotate: false xy: 456, 178 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/belt/built/left_0 rotate: false xy: 456, 178 size: 87, 87 orig: 96, 96 offset: 0, 0 index: -1 sprites/buildings/belt_right rotate: false xy: 535, 83 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/right_0 rotate: false xy: 535, 83 size: 87, 87 orig: 96, 96 offset: 9, 0 index: -1 sprites/buildings/belt_top rotate: false xy: 545, 172 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/belt/built/forward_0 rotate: false xy: 545, 172 size: 78, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/buildings/comparator rotate: false xy: 467, 635 size: 96, 89 orig: 96, 96 offset: 0, 7 index: -1 sprites/buildings/constant_signal rotate: false xy: 983, 160 size: 70, 86 orig: 96, 96 offset: 13, 10 index: -1 sprites/buildings/cutter rotate: false xy: 1096, 726 size: 171, 96 orig: 192, 96 offset: 11, 0 index: -1 sprites/buildings/cutter-quad rotate: false xy: 369, 824 size: 350, 96 orig: 384, 96 offset: 16, 0 index: -1 sprites/buildings/display rotate: false xy: 812, 274 size: 84, 90 orig: 96, 96 offset: 6, 0 index: -1 sprites/buildings/filter rotate: false xy: 915, 824 size: 179, 96 orig: 192, 96 offset: 11, 0 index: -1 sprites/buildings/hub rotate: false xy: 1, 651 size: 366, 367 orig: 384, 384 offset: 9, 7 index: -1 sprites/buildings/item_producer rotate: false xy: 451, 267 size: 87, 95 orig: 96, 96 offset: 5, 1 index: -1 sprites/buildings/lever rotate: false xy: 1384, 367 size: 66, 77 orig: 96, 96 offset: 15, 13 index: -1 sprites/buildings/logic_gate rotate: false xy: 558, 547 size: 96, 81 orig: 96, 96 offset: 0, 15 index: -1 sprites/buildings/logic_gate-not rotate: false xy: 809, 533 size: 82, 96 orig: 96, 96 offset: 8, 0 index: -1 sprites/buildings/logic_gate-or rotate: false xy: 656, 545 size: 96, 83 orig: 96, 96 offset: 0, 13 index: -1 sprites/buildings/logic_gate-xor rotate: false xy: 452, 462 size: 96, 86 orig: 96, 96 offset: 0, 10 index: -1 sprites/buildings/miner rotate: false xy: 1617, 629 size: 91, 95 orig: 96, 96 offset: 3, 1 index: -1 sprites/buildings/miner-chainable rotate: false xy: 1710, 629 size: 91, 95 orig: 96, 96 offset: 3, 1 index: -1 sprites/buildings/mixer rotate: false xy: 1096, 824 size: 174, 96 orig: 192, 96 offset: 9, 0 index: -1 sprites/buildings/painter rotate: false xy: 369, 726 size: 192, 96 orig: 192, 96 offset: 0, 0 index: -1 sprites/buildings/painter-double rotate: false xy: 1, 78 size: 192, 186 orig: 192, 192 offset: 0, 6 index: -1 sprites/buildings/painter-mirrored rotate: false xy: 924, 922 size: 192, 96 orig: 192, 96 offset: 0, 0 index: -1 sprites/buildings/painter-quad rotate: false xy: 369, 922 size: 359, 96 orig: 384, 96 offset: 8, 0 index: -1 sprites/buildings/reader rotate: false xy: 1661, 726 size: 95, 96 orig: 96, 96 offset: 1, 0 index: -1 sprites/buildings/rotater rotate: false xy: 1935, 824 size: 95, 96 orig: 96, 96 offset: 1, 0 index: -1 sprites/buildings/rotater-ccw rotate: false xy: 1758, 726 size: 95, 96 orig: 96, 96 offset: 1, 0 index: -1 sprites/buildings/rotater-rotate180 rotate: false xy: 1855, 726 size: 95, 96 orig: 96, 96 offset: 1, 0 index: -1 sprites/buildings/stacker rotate: false xy: 1295, 922 size: 174, 96 orig: 192, 96 offset: 9, 0 index: -1 sprites/buildings/storage rotate: false xy: 195, 68 size: 164, 191 orig: 192, 192 offset: 14, 0 index: -1 sprites/buildings/transistor rotate: false xy: 983, 248 size: 68, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/buildings/transistor-mirrored rotate: false xy: 1053, 248 size: 66, 96 orig: 96, 96 offset: 30, 0 index: -1 sprites/buildings/trash rotate: false xy: 1740, 824 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/buildings/underground_belt_entry rotate: false xy: 629, 292 size: 92, 74 orig: 96, 96 offset: 3, 0 index: -1 sprites/buildings/underground_belt_entry-tier2 rotate: false xy: 645, 460 size: 92, 83 orig: 96, 96 offset: 3, 0 index: -1 sprites/buildings/underground_belt_exit rotate: false xy: 628, 216 size: 92, 74 orig: 96, 96 offset: 3, 22 index: -1 sprites/buildings/underground_belt_exit-tier2 rotate: false xy: 362, 191 size: 92, 74 orig: 96, 96 offset: 3, 22 index: -1 sprites/buildings/virtual_processor rotate: false xy: 663, 630 size: 96, 94 orig: 96, 96 offset: 0, 0 index: -1 sprites/buildings/virtual_processor-painter rotate: false xy: 362, 267 size: 87, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/buildings/virtual_processor-rotater rotate: false xy: 823, 369 size: 38, 96 orig: 96, 96 offset: 30, 0 index: -1 sprites/buildings/virtual_processor-stacker rotate: false xy: 540, 363 size: 87, 96 orig: 96, 96 offset: 9, 0 index: -1 sprites/buildings/virtual_processor-unstacker rotate: false xy: 1563, 726 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/buildings/wire_tunnel rotate: false xy: 629, 368 size: 92, 90 orig: 96, 96 offset: 3, 3 index: -1 sprites/colors/blue rotate: false xy: 1144, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/cyan rotate: false xy: 1182, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/green rotate: false xy: 1220, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/purple rotate: false xy: 1258, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/red rotate: false xy: 1296, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/uncolored rotate: false xy: 1334, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/white rotate: false xy: 1372, 143 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/colors/yellow rotate: false xy: 1133, 107 size: 36, 34 orig: 36, 36 offset: 0, 0 index: -1 sprites/debug/acceptor_slot rotate: false xy: 446, 181 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sprites/debug/ejector_slot rotate: false xy: 968, 434 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sprites/misc/hub_direction_indicator rotate: false xy: 1381, 109 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 sprites/misc/processor_disabled rotate: false xy: 754, 573 size: 53, 55 orig: 64, 64 offset: 6, 3 index: -1 sprites/misc/processor_disconnected rotate: false xy: 922, 385 size: 44, 57 orig: 64, 64 offset: 11, 2 index: -1 sprites/misc/reader_overlay rotate: false xy: 820, 225 size: 70, 47 orig: 96, 96 offset: 13, 24 index: -1 sprites/misc/slot_bad_arrow rotate: false xy: 946, 163 size: 24, 24 orig: 26, 26 offset: 1, 1 index: -1 sprites/misc/slot_good_arrow rotate: false xy: 754, 545 size: 24, 26 orig: 26, 26 offset: 1, 0 index: -1 sprites/misc/storage_overlay rotate: false xy: 955, 39 size: 60, 30 orig: 60, 30 offset: 0, 0 index: -1 sprites/misc/waypoint rotate: false xy: 1138, 38 size: 26, 32 orig: 32, 32 offset: 3, 0 index: -1 sprites/wires/boolean_false rotate: false xy: 1017, 41 size: 21, 28 orig: 32, 32 offset: 6, 1 index: -1 sprites/wires/boolean_true rotate: false xy: 2032, 892 size: 15, 28 orig: 32, 32 offset: 7, 1 index: -1 sprites/wires/display/blue rotate: false xy: 1133, 72 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/display/cyan rotate: false xy: 1171, 108 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/display/green rotate: false xy: 1206, 108 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/display/purple rotate: false xy: 1241, 108 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/display/red rotate: false xy: 1276, 108 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/display/white rotate: false xy: 1311, 108 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/display/yellow rotate: false xy: 1346, 108 size: 33, 33 orig: 33, 33 offset: 0, 0 index: -1 sprites/wires/lever_on rotate: false xy: 1388, 288 size: 69, 77 orig: 96, 96 offset: 13, 13 index: -1 sprites/wires/logical_acceptor rotate: false xy: 1409, 446 size: 42, 71 orig: 96, 96 offset: 28, 25 index: -1 sprites/wires/logical_ejector rotate: false xy: 903, 142 size: 41, 45 orig: 96, 96 offset: 29, 51 index: -1 sprites/wires/network_conflict rotate: false xy: 1040, 38 size: 32, 30 orig: 32, 32 offset: 0, 1 index: -1 sprites/wires/network_empty rotate: false xy: 1108, 36 size: 28, 32 orig: 32, 32 offset: 3, 0 index: -1 sprites/wires/overlay_tile rotate: false xy: 809, 467 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 sprites/wires/sets/conflict_cross rotate: false xy: 1269, 726 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/conflict_forward rotate: false xy: 803, 116 size: 18, 96 orig: 96, 96 offset: 39, 0 index: -1 sprites/wires/sets/conflict_split rotate: false xy: 192, 9 size: 96, 57 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/conflict_turn rotate: false xy: 1893, 667 size: 57, 57 orig: 96, 96 offset: 39, 0 index: -1 sprites/wires/sets/first_cross rotate: false xy: 1544, 824 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/first_forward rotate: false xy: 803, 366 size: 18, 96 orig: 96, 96 offset: 39, 0 index: -1 sprites/wires/sets/first_split rotate: false xy: 290, 9 size: 96, 57 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/first_turn rotate: false xy: 1893, 608 size: 57, 57 orig: 96, 96 offset: 39, 0 index: -1 sprites/wires/sets/second_cross rotate: false xy: 1840, 922 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/second_forward rotate: false xy: 1832, 531 size: 18, 96 orig: 96, 96 offset: 39, 0 index: -1 sprites/wires/sets/second_split rotate: false xy: 722, 214 size: 96, 57 orig: 96, 96 offset: 0, 0 index: -1 sprites/wires/sets/second_turn rotate: false xy: 863, 385 size: 57, 57 orig: 96, 96 offset: 39, 0 index: -1 sprites/wires/wires_preview rotate: false xy: 1074, 36 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 /***/ }), /***/ "./res_built/atlas/atlas0_mq.json": /*!****************************************!*\ !*** ./res_built/atlas/atlas0_mq.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4IgZgTghgtgpgZxALgATALAChsgQBwgEsAXRAegCM4AbEqgVyLvLAHsIB3KCAEwH0ADADp8AOwDmKbJiwBIcNHgp0IAB4oAnABYAzABoQATxQAOAIwA2Q5xQB2U4YAWWywF992BRDYkoZXhUwKBoEOE95EBJiGHhAtGiGcK88QlI4AGU2BggAY0yiAC84FVANZE1DE2RBG3tHEBcK9wiFBGy8guLSkFtm51c3bA9cAmIyBCpaekomFnYuHgFzUUlpLFkFSFgStDKUPUrjM0EDXvqB5pHInz8AoJCw1qiYuJVE5Mix9Kyc-IyirtVOUjtVaudkA5LpoWil2n8ukDQH0YdD3MMIqlxhRqCxZsx6AtuHx+AAmVZSZAyFLbZR7dQocx2OxVRmWbQsiFQxqDZ63fxweKoYKhT4KaJEWKC94QJLPb5kX6dAHdekg1k1OqQhpNGHXNodf6Anoo6w8q4Y0ZpCZTPFzQkcYkCXQU9abRQ7HrlUkAVlBbI5Wu5uthN18AqFIqeKQlUqFH3l1syhsRXq0GvBfWDvLhKZVSIhqPNestWCx6UmuJm9tYjqW-G0rqpGxpSgL5V02nMGqsPu0QZ1ObDd2laCjYpekreCVlE4VyYR+bTFQzA7R+rweeN9NN69L5ZtVcYBNrixJPqb1MitPbZh9PcsPrNWcHVz54fuY8eE9j09QCbhJMlSNVVgXTY5NS5V89XlLdQORVw9ywa4DxxaZj3mOsSUsS8W2vNtlzOaorEfNdi1DbwP1HYVv2eX9qIAr4gLg28VwgzMLnIjd4WVbdVF3Lj93nSt0PxTCzwEOxcPdG9lysTliLsQMoPXd8R0jWiY1eBjZ0TbFgNTNVwLBMiQ24liTUQwTkMxYTbWrE8iXrUxpNbT0jOQUx7wgpkn1ModKPUh5RTo7T410wD9Isjz-Ugl9VNzRc+IQ-prJQuyjzEh0JP4TRXPw9ywOQIjGTsUiVK4tSI2C6NIno8K5Uin5oqK2KOO1BKvhalKizMoSkxEu1HKw5YRHESkry2AiPJK5BzCfbz4sqlJ+U-GiQq0qcdMapioqS+CGTYkyKrM2D9oLAS+psq1sUGhzxKdfhzBWca3TcukitJSwGmIvtOSW06VqojSNrqsKZR2tpmPO5c2v8t9Et4g7LsGfrbvsjDsse8xyVe5sZOmordB9cFfr7eGYKBoKv1B8VwZnSHUIMpcYtXE6As3GGdysq70oGjGstPbGXTxyaPQ+-ZkD0UkH10M4AY51bqPHUKtoaudoaR1i4fZhGuq5-iedR66ywy0SaxoOAwBIIR8qmwrJYcBTGXMLytVMTkmg9jclZB2q6bViGNb2rXl1J8C+g9y5vbO0PudS3nbP5zKLatm2XrWfH3tY77vOIr7uwhKPzRjqnqpp-3JzjIO9Oag3JfDtjI89sw7HM+vCzNROborAXU+tsk7fF1jTEsZ25tJTQZaLlvPLbqq1pVzbq4Z4O67jorG6OZvo-nxGQIuo2LRN1C7sx8hLYHkXM7F2SPOZQviN0Mf3dn0vh3L9bK-qmumsVbrDpb1frvduG8epd2NnzdGKcTyXxto2UWeF7YS0OqPaeT9TDy1biAheytNJg0DqvWu-8O7lCATPHB+9DKGwTpApO0DzawLTvwC8iCCYO0OuYTQP1GSkiUsAkue8P6L3wQHFe-4Iq7XXgfMOGpt7YMEaAmR8dep0J7oeRhLA4H8Bwmw7OclBCNxxpggRXshGBU-kvAh4jGJQxDsozecjTGtyUdQ8BSEoG9xgVo5hUk9EFRQR2Hsk9p470Ubgv2P56YSMZvOZmyVAFOIoeEqhLMaGqOPp4jRQ0fEDxcv45BrFSSmFijjfhySzE+2BjVKJhCYlrxIWAxJEF5Fz0ofrJpKNMn0K8Zo+g2i8oFOHoRUwRi+H-QUZUiJNTVY2MkXY6RbjmnVFacXKZqSEldJLCfM2OT+nMPMGNG+SDhkeR9CU4JmgsFtJScIvBtMq5-lsUzABZCklhPWR0hx7i0o9OyfdfZA9npDzvkVD2PCJ6CELh8lx0yK61LmbEzW3zlkR0mbCjZyMj7bKyWhPZF8Dm42OewwJ9gyrBPJRUjFdzImzKefMl5pCUDkJhXPVxaSfnd1NsnPpBKgXXwmic0FktvpGOJqE9FbK4VfwRfSpF9illvJac4qVmLD60O6eovFALyDEAkE4G2RzBUktYhyR+jJiYTJuZ8ixIiHk-yIX-BcTT1TKqpaqr5Sytnoh2Ty-FeqDVPRBYTSWT50EWtMP2d179bX3O-tE55cTXnGTRda6lBoO7eqGL6hh-qiD6ptkS41+iZo9l0CY6N5iQC+xmcvOVDTnUotdSslVMbOadOxT63FZ9BYBptgKt6ASimmHDXNZ+i1JVtprfCul20G3xIOs21Naz03tpRVmtGvS80FobMGjhHY7CzXMM-BorKp3VJnXWudxDG2KpTU3SdVaeLrs7dm7tfcTx9pYXu0lUt2Q9m0NoU9j6qnUxlbO9WN6F3a3eSB2OL6NU4r+dq8+X7dHEpLUVH02GAN2AnWmj1sbaVXsg066DsNYMEbbc+r1r7N3-NQ-mwNfiMNDuXOyM0v1OytqrdO8DJHf5SMaU2+9qy35PoARunNW6dVfvyaxwpck3Y+W0H5StoHLGiMedesjyajrLvE+yzZdHpMMd7Uxm2gyFOnNalG4i2hypnt4xe-j1j61Qb07FMT7SM0dsQ125DPaaxfsOT+nOPoj2AeuSuwj1aXNWLEe53TTL9MPqoxJzNJn33ePoCFjOxa2P30AwB85PGNN2vjXUxNyK72pe87c3zCGMlIa1UFz9FmnpFsHYpjyXDzVjsc3BsuFXZU6aE7ejlh0vNlfg7R-zb7AsfpYCFgdWdCu2bLeUpz5W42jdI+N8jrM3Xbdm5NqT2WaBJDSGIEgd1+BwLC4RXDUaTvDd2xBwTCzhO1ZZUNz1Z2suLcoJduA13bv2X4H2x7Hk+GccZKp58f2iO1rc2Nr7E2ElLrSzF6jknAetaoCDsHd2SBsHwNDz62hSlKStdmPWyPL2o-2+jw7rU2YK3p2uubzWAsE+B1d4gN3Ji5DYGIBAfgbv8AQPmsQIQKeSx0LFXQRYsyFy9j6HbxGmefcZS6i17P7Bq7vEZrF836M4iJ4L8HuQGAkDIBAAAtAARwYFAXg8vDq6EPT2U4Wpn4QM53xhL2nme65E3Nfr7V-edUa3N8tUauWn0JwLogQvyA27t3ACAHvyhKTzigP0L3SrT0BjSlHiW0dh9q89A3c07Al45jRgHc0p4eKB5b1P4PeBEAIDQKARgc8oGfuPcwqnVkB80OYTX5eQ866TSl-PyB8Oj2hFP07xmzemYtyntPYACRZ8H0vywSvfcQlduCUvDPXMV9D-PvXc1G7tXPzHrnzeuEN81dy6BHe0+WwAG4H5DLCpTYOYaiHpF6QgJ71DT6M435z41aTblA14+TQr2BQHagm7qo84LZ84-7g40BsASBEC5D8ASACgO5iC+CH59iL7zSWCI6eRnCX5xZgbB4Or1IeYpbjztQVrMFN4b7YHm6Vh4GTAEFEEkFkFkAO4cCH6zQewQEZIjowHX6z6OoHZ6aP5aiKGkiYGWSb4XY774GEHEGkHkHRBQBi496k7Z5AEhqHSAaxR2Cn59DfQv5B5absHVYKqIHMq16uHLT-YCET685f5eIiEXzGESHkFqAyG2H7pD4ahjwKHBHKFsHRLB537h6aGdwv78Gm6CFb7CGGGiGRGmFkDUGkj9aaDVFaEB4lKpEeEJoMqZE-a16KGaC6EqIpFCHJ6g5W6TAwCp5Z4O65BOBQCp5QDA5wCH5TxeZWBaEf6Uxl6wGqEcHJb36zTtSt4BGx7N4FEGF9Gd4DFDE2HWbAEdjcI9hMhWrbHMHuH2pNHyqLI+HFRtGLEUSv5BFt64HFHkCDFqCAFnF2FBIQQcgQG+RuHxaNFVbNEIGY5mC14Qk7GfGm7v7fGhGHjhH4DjE3bDG8DZBTGH54ZK5ahonmjv4NEPF1IZFwmLq+HsSkm3GMhTydE0JklNAUk9H86HFp7Ymd7DGDEQA+AQCCiyHe4QS6DOHMnvGUmVbiI0neHwmQTHR9DsmN544t4ylclYk4n27O6u7u5xG-qzTXJe7oFLFX5pEwlPHfYvGbF+7lJ8Eanx7olJ7cnE7kB8m4mnEFY9ZFR4Ymk6CMkynSpWnylaYtEvHZGqlMmc55Hqpqmf5unhFKyO65C5CcCH6HKzRJG1GQmsHQnhkPKRlKnRmvrr75HdGFG9EempkO5gA0CH6kin4rKaBbHeR3FQlUmIrzoaFtEdnqmZb6Ht6-GplNktkoC5k5HIn3Fyl-gKnPGlltEpEVlYFVkHEem96kB6ki4wDYm5AkAO6p4AEQBhDjmjqHJtlaEDkVC6Cyl7bwGKl0nKmMjXnQh3mrl6H7Ejk8ng5bmZ5plsB7lQAHlZlQpXEr6FhMFaAflvZa5wFqEs56ZHpaHQW3msmcpqIYnb6-mTD-n26yEag+hbalRG6B5dlzmV4lnPnIEqmkW5EamJktbYVFG4XkDi4gUADWgJvpNmksrso6YJpJeG+Zmm3ZSW6hKWEKT+IlyJ8ZehTFIRyZvx5hCATgDu4uHAUAEg0xRprEPoxSiRUpc0L85JLJoZhZElSFKWo+iJplHJ5laqClsZnJ1Z7p-R5AqlTgshVOYBxl2BFl4l726xWRy5DFQ535PxbFDAYgvAWeEgPgMVAgVY-AcAN2EARgDuJARAWeXWa2fpksVOEKl5Eqt50c2g95H2iFVeLxF5pVVy5VGF05ieGU4RSV8ViVsV-AKVaV0QA+ely42g4FPkgglxUFlweGlVAm1V1FRSGolRqFE1Gun5XRrprVvx7VEACV2QXVPVagpAWVOVEAeVt8wJCRKBrsWh6Bk1gVlFt+tJc1DJhY11y1Tlq1vyUVHpm121SV3V0wqV+1JAshw1xEhyqBZV5oN1cFM+nhsJT5j1dFENTQUNgRlZa1yc4Rf+RAEAJAruNA-AhAbA+QCA7QjuFhIQRgxQPp3WfFh0Bl-WdgNRzVisFFD5Kxs1siT1WaK16S65P5HpWNONeNBNPgxNpNDuY5A1vWymv0ykWYRwnZBZQV918NFGXN9gCtg5fmkVLFNZHlgtuNIQItRNiA4talUA+AcAu52JIph+lgC1I1pI1y7RU12uM1D1nNiNLtPNmFSZ61bFBtwthNYtHADuMVHFuQ3F1N+VtNuek8GoJSWxK50NKx7BC5tpS56t82PtzNftGNvxgdRtwdptsRQJ8RFQDtxEUKDBzWFVt1bNaxkl9+jc9VE+ddb1vN6N3+vxnA2NcAIxPgJNh+I6sUJSyRolI2VVKhHNHkZZ2dHdvtzFylbFvdIpGl+ANApAYFchJFGq2GrtCFjd1lzdGoXYeZ5o+9Od52-NHlq9-duNEAYgMxOGI1+GL9TQl9KdKhsNNpGOz5Z9oJ4N79Ber1qNa5XdYRPdfddtTN1QlgxltlM5rNU9Xhi5-9kepJ5pHx8l71LV+dK9fd-AuNYgYgtAIxbA-gqeEgMxldBeQZEITtq+B9qxqDGdz5z881WojDxYa+C9udS9-tHpd9RDMVpDjZUtRMVxmgNxaFk+zDP9vZKWo69VsjvDYDX5fNfOcw3ekgd2D2EjjsxcoNymr2yx39jxijJ9x2SOKJ4DH1utYkOjEgd2UOBj9hdg-Wx6xFM2X9YZVlNVSp026mV9+ODj2jVDJOZOMxegCd8xusFpLBYld1j5aDMGWddOCTODnd9jbp4Tuj6eouHFku0uEgsu4jZdv6iup9Jj9gF+xu9dKDcNqTck9pXIdTnkoDuxXxOTGUeTzj6etuepLubuYps0zZpp9BE9wVbtR9ATNFGDEI0eclzpkaEDh4fTwugzPFNN5xpUEKxF4JHjUz8FLDTTbDrEtF9JqpRzyzQ5ilOBYTzATjkw3eve-eh+qmI+EWqy5pgg8jFjnB9+cOyADBqzxYfzITw5WjTzETrA++0dp15dT4sUQ11yTImt5FStyT7tqtvWCz1zGLmTjFsZAjycGz5ATgDAlAhFI1EzAew+-z1plj4epSUekz5oDLkLLpHLkaDzuTML+T-+2zMduzFQQGRFu94pyNHxs5DdrDf9FzdVQYaFZUTV190LNAzzER4hZR-dlBQNbj5Qegi+bZ0WIZvjllVFHtHk0l7s5r6juDWF-LmrsLYhJhkh-dpdvForU8njz049JcsFZjfjVruLjiWdihQbXTaNPTZLAr-TbrURUh5hlhmlCLQqZ1ILtDkITNLh0EMryD01szM94biN-hTpEVmjjzLrgrpRHrDuMR6bJqy4I6VR9DWynTiTk9Rb8rrODcYVxYnbWTi9SlvT8bJROrHrw92bl5ztdRpgjLPZgLoVEb87aroTzrWrgxpDaZYxExhJhrdDRiXCChZFmgnbsrjTv9fbnubRZ7Q7GpOtm7sL27wriLv6VOdmvCpWhY97i7-jJbksrTKIf7kLT7Y7Nb-T-xb7Gb5dz8-WJMaLjpLNWLcrZzCratiNTIWD67mpazOI5LXpep+JVLlsRJfoPYub0plwfW-7obzTs9iJLlcjkLiZrl2WhHupAp2Nwpoph7xU4p1QqLwZxzMN6REZ1rpbVz1Htzfm9zXJnH-JjuwzhpFTrE5a-WppyHmLSTaH17yFteZp4Vfm3LeD0Cin3p5Hgl7bMnitunU96dGHjHWd9zrHJLo7cbkHkwdZ6ZmZ-H2Zcik+b5SDqHV7zL1e-ZxnTWVbz7+TdZDZNLVdl1hYN5CTl7Pb6HN7SqXtqX2Dj7MXEHWrktanhEggF5hi4N57onqdALIVEXEbuXuH4HnnWr+Fwx1tIFh5x5WeZ5-nZXPuQXz1TDDTGX+nKWLdV1w3fD6r1brXG9257XQF+5BrJXHkQ1njhiztqjdHKtDHkjEEKjU3Dr2TZnXi5LbXTbmGQHEWRlSHZ7BboXo34XLxlzcU9FsnCG8nbl53fgkdMHzbZyyuRFCD2naXhbMzvbnmiJoPeXdz7nfLhXsLXlGl1h2lulq3-pHDEEx+4J7LDlOhI3EPmXemiDWHeP0puHbHLJCn47nl0AaliXZKAbdn3bMzjnWX9JXtydx3I7CPLXsL31nVyV-1vVGVh1uVWZY1xjNxH+mCO3KT5zT2PkztsvUbtjGj+HlY5LgvO1wvdAqV6V-VGPoaVXF1NdH+Sk8vOLe3QH819VFv7dPP-DHn5ntPOvv1e1B12VEv-Hn7EFWxDvVvxbkntvEbgfYHBX-P+T7vu1IvgNMDfrFaKI4fFrytCvTn+3XtKfTvM3sX-Thd+NxdJNod5NNAlN-3V3nCE5kIu9AVqf2L09IfqKb389OfG7iP+TBfxtIdjuxX3rmb9DZMDBjN1X5jTLy7tWOs8tUX3OkfrvXn5AXfRfZtYxltHXtt-H9eG3V5ud9RhPh9kP43A7XsHREfmvGEWrS-otJdju4dv3Ud45s0zIzPKH9nRb7PfZq7M-exc-Z3tPV-JtYvpd3WxAdiYcifym3SD6H8rG1QVutCEd7Rs7Gp3dZrTzvoD02AQ9fjnLFHoQDR+IbE5oB2b5J1v+3TZAQR1QF9116m9Fbv33LrjME6tfAPH2CgHE8j+oJOARfQQHq9HWedeflqzQEP0n6-Hc9rQX-QQhyYnAlgWN3vzaBBKpVCQR-S4HDtnefPPgbCzvpEkYmtLUkva0tKWtduivNbqOify6DuBJ3J1h336bCNiGYjchpQ0kA0N+s30VpA7V1AQt6+enZ7kqS9wahrkrgrQO4Lb5QtZu6gwhjYNoDA1E+AfaEIEL0Fp9rehgzPudWT4xCmuv-G0HFVmASByAIFfIPgGsJS4CCNAnZpmzBpHoxBkcaOEHw-5sDEar4BdpC3qGqDe4mQhgNkLgAAArK2gUIQBFCwKx6HsJSkqElxqhEnMNv2yzpNDGhVQnooMQQC5AKWVLfgN3hFIHkiAoufgKnm7y5B-AXrEoeXWPxyEfQ4NXQB-lOGjDiyTfbLtJ2KhnCCe03IfHcOaE2g5hCw3ob4G6pu5+APAHwH52N6HQPG48eBvhlJDoFQRUgrwTRR7BcMwRSgjUl9EuBfRnhFAV4exSKGkE2AbAAQD8LYB-DaBv6QERKxBFgiHub-IntIPDz4sUAoIxEbDz8wIjzQSI2YT3jeGo8dK-ANgCeT7xG98R2sF+tUBuYuF2mkpC4ZXEIHXCW+8DS4CKMhZSiOWfzZkfMPIDcAjA+ANgJ3iJJMgiKQPBhvS3uHBt9B6fDnq8SzoMimg5wrlk8J6J31KwmIy2BYX4DjhNRQIuWFwzIrFIIRE-F4sCz8HuiGhDw24dKJ0LWi+6totgPaLEBENZwzoxIoNjmg3kPR+-U5hSNqzjw0WCY-0UENOFBjkRkwG0eQFeYb1+8vRGBo4WMquiOWavdLmzzGE28iBfuNCnLFw4VjzRd5EMSKReY94ixRgdPEYAsKliwCQ1BsdKKrHg9D6NQmATcJbFD41eygvoNOOKhtjqy+YwsdyPIAJU4AaVAcRBGZBWoFxTYpMWnVrGJCJhiNfcbOOdKNilx76FcV2LXH4AcgG9dHryNhiCBgWDgU0leNFGQjWIc9c8c2K-HtiKAq44sSKVU4viYob4hOs2WHGVjvxXozOmeK-FctAJy40MQWLvHFjOATgdIDMSgkQQvIe45CR4Ic7HiM+p4qccRKzGoSbx6EkCT2KMC0ACCeI-Yb+kOGxMIC-4w8eJ0uHjD6xizKiYgL0L-igJohOACeQ5FCD-hIIcVtjwkFZgVWpI1ngf1YH34cYwSZVhNTpHRdz++YxNkbVyGg5rCwNHMrvVkETU1GcQhvtAPDyGUs65kyGpZLMG89RJ2rYgkbU6HdC9hIrTNpKSf6+UIQADJoKpk9F1daqU-A4GRRCln9Y26MfMaQxICcAOAnFfgCLjEANliCxQnyXB2r6M1gMgY+UaFKbortiIfuM4bEOcmLMrRaEjseQASlJSIAKUuAHuRIA8jWJrEQkRBEQ5cNXwFokiU9wQnsNa8dk80fqKEnxxsxHLYMTVIoCcis83IohswGfHtTYY-I5IZOXQLsh4JYUxCTcLEFNAtpsozaRVVclhBrc4YjgKlMHoIAKi-WEpK0jr4Gj4hjfPiRKOIEfdZ+uk9CWdOFwXSIAjokaJoLGYINTB1YlSSmJeIOSsOpguce335j5ifpBTAgv9P-KP85Ek0rpMwO4nj8dpz5RuA5MxlwjK2X02qYjJFzIyRGj9Z+ovlJC0ytQCggvFwLBnJifxg1OQfTPQJYyAxzXOKd9LgDnT0pm9A8ldIwE3T+O9tKotw25r9SaxvEusW9PPoVtta6QigAjP5m-TBZmUgGRJBMkJ0MZvCPAYaISHkT7CxgnQSQJjZkC8xfMgWRlOFmoy+us0K5HO0uBcynp1k1SSVIOAcDFBaQkmRQDJmi47ZNsQQdTPmqjIOZrspmWOJZmDTTU7M8QZzKJnKz-ZeFdWbqjgASAGAfef6bkGumyEdR1QUZC7JC5kjxxZE40XPUenjTzBvA3uGrPBwiks5Oc7WU6CBk+40WoMmOQozjlszESMM-LqnPYrpym52cngFLnm5ZT32RSavvIUVmMyipx9L2VLB9kLyYpVs5UTbO86Zyx5-00OcILWkmUICDMpfNHMe7kjWZRg0+vIKTl+zYp9creexVX5wARZmA6SfYGzbVF3pLPaZuXLlknj+J0soITzIfmkz055tS2q3KWCyEuEes0qupNLnKTY5uM+Of3ItlICLB8Mx+RApfkOz35JolZHKMJmLy5mv46+fPNPl3yN5DcvCs-MplSSIJrUQ+XLHykny3ZVkzwb3KvnsDI5kg9eZgt5m1SbRItcSTlRYnZS2JDVAicXHnFPDsZRZMUVcM55Ti5FAYyaaNLfQoR4AfgUoCkAtr4AVAjQO3PgAQDIByAyozgJmRFxxULCvATgHAGpa7lPKcANQA-VBxcUs8IAZ4CeWlyi5DFKwQQF4pSCSg0ehi-wH3gQCCB+AMAJ3K6GeALAYA-gQxQACUAA4gACEAAgqYByWmAglXwDfIchpGMjBAQGbiDsMtiGKRAPofJW0ESVC18AvAAUIYoAAkAAFRcVuKAACh4ogDIAMg9SkgAAFVGlAoZAKSEoC6BeAI6SeKYCtgexzAYAUwLkF0BQA4Ab4pkJYCgBgApluQXgOYGQBQBtAcAKAD6CgDMgwAEWXcYIFyB4ZBApgSgGAEsBgBeAlgW5eYDWWmAKg9yygCUkuU7DTAYAMAIejgBywPlxMKALoEoCj5eAb40pS0pADDAkVWAIAA")); })() /***/ }), /***/ "./res_built/atlas/atlas0_mq.png": /*!***************************************!*\ !*** ./res_built/atlas/atlas0_mq.png ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/combiner-bp.png": /*!*****************************************!*\ !*** ./res_built/atlas/combiner-bp.png ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/combiner.png": /*!**************************************!*\ !*** ./res_built/atlas/combiner.png ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/counter-bp.png": /*!****************************************!*\ !*** ./res_built/atlas/counter-bp.png ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/counter.png": /*!*************************************!*\ !*** ./res_built/atlas/counter.png ***! \*************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/inverter-bp.png": /*!*****************************************!*\ !*** ./res_built/atlas/inverter-bp.png ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/inverter.png": /*!**************************************!*\ !*** ./res_built/atlas/inverter.png ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/quaduo.png": /*!************************************!*\ !*** ./res_built/atlas/quaduo.png ***! \************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/unstacker-bp.png": /*!******************************************!*\ !*** ./res_built/atlas/unstacker-bp.png ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./res_built/atlas/unstacker.png": /*!***************************************!*\ !*** ./res_built/atlas/unstacker.png ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { /***/ }), /***/ "./src/js/application.js": /*!*******************************!*\ !*** ./src/js/application.js ***! \*******************************/ /*! exports provided: Application */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Application", function() { return Application; }); /* harmony import */ var _core_animation_frame__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./core/animation_frame */ "./src/js/core/animation_frame.js"); /* harmony import */ var _core_background_resources_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./core/background_resources_loader */ "./src/js/core/background_resources_loader.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_game_state__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./core/game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _core_globals__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./core/globals */ "./src/js/core/globals.js"); /* harmony import */ var _core_input_distributor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./core/input_distributor */ "./src/js/core/input_distributor.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_state_manager__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./core/state_manager */ "./src/js/core/state_manager.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./core/tracked_state */ "./src/js/core/tracked_state.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _platform_ad_provider__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./platform/ad_provider */ "./src/js/platform/ad_provider.js"); /* harmony import */ var _platform_ad_providers_no_ad_provider__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./platform/ad_providers/no_ad_provider */ "./src/js/platform/ad_providers/no_ad_provider.js"); /* harmony import */ var _platform_analytics__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./platform/analytics */ "./src/js/platform/analytics.js"); /* harmony import */ var _platform_browser_google_analytics__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./platform/browser/google_analytics */ "./src/js/platform/browser/google_analytics.js"); /* harmony import */ var _platform_browser_sound__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./platform/browser/sound */ "./src/js/platform/browser/sound.js"); /* harmony import */ var _platform_browser_wrapper__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./platform/browser/wrapper */ "./src/js/platform/browser/wrapper.js"); /* harmony import */ var _platform_electron_wrapper__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./platform/electron/wrapper */ "./src/js/platform/electron/wrapper.js"); /* harmony import */ var _platform_wrapper__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./platform/wrapper */ "./src/js/platform/wrapper.js"); /* harmony import */ var _profile_application_settings__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./profile/application_settings */ "./src/js/profile/application_settings.js"); /* harmony import */ var _savegame_savegame_manager__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./savegame/savegame_manager */ "./src/js/savegame/savegame_manager.js"); /* harmony import */ var _states_about__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./states/about */ "./src/js/states/about.js"); /* harmony import */ var _states_changelog__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./states/changelog */ "./src/js/states/changelog.js"); /* harmony import */ var _states_ingame__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./states/ingame */ "./src/js/states/ingame.js"); /* harmony import */ var _states_keybindings__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./states/keybindings */ "./src/js/states/keybindings.js"); /* harmony import */ var _states_main_menu__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./states/main_menu */ "./src/js/states/main_menu.js"); /* harmony import */ var _states_mobile_warning__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./states/mobile_warning */ "./src/js/states/mobile_warning.js"); /* harmony import */ var _states_preload__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./states/preload */ "./src/js/states/preload.js"); /* harmony import */ var _states_settings__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./states/settings */ "./src/js/states/settings.js"); /* harmony import */ var _platform_browser_game_analytics__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./platform/browser/game_analytics */ "./src/js/platform/browser/game_analytics.js"); /** * @typedef {import("./platform/game_analytics").GameAnalyticsInterface} GameAnalyticsInterface * @typedef {import("./platform/sound").SoundInterface} SoundInterface * @typedef {import("./platform/storage").StorageInterface} StorageInterface */ const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_7__["createLogger"])("application"); // Set the name of the hidden property and the change event for visibility let pageHiddenPropName, pageVisibilityEventName; if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support pageHiddenPropName = "hidden"; pageVisibilityEventName = "visibilitychange"; // @ts-ignore } else if (typeof document.msHidden !== "undefined") { pageHiddenPropName = "msHidden"; pageVisibilityEventName = "msvisibilitychange"; // @ts-ignore } else if (typeof document.webkitHidden !== "undefined") { pageHiddenPropName = "webkitHidden"; pageVisibilityEventName = "webkitvisibilitychange"; } class Application { constructor() { window.assert(!_core_globals__WEBPACK_IMPORTED_MODULE_4__["GLOBAL_APP"], "Tried to construct application twice"); logger.log("Creating application, platform =", Object(_core_utils__WEBPACK_IMPORTED_MODULE_10__["getPlatformName"])()); Object(_core_globals__WEBPACK_IMPORTED_MODULE_4__["setGlobalApp"])(this); this.unloaded = false; // Global stuff this.settings = new _profile_application_settings__WEBPACK_IMPORTED_MODULE_20__["ApplicationSettings"](this); this.ticker = new _core_animation_frame__WEBPACK_IMPORTED_MODULE_0__["AnimationFrame"](); this.stateMgr = new _core_state_manager__WEBPACK_IMPORTED_MODULE_8__["StateManager"](this); this.savegameMgr = new _savegame_savegame_manager__WEBPACK_IMPORTED_MODULE_21__["SavegameManager"](this); this.inputMgr = new _core_input_distributor__WEBPACK_IMPORTED_MODULE_5__["InputDistributor"](this); this.backgroundResourceLoader = new _core_background_resources_loader__WEBPACK_IMPORTED_MODULE_1__["BackgroundResourcesLoader"](this); // Platform dependent stuff /** @type {StorageInterface} */ this.storage = null; /** @type {SoundInterface} */ this.sound = null; /** @type {PlatformWrapperInterface} */ this.platformWrapper = null; /** @type {AdProviderInterface} */ this.adProvider = null; /** @type {AnalyticsInterface} */ this.analytics = null; /** @type {GameAnalyticsInterface} */ this.gameAnalytics = null; this.initPlatformDependentInstances(); // Track if the window is focused (only relevant for browser) this.focused = true; // Track if the window is visible this.pageVisible = true; // Track if the app is paused (cordova) this.applicationPaused = false; /** @type {TypedTrackedState} */ this.trackedIsRenderable = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_9__["TrackedState"](this.onAppRenderableStateChanged, this); // Dimensions this.screenWidth = 0; this.screenHeight = 0; // Store the timestamp where we last checked for a screen resize, since orientationchange is unreliable with cordova this.lastResizeCheck = null; // Store the mouse position, or null if not available /** @type {Vector|null} */ this.mousePosition = null; } /** * Initializes all platform instances */ initPlatformDependentInstances() { logger.log("Creating platform dependent instances (standalone=", false, ")"); if (false) {} else { this.platformWrapper = new _platform_browser_wrapper__WEBPACK_IMPORTED_MODULE_17__["PlatformWrapperImplBrowser"](this); } // Start with empty ad provider this.adProvider = new _platform_ad_providers_no_ad_provider__WEBPACK_IMPORTED_MODULE_13__["NoAdProvider"](this); this.sound = new _platform_browser_sound__WEBPACK_IMPORTED_MODULE_16__["SoundImplBrowser"](this); this.analytics = new _platform_browser_google_analytics__WEBPACK_IMPORTED_MODULE_15__["GoogleAnalyticsImpl"](this); this.gameAnalytics = new _platform_browser_game_analytics__WEBPACK_IMPORTED_MODULE_30__["ShapezGameAnalytics"](this); } /** * Registers all game states */ registerStates() { /** @type {Array} */ const states = [ _states_preload__WEBPACK_IMPORTED_MODULE_28__["PreloadState"], _states_mobile_warning__WEBPACK_IMPORTED_MODULE_27__["MobileWarningState"], _states_main_menu__WEBPACK_IMPORTED_MODULE_26__["MainMenuState"], _states_ingame__WEBPACK_IMPORTED_MODULE_24__["InGameState"], // SettingsState, _states_keybindings__WEBPACK_IMPORTED_MODULE_25__["KeybindingsState"], _states_about__WEBPACK_IMPORTED_MODULE_22__["AboutState"], _states_changelog__WEBPACK_IMPORTED_MODULE_23__["ChangelogState"], ]; for (let i = 0; i < states.length; ++i) { this.stateMgr.register(states[i]); } } /** * Registers all event listeners */ registerEventListeners() { window.addEventListener("focus", this.onFocus.bind(this)); window.addEventListener("blur", this.onBlur.bind(this)); window.addEventListener("resize", () => this.checkResize(), true); window.addEventListener("orientationchange", () => this.checkResize(), true); if ( true && !_core_config__WEBPACK_IMPORTED_MODULE_2__["IS_MOBILE"]) { window.addEventListener("mousemove", this.handleMousemove.bind(this)); } // Unload events window.addEventListener("beforeunload", this.onBeforeUnload.bind(this), true); window.addEventListener("unload", this.onUnload.bind(this), true); document.addEventListener(pageVisibilityEventName, this.handleVisibilityChange.bind(this), false); // Track touches so we can update the focus appropriately document.addEventListener("touchstart", this.updateFocusAfterUserInteraction.bind(this), true); document.addEventListener("touchend", this.updateFocusAfterUserInteraction.bind(this), true); } /** * Checks the focus after a touch * @param {TouchEvent} event */ updateFocusAfterUserInteraction(event) { const target = /** @type {HTMLElement} */ (event.target); if (!target || !target.tagName) { // Safety check logger.warn("Invalid touchstart/touchend event:", event); return; } // When clicking an element which is not the currently focused one, defocus it if (target !== document.activeElement) { // @ts-ignore if (document.activeElement.blur) { // @ts-ignore document.activeElement.blur(); } } // If we click an input field, focus it now if (target.tagName.toLowerCase() === "input") { // We *really* need the focus Object(_core_utils__WEBPACK_IMPORTED_MODULE_10__["waitNextFrame"])().then(() => target.focus()); } } /** * Handles a page visibility change event * @param {Event} event */ handleVisibilityChange(event) { window.focus(); const pageVisible = !document[pageHiddenPropName]; if (pageVisible !== this.pageVisible) { this.pageVisible = pageVisible; logger.log("Visibility changed:", this.pageVisible); this.trackedIsRenderable.set(this.isRenderable()); } } /** * Handles a mouse move event * @param {MouseEvent} event */ handleMousemove(event) { this.mousePosition = new _core_vector__WEBPACK_IMPORTED_MODULE_11__["Vector"](event.clientX, event.clientY); } /** * Internal on focus handler */ onFocus() { this.focused = true; } /** * Internal blur handler */ onBlur() { this.focused = false; } /** * Returns if the app is currently visible */ isRenderable() { return !this.applicationPaused && this.pageVisible; } onAppRenderableStateChanged(renderable) { logger.log("Application renderable:", renderable); window.focus(); const currentState = this.stateMgr.getCurrentState(); if (!renderable) { if (currentState) { currentState.onAppPause(); } } else { if (currentState) { currentState.onAppResume(); } this.checkResize(); } this.sound.onPageRenderableStateChanged(renderable); } /** * Internal unload handler */ onUnload(event) { if (!this.unloaded) { Object(_core_logging__WEBPACK_IMPORTED_MODULE_7__["logSection"])("UNLOAD HANDLER", "#f77"); this.unloaded = true; const currentState = this.stateMgr.getCurrentState(); if (currentState) { currentState.onBeforeExit(); } this.deinitialize(); } } /** * Internal before-unload handler */ onBeforeUnload(event) { Object(_core_logging__WEBPACK_IMPORTED_MODULE_7__["logSection"])("BEFORE UNLOAD HANDLER", "#f77"); const currentState = this.stateMgr.getCurrentState(); if (false) {} } /** * Boots the application */ boot() { console.log("Booting ..."); this.registerStates(); this.registerEventListeners(); _core_loader__WEBPACK_IMPORTED_MODULE_6__["Loader"].linkAppAfterBoot(this); // Check for mobile if (_core_config__WEBPACK_IMPORTED_MODULE_2__["IS_MOBILE"]) { this.stateMgr.moveToState("MobileWarningState"); } else { this.stateMgr.moveToState("PreloadState"); } // Starting rendering this.ticker.frameEmitted.add(this.onFrameEmitted, this); this.ticker.bgFrameEmitted.add(this.onBackgroundFrame, this); this.ticker.start(); window.focus(); } /** * Deinitializes the application */ deinitialize() { return this.sound.deinitialize(); } /** * Background frame update callback * @param {number} dt */ onBackgroundFrame(dt) { if (this.isRenderable()) { return; } const currentState = this.stateMgr.getCurrentState(); if (currentState) { currentState.onBackgroundTick(dt); } } /** * Frame update callback * @param {number} dt */ onFrameEmitted(dt) { if (!this.isRenderable()) { return; } const time = performance.now(); // Periodically check for resizes, this is expensive (takes 2-3ms so only do it once in a while!) if (!this.lastResizeCheck || time - this.lastResizeCheck > 1000) { this.checkResize(); this.lastResizeCheck = time; } const currentState = this.stateMgr.getCurrentState(); if (currentState) { currentState.onRender(dt); } } /** * Checks if the app resized. Only does this once in a while * @param {boolean} forceUpdate Forced update of the dimensions */ checkResize(forceUpdate = false) { const w = window.innerWidth; const h = window.innerHeight; if (this.screenWidth !== w || this.screenHeight !== h || forceUpdate) { this.screenWidth = w; this.screenHeight = h; const currentState = this.stateMgr.getCurrentState(); if (currentState) { currentState.onResized(this.screenWidth, this.screenHeight); } const scale = this.getEffectiveUiScale(); Object(_core_utils__WEBPACK_IMPORTED_MODULE_10__["waitNextFrame"])().then(() => document.documentElement.style.setProperty("--ui-scale", `${scale}`)); window.focus(); } } /** * Returns the effective ui sclae */ getEffectiveUiScale() { return this.platformWrapper.getUiScale() * this.settings.getInterfaceScaleValue(); } /** * Callback after ui scale has changed */ updateAfterUiScaleChanged() { this.checkResize(true); } } /***/ }), /***/ "./src/js/built-temp/base-cz.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-cz.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYAK3hhi5RGH5xEANwBGgbEAwsUtICH5eADswrcv0QBXZckSweHRAGMeYaQF+9sgJ5hxAa1LJZPTStWaAW7BAWEAA5DAAE1UAGzBoaNJAP0AeWHkBQENAAMtiJWlEckB7QDBNcU14DzLgzQBLsBNWeS5IABpwQkgEzQwaekZIAG0eZAwAXWAAZSoAUQBBAFkAfRnUVAWASTmZgHEpgF8AejpYMWh9uAp4BdZMS4weADMuO-v+-aHRgB1NZjZOXn4eNBXGAMChhIhZKQjGBZAYeNEIj4MGB7lZlOQePAgcpXEZPKZhLBiMJLBpTHxtIhNBEdHpLFjoEiJPcwD5SUhGV1oi5LJ5WNE6HEWOwgVY9NBRdofPcfCl4NywHRrtSmfUuGAAKqsUjaCLynjSeAYrpKYlgDQARwMWIQNJ+IrATihYAA7vDYrpSBgNBLXSliD5TcJQchwdSwAZNAlLG4I6xvYg9djJOx4DSDKxHVDyCi0RQnFwvjNsWa9SZw-cKELfkC2WToFjmlmDH7orEWIalJJLIgBXHmznUZZ0S4caH4LAg5F4OWaQBaMAAER1AHJJ5XyFhJxCoZOfdn6SWoRhiE2nS23W2RDJCfwlVSaWLSL6icJ+rIRtLZQg6mxXh+AEIvnGUgdWbVt2xvLs6h4WgwF5BJyElGlrh8Sdzxze0sT9Ikg3CBcAGFPG8MpzTTJtvXgLRXHDWRomteDSEQsjoAPbCcU9CIDHpSIHnuI0tEnBCKGQnREDQ6sHTdXCUmg6ByWge5R1LGcH0LTQqADIEQ2EfjTAMH0wAARgADlpL0fUZTsBUNaIgQACgAdQDbIhShBEwDcKjM3PGEDGgFwNxEbNRWiMkIicACAEo-MnNYV3CXlvlgKlYAVRNERNMoXUYzQEDysAF00gTWVFMAEknfkqTKCIgM0VADOyRBOWRV8QTBEEDWw3yrEPZMpykalex1YRDSQilXRcnIWFFCJETMHVexRJBYAM7CH2bFcr17ViyPpLrXEsProOyhU9Vs0h2BpPTVp9dT3xGcYUqGzphBmCI8jym5oH-EYvn6aJAVgP7tEIfoACoRiXfJYzmUg9S+QgwAhqGNSjIY5RpRzECcbU0OgRGwchzV0eQTGwHGG8dIJ0GIBRsB3vmiklobWAzC6GmkfpoiyZNVidTwRyeEMgAyMApjKTdIoZjGTSC+y9AME9uRirQaVIFkACkDAVAAmAAGA31K54meaZfnNDwOGNDAAAZeBbM5omoZmNtSBdIFQ2g+4DNfHNzvlS7JL+PgwEAE3JAHg--79kBuAQYegAxIw1s1VgIgJH79g-L41lccIM3T9nWrNHTbCNFwNfymiaWOJwmQ4-ycipONC-BScBWaycHfL10qLcOqAaBkGTahxc+IEgr6lEpq2y0LAHPgJ51SnnCclIWQpEsAVoCiwm6eJhqOA4bewHsxd9TGqdLWtOA02D1fgR9Y4eGHO-8iQMB9jiCdmT8+FMowDvPeyNiYzDiCOOo8NhAumJDbWE-8kRAg7OCRicBgHcx1DKDABkIR9nqCCLQRpTBVnskRTQWCU77kavAM4wphCMg4DQvU3wUhOCbA2N+4ZkAXF3rTEBLs5opGZrEWAuNsIa2Dk7feUNUBGg3OWHiQxPSGlDHlByxV2pe17OFFw5BIxAl0BOURvc2zRXQaArh3EcjcI0APGOQ9-ofk0oCTRwgXGXWoqxahAFfpFk0E4SEEV4LNySs-WECAmzxXCGiLqCofDSCYoaGkgY2q8mQMgSMrDq6uDZjOVgk4cQaGkJiHKvZYjQCVvPBa3xskpS8stNMsgrCxjQvwJKjI9RiGqZNEq2oJQ8DoovMAAAhehKccTZHgDGCQ0JkCjg0G7GEpB8jXSrG1H2V49CJnqAPD8tsfBuEztnTQg847mKhv0Ay0QAC8xA2asGgDgfY+xETQF5OQCIXA0lvE0MUhA+wAASAA5AA7FMAAahwcFIwADy9wZTWCWmPN5FAIivCucPZ2yMrm3PuY855xx5QJC+Z4LO+w1jjAAIqaEsKwTWqBaG-A4HwEYAAlZZER6jovINETF0jsU8txbAB5Tz9gunFVwDQgjYAkuQPscgjL2DMtII9AwsgpXzW5by85Aqbl3OFfi-YdwiRqtlfsZQG9dCKpDiqkC1DGJ6lPlsFIAK1VRS1Xy-huqhUiueca4gprvkWugFarC3A+BZwSLIfYJhb4KuOFSeI5IdSnFZbMRccwphcGQBEEYAL5SZgTd8aIBIPXR1jsDFobQiCvPeREfZmg3B9DhQingSLAR1sKmAAiLBJzSWsfAACkA2i7FaEQDAUbeyMAIO0BIiYkR9CBYgUIsBVDICrUjSARo9DkD6D2gJiAN3tCJFCeS1JoBj2KZ0voUAx3tD1NYEw0RxjwGuF0igfQmh3qIBU+FsFp3VuPWQfyD5oB9Cbd+9oZM2wUjA3gSAcwj2bu8DBlNfRhlIePRiVD3w+hUGHUjUdgHIBfk0HKPoZQKjwCqKQTDkAzChgA0jIgI0X1JQiDMDAtH4OsEAJqAd8GxuEjBEKEmGiC0DYzqCI0BOPcagHxu+AAeWgAA+b+QmhpkzE1AEacwfBGHgLJvoCmaS8zxAYbTkBaB6c0AZmTXHjP8ZpMptTZmUpacgyxsoALsxGZ4054KmVROeagLQHzBl7NycgCZsALnAs+BQDwSzI1Fw4z81AaQwQiGWdoKlpwkXHNKdU5EfxlmGzsegOMMglA+iKfK1J6AKmwMhcgG5rEMxqSSfPVVigDB4OKba418IdWpkNaa5Z4DSEOsRBs3ZnrNX+uTcazkAb+mEBDZy7N9btXituYI4QIjm6vL5aY8x+jEI8MzAwy10Jehoh7qoKy22lnex9agDMW2+GWtYh7OwPoUxxgETKwGe4b3IDjABWsBOX3AM-uuPSPo4xUAzAIlMfbEBdgjrvZAMspBhnVSNHB-AxGzBpWwPB8+3Cy7kEYXRtCeg+gAC0AjQC8gIH8-JfAtjGsy8yEgyxuFs7AII0h0hTJyD7RtlgAhDqx20Vr4lNBzC0BZvAM6iBVScH0AF5BVAMEg5AJqXRA4YCZ8geQpWDdKN65TQ0Ok+hrGQNqSgKhTB0Y8ZoO15B6QArQnh4hIgxCCGEB7uIbEh0G9raihtTb4NwpfjwGIgQlwdtRRTI0Y06PEmiKwKgYhi0Ej6KgTwpAOAc-4wkZIk5RAGAj8R9V7sGzkGxuQMjXRtdiCED+aQxRX3w2d67mo4RPTEGiAERI1GeBNiEJAxINQwAT8D+IbUChEhBG1E+2vYBi+8Z4IAeEAfyMjiCgZ8KVYBc+p7zsokJbBOA4B4AwYv2fCBH2PifwRu2iE8C-vQOhoi+DIAiF8HPzsDAA4FUCr3KC-WI3kjtzBHtlsj6AAC29BDRAAJQFi1Uzo1gPgB0gQPlDRkF3dk0EXU4E0DXVUDAAAC-UD4A0C6NQl9NycoBi83AxBghXd9diNsotgwRF0-Al86MTA9Rhktd4NwUnBYAEld9YhFNDAT1yA5xAZG0VNsC1UNUUg+hWU0x5p9tDsoBERhpAFTsiBwllBcM1dYcdNY8oAYUABpSzPUAUBARHEwCwLg5jKAHsGleUJnPRdITQlrEtBAXdeDYvDgCINIJLFrJ+fIMHbQqQGrGIrECcLQlIjws7LcJ6B8YaMoJnFnNnH8VAf-Z0HnaIqwnHeUCceAXgxjcQsIRiSIeQaINdSzYpeAF0LUVuJndeMQZlbcNwVaXscwKwcozwkgd2LUBMJMHo9VRAfo2-AUVgMXQIYHd2Ow+AAJHwABInSARnXo+Y2SNwFow0ViaQWoe-LpNwLXQDfQoga3SgW3XAsEKYcgHdEw49FIAUPdYgA9MAR3Z3VaSzBAXoeDIFPvJJBIb+VkJ3XrTg2wRAAIiMSvLQZ0GvHAdHMAO4qAB42AJ4nScYbiPqD4ogUnb4+DDUFE8gpfGEwEvwEoYEo4PocFRE4QHWJILQSg0QcQZwEtagkNeQdITQRQXE+kxAJoW4g3PAjlBOcSeiDQEkqAMk5gyASkjk6k7k4PHQUgdIDwRhcgxk0EqAcE7USEyQYQEoUIOABEpE9kifC-dEzE7Ew3TBYWZAfEsEc+Zw5g9XT4snIvUgKQj5WSaANw-wAIQ0sHGFXQGQLieCYgekQ-Nw0wQPAwAAfidINxwJ0i9InApFePeMsPGOVJ+L+LDNWJaxBLBxNJUDTChIbDiGTMnDyFtKpLRL0QxMlOI1iMoG0KtGFjTEVPoy+JVIkMSETHpJYhSiSIqKrKL1-zYEBg8DUGTxKCkENGTwyWgACB-B7OUDyGrz0QlMIwNzTBSA2K2JVHbyLLOxLPg0Z3NxKE8hOKxBUAuLYNMGuMcJ+zN1UGCEF3kB-GONUFOJbGv34DSmXR3I8GKHEDmSRM9B0F3143mK0CCHAvFjeV+D5w4H8LQuPIOwNx9AnAvJIh2LIRlHIBMGqSHLvKgASJ-mAtOJUDsFckuIJAgwqKTEsGbRjOkDjOyETNGl11J2fJAtfPOLAI-NgGuLAIaEnBEx0AKASSAICDIFgvXLQozK7KO02LIsQQYtgBhRsN9NJJHLSNZjEuYvsDYukvKG-LeWZNZKsokvfKuJcF5N0XSPpJcEUtYGUvhkCHUrXJSg3Jl0zOIxujWgSOfmHApFovMopxnH4B52wBa24qZwf0yA5yhDX3XEjDcGsFPkUyio0BUyiibEGKNEoLKGTx71x0vx4HVB3330PxsE51KKNF50QqWMyDAIgLlH7gis3VYypngIxje1MqVMStsNDH1NqAMGAqiArK4p-PEOEHv0f3gFkDqq6psGQAKAnx-GQB3O1IMEYWDyAJbDtNRJbBr3VBhWkwTTQMP1XTyAECyCCBuodL0V7xvyP21F3wPxfxKO5z2tlxPOIwLgJEJPSXyDEOJ2LJmsgCBQEMQEGIMGGIsHpDr3GIyvgyoETBcAEC8TAMfIrhQmfAFCAPkE7Mhs3QzGmKxDWDyj0C4jip1ASv9LjwFy52bKcF6rQocp4vELF2yH8VyHhsqpCNqGkEkOkJ3PgCbGiAuu1AMDys8n5xnCyzqoFtfRWKCAXDq2OB1AwBU3BLI2CEP0ksSNqH3PUH8QAkUzOBNq6DUzsLiPEDlsFuTwbJKGyFUA4BF1pBkGqHCGq0CHCD0ADQkDmI4BUGuIIoxwN1jQvSqIQAordK5vJJYMDOkGDMnFDPmPDOFubSerEDQIMC73oTVrgBbFhBEx73sgU2gGFIEBsEU15EjFgHKoAjAGjLEH4pbBn0EuqMbPmNMG0vpvaDomtF0HxlRtgDRmjC8giGzpVMZ1MAaLKCgWQB1to3SrWpYJaIlqEHSFSD+oFopu1q0Glh7SEqUJsBn13qIKMCbBEwqCyx-BoNrIwKMl1iTqxIN2O30o5hZpNvZpopvM3TotVMgKqFqCYtcqkvctLvgx1zgsoJDVPVWhcrONYpyHYoQDcGlqNAWtbsTEro+vARkFhDLmiDcAIa7DUA0E0HVEZ0dRJudGFKqvIGqCbF7AtM4DYG-xevoRf3hgCAPNZFgtizgD0DdtP1MGTyQbOLcs-KcGdvkdNpUydvVRU0U30di15EdS3mamgGuRXBAe2KRBXBUwIke1tmdpMfgDUwAGowAqBVBiA+a8AJD1VwzY6S04AmrDHyA1NO6oF4JgmLGrG9KbGug7GIcocqBnGoEVM8Bi8IhyB7SGiDqjq2STqQnmyshhAG6VAwDxAGxIQjAuAwmImXHonzHLHrGryMA7GPtUn9gXGMmwAHyLdZIKBMQvoiqDAinUhNAmHWBVBoACg6n9Hhr2h2QCQ5gYYjR17+C1AwDLS3BD1D7HL4NnVOxZI4KkA28MANlYLQwzxnRvDXA7IAQaV6JHVxBjaFGzbmBetPJNitHXazbf4qm6FT5nIX4chfI7msBJYCRYtxBRB4B7hrkPhIB9VfV9h2iXQjQuAw1-gkWlB8gtxEXIAFg6IqQ3AkWVNYF4BnbEByrgSRyphdD4MGXZJVnyAvJd0dKoM1nyBKdSB9kyZJrVqDmoBwUIw3BA6eJ8mx65apDSBd9KooQLqPpFAOAdmCw+mCj4Bn8-8L8yi+cd65qtBQDtQv7tnl1ygIbCLiNU6CIjBM6qKNmwi86C7b8BAMlhc0GoB774B0hXXuFoRsH-JcHymm6W626bB+N97jGoQ8pe6wBwUIDhToJR7fWDBIjgip6rXN0lQbd2QtBPnYAW9znHWoAphaBASq64hI7yhY6+iE6td9mRaoBN7EhVB05YgSabA7xy24SVyghoBJLwDjjExT70b+BejA6oCwA5g0hzJtzwgnzrhzczAmxF8xxDqNqtXkBqgnzudALMg2LVBh3mFIgEgDB1LjgDymwMKP6dQeJPn5pUzLXk7rXzHbXYAWbf1W1BJ7X11oG-Sc7IBf34IjBPXIAABNW55uYA1weFNPDiTuQkLSVwMkPumYG2XyCpDD50F0VKZN6EFITNjHOXe4roPg-9yAVpnYmFMaEtBGqa1rWs1Z1gAMipbQeoBtiohsAUYcYZOEBERBZkgJLpIJzuMrZQVgYoqwGcQSPoDUT+2SbUJakumIwMgkPjhBa82w5QYIWSENizFrKqekOYHWMwfkFU4vSvWSaQUpvyRuyzIpQneAGFDEQSZNEg+8x8wZ1zkZsYs7V5XBQzPEFz4Zs-eK8Q3GPm3EYwckGMZ0IZtz6wYEr0CdeAV1NesI-jVgKLgFDURcSzIz+ADTgTrTyASzpIPTtNlQAzio5ZhAVl9loT2V+Vs1-8mrvG9Ojey2wIio64W+W2TuYZeiV9Y0MHcFKzhV+INMZPfkfwSzFe0ZaIWAMeDQDmjz5tlAV+wu83HMaZipArktTQSWcYaSbIcYHgPUZtHTkMotFwWb3wPILLSzSwIwF9HjqBkVpwN13cZ7y6JwN7qZD7yAOwy6AIXjTg57jucgAHtbvwx-azuwBQXdQzngdgXJPoD26ZmSg+rj074gAbpwQnRHPH8qHGInzl0w-jgBKT+kVRQV8YywJwLeIrqnpEFkjEVKXYh8v8gCn8RTY7NTRChTVgAIcgzczgGwPIDnr6MmaA8YsgGSzYgb2QXw+DOwl8s4ygoh3ZvAfnzY1QlraUUgHoWAInKauHKiDL+ipn0fU-bTIgfPLAPoZceSYge3pgdEG4ZAyvSZud9Ed3yAEaNYBANAI0LrK3yAIySWnML+QTYTdrzwnEkP6AWRaH0bakHbNTKQ-IIoWPgPuUZAFPsP9PiIZcNVQD+yWgXWKKAPswbeTPyIAIBhgoTE4j6eogGyeUHmczhAReh4F+dzoczv6IKgZGlA3+2LYfg32rvkb0iP5cT+1EyzSMFek3sum+3wXXjQXDj5XRyzMwnUcE+gfA+7CnXsPqn+9AxZogYA-vnsapM3io7KKYsQS7sEtGjGrG6TrU2MV5bUZlawLjUyJggniEfDBjCAFriBvq4pa-kwDIAsd-2Zlbmp9x9oRkWsB-TQMvVIAxghOvVHrkjXWbwZx+6BTAtPwIHkBle8oInP0CsJEA1gAfNYPQJCx0DGBDA8FAH3YHMCRWTA2gdwJ4GJ8+B-AxPpADWAAANAPuIKsIjAWsJgWgEMDGYn8+gmwUQRsAACDtsIFAAFmwASBVlDCnBRTBAA4oCnxWUNvBINaVoCd0DIrDWACZyW60sKeHvBSGYEsCP8kayA8HGFxCZfl0qpgRAF7kPCKkf06IQcogNvLI01S9pHHgIJrQ-YMQ+ScLlACoBS8XA31WWqNERJBB6QrNJPEEBDaNBW+WbYQZxG4ihDEaMQ4ch4IkIlDly-gaIRUO4rxCgeyQ+Gp5BCKUEWyt4FhouzZqLUq6StWwF-STZzVUevQwYnM0KEvsBBlRQGGNDKHm8AOKpZcMtXqHTDGhqPZoSkLaFkNBApNETFEBXK+UUqmQ+CIJF1z-48hVXOWoA0IxWFsSN-UgFVhrCoBeh9ICPoAF9ANtvPmz7kAXA7hbettSvq34ahPlOXmdiwhF9yAW2FUnVjoSNZP4dQWATACMSIJlctmIcprgYwql80reIIMEGaj79WeHMGnmUMgB8dG6nHcYiryW4p8S0bwovDM0pFnYMBbg4QYwVswWdSAH5DggeQD6swi4uxJdJpRWrTDVEquY0iBRE6KUxRhQzHO3yVJ4gOe0QX3GohLZldAy-GWENXW1LcJhwGZFrJ8xdAqiwc+xOOrJHIKml5AXECbBdzS5+57yMgXjDuSRGz0RuaEEkaEXKGbpeQcAPdFoEPSODIAuHXGKQHxhDlgxeMVUfeTVYTY1U2uDUNdiFakgNhiQ4HksSFwNEbIdgcIJBRXReRwg8FGwE+VVbLohM0JFupGDHpPkhA1DMZizgmYBBKq6YowA0T4rZilAJaPMTOEEBdty6VIRWvM3Cb1MnogIQXC2PCCqMXAevS8gAjUwysFaP4EsW11kbo1VouQgsfWPkDXttq-AN5jo2OKvoMxw+Qeu2NzHQUZwvzd5nOPlpytFarXMsU+TlpzEh8dQTcbI3qAFCbsZIapISSOgMg++CKQftGNLE8lIBt+Zrv6MAbOk0IRCOKoaCoCKi20p-L0YsLwyISYgNoqMShM3RGQFguEo4GIGHAfoKS4zQCsID3Fu0CJq4igJeJ0ayMSgAoZlOfXkAUSzabBc9m+QvZS8DAtEt2sCBlbyBEgP4GsUAPGK4TdYCwJKIaCdCeiyuu+bUNqyomDEqwG+bAUEFYkqYRMfFQIMuWqDqU9uPEl2leM1qdCMkYAXLnxz0ZDj9Go-VgLr20Zu11ePAXniglXQ+MyJvE-5vBXXy-5tQVJEXLZz24FBRJZ2XCQAGYFg94DPgTUDK7iHJZtIFFMC0GeS1MmpfgFlnFaBA+6L6dcj+HbZ9UlJECZfIyIEbOBb4kQZ8N40BjwQm+wgX4dkAFDt1BxBjGyajzwDesEAj9CMOM2s62dCpFAAoE2G1DZMhJ5E+KSpmSbQ4UpzVEvNLjkZ-MVMrKFKVqSlY-hYpunGVLKMDHCQkIQ5KVH0EAAwgBnk5KWZKIWgJnFUQNLoDhuSg+GLrksyE83YLoPoO8PoiroCuBkczn0AThIS-Az3JwFSDwxOA2W+WP6S1hgTkZ4MwyJvqoGX40omIFwCPqMg4Awh8gctffnSJsJkjMZSIrCOChKSEDsJ01KoUhCkJMjs2TuURPOUDpAFqgv3VgE4AvJ7o-uYAJmbcRI5wDLoL-RMFiA+KQBqR9PM7CUDqIsESpvEeRgMlKFgAxYq0MoNyGFpNDUxpghqafjACWCXubxQSHYJ7pgBAASYRqzFM2UbWaoUDG8xCZDHYWSqTLYJpCqaVJMYrM5rwZlZtvCwVYM1l5RjZesg2UbNM4mz5R0WOkAyBEhDlLZfQQABqAnAcMk2EDJ-k0KwIbBgIHpJoD7ZKYx2dbxVmuyNZNgz2frMsE+z7BSI1CHlAXRhDIAoc+DHMCyDEBAmPJNGULUbYOz1ukAZ2eYMnDqzrBWs32V7LzkdFjZTpDmfzKJHGEKOAaWQEOScJdRZJywrVi4UrKkAsBOAnjL-l3o61k54xYfvNlgAvcwctscFM9kDECzx58LQwEtyCFQBy5UAZcNpICDLljWMzAPusISFpy5JI3GQP0Oj4uBa55AOWkNN3wjS0KBYjdj+DrHFNbAgUmZkUAsDfwVeeLYkMgBuFYlTZPgc2atVRCmcz5Zc8jqW3oBiBlJyPXgZUTeSNy5OpEn8E+XIKMSeAzE6PmBR3Gozv5d3X-BYGrlCBk8qQRIM4AQX3CvCLABLIMgwUXzIA1s3BeiFPhLo8gHAKup9Rr5cDCFyYp+U3I1CkKLSpQGIBL2oU-DaFN+JpAwpwqIAWFcc9hZwrtgXULACkxTpICEysAfAqgbIFwsDHCYjQ3oGNhEGJbyhBZm6PUGgtPlhCb+WCyAAhLlkPy4hqcxRdwkSBUNRo1QMvHEAMgqAfAd3eGHZ1dxkxgQe3AsLKMrKYhyAusARf4sCXyh-iawdUJf2FLBKiFoSkhUkEiW2BolhdOJcUglrDTkleQVJcVICj2L-ZIaQGLkk9EMcvFJ8jxULP8X45Du9IfBWsJCUKKlBpnB4AVSqCG0wA7KCIs0XfnSA66DMiqbYDsAbKJhdwm7HyDRB5KRZ4OBSbs1Pg2RVAMighY-KB7jAFJQQD6O0qOGXUACpALhQcqdxog5w8SJzscpVL3LSAAgc5c3UHpXLyl8iu5Q8siB5AdAjIrZUICAKkAyAnSooUQG3khEj53ioZZukEWoB4QezG5VMqB7LKnRqrQkFLziDFIpusjZViEBmZmB1QGk1gmmzOrJBtRrC15S2H8oMMDA24sxaIzyl6JgM49dwtPgSyxgGyagY8fDEWo8QLAgmMoE7SMk6NMlFRK0ImH+VaFS821AIOwQhXEKnZOqlXjbB+GyMraTgXfPSpCZMrxpLKymurR4AcrqIPDGWtapXa94BVoYMRhICkDn5+2TZcVSUElWjQ105kLiLbMqaKrB0KUraf7L0Bn4UFHXbFVqqNX+9ZFty1MTClXShAP5EgMAAAE59Y4CDMGgSKDahGy8gX6oAR8AsVXIeiXThlI+W1dLAz03xefP8XspRF9kS6MukmbXLJlFS6ZXHhzVBAfhFcQtcWo2VlrzIZgStdWvhi1qbKOQBtTwAylqrxi9wZCQsMwUnKu10LeyKZH1gDrhBma5+fuvWySIIBxkEyMWr1BnToAqKqYe0E3iNdS5Ay9Be2t3UqkQeXgGxemqJVDqoVQKsdVsJExf5hC6re1b3m4QirZAdgQugpNvpDSTx0fLUn5PVKyMsxT6oBta1ghJr-Ox8z9UTL8UnK9MtAaoDmCfI6L0ZGa4lamPGAnUA6MKxQDRoyV3DAxRczFe+qI0+KSNHak5fjm-lrqDVlSuPDRqyHyhQCZqnvDZDDq2ANl9dNGc6BRl8U9JKVRTc2rxpQh+FX6wRUJuKQf57IH0IFeQVYg7U7AJ6jrkBqzUSa81KMrMa5HWWrR-K9ChJC2BRkR01KGmlzQYC01nYNVVvHdfprRlrrT4Fq3jGZvXj9rRNw6qAEouqXvz14oWycLs0SARBQCEQWqbGE0XH5uEfq4Uv5s3Rkw3iiM1NVAAM0ia6NNm5+TCjs30hog0mylbJodjybnNGYJTd-JU0h1zi6ldrawD81xq0VSpE4G7x40pq9N-ikHukFi1A9UATot1pQXHXAg2NYBUaGLRyDyNm4VTEwIviEDqhxF6W9jZ4W4UwBPeTvSbScvGDHtZtDG49msvkBFUSgNnSwK4ESBbKSgnOC3EEF2bw5WE6oOYBuxhAIa2V5oqpseyTmxLUCgYZ7VkBw3Ok3QCpcbYMvK1CLJYGAFwELAVLVbIVqY12AkA9jgQcQRabBpQEVDo7jtzGOUcNsgCJhPobwq4IHIlDESiZlRCbfxu-XMzmILNMaJipx2Gr3sf4-JGVB2kSBMIQLDaL8soC1hNpHG-2YQilgLBIWRCf3jxtmGEzIAXpSecly2AK6CQEsJxQjUgAJwP0h9dncFv8UG6pYYAXXVCwA2Drcdz823SruwgK6Md169pGM3Nhwj4dBuRHZcFJDPgWorIzxbxpxXtBBFWO4QPcp6V87ANjupuTHpSBlQ3dLgf3ayDygQUXQ7yjdWdlDCbgCN4xSPQOWnZOL1m-OsTVAGVwF7sQ2e8nYbr9CGRWkEgMoPDoHnnBfh2hHftJj5nb8VkkkowCEQWAPgFgCaZgGqIjngE2FUvFvo22pnSBFAJNNabzR1gd1xp1i+iMtIXD8Y12WwjSQO0BAChlpKvFGciuppgUqm7msXaF1GJWSWp4TcEl6roKH4NqTSBJNI37yJg+VPY4NfNKvFSqw1Cq8oKRBqH0gt9fOfKDiCoJZYO2DYcINKq1rIAxxsQDwOkFIbkBQCq0iRurVOpPlyyQQT-VxGfa4bN0fej5AsATUEg+ls5ZGtmtjkijCNwrSABpK7U0SVVfE3krSBAqKAV5WgPunQdzXLaK1oZKtXdUXUPcmGq6jKfmqLUlrWAZaqCURQ6L96uNhe1CVDLrkMHQ9TBjRBpNUPkBlpM0GEFRG0Ar9sBq9LtMIrRBh4vYouw0D4AcgCAg2rgIEL5EUr9pJEMUDaGkhIhuI+0-oeOUCxSRmh9DybBGTmFfDIA799TVAOMDwBrAWQPUG2DtLojbEmwfsNxGVA0mi7UjXCKBMtOCPiM2YiCYg86TIOuKyYtANQ0gMA6VyA6yeHRQ7DA4aTyNlG4-QLS4ML7EDOtLtPfmIj6YZ8dK1bapLmkaT50ZgaQEFX4BMbq5gQFKaUaUPd6Fgr66o8TMA6-qSIeuU3UmMXROBNyQCmukCvhJCHZp6k8aR4D-XkF0Q8x7fFyNZU4gBAeoaOU0jzUNl99SxAIMtMlXrxGgtxoTDSDKDpHmtfFc0n-p0YMTX06FRAMtJk02RSACx7ssofIPdKUg3G1nbA1JXzEk5+wQFYnL7Zwr9uc+iubMp9iC4FlYJt2k0jGVGh2jHoXXF0d4PaAFwgOxfPBoVY4HKov+dcnQwX2wAD2OQe2qw0b6yVjA3+xfBpL0AcAUKkioQDCa2EjCYVzy6Iws0DHlHR9kYIJaXNgYFL7sRJqABpJ1O0nOjPBssD0YXAJaIlayupVDviVNKklIbRLGksZGKHETSxyg0PqOhtr0TtBnNXHNYF6nIAj1GcMgafrlSpebaPKC2AlOxS9E4Bi0zUoQMxzTWnoOdSIYXVBZl15oAwI2qnb+MjQu5GM8CA0kcBkAPPYUj+BXBUAVwfOYXhmLqAS8ES0vdzDwHmNIi1TZs8gJJN4UlBdN3pjwUugUmu45p-UiZYwabaBmV91UpfRkKbNRnxpI5wyeNL7osmxpC0lujt3hICT7SFxbJkCqpbsH-milfKVXMVA4LqJhQPnPC3KATG26fVIxbXjbNInXFjizcIrGpBuKluo+7JQsFyVankaOpopSUtQJlKAzQZpA7ZinPlSNJsswpYwKAsqBhS4BuYJQQ0lOE+qImV3stPEB1JagWB4oHsaCAzGUyMFs6Mir0CQaETpBp88sf5ComjQkkw5cODVG-rrggxX2mcsJXWbxzYFkM7sO7z5AIzuDDSVSapDjLFzC0rtLifflPKCTLyxFW8sovtA1TGK+i4Fon2RzVy4gK2vnXZjkz70R9Cc8GYguhn+Ls5ik2bQ32aMDzamBcMst1XsFbAYasZolpnySn02skZbRpPNVBldLy08ZvwEXYIzGlkUR80sf0MLARM5fH0jQY8GLgEk7dWALUBo31ydjPNIy6vr4sznBLc5haTRrXX7nxpXaJOF0Hfm3wBASbAQGO2KAUBSzFwgRn2B7NoyzjC0mS8tpKC64OAy0kY0EHktJW0ZIV1U9RfCtqW-zHgylJjRpDoA0IC6UC5OZMtZXUoOVq8fobjPhK6qYaxq8JtS2IB0tzobS5QH0w0Kf9zoGjVCEUsO9qLHer3qNcA7XaS0a9Wa+lcgumXsr5llTKgYKsSXzT4ShM2GtZz3XNzj2mwDta2UGQNpiDNgKMVETnWoAap+4BoFfR0c1R4KJiBqTEBgcF+gdYYpla7D8G5rONjSQklBqpkbjqWaIHea2FcNh6PAd7eQUAJJtldqBKkNUD7qgr+AHVMGjTnaon1+hXsF7SHg3j6La8NfQa0sddHz0sJDHWBsUX8B6XYhTBoFARbqAHG3rHgEXkze3C2AlqpgZacEAZU2BBTjteNgEnzMC3gmk4M+Dkx-AOMnswINyeWeEDeSvDZNMs2RLAArgCI1ZxCn0fVtJzmp9TcFMp2TwaTaqQQCwOnCoqkAUpQ0jUdtX6Ec4xh8JaC1sKF4n0rLhVx8TstCqwhWbmsUmsTpcC8Nag0540xVPbY8AooLp3FaQAoNPm1RZNi-rQXoIBnCaUBpu45YXYvxe8L9CC4gHqv0JIg5-Mdezd3yPHB0sWfRvU23xxGlliYJErVTXX8Wxc4CECogA+pzTDbLgBcA3THrahYAmopO+NNFzi5-EXVxO59Dtop3S8kRdurIw0mMmRcetZYmhVbOBjfAtdpY-De8hI2brSwoe9QSbtgctgXSHWFXR4DLmhg2AwAjOCbD83Y6rvC-WPe7w6t0hXN0o+3pREcw+ZsDIUaFRSveiCQXGVziHvaCM2p0hzPXbqYqL+QjQ4DORNJzk5N5-ieUehwjhax07RLpI96PTsHKBixojIHUPjgiDzwj50gZknYHisCFUq4nTACXKSE2ghzIuLqnbPGKcR5ysqtwOSekcHyqeqWFwvBhyl4PfAMLWAHOFbhkDZ0EIKgUOThDjAewOdHdbA0AAGgOKwSD4mNQQgriwLr2KPklHS5VWY6oPJUC3A6m80KXm5KBB1QyyiJ-2zKZpt6Eq6PsHxnMD+VzNKgZZHuFLyAwDaNpAg3HXrbpHYpGlIx+vkVaO3vtwedSrqRiCDbZFWFevu2p-QZh6LRdNsMyXlCpKn0dMrgT+ifTISEMvYbp7wIuvYIS0sk1GlRVyHu8O++LUcvKBCfTOoAAaC7bYQbzrKFnvA6nfKJ-SB62wzkKiM+nzZCI-k9HAhbAwIhfEDQqs5J7IHHz4PT19G5+f02TzWA0oVz60jc7fxxz7IHgAUP+W7GFi-qEFQiW4GuBlhK7fIo5xMdYRnymn7ATs-EHdja5AqigDfIM8WcwACdAZLpxi40CjP8g-BSZxcIxeohfRTsswUM5iFMBmnnZ0l2Dh8w01zQFLyYYgpO1BEqQ2Ca6xztgaax5iTgTig7u8fPOerfLtwOqHBQbaml-GY9sTVJrzjVA-GCWhccyTKAWwpQGcP5DyEg6LjPfSJ7ns3QbI7Iebdbo4+RoER5QlBA4vHWkC7Nbtz8q+RQGzO83hAogPXLYDIjJAzJDW2oFa-rb6stWvVMOwNWIbqgXeLm+fGrQuo95OcqD5lEVpfUuLoAJnW0BgtgaM40oXuycBwGkCLU5b+lmrU3PTf0QTqtgSV38JzeJ19XUGfyC-GTfzCznyNIt5m5EBptYQdrwtxm5LeGhdSRoNEq28G37LZycC6K9MNgZwwJj7boTiasduBkDQp8AdoBUa0IjYAJgewBC9kWRHeZjTgwjDDwyru7AGLwGCeDBzjBeTjWll1s+G0XWv7zAVlIXi-WwM6tD3RRyiA0BuANybD+Pd4+g2lmfwRkAACz-vzJKM7hGRnRBNgSz8gH1UfnqkuzJw0W9J-iatd+bPGRTkKjeH2OL5W64+WSAnFiMx3-jdQPXBIyfTGtSAK6ZdPG6IC9hgxSb2ZYV1TfI0gU8gX585KpAzNottQJTi0WWpryHnBbgMoR53uVNsuRgfhmAQKCDQTrVwlwE+Pzy1B2q7NpRmFS2WJWKpzgXvO9pny4VH8A46dktskAIByroBK84MUEBVX-5KjDXi4EmlUAqPOmeFEaGNEkOYG-51Hi4DFhApVAloiKJO6daEezFQucT+UxbBSqXX-GMAr6+kZmdP5xQbzyoCtHqtCaITuINkAEJg2UgtQKonTxcBPkovPERCvJdlXpB0Lp+QJg2UUqiBKd2zqANwhUSCR7llvRjx4Jbmqzdm+evN-LYT1KDvt0+dGky4aniNPIYIIPH0ihBbNknoO4XHgzIz0gwR4xENJbxc-giaXyxrF+gxRc6jewsMnp0wHW+50n0O34Z7DdwI6wCX7-Il1oeEF0utCZgo71S5gCrebvG3xly3Pu8VCCJMnbkAsGe-YLjgYdJNm94veDvxi-owZIErlmMa4iDHh92a9+L-elAlY+WRXri3qig7Y6pH+Wv4CBeWxdnehCfn5xba0C8JMoHvc1ERvnTmoH6+-JwvakUoZAfEyRaKClBEwzgBAAg0R9yyPKVXFsPDC23Cl-E9nyAMUgwBlB0esPqoT4EAqcX+P3Xh0dl1GhS-Vo6BrXiu5kBBBo6FcfJza7YSMR3tzly0zPkDchB8oY6o4AO7ZcVF5Cz4G8HQ+-nkPuXyNO33kFiDW-qKL8EJ+pUWo8eVOX7yvaqXIDBB35lV2MPiPODQlNSbv2LrJW99ttVA6oW2BdVvsRFCQ6NWoFQS+2VNxW7heb2dhgn2+7IsLnTGUAWBtY+gUfNzDL9HfZ7S-a2Ld1AF1gwQhcnX9oDKENC1+hc9fyAAAFYm-oHXb-Ri0Ad+7M5f4tXtgH+wAMWeUJwMP+2zwYDYffjImsMBCBcI+jOPCr4GB+W+GejF2AMVwAQs1KwzX9Y4crYtBAjeVFb-oZ9oa2K3eKPoHozjYJ65z-5CGq32tKdj5-yy+X-CG1HBhBV22BhdSLUEBMIA1ioLJ5CkA8LAniCQ4rhIDXACDMPhOiYLiqxWupTtYplQE7IwhiuVbjWgr+gyO+y5kCAEWyCcEvoByb02fimQZgpeBQAC+BBn6y4+GFHz5Fo32n56XySAIMQGgVdKZYIWlBIYQJAXGFsxcij4k4BE27HkhSS8TgO6wBAMaMXR1UtnGUDvaRkPrDFqgkCkBC+YPgKBEQiEENzbE+aDnirGNRiqTaEnrnzinWU3KwCUusvkK5sA8+IUCqstQGZom0QgOgay0TlmtZBArroeQtginoR4l2ZgR8ZC+7phSCiE+-nI6muLXmpzdIGnvAglcrUGIisBQilYA5AMQQAhKAYiGRChgXgIThXwkQRNC+Q5tt-CTgHlo8yIgV6JjRtgSXshwmAHlDO7JGngBuApQgyKyCJGzoF-ZWggkAqDQAJPCryT+Jhn-ijEJoIiCOeNgn-CxBaQSKBt6z6pRzxMbTCQ6VC6xhrxvkKDBoxZ49okkJtSYAI-oiM3qjlQ4G0jDba2wTYLZ7AgnTH3SLgN8rl5DAytgUx1AAzFm6pO68DQwL6erkoaswpFAkzDy9FN5TSM6Hip6qMdaoQx2UArksyEO+YJQKF+pcmQ79OMwLRa7Mn7uMRIg-ihgyWYz2jwCggc2s+CRgv4AzIHc0nHTyI42dlX5csEoDDz0u5FiOygE9gEjyEimnJ8F7E0lLJSIU3JgnybohXHTxwwQwdkq7EHIf3zisECCAoNiSIvUDWKWDqXJJQlFH+y50QZLoToCzSEzjyUlmPUBwwhoFqCscWISUDVYLIVyysAyofACsoaIXchqhuoJdCD0RIUQBKhtZMuAugTcsXhscFUtECz6FRBaGGg9sKDhGh9oQ7BmhtXmwC6hspHGi3eg3hkClObHM9yCQRoMxxCc2QibTSM9QFqHmhbAPsSeALNEXi74dEDh5L+2oYmHIAMKKBw80UQD0rPc34vAANcGuhITNcskEuJCYioSrjRkWgD1gICKAvrT3OxWjWHsAnuGfi7E2RGYDeCebvRgpcAoOlwphh4ruDmSeXMlwYAqXHh7jAh-lFjzaw4dCDx0cdHHJThwIPdafUrkBf4mA0uPvzuKzvCaEyAOkixQEmZWLRa9K6GL2CcOo5gzTUgTim+auKh8gTRI+iocgqySVhngrPcg+hrr4qJaA5yRBGuqwZXhL6ilAxgGuhsb-q2xuMSVGGuq0ZUaX8rRq9ciuGiZkioWsEDAko2hjw6kv4YmogsAoDTxyOgZtdwZhDvH+E86TnDyEyg0EYuoygfIRQB4A2auR6KcCajYBpmYhhmaSG2ZvlbAh3okzwCgoQV0Ds8gllzxeczZAJaLWv3OQhukqzBKCEBnItKGyQEGiOy1ARdFPp8e3Eczx8RdIc86VcjdHGHehJIVUTDg2RAtiXyVtq5LeMDtnzhyegTOvDm2fnMVrmMpIaSHayqPIBz+MInHA42RncKpHEhlWAZGwAREDiH3katnqrwknkb6KGcdIjJx5QyKIFwzAwXD5xhcTzv4QnMeIO75xcvPglGjEuIcZz0eZAZJ5n4ZcE8HbUkdHUAAAz9aIRR0nKRFIQFnFlxRcUfi4IP41+olztUECgVyIcA3HABDcc9KNzMkE3NqRTcqlH-hzcMgg5F+R77EJzfc0IGFFERUADmyPExrgWz-YPbC7jSMDWippHs91rZjmeMFJgH2UQROYaLcy3AOSw8DouBYjhaZgSa6RMAHjwrcgPBSC2w5hudxv82nAxGF0t3P1RIG3KifSu4T3Cjxo8+jlACY8euB4DVhtmARDmCKpBDHPgwgGiLXRXQSkDZABPETwGOJPHRxE87Dk8o+Erip6B9QLOkBzhGzDrzrl6FRKnpK6euqrqlsFOjboUxEEWdj+6-2NTFR6-clME7guYShLzBKpDCgiA-GHRiBIRuq3b8AmpM-RthYePajiAM+HLQ2crCihawsGgAixIsKLIaj+ogaKSjBougLizTkBLEizEsh3GSyQAKmFQDrwbaHAYUwEtlgAaAyANSxqY9kFlis4uXvAB1i-dlqQ4gqIGZ7w2a9kaBgAOADFCV29TPUxfA0Gg2QpssjMQARew0rVKwAMdllqGgAgNCRPkchIHjwshLIpgqxuRm4AqYmsbM6wAhLLrGks5LNiyhwT5GnGGSNLP7b6MXwILE0kGntfhgSVIPtRJA1JCfpxA77s0S1AyKJ2jKuYHhXC-O-AEbHeAzUACEiAXsQuAJsc+KxouADYJ7DNE4gR9STgyAGyxRcCcXLHJxSLIphR4HyMoQZxWcQXo5xOsSSyNo5LB3Fp4TeGNDWxypuEzAQLigmjTIabM0RLQicXCwKxyLHiiioXiNSBbwUIJ8jfIAMYThjM+oP5A7x2sUSwHx+sSpiyIrAA8haA1sV2iawwgFQTjkrdFqzlxl8ZoCispPlTTTcQQChSRE16v3Emxp8AICUEnKp27keYQDFC64lNJETLkLMK3HRAYdC2Dte+QG2zxKMLEnHPxSsaKhpxZqGRjDs0AGY76K0QEAkTgucaAnksQKM5LBMLZvsA0sXaMjLxY2gPIziUkzK5AtgQ4OiBto16mfhCxQeLwlBIZQHQBAwruCWgEU+hIbgsAxuPwHYOyNC+gli4QJB4kEA8rjh8ypVPX4McT8EMxdAtRF35LorrvibfUTDLAiWYuJEiDeJuxACS9sgTAEmuQQSS1gjQ3ifyyaEceIazGOkbiopcqyJOqTtk10S9znAZMIwjvBswWbgW47gIsGZmRDPtGkxK0UXD44DYMtF0ka0YHAeam0SOzD0VVntFNogYvyJIgi9DMB5ABKr2Yo0aYKfgZg8+PVTJUjVKYkgAuwEAA")); })() /***/ }), /***/ "./src/js/built-temp/base-de.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-de.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5QCSAdmNMYgA7wBeAdAEtSYFgFdYvWGAAmY2YPhgAbhU4sZ8FlrAAleNGikx5AMZaANGDHIwyQdM2DtbALKJop4s51yzxMABpUmQAI2dEWGE2QWRkeHIwAGsQrgAbOgSlADEKeLZeeQTPTgAzUq1+SAtwQkgZQU8KGQAZZyTGSAB5csFeRTSMxIARRtNmsABaMAAJRUSkxBYWOFl5e2l7RJLyeEFQrQBCatqiNNIWDBp6ToBtWIwAXWAAZSoAUQBBVwB9T9RUD8mK5PgBxd4AXwA9HRYOQPFC4BR4D8uJgURhBKV+JjSrcoQ9HgAdFisdicHgCYR2MSGRzydwlHxsLBM0xJaTKBLhDSWWQoBxgXLkfJgRASEKRRrzaTFBCDWBWA6IcgHBzwaRiDTJEI8mVgADuCU0LH4JLa8AquwUSiwBoAPysvAgWFY4BrBBgdch0plEkbyCaTUK8jolrI9mwZuKuLAsKEACdiTRWGxgWJgF5cAYqChLQopOKVTNeRBpBB2QWCYguMViAD7xvgtgAqlwMPDNNAwKVdoIrA0lE5tGBGV5mdZtUYNnWvBGfELEKFyIIkjoDiUMlrPUcScNEDawAA5RBeXvo9ikA2kYhpdNsTSJYI+jK0BwJxVitLd8Vzx+jrQsHYBBPU-A1BHIVY5HnEdsiXFc1zYBIjXVcg2GQe1DGLAA1BJMUMURBGdAcPG7aDB35Up7USA4WAAN6iDAXT0AwjBMcw2A3Utyh0ZBaVWLUZDAOg0Q0eYlHFUoI0SW5QkeLUtBkNIiOIHRAhVBB8Tkw4SQAITLITwMg+lF1VXixlUthBJgnJQwfAVpAOZAyx0NJSOLF5YG4DJ+WWGyewSRidGFUVJMjJZ-2stysMvQ9wLSLtmMCXYpQuHQtFgd1LLNFgjwkXgh0jMBWRQeJywMMAAHVGmgHR7QORIKLHbxayi9z-Lg5dV18RRivgB0nWIZiQt8BIwAARgADhUYpx3gE0dBaeAuTvJdlMtBJTRLThysraQACt5ubMAlpW0R4DEJRPjMhxDC8FdYArUh-1BeBE2TJRez2fgwH3bsjAVIcVPYLwLh7ajM1gQT1wMLwE1KRjpB2l1Dl+pZTwCANgwzbI+2gbN4DSZBntpMBClKBNBh3EMRR0LBtBXQKB166C3q0Uoy2-MVQnWq02EWZY4B+pg5yooDdiwImE3rT1zsuoUtQ5aIdBawpJyEmREFUNhoGcITI1tfMlFcQDbXgdIllgHSWBJSqtAfeRNe7LMc2QiDQjgKwEmISmoPkAAtMQOyxKTJMPQpoA-XhlK8YKkCh3YyLGzyIrLNLJlwyDoh+v6wAOTQJA1Ad5AFlZNRYBBEgirJbAo7RLvdNg201hBu0KOV2AJjIWGt2THmwigQJ8-8U40NPtC04kWFuZS4CnwgwFuAAqR40fIJJJlcZ74BJBfl9XlsWAODstCkJQ7YwLhFYQXfCH3sBD+P3YWDPsBPhfxBb1zNgXcJuAE15DbNgd8V5VT2JXJQ7xnDukGFqemt8ID33eN2Qs+Q8Am2IIkU6f8EGL1Acg70aCghLkJmAAAZGAd4DNMTwFRgPeE-EVKwBjgELA9NKG8jAAAKTEMpMAAAmAADEInKe9QGH0rnAe0kggaQIruBdkaQ4Hf3JNwPgQgRCABNyQA8H8knxLPWAU8+6vQthXHI19lbTyhHJEkIsAg8jFErZQe1pIcNgAopISjLh51hj7BGoF1YzUgmIWOYBDqaCqqQUJRVm6RCUNvRqYYOSXUGDoUeGsxpUPcURTxyi1ZcnIHRHiFcWGVD0QY+eIDV6ZyZEdEc6lKA6GsjMBI4poClGaAkOBOgAAUAhdI-QacxGccxeRoRqloAAlLg++qAxC8GjkoHpForSyL6gNEow07IuKfqfBAthUBuUkGAKEYBlIbBlDoV670TTTOAYg0BnkKAAE9N4k27DOa5SZNApEbjM-B0D5RpFCCqJQQzTYM3mMonpAARsZazQSFKwlCd+vBP5pChKMZ0hVEj6EMMYMw7MMjsj5MGF48B5qBPiJgu5YjV4YMSCNCuzyeBALpWAVACQOkiiWOYApG5arkG6WwHpudf53jSEmBGPi+yZWKvmYqEhDi0qqQ-bUygBgVWpeQXuUIKl6Lkr9RQtVnZd3TKsLorLMwEvMJPEkXCjoLCWPZNWao4Toh7mAOxednCOKiM431FEADCIQ+IsAcM8+8qg0gaqZkE6AITVJfh8vQzcCYgJqwyLVKy2oDj9HgEmowKgczZApTIEF7JDS9WQHRDALCXGBt6lkjxXivSRhzr1QsvpHpKF0KQRAMhnJcGKvsWUP4xBSU0LYKguxBikEmLpftgYyZphPF4LNu5p5yTaCwJI3Y7XT31fcvBq9bgmDSAAXiGrALg0AcBQihA0JogZ+DjGQASFgGqEBQhmEeAA7O8bCvBsKPB6KUPoAwhhGufTIfE57KkPNPeeq9j1b33qhHCQm5xX0hGsVCJgLwACKLBTBcC4agREFI+DCEeH2gdQ64PkDSAhk9i9kPXrQw+g03H+C7BkA0WAOH33kEo2o-opBHgvDEMueaAnGPMf+UhpjKGb13ofZiWAxBpNCYw6QD2XARMcDExox4hGUnlXoGAHpoIHAzGk5M+TLH75nuUxxtTUINNadCDp2Aen8aGao1SUg1jzihChM5d0In3UrCOdEaAUJdBfGGK4d4-BkAyEeHMNIUk1S2AADsNVqjIqx8G9F6saIYyAtQIQ1CIHWvTZZGAEDqOcAdzgMCdBaAOrQJwF6QASOQCgnRS23gSL1uomnjDQAitAUYGrHydCqLVuomhTCxDLOStE8JfPkE6BYcbRAE29FoE104E2yC0hm50Doy2+v2CphcaAnRXAHbqOEB7KxOigle0QOEggPtPbwJAKgVWF41bO5AZw4Hw0IE6ApDQr3IBRHiKdheRA0rkvGBoT4GBSCdFUIkA2iRyVJGhj9qAtBMcXBkNAHHeOgcE7AAAHloAAPkzPAUngDyeQDSq4Zwhc6f44oMJHwiR+fiFh7duotAJeF1p7j4XiQWfs7ly6HnaUZgEqFwzkXRPIZk+l0QWgWuTAK-p1ARnKuDfc6N1ANK+5nk68t3rnw07MA89oI783Svmds7AFQD1PPapY5py8MglBOhM5D9T6ArOnt28gPYSXBh34yCpxoaA4fB5R+T-L1ntho-wFD3HhPZ2iAXcgmntXBhs+R6B0zyvceAhM7z63Avnua+A6gNbmvLBQeEHB31tczzu-Nb615UInQqCfF0jzrHcJSBpE6G8XQ33E9lgYEDz4LQQeJ9hmozo7wXhBuD94BGnQWyuBPzMYPaJzCdfeO8XQA+IAQmq8t+ozZSD6WWMUVHE2DgGQnQww3+YANS0QiOzgi+nQ6kE6h46S48n0EMnMOQ8cJgBgxwH+tQSeiAzgJs4gABRAFszyK+XcPW0ukAC+Au2AQOwomUGoBU-elB2gBooIKAtBUAR4F0FU4qiOpYlwhMpAHWQOcKj4cCHAFWFAigiOCaMm-GDgnQ+gChDAlBsQXAg8LwWs8AGAHBnQTAPog84kzBEOpArKLwNq8AoyW+UAowBgvBZqFWYAlqaSlhxwlBT64wgYO6HQQOYGEGWGY0owMGHO5ABSiOqkaQXAM6Sw0ARynBkAWWOWew+WhWjBRwiOzkmgukpBQOUCP8Zq2szO4ok25Akwyku6rOiOy4V4gqlUKo4alwK+FA5AzyVgJCjUHgmYZqRkQkgaBstgukg2BogqZySwGA02tgbkE6RwlC5AAYBwCBXkY85w2gGcxQ0QYACSsgV4LArWESQamCIQyBjUvUG4FY7w5AHMmCcC7hEO02XIuh8Q2Cy+QOLxfuVRlBDxOhHBLxh8SQLAuxl+R8nOzqrcJ0y0hMA+Q+UADQacExRBUAoQEgvmn2eA4+dQpAvhUAXQgQPOmgGQsObxdEJQFB5eUApgvKUJ2+oQMmscJhaOUA8Ru2QOWYH4Y2ieicXk9eXBF0cAGkPOicGonQgc5A9o7IRWTBPOWAsAiBqxCRcpaUb8KwBaZJjJX+hJ8A7BKOQO3qKE9YVgBoXRwMUM2AiesaBosSRJUAVpEkL8ew9MZ+V4bYHY3W3ekALpnYFURsO4DJaOJAV4gQ8AzyPIDQlw7pgQ1EBUq09pvpr+YAMJRA6hmh2hTx8Alxg2LJ+A5JSOQBCRBhGhlA8wFQo2u2ieCANwdBBaUGuWXqhhRZWQD4BspqAw-JmeOA8ZiZUAyZlAWhjxHBUmpg5ghgiJv2eZZBrZyxfR9ZUQjZPOFZNhkAoBvq4qbZhkJgESXKS+J8wMPZs5lAVQZ2XZkAaZLQ-aMgcE-2GBo5UAUQzCCRoBxOXca55q0giwV8j085sIIBycz5U5OoywFY4azofUbkwYWMlQnZlBWO4GIofZPx8QoBmpN5uZ95nWJJ9JPi-8QUfpE+35QOukTh0Eussc5AJEBE5EaSf5EUZyGFlkVagwcAAA-FBfcamRwUhR6BcBmUNuiTmXecAcSaSSyL4uAoFF+ZWbYV0S0HRaNC2X-K+X1KSahLAB2UeZQVyRpPoAAI5iAQTzQoUCUJHcG0jcmORaAMSgQSWLnDDrD8T8jyV3j1zAQaR8hpgUT5EwKtphgvxiBGiAKHlg6UHzQOBBkhl6ztaGXjlA6B6NwHAZAYDKIAKPi4UrawwgFikkqHg9LuC0iTCTKxUIDMxDjyAFLxg6DxTfifjbHH5BrWC2BLiFB0nZSsV9ZCmwBhWhntbQAhosCwXORRAXBRVoUxUeAujxU6F5ImDil7rpGpVEBdimAgFdG9HJqFQLiFVaATWJWCFsBhxkpTkqhCSFCZWzXFY-SEV+wKDbAqQJAsXqUQ4j5dXhl4oahdDYkYljkjVQCbUgkJVTWnWsiMGqE5mLUgG9S-XbXKIGgbkSTwEHWpzLonUzVA2SBWytV1AVCRAYF4p-amCDX958XqlGU-nEzrFZxDWJ5g1A62VgCcCrBFSlrY3WhYClDQwipM5Y0JzwCs6TKGmEyxzdjAVDT3iuKgHEzCQVzIw6AVY-SXELFrKKkjhUSdHdjRo+SXEZChDhrQBYFBWmHaDwWnmxCKFE3+kk0EU6HPyvyrmwDJVmmg3pU00lzOqrD9EjBgHiCE4Ti200WcC0QXUOAVhpCyURhIRvhwDGFkrUXajbFkDDwQRLGpzyl62D6UFiBcAtzwBSZxAqi5HZnE3RW8kNwPyZ1xJ3HqnU1QBzBjS6zagURiFdK7VujgIRi1yOxdGEmvzuB3ishdxIxjVqX619YZ2uldisCL5yD42QFm0T5F0enthendi4x7AlCb5qn+lV2QDYSao2SMrbJJB0R-5sCAlzi0T5TSAQWuj1Wl1j0VRfR9C0iljlRsDTDR6L6XCs7+xyh0TWjDgSQv2LhdSISETOiHBM6Igf0YDs6gFNyL3daTCB6hDJCu0mR6Y6C7DOjdgZiEUJRMgig9h6yQUPV3akScUIC9X9XDWCVQAyXCVYV204X4lO22HyAh2bLsAFqJCxo+RfIfRWZM7jBaiwDs5pj0zigrqcPOCTKoyXUmQNA3WkX3XD11ARY9USCUMQTIDUMJGfD8ReDaCCDBjnEfhxlU0sNLnyAlCGOJScOYLFqExKB8MRJtICNCMVyiO2DiPyBqy1TSOyNEWOyJ0kWqTkDKNp0Q5qNBoSCsBHbgZrYZSaMig6OdB6N3Q1h7DGMGCMNmOO2eAgHyD03SCIDJJYagMi30xBxgC6TTFoi0jsx2Spi1y9RpNGlfyRjkz2j0yoyuB0TYpXW6xKCL6SBTp1jpM2NaDhNv6UE8yXQGbQHQBHikCwCHznAkoyApNA5LNzjC3SAP2sjP0IAg2V0WM1NzMrgVzdhX3CTGSi3vHjT8I9h9gHPS3o0kN1BPURXhkT2DZT0E2bNcHSLRy3WzDLMj5l4nP5M03GoOE5icCci71a6wDgvFVh3VMSNFGdQIQ6AFKRgcyYXWRcSjbbj0w-Q103XahFRogqjtENRgAGb2gVBii2DnE9RKDv2Daf2Q2OM7UYCTCeVArCoQNwCcvQPgPLis5M4Su7yCPbxgCmDRTQAXoADknzYklwyrrOq+oIED4wmg7OAA1GAP7IoJZHgJVAmKNm-ClKtLSPwFK+QKzjK3q0oAq6RCq2q2GRgJq1fjfrq9vKzngNGC-U03YFw1kGAM40oGrBbJIMYfa9K2wLKxEm64YB68Gc9d66zjvlQP6-q3gKwAUvuWsocpEPmkKuGSuM6Mov+NkL-Y+ImGMgm46xjUQKYClAgO4OvGNrPYAd9ZACZWNF22uGWfxXme8AJkfgJqOCqCO8w1C1ADZsg9WLYAbCyCuL0OwiePkDnC7YLNIEYLoaceyyKxcNA58KEEkFGXAsK1A+zvriFKLoIbRFZnYbVCg35EzgeJgpaBekSJAG5uhhaQkPwEZpSBov+2ANyTKX+5AD8DzEsEkP+6zt4AkBA4gOzvTAkPqFfZMoFRE6Q92+QOLaQG0BsChVvbTaXKsF7QIj4pLgVIGJaM4JcjO0R6Lf+CR-R-lMWFrneAo0nSsWlKG-DkpMDDw8bLO2NGrHKIET3K21ACJJoe2xSisGQLAPUeMk0b219TQ5ALgzTuOCKB0r5sJLQIWcW-NbCRY+Sx+2XGsE+9U-9oZ94MZ8syIEUf-YkLofaWwFi6uDc15cWNkBDLCLsF44No2EA9i-zM6g5WEvNFEgELVPY25IIfyJdGhIEhgBgNiCurYOKkuHACYLwODD+-J0edgUmZcHob25AJ691V0AUm5PnZ9VAMTFyO4FwJ0LpP1DoRvX1rVMSrALpHpQlN1akza3YLO8YcHr5lwKW+YPkIuaW3G03V6EiFwKyoKcs3EqN855FUDlG2AINpZzzhbOYK4LwlEL6M9uG9aLG+WwN3ULsAUrVF0IzBXKlITTiZ9-ucojYGuOV-iY0GtPAHo75h94oF9-89vhKJMFDxlFCt4poCU-6rN+WcIXWlYcmJ0DMC2MMJMC8EwiCt24KEsFCG0ud25OYPt+N9p4u29N8koI9xjzmSp3EsOz21AFz4TsZHJ8w8hUJfSed2NfAF1nAGc+bBc4uUtGjUoDUzGG0koHi10892cFEkkL1+WKMJg7D1AL-jIKYmNGj4ILGs-NT86gkC8OBLAF4MT5oJ0KWwzHgOSuqIaMXsQEN1Z1QRIOSsNzPVAGk9Y5k+rxSWYc8v78Xvr5AMEATBb4ngq0gOQFH9PUNXD9AG07a6UKpLROd4IDwD2k7wXxqFLjmZnw4F4F1s8v-nkbRBVZ797wp1QUvhQGPjmXxkocs9KbsD1kd2KT77MwkYr2IDzjX3OgaF9oTFPonlfOQLd0DjvUvqX-Ps8ksJ0EGmvz7waN4NaZAHbIIPWDzgh+yCvl4EaeQLwDzlqOMOcJ33QSqDzKQE9u80QMiQd5cIt82BlChaYM8kn3Ty9bYQVQggS2O6SZwj52cdsLwHESUDACVwlsB2uqXU4j4us8VafGLzwAQDgynxHMlDlIDXBMoN5Q7DwAMpHdfEBoJbOSSIDwhBCShPYOfzErk5DsO2dELAW4CIB+gjDZgfbm0BMB9knKFPsXmpydBxoXqfZCcnYA8DIc+yaAIIIzwbMG8-ufgc2G7CnIIWjJbsrIPkHCCNAwwYwDzASI9JaA-CSZNIKiBZoo8-uUtAlDGzkl38KjM4JCTSAhoXwGoeAEsyiDxNvuKFDICtCoDz13iTOPwYTFwHqk303aMgUH1CAvNzgWEH3lqDWZJBCBUeXYBfxkDs59mvideujUTzIlHoFwbgvQBeKdAjwCYGAeCRKGv8oAgJLwURG+7t91SrBT0t1iPy+p64FUFoREicIFIxYpPCuv6TTLwVFBthIqOKkNCw0lKPAW6geWb4cAzCALBenfQ0F9Z8hqJVZpr0vzwNHe5ZeYCvihhMsVc85eYGgL-iMBbg1A5gNIKYBMBrhNw64dhGkGPC7cRAbCLcJeFQA3h7wy4dvRuHfDNBzAAABrSDgR5JR4Inmchvg+IyAEoUDhBCAjgQO+d4JmCoAthsgyI6zBQJ+i0BBGJgZ+LACu7lheacwryFEEjqmBGh5teeinDJFRBEI+JSIIgAsLsQDAxAqAEiHv4F0ARt5eeq9DchYBI8HwharDBXCxhA+kAb+gEiaimwxQfnRpoeAzBMF3U3cSNkz34aSx0QlAdgHrHw6MkuyfWAzCTHMAjC2uc9ftqgF+bzIZQPA4UZ4FFEx9JRTEQ8AQSAjhgmUqLf+kpRQAVh-OSQelpaPLbSAek7QNID9H9jgRhKhouQByHgB4d4yjgzeoTDN5ZATRlw3TroxiFJiNogotMdZztEF8HRDpRwL1BdF2kaY+QVFoqIyjwgVRx3JcJLEUBWhL6TYU0PGMHz2DE8gJcPGojkGWjjRPXRoKEwmFMd+YBscsToCjFWjAoVA9UmBwMCCCa8UeOcXHkkHaNqhMAUvt1QIKj8dOUAEgsjgVJdwCoihPIWNy9ZyCaeUQyAFG2P6ExMoX-EYZADrZMdVQ9tUduqTWGPY2RLfCuDQU6AH9K40gorFEHDJtCy4WGYVNIPyA7ioAopGavlwAgsB7QbYhwQRwmwSgEBaQawpSLNF6chiv4L3iZCSLwAWKieeYQaGsJ49nAKEFYXUG8CaBKJrJddIoEbD951xQ-eZhXC-5Zk2uLfOALAWf7q51xRpFlKQAWYoURJGhcSXCJm7rcw+AHaTHjxbBz5zG+YsUen1obtBoAniHJHWCkhrs2OI7UNjIEHh01nAhQDUc3RYhYMdJ7IUNtWAKBsNZKpoB1pKwlbDBTq7LBrp-RvoGTeeYzGyIMRjhJBwIu6QmFYG2Icsz2rOTBkNG0nBT4At7UVqzlDZ+SpOVceGib1pB2hLWgDVAM-wcCbEZOkEbiBUFbGJ8O20QQcsOUWbLMsQ9QmPv5JhpMdAuQKQTHMKow70+uPEsdv23eD18fezYWMPnUgBLQOS7PCPmFTP63hMIQ3HUPHx6zrjoCrSaelyCoAYTQBrxLkbhISLrSdsm0nnC1CIG7iiA40H4GdLC6ngdsTvI5E9yfY6Aopn9d4PQHhCoddg5AJKdFL0muJHp0DZKKvW5TIBPpPktMIM0kaXS3pGRD4ZADOn8IfgWOLkM8l4qfDuQRDNFs9PdSQzEgM4AYszlPaf1nxDbCKMDOgaBJNwLEpQA5OZZkxqxLkNgHWJ7iuTXJAQrblgPxnQMPJ8E6yPmlUgkz2cTsIUPW25A0UZw-4XKrrWkFnSAAzD8BEgRRwaFUJwr9NZyBB3gTAI8HzK9RKR4AkwbUrQnRbyxtUlCF6Z-HEiJBrIhM7kG+OMldETWpCEPqkkSDFS+w9JZtm5MdYsyuAQbdenjLva+sg0MwPmaG21QRtjuMbW6cYUCQMcT2d7XQJrNBm9Q1Yp3eNihMq7TMcC8wrgF0NZF1d4qNhXiSwFq5QBLZr4sZFYEzhDwxoFCdaX-mXyqT22BY8Ua9BKCUCwAOI0wHiIyiEiRGYAQAEmEbcpnKwW7lVF1xyebngXKLmQAMZr0s2fOwbnqSfu14rEQPI7nkB8Rw8vuQPKHnXcR5CYyAIaJqlt8UKhcnUlABeAGNQ+ZFPQHVKyCJAKEKcX0O+MTFqSY+zc8-tiNxFryu5O8zeTiO3lEjm+aIaAod22l1AT5CRfnKSTvlCgEwZkJ+X1kWr2im5y89uZ3Irgbz+5f8-qMPM7JVckSZ4ibnVy8wUckx4RN4o2KyDzlSAGw0-nQQhgdI0g9MCJNrxvDiBLgHZRPCELSB147eEgTrNhBaDN885JCjmNd2-HgLhsQs1UPLOhmILG5Gk4HLQPxhGFAo4g1QWSx9nczTWSgNMCHOtDhyy2Kc+waPLFwiLxQ5YcRZPOnmmzb50guRQvJumGKI2VMsOA+zyBbFa2j-HRbYDBkycTZkM1sR2PZ6cAIghgyxafKnn+KzZVmIMj2jMGyKRR8ixeatzukuL4CbightsTghmQb6viooFEsbKDI4uBSNcD2mbEjjdR7YvedDHIAdhjAGgeDneLMViKTpNQyeTXO0B1yfh9imPprXFChBixV8plIEmyWLFhGY0KNjmiEglzG2KVNYP4EKAZB1QgSvUbsISD8Jwlu0rUJ0oNxMt7hCSl+eKL6XSZBlVgYZRbK8WThK4qom5E0m1AzK3xDsBZbwjEpbQZgdEUJr2gYHEAUICASpW-nXH4xlIPaHqSc1EUWLWlkACRYv0Ch7AhgdixJQ4rhHXcsQFiC4GWCmDgFYV-2aQNjxUjIBpYssVQLYHyI+cvQ+1HQGkzJX-KEyifVIFdM2UCSwgLHW+TEvpUch4l3SxFTH0ziRhpAvAFCILJfGzLpORQN3DSv1Hh8fQV0yYM4De6cFTRbSiJc+D1Csqekz4NEByoRWHKFFvK6AmTEFUPKxk4M8VanL3kdyQVzSiFaAr6zQqz5F8oxuNIBFf4dVi87+iVIyaOrpAwyoougxPoYwrlxYZWb12jkeLpOP9a0GqAiQzBKYCMPkEYHs5vd5u0qJqB4HHDaBwGkDZKShMTy6UB0jKpiZ6v-A9IAALJMHxbEBOVzqnpeKPdUh8vV44mIGwHN4B44V8AH6MGq0A8cw1TsiNQAxTSXI0gboR7JyDlBmEU1JYtNS1FoR8yzVaEmgbt0Am7iv84K-OT8LtWQA+0xbeBc-Pnkx8t1+oYZRmBbCYJjxAouulZFsAABOQRJG07ASrE+pgSfpCo3UHq1VQaINJVCrWaCXVe68UW+q1HDK2Eo0JuKeodIbE-IaYG9XeoHQPqcypQLaYqqhWTyANY0HpFNEETfrIWf6hRQBu9XbI0wGGmDTIAlWAqvIJKUFYmNXUFqz5XkR+dqpw2LyH5d4nxI6sbU-Q7YfkKNUoF2ZBI+VHvEcckCPouBDSEEDWL1Fik+j3F+1XqBUTXDlilKdGu8aRr3n2BaA48x2tRpfWTzRl9gKBQxqQUKLIFIFAVXsFMgvsw4+kXWEnCrgqFkxfnR-npq8BwIVN86vcXgTMSUaEFlocxWuudUbrsgsChqAZqSXDYgtxYw2PaQU2uNRmcmnQKSvGIuJPFOSmLcdHQbPxKE7WcYnBvVJbBMyUQpDQFqC1Oqf1NahRYFtVARb5UUWx9qlqmLtB4tWW7xKLLGijK4aScWwOlsa01dLgOWzegYJoaFadNxWxID0n4STA4IXgLDbusM2LyKtAy1jREmGV1azkDWtgAlua2ChktixFbV1vW1NaMAfWvrHmtTH+bhtcCqzGWsm2VqQtSKqAMcoW3hIKoHTQmCOC6mNI7wGSlllmPCBtpzJE6YrSsrRyoT05E+eEBwCtV+af1G61wPaFSSxASt2G2bakySAFQxRqi85fcq8V7VSYT23FEwgB7ahGOcAX+ge0UA-QQuiQWIPEESD8A6dOa8vqwKwA0bRpmo27THy6wCjHAOgArLNC0wERwgbcMVQzD6jlVaw6kNEFwI-BFK-IZYbsLzqYySQdsYoGhM-Fc2g66gRkBVZpt80s6qEeERQIsHQEHLGN0+JRRZ31D67al5OudRrqIADplAVJGQKiEGyHyvNaVLTTarAU6bH+cqwKLPJN3I7t8qO82PuW9XY6RlBG7UH7obJajBm6u2lRDi0B4RnkPwLDttmRm8SCSyYrMqNIoW7AqFr0BmHEit0YARpKtZhp7qG0RLS9igdPZECGyB7Qt5AyFKotr3wArARDZprZFpjNruQDCEClfQT3Hktd8MwbIYEIVe6V1uu7TcqpIQxpsV8KpvXduBxwrZQvqdvUbtIS+pTNggN+NlIARYAjtqjPCBprO1z74q-KIhjuu82urOgmcUMhqANVmbN98+k1doGQDD68FMAHbM8n0DpCcJUANIUdXhkokEgPwCKD8HdQQ7l1FtYudsmJ0OqTQc8gpnTTGpotlZ58otWhyzVfSsha9cqFbExWXEaZHqiZvht70qJlZfq0QAGvGUsAg5k4JcD7EuBEqwY1Yd6c4T+7I8MA4rR1q5M8iBFtRpFcimREdiUrQgHMQYGcmf5GRPYl4ezsrKTXjqqtzUHwHzNRjTB9wKtNA4sWBgCdLp90twHDqWU06nm4Ggg0c0qXHlgDgYH4KdziTu70xXfM7vXJ-LK52ZrOVDR9NwM+TmpESfA4cw1CowSDycjHdsmPVgadwWcSDdetvWIoB0qdO3UAf6ggGgFnmxYfNvklb0qASaZWekcriaz6aPiO5UkMpTTBrF+NS8PEHlat9uGkYbsD0n2imUxQ3YJGY7BEC29kuVGaAJMllFCQ30PISmZfQcABADwc40WpphZ4ebrlpnW-iLimPIA+D7s1nKgBeAFspI7RsUNaHmOqgKiMgKwFMetCNAxQvs5Kbsbzj7G7A28TWb6imOcNHo3VJI4nraqpG7Dams-VSP7Ztb0IFkbIxY0fJnHopumv4z4c8PDiAjzzbIYQdRgqqWV1oUWTC1sBhzDVEemUrsHEMeG72A6ATPZvM1OatMlwDQ831sPO7+SFGxYQ-KX15MlqcIrbcdEwN0ahgms6jiZDYWNrvQqq5+KjHQDxDtRPGtmIY0LllyBNwYMGUob53Ew0gTBPmT9DTyNkpDXMVahREk1w1J0smhrQpuVmsglN5YYk+uNJM-AgVQdT4ztPv2L6EgUIOE+GlsVuGaaY0PiOWFRW7oCaLkIE5-QrltqwTd7CE59ChOWHgjcxG5jWjrRMJDwwQMuEKiVhgwOwdERsJwd9F8gu9NzNRcgHHRSQ9FOQKRSKqxPJSi2a+ntTaHfYRxSo7Me0JglgAaGmZErEk28ed1Qxa5iwjpVCTtOjDcz0U5s2kE1n+G-TFhoI0Qao6oNUzQtLUIGsSCTLCzRquZS1D8DrpXlzxmw3WfsOLrwDQ5Z9VPrgNLz2ELYf2C8GvmuGaTqBopvdOf3u94BoAsxBGG7DKzvD0ATWYEdeaox9wM4Q+sfWHOi6QND8KI-TAvV9QZAuwEWkPqqi5TCobAbwwFOsjKz-zM1JQMqyoDKtQ2YcN7nNAWjgEQBiAxyRZL7BlT9Te8w02PPIDwyQlhcsJbAfnrWKsZMS0vrGJQPO00DUEB6Z4YovRL1V1FyZPef9P9mnzDkITW+Yoh4o2IhKPak2TYBlCKhjFu9r8tP1i7uzLY0NgJcsJIReg+aTzeDIKVq7az6Qn4DUrqWCRGl5YKA-MB+AbKyL-bTs7sqUD7LDzdF482OI6FoWEBl5rsO6egadm7zvh0mQ+ZyFPmYWiQeFieeVnEAPlEbfQCpCkvxz66e7eztxoDzbLSEGwcKMaoJMZEDTS540yCvhn0r8aiwjVWjzGjWmA91l1hvRfX0jgu0eVhyxeYrDOXlZBV2+e5fBNeWYTQZ-y7vsy2XBD9Oi7UJiAW1tWpzJvLmM2TGYLmNKS5i1ZXB+AnbKTSBtDWWorXTbbRtJ4q7ZYXD2XzziAq8y5a1YzXIIHFvs4+bRgvmhz0EI9XtVSRbWW1NAf7IlI8vs5ED2BirnhaXMFHwDJk6TINt6l6csjo28bfNdovLX0DdlngpVY2s1XPD31hqz6aatHNUY5LI6-uwc7Ky+r2yVxc4GchdnbrPYQHYEn5QD7CJogEwCeba0jWIchpl64RamumWvrI2y7eWoxgLW8xS1yxiVZPNrX0LTliqMrIht7WdwAZogyQdLgJdnL72+UPdP3oEMXtaQNgBTDMjX1cbBE4pnSwIkJcUIg1hcMTc0sgGORbAqmwkXDF-G9ibO1s8zZWsjg2bjl6q5zc8Ow74dNOyG8lPMO82uLTnIXWLfWQTI2AEuzge+DfLCaVY8wd8wKoNsaiudoplK09a0tfRzYLXTI32FhYtmirJtwG92BeaIBygA5wpugeDBc28YXcYmHIHtt4HOLB13OKpEP6fgnYP4UIIsvz2cJhlh0NGiugphUwvQ6enDi2NRisWFwFhWpR3vBjHtIYydNKG902JOFT6AQI2VgFMRWwzBqVrSxxJl6AHnDBFWpsr3+uQAHUjd1kw5yuvDwH28EALsrJSALSplT7MWFoA0PAWrWRUa6EgFtaNHg2FYbVoEh5lKAWtYuGdrSD6PWRoLWVZVkGgQs301Yx9+NtWcdb5Fz7MQVYMrN42-IXQcQxg9BD4h0gtrI-OptmkBkX3Mbk4p7tfXcq9Q4+8wOBzoDVirYQGPSO2GkFCTQQBR3Wf0STEDElWZGzfQEvYbrOLCxLhEiqCUONtvtuHzgtA4MuSBjiWFNYZRMBtoi0sxoAslgOUK4cgwyAnqMB+zjWN4BYGfozWLQIHBjj16Dm4BjoF41qxidsAX+joC0PyA5DZOpQPjHZLtnP6qBTWePbzh423KheTw9nO7AP0I4QRhg7dZJu2rSAbDyO73xIIcO5H7obsDw8TstJL+pSemWkBmow1BoqMT4IaI0LQBO9TZYnIdXlLk1dY7BmjklwcZZow29jKe2lzeZg5v9wEyfRiVQp6cBWEE3avwTiS45GYS9qAPXq2mQBPggwLAPEGcDX9BUE9LlKeGH5dqZEg2BqAhrkdID-SDup3UfnmJiVI864kexcH0gyBWQJC5QEfnkQ5JW0c3TACAv04ahEA53X5k70tHRm2Je89-glH3B79rkJRamV+1gCTAs6YQlrPPo6eQA9K58lyN+M3P49hgd6uM3M6R3N6oAjdLURRERTgvXEIanjlM65SSpY4SoDwFHW+n-gDO+DZyBOnYYuagJlJSwa0sOwZ1wD0AdG90-JT2NPEkYG0eyOpewEllVnV44lTci56lmPKLpdyKZIqhmd-fUgEfyFFQAtMgrqALoGNSeg2xAK1ZTmRKLP9tCIzsIo1khWbmVXju6QzocVcDU-jpqb5ZtHZ3iiYXjgLopq85iZO26riX2tqF1dSgSgUww11qN6IdpzELpzYoLbemzgAgqPJxO3YqXSDlpqr78GyPRzaAfgbeBImIMXGiukc14SNwLlbidBHmfeRl5AHAxchE3Ked0gAFZRwSbsPnhRYDZv5cog29Wm7jfuIMoqeqN+6SEQFuU8bLlbKD0MGPjQCpvc3gwEuEg63Nh2dtkvjSCVRVIhMclCsEKlfpWuPwzc-7FIDHEfQ0OMTl4DXAniuVd+0QmMiq1jvdY6PRhptdnchBGjFha8F-HFmdh2iXMZWzEXZBogZAcY6Gdmh3dm8I0Yb9kRS8ItxErwK+LhmMXDIoB03n79c6zr-faM43EsXhCqFKF5BGscbjmPxMLWdLeX3ImAO+5+BwfFytL7YBfMGCyuEyQS3LaQC5DLcswZaIF-PV65GheW0AF5qFIaAYAV3xzUrdypNebvDwb8n5RFXo-gIrALWxJIkFxdGd26-gQ8KgAqA4qxenEPrk6NddATSBNOV9yh54AfvzgQHzD7+4mL-u43gHzrOMUmLpvwPnLqDzy-TfofppiHgD6h9M+skf3DspD86rC7f80gqeqz-dpenHRbPuH3t8kbODjExAOtr3cvbPkGYMYELmbVC8gAwvFawX2OHKfOsK7JSwqMO82rBh5RJnSEfngqDJl6w7AtaUpMs8aBdX1a-8MSLwYZ3qktAYPENHfxqZ6wWkURU018b05bwC7-d8zVtX2Ohfb9pu4Pej1UXIXUOqFu2OvAKhBw+7FEATgLPFQ6BhmpXH4zzD1hl3ZQIoXL7dSB0JiiAbNRiipz74BeeR-bAeIMHewbNl9MfSnfF1ZZzEtaOtdMAVx6JibXEB34FM53zukwhpHSUbCKjyhU6sng9oTmsQgJgxehXTUnnGPw-+k2ImeK7ggFO0-rNzr0cgEmFJLAQbAaZnx8a4UW9c99nwf1+tyS9rVVRCPp+oWihhxBU7hB4-UQGQdEQofBW6d-PSu66w-RxXOIAGebe-qg9BvMzdj968VsvQypksbSAC7M-kAZPqw2V-NqqRT5SGzc7pveTo-F5FrK1kHfoZyBd0GQWwNZEiLq-8T7yGcbD8l85zdvC1WdgUzCl2ef1ykDAENDx5YZPPYP1419A4C6A4kZH-tnbKe8JRwIjqeOttk69pV13xciGP0h+gGTxoJastTMF4BvIYcIuQWxRAM5e-HwPvuJGZLGgpAv5HIJ9jqawzlKTQF1MzbjMzS6eOCbAVwR+TT9xdBwZEXqEtAqzKIDgfKhH86F9IU+oAZYESdAG7kF9Lxrvpr1wwrWs91u8vnrlz5x+8+q0y6AWYP8aQ3Lme5TRWzlNvCCY0Y3Yfy8GDxWYV3gPETP179Y0HII5jZelgkGcguBpA-smYH+dOr8rM7L9Vv7zh4jkBsJvfhIqMholKBq5G0uXcP8LU5DZg1E1el1YawXRHtLSEGKrWRTewloEhtIcpg2BNgtgNcykOi0M4Ldg5xNToVghAhUC2C9RvzzsgFdizDdakdDoQ3MSytihZcAMN3B3+FXoYKdmLwM5CUAF3NrrOqGrmYgt2GUEoCdm3-kHxj+ZruOi+Yerkj5ZIfMDixgw9UKi6zSvpEKoNsjyqxquIKSjwYqInZltB6M8ZqMxs0HrhcD6gAsnbL0URRIoGBIogR6riBQENcyCmipt2AZQfMO1L2+dQBqgYA2gEXzqu89DvR2B1FpwE9O3AWizOB9gS6CWgFQByDaOiSGBY0UzlgJ6ucaZiujaAxAPkBCQBSKr5rg5YIEgCyS0NmiuIGAYTD-guLFDgYwVgfK7qkDhgTQ5EgAiArS+89Furfc9DrP4fQsACyhuBDqC9BqimgNUHDoNOpn4hMT7NGTX0RoFQ5JoZQQTRjMi-gkGy0K-mVwJBbQSGZ5eb-lhSjESwPzR+Q0ED7ATossMr6YU-XooALQ9Mg0EagLKA3wwCf8DkHA6dKtKr40RQZcCsAHSM-5MqmqhWBRs+AjygE0RbozYc+m6vNBTisLr1BnBemKQDqaP3nWLwEHBldA3QmUDR6ceDHnKbwofVJzBXM93kVAGcLiL1w7AewMiTeI4xHwBFid-k+iVeEgOQzwAmnI0QIkjgf2wduY-ufANEEhHCTnAXoLWR0MIvCd7iiRITz5VauIXAiosVIc5KBIwfDNbJe6ED+5y6E0IIi3qNgnMoohZ6iMYvotunh4a69XBmxfM+IaAr1Ou0hJ5Q0TRJQRHS0+AXxey1TBM4FQKImvhWA5-v0Zvwu+KjDE8EkMSF96HqmsHJ6HKAf68+RgAvKQUo1kVidUMoe6Tcs-1N4jI0EpHNR6+bbK04vIpwqG7LqXTqkxbcykIsD-MieFloRKfBJ2JawnoD4JbMcYboQRhOZAwHLcjimty8+POGoyp8i5L1wuyXvG0hZ8x-AQqgS5ArcqW8S3F3LPQ9UrXxQAcgetxUuNYeBjhhyILc5uauBFty1OE0n1RaMI-thS5MH4qeDYkEotNSn8EItwBbwXIG2ClCAajQYHAlHvJJDoU4fABSuVvouRroAQJJooBUnkuGThhHvAD6CBoIvKbhgapJ6LhPvMuEHhS0BfiJhc4HJo7hF4dmH7hXIHBCRYZnoEQ0Qu4T7wcQlcF1zsCM-kqKMwCfDmRDoB7sgCsAVEkKa8Ac7vkDPhXAOBFdAfCkDgxObSDBHHEP4R2zwAvPM9iyS4-rJypIl4V2ouELANnjdcQOB47ZhxEeYSki7pDSIVY3UERHiAQaHEIQKWgPaAKO60KxJUKOXBkB2Yj4iC6yilPLSA8R2PNkBrGHwcNhrGgSKATIkfLB8FCRVPGRK28VfIgA18kEEfgDSHvLsFS2POEpy9k23mpzd8R3EbDRcAXLyG5ApnPpEHmH4k0p0E2ZjIrl86QCaa56nptdY36UADpaDYelsIoxUcVub6U+pinkTqWiOnUDjW3PJABYGEzB5GQA+QRFHeGRzhSaskTJqFGBR6mrnogm+mrPwzGEUd9bzk4OsQDPYJhikSpRe4iXwOB9YeVFl8eQSubDu11otwnOqGj7xxRhbMUDYRzYXsJwiHUa2HkAeAPySPQXYCkHAaIlg-C7mJ3DfIgR4Qv-wZAJwRgDrWlzPfrs2FYAaAgWP4RcD9UjILNiOMe-JtFaA7DM5reIJjEwyJ800fACzR7pMdxhGk0f6RJC2vLAC680fOKKG8xvFXBmhweCpHEAD0WnwsAZ5OyAO8CRM7wJArvGJTaRXvK9rPhhgLmEpwPJIkS6OL9toqOSgxDoTOALgBDFZ4jjPjS5hXfgvw8893ACF32b9nhF7hkMRjGwAIaFwAjSt9hiogOc5BOEkxw3NEyLkVMffb1qyBrPyXiy3MERg8EPKQCI8MPOKI8x-AaEh8x-3CjxIAb0ezFjO2MXpwGE1oU4oig7yJcaIh8kgwGtRkELowSgQsUmgzKEUNIRI8uPjHo2R-pGiDugEvCNxKI0vNASdYwNAryr29TGfZq8PvAs4kY80C7pRIrEMjJPivup+j+6tpjmTJ6tSqnr1610nkTUIdegHEN6MUVrp7OBuqCToCaci8Zt+oQMYBQ6gXpAAK6RZvHbm+kAMnEyAI0nw6OUgjkYZbExSDoBmYWGC6xWYJEdagsi39tqA9mVBt+y7ApQLByAc6mKMbaYb6Lpj6Y5AJBzQcGoLBzwcaXEhyQArOFQB6YoAqagXMAouhzs4PSALIOIKkMqiS02SCSjlgbsq5K2w9sA5wagRpELq3eOYG6jwg7CDWj9MFdnFxr08sAJxfsdNM3GwcTOJ5jvW7QE6yQAUHAK4Dx-7EPGIcyHHOJBY30jZiwAdmKECzxsohvGJsYqD0STCHcLOa+uvUHUr1gGkNTDBEXhDICTArgmGgRoN9AM4jgU3jl6hmc4P07ZBgyKGg7Ec4HiwBq6Nti4MmTcb+z-sTOJ4TNAcmi-FvxvdrACDxCHLujIcyCc0BE8CQAUggJBOGqDLGm8SwCAmzIhoDuolaA3FFEN8T+wtx-7G3GIg9SjIAKsxgCRpdxhfJIg2ASYrSB9x78WwmfxHCSPGrG5sLehYOGHN6AaENppQCwmirOwEsoYCY6wkgF7OTLwArEkJCnxQ0JTJzg2CcdCBANgDwB3gsiXfEKJqGO5iPx3mF3HhoniB4AfO6KHomsJ7CcPHIcR4KuDRQICZrBhSnqF0AZMk4IKgq8zCKt59Q2CZMRpIDZtjAOa+NNISdGsCrIgmoHKINiHQmfjaYroa5GbCoIxDJKECEksMISIk8oZ0AwukEt-pToFuHU5c0GBL85ck0hJcB6ydEeQRVo3vgRHdwPOHuTtYsyROSOMN3hbq0xOZGlB6yZHKbSc+OwAAiZ+qNrWC2ux3uzymUIQH0DwAzoeqyyhwOIqE8syiEsAmx2aHpHmcRhJcBWaCROwQ1aB9n6IWR7nGZzbJFvICqbilwJ4KfAjuv9hg8pQmGZA+GAKTwccQRN-j4c7+BCBAAA")); })() /***/ }), /***/ "./src/js/built-temp/base-en.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-en.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYPaGERgMKeMIBGpAK6wwkmTwA2AEx4A7DGABmiAMawKPeEKPC5pZIgRhYxCfvJJYfDcI2qwrcqX2noTW1SHQENJyRArWUATzB9K1ZlOjBmNlNhJ1JoIUR3TR1NHgRYsDpWPPUtMGtWLkgAGnBCSHVoBPJVABlNAGtGSAB5HUL9HkRlMAARQQ6vAFowAGEWeQB3YuIa+ABCRuaiZVItGnoBgG0eZAwAXWAAZSoAUQBBAFkAfRfUVA+ASTeLwA4k8AL4AejosHIiGg4LgFHgHwqWA+GB4Oi46J053BV1uAB0NGl2Nw+AJcqJxFJZPJFCoqto9IZjBlzIhLNZbPZHM4bG4PF4fH4AkEwCEwhFYUFSglkEkUiSMgZfDkPGFChpivBSuVKmLalwiQBVVjHMCqHU8ABu8HIYp5YGcAEcZKYEF4lUIYrIAOTKSbCjDONUbeyaOwOKnICSVMAyDRHfS9eOsYOIS1mfjQdjwLwyVhgH0yci6AxGcgxI0aF5mKOW6yeXQUVIsdhCTRS6CmBpFv0BsAsW12bP6CYSAt9ktllmVkfbeDyR0NuOLKbHX3yHQULDyRDSORO0yycj+OuyDDEXvF-2TIcScx6psq7J1iTnSQ3ApFWy1XGfnYiXuUhzRvAd73nZAeFoeJSCOchcibCpNHkYtSy9MAwy2HlkDARYlisSRNAkZxVF7YN4Hgdw40kZQ3Vg+Cj2gE8z3nYVVBkfwLQxHQ7So+QEngxChUQFDW3SIQsMjeBcPMaB+WgHQ4mXGTKmrKhiEEaMJF4mwSwyABGAAObxfAonIbQkZJbWUIQAAoAHVNP0LZmFkNRhGUPlVDiXpKMLYsFBkaA4m3UsyBLaAdgASiC+Q-l9XCEmJWA8lgUoM0ZMANHgNZYI0BACrwsANL431KSOeQkjyHLVEAjRUBLFzpWqR0xBjURLO9WRMjPLNpNSVLPAmY4JFtBCBTWZythYXJVHUVxjgmXQXH06BezjMDJgmZij38SzeoCeccrWUpLRs0h2C8XTYDW6sPxue4htUEacrAF5VGtNLMFMf8biJc5lEEWB-vcQhzgAKhuaZEHIFM3lIS0iUIMBIeh41EyubUvAcxAYjNFDoGR8GobADGgagj0wHuRBbXa0xiYgNH3vm4o3GW7tYFcLQibBpnSYIqDqmY448AcngQzAAAyMAnhy8gMBiHZ3qx6owrAOzfBkS9YliqivAlAApGRSgAJgABgt6sUeZwWxRFjQ8AR5wwC6eAbN5m3SZeANSDWIQOvMHQSx5Utzp1S7xNJXh+EAE3JAHg-gHwSBuBQYegAxOR9LJ1gXoQaA-qJP5hFwgs84dKN6fFHRCsFOxKwdfhWGCrY8lTPPY3kZJYXkY4uPdu04jWSjenqwHgdBr3oZmEY+KK2phPiFgAyorB7PgLEuBqNhJM2cVJDgAxkmgaLGdR0nGo4Dhj41qYrXGgaXTdOA8yjiQpJEENoR4QxX9hpAwDglSIuauQUGRBBPmfZmLxBoUDiMgRG78HAu3pGoCBg5aaxlgnAKBAtjiFAwCWfcyRt6FiwPLGwLY7IEQ0AQ7OIYWLwHhG2CQgQOBMMtMSYoMRezdj-k2BBzhT583PtDD6C12aTFgPjDIEovS4OhqgO0YVGxcSuMKW0MYCr2VKtpTy3k4jkATEIHwi5pGYR1MoGKCj3oCM4lsQRuwk4pxBgDT8GktJVy0pdKiqRGE7ELjWDQMRpA+XiG3ZK39FAIF7AlXC5ZLKlE0NaOCtovARkdHKZACZuF1xsAgeUS5+DOGtCYPKExJjQG1mvRaxI66pT8itPMkgDAphQvwZKgRLQwlqZhZBEgzQWVohvMAAAhVh2dzAuXgMmcUh5kDKWcL7BQpBYbXRbI6YOA5fAZlqGPT8PQNC9ALuCT8AMXGTxJtDc4JZlAAF5iBc1YNAHA4JwRtDmFwOUeINClIQOCAAEgAOQAOxPAAGocHBTcYYoxxiTBmO0CgqhcS3Mufza5tyHlPJeW86EljSBfKsKc8Efx7gAEVwisENqgZh6QOB8BuAAJVWaoP84I0U2JueQe5jzYDPNeeCNYwquCkQWkS5A4JyB0tJIy+4MhJBiuKKinl6LRGoyxXygVbz0T2AVRK8ERgD4+BlZwGOj1GGwUtBrIExQAUKuiiq5Qarmbct5TiwVuriD6u+UanM0qlRklIKco4khwTWBftK6EeRoDKH5McOETLXhTDeE8LgyBVA3ABTqQs0biRxoQE6tOycJ6QGaKCJoRAMChomIwAgLQjgZiCAMLorLm2VpaHaXw5ABhPHIN2-YKNID2FkPJTw0AZilO6QMBog6WiWjGNYZQ9x4AVB6RQAY9QO1ECqSMaCdaDgtBHcFSo0ABj9G3S0KCAY3BnrwJAN4c6h1ERvQmgYoyn1HvtK+4kAwqBlpRhWw9kBvxagQAMAon7h1XGwHgetQ7RoruSqoF4GBSADFGsA5Dwg0OfqILQJDxxVDQFQ+h+9AAeWgAA+LDRHci4cvUQUabxNByHgKRjDb0hZsZw+hxjUBaAsY0GxkjuGKPUZqKx-OvG8NQFGgCk8HH72YYiqWTAfHD34YU5FJTUBKM0dU-RjTKMmM5SmHjXTkBMMvTiOp2TkBaDmZiKJsjemJM2aM-Z7syHoD3DIJQAY5HvN0ao2e-jkBuP5xeJ4Qj46-MUAYBRyLpgqO4SCzMkLYXNNQEM9F1QQmRPxYCxRwzVGtjkeS9AVL9nBNSdMIFiTlWAOECA0OvyzmD0magKlSQf6XgfvC5E3wygBhLCoEyro9mJiJagC8Lo-7wumDHOwXt9wlhec0jXAY9wAV-HTgt7LMAKj+G26gF4SwnjNYgKCctHbWgyVIKMmqdo734GA64dKsGoB3wQWAcFL23BQZQr4AYQIQGOkPsNI4b1zAJiTCmCpK09Ihj2Ld5oEXRIaDeFRGQnWWjVRiAMVAcbCeXsgJE1jX3IA0O5m6KDJ0gTiAGEC3KYBGcxig81LQEcMCjZYNzo4vOydVMVXmBaAwmVi+KED+UCWaZ0yZ-ev4suAtk58RoYCTV4AApQn+zSQgvFCHV34rXewycfORYc-o97YU-3hdMWYyLqZ2nGlBhwyhWBUBhPmmwVPs0e-rjGgtuwoPWEtKMwn963gZgkJIOI5GOQjvIPMIGRyqNQcVX7bs5BcbkC1FobbFBKy9miQNQ3YBegaD9u4cwRj3Cxr9uKdwaEFC+H9naZWYOlxRkhy9aHY0AfmhbKoavjavAuV8B1dWmyTaTHKHaEw4QN5QfkgrmMbsbItoHpMfTK-MH0w3zqDGlfq8DGP1XtY7hD8jbR0QdQI0MCvfg1AaJRhf1wcO6Qa3UBBgAGl7OWjJDgb3p3xAHYCDZ5D+Ajb3pLCQE6j2bB49r3pdC+49rhZfywwzaQCS6Hyq6HYhiLgS6mCEHha7hPSVCvRU5d7UzPSUEAE6iLjwDs5U7Fwn55RTQ2BgDFwoAWikDtqHalK5SmgdwDDgplI5wiHhZuRrCmjpiZjbZkB5SyEwjyFSGKG-7wAhKaCMivaQDxZ5QaFaGeAQJXZgCtYtDqJy777iB9oDof5dbQafYDDK5miUCyz9obrhYIBnD3rpyiTJBeDmCWFuEt6r7wD0w4CmHmFEDBGwDy7hHiDyr6B9R45DofbJDbbWEdQuEJZ5j2beFYEACaJ4qQWREgs0CglE9enEfUWySSKuHo9Qh60RUAB+rKfhKg+kqRR6xQGR96zBFIreX+VE+RUIAwHRAR84Y+U46EZRkRzRZOyUhQ5AyA8R9MoBjB3RRA6RVONCyxuEgBi4gOXhYx96LwLsgUVSFxPUawaU84hx3Ilc4gAA-FEcLmURsbUrYRuvYSZo4X0VABMa-OYA8eAYdgUeMf4cCfwKCQNGEREW8cBhgZQJLq6BLHkb8Wkb0VTjgalG4U-OiaoKMT4VAMUTINlJRIEcUu6JgWXtSOyKwEkMpD3mYhAk0YBmTnmMUIYURMYQXpiT0U4TAfzlgGADydofwQ4ZmPoETiGG+BXpoeKKWAgsFLHnIG-lOJhHceyBZBgBoL2C2EtukPOGOEvsoOyS1mTgQbAOKXyY-nsRLFyIDgKdsdiUQZzAqUYTofQe0HrlpBsNssQXuAOO1ryTofODyBLBaPAHoCbPIF9HRKYFvMTpEI4Pgo6RaddmTqGRKTzDgYuIMN-s-q6UKVALaeGdaT6TKferojmXaUIBBJIFUUxODvwJGaWCGOwIYAdJaLGcoLAFFIiUOjdPpLifaN2ccFsd1m6SAQ9n9oPhoFWQMGSfXCYFSYdGqCICOS7HZORtufAFRrFFND-FsFpFXnuF9CoMQhIBkvWA9lvDQl0naKIKya1D3rQf3mAONIEOaNPlGHUWULQOwPaFRP4KjhycBohmUT0JTFOf8VTjBdjKUWvvVuFtKcuT1KaU3qUBBJhvCdSJwSIK4B1LeRIA2PwN+W4Mmd3N2EeAgsOI6HQMDGKJhi2LuHCR+ZhpRccOBZacBmXL7vKsgNYJWHBTsczqzgJQgGboduhfetmi7P-ANFzmvKkJ2BIIFHGnAN4CTnmPMRBUOgWHIaYH8AVL4BxBOYuS6dOaWZAOTH4CmMoTHlllKUtgMD7JUiwt1OSexJxI4G3E2fGN2OuXDg5amMZUIIsEFtCMcBgFRuuBoJuNGXAL4HEC3nBNdOWKyFFORvCDFVoDRrokZSoWyPuOEu4IFduAmAbDXlGEYIWPaJeAJBQPLKAhDhEFRJmWYWThGhOgwQgA6SsWJTOVAINQcf1WCa5b6feiuUpQ8WKCIJVKAqguGbuQkAmLADRuYIFXQOWNFMrOcRpT1FcUdeSbcUVCCW2frq8QscBr1UsHIGNcNbZWNfEHIEuTNT1EpfoOqQtWAEtRKCtegmtbIAVFtfwDtbQHtQddceSSdZqedUUrwZGIIDdQZVerCNAA9bAKZbunCvxE9dZfBaNumSsW9QwGhW5Z9eSVheecICME7uYBUC-CjbkHyDDadakNnIFIjSaYeMUGjXxc+omT4ITECqQLAPZcmBiW9g4eJfeuLfIKFdLV4DECQbJVTaNYkGAf9dvmAAZKbPOMrSmKMiLfaNorxVmcBnWToaZTFRZbUs9QCXZd2Fsp6WGSYZTdNVAB4gbtSBUYtRLaAjbegseS5NvI0sUGUNKM+dtUoB5EREyFlSBdAFvApbGIpStGsCXoeIFfDeYNFb4AVdMrMrSANCHTzLlSlbFVRjsORoqlRvXeQDRuRgkNavoFpdAHcr6BXRgL6FRmNhNrlW3QeWAAANTTAwgYB4ArrJCGDqj-yIBcBN0t0j3xCd3d293907Z7ZUDD2IJUZ4AKYeRM1xpcTZL9k8AKigKYZA1aDL0N1gCt2ILr2Y2b2aEe1aD91zZ73ggj2H1cG-J2i9wgUFTxruASjVT+BeBNn9mp0r1DktBSgIDR5wx2hO1U4s55SoN+RoHgnYlPDi73qENR04PoNe3VlQC2rDhR0iAxh5BBBu0aDiDXiYVtw7T8Cdh0TWoiCF011uRuHtZV35VxWgIiBKgaxOQnmalYXkJ2i+5P0iDEDOA6B3IEiQBaq4rgiCHDzkBcCBoxzqN2Cwy7hqOQAfC0R5C9DqNlZ8S5WICHmINEAiW4M-akCIUzbFlQByWklsMQOJhxDIMPhrAdLBRGC4QuMvZhADTkVbzUEQ6cVvTqxw5YxUyRMISW3dXAblBy4dXEhkCwC575685E3y1QBPBAUJapB5NuQU0a3e2QArlPzujQmAWuGoQlEtK0WwjCDVPOBUS1PUWpnZQS0PirCs3lWVFgBom2AN55TqwiCJ0KCwixhNgDzuBOCwhbAt70yZM3ZW0xFaCK6y0tC93QCDDjQk5wX0XwDR6sADAIy2heYMGGCjLx3en3qz0zJ7h8heb1XE4GAyT8Tbb1U6WAtaJ1MOG+CpQIBvPgL8lQAsowtqnwtC6HZQO3NxlX3O0Avn1YsKj2YlIvbwCDCgMwvOmIsDwIQSCshgOO1oWCDXkvCWCkuL7kuTkgGMvDIWBGDzC0vsuLleGkAYDVra4yBEk1nCuitgAArGhTD2YYtwtoIIuQC4sovKtosOFBNkNIGjV8i-iwy4P0FgEDCfGTV-HM0IAoFwCm1uii0FRE49xWQ9wKBm267hbw7jL9kzDOCWW9rMPcuwNVRxoaDywKshvyz3BhguT3A8CWjjFAyFjVShvPlPn2Y-VxEvOO0wHvWDaXQxBfN+swH5vpvdzkCFvZujVlvAJz30votX1mJU6oANtczmtDrQDRvEAoFq0ITbadv-V4wvZONQCCQUBP74Ey3YF5GkH9NWVUOzv2a0R073q2ttstBq2+xrDLkEpbvhbNzkAEv3qNQHsZGDYxB5CjbnuCuHbHnAFQBSPgbhaWPJjvpn0XqHYJijukSg4wiE63XPrvNBBqsQtwX6AxAd3wBKuMjgqwzjDaKylHTkbtbg3xDgckJfT2hpSp32YFPtYoGwMDAKawDtZ4BIeaHp7hYFCkCnADlTk7q5gStQD3AMeyZEDe5YAS55Acf8Y7oVg-QgsUD8c8dyY5R-AFJKLlsZaeADAGQCAFKAK0bSfCcgYFLQASexaMeQD6ZycyRCBAIuVdZQDajIBqd2gafrgKrO12S0CmzRSsfTnHwNZbUqD1bZb7NC0Nrb6CwKgICK0Yg-zgNwXWQ6hUAjWQDX5P3BfKAUeHZyg+eTvedgFEnhbG00dn6JgOWvzkbOC3GdC12LvqnHAs70DX4SX0Cuzb7DuQDnn+dji1LjsOEnROXxtnEUl5TFUx6DG0z+HXkyUOH0zxGadkmlhVwVFNm+JhGqBdUtEkCXQYNn5pglUGcAdczHBS3f52WLcx75EmC6uQChfPm75eG7f4c6ivbnDZZEB-D2eQB-DXfKd3f3eXdQB-Dgo3dvfKfgpPeGdQBfffeGeQB-f-cOF-AAAaN34P2WNw4W1gtAVwMgyApXUeLwoPAIxobwrsEKTwXQGszHlJYAtArdJYzgBUbwcZjj-7LQh8rgcAP8DXfxZTeh5LtP+gy386NgiAmup49W1lvHiIjHXjWJtlT0-P9nd+S29orAlbkAiKBOC1KpRUciFYr8GEEYLe-gZly0d9GAXV6NDhvl0DdHgpOL5lflyXz34v7Qkv0vsvJOC1A4GELeU0cEOkydcQBvPYko3DYoKEdoMY9+tgBvA5uvHnrlQM40MtgvxvVOoBlk37wnlvTgV9NvggcvwsXlfS0jc198fE656v-EMIkw2vIf12bn4WVefmEkqApvhvCt2YGfjZzZHvno-AegejG2VfdoBWd7WnXoNGQCyAVXnM3Mj+2OwmcFBOxFTbJOU-BXqLanZ9k7UHnth2QbC-gLmnXrtHT7hX7+JzWrxwtOuxh-lON3w-Jhnzr5j+N3WiuO96kut0eekEOOphpfev3WlgmHygOu8HpTYXLOr8d3KwFeJqE-YP-LAvoUHDutDsmkS0OANGxHBuwVXJdqunNqwA1WurLxuTmyBYECIcAKrrcXxh8Ff++-FoIQIJgkCH0hrIduFm9S9Z5KxoAbPUyT5S8KW4XGMrAHmAd0f4CObeGg1LDmAAAVgj1zScNYAvYRqo8i4FAxZkIJCanJwfrN0V61fRDr3RQ5BNem6TXQJPmUrE9+IX5MpAaVLB8MCqkgzgdwOTDCMi6ojKZPqywRaDOCEOLNq-CTDgMt0sXfVm4CSJ9Q-OowQLlHmoHhQem43DZnYKm5D8WEYhXKOgz-62Vu2NAw7DJCl6R5ymhSUnLF3zaGESarAOIFkMp6HMEAMIbsraCoCf94U83GsmUNrS0DCYRvSAAZA+ANCoQRQisETkX7qgTBcVZocnSsE10m8I4QsBKF4bV1i6EsCDm-F6EFV5w3Q+esUD64A8GhpsD4MlFtA+g9uNCHKPPUYr0AWhLYD+E-RGFxUVhmhFsEG0mE2D+ALeOgXXQbor1QurAUjocIHoyCEcTYVQFPXOFbUowQbTCHvBbwqluw8whwg0IADMHwJ8Jp19qDFOhVGIFIMF-pPD1QcbEhLszGTvMagiIQCtGlnCLw1+84TUIIGwiVxVkkwNEtLT0Yr07hV9I+hlQOEiMqMO9fbJ8LYjtCL6rga+jMIrDrQ64qpOkdYKoxMpmRteCWgoxwgh93Ob-LJjujICsBmuPPUgZACDZwVmGHOFdjqAHK9hEUUST-tLBKgJgcotkKstbzYF49X4hPH6v2n4hk9+yNGQAEmEBPcjCdGtGbUquQsGIaQKIAqiqcFTbEXWymosDpeporwOaL0Gk9yeYAe0YTydHk8quwoPqGO2VHHNqcv1LQL2CRb8hqgMscgsmElJ-FpSxojlkxwY4OiLRJPWAM6LtEOjoxNo2MZjhH6JjVRUAFjHD0zFgB0AKEXMUOnzHJ8TRxYkMZaLDE2iIxVY3KBWKiK34X8gHHmN0Q0YKo4KgBOPqaxz54M5apAdbgMFhwZcX2HrbfEVlgAZsW04KSbPkJfzqj5xMZDkP2TqFeiSaQDNYWMjPHKduxrAwsft29w5gEsHYVTr2DIAeQ4w7wzACyMBY1B8WyQcUSeIizERMBGtPsp42e7VckxPo3YSuIB7PjpearcUA-HEYsIlSDEDZPwE5EKDX+Uov4s1E0DXlrxiEnYcnQ1grBMcdnJ8RLx7GviMJpALCW-Fwlftph1E2YbAAfIBVHALAYiOELc4QTqqdoYMKDVUAWMzxRNXspeLgk-cEJjY-bvqPgKMSrezEudpAA8pZ5NS5gW6Cm0mAMItcQgcSaWG164j1R2HMvvgztCmxKJKk0oUZJKi7cuCwPPMUxJfHaTdJ-sfSW2TUnGTjwpk+MJ4GfKWS64a-cCe-yOxAxW20E1yrBMclU4nsIbfwChP9EFjtJzojEJ+1qTLRFgTwW0AE24gpUeA0SZUAOE0DNwByTedkAOFpA1SbJXWFokQDi7lhkpDzCSc+TsjtTDADE+CWhLYHY4FYbIEJvlFWGnDrJYQcwKNHFF5t5Q5YeYMkmJadSo83U0sL1MSB7UbuQ018SNNUqwBxpxw+8XiPaRN5l8okmKRm0KHnikpvPKADeJzbxTdpXk6XtjSEAYQdAOg0FttQlrhM64jUuQEIGkD2AMEygW0KnT5E10-goQQKLyOOClBMMa6cQVM3zowl3QqVAaBLWQTeBaSLYKOgGUqSpQAwddPKvyOImtSoAroDMGtNGrqkep5KGQBmAGlKS9p2kj6W-A7AFRW+JRFGVDJhGwzNSCMkqcjMwIl4JkLsOQdXWZI0tQ4eMygEblLCEyVAxMipGTKeGUyIJ0LVAndIUl0zsCIox9oNLelsD0x0mDCB3QcobBaKceMAAAE5zY0ZCiEmUpmDZ9AW7B6cpJxJGyJA1CJYA5FZmoTTZr482RkEtmg1Ch0g62YIFjxxBHZzs-ps1JMxUzIAOgaAh6JaBPTEWvsjWMZHNhBzMpWkiXL7M+kZ87Z+cxOZRGTmAYIJh8ckXrLjIGzsxRrDSQGJNGpRkwIMnGTpxM5bwhZPIQJm3DpqBUYwo0siI-B4BNVe5gxDFl4H3BsSxmVkDgb3Oimh8oAUEWgO6KwHySm5Xs7OdTjggthmx5DE2ZpO8kPNoIY0jpEfIQhBUFqrMVwMOGGR2k15BzfHHWO3kwT9Z+8pMe2IKiny2ZIcjmbfPlLO8SEEjc0I6GSA1wwgNU34WDMyS3ztBVgAaKC2qlyB5ph2KCB4W-a-yVJ-826W3Kykk0hIA0cBawhwlQKowMC+QBgvWB7wkFjEb6agsdDoKNANUrBVKVkDDIDZhCnqRZ2GSFzPJ5896aArhIZ9qFy82BfQt3iIKowXElhbJDqqRx6FXCv4jTIF7wSD5-CzaUzJZmvTRFbA3yd5RNLIKkA4dTRd7l7ihAIcOE-YeoFnhli8J7fK6evOHQwhmAjcq8fgqpxe4tmhi9ua+JeDJFV0tU2RSgviQO842yoN4ZjNIDOZpIyALeOnERDjR1F7bPjhx18UCcp6a7LscAtyUZA6AfUXudyMnDshOoxU8JMdm4T8SKqE4YKsIEQiYTlERwPKGIAQBvySJRADYM4G8WKSAeB88WP0uIXFyzim7fqMlE2FdxhWAXSYHF1GjaI64WFPNIpGfLGduRX7JWSshd5txAgepHaN0pm59KkQhkg0QMoNkjKJAzki5WMovkTL2lUy1UGYHGmnK5FEUZqim27JvkZIGSpBqsnrE5L701ywBlUgLTHEz5QSnyZMrYiY1IwWsS8GpUOW2QEFny-KDMsbjih5Z7y-oRDhiU1yWsEEzpENFgAfADlzDDOTvIvF7zM5nopMY+VJXUwp5lKwJSQuIaUxKQJKu4hSuWh2QlQvYLiacJAjdwNA0UY5WTmC4JTPJ90ulY9KTFvNVu17IBUYtfGwEGlI4EVpMUfCUx9aCnc2FrJimC4f4aIX3JcuBWzYgUUwNnGavuXS8ngnK3ptCDkDEA4g0gPZfXhZXLQMQKyMGREqUrOr7AVYN2YdnPIGy4RB2FVdCucJANFZZeSyJ6pRX-L8MPxOVd7IGCg9BgTKNleMtSHFBKQga11cispUCBQgrFWxVGAiVaRC1PCOKCMzpA4zk1cmaVY1yTFZqc1DyvNbVKIpGIg1xa71WWregShHQVaswL2tdVNqPFMaYGKmqj7pr+itqqFeyp-wlSwouXYjANFBkAz6FpagaLQrgX80x1boCVcBkKD9kv5iUn+WmoPnpwVARCpdbmqGAlTu4kMhFReFPKqc+k-ALkOHV2qGBSgjoDRDEs9A4SgEX7fuXDJ6jwKIwizEVUgHcAGRewUdF9cUvGgxBwwb5RFVeF3WBRoN1EMAE7JVkDgUN9azSJhvfUnquxqfK5nJJpU+Lr1SY23njA7XvSBJGK75q-CkW-DJYulAQfX0bwiAhV6EFhFvCci+J6FI-Xpu6tFW9zewy4ajXjF+EDhAqt7G8hWrGgTB6IWkAyJRpaClJKAzM5QMiF8DxiW186OjYMtbUqSxCBm5aNjXvVRrl1gPCWLdAqSBNgZEi40juqUUDD5wW61BXGGcCP86koMmaBMB0CEr35Q6PIBMBiDsIzNQ6A+ZX3YC2JYt8WljcYspVxa2QKihqlPMeTTNmZAExXupv+p+x3QA7Htm1R7w4TAti4EsHUnzUcS4wX7ENVC19kJas5SYmza5smBhyMpIi6Nfeh62GbSgOs6THYuNJ2yE5loF2UICtnJgbZl0lqSlxSitIL1Qy7rS5sM1kw1tDcu1WbPq1555S9VBBNpV40RkowZgjaE2EdDOBrARQaoKNCNy1VpFfEtrX8SVDtT+lFqw+YtJdjJbUKD6ztVO2C1Hq1Nvq1yBnyUp-r0ocQeADTJvwtTmiE4mABWBiCS5119PNjrlDWTLCGZ5AD4JUA+DRovFsQ52vZrFCA62eifDCuSWEHaVjawJKMDCJul2hmRiwKOhmzLkSRwZoQHzTCN+kQ1-pVgZkc4DECdBj4RuUIE1v5bgMbhSghuuMi5pSz+A7Fe0AbFK23EX4Rg7FcgiW3QyCqRGtWQGA51gBUlAg-XN4BLCDIJAxcMQMOECg9qtmvYMOlsEzAxVElVLdDWRu0C4b+aPMuTnsytK47OgHwcbRtqF7O1zZnY8zQ010QwiI95AZkWN2bJM66oXBeQBHp53th16Mc22fHKdmzak503EPeuuRCfzOtxNI9nWNj206ayLOp4chAAXJ7yZfQ1Pb4nT3FQkJ5YPxB1C4m2hNA9kBnXuFMUj40VXM2KC1sIjEQ5OE+7CV5te14zfefGlxUkoV2N0G6qAe4HgCFlO6XYX7WiNoTk39Iuuhuo4bfKP0CJEEzI0isAi5gQJg9SJUPdJM3mR7o+pC4+dBDr3eNNa+3RvfSLf2t7ERHe9wF3vwgz6Ycx08RcFDFAwjMobMZ+ckDtLMipI4YEGVOIwBP6h0OXPHfXKNbk7j+yAXkoAsG107JmF+WCMQdn0YQ0DAB-kXKBIPAH6RysUZD3P9UH7IDeYG7eknU1DyNV8CnKOV0fAGAtgOMu0CfsVJEypmMI4OMFU+EQb61khp0PlroUcLD15+0LJ3L8g1UBhzI4dTQpXn0LsDLQXA2HpzBxTbphB7bEkGKCFDwQB00gwUvj1Rg2RuU8IPlJ3xPCWkaU9nW3qmGgHQp8OV+IsDE6TNAqqpdcitQUBTysApYZkBWBMAgz48Twiw3YYWoCIJJPvVTvocD1uHr6a-DfQg21kv6SdgUioT7XKMUM9cEgQXYFJT3BC09W4nQ8VBXK01G85ynUGUrfXawtgeImiJgY+VB6quZh6SUnuWEeyKj1OAOWABj0F5qj1NDBMOC70iAMOcHGxQNET0dazdYRipHpMCjCjkWXM2CBtTtDRzFtsc5WFQAhrojigvCLNo-A611wYRpiNUL6CoC+gTSaHMZlhrk5CA1jWHT4SYZx3l63RhOsiQGwBJYDGedEx7doB72zgPqvjckhBC72OhWdQk4pliOQlAnM9kzWQxQHXV-GmIjCaAEKP4DiHSwnIsdn4hkZtxHEZQPdGMH4i6geJWe4Kdz0HIlHy95kySdVRkn9kSdu3D4A5OsOVCXJB3UsHdyRONMeoqJ5o3-Da5flYOdxAw7UaeGdHlAOx+QAHU0OJ04jToLjvAE+E8G6T1EWyN+ugjzANA8wH9USOyAPhApQgC-MCagCjHyVth+KcsO2mGApj3nXvalLgIDb69yJpYxOAVPzyqDx2eMiqZK2bHvDEwIM9qcOhS9XlnDdQ92syOjS3wuEc6bfXVGunIA7ptnYTs0VTH9FXgSnfMeYHkH5TwRyMwCbjPomnhJZ5M3sb8kHHQm8gVXu4AJPTh+Zt+lKEgE11gAR9dgEJoWfdPN7ChHwEfJZy+zQmwugikhIQp-33YGmK5Os5lwbOxmNjzZ+kdOb8OIjQj6wCgMcmaWPxwiJsWGMvpb11q4xAQDIILvGkYROCfcY0-4dEadIEeYoMc5hi4lD6EAGYNqhOZGOlHDzpZoreWaK1tja91Z-0bWcwRBHtzvTRs3ufoM10ILbZ2FZ2dvPyALFWwFGdVsoWL71AU6UbUrDAvl6EQeSqYyLzyVoinFMpzc0hZWPKnMOTZjCwVVJ3EBsLTy-ybAhdibLUw84EQOiGqXLYDA3CSc6Ue+n+QaNmc6vYCX6YE5mLPUdQOklgDKwVyaJri3FTkvwB5gBODEZaFxNQj6GdSewJwVfMuxKD3uEfMgFKByMekeYZWHZHFqYQi8SR3sAyciT6CtIybWqM2Et2sJEmuwOztybx0oD7WtHMU1AFXYxWadv+jc34xGZ5RWd+bOuJaw-OIj+ZoCFvAkbgTKwK2C9PkBrGPqVnxsXQSQ+4AAnaApI-w0dPAGiimnXjQgX0EsE+NTJMrxQRQZvubroBae1QKOlpBhF00DLJpzUjlFaYe89TbrIqF6HJP00womltyxpAdOakxzC4iPqoHFVVcq84el-VMeK5dxKuCxn2lbqi5UhHdPUKvEeHXU51u8EgIQ73DehEzlYlIx+tvrwDjJ4p9a5Kp7pmKAVmKasN3q0f7CTBprXgeA6bs-NfCNrGERAvOBhHG1wqS3IE-tdICHXy9Bl1S3FcgAnXdam+c64fK0A9Jrz9XVg7LK1K1rfLh-fyyYgjavw-yoVigv3j2ao7z+04gUkpb0JX82e5OX3GhhTpwVnLtafolRHkYjYUu2eO2sokBZn5s8gDQocyHyVQAMwX0JfJpw+ia3Dee7ZRBQFURNsDbKxOAvQUUAlNvs8AC2-ZjOYDByyJhCCdxQ0BPZVAa8c8daCXEXRWAIHKQqlHRAqtyCAdzVha3MqylEYnER2hBJWrmYe+SreQAnk4EdwYuQ6ONLA2x0tAlA9wMcFCfgmM85b5AVW9U3HAZa1VIpHLawh4DsJiLQVDZS3tVtbxdEK+ou9Idp4O8c7seFZroZbznQf48AcqCSboi1JHrEzLm9oCGxwR5SKASOaAnaATAgg7gpSXPcc4PSd0BYO0OSqXQZy9C699CFvbF5MB97nzfewnzdNXm40e3SXIQgvsH3IAF97JVABQKjTb73qB+5AHtQcdnuEo9eUQETzZBMEBdhMnUMZ7MsjAYRZWy7mqHA6xFZlSe4OEbwhBa4bUakGEVyCch+QOd2IFvDaPsMLTpU68nPv4jokcKfERewDxX0JkM7DhUaB8GSwycwA3fNW2kRCa0O6suhQ2ow6SvDlLIrD4TPnAGAABWBh2w9vuFReHImGTk7M4eiPh4BUGIOI-4f3oLYwjvh0Dp+534uWARU1po7yJf3bJDhK3nBGUBiadQK6LhE-O4TAOwuAALRAi4Ruw5jm0JY4O1l2jTDZRvA48CBPyl5YADgHY8GJ2QngmwZ8gCKQSURJgGyIob0AqC7WyHBjgZogcser2mAu98le0u2y73Ug6T0+zAHSefNsnFvM+9fdhhEFinwZv4noHwG+Ee4t9qpMBQ+CVOIBmTxp8RMlHv9nGi8iFkGKse2VHmQLBayxxccczy77j+Zi60dA6MMRr6qaJ3qiDaBHQoZVZJ0DiefaGOVDz7ak7mYZPgKWTv2LU7ydMcCn6jop9ecvvn2SnOTlp9U-wE5O6nG9q50x0yd+EbnhTyAM0KBaxAGnNT4hjsI+dxBnnDAPRytsOwhtCE-HL2YzxQJaBmZ3HaB2wLonc491XHGFyMg8qB4fc9XYQC7FVLJ4hs5UtjPPIESqGpmnYbWowUyZRbO0kJ+AARHgim1tC-uYCj04p3IL6XTYBGPGyGf+try-x2DqOhHBwO3dnkdpQJeMvIOSKkG8kt9WQVX6RJwLhwnUSt5VFmXVOTOAGCVcjEuXSuOhUIF9ZWAtElodcmK6eIkV3AirvJvOHYqOgmy2lefKA38BbxBgJU7rleW5Z37e8lBSdcxGqrQAyeHoFVw8x4ya5x0pd7SULKojXkJ52SaTIjm9drNZ4hgSLT0qvSwH9AfryPnnbC7puGHqb0N84VCARvhkUbkTMK5AmBB9Ak6nCAucze2UBiVbvN8KRAi0VxXS8jqHZCBjTygEL0OGHteU5Vv1nXYw1qayHc5OO3jyFtKodadmF9HfxFRiGGIBMozVELsLqF1mSLvjZjmx9boirjSG-7TpTB7ZlUBjm2FPAly35tjyLhh4vidA8Y1GlLhT3CjOMMvDLUy6+J5uw0lDXlDJBXde8Iig+9sASgAAbObGIAcBlDO71WfXGUjZhUotmeQMB9A+mmfV6vRIGxlLCmkkq-OVQCQhGsMKBwaGXgpflCmuBJgUddZr1rG0EWMgIIkD9wA+3RblAhA316BIVvLvenLHk7Fq5e4FvqXE8xHBFNbuwea2HG+eTXGfIYsIWxHlQGaagIKCSoVurSAjqUAJl9B5gX8VlEZFUBvAfvPICyeDUzuEMTi8AQO5srO1jPuo0oYkZ2gNv72DgeWbNKcVQDllcYW6FZ9RXHkSEafHXu9DwewCMg6U1KBGGNDFwGCELMyaIN6biXfEV18wNYEjr4WY6q+9iudJbeTrC3yQW5aY5Er8pF+Ab4+7SUy+GiuPkAMTe4HS-cGwWYwVqE6aU3bR0HrgA93RUXmhTNhAQWGG6usmN2rdHDMoNS9MUgkp6dgGr3GBKVHRNTu8fDyAnu2Ly5XKc8LKUj1KNs8vv3FlUt+K9yweXA0BbzlFbau7poFoagZZZ7wWuOg8sReHF7ZBQho6gQWOtSQzCTrxtbgCPMvwRZzrGeMe80HbO152AZENnyAE8FENgINWP3lLfdpkhNk75d2o2QKE0ousPSUdIIsYXItuauvWkawB14xGcHkAYUHrDh8lfaClPen1IP2ybJHSm+Z9MUI4t4jOLvv0idsJOr6mwAXvGAUytuGW9-bozaI1FoA23BcPkrQ2pjv5kKjcztwKyLeUIHVgRS7ZiMuINIQrjwAoyPSPgFDMGChwDdIgdmXXCuA-RBi0hDQJOraDXlsaZrIphfzTWM9EUBD7GuCDNZgBTf044r5b+GRgLYYWJ+-ILhBlYalahYGZxsxTEYB3k-VA0JiKssIbzYTsoh64FdkGeG0fsfRXFJiB3McCpJ9n62jyjx-ckdzWYxybPB-fY2X7-zhXaPBhTzawQUICZM5N4rXDbAPpL4j8dWBX4GSThvKF8DDhgKKiOAv3PwvVKjgX+ebaKokO0m86kyNsnOCjq0gKXybjR-JGGShdkgQIDXez6d8kIF-cbP78v-l92AXOogDXZMyAET7ANJto26j9yB4OLv8pKuL35TAQddP5ASf6nPaUZ-pENHNaKn8byI7ckBRNaBrGNDVoYgwi5wwF8XaDIBFcP-cxC-9JYOSCQt2-Q20795Pf0kg8LvOkg6gr-L8kHh4wP-3v8Udd+UgA7bHm0Z4HbB32AwyNLAnuEfrSWQfBv1RAEaQEZUIEHpqramF2x9sOuB-orjBwHh1qXbiCcV9BCT30FLoerhWcizIMkIDr+e-iDIxSD+lzJr+RYiFs4EU7kNEiaMW23sXgRkhkFAuSjiOYVJZgnsxmGBb38EoAIFFpgp5DMRDsh0XgIdYj2Rfl9tsFTGgrYHmeFTsCd+efnfRMDamCF9udcNnBYrRRGEL9e2SwK8CioDl18Cz0CCVqBWAM3ywEliR0lvF9iRdlaR30eIJh42APp1NAHmZr1SCkg1gD6cmUSdyjxmvHIKap7MWoD6d1wS-DSDhwUoOVU-iYoMXk3YLbDyDhwOoMhZqg5IMXkAXd0QfRmvdoPKdycfiC742AUbD6DSwO5iKC2AWxysBTKAYHGDczKoKHRagaYMGB3qe9GmC5kZoKHRtWQIVGw7BBh02CYeHHEGB2ADXBlEFuCKiKD9gw4PIJYrJjmZ4GvJKwiwccJYEQFdiJ4IYcX+IVi1UxWSESlYSEWVnlZ3g0VnTht9Vn1cx9ub4IkBAQ+4Drg74C2x59jMT7U7Z4hPwKY5+2XjTuCO2YoBchrjOCBaQ9uKNgxDsIEVRxD7MHJkoBs7WdlqZe0SpjcIKFMZBWYLzZXCE5V+WSS1o7xFsC34vMT0ysN4rRMyXweg3ky1hPAAU1ICqjbBSglKQ30U8JYuAnVGxpQ9Ag60S5ZFj+Z1tXEO0MnDK9Cvl1hZBRPkegiC0dYV9fIk8ViAP9END7MU5QGBrldNgTRSVclS9Vt7RlTuJY2FFQQI5lfQFNUe+F4CtUbVDdz+IpVFwKVV7MM9S5DIAW9XPUeg05TKMjJc0PRI9RSMIZYLDZjU5Z4w9IX14W2HvmbZ2AVtkJZfZKRmSBcWZtHv5fZLMORZTKb8luYfAwoA6CggisPIA8AMOWWAZjQC2HN02b42Z8YODiyuDqcb4z+xdzO4KiCViaPByAzWJcR1pF6BVidZrWJn3mssCQa1sAtKOkCnDmwiDmZ9dCJYC7Dlw50OTAt+H1m+Y2BDb0DZ1RMFhTYeg9EP3FiAbcMspW0ZMFjYWuKAABYjwmen7Y02JIJyAK2cgmKwoACqzrg6recFwI1gjGhfCs2CthylD2JjgeN8jEhEXo7g3qgrYCIHIWyFbMX5mfDfMLNmxoZQn5iQBPA-wAhZl-djBZYyWfQJl4dHHlisAMHJUjZZ1A9FkX5gI52nII4gCMHMD5ABBE5dKIwFhLDVpJXFjU9werx-hKifsjIj+IQLmwCSJSAAXklghURAcDwbvC0htAsnFCQUhf-U8RqQbxEOCTcbni-Dt8HxBgZ48JRhUYzGTRk9RNgH1GJQ-UHwCMY8SUxnUYLGENmsZIAKjGuMiIHpmY5S-PwwcYNYG9zR9mrPqxXoi4fH15purMynxcYkJeBmQUwMugTxBwXSPUZyML1Es4+gKjDMiTGRcDMYrIqxhsYDGckHNBbUWAHtRJAexiowvIhuiJAoRHd3chVARKh1MkLEIW8BXwcqRIQsIMujah9WB3CRROgKg2yQwMBCKkkagOIHphIqMABXI3IE2C8A+QAMDiBBBYgU2MdImMjMZyMC3El04ohKLvdkoyxiOQbGRFDmBgEcgHGg8ooo0KiNAXRDjdVAbERTBtdbeGtQ7ZcKOUZpo9Rn0i3kQ6KtlxWA1AzDChKpBjAgYYKEWiLI8xhWibIqjCURGSBxzyjiobNAHtEAYeGYgYwAqOboiQW9UpVYgH8W1gxmKxn6gFkSom0pvpRfGhspo1RhuiPUHVEMjJAA1C1BegLSnmAXoYgGUBPopKMsifomxiBQeAEmNhAgYxYHFhj0XuGnA-CWcHJBuwCyATQT9RSI6gQmIaIpIH4CCCYoX4Wb3MJyccu0FwZxGExljhWZrCljyKGcX3J1nIQJosggZgl0JcSYwGFgyiO4NiItY8QF0IciSgHtgDY+zFGhmCDxgndKYVpjwoyidNjCYrAKu3gARAlcJdioIBlGqAPY4kKpCR+J7CQEfndpjFAaQoONjAhABkM-sYpMe0VoXgS8jTtnaRWmEBE4ghzv1YmJWJABQQIAA")); })() /***/ }), /***/ "./src/js/built-temp/base-es.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-es.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpY8aGACuAOzAArYfAz9opAEbl4YAMalRccsJ7kwAMwCHSnqsRDWicojCJhsUskSweHK2AA2N1csSqeAM-iAJ5qjgo8on6B4gAmKvo8GMLWQmaxNgBunGDIhmmOrB7wEuYC4mK5bDaRiaI8DlyQADTghJCxPNDq5LEAMpEA1oyQACJdPbFgpIn+iB5gALRgAIUAwiwI3hrISaQAhC1tRB4aGDT0IwDaPMgYALrAAMpUAKIAggCyAPrvqKjfACSn3eAHFXgBfAD0dFgqShcAo8G+liw3wwPH0XAx+iuUNuDwAOpoWOxuHwBEJKlIZPwFOZELF+PBxF4wpo4cJVP4gmB4gZjORTGVLNZbPZHM5XO42T4kDyQmFkBEogq+QkkikyiyROInJYwABHaRgaAqOiWUT82qRBooFkILhgV6iOEyGxeISJZKpMDKY3wIUZCxWGyscikDDKaDuULxaAKU4B9zIEoUEWh8Wp10yrLwU7+DJTfmwYQCkxmLjE94LOzZ2C59VOK2IZpgUTwVSCO3kfKUsxePSl8tCsxgUU2RBSOBWBC2TxlDtd6A8IuCJarABy-DnpA8mVX6-5pyEylUKXk0DbS+7Dd7QgtiCtujnOvzYCuCnu+pqojqDVIPEv32YlRkEVhhAAS6EG8VzvPtUw4VRBzCU5o3HTNWEiO8Fy9TVfWWNZwkiGwzwvUghH5dQ0PXCMJFINtsl6FRQkQDhhAWCdxwjWIuV0PlMUDB112opEhFCLCcz0b0tRDMUYxcaB9D8QMFybJ8MirURXjgFQaVkNRpBzdkwAARgADnbHhsmKIQAAoVgARRNOdmwQK1e3EUhz0sJk+S1V0VDIVJ9gASnHQNmURUJ1A5J8EHrFREAAR8ZHgWT80RpEyfhYvc1d+GWFYAAlEFCZAuTIccvA7RkDmJIjkHDDTmQWfSdwy+9bG5QR+A9PNyBXXl1Ca4oGxMvKWQK2xOn8DR5jbRl4DySj30m+o-J1eMrAjDxTi0z97gANQdKcyniNrpAMkaingBwgPuYkrg8LpYEe8RCCuAAqe4wE+Ug-Io88I2JQgPx+sBUDEBxVr9eB9CE0Q5jAHgXt2BsmWgUHPoh9BKFXMpkisIsylR247WDbGIG+373mnBAhDSuaolsqnwd+1ByACWhbntQK8HWRBE3XUIXUDDAAFvEH2MB3nDUgeacDJEowsU6nmI89I4il+QAJgABgNrSwZpyGucVvmEDwT4+3qGzBDZ033mCAAv5WktNGQdD0bbyF2mq-OYNhOF4fhABNyQB4P6eqEXrgd7DoAMXsWTutLeZpWZwQHuJFYdIcVjVDTl63CtVrJCu-gKtY3IWWETaUcCnNS9NYQIj0Pwi4zvgO0ZhZswo3U8w4ec2TNZtpae2O3sdiHxgR5RAqEH9xPVGN9Alge7NYCgBAkZailIPBl5MxQ4EMc8T1CmeOeEDhbLAOyXTdDB+oMCgnDhgMg22CoojADh5rTHZFIV0-B+TwE6LMPgp5BBwkiBiTGV8PrUwhv9PyxBXoUB4DYN8CwAyeAHhAzEphoFgHci-X+YRdLXzAKCFkgY6o+xUMfWKMlrDCwfkRP8+F3BkUGhRNs+h36tjISgFKDF1SaAJrENsY9UZsnKvkJBJtUF9hcNvWGbDzA0M+GmX0-IF6dF2A6fgDl3hiHwe+dqYBgg2H0GIZmNgq5gAiCyMKNCVgAE1ciVUrvkECog8RT3jl+XOuly60kpOqNQAROgGSFulSgBxs6iDWMIeYxpElhmkFRDQcCFDezbLA0gBcXCZEtioSIOUPBcmsJtVk2wKobUZAIBu7kHCeHgKpBwwZcItywAvOYK9YorniNYIcAMyiem4qQCCsCRQ1S2MGJ06xCjaHgPSXIPBRHCwjNEqgyg9r8C4kxMhAN+CnGqk+Yh6R6qBK-C6Lwy4UnPVeu9FRv0rgpA8AAXmILAWArBoA4ChFCTo3QKCxC4CNfEogDwIChMVTcAB2V4R0OBHXuOMCFvRphQPmHib57ycafO+X8gFQKQVQjdEc6FjgoQKChICJ4jkkasAAFKoARKSTgfB7jFVIKUaJ2gGyEvIB4YlKDSXivJYC4FoKADuSquDKFiJ0WAdLkBQnINy4OHA+VPFbqq9VYqJU0K+TK-5cqqUYlgMQVumrqWn3DLqskod7hrFiXsAwRk5x2VBA0YqrdQqmslezD8ZKrWUtBba+1ChHUOAUNAF1Qc3V8AZacRlThdI6rhE+aAXgXAaGgFCAASh8UYnxXhcGQLEe4zs66TjIXUvi5BQ3R2CZANoEJWhEAwJm+YjACDtFOGlUQGARhrCsBQpkRwwaQEDBGcgIxXh+woHO9odrSDCBjFaaA4wDxjJGE0Xt7R4j+CcB4J48AJwOGXXgFoG6iDQGEPoRItAh3HE3WQHdGloAjGGKe+duw9rd3-Q+z4T72gRFA8WkYAAhKDRA4Gwc0CMKgXawY9q-ZAG09QEAjFqFByALhUyfrBkQDQ8Br2xViO8WQIwWBdl1J7ZIpckNQFoDRjQsRoD0dIIxlSYAAA8tAAB8rGxCYw45AKjnxIj2HgPxwTzHKi7Cyg4GTtB5MacEMph9TGVCiYk+piU-6gPtCowKlI+moCGcHmAYKiAtPWcGrZyA9njOOfTOZr9lGOyjDKu5+zlRYhSy04F4IfGGMGaE15sL5gZNmlo9AJ4wUGAPuE8lnj0AxO+Yo1AUzDN3hWm43utLFAMtQGE0VwQYn1Miey3uvLMmf1uatDpxTqX0sjGE213LxARO1dy+prTnWGa9fE1sjTFFMOEGw-OwY8AovkYoyRoW6H3iIYs0QPKu1J1UFLX0GT8wquQHeH0DDO2oCCDMOwFdTw1hJYwfoM7TxiqAgTldvzTBLBdge6gd4axAQAHk5sQAhN209HRlqkHg0+Dsg1VvIYaMUEYJ1BoxGieGaQ9JiPYQjCMFYIOFCwEguIKxFclS3Q6VxeMiZSDJgmb06ZZhrCF0DBLOAwpoCHCh20SAThIi6KysjqARQyojHZcIF+y6LOQDygp7AD6uEuCylYYjHYFWgntCMTc2V+DtWI6oFg478yRhGMVTBQp5jRLMMqaBxGX1KAgeqkYpbXcNHx01SrTxEDZBfmRh9gIfeUA1-L2ZLInjbvIF2K3roid5y1pEzWMS4l9VcUkw48vwWTAGKIYYD7r3kEPTvfk2LJh4pIYO+XxB8ysAOfmwtyuoArAbRkecebeL+HFQcYjSt4DweCCMMCMY117TquOHewm7BbvIIsF6BexPEaUKQBVZpyAAHUrD1HHUTvoch0qgLbOwPZlPIn2KRt3KwhhV5-YpDqYcUQA+MJliTsnFPLqRJumNfgYDbvTo2AbARipiqyvwWiBhH7Iw-53SIAno4Yxgv6ph9DwA2R67WTvjGZO7+7ujIGoH5gACqBeoga+og6BNkq8sU3kBUc2C2UAnQ8wkY4G+AOGBSAKcGeAw686pAheUAIOAA0jJhdHdC3pAPBhQOMjJmYEjPmJOk+F2IODJs3velADbEIHePEDJtGHeGdkdHuKcjgk1JwOHj9pANGHdO7vALaHMHLqYVgLAE8A2C2KcB2CMO-vQnoNYjAZptdjDmNPADrkHlAE8JBAQkaCaCwAxr4QePAAqgQawBkARg+hjqnOksXNEEEM9mvvEVGEtMwZACkamPRKkFkQqvwctiqJ0OOvkSkc4FOAPCWJ2F4LOl+nQUQLcNvJQH7kgfAKukumLijrAGjg+n0WXpUqHg2AqDJggJcA+gnPMJcrbh0ZVu4MOKKC4B3kTL0IyIgDgODmAG0VAMsV0TgYHtRlyMuMwVwZuqjqIXjBsTYFsSTCjBMTsdMbCOhmWOsQTGAE8TsY5jYKMvwMcRjD-GAJBDzI0PsYcZAGcQfoyPMajCkC3tcYMcMVAKMUwmoIAe8bMVANuJ7ACVPp0H5GzrLmpN8ZsektsRkHsa0fLqwroMgN0bgfAGBP4QMVAC4EMaIVwokOQE4HoAoBIXVLiWdgAP3Xo+j8D4KZJCRCDCl+yNiUmIAAD80J8uiBrJ7Jd03cmJnJJGtxIw8xRytgCwipkhvhMxZ2Jpix5pIpegbIKpvx1JJMdJWG8u2hs4HumSqqBp3J6JkAHu1hFI-o0gQYAmVpHxD6VAR+64+CygkQNhFJs4PxXEbAL0bOBCaQKAEQFETQ9JOGRCsA5RwQlR8C-pRpKuuZ2C7cDY9EsMCAyEopvh8YqgIwUMHgMYakTZbIdIpAsAvIF0fozgvIspOgDCjMK4GAUQ5AbYUUd2KgXE0hChVgBZHpOG5hJZFRkQVRGA0AfJTJUoGglZPJlhIZ7gdRDZ0SvZLZphbZK6iI6o1STEt+PSA8J4tg9ZDRKgt5fkHoA85SNEFgYxCMhcpAToqAO8ykOUc57I-JTg65828uS2ZZu58C0AHuZosAIOvBqJXJVZUA7w35jZTRk+iZ9Qcw0mrZt2++A8V5P5ZCZF6CT4poAEcMF5mMI8gFjB6EnR6oYFDgfOG586CMzgyJWFcChc3cp5gZGOQ0cQS56yeONF3QlupMjcGMfUPUYy84Yg3goYHO5AXOLgY4dkwmYlpYygYm4U+CJBlIsAt+4K289QHCOobITECl2OylcBqwXCoyDC0wpOHhAgX+10hQv+YBakEBQoLI0BEVsBwlyFOGVGLJcJ5MVW+FhpZ5D69xBMQgfxLOGVOx+Wa2D5Ree4xyOS647kqk+lqsDxLpxM-xr82Qw87lA0Xl-IOOGyvlKwUF0k-uFARSaMJEaktiAgPMukgUIgQVH+oVES4Vo0d0fehZ86wgCRzg5xyAgpw+nBphAZohKw+uqBk4hcaRXcQQ2e95tFIxiIQg8grIA89ueZq00Ax4NgLsHgpGQ84RWsL8uk7pyV61rAuR8YgIroPEXIRaZB+1BW2VgZo+DOTONcxRiWql7ZMZkyQg0yWiD1S51VFQY+UV9OSY0gKYeiZQywWWcIZwYmx1-+Wgwgti6hO6I4POtggUQoYk+wwmCItN46EmfQYY8yqU0SRRPmDlt+HVlImSf8L6p+fATCZ4LA0STp8UCxcBGpOG2a+6+YIhh5ApslvJGgCF7gFpd58N5VreecfYFtzcFUJuhCkCJCm8wm6g0MEmXEG+k1HcFEoUMs4ptt+N0p0SX8qkhmegxS6pa17QutaSsAhtyAxtk6ptR5egPQBGGNieZ8BQYeDtviD4Ltc09k7t26roXtmYPtdAft0AAdYAQdM4IdKQ-+BWbd45iS64kdDlpAMdIlcd5gB59gENL6b6JCDoSdKdKuadAphkDA2dD6DN441VFggY6ML4S57oUd4Shgvggdwdkmey-IHd8pYQYevefdwN0GNSN6Qoro0A24sARBBYS2sQU9+JjNyN5NfkPS-u4WC9rejUNOOCCwds74pkusJNggX9SAjpA8qANUFESVEOKFO5z41RENtN3eMN7952JFN5zF-ALsLgtkQht1GJYVO4cZPiTtjM+DjRzZfk+Cyk-gL0ThPZVgSAduxanI-EuRVo64RgFY5gKy7wxoEsAJrEHgbGAiEUey5gMgLs1gc4-INNEYgtN0EY9IcDdD9RpFjDpAfNWgdNvNSgYmwmZjIm6gVEno0APyAA5KheWeOvY2JmsIdn0HzdY-ABJgANSyxKlaBWB4DXrFDcjX4sa71IBcAWPkASZl02OD0ONOPoUuNibvafZUBeMAw+PWyGCNzL1dmT7LmVVZnlI25CDZDLgsZEJQIQWxPxPeNqC2PJNoN7muMXZZNQjeNiZ4AQ0xGUAqB9mxU5hqgfVpDYRlB5qaCdFaW+iiTpAiMNPa3zpyhbWfBWBLYqFZWHV64G5VCx6MLTG3GvBu4jHqophWC3K2FW3kNjAawsYkHKjKBsUzk3JSg5RtgNgO7k7L0QLriYDKCy7FAOZqN03NnZBGMC0YASb8j1VCICk2B2TC2GS25zLxi-EeHuAz6ObKD6A-KEgeYUrypQgxEKqBhcCpohx8CEuiLkD2EEuQDfCJhPiDCEtiaIDiN82IA2UrMD3kBbNgTICkADDowGnW2QDR6XLosiS+A+wDyCnXPrgy2eVY7dU+UrLv6-Pn5LU07HKZiKuMLrhkzox1S858tEAWi+5ygsjMADnb7kC74Tpw1ra7MjG0CzPuB3ZWU2DdUa0T5kNqUPqlQPV7gkJaUObetajY7+tsglhlj0hmiQXQVDVwXuTlCGSnR-V-MljNVCnmBOGvgNIKkKMFXWACPQArKvANzIQ7q5SpB16rFljtTIMHH87tHjq64utEApPoP7kg5MReB7UsHw3CvZAbOsAjD-RMRJb62FzwY6AeB7n5GhOdiOJ6BRPOa+GIisAIMqT1gj4lDuC5IFgmHw0RgNgIALuox7nu4DnuC1Ou0yYS5difAcTqKBlESnt6DlOO6+HKCeXwAg4jOXsyXB5wqBguCOk2BYKnRTGtldBCzFDmIODAdH6gcnkPqj4dzWSNiz6kCwejMxDTGRj9rwBBpv3BsJJsMPsLDFQEGjDPtPKD6Lu3vT3fsCDF18BSG+AIAbMCuBiTpysHPXNkMclYewLaC6DPsFvwDC1wDwY33hjYQdlb1gBfWkbHKINKHeSDDwb5iwDjBng4MPrvDSXlNXL1CzCMJ26TPqHlvJorFMglG+ES6iCI5PAKoNAm5PCHgjD9OQd8O6D-6cQ1TvPOdSH2CrvSWYdQBETn1SGzLBDRcmdxezK1lSHFBWApdgdQCitYTuBmhhPwemFYTsAAp3E8DldZ2mHQBeewAm7C3BCBj5FToO5evVD-qx27aVVI7dvtB+kPqlqCqRl2HKAsjo6BiaG+GJjSAjDvDsQeAybNdHIKrzeCnyKjfw0QTkC3QdlKM7dbumGqC2Kw1xfYJkG+EKoYJJFQCKfyFbdrYsuqC8GQCbgyCE6+EOK9cQIjCghChdf91EAFI3vwJ7tdgHv9e7bBDIQseg-jpHRWAXewD5GdndnCaoWV1igXvuD8XTLgpq4NiVNI-xSCDwHw1kCwCoXC0KCyExlkV4AY-LbL6+G1CkAXAo+cnPrsC-fJHm6FiMgcZEDltYDu5PhRE-bPp3qYCiE1hOBdhRDGKgJC9QBUaAgJSoCBhlaUdQCmShXLQmJgBQiSbsbXbtEJTQCa-kDa+TYSb631gDzG+lXw0NDLSW9a+dg8ajDbrCwjB2S0C6yhQq+GmkOZZTZmArgT6A8UaQ5A9QDFA2RAP+GP3vOpdZUJ-5ixk5X4kYELDCYZ8eAs-HcJUIA6+QBJ+wGzpfeiAv0c9E4hurwwOT7CbKAKrExibXXw1sEOCiDvf0AoFoFF6ajocqBgNLfddQAkEuDWcw1XGmFa45F1JHVEE2BZSnWo3phS0CSOeuXFCd9rZnEsll-XpEmFUXJhipmaQWtMBkCTtQ8EXZ+QC6Jo3O-Qb2A9-P26dTuU03OuuJLkGYFxMxzQMDT3zDMErgkvKAICGD6AhoBZvKAbAJgFHRg+yA+AQUTgGQD0BGAtulACOiwDsBbdSAICAAAawfUgT9nuC+EnAisYQMgAH5098SgII6K8D6B-QAAg8QOBAg4H4J0AsNIjAC0B3aKQBeLADfbfVeWE-GAKB25yqA5+8NN1hiRnBhYZB6Ne8nUWjwpBlwXPJgHel54jscBD-QMnLxUhRAq+kAogG2SFCsBUuT-aQEEzUjSEHixYDUD6EJiukSqGbYcI+zmhqAHQ1gDwEhQKyHF508sbvHoPwrzoFBkATmADD4hmCDB9BW7FYJsFvtJONgX+jjTKB41s2w4IRqOEnALBvCxyKGl2DbBJkakzXZuKEOhoDxsIa9IhPmX2Jx950F0DAoN30E4CEaohJ+ECzNYq8LBSQqrikLsF5o+k2Q-BI9XKDPwPB6QssN4IpAK880AQpofNh+zBDJ+pANLMHEt4lC9BkAKgJMkyBSx2wcgIKKxWqGFh+AeNcnmtipbu9yA42UQllh5S5Yje02a-jADuhq59yIuYQAaQlzBBSMohWMvvFbpG4ZurHDCuDz2GnMbkf7UwrT2+qW9mOZfNYHZ2bT5pPWznVQV33f4cEOha2RXGv1TqugFMZ7QgdhW+H5EQcrATOK-2Ay1x0c+hVSLbmzAuxuISZKroOjWGSDSwd6bBB4Hjyc97+XQkYOKXe7Lg7QjMYII2nVLbsyACqIUVOwoh5o9AWEGcK1kPBKiVci6DXJINm631sI0I7ZsXzgCp1dIHwtvsEG3jYQ5Ba2K0TaPvpTsrmRrekXZlbgrouO-ANYH4Jrw3VugyQ3LuX0zKDAUYHAOUr0DkCKAXmamF0c5yir8REAxACWG2GQimBQxYyTsFVC4gW1e8ToBpg00hgcR0evbPclj28DCdYxhzeMR9TAAHgZwqRW3PwDBYaMQx6oFWoY35rqMYWUVNZnoCrHXMM2TpCiCQl5BFc121+K-r4TWYw1DUPUaAA-QHKp8gxrwPuHGJ3iq0gSagXwEyECEHFNSPKI6OlHJYmj5BhFcvp1xkz7xYAw7Aon4A3iJdWAwQUsqnQK7LpJBdQ9nGUngBUAJQNuJbiKKiG-j+RfoinraO0GQBTI3wKCbCC-HrpF6X7byDYEqAtiYWsEv2uQChbdi7eV+D+HC3ECoSxMqgCWLHg4idjjGgtKKuhMDCnB9+8NKCbrG+CxRsgwQeCYAyoyFwQGk1PNOBQzoaBQWFEmFv4GMjTNHOYebEVhLpqd45hXo3wZDXmCmM4mhY1AK9F2KrBCJaPGwKxECZ5pJJlE2UJMwxEzMnOm-WKAtWUZXVg+UEgAMzfBHwVoHOh0kImbgQceknseuEqCEtrE4CZNAwnICEsZY-lTkM11yB9h0JvEkWGoHRGiSsRktEpstRwjvhFAe8MpH4lPCGAsIu4gsZYxUkzhrY8UX5hBCKZ+RCJGTL7G5PLGoQkJP7JHoQnoBwT0IoQX9I1mhZiZS0FUqKjj17yVsVhsfVYSgwFx2tWAi-PImLkgCIjMq8-LtudxzD2dMRJk1IG2GxT5IdAznSKVQBdgdhSGGNQMbFwKL89+Bgg4GCILEGwAJMgAJMIBBwmLXKdOXySD1MgnEUYr26H1S-AJXW5gGKGFBjeB1BIsFdOOkOhbpYAS6YIJunvs7pcfSAPLEuIUA7R86Z6anXPpthhuOEUIHLFRjkiWhgw6wd9IOl-SjpwgwGeDOBlXSwZ4gj4ZYGwgVknp00p-pwAMY2JIYkzeIWVWxk2CfpAvKYATL9hEzxBJM0GbEVunQl22UAEHkuwwpjS404rfMG0JXSQ0t6JHT-i9xGB05oGZNWBkoXwJXp0s54M7H0COjHZ9RBnaWcpHfYQSEZKuQyY3mMniT0wwfSwV9L2nWyxJ40e3iYivBVBXQhU4sZPm0mpBRhJTDjr+0aE8jIZXnZQCbLsDfVzZtMqdL7zQEOycZTszegKVd5GSXZD7RHJLGcyhyr6RAB6aeNZmmzo59-IgBbIxKvTeJ9stmUGK-YBABwUYl3A5i0RAJKgokNUZmGol5jep04lgCRF96lzJ+tM14JXLvQPwXQ6QFkHVCD4Jya5e0uuQ3NNDRiVA8LHhK3PEDtyqJr0miRBSLH-NPYUdJGEtFMEQVepkgqTOLAjBSZmWxskUfEGLmTTOh5c-YZtNkKzzPpScs7tELXppy9s3sFjLAFfmcRMwMUlYjo314O8QKTCekPRGiTzCB4oQAcvM2ikOdYpqQPcQNLPGBhdYMcoIi-K2lWQKCiA9+T4Edlfyre6MFQH-P4iVBAFBCriKAvPrZkIF7sqfNAvqJwKvRK8JBWUGElE905aCkRmfMhnJo2GCAQuVjIfm4LRC8OGqF2COYkLdpX806ZiAcTX4FgywZaUKAKQhT4AmSUDuUhVgZC+kvo3pOkOxp9IYwL0ZZD3OL5NQO40i40juknE7w7IN0P2jPMwGJybB0uYyFxT4VTNUFC07UL-C1prDpxhQDuIsCqQtcUSmA5+UnBXDzR4xbiyJeBU8WdDvFQY3xeNH8UoL5pts30DqH0oYK22kM3WeIsjlmzB5kAZ+fFzmbVyP5Ng+pf1DwiuDYYO0HgJsiFgcLQgMYMcLmTKCmt4w+YwSRJhWC+cl5lyX9FSD-jrF4Ai0M0BgCUZbVok8YXhtB2mABzZwKgU4WAV7C80uxdNWxfDWNCC8aldShaZwmECGBYg2gW6BksIFZL55KxAwDwgfAbz0ktNBqmTxanYTVgky+QNMpjCzKL+gzRZYo2UYqB+Q6yqTtByEA8K5IDMIBGaH2WGBDlYy4RXnKgCMhykMhWICiAjAwyJFZ6eGFHMfmEDn5AXfhFiXbmNLSFn8-znCkSRzg25vXdeXYh4RYrMFA3e9pUrvlkrqlBI+GbTJRkKKvFc8r+WKrGHvKM2ZoUkegnTDc0wAAATn1i-E6kIcoIdONUBrcLloq+9ikupXyBHlH0hlTYOlW41ZVOoeVRsT6ikinMyqtVRqrNalL1hkAfQABOFXtBn5Yqv1BZH1imrWZTSoMX6vXB3CXEoQANeqCjBdIepucnlVLz8BbMqlJc71WXNpnozmi66RRWQvm5YQ2QuZQhMUEgVOhJl9lVFTK1-i6ARqLC0BGrV9ZCQTcgJKhaUxwS4TG1CwN2fWtrGuAIxV-BNfuJ1o8BaAj071TDikX6q8FuiJCNmtpU-c3RAwkNXtJnXNk+Qz1BdSIF3R+REIa6tKGUjCVBDJBlMrmqmopXw1n5Kk0BL-zNVKLU6NEV+C3O8KNroq8kjvH2onLbETIa0dlbWNMUvrOl9IN1VQN0BLpwh8S2mVervT0q717HJEI+rXnPqG1UwupDUHDGfqO8Zkn9WhGQ3-rokgGw9TH1bI+90SEQoeXgqg2uLvewsINVjOXVfzEJvgGVe0obUfKu850IZmhv7VglsNYxV9exvw1+wulhG5oVADOU68yNtSyDdhFcVpJbl9y4oLRtJX0bVOqcucO3NgbYlMN6SO5aT2iSrzXBJkNlThoJ4ya3VvIhtmescUPp4cL6ZQJ9wlUqbTOXYawe2vY1vUSw5yHGh+TNaMzPysK5mvAEgpV10oTUZQMBtq7S9ReU62Xh4Hl5TyleUJXNYyofSgh3BC1OgMuFbrdqYYbYFgA2P8CQcDKCqxkJBWqoHyt1xTTMHtj3C0dG+kKaFeaBLXuzzNkMjwhgGCDogsW0GgVS9BnYjF5ZsuEjnQkRxbUxY9LW8XjCO63NJ16a8jaIRG0MIax5oLOf-Uc3mqgxi2sUO1uOEjJaBR+PyNcO5VDr504c5ED4AogrhqiVmmLSPmshdA+NZgYWIusSFOaoAB6Q8Cxie0gstos2cJaYVTD0sx1kmhJc4uSWPakOggGDXmrmJg6-4-iyHR8t1ACZB1fUuglIIoDBAPcbfXoHDKgCt9iYTE9-oGG+AaRvgeaZgLgxaXLa3l7SwNpjVbxmcelsMUmoznJpR08+YyzOowg6nLBudzGlOHjycQUw-ldNfkARtsAwLyJrUtiuIBBKFcywhHSYjEEUnmMzG7wJZSspUaNag4XYQZmrRlImh7K5SFmnpWJrNixlla0ML2F52rAptlIDqI5mhWT5KgibZEhGDbD4IAtIU98mEXwQgsXKANVtjCQJ29BvgOPfleOqiFiqIuADSALnE52tSceznDqaitVqs7kwTIGWNKuyE2qHQ00R1RSGdVg0tV2KswrEUJ0nrI9Ozc8ZRpvXKaGdkAVcaLsFqSQ70qes4Y33VmT4ioI8vNCoGyD8KT2rizULbn938BDMBQYtrTtkjhQYo4QCWCzF4X8SDN0bXBOOBk0dyxQGmqwJ6BljZS4mqAUYCE22QuB6EvcNjHYmERrLTsGgLoMKzbArAWATUgiWMuFZ+Q6cp2IIKYAogdT3K9FemIIGD2ekK9Ye3YKOpJVolRCq6uddwzQj06V0ie7CburnUd6iSGe7+oVD8rER4dG64CpVubiESUDk4dVLhw6lYbwk8C4A5uVAMEqZwL3YHQdXPFZrxVZqonO8Ccw5sRIOB9wNkKw1IG6abADGSnqOWC0ZY7wZUCEvc1LyN5PB4MG2D6XbIq1FWhZh4PqogIOkr8HhQfPyYt6YW9iJJaYPMAVSVk5aiRGyDw2Zjm1OhvQxywLX-E4qvMDqX+rfVcaMN0sD4aHroNFAGg1epg4-2vQThnOUIRJS4vr1LrG9zewifSDkVIARDYynxN9R4B1t8a6BtWWzriNYGJlBNfeb+i30-wma-EPIRzRWguqK2ths0BOGbgv6DtrUA3qAmgB-7xAv7XhfkptlzNzAqu5ZpIK8Pk6xAW03BhtIGNx6ojYyuhfmDQPp70jmerIxwc34ys5p7R2jvUZhhsL1QUuzhXCIHiK6KdUU2adQfnS9GI9JO7kHqqj3niY9O8GJfwgQNUc3qTfPyPVRaMzVhyhE5PRQFt0rAaAcjShX6HvaHzPYCq+1S4EL0HBIY1WnhnCsuTjjwmgCd8O8b0ChBCJRU7svYyoD2NexpgFCPxRfTE8bci8CqZ4doPfAC5TEvuVEAHnnHH+fehqRm0nlRBbjreBvhgcyMLVCJ4UseTqHpOIAKpMsKGPvPZPMqZQA8PhJeA6kwdaaD4UeWJCKSvTKhfkUUwqzClQJhIiUPcSHuJMXz6WV8q0DfO+rk7Ek3wHBYBPPFDH3wY-MAMQv9GN7mT0xzAw5jX7lI6xJPF45gTGNALPjIIjsCxiINlQd4IvaXdhIUO2BODCxmuLOuFOURXoMm9QlV0YrjHbIBxgbsSdEW+GTjaS89TcUf6yL5CmRvifYvAqMnIAtphMN3seN-xnj6mjM52tsMxHczPO0Qz2KKhmcb0uSwhK4ZXjTIND7ahzFYoJhJnhexJipSTvE1U6rl54eTRtTRxx6SzDx-gE8ZdPa6BDGjBaZ8YoW-ywFM+opa-tannhnAeyeZY0cbM4S6xOQfkECrARIMiTOOglVXpJ1MhW4pG-w4GTr3rr451p9SvcbLPzmKzi5xrcuZhZt6Pjx5jcCsCThX5AEI0H8xvuvUnDEWnESKDMmXA2BCJXFbIa1U4AVTUxxafbRlCjHTLZDOGnUG1TWVXmejxJu8+QG+CjmTTj-V8xObuVTnsAM5jjaWYyMu7fz+Jpc7YaAuYSQLRUdc3ODb0dcO88y-TX-BbnoVD0aRRKAOfx0pmotcSs8Y-2MEK8UA6HYElzVTCdBHudGm06xbnMOZKz-52s+YHd2BmpJAln+XOHmDxbZyda1Y-lvGj1VCtYebEvfiLByXy9N574PoHG4AjcG0uSJC9BdxFmVgB+AElPqWWrSwTJUAy9+bZNjKgrBkAYC7l5OrA84h+N5tZ2zZJjN+VqljaiqwCjbxAGsZwFggqQywHIBJIS8oG8gbVBAeWsqKFKn35QP9NUVk1xB1a5QS+BwIPuRZ8sGjlOTo2iy+cQZuiYcQbRnaGZXq2H1Ab4xmewFlwdTDzN5MsMUbMAyxoujiSJkxrshuRvZxU70R4zbDxgII0EWwDpO338T4To5UQKFGDMombA9jNYBiZKZvj9oB+sTJr2BYW7Wp9ldcLkUUhYX2wnYW8CKBKH8RCJ2Q7quNZWuYQcmao6yyRIQCXJH4IK3K09o40oat6oUdU-LhILh7aDuDXzskBH6EK35H5u6nOAtP2UO8Z4QoLaxEQrBT8ZcachORmrQAJY++sxspOP3Ogl4eibNnTck7M0pkdiQUMKByFxkhARUCUeDa6iESMhf+jG9kNKNLRFkS5TMKhbtOaaJaqQXkx8MJu9G-LXSAK6NdEKk2ObNN3PmFYTgyzOZQBu3TvFcsOAmriiVq1NHatPhOrncyhtTl-zB6RZnwgFBLP66iiH0NIukcbi2qyBYqeOvtFiy9WQAttoEtbDukDCYNAwLDUQgQR9pZ3yAOdk7LEDxVdgy+7wEu7mbfqSDVWGgeHLECwAJ3EhmQQ9mPn9i6X2gM4DEHvjuoK93m70tbKEI7IlCpi+o1joFlu4p2sWJU5wIsESI+NiMXgREU3cgA6AngA4JS4QKiE6QBwL6tkJ+OUgcBodKWuLjWS4nfNxEyGg+2xH00vpapToFFtfeHiororugaWt0HmAtR1Q7AZ8HheQ3Rg9wfEIcr+TLDOURxqUk-IhfmTTBaRWOGrWyFlDxR+BPk3e7uOD4f3Q+c259A1aovQBL0ydt9hJD0XSBkoHd+Gng4WKqcAwpD-ofJeSCKEIMRCJ8GQ7WyDhotUAf7hpGYvmD3R7DpvSQQFLYBIBfU0TZAHw5akC7QFCCVEMkeMF8NEoM-sfeaV5JdoYJY0KEVNvnhHDLapql+u6vigHAeQUyhUidBUAayvzSteVu2jmdceLt3qzcJd5c0gKTd7gh2BJMKZJ7evIrCw8iEKpSA7j3TPkUgbeOXtRARINkACddYRgAAVmmxmZaHJGFkJE4mwPpTI6qkJwk9gDktXQnW4bCMANhxOYYCT8FJDrL7YcbHLRHASI+xXPoLte0TfHXnzDXopEZSBoMO0k1RDmnK4GDMg-fAAJHASj2uWfZiTCtok8q7pz9ofALB+nyAB+GY-rVsh1kHeYchZNkOjP3wlod8I5WkoeAlNz6W1g0Hu03jtB2D0-N8ALRr4p2zNTpMr3gHPpTgZxyACgVuc8Py99DjXA+m3DwWEnykM0UNwyk0E7nTAHB75YLZXPQgvYTKSjqqf-bR2pAbIPWCeA88JNmAqIRzN6e5B4X5MExIM-nnDPVAAQUZwYgBeBxmE2UTjXWNUkEHNoCwP8qfLQG+SIELjzuyC4uePPDUp+G5z4VedsuRgzz7lwkLeccQPnH9b50C49Vgv-nULhJwrRJ2-O3sLsTl5C8BevPYJBvDwJ1vlcrp6py0HYirGVeVO261TxNSOnF7pJ2HHT88YCB0tOBcXDG4Z++FXB8BEKqwA4SzkCWMgLi3ccNfxL2xdK+IVGWGJ+R3TUlSEEkQmg5XcBJkS+nRk5WtinnCxGNinXcsVHryMHOhUQtBPqzFAZBvq3+9QC9smsba9pZnA9c6YqZO6lSiWsoMw2iA0dxAUgckiuDIQy2zSl+t+Iixv3fU79eD0+bC7Wz2I9oAYrpGd0td0XY2QBGN3a5GAn8GbSvDvI28zkYQcwE+AO7AV7HFovY-ENkPrcmqK1tHZayqtvxcpdKftn+Raj1YSl9vtVtXcurxjfal9pH543zsUCvyFc791FdbbBuCLbJYEt+FgD060qyJUY2js5FxU-LwxOwqx88x++vdEaAdzi1QA+-A0Zvn3IHt93oGQAuwVwZgad0Py34AeyYQHtiq++Ri-01IWHnDyJpqdck68QRMd4GRoB4TureHihkkCa1MVmP-ttxYOFIBQggYLdPG8HztQG9mXFgzZm4W6At0EnL0DAP8knS8eVhEOft4cfhjRhiApaLak+8f4k4Up1kVuiuAqhPJiOyWmwZMrP09wWMwrfDHxtMgAAWOz8QA4CpjhnbIIni+rxbRh1AToDXRI30eoqSgnYewDfjPrGcKkelP+E4FYlDgGQwqNT7dl3mZWuD2-UzNu4HgJxUATwNimQkV3MQT5egAG95pbgqnAo+rkl3B9EfzArR0AFRS+03vKXP2batUFh6SN7dTPQYyZX+9Ti4cmQXzLzcwvgWpGAwGQTyJ7GK4uK3q512GKoe6mRXxo4+7EjIVshOhXgmSICh7Cet6AypVAH4z7dK-CQIt8NGYPPCFHMuI7UAXKfwtCB8iKr20r9zDqIqFwJYQFbN6RE7BdL+I6oq7zl5An3xEtvofSCIzABmOfmXkC+ONHmAyMpnKxxivva5qH25v3gFlfwAtNcRu6pRowKwzUgE5Yh4TXkLbnaiHf43FJ4oL+Pc5NPBSgKZjtp8Y9ALjWgUWT8JELfPKv5nXs+N1-KS9ezSVUrMgmfDVNbyYs5W-PhyMfCgVYrONoxnOxFCBIgsEEnpW2B-mPxAQl6y0lCutesbrCwVZ35oHh8+YEM4ReDoc-yC-XVcb+dAeBnJfD6vf-R-keOSiwFWP52GxxlsEr8ADw9v+byaAE9nhOND4aAHLWxvq0V3CiAEsxi2ewg0pAoLH8eC6TkAifhxvld3CHzXtxZPdubed6DL3s1Q-FdRNlq9GO+p0HeXP5sbqZwwtHX6tkBp15h-HldY5E0CCwJ6VJnw0l2ywd4Fu05ytPtUowS-f2H5sS7XRmDXCyj1I3QPP49oJBEE1U4zsMeBfH-aDuL52kI8dBDSEQ0-RCK-4RGqAX+5LzQXCx32Z1eWIOhU1oP8Jv6xzCsgmzcC8y3FPDHkFfZh2RMwhVHjJb89VROWqBf01AnAxVufxYMQ6Jv7AHUgQAHWJ1jO8ohUfEI8aOeFRmgmIdyCGRuGc+hhBRqWckd8IA6jjtBmFToEMBTgWQA6US7SDlA8JhMlzSFPlL+1RVudUQCQCTfPUD7B+QNJ3VUctUvSwxWiYO1LEw7AkQz9iKPRgIYDGYjAwQE8XKlUkBYDXUhVVlOFmJp3GI7DbBtvRmU6YZYUqEA9WKUzVmkYHOkTgMkJBUAcd5LbClLJnGfcksJ5kYWD10vybgIYZs1GOwQA47YIFAEuyA0mKsGEZOzlhMyDIku5TCeBFplkrFhyk0LfY8i-lNwU4hcCmOfdgdB71DQJM8AdQehS4Z3Odma9zAXDhkwxZZdnm56GXfy2MJrOr3rA0EYhBa5lRYuldF1AswFHtIZfUEkh9AkUUZIjaaem4REWcI1Flk1ZIPvAZMfUGnZ4AeImVEDCITRUoIg1gBaDS0JIHk8IMeFxZE1IKwxYAmgtgBaDveBVGUUhg9uCl1xgnoKGCUCV7HaDhg-e3Q1EkDIAWCWg+YhzRVgzDz7ADXLwMWFAwCdknRfRTD2qAFggAC0COZAAhp5uPXTZwzQG4LuCQcewHm5igUoEGhuHeGhnF4AfjhTUVcYTkNZY9AHVrgaRKPFv5v+F-iaCIQn+0cJnAfIjzhGQEyh5w4QrKDWATwXkl1FMPFkBdgSODADI4KOR4IPU9AejkY4rSUjmKAMvJ4A39SQ3Dj0BaQ1pDZ5EWMZka1DuFmXnQ6ubzmIAmuHIOrJ2uDOkvFfCK1i6IbWEkAHJtXT1k2VE2VtQSlGkYEm-8JuGblvkZpcaGdlBFJLB8MKuFQjEJP7GQlYN07ARm1M73PUzOwzTJbhA1EcbVx4loNacWJ09Q6nRzVTCXFSrtCVbyEEB5APUONVHtXri0I+VMdUz8GlbdkmIgQoinsMwQ0dhHUgwmAxs5h9aMCvEs5TrXsDlGNiSntRtGnR21ptQe0QBPxDsk31piSzRs0zLezS8CztOQnfNtuKrit8Cw6rl+C1sY4wacQPcHmpkoAMVVqCzCQMONUAQgGGyC9QrIOs5nOPAA7CG4TygqQpCGHmKAU-PckR4uLVrixN3AYywmsKg5AA2YFxIAJkUHSMAE3YZOXSHk5YARTmkBhrM7B+t3AKv1Gc3OY4KnC4eVPzKDzuZsijo9-Xwhfp9Ob6iM4oPIMVLdGQyznC5HtSX0EUJrHkIa5iAD8Ji5RAA-Be5fOTQlyoaoRHDwA2uCIEK589LkIHoFxFLkRDKAZ0S9lxAJ6z8g-ZAtjFAurIwjcBOw3Wgwi52UQXfYquQMm2tr8TDyr9boIQE3YJrciMoiiIJ8VfFayHcN8Bxg9CPYiPg6eiYVdw1zmY56wbFEh0UOUgDQ5ToGwXKcyQ6YBA4XAgx0cBDAYxyCDX2aiL25cqNeh9tjAnUF79uGDkG0A8fVwO25mOHsKZUBmGywlBRfe3GEg1IJXWUjxmPY34VGFDo2j5lPHlTEdhSQSI4DOnZeQWpwRVggBhbxJPAvcokKiC9R4kTPA6RQgTcWmhfYf2GKZp8GwGIA8WRlijQSWWNAdQYURNGTR-JSADpYGWQlmZYaoNlkgAxMA4SQihAJFzvoBkblgkx0bFQHkBQgViTxsvrYkEmUIxbg0hp-XGtThh6xFCzSiMowlmEwcoxMCGAxMWljvASoplhZYC8dlipZyQZkHEAJoxqJiZebMxmJBwo6xHsoAPYykBJpoDRFPcWo7ZHsp7EQKiF0yjJUDEAMXCvEhQM2XYCEB2oWW1WAwIWnkOjZlDem58cWdKPhhGWYTFzxIURfEGBpooqNmi7oRljKjWWJaMDBS8LEgejegRqK6NtoiCJsB6QFsBkNN+BKNJIdxMMFSjcWAGMJYsoqlHkApMZCG3QoUGFHrDBoWgRlkd0GaOnQoY0qIWiKo76xvQgUFkEaiNwHSExZ6geYE2ilJNGIGp1OJIwf0aGZMUM9CYdnGwRB-XYFsBdgAyD+jRoolmtQY0BoDjRHUeoEGBPQOeyTEPAJmKB1YAaGLZj2WTcB4BdY4wyhAeWDcF85xANfiCZ8aQw1Tx5iXiT4AikcJD2iHEHBCmooOKWCQp0dZtTNwcAsaSiErcREH-E7cGsj+1vI+IGFYxpSymRIV7bQiwRx0QIih0huIL1Pwv7FUgKp3BYMBkwQSeBAzj8iEPE9YqhS-jcFmqQuN8IqMDONFYvcB9EbiI2ZCTmUq43RxJhIuREF2AOAeAF0DUme8O-l+EFmGlBm4Bin0ZzA0UI9ZKseBFs0XpCuL8g2QOULXdxoKCxeIZeMgkkFKReBEfp3gcpAxlKTN7jAQugE9zcoGkU80xxgHbiFxxCNSHAhAgAA")); })() /***/ }), /***/ "./src/js/built-temp/base-fr.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-fr.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpY8OGACuAOzAAreMLABHYTzABjUqOg848MAAPlquOQXktAE0Ej1o861LDyYRMNilkiWBvj2ANomXkAl2584vCwYD56yABGPKKIGqpgZmAAZhTI5smsXsLQAuLZuZHZdObQdiJWyoiUWrEpsTzwXJAANOCEkF6qGDT0jJAA2jzIGAC6wADKVACiAIIAsgD6c6ioSwCSC3MA4jMAvgD0dLDkiNCHcBTwS6yYNxg8KVyPKYOHI+MAOmos7Nx8ARCMSSaRJRBqcLweTwLxgAButjyZnhxg4ejUpyMpnMuVi1ls9kczlc7mgnnCviUASCiVClMiMTiCXEyTS5AyyK0hTy8AKOTyKmQJVoZQqYi0ShqCDA9UazTAABkKFyGV4eKj4tBEmY8uzOWBjPIPHlEUVWORSBhjNByWiBGETP4ot0YfbdQ5kP51RRaZCbBVEEolN7PBTEactHirFwfnMZPCZMkvAByRwYDKiWB+pKZeCuUQetnpQStBFI3OozgOa0Qkw8ewR4wWfFgAP2AI2QvN3QRdkyswF5IAWjACy1YFEKdsLqa6LueS85ht2rsSlL5aKJmMVfRZry-gQ3a0jjAyB46rByXXsBlgyiYyltVlogaoia7wfYAAhD8AEJNFmAAvYT7pW9rnqK3jmCowhLnYvJhOwsTbloiJ6iWeSIPC8BKGAo4AMIuEy1ZLnkK6EuuqqwfB5DkbYWBljhz70i60jcoSbaWiY2JJE8KT+MYWYwbYtGIW28Aoc2ZGpJhDg4Xh7ZgNAQTQCk8TSb4g51s0PwEVoUgyBapA2OSYAAIwAByThqSDCLQXFWiuTx5AAFMa4HxHyjr+BIuhgaQwbCOw9gwl4MJ5MQ0g2j+ACUZ4ThIaYSLYMoqJiKCZo6WiiLYOGnulR5FKOGxwgAnvkDhgFEdmwawuZcf4iZ5L+ohzEoUUINBoIJhWJiqFUQZKAAF3kva+Mx6iJEK2TDTKHlaeYaSiEo7gDYg6qwP4WEmPWa2iFYXgyfSYHGOuu4OLk6iVA4wajTouYYSt+1xJt22pGcAB3HX5t5SRNbCJmsP4gixqI95jHM8IQtmWCqhEk3BMUXhzVorlwHWG2qPAsWfmMPyDOqcD4+IhCDAAVGMY6kMk2rRMYPyEGAFNU3+G0mi+b5NNAjNk5TYDoJQ3Oc-KPOkxALMCwKSTTqw+1i0zkuoJaHXxFYWV4ARABHbHif4VjkI8WjfgLASJm2nGuXy8INqo8VvmAABSChHfSABMAAMntg4r-PK4FLD4hrUtbjltmOLQvMS-zcw8GY6LIKQii6IVsTCBSyROjh3SsCFyl-JwvD8IAJuSAPB-BOHETsAkxDCwc7oKUVCkTh2IIeM-I7WjqRoyl5X9HrnuSY2SJx9KCCpZWmCmfK90L9gSm2NTKfmavwK1hMaNXUfM-zAAi-GCd5MHSuY9Kq67ohw2AVsvFw1TPthuFgKQUQY0oZGxdvSvCBwHAya5u9vQamMN4Xw+otBGgUGZR+eEF4cGxuEEYPAtrwEOIZBqUQtbuCytAT+4sd5UwAKriETskYgm8k7NlIAAT6hHkTB2DvJ5FUGEEEKgADfsAv78x2PrQSbhooNSfGlVQDQMB2EQGxa+6UxESP2o9Q049KKCEOOAi42YLxLkOGYNQyCQZlnJPAEwDo2wCjwb7KmqBpbFg5IIbhVM5heh9GceRHoQr6ghFRa+ioDJgmcHYKoTo-KmKcKQMIMQZ7fnMXzKmMxwmARCS1CuVca4Pn0j1IEYQTIz1XOQdcP526iCoKlKEZ5VBZGkGEQq5AeBRHTuQMsUhlJQLAKce6Ixsg8HkP4cEkIIhCmQGIYkPT6RJXHogSeDVOzlJ7K01K5gZLlAwHDeWJiLR8lQpVGaMp0KKP8XRZSihTLqDYnfTuCB0RsNsPVEwKZADKgBeB6idxBUGMEdfgSklzNI1IoHijkpBhHpBEbIEIng8ClK4pMAMc7sCyj+ZmD5FSAWgIUjexN7HMzsF4AAvMQW8rBoA4EONojQKhyAmC4EKD4ogbYIEOAACQAHIAHYZgADUOBsrGPvaAZLjGkBSA0JQTQvDvCxSTCxmLyA4rxbAAlRLDiRneZSlwhwoiHA2JMAAiitVgjtUCXALhwPgYxXmwm6GK6VEqYlSplfiwlxKADuzquDGF2sglVyBDjkENWwTgJrJjCCiG6valqvDWujlTQYWLcX2oVY8WAxAg2esVS-aAFpfX-CLmMIitNlHXx2Mg+lQbcaHHFRi6N0rY1yodYcBNSaogpucK-DNzA-UAlIGq7o6rXCaB9acCE0AfDy0OAAJXmLvBYMwuDIBMJDOO1ZdADp4g2eAYaa6V03mMNoHQiD1l5RQEwSLRAAGsBg8r5c-QV4KRX4QFjUJc6IYFlJ4N+SAHR9jtCIBgbtG1GAEE6N0RA9ZL4DAIiwQ2v0sw7qZpATwlpyADBmOQYwdgYOdETUiOs0B942zMIhvAkAoBfs6GYYVrgvCTHgHcFxFABitHQ0Qco17aD-t3RhsguRsMDDPSR2D54jrBGgAMBYjHOgxEE-oAYOwxNEFOJooTAwqDvqZp+9jkA5TvgQAMeoYnICMLY0zIg2MqPpRMHMDApAdPlSqgvckZnsB8c6LQUz5ToAWas4Rx5FVfAAB5aAAD5l4OeE054zVg66iCcPADz1mwA+cqFoc8UXtNhagLQSL0X3OWbiwl-zQXktZdk1AbG9LCSxa8zZ3wC8oqt2K5AWgZWEIVagN5qq+WwC1ZtPV7Gu8JktY01Vm6jdENpYa31sq2XPOtaGx1kboX2NMdwm5yYZBKADF8-ZtzAWFtGagIVhA7nCyucLNAVbFAGCEd8wdwQAXkBgE28t07O36ucbonMQsmXDvnfW1dt70AAvEAezdgHyB6sZbTodjbgWzyQ8ECpwganYMnvgJNwzRn9OSKU3MP89XqmkC8GBqgo7FT1Y2pdqAcxFTKbG4IKU7AkOTAIvV5gTwKeQG2I7Fndx1yM9QHMAiMwEcQH2B+kjkBBykDZgdTwwm8AAbk8gpcAw2Wy6Rk6ROenYinGm5AdqnVSITTV9NFws0ZRKSdC6Ugbo5lZbobJZ6wRXp6JagjpH+21YLD5MIdHRAQVlQGI7Wwng9Oq0voDDAAx6UUJqTCLXwoLuTEfhgFA2BCMbAT7UUb6nsmiEmMo6P0HCPpPQYILJ7BxC5PyW+pzEvSWHuPWewjVHyA4QqBew9V6hUir01FLwrBXmDuHWnqAREsw1LqYuhky7hCrSRjX9TwbSCOrtAAdRqO+UDhHAHai8P4Ms+TS9CHSlFi2FR9kGyhMJOF5RGxhObHEG2KeEAVEdfAKI8L-ZKFbhwYcYEEbG7iAzQowyi2CtLej+CqyQbojgaWgZBn7zxVAZCaLRRaB0DAw1J8jrgtC14qQ4Qp4ZA+LZwDCMrhwyD5Z6Z4HwAEHwBEGwjEInq5SOqiAkFkEvgn4+616pxRYj6QBj7uA8HZ6wZWCOo7Cp4kF9yuyLxCyObqauBmB-gB7F4BA9I0YPbEhrbDjqinoBaUFBohrIIDCjpGJ7Ru7i71hYwYBy74CL5ODOBqC+6dCkBN5QAADyAA0vVmYEuNpoRjMIKkGCHmNlKCtLCAMB9lFkuEIRjsPgRlAFYkUNmOSvVjaEkezsYT4KEdEbBjaKEEYf4I0O4OzHaPVlgLAJMNmIWFjFYAMFRo5N-iAgyIjCbsKCAbIXthLrCKEPAGIRkIHloCpD3PkjCKCKkFqPVjbPAI6oQqwCYAIirpQvboPOYA3ISCzmQNMawLWLqCJiwo0TJCgEAr6PLOscvu4ajkyCBlYbsePhSDJGcMGJRBoMLmAO7kQB0onsnqnshgho4YrrAMrn4ShoIrch8ZQH6PVggP0OngnraLUl8qCZnl1OWJGMpI4PgTUGYDgC8W8a1kiUnhiRkIGsGOPH8VAO4ACbwUnsIBieSnUEiSDJCScAsaiSpDSdQZiSeGAIeD0mCSgvJE-OUHdNAC0OxriZADQcqMBgAGLxA5DGBkn6ZK68GKi+Bsm0nJBl56Aoam7pxMnQlQAZ7HLwk4jKAQZYB36snokcl0nYlilcGiINjIAEkckZC7xdG+E2EdEUmAmj6Om2LogRDlC5zOSqD6ns4ABTh2f+FY644JsQqoZo3QDYzSIZIw4Y9+3I0oTQYAAA-DibgV8W6R6cED8XRvLotuScqQMEaaQHCVIrTMFBaOmdkRhsyTCcaQ2QMU2TUhkJac2OqTaViQWepqkdKMYcaG6oqT6bwcYRrjUGcFgIosaLthjlCezmyn1PADhOiG8p4ncb4kZJxGwJ0jbjJKQmChCkJqKaprXkYsgucWVJcbEJHhWd6dWcXiwOHtBIKHsUBGRF4XTuEbnMIJPOiLftPrYD9HIOnJuKaKJNWOcOoBgAbGWGAQAJOqz1RKQQiRGeA3mI6165GwCPnPmXzQBj4NAcgQlvlrkflQCjoFFaY8DFEHm-nj7-nw5ja6hKBga4SKABCFEsVEyeC+AyT+I-R5BqFOjqROB3yq4uyPoYhUV9kEUi614o5PkoQvnQDGHkiwCuEuEK4Yb0WQCMVCXFE5gejVKcWrmwY8UDA+LsWnC2XPxZjclbSGhMXILCUaDvRzF9KCKHhuDSH-SyVhA2jsBz4pCu72nqYpBICwCtx6XyZz5hm0WwYzkq6AH-Sa7cVAWEablFCPzojjJlQ9K3JDT+D4YPR9iqBpXiCuS+YJVuCtwBbxQeRThakLh8TpqqAmm9KLhaT+CJx3xj7qBOj2iphBgsDZRNE5XAGowIGJYCC0AYGAT5ImTYIbTGwjmwYmZFm0FIIU7GX-G+mQDUkakLLHUgx2WkYFVQBFV5BVABg7nySLHyAph2bSBfKDkp50mVTIAABX8BCAwoyIg681dE6uI1pAd8XueSvy08ARcZyg5qaBQBhIzCMg5OngcQ7gOEcKyQYExkDRdxRu0NLRZuu1cVsGwUcxCAgayArg5AShXpdFlJEh7JUhyxD0I2P4gFvKCxN6SxNMl5foXIrALSTYOI5A74w0A548wQdpt56mwU2xggGw4+NMs++005plgCVuZ55ghxziEtgtvFhGxSduMkaiMFaEFYxkK65I840gOE7lQNqJTgF4flBIFQluro9SCiptfALiQmd6m2Oul8AWjKpgh4hgHg845w5YWEK0gEVgeQ0Y5g34vmlwUdGAQWio04l8PhwdTiodEty8rSlo7Jg1pSKgsQqZgkTQ-tloyCDUqYkBZwogalrxtevaOGHp8AlFTp+tnNxe-ppI6u3ZIZStYZ+VQthVFYG0SlwZzZfZi8eQFGGCWC6ZWYbkvmsEWYQWSkntzYdAQYsA8UJsUZ5gYEcZGikIxNokix3czYAA574PmbTZ0APQRE4CPRyGPedYAxvf0tcnVgvZbY9RWGBCeeQJ7VPnVBSDVI4HVDvYwvvdfIfbYMfctWfdyAEMKrgvCrfdADGUUA-WrImS-SmW-VoJ-XmXteJjkNRjUvvYymEsQt0EoCjiYMA7wegLyCtNcP9EbcIP4BbY5dYG4JaJCFOCwpvfkGSloDyciM6IHe9CbDQByPiKVSI82GFBFDZPlPZMtT5oiCmUNKNL3eKZpWRVYVrTrjxA1QI0YUNE8Zne4ABVA9IxkotJOMRKhg5A8bBIjXqEGD7ZUWEOA5iIYA1Q1LWIWLiJYKDGADMOIJY8KvbeFOnJnWoGWFOMQNtMgtWD1boCvRSJHXIwXU6LBKiCmfcR42uBoLnQYD0EFjncGgFr5t0w9ioNeD4LaNiimPY9pZfCmAFgRMToqLnQM-AEFgANRgA7BEx2h4CTChgNVVBwIIIpwmRND2CHACAo34W9PkBBY4ODNIUjNjOFgvmTOTD0obDSlUBzM0wLN4CqkaAu0OAgXlXLUgqo08gt0HJpA9xfLA3wEMJ72wBcDnOXPzPKBDPQC3MXHjMYCTNU5vOHDzMBZ4Ba2TRaCpgUCATZiuIiQ0qkCTwISmJBjbTwvdPMNEDUiJXwDjjkAo5xGnVVnj1QCcPc1fJRCsVSPb4DScBaEKA3S5TIBMSO19xPpXSKCxDvytwPbtPR1fKhNPEPZ501NBa3ILzgLXxaqwUk0KtgAYB8KNG+a+DEDGApDYpfCQCyryrEqTFv7kBcBtpZp8DOutI1BlFOuQBLAugQgnrOsBY3q52IDtWQnKkzCmGEboV7QUg3gyjCsiXMse6cueDumJxIrngnWVmdGL0wNFAvUWvUggyhSwVmBmOZscwBVDW5Vw1gD67dGBkU1TSY2tFLVKQzz0OXTRP21wWbhKVvo-1EDoGJ6st8jMBhLr5y0vluN+FrUXYUgLz05JXNi3Jd0QiivltYRvXaSFg9K6AztZ4onNjCtmSrgtvGuGtVDbtqt7vUgQh3z55gUYi8pkujvrjAqVLKRpjwiHz2ALgqRsRwpLjuVKQLxJPJC3vwByurpngg1dwaTciZHIky0ZKTuq38ZIX-2wBa3Mbd7eSgOrt+mvhOnk16DBTtEY4OVL0VsgdlPJ3nnUvztCIHNpuhAyjwJVAmxxJ32xmeCP0NRJmLHgMMf2Df2qZi4dAaaXziEZVQB3NXHQCuHMQ+Bs08uQCJw4TjisDnr+BAtBElvkhLirR-guyae1FbOuJfVVCCeMewZXCsBWKBFZThEoaIPdTmc+djaWjkvwC2cXhXFKaEiX5Cu71BclvmcLBwTuAlADBefrhwqDJeApfK7Bfbmy7wCuGYFZg0Wj5fkWnhDTjFfkvBBeEaCSJLjxjOBFdkuleQA76X22TeBVetfyLEguBBBx5jbODLJLjFr8OEZsy8pwR3FpjXqqxLmwCIOdbEhoxzBUD0qxT1bmfhdeCReEbpebviAwvxcdGssCIctctgYBBHdaCNvkiAU+FUk9ktnbfnAICqlwB-isPNlF5+msCHOlL4bvgUh3BR31Y8Mnp-iwiwD7xnR62EaELeMeABeZHvhCoCL+2SiqCIg0t0Tbdo+eCTCOrIIdSTALoDCYXld0f1jw-q5GRo-i0v6tkstOBUbWcI9+myd44mRlTs+4Sc98G8cs9QDvxIDkD8+uN+GnOgLKSOe1djYA-sC3iCM8DK+paWck+wAdSqmTz4-Jth4VcyRSi5Pw5TtQB1IRcvmHc+dqcstlRi+7dXFso1AsX73AVS3fsQW+aaUn3HnZd40UjeTSR32u8wygyvZhKaWqk1SE6EajrNOI14A++o66Fjb1CkB9CwDWE8tMbsBGIq6lO2hucY7d1YBpcXaMlpZMbOCLm8EzDpqBENRXC8P3DFbhbwAbBg2oBE9PYTdQDmSyS2JgDHN3WwalPIDQA98S99-Q5BZ22j-t+tZg1T+99ma7wzjnWuS0BuxbfV9VkAVXYw5ShDwvEi7m9dD5deBEStHdGcPuAY+c-6dLjZxUCmWkGmMPYv+whp8lvAHdH99IAOjZLJIzGxiBIeWfDbMYEdSYkDWGja3BIwFpjY6kt4VQLHXoB0E4+-LNguUA1Awxs2kAXKA-3BTm07eUAEQjMQ1oDBiEOUSQl8hDrHEkYWpfdF2AGoL4OiNBF0oAM3KokaM7gLkjyTRLsl-qToZoAQIXYmcyBSpPlnrnLqMCpMyAuwqoG4aBQXCsgo4iAnjYh5CMH-OyA9kCxaDyAMfWENYUGCVkiAGwJfpAA2CWD9+1gmwVYI2BsorBzguwWylsHmDHqDgtwTYI8F7YLBAADSsFBDKyYwMbK4FoAjBhAyATASQScHzBCEY4OYAEK2BU5r4bKIvmZFoCH07AQkWAEl2y5xsL+GMMkO4CUA58S2WVZvDVzgBdI8mXhNwIgHzxrh4cZAmvtcH7658TKMgioqoNAGeC90dOGpHLFq6EY5g83KKKUhlbBpTSdtFvielup11cOJ3P6OuHHwbRe6BHfwZACdqz4C+bQ7oedX9groGA+-QYbymGGC9xhQqSYf4kXBLQ5IIxXDlnUcgnCywM8FVjkBhj247a2uTwF6AsKroRSZ-Qip4M6LqhmI+w9mv4N5bnVAEEIgIEv3OHUg1eVwiYcSweG2I8gHkRRoIIRGLDm217O7nF1WHB8NhII8-ntlxJEBcoq2P1FP24h7DAB8Yb-FUGNZThfAgg3YaU0kC5BPqugC0NtG8g4FLOBcVfuQC+y8FNsYooLMczBzFD+OOlL3FFkVL+4DMVtfMASgaiGR6slvPbjpUO6AC-wJI93sgJh5T8fA64QAWPlx7RQx+FvJQQ4QOGQBuCepCelmDTgWcYRMARUeRQGCuERhCgsEZmB9zx9Qg0XCkKeBDEgjRcWwuTKEhqQbRC82fKjpAGh7ahG6lVBdEwzGwLtHUyYmsvc15xjZyEZgAsYRmlL-CQ8F-F0OnF+6wBDu3LP-nWXZxEROEBAmAWVBsDa4KhHRTsd2Pd6TcRWJYoNHxVuIW1Lhow0fOqBhCXIqg93DiBUDAgVQhIqEA-OqCUDDhtwScJCJxFTDwAZejLC5gizmD-Nqw3vDTi+T94VBq2t3aqKxWaSy9EwJ4VaOnFdhoVyCGrAuu-HBRbi26sANpvnWvH2AZ4t4xAt2W64bJ-xFsbXP4BFFndjAfoYklRGgD38meU4yAKqXvEiUqogg6tiDFsa14-hDxAmvACoAJjhKqY8ibXx7wliexZJIgOZCWBMSTgJE8svEUtHVgQQ1TDpqxMvrRRAJ+rR8StR4nR1jWoEzwGL0EkdNlq+4+gGcFQ7sDthTEt2EsHSg4Qyo7EoXjLlWikRp48k-iYGAUg3RRJ34nHlxzsDSTo6CIWXESLRq3EfwCLE8XAD2HJ8vxUzGcenFKphBu4h2S1ms08BWSC69dcyXjwFJ4RcOuSHuEpI6JMSAAzEsHQJ1g+K2TLqkIFMkBZ+ckwIKUFhBDoIVWAQLKBtBMSxBOuKQeFONSxCJ1EkMsPibpNpb0hrwoUu0ctTcAIApIWHIoLSgdqollhclJyd0zmAuT1weAMQnSXRAZTOcOU-IMtBDCAtOJ4HAUKC15AGT6pdEd4awmR6-MMpo6aaZ8iWiYc2wGoMJPhRjEX8VA3QfXtCM6BTl4+DEEvt+mMB8hsq62ZAawwGDfdpA9WSeO8kdSB5HANRRXnYFS6FU+APhPHGVAPbF5IZLBMbI6nISek0xmRXimAJEaXSoRkAThpjUun9COiYbXhhIQbDiCC4GQqYtoOulnVeCBEDaBFHqyajYAbNSABkLMA89WAZUR8mBmF4Mh34FVLuCWBxKKcmMZAVgJQLOA7E1OkAWPsWw6JxA+i7o20QhDLA8p5MKAlqfSHIky4vA9o0tiiMDEsFQZh2LITkOBJZgChsAILIACTCMANkJEJmzdCF-ZLOTP06yz6+q0vWlA0nHpVHqmQrQNkIaJ5C7ZYAK2TbKmJ2yCBpNJRFdOdmqcoAgCOqPcDLCjowkOYekDMGFAXg2+Hs1ERhIyGGzfZxsgOcl0tnWzfMtsoueHLVgCFXyFM8gTHI5zegIQS5ekD321yQMS2PFT2frO9l5yS5-s7yIHODmlzQ55csUoLIdFW8-REsqWYqTMCyVsuDE2uXLOo4KyReyIzuUpm7p9VnwMkF+FIFWjQAywrgP4VYG8ljEi+-kn5qD1Hj8hAii0vEHaM2GvEHZ+IJsR0VnmOB55zol2UhjdnRQrBHc7OV7MgCHdf89ApMOPC3DOc+Zw-MAjREESfJ9JA6VdI-OpGi9A4cQNiAvMIF1yZgv8ioDkmboPT7qFwwBV3OAWcTQFJ4cBbaEgVGsSwz8GQHAoqAIK+JyCgWEBwIaw5hGcvTAigov5iB8M1oXBiYFDYw8Z5B4j+dLO2HfyraYgQ6P-KGGkK0uVYuakOwg4ZxlwSiFodwt1D3sMGsLExE1KpZ49gRlZVBUqU8BuwsFMiqABrMOhgBdBp4bwWCIAV6zlFtiVRYdPUX2APQFEbRZVF0VblqoJowFHNXUkWS6IfCuMUwE6Qq9X5THCRcl2sV1zGKfA0pmhjsGuLBeZsp4PVReiwg70ysifHWySygoFaqjY0NmCkT+I-Jx0cfIsMmi25alZQC7NzBQXBFTcl9ZJUvMgDSk8Q4rCoK5BmiX09+LixRW4orH9KZcuYMxuEpMWVQxA7S5scKEvrDhYgRLbpbwT6U9srAgy4ZatFGXeislGE7ZU7hxCzLmpDU8QIsrOnRKXRdhJ2e3MSWfya5NIuuXHOuR-zMl4ywXkRAY4rVH2WgFgE4Eqi3sTE2oSgPbnrYOQ0laTDKeTzHZThvaIldEJ9W+ozdpC-AssEhR-wUNVQToKqTKGmpOAqEMgSwKoDLD-UqF1UHhvcEcl6sOmMYsbPIGAybLTOyDQZaa1kY4wFFJCiZVz3YAAr6FM8FlbwOzJwr3JCKsCEiq2nsc8gNShZDIxkIHyHANCtEHioagEqE6RKk2iSvMBgFyVogSlTUGpVW4pQS5HOgyujq3LQRORZOV1HEVzypFMsuuagGOnM9eVuswXrKXboA8Iwd4wFWAAACcHsXMNaHeiNKIg240pksrO5KA-pX811e6sETrLZcuM7YccqAU+qkIya8CUP3gLJAQ1YagIKaFskRAU8s+KKLGoxwpAsBXQ7BT0rdX+rBlVkD2IcozU-KTl8QHNf6p-L5q8wwa0NWYHDWmKqRxQ7MLw0eVvznlzqjHDYqF7RB8QGSsZXyt+XERWw0K-tSKTAAIr0az1bkG7T+g9UCGv5RdaIFuplg6qw-TOP+LQJCAgWIMYSVeoLVaAK1P0KJbat-o8AoIjqyRWysIwLAG54eLHvR1oier15AGoDUuU3VMKDkM8ZFfV3cpBkyoWYYgKNBPDupSJCiWDaOqMyxjP1fuSuVOoSVOr-18RSSOOO+WrqMJRES6TmW8g8Byl0HMBPQuSBvrJhz6GTrRE1W3rq19lTfiPnrXzqW5DkgBAJvbXTrqNQC2jaSwxFcgzGdtNjWgw43GSuNIJUwLxqZUlsWVnQsEcJoo2olXIXK7cMFCXASaElUmshdPwyBhKCcsm+wKrBGI6bu6joKBf2vCkrVYNfEQVIfGEh8av1OpW6a8sXmCMDNCpKjV6po12bMC+QdwExr+jPrTS7Gk8KpqpAIUQN0ahAB+vUrqYB0zAX9UksTWNqZw6NcDUorGEkk5YOIDCFiIahTg+SWgMKMoBAgjIYmmQeOgoDhZcA74SkfxPNn83tC6+ZGi6s4Fb7l8ItEGqAL0MnU-C5IM8HXPVAkB8jhAKYXQFu3E6rxqgPOPRHfB74grOFCG6AD0gGRaBswCeHujapy2wYG04iiEeTPa5AJdwkJUgCoIJmEYLc8At0BDyv4-ZteTgEgs4Iv4k8FSUg9+YVuC0NqVSPAFCqowNhWt3AQ3FdZFqAXWbGpp2zeTYCvbJgUw+sTwEbGy1911MwGaGKEREURzbQ7E-TmDpeVCa65hLAriBtg1lb+VeuSrTKC3bpb7AYBOhcPyBQphU1dEMQWYov58g8dZUJYFgANhuBKdTyu7XEQe0IivRa5UgDsFF0uJ4AGTMXRX2XXTrSNRW3grwnPXq7-aOOuHU0GZ2C9VdogcpR3VN1476NmNNQC4ALDZQatnIAneKWB03BqQdZSwNcVB0zrhtu8UzSQOZ4d1odgMpHZNoupmcTVK1dUDDu5Jw7DwdQjGjMtoADb9seO4jS6p6WnKBlPi4lhHqIVrzytUAfPdMs3UJ6M6SevHSnuMbwaqg5IGbh7rHkwBa+ZUYwjAPJS9ibpUxTEmpIeXkAlgdYJYHluICpiPlsnBRGokPZMzYGou9EJnE+1B0vkGUupp8sslWrgpo4R5Mgxn1zbWQ0gByOvqBXEhQV5waaU1pGIZiwg2ocQLJpK7yIumx4waWqolZgRn6W4Z0DUCQoaL1GP0bPgYliCJAMpVKy6DSsCj3Bppo4AAANo1AUgqUII0iSyhBh4uHFgXWR8qJBgUJW98TBV+Qdb26NStGqO2XFnh+O1YfDgRqgDQCB9IXARPEsyqmUk5NXeek8rLaYStAGUv1SdK33uTcJnlAOggJ6QmxSoR0-1bNtq2Fqh11BEtTZIORRrNNF-Og+SluBEamDhw0LdrnC0cHoGXB9VkBOQi3FppnIoQyvp6SjhcFA6b9m4mh04IeOM3PZc7odpFAvkvkk2qpsxGch4oZ8ddSfPtzPoedBayGiCGMO8C9xIkOjRSBf09NumqASYBs0UBgREGENbLv1T5Blg2s1WcQBlNISmBycGR0QHtN-1egB0DZSGjJEFECQhIXiag1dr73d6RFkEHPVoZExQb1NoGu0XPp8SGH9WTiRuQJO31BYzDFVCw3ehv4kQl9x+ro1cpEBbTvhGU5DahvQ0OBMNtkbDZzugCmHjJ+SFYe5XqOE6ci-etQ2-Cu5SCqhfpM9V8r0MLFzQFrI+cJDiDuUhQJEQvQprkicbuD7k140uvIDTSTYTldPbFpu55B79VSfw4sPpDXQ91k4A9eyQ9qRgt6HMVMAvBTgtbbdxIYwO8NdhgnFGGU5uDstuo5TP2IBo1QyEDWZa71YQHg5aMfWnhdFuQaacmBY3XrX1ymk8BaHujYRFieI-wBgHi3uUAgJwoXXctUMiL00m0B1RcYNqbxilzPMdH-uiBgbfGhGXoxlM7DZlme00rLg-zyVnK4QoxsRpozvTiH2A+2r2ltNUKcR0oBgXiFkGlgIcUm+IbhevrlO1JhA3w-wJUoa5QZQlhoJU2GyQ3eHBA004Pp1PUAtS5lLU2IwiwIHimx9cisIjKZkF2KwiqpqAOqfclJVNZphjymMfEaWGwA8BwUeSHcqPIUQf7TsgiQw6odvFB+2rXouN6XK4NbW+hCEtipimTjIihg11DUnxrUxTavg-YAF1Ha59T1AUkvvGMLxoYiY4SEkE-FGHk1-BoCXehmBSEQoNmhqGotzUKGW2yWz-JEZ-ZVTsTcvDnmcsDLchlzIEmk+5JPKgVzxFQFMFQBTCtSA+ctIPg5Jkizm3eh2AE-Ge7NLBHZw+1WKVMwUpnzq1hkiYIgIWYFxzy9E9uMaWOILoL+CyvIQoBNgAzTKihqBlIHRqAajFIIeIoiryhnhjD0SqnqpWkDo1pUlY8sIAzBHxuoluduhCpHaHHxSCZgRXjprqFhRF2XMfYcyWBWKILvBNM3CHfCf9nFkm-QxOZKrGmRDK1XKIKzQhh95zfyPC0ma8AwH0mUhHI98aMOV8IzlrbumYBykbSx2r1KfKWb+jBlPApkNisCZ-Ph9VQOZw6J2ZoOQAEzkp5BH2f2WzrKZ+RNJWHv8vwXiqiFwsytWcvzn-LpgRc-q01NCxtT5Fqw3pbZ3nKHIwfKE22YDPF9lTaeuzK0pppdmmjg+uJUsB02pjjNhgEoP9A5Ui8dZdx49tWGEPdIoralgcPFY6Yb6GOK5oSala+Sbm0ddVz5X2rtozwMpoq5sLCu2PkXxodLfJLTA6RLgiaMxji0RUAt3BiJSwfqEGl9L6dLj7XATRJB0NELGrLHZq1OciszmOrcVvox03CPGAdL659w-qfFaRB4Cg1sLaaSQ6HyJw6NCSB4oahILkSp+j47VvmvgtZrAhmeM+30DO7vhaKuG04aJAyBLw4C4E+tdHKbWNDFVz07pvfIyDqrpmg9adbCuXWFLbVm63Oc6v3Xo6j1+AM9Y3M4Wmp0RhzSwBGKwqZYwRuoPczwxviVrf0LG8cdKtXAhtolpTCgC7DN9RtJ6TObcYuuTnKbiA6m7+dNJLHfAAYWPkuCZtfWgbtMWW--q3W8joA-IzzRttbDqgi2xVzywmZSBPT-cqYhYB80QQzDyb8WMAKkYcAoYNQohsAHJYismm197k-I67aevkWTY+kAAiCtp6Na62FAfWNhBhiXqQzeJ9ylayN2LCNogQZwKujhQmxXIsdMdoO27UyMVVPIHjk8ZkDdUzYR5CoAAUpq9tqacUAC6VdrFsN6JEtg7rIyDEyWmrZ+N6o8aPCLGfjXMvw67H+PkW3E4qmhl7VSYtQd18vcVnOK0Cudr4p4z3o+fsDTMScFlo7eeeXsebIphIDQLFAsv3mveT5giK+c+RpaAeZzbpgi1o1RFJw08dKe5J6q1gkqyCcy2OxRBlNGRqHU-W7oHVg85G0N1c0pH-xZk9e18c8uh2xGwUAOMkJ4QvoCPJhgEngWKIRPUy5Qlg4p1MY4rJUKASdpwhW6PjDif8ORSjZIEQ1NzztSlELQhgHDVgfjFAJsAaRcwSN4AJzgSbcpgSTrqMTzPU5sC8MvoC2tAo4OSz-mqiCAk4R+umwXQVUQOhJXiO2hXaSLGIlI6+lfUbYYFh19AOUggXg7tsO3dOhDnASQ-wEZm0xZwREPChLOWhTIZYCu0YqKiZJGo5sW+3uaRiLUZQHFtvfpSrm97ArhGAMScS4ICJLMmBEJ50El2iUsBkAK3Qk-qy5BPATjTwOpF5yI87QWF4SOQCydnXid+5ZkSYBJ1WiCBzRUQGzBMBwxxF8IUztnCBh+mWcsMFdhqLgDbduIaXRka4xrF2c+siMgiCoVKS2tYAW4gRL-1gw+BY+sTogAoEmAm9BNYIw61QDlI1nKuxEwpxbpo3U9p86z00qmC2dN9DtmPL1mAH0gq8XwXUQp1XTdR70dlolb5KQ4ZAlqCc3tHUCI85M0ZJIXgP60MUoPPw9ZGIFyl8ncOGTC9XlXfB84u12DeUO1OZxjjsvD7oAFGRJ68nujK9SmSIpgGi+UUUkS9fe8RD4Hl2cNqKuXAYVABJfl81TgbQl0QCTQ0vbF5Ae6NS+wCeD8N0SpjD7qOir4oosIKjLogJrII9OKz0yoK5ORRMKqMgeBC4B2fSa9nQZedrUilcLmwAsr+7K5EcBwlqoCSFk4aAQpXP9XUUxB3dbuCgcA2c+MzfBO2Fln1AwrhmQvKYyyclgQ6ZfLUWn0wcyHMIpjN0ATWZnvIOLry9QTgg1AJC5LoN+pE6fx82AFPM4UwBddRv2cgaPOGcAB4syOXZisbM3COgXD4Az050YdasQUbuS77WGVHrL3WC4QWpM6AjbPbajg8qNjJDPBKCN192BQTiC-CPCNNfAyBV2Gq3QKELQiFseskuE-Y-U-TvVVgRUb6TdtfHpuNopnpgDCLoASXBAATe2GHX88T9baJ11A72jS9LOhFSoA6j75bc9wtO2Cc8CKMnQKkOfPu6XeDJ1ASgNd1CPrWHWku6gEYre73dV8K3R7xQCe+KZlgFVDIJ96nuXhnB-od7gmgRK03ekooS8996ZSoBoa+iE2yt+BiTjqBi+e4TMq0jQ9ox34GkEfr3Hpg4wbXCH36Ii-so1A1B+ecj0G4T14owMPgImZm6pF5d7bggYgAn09LIeZB0pAIDCGHdLWsuEJDDwB7HbyWQQzydJfYF0D23vT6cYd6GFA7IczSgxy8wGzMa0PEA9t+IB1EvlwolIIxL5Oglmn5LtS8PSdynEBfAqZQSnkT9gQuf8UECCkqpNRg2TfD6whWDMnkA2AJHr4eiAx-6CXhbZkm8Ua6Lh0PSlSw9WpBbVfjhbweMcG0Tsau+S5q9OJWCot5xMy6ZfUuknwXgit-cgeKwMkfY9nxItdR9AZ5gXk7negjtUHrHRwPaB6q4U4IcE1z9kx3B-tdAIgujhJUmFPMXmVAP5p70fUtv-hEILAqKbw1jYBUCVcgMmJo+wjeCWtesFRHldkLrh4KSYWAVyjiAhWqURICmF28-RECL4Tb-AFfOEivkDdcQPUEIUVBktS7zIuIjb6FvTKqpS+HqSK+7PBjaoRuenDvjW1ml8qsWbrXDrgnNj4+D06sg9CnPme4kdsApL+icLYVrsOFCqwXeowPLXL-bKQEJreRJg+fDd4TfOq5zx4ppJ0IF0Df-eFXgPhGD7NqqIAwoYLnHWW6rq0-OJ4QFULbqR-09kW2EQ5pR6Rdk-VvzrkKK679ceu84XroN26-9dcHoM8b4N8S7Dc6D0gf6NX0m-cbpv6XCb6X3r6tosvyIsblmWr9Ym-QvA4uk31ACgvoc4Uabinhx-m8ls+Qvp8S5MBZpypsvX31M1pbyB-DBMkulMQz7IXHvAXW1JgUIH3v1eBo+iBa0bbcsmCTmhTqD-1ynowhoOlLFecH5SwXg0mUdzWzhe1fXQ927gfYuYFT9ayTE4lIP5VFvzTDFacjRA1k4ZYpfYMT+KwCrxy+mV-CCVOaj38oPbf3FW56ahMLpXY6DxQ-yTsXqucLQKd9Mdus2YTK2723DgB2LQ6gkYjWkJwYy1k6L+1VkFXfzoP1yoIZPW8f6AP+dSE-KfZvCiP6pySwihJs-9QiP5zI4r0DjJ7PruMJ5U98kczzBA7QNUmtIRBHpCz9BudOCyh5KeVnZJFWHVwY1BTHyBg8uuBA0c83rA6HZhPKG9DF9x+fJ2hgtZJ1xKwrAICzhwBgQfklEg3WAEdRSAcgJSxWhKADdgxwOHAPdOgBoBwgGAorEIwAAVlYDGA9gLkw+QbgKhxCMcyFDVJRIQPJI38LMHF0QcAYE9gBAorDV990X00AEOue90kY3fAnxdFOlGzjs4XyLWjSB+-GQWMDtfVZGFNOtMUD7VKvdgJ1lo9BPkeIWmHKzuAZcCOBlgM+ainkQIKCrw7NKoDkSn93KMz2XBaQbdT6xAqaoGcoFJU8wXhM1EIFYQqgEYEwBWwGHxssswTvyzd25erjYhiOd0ie4l2TfH90IdQ600CsNA4mYgyQckBM9OIP5RChDgQf1vkx-bfF3d73Yll8AogUgE+gBwUwGEorQWCg8hoAObhuFiWFUGa94KYqhDJEGdEH2ZZOY4Bl4apZIAkDQ1BjS2hcNXQM99cg6LW+4UIelFhAQoUwPOpnbZID6x0jEHnLcjlTtSAV2oLDXrBGlVKAvBEHI5BUUjwOakbgKQOzwyRovCsC9s5iM4MAgl3Xs2CBFCJ3nacSglg3tUkYNQghR+TWTX0VTuDtUs0wMDmyQc3AWEJi1EOEJXyBjAR4AMA9-O1ymRIQxIHGDwgKVnkskKCPR6Qo1PGkY1mwKGzLBkgAsFpDebO4LjgJHMalhA1SJ5xUgn6eZBqkZEC7F9NDkaT3fMAjJzxgC4UcM1KQ6fdykzgD4PIXlUuxAdTsDW9Bo0gBLxSeWulpBEBj-IfGdTHIQ-uPXGGl4ADZi45wKdhB8UvqWVW3sZmMsBG9XmExGxYKpGvygoooLCDaDZQ+UKPhmEPWVVAZQ5Lw2t9KUigxZrCMym8oiiESj7UbKPUNgwIUaggoAyoYwWICpBeJzOBEnDew3EJPEthfI65TuE4IS2R-Gh02uRlBF9n8BXgS48vQNwO5Kw1XxLYB6SXmTceyOegUdXOXUUMDNQsykT5iGYJUwZvXDHH9DjgsFFlxdiesEf4WpB0285A3B2RPIdKRUhkRR6d0RUoldWDGFY3tBinDEddDHFcBWAZ2xwgZicIgntKoBz3qxtw3cPgBR0aHRY8xhQ8N0AqTE8LYAzwjfmYIDwl+xnhb2e8J3CifWggPF2cOYBvDLWDkzxwmLYzjHFIwWXmEQzrbcIAAtUgBcAtaAYBgiXAeSGsc6wtgEQjkAVwn+1CMdCO9sakcpTxxEJBAEu57tYZxrYVqBcRPDvcAMT5BzsSQUpw5BUL21kQxaiLzxyWUMIqJVIBHQ-9KhK0B-R4Acbg+lzgb-BftJ-G4TpUluGUAc81uDbnM05MXiKXBpSBI3MDBI6bhEjhgvb2n9zAQL0mBgvLaEYjQqCLzMBfDV3U5gLA8OmX1OglPHG0S2aeXlkIlbnClN7tVJS1MbjDom4tDYXixEVbI2xS0sTwl+R-kaLD1WCIh9dlU30GrXs3u0hzIKMs4J1c4yuMSITcP4xv1e7UA13vToyZ1FeDQ2UUybYbjOB8tA7jwMKXDogii+XIv3S4wQ4BVzUUie1U74aUArkHCGge7Rd4abE0IFhk1B6GS0IZR3nbCMAZqN-NQwv8K6hL8KUO-NbrbWXnCOQccFtB8g7oi-8lw2XjXpQyBRyDIl7C4IxwlAB3iXBQQjsMGjA+ECS-NzAOwPvDbQBsI4jfsacVT1T5Ie0X1lqE7SyJjos7C6JVoBsJyUQZKbVWjL8EFhalXOJiKQoGwoiDZlOZe+wWjVognknCswHlF9MmuUgBa5vINrjKD0Aklmq4cwKAK4izrRLgK9zqFKk-MykCcIy56fCsMCJ6dQXULEiWbqFDtbkR-TYNxAVGNT03uTQE+5YAb7jrF2GVsS5kazZdlB4e7NaMI4Top6NgBiOTmU9c1SUGNpx12SgEWcnpX4DCQf5THWRJQPCICQ5KoJrxW1kgrAHwCPcT8JwhZSPtFqI46czjvlTQbFzGxIeaHmy44eBPzIUkeH2lydBrRnjHDGdFs21loALXg6gLYhqmVBeGcnhZlqw3CiZ5ooPAEN4NFZrS2htuNXlH8DucOL79whb3AIhugB7grEqxcmO9wWcV2OIBdeYcIN5qeKMJpluIjomKdSdW4BVhI5UmIZ1IXDKI984dcXVTDpdeXUN1+EMPT3YzdM6y91HKYvVr1DYevT1JR5NUMkRUoRwm1DeCRxxMg6yIREPI9MToJMBGZEvDBAtSXPF7gWhQxWhQgYVQiXhbWTrAdZg2V1lrR60ZNCpRm0dNHIB-WJIiDZnWUNkyII2SAACxikGIGTpSfdhgtIY2ILCGU37MIETgeAbB04cAsH4ClUKwVcEDgLkEF2KVPAbFVdg8PFMnXj7WA8WDZfMXeNnAdCY+LpdYAYNnPjw2SNh9ZC4QEAgo4Ep+KPE4jC5j0hDyV+1a9u1NsBkBOFGkCJgekHkJbZBRYVGkAzIAZCGQnAHpA7xyUYdk4hGQ8wEMgHIKRy3IGmasE1ADFa2Hq4KuZIBSgOpUZztZN451l8x90PlG0IT0b+KIwT40IBQSgzS+J2xPANvHsA2EkwCfjHJR+26YfgLCWFZkmXuBpj8zPwH8BH1NQkgSZEl1jjRiUVcELB34WwApQqUdXllxohWEB4BcgRBMgxkEs+I0TI2HvlzgyzAxJKhq3IQA6Qlo54zCBYzYxNEBUATiC6hgLMsBBARgTMDMg+ybJl0BnkCgxQJAwQeHUIN46BOdZt4+NGQQG0FNHfAT0IZgmdiALwACTT4kNhCSr40gnqTL9Q4FjY70JPHkZR4oeB7YwTJuEvpSWUgAPwiEjkQkR26CQBQB-rSITgA4JMwiU4g47oGrljKQeKjwY8OmLb1JcAeJaod2JgP05UiUlkvheiJgL4JzSI22f86SbWT5IXyC5NDDayLHTKBwAl-x6wrAC5MLZDCNUxuoHoOzHeS6SPHFyASQHgA4B4AYMPuYOw6fnv1ncFSApZog2yjplxYquSm5XZOWIpAFYjoPOA09FWP51XAcvgVFbwF8nv4oYOUl9NCxTA3fAZ3Ftg1w4aN3BAB9gIAA")); })() /***/ }), /***/ "./src/js/built-temp/base-ja.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-ja.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpg9gyBCR0AKaYDsGQHsMgYYZA6wyBQxUDmDIA3LQKAMgKwYAOpEBG+psBJDIHGYwAl2gCwZA6gyBABkCt1suOBwSMCLaYGsGVYGMGQGYMgEQZA8gxbRgHXlABCNAEIZACBUA0UArwMBVpUA0ZV1AO7dAcGNTN0BT3UAWDV1AactASe9ATQZAaIZAJoZAH4ZAA4Z5PMAgBkgAGnBCSAAbUgA7DBp6RkgAbR5kDABdYABlKgBRAEEAWQB9SdRUWYBJacmAcXGAXwB6OlhyRGgduAp4WdZMc4weADMuG9uenf6h9VbmNk5eAREJGQUKg02j0RjMVhsDmc7m8vkCoXC0TiSRSGWy+WK5UqVTAgCEbQCBDIBIhkAMQyAfQZNDpILpAFI6gEUGAqAZQZjEo1IAihhkgAaGQA3DCVAJMMukA0kaOQCmisTGcZADIM8kAsgzmQCqDITHBlRIBOpUA4c66QBQcoAlBnFUulgD8GarvCmaUSAAHTAIGREsA6RqACQYCo5ACYMxPMaMAh0aAck1CoBR-WtgCEGQBRDEawABaMCACIZA4AsTS8oiMgpFYtJ+McPQARoM-lJpD0AISZ3SAaNTAMtGKW8folQaNVRNIMgjkATkG6QDqGgU-YAghmreTDYEAJrHmQCLvuZAErpukA77aAHQZ5QbAGoMBtUzb8gatjkAO-qADQY3I2JS2SeT67pAL8RgAIEmU196AP+dABTqDNEpTKjn4AEYAByAaAVRFzAJsMgGuGKuBuYgBTcoAMfoMsSuheuWXiABFygBZ2pUvaAGtyjgdkC7LSIA4wwlIAEwy6IAaXaAJkK5ZGnm7x3g+uiAO0xgBiDEyjgRu4gCdDIA-QyAM8MvKsoAtwwlGxgASTqIQKAPpWgC-ARKgD+8g6EY0c4gGAA2mpgeBh2E4R2eSAAoMjhCsKwbGq0GaDKxHHcbxfHyJJBSic8mbvD0TQ8HAgzvIQYA9AAVIMYCAAMMJSAPUMgBHDHyzmEO5nmAGUMgDlDIAJQyALsMUVsThoiAGxKwgAQagDaDIAyQzBRAoVgIA3QwlIAawyiIADqbJal1ZZTlrkeWAQKALRRcE1XlgC-8YABUrwXggD3DFFgAnDCUxiABUMgCzDL+gB1DCUeZgAAFAA7IAEOaANTmCTJJ4RoAJQtXVHVdZGMZxj+v7bZ5nzsNwfBFoAXm4SoAlUq0iSRqACbkgDwf7ZOz2Y5tmZqBojwdZTmtIAjAmOIAAHKAHtq-DKbhuiAF+K6XiqtJF6XZDmwIDLl5QAInctzwOQ8CtLAYDIGw0BgIgrQACZgAAxiwTRNITWDkzN8APFwJNk2AADuPCwMQYCkOmcCILTTPQFtrSY3VqAAK4cBwEuzVj8D2QAbvjYAC-AYAEwAjnL8BwPANNnbrfMCxTevGwcPC0wgNOIATiBgDsYDQPAxOkLcYDpnLPBNFTPDtJLJ1gJMHuwBQACeJOkFTFvEPjuv+4Hweh2ALCa9btOkHA4cAMJtLcPAYHLhzpkzXOsGAWCtPjiDR+Qs3F60pflwTNvQKQFe0-AJwsOwHs8BwA+Jx8-Mx7UHvwKbFPU-HBNSzLnmTFTwewHwrSIE02sx+w5M+x7Q-G+HqD47cFCk60-dgP0rDkKQmvIITsCs1Qyd1yguu7y7VNx3IHLD4YBH5e1gHHHmasmh5hXiFOqkxF7IDlvTJe8AyL6Q+mjQGBkKLlH4IAKoYSjSDYoAXoYShMUqHmAG7xAANUfIDsd5tSAACGUQ11BSAFx5OikoZTmEAIOeHZpA8gGqIQA8IaAGjI3QMoCiAAMGWkD5HCADXlQMoppJmHWtUMAVACaM1IPIX68EJSAAtFNwgAuj0ALFR54UaZkAGiagALhMAFcMbFfI0P0p9dG4cegVyaAAXmILAWArBoA4B2DsYO0A87kCplwPOyAXitHVvzAeAAJAAcnNcYAA1DgmTBiABtFQA8Po4wiRQKmzxvEY3gZ5Lx5BfH+MCcE0JBxoGkBiaQOJ6YdjLBGAARVvqwAAUqgQeXwOB8EGAYuC5TamVNynVGpdSAlBJCTsHmayuAEw3vzNpcTyAjPOuMgASqbTe0ymizNqtU7xfilmNJ2DcAWct0w7J2NHEWj99nfHGeQpigBmhj5DNdY-NklPI2mci5eUFk3IaSsh5xAnkvLedAD55sLqkB2FXYWOxSYmz2QcSm0AmhN23scQ5UwsbTHGFwZAVNBiAG--QAzFGOEAEPK7VwXvXcYMOoDQiDhMiVTAAMiHAA1t0QpxT+W9j4cYQAjlHpVIpABoWx6hEAwC0dMu9GAEEaC0RAGcMDdB4ryQAtHLcpcpAfGT9yDdCGoAS4YShmsaALXu0BKZU2gDjRJidrV4DqI63l8Bab9F3iMeAlxDjN26Fwf1TA5a3FLrQLVPKnVkDlq66m0BuiipVS5KAyBA72TaJm310wY1EHTAWkl3QABCZaoB20ZlW31VBFUuWVcmyAIdS6tCSd0EQMbIBb1fkm3NUA2jwFDXnamkwMCkG6M+MAgAlz0ALJKdbIC0EnW0d1M652+oADy0AAHxLtXTm8147pghzlggHd86wCADAlU9yaiC0Eva0a9xtb37qPQ+p9o7IDjuSb3cgX6oALsAEJmgBk1L-bm9dQGK7QFA5AA9x6oMwfPQ3LGiAY5IYXYAU9N0ONFoFhmOiHZ3dBQ2AAja7PZTvdSMMglAKO0a3dAQ9i6135vfQgRD1NN0ZoYxQBg+6uMfrY-esAe6WMZvY2u1N5BeNUzfWJwTTH93ybY1ByTomeOHvvWu19V6eMUZ-fp5N7bzXCvgKRkdsHYCIHTN0Kgkxa1nsaFOg4pAmjdELlQQ5Aq1272E1ASYAqW1uaIMbWmXxujjBGIXGjxA7jBcgCMZJywABi4Xn1MEuP3boIxUCTELuMVthAthKpzZAROyBSDVspg3BTtmiBb1gEzbomF-J8QHSHTz3QjKcR4vxRMopzB5EAJ4MbhRCiV0KyNiXFJC+VMAaUwgBwhhooAQH+ysWbzYgEO0xCZy2a1AVgRKY7dCEVFAd9NKZYBaAa31gAXszkoAUx1AAu1j15ArAhMjEQJrDAP9ujxRirhAdpB2CtBGMB-uyTevdDwWUQhxCyEUMqAOvlpShWtFFb68VDl+UDuTk0Vg2iCVEoQN0RlLL2oDvTE-HmntyAAHVnY9vaPD+8+DABSDOJDwogiq2rCoANoZ5D8EAPgJgAyvQlIAXhDACGDHqbsVQBsmWG8KAUhRADSDOYQuxAn6v3kJdwoTJ5B3kAPKqgAZDP4IAfwSHrEhrAO11-2f4CvgJrbzvqjqSaPQ7v78AAevxd27gAqtj1opAeatG6IAWDlABwZqoI6122hb3fdgX1gAs32lBrwkA6G483WID31clADxkQ+AdpNE7VvO76pKfhACgAZJxA17GOhnstjw9DunmbM3t0Y5WyGCVYaNVngu9SAYGLfgDt-sAlFuO0QUgOOoAAHkADSa7E5Mwp76wAUkqABM0td0Xb5q26IAWoZADHDGxfKv413k-xt0EC8g10E1FmpqAgBYxUAO6xURH-Gy9t0Bx+VJAcI10sBYARh7NqYR8G5+t2JBtTJdA1c181YvZ4B89h1fVABVeQlHf2lAKA10ADAXQAY8jkY11El4AeYg9WAqYm5U8oBoY8JxEChEtw8KCMBDhE5x9IAMJuQ+RAALCMAC5PJgnmZfazCtamEOMfE-EoJqfgsrCAHbIgB+H7X3f3eAcYcgK1WfetfmdrX1YHXCO1B1CLetfYboQqIqbCFiUQPQnCRwQARk1AB1U2W1MFJBwFkLAHkKgEUMoF+yd1fhGBQX7mgHH21XNVax0KgDMIsKsLYhBxsICEAHylNdBALoX1SIkoFiXQawpw0kNwjwyAFQgVUgPVDLPbJoCuGgkIp1bQmgyAB8CUQAKY1iQNEkiTDUjiooijU7DHCVsXDci3NIAp1S5yBkAfC-cf5VYN8KictB1qjuhd8LEWiUioBAAac0AGV9RwXfZbPIDXQAfH++iO1HcxjX4JivZt41CNC8BKiWtZjt8d8ujFiUs0jLDd8ujsjXDzN+in97NKBjlDYeBNlNCZi2saiP8ogJQ-QHjugmpdBABZ5UAAIzQoJ8UE8Ey0NHD4jtU2fmYQmOUQ-VQEsImo4-KQuCUQQASE1HtECIluhAAnJVWLcAKCJI13EDCiYkAB2GdiXQQAHqMUgvAZE5QPAqg4tC55Az8L9fwtiah0TzUn8vZsTcTxDoA24hjSYt42h8SbioAiSmpRB-9ADKTaZugJspstS4JdBABcJUAHxzQAEgVHBABuIwlMAHztQAGQjChl0GIvALEeS+SBT9jLMRCQ59VoBjlPZYBF8F8ritDgTJDtTdSgCjDqsotozTTLSbSmpsitspTGg8Ym5yjgy7YHZt51SozfVOtut4z2CDTfVWRfJ8omJnDLRAACX1mj3WzNgHKMPQ2jAH4FLNF0AEolQACldzwsolcYCVcBI1ddBAAVBkABxLQAOCjeT+SMy21+jx1RiCj+h+YizwjIAniUp9SOsutRdAAnBmMCdFECeNEEAH8GQAXflABAYysSqEACPTQADW1RALDdBd9NdzBlchtxyBQpy5yFyPAlzyt+i5ZKDqD-DkBSZyAq8J9-0CTug5I6CttyzEzfVl1wYs8yTHtABOh3eOXI7XAtYL1WNmWCJifiphQVVMj0uOmMQqrM5B5F5AIL3zQqpN9SNNEEAFhfQAQZU5QyQtAoYmK+RRBWLRAUxHBABqhjCgSgEo0SqCk083aEPT8BcFJEAHxXQAYldbV4oPyd9TBVAPBpJHAvTFy90ThlKMBD1AAABi4OYpYiKn4EAG5XQAI3TRBABn5U1CzwsQfN9MaBxQ9SQIQCVP+OQC3JqPmPMX3N9WjHKkAC+9E8QASyd9LTA1FkYNtmy85gFYBj1PxAAPBMADyjTstPJ0rY3Y-y8tMosNcgXraAVJUgWAEPFoWmKzKmCK7oQAKnNWKYqoAjpnwAAmXQXyBxVkFIIqX8YhJxHCGbVisy4CyqqAKzHEgMhU8izzKigstUuihCjUyAQAfvlezVATTerIAEcnxPQi9ABCK1UGVFyF0CYjKBKEAC6GRwQoFMcwQAIptABHHVEBNLSk0UAFO5QAaDlHBSpABo+V0D4IlMAGcowABl9+AlKn4VKTTdBPS3AgKLK4BkbrKNs906dD18byBj09085E46YiUgifEAByZa+U9oamw9XzfzCysm+AY9AAajAF5FtUkA5DwF30ABHvQAJ7VdBEg4IiaSa2aKajhoAaa6bVqGbD00tMsqBWaE52a8BuS096RjBnxAA6L1EESpSsAGIEtPQAWUTAA7f0lsk2lvFllvlv9LEKVtCzVp2DZsPTwAaktoEtJD-ESkAE7TQARBVdBAAwBMACO4uUBGSWxagYl2BAaYZ2KzH1eCuzPa8QEoKSkoXQb2pI6o8YbvX1DOrO3QQAC99AAxtNOsAHiGDXQMIIPIDwQAWBVl1dAnRaQMbvSqgtBdAeC8gka2hrLABb9w8CJKxqssPV0EAGoVfEcUDsB8wACH+91XZdd4BbgfFNB6lllQlSCoFyAuBUUfhNBtZnYQD17IBZgq5KZhVNBD0GQGQLLEBD0s8NKAgrFABIf9jpguTtVlqyFXzWCwjITI4qgB7P4GLqkMtv4AGqdANHkEcBSnko8BrB-NMiEBSkqBArkP6MCsLmvVCuGI6t9SksAIWPYsrKgDiqNuSt0GIZwjSponUSQbyEypmlJt7iJjytECKpKrKqNAqszKIBwevXIugDjVLiDTfnwfCp2rTuLKgFodIemIrKhMtt+SYhwglCj0AGbYjKsAUq8qvYgRqAOgb7bw2mAmQmZgRqlncgNnB7VO0IvapiEa3iQAdoZABzhkANhkAGylU65xhxNxzxnCHx3QZ0iUu8QAM8U8D+BlQjFABleUAHmFKsA0QMRwT0aUDwYwcwMAOowAUQSvBXBSRAxfJebXHABThhSGWxokAHvlESQAcgMAbMH3CB8FD2gC8HGlqnbAzF9NZalsNATatNZE7WBugcxABvzy-3jM9iZgdmrQDiDgVO6BFqKpo2jlYFQCJX7lfiJm6CttEGNUACNrR-Rq6guZ9OcQ7oY20QcGcOtdU7MWeAaYOWJoLeU7Go2wUqK27-Xpz2RfWqt+YlbaqAIO6UUQCOtfByBzJmSYa9UgP5ngAFmi7oaIEFkIKu9KUQQAHQUjn4zo4MA1V4AQV2rfVkkg8sZ+DABwJUDEAH+zO0O5zZ+AM5hZ9nX1Y2r5+M8xpABOpO2-IuzOiBxAyYuYti6Yy4E2AVI4WAataqx+OHX1CaqahKUQWQQATu0c7Lbr9SBWrq01ZYAcYCYtraKoB-bpBbU2JAAphmzsAEhzFUGIelhrfGEYS2emEYHgROC7M1y1iUQALASChAAXBVhNuY5evVDRmaRaIb1I5fBxjlDcDXDagF+UABWGQw6Y8WJAcgWNw17oIqkW4a0au5ngdgAJGoxNwALYZI3pjoBnXiAJWY58YOCnX+ZUEzt63Y605mWMANmHntmAHU2Y402mX9VMlnZh8iYOC91lrj0iSuSUhyS5NGrlqJX0wj9fVABthkAKJLwAnes3b3jK7VIE6Hfk0KIGRTnmJagCYmTd5DrSIEOHaBqK5DYkAA6GG9pgZuK4frHCHkF9owufBuZYBANAR1wNLdO9VkKKQAMYYyg3Yl1X3O1APoAL4M2QPqYTNj1wOoOYOONf3PCEOkP+MqYsZe4q4aiZpaABqNo4Ot4JY0OwAWIoor8csKtCLzUmY3di4vtJiGqt5xHAWjXAG2O1YqA9rPc91BOmhd3U32k3nHZuhAAY7UADC5NdYBFq4VQ9ijAmHmZ2KmY9XQVi1C6YqfaOVoVJfYQPFdqAQAQmsvw-xY6w8eP7Y+Pgjpjc8WC2CaiFIlIRLeQJQBzamMHgCf5Rjz3ajyhdAzDsjJSWPGgrGRmZHHG5HODvO10jO2hmqtWF8kvpBuDr3cWEWU7IBAAaby92PUsEADi0vO-GJdtWcfHoHLIgZYOD5YRrnDyAZrlr+rqAZYTJODnr1rzJDr0dIgAbwbobyAEb0b-9ZYAADTg9m5y0GHjNJloH6DlmQHM-dygEAABzT0T3GaS9vkMAWgUmiuAmImJ5l5js2O0WLeOAe2Zz3axLwAR19AAIKMAFGDQARg018m5EAoc+5jZj232zhz2IyEvtzAAeC24sAAg7V9gNCJWq1geNyAY1QAOk0qGkrHBIffbfBAB531KmxDcOi--UfgThQVNkB+uMS+0ph5w7h-McLaR+NUgxfpSsnuYTdHSHifkG0ux9EDx4J8648PNXXx4F6fJ-i7G4YqgD4pp867p4R8Z7R+NscD4t5-5+qEJ-KyY-jLDwYy+EQ8orJ5C4NBkS0AlB56aKQeHMS316Q+U03ygCk1PjYxg7MyJ6YHAQVIO3fUBPuZjiHRqMuygxS-mcDK7f7hC+NpS91cQ4ZZC-9pD+nw+EB4GKTyvRqN+TYgg8AGKGQAaYYymU2huPeAlFnfUmo4PtmjtfVABDhnz5KDtMYKY6McHVhdqt3lhzHcIagEACWGBKFEyoCqqZsgHmDvlLXv+gxg+MpLROUf7oQASNSNxG-3fIAq4jZZWiZw-eWOmiA844Bug1GgDm+tOD5SA6rATj-vsz++Ws65MnluhSXXMlGosFfCzr-s7AAz3RGsW3kEAF0GUQdIQAAJGjgJ9ufmkDmAPKX-XyPIE2I1hJaNtbditWdrWUwA07TknkGNw3hAADOqOBwG6rCUkVWcKABZeUtryB+6KlCAQ4kWxj0cah6I3MyA7DgNvaflDlvHW3j+FaYgReqo1TuCOckeuA72tkVjq9ZG4BZTWFQFb7D5NugDKXpAEACDDAXxwijUr8U-K-tv0aDPhZgGg-YIcAdgUBmM49QAL1GsMISNQIHq6dJM2NMwYADDFUQFoFMEqUwAogTUI4C5weA3ARgpwutgM5F9IAGggarMCnSawY4eg31EYKEi6ALB49TPt+FZD+17ByA+QA-1gaABpP21ArYvBkmAmjbWE6sAt2lglSsySYiiAeafNeIcenkD+1dAgAVH1aQ9uVrhoIADMswExm6g5wPh+AgAPlNLagAb59OcFQRGvkOspVRMoZQzKh2BcDGBAAl6ZeBLQgAN7ldAgAALtSQCMEyuYA6iiAwhxgSoQIPSE0RFKWQgmjkLyHj0VaWWMoSgOzra1daYQ3QGbStoPkyB1lQ5GUKJLyBvawdXQDcz8pN9l+ecFoE1gl63txeUAPsMAQsZGtIAg4FLtVW6Ajg10dbXRDzG6CAARvLuYVw3m3QQANS+++GOJTG6CuM5sa6HmElgd6QBAAvm7Kdb4XmYHn2kbDQixYmXQAEt513U+JkgRa70u+kALkP1EL6wZ4AX2CBN0EABeXvvmjbYkfM0bMAOKPMwtMmAZAVgG51IoPdGgy7F5oCR3hoFjWv4HCOYEwjZ91GDiQAMsMBfFiGAAABkYAHCGxDGj6kX+QLSAAd15BHcTu6hN+Bd1ypgBAASYTOjc87o9vM3y4xb9AGGomomENtEM9X+F7K9s6Npinc3RzzD0d6OO6+iEx-o5fiT04EUBlR5qEMd0ApaABa03MA3NzRYAQALJel5QALOJgAWwZwxiPSMQ6OjHHdYxro87qmK9E+iyCfo2OpcF6wXNARUAXMb6nHAhASxgAAXc6RZDO0RCMdExi4xrYy7u2OTGdjUxuRWUSv1D6l8OmkAeFI5n7EJkNYW-SAHxSSKkB0urVboD1XjLidVMsAWMSlgTzN9VRvbf9InFuCN41R-YogIOITZsQYhCfVrhWSnHdAMOZQXQIAA54wAIAJEpQoSUI5DyA7hJAw0Brx+GgUO0gYlOoA1fHvjnxY3b8ZADDEATn+EY+0VoCCCNgnBjgb2nQPkBGDvho6IXlABuwhwoWUxHwXhJNqAA05IImdcgG9POsSRLIkUSqJ4oGibDAfKcTva-nZCfROb7AJvUrBdhlTAvq6tASWEhMSnzwlWibRhE+HsRIhHG0ggSEUQP7VECYDgaugb1ikEqH3CkJUXXNAxJmL4wBqGk9ppAC0m-gwAR0ZrnB0Al6TLmyVQycZO1GmTzJlktwNZMQn24UJWDA4qdn5gIAMJT-N8epM-EDjXJ96c2kJB8lET+JEI6MKJF7BcVhQ3jXQFxR8aOBAA4uqABJb0cAZSJSmvBybEjyw4T-0eEkIIAEFbISLNEz6ABFhl8g4RKOOkviUjwGrLEgpiUVVroGfBjT-ajgDqfVO15ScvsYsWAKGBDg-NWJuE1yR1K6kzRep-UwaTxN8m5Tugo08acqzVbTTxpc09qQtJkm-Dr0CU1SavWwkuTNRkAAsVlKGlATfU3dTUMDVECAAXt0ABbvvIALEWBAAM8oB04Y3jCUo8MPQdhTAJ5M8j41MAa5xIVdIyukBCDmAjJITQACwegAEYtDKmTHxhKEAAOUQaHcDYs6BjgQABc2oieanjUso0CGp8ZQ2Hqjek1FPps0QANtq96akodJ8HHSke3dfmdSThmDCEZSM08qIFRnozMZHgbGbjLlklSiZJM4wGTMpnUyDmtMhmUzLKENTm+T8ezE9L3FqSPxagr8a5JuZfSjpOU0WboHAwvdwYgYYOo4AACcAABglw3M7p9kjlrTCRGpTIAeE22bNFDpCyxuIs+sd3RhLOzXZ7s72b7PDr+z3eRAW4FIJ4lhzw6u0t8F7KjkviHZscqaa+B9l+yop901CealFitUgxSU16SHLwmljAAJjp2zhZxc+0cVJAm6Byx1YmsIjJogGgvAT3EIDKFUAa51K2M-gOANEDdzIOoE9-nPO8YgSKJ-c6SfZIDE8BaA9couclMtmg80p704ce3OjmdyIR0DUQM2HaiAB072HHyApwaLeVBvLbTN8exRMXebBgtktTYMeE8cafKLm6STpvqd-lnmKm894mugcAWAu8a+1Gw8gccWnOrlfziO4RQ+aHNcn-zZoXkCaoXK-nnzugoCwkOAsEpQLvKxC2BWSHgWILK5Ac6YhzJB7ZzMFjYXaeLLwXC8CFvqEhaSDFkCzAApgxOhAApEpXz5ALYQMPelty0L05eaf4lamBHoK-5LC7KUAqR5ELuFvgSBdAooVwKEFjYJBXIWb74pmAz0-eT-JzGuTAALQyAB9hkACN3souGn1iuKgALvjsKxU3QOrJrCAAOG0AAGCY4DsnSKYA77LAFzO6CQ9AA1Xr2KfpUAQAJry6lHueLScHCBYGkPCUtEsAAOSqIEADryrSEADHyuog7DiR+yUk-xVr2X58wCYJixuVbKPk1FxgjWDAHHCZz-FsA30vyb6kmCIjyYwQuWNrFIDaw72yKITGAEJj4wGl0aaKe4X6J6p1YlMCPhcCfiZjEpe8qpQotcnFx-hYAcir0yemtLgFUAbhY2CCC+BmwMJVOVItKXILIs9SmOLMHriNxI05stWKL0PETFnl1qXFqQHWAjKI0qha5d0Ayx6C0KpikJb6lGgTQSgV0QAN9pAC-BSovrHqLdA4kdwOYDBWTRdAUK-Rc0zKXNKAhT8IIpuMwkvSUp1SjBe9N6gDQMpMKjhXCvtGABEf7PLkrs6gAJH+GVPI2qebUxUOTX45ALAEsq2lkqeRO0yJW0qgAsrRAjK3QPSvFVsr5p5ygxa-Jikntm4McY5FpyiTZioAmnbTgEMen4xZgbqWYEYuICcjfABY06vDM+llDfORSkSLJB6JVBwI-ABFeYHhkgtdAgAYADAAdobpRAAWgz-SgZoMsoYAClle9I4HBmwCDhxNAciTL9aqz6ZjM3YVUCJmFBVAgASwZdAJM4QIGHhnay3A2LSpgaCYbnDwwd4SStYpsUdh+yCa5wlUHnlQdSpk2ImXRMuWaqyC2qk2dQT5Vg8aiNzc1VLNtlWq-Otq1QMGBrXd0E5bsoOp7PLmR1n5JSvIlqqiQXA9sH8rtVUUS7jjTqn8XWPDPfkJTzhLAcmMu0JhgAVOGXeeOGHGD0AdBxMHuK-DpjUiW4msEOKzAABWaaYmEcDADdKwAVMPpZbEFjmxJYC8GmLElEK6x+YvMfmILFdjmx740sHWKAhXUJTelD6jZTrGQB5g4BBNVACMDwDLBfYP652LrD+EUAq4AZGeDrC7gORrY8M0jS3HI1IINa5wkONrC-ghlk8Y+PMLHUXVKT80O8tdZT23LkThxfa8eifMHU2q7VNa3sHeGNpQMzyzYeGbfPvllDH56Lc5QurbVLra5ydTka3KpVQBlG+6KWQZrKHyBu6gAEV9LyT82ptJtJBVAoZy83QNZqfnmBEZZtZwloGhCeBiQgABwYf+xIQkAMPHqABY8JCApBkZZQu1cwxsqIzx5k80kNPPMBLzipogeGc4I8rLyJQFYkdbAJZlmCeN2mpScinsjFtBNkZbcpSp2BCqyG3QfKSJFUDwzqtO0yTXZry0ybwwUYS6jdTRC5B3q+IcwB83GmQZSBUsnuR1PMAZTzNSEvGpGrTEtrIAvGw1cAgbhZzHu25dyWJpoHuS2tw60dQ5uQjjSggVzMyRZKsnaiJQVtKSU0y01qqlJHahKQEKDmcj45LswMNcyDZP9gGyGftbnLKGiBAACwwOIhoJQDxmxGtXtaDtOIcMG9tdmfb9QBQEynlti22zdABAl1VLOppUBqaqA9AcyGDqiAqWtLfUEaENnGzitswdCQEJYDMSSOnIzidxMAXkNft49RncYL232aqgRksIY4HhkhNAAhHZ90CtKlJkIjtEDyBzARgDYbDAlBRh1QgAELcYtt2z4pTrkmjKn4ck5SS80NX5dZgzkvcTIPck2UvJk3RoMZsd5SzdtIu6ykDpB1g73GEOodVzt7DwzAAu7GAAjtPdCABWfT4gSgOoAlMoeYEBrLpRAHYUQMYFc3os3A8QJXZuDcADk6BpO5hkVvu2zBSt8UvVU1JWmcidp3UtiH1IGnbazBrWm3YelED7ScIfu53R1sO3hhL5bi5GTdKsQq6O0y2u8U9oYWcjxZxelSparL127Qd4OyHftvtW9h-VgAGLkBZouVQF4Ex3j1xZ0WgsS3tT3aq91eqv9U8jQX0U9qWCmaDgt-DsKjN6FS3ePX-kA7gdQ+x3SPpd3hhvWgADj1RA-84wIABgVRQI4FEhbEJQ5gZGVfNECAAI20ADdMWNvHqgwJcjgS+XYLL26BxxUTFfRTrT3r7yAswLvYbr2rizN1dWkzWfpYUX77dw+mvdDt7C+AuKPUkoIABGGXQMIvgViKJFeoeA8v2W2nBDgwStA4l3SWiBAA9TGAARkN73WVy1eBq-U7qk216YdYAFVoAHnEzUEkvkA9zIeSehg4tuW23ALGfvTkYAFWGAJpdlOpBADtVYjbDZXhmaHiE3IwKLyE52iHZNxILPPwCEpmsvIj4F+gJSNAsNJygAYf1zas+kcsZF-L8AFQqgAoB1Ez4Qc2I5BiUC92cqINNoq+pdavxqqqDpBe1BVtIGmqnVlQVzeGUmxKCAAwf9LYUIcIFhg7QYeWaFUZozNAVKgOcIGgDQME3mhyA2jOFAAbU6ABpQ0l3U1C4uOy4fjvkBZHk9+w4mpLTyPqMQtNAliF5FFzDDFKZe+Gckemq2CyhugbStRKh0uGZopIdSkBD4rOFw9lQSjs3zDyzBeNnI6zgniwNQA7wR0J8B90AA2ifwEmOWcnw-oAoPIDWybZMhAxgmmAFw14A8gcDNSppR0rxR+AmxIyiZU8F7DewFvHhSMbMFGkg9IEPneNu85iUd8AOySn6GV12dSAhxynSobnhqG2D25E47ZzOOQAuc+IeQMYBoiTlZwTDAwyg34ii5-DgR9qI2XCORHLeLh1cYquL6caNVQJbcuX36LRYEAs6f5hqtVTfLNUvqL5Y1k1Txk00+MdapfAebdAg8jOTZaurfH5Z4y0y2ZcCMgDrwZlh+dqs3x+bbx6sVMFmM9PVjdBVYbucHD21WaYA+xUAMAi6fZzxkSeIXVAIbyzaPjQ+WGUkUy2JhL1VpVBBAJJ1Y4OYaugJAOCMGizb6fBMgtyvwUACtDFFGerCq9lkAQAGcMJQIXCUHigsQSg6h6KEUIzPPVdA5JCUgQQSYS5dA34ChI4EAD9UYABdTZw3kG-13gmov-CCOSWYE8SIku8AHqlJPbgU9V0AUmIzG6CABXS0ADwOrDyYDTnNukARc7T1bXlwiUBXQAHZm3rJc80BPo1FPQB5+FKwagCzmTzgvRaf+nh5eYmgTOZOGrFDSTwt4iSQUSHJkHPVyggAfEMJc2ZvgSySCA4ReavkHqZIF5DyBRA35soH+erOPZ6prXT2K+dF5TwKesadgMgcJTh45zuTA89heDlQA8LG5pbX7mebOxuge5g82+L36+oxc+Fic8gZospZAAobH0Xrz9Eq8bdjlgftPze1QAABRgAPKiAL9YoS-BYlJcVGU-AfM4WewqAAVZW8byAAggYQANNe7gLnIBBN5ycjET4RTuWCMq1MGm3YJpjyfNS3BnmTQeHnPH448SZB6h38P414giX7R9lxy2xCguXYJQgACuNAAFprYgGTAkS8uSWKVszK2ik6AE81k58XEuKoQADnmgAZ-SrFCg5yxCJtaUS4IhQYwFxTivxXdASV3CJyqW5pp7YkV+RbZb2rVp1g0wfK3GXtk0rUrKodK5la4qVXpgeVhQYVforJxNR6CmQQ+Ag4lBxAKV7oP1cGvo7CqEpWaLpRwgwcfIvkDaNGla4YbRz1S3lEnW6BzWDz9kDAP4m6DTXNe8quhf+gJh4nmAhyaginxkGuMkrPIcHYAD-tQAIYxw131IjOfAAAWN68QA4CiB-IufEs7oGjWeACgqgQkOYB7MIQHE6hrkJIHKY8g8I5JaieYDqKAANrMhvQ3YbMMQAMbWpgLwNdbKa3XHdEpQGx4AKCoBC4EoQAHrp3jVQMrPBsMRAwDpFUBllw0Sh8mARwywDRKWmXGgu8Y-hFYTGFsGWl1vaghOevnHRA0JNK5lfMDG1xrCJ0RIAGe1JXaKUvyFBYGRVX2i0d0CABa31vLhNiQ-AU4VQEqM60gbLR1-VVIF6cXpiPsPGOQFH4Sn1125cfsYHkG4QlBYt0LmUGNTmAXbbtxQayF-A91oaNYI6JOWMCOAo8loVQEHmWCNkOwFN-grJCRvlBHA5dY1KYHroFNdIXNyZdMUGb8i34IwdgGVeTN7UJmkuT20SVZJ8hEV-ZZwoAGy00QG5VEAV2GzNZuoUOZLvup0LMARi+npaCEXIAs54i3LyYCD3ugo9ovkCK3MUXfUVFki8xe6D0WSLojTC7MCXu+o2LB57QYXaaA3LN7UAFi8oHYtF9mOR1vkTvBI7iDWga2kYDBUCRC3or25JiBnRwhbbdlSPKWwUCybuS8BpIBu5HejuVDogSunfIAG7lSawaFJDmA-7sE6RMjsAhR3VA7k-gBA87O52HJiSDAA3GLbC3EuhokaBWw7n1XugLdwAKFpugQAOlmXgFIIAHDTQAOraugQALVRl5LO4UEIeAFdANrGIJ1f-SN5o4hxZU+QBmXrbJee1IhDhDMKQZAAKWme26ioDxwGYQEoFBAA3BkNm0yNYQQLazoEdgQrrXYQSI93iO2MM5wHTDUQXT6YSLsAHmNifMccEBqD6ai88qp1GYVrkAAAKxOPrHhMVx9xncfPgvZ3jse4OigREwbl9j06UE6schPwkLEkLto4OtYqL75qbPbMw3HtByKV8fB9uUr2qBjan3T23DavLB3EbVzT7qyUWxMRdAg9WhzWAIFYyQgM8wADVRMeOh8YGcoJMOw-BDB6FZfGQsSOuDPVsFXgA2M7GJjyrTUVoY7Bd8ogQAGbRgAKRVdA2ju1p-frGBOvZ74QGpqFEBDQs+2fHPjQ0AIzOd8hQQBz07FCLOvIUUbiByGWeNW+Hl9liesooDSsAyySNWJhZyc1FGwgALMizDntv54AAdXe-boFvIwg3AHYOopdgQcyQBtogQACAq+tcgyUCDs8PHn0pE5jRUryDtXTvVvaocixfbw-Yccdtvqn3jsBPb4wMWILDJfiEKXusAmK-GQDLsFMbGxl0S7aDfre4YASmreq9j3xiY0ceDcHC9Q8XGYMcTmJ-Bo2kxSXusWrF3FiRXxKALE++IRp5d4nDYb8fex7GrZ+wvYUCE9fcyDTtBf1uMFOETD9gZOMADL6AOMqrmHWdskABWkgP5MyCTq-RJLDs2bSFs8A5RmeEbZniu0Ab-ZQoGCY7r8kHVQW-gIFsAB6DMSDZaW1RATd0SJzYHQylYAcpRWhIV9So1Yy12agmKZjjVdLLgJO5YcFXOsgUjgARoYHdbENdOIVcml4def2MuHx26DmtDRpQcHfay2ZvxdmGrJbrLUzYpYPmKzeMnS9Dj+SkqHjXCLQ17eF3zuCcHga219RW1wMl+ut5-TYCsACVUnduGFW6CKN-0Gqc8b6ltKT987bAaYM-HgAUFugmoCZpxmve3vDkZcXa76g8pPuh3rAG95rCI4R5ugwNb91e9-e3uXctwFLO-xA--p+4q64ZqMxkCo8YPsGUmKwAABapAdpORW6AwX4oz7jD1h+QCL5r0uH8oKyDCi1XYP8dR5jywK6MDB3+dw7IvghyCY4utBZLkt2Y+sfTZHBV7oU64-vpC4LQT2N0Fr4F9dAC-S9whVHwEsiW9-MlsTrpYfL8WTMZmyMCye7ooA6n3UYDr5qfdKWNLZT4ZxUm+pohsQ7UTRjinlbuglKykfJM13UxtdKWD+-nZDiHimdsGDvYeM+nHNTZh422c6brkFcDNnGbeYeJPl3NkNh4-+UkUODGLfU5avz9QUfOBx4A4fV05AF7XxlHt8ALZfW0ebLvS4h4m98HGK-kA8AodCdW9Wk9ef+2TMXF+0GHZt9O+vqTd+DrnZRsD3wxROkEROKkix3hVWZ8e7q8DtrXHBK5uO6vdBER37pl-JAFqN815ARYQANOaz7mb0gQdgjv3Rgt95qVBKPrfoAI74uKwDgqQARaWRhdz22KQsSYW0ceFoi3rEotpQT8xJ16YZY7eMRa7y2mYdEC62F3+XhTDURMnPen5YdL7cT0lbwAJWcAaVmv1qreuoAgM0PbMYSi6AhjOEQoId+O+kffUIted-GRMY-ZOWljMgClliaJNdAnTnxgR7-fwASiuKboFGDFxeAUPrHDLjqxeb6s429Yk1p62ta2saM1bbn4a0KKtVXW7rX1KawtYlA8AvrANkp4LZFtSRZbYh7BirZNsa22GVd26b1ctsmsupqmMabmUZjjYPcAri85biA+dl0xb5Q0tuVSmHlUAOpaMrjiyn7lgK6YuUtqXXKwATSipTKJ5OQAHMvcH+QKZqLnUnQbg2nAnDO8I4kcJCH5PICDAurl6J1s+pvTuRwoEUsSV5MLGRTkAj63xU+poAvpEpscN9KgMLGHzkxi7CP3lQ-WPQzQ+EG0BiO4GuhRHqg2G4mu8GujU5nCSsppyDV0CyCIoi2FIJeQjcCkl6WcdP5oD3TZ-GNwqQ9EX6POwAz6Zfq+jfQPp8AhY0sRf4364Dd+V-rQePxjiiRQWGygAFzNCQikX5Eldz459VApgJ8A6UvDLYsoLxuvWADvBpmSggO1CEAB6MwptWUJmUMM0-VejPo90c-yphW8Zf1X8eVL2A39L6Cv0gBD0CVFKRZ4ER3xhG-LDXm13gNM1kpeQEC0WxEaCALXoN6W5BWQe4OSXFhe4aJFz9lfetjW4nlNNAQCS-c+hQDr6NAIvhWAIJEJhG-emyPA-AZw060wAQAB99fgGv9b-DwEqBj-d4C24ETfhFEAtuZG1EBAAaeVAALrkZ-FegoDtxKgNCRF-F5B7RhUSmlDAqCYgCaB2ApANL8uAm+lSQeAUwKOBBA9JlUAfzQAFxo3QDENxA4wFEASiXQVqpSAPoTiZAAZCyJQVQFpB-NMGz6F+AZ8mvAP-TKC-87JJ1xux72e7GOxw-boGex3sbbCqwasLT0qJIAVsnKJHbUi2YNxCVAnccLyBxHUZWQBty+whMCoJ-gOCC8msI10cdEqC-6TcjaJzCdIlEBnwd8D3Jg2U4HzQx4LN1dckyUQCkpWIcQEzM10In0oBxCerFE9fUCnwSZm7BJhp9m+DjXEJuOSYBmVA4FiQPIzIfgAHIhyTKGSCQALYCAA")); })() /***/ }), /***/ "./src/js/built-temp/base-kor.json": /*!*****************************************!*\ !*** ./src/js/built-temp/base-kor.json ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpgKU1hALN2AdVZFhArzWAQGsALo4BxBsIAQJxWEAqzWECvPYELx8YBHmwKhrgDXGwgXYHADQOAfmrCAHCcCWq4BFxsIATxwJvNgFTXAGquCJgUvHHgZcnBQBiawBDxwFDxwAmmwBOmrkgAGnBCSAAbUgA7DBp6RkgAbR5kDABdYABlKgBRAEEAWQB9KtRUOoBJGqqAcQqAXwB6OlhyRGheuAp4OtZMCYweADMuWbnc3oLigB005jZOXgFhMUlZBWU1TR0wA2NzKztHV09vPzBAsFDImLBAFLHAWpnAHBbLvpHIAQCcAN02AF1W3iFHIARycAkaseQAHNWBAKOjgA-awAQHYAXccAOy2AH06wIBWxchvkcgAAawCxg4AdocANQtgQAYQ2BABHjgFah6JcTYGGRgQAAzeJ6V8yWBALmTZMAFqvcwAMrYAfdriYEAN6OAG-bACG9gAFxhlfbmAPc6gpJnoBVNZ84MAPqNgWzssAAWjAuQARkVROJpCt7YAeccAOh1gQ0eeWAsCAGvHADMdBMANrVeMCAYJrdGBAFHjgAHJsCACc7AByDXw5aUA5zVYwAtowqVerAJMDjkAeIPIgyOAuAAzmwIADVcjHy4VrAgAs+wCoNXLABCzgF0OuWAGGXAIntYCLYGL2YUgBnOwAHLWAooBE0fEBY9GoJ48AjhNUwAlC6n01ioTJBABGAAcgBwa4wYwAVPbvWdEwAAKLERsDjj3RpVqsBYwAf3WBAOFdVKkXdAA8awAODscQAHGsACDGvgAQgASjADw43HMBAAAJwRAFtVwBBgbAQAJgfdQAWsbAQANecABUXAAI5glABTZskkWZNkoibQARmsAWLXIUAZMb1QjQATlt3QA5zoYmDNlCRwQzCDxABcusAaLAQAGOsAUqbr0EQBR5sAXs6wEAE6G4X0MBABCe4FHCxQBKsbrRkmVdQAHLrwz0T0AHB6AQU6NjNM+j2U2O0ikAAnHAz04FjB8RQXSKdzkh4OBgrSQgbQAKiKGdABsFsBAAqunFNii3JYrAQAcCfEQAx0cERNABO5tLCAyuKcrAfK0J8EqIDKs453EQASQcAVAnapiuLABzZqkwEgxE8GBQACQbAAAyMAZEACEa4xgsAACYAAYFsAEUawAAdkAFbGwEABc7HEASq7AB0Vz1w0AREn03SzLut6-qzj49VL3a+rtnYbg+AJOzw0AB2bLkAAbHd0AChawEAE3JAHg-9zelC8L3PtQBS1cAEbXUQ+rFAA6loLNnQqF7kAH4mEeRuimWRQBACezaNABPOzHE0YlFEaR6iYQ8QASDuRQAPRsAUg6wGOj4hLSXIIdgCLzrixqwEAV86rEAGRnAAbOhM73gRZGx8QADUcAHm6lJFuCHsywAfZcABMn7xygFAEAxwBb0d6QAXGqVl9PQMMAwQ8WT1ci0rMvN7lABE+ozdxxQRABKhwACxcAGs7ktSx26sy1qwDJeTxGF0xAEZB2T7ycQAFsd6Aw5Xi2TekAAB7dDlKkcTAQBHlodgWbvVQBQicADU7jAMDW4tj+SwGhnC7zjQAIOujUJd0ADPGwEADBbABY6s1onguuwDRMBAA8xmd6S5lZeYijzd1CdVABIxwAIVcAGMHvbATnUbSQAQJpDQAMhrAQAOGflFzzIsuV0cKwAS7oiQAHpe5AnAE-agmlwvvHkUj8RAF6awADWPJWnFlQAEqOOEAAE1vs6KAB5VnEgBGHscIiemDNkTmk+MCQALTNgHdDiYWjhAAg45CQAGD04h6oAFoawBUHIPAZIqQwCABee-EXpAAe4x4VMc97SAEHO+K+8eZhT5mPXIABXcgyQAC8xBYCwFYNAHAvRegABMwoAGMKBKK4Oo5Aqw0gADceAIF6AACQAHKrQqAANQ4JYooEhAC7Q2AQAKK3e0ACrzOIVhiOSPzJ2cVRHiKkTIuRCjeiDDoakLRpAdG2l6C0UoABFNIqjWAAClUCjBYM9PgRQ8HC08eInxoc-FeMCbI+RiiADuVSuC0KUSo2AkSdHkAyTsDg2S5CABg+jEgByVvyd44RJTpFlJCbMWAxARG2kaaE0gtpoCsGaU9XY2Tt5gHcfeDohjjETLgn0wpHUbSDKCeU3oozxmTO0dM2Z8yWnPT2L0W0qQYnIGGAgZpgxEBbGSIgWAfAti9AAErVAACI1AqFwZASiiiAAieo2jhdCAAExzGnDdlgwXvERIRAVHQHUeQJRAAZHgaQADWOQHHOLcQXa0gARGcAKDL4JYKQESN0BIRAMCPMQMkRgBAkipEQCojIOR3SAEpW466KoqQHgOQcgFAcgyEVGKpIYzSAiOgB8pR0AgU8AMUoyVOQ4gKsxfAVRBQOWlHgFMIYsAZV4EgLEFlSRoAiLmHMHgtAuUYsVWQFVaroA5BJfa8VyAeD0N+b6m1NQDVJFtMG0K6Qw1QAAEKRqIIMGNoachUEZVFZlHrICEpdWkQx2AbWiEjZAH5yBi34A9UQdI8AzXqLSEoqoGBSA5APB2G2yaoC0AbekdVLa202oADy0AAHyduBN2yAdaaiEpEQgQd7blRdoDUkWgc60gLvgNAJdI7x0rqnWu2taR4DGOVeQPdUADwAVXTWnt56xG7tbTkUdY7b1HvvTO09QLEAAE8r2QAPIAH3G71RSILQX9f7n1DqgG+0Dn7wNMCNf26ApQyCUFfdAFDTboATunUGrdCBd1Nr7bh9DFAGAjsI9uvDK7h3Ycbeq-Dx6oBevICRpRm7aMUcwyO9jeHb3Dpo8Rsdypp0bvncR19B6s2EBzeKol8BoPuqQ+WxAtoM1VCTaxyAjbBikE5TagAwlQf5eLp0cqo1AKoeLM26Z3aonYOQKilGM9O5g8xrOQFKMYloAAxezX65mIFUVWnzqAqjGYqHJiA3QmX2sgDq5ApAE0fNPRx1TirDHJHC0IHy+ky2EoMzkbyvlRIk3BAoJK04yKUTAIAGoGjKQkYZwuTCmoDPMJTUeAW6stEFYF8v9OQqSAETxstqiWAZDoaQDAOR9JyS7EV5ArBKOlEQHo+AGAUDhcABG9ipV6yTLaQdgaRSgXrC8Y4rORl4hDXuvMA29OZlqxTi-FhKSU2rJS4tZchdJluIHQ1gNCPnQC+QgHIMK4WIra2uyAtppUVOw+QAA6ogcghaBU2tu+qQAn02AAOh4wHTpSANQvIMAgAEpv9rqUbLhwwRiXIAGVH6aAA4J1ynx1CAGiJ9UDciGQjK-pCrHhwKn3ioAGw7HBRAIoAbB7XTbjLaqzb23K14vgJtozUBLxgDfQrjbW2duq-VwAVWJWkUgFS0g5C10lQAIZ0TfSD8rd4WmIUjtmW09FSOg7ZyLhKEZbnk6oTcNm1WVRva8QAujDlpQrErHQriZtT6lW+6e1xLKiOWzfjdyogtoF1Wq2P1pIpBPtQH1Kw6dOrcsQ5tXGQBR3dNOaSXQnIgAL2c3tO8HuqbXH2OjIadtC4Do+81EHqY3+87vgN5-2gBpQenVgWApRYBqoz6e0rBXgRgBDCTN3unK+T-gF7ytOR9QaQwdOgx8AKlG9YEo754WqbIyYfX4LZAr+sAwEMHV8bIDomxAXRhz+amzA5uAA0sptGk2oShgN-tYKNoAKk9T+sWYAHWRABQq2lA62SuO2FQUq1q1aamPysAuWOQ+2h2YAq8lc06CA2QNqqEPgYAvYwGjgpBCYgA3V2AARqwxDgEgSgVAGgWtnrsrvWiIqomFtAFnl+oQcQbQfQYwWAKQQnLHBIFQQMDkHQQwUwWAEoZ-J6PtoACpjDEsQHqvBkAQheKpAfK-miAwaYiVa2e2WRB4W6hchcqKhNBUAzhmhLBYAHBXBPBcOjaLq5AyAmB+ulaQKdC++heKaOW4WgAtQNZRsJuHea3YaGOAtRbSegJEeCAAFNWyIADJ1AA-P4bmormEfABEVXr8jgdKuQNEVAFIfEYkRpIABTLyRahshmh2RbBnB7IJR4qA+S+lA-y8AAAjiIjwLUvUeWrETkCPmAGNmAIACKrXw7RNqrUjgBMRkDMUkIkM4o+o2JoYAgAlC19HGFw7wD1JgF-oQH8pzZ4D2ExGOE5AbiAAoPawkKmAK8YAB31gB4GSWjmOQBOu4Sc4YG4p8iYgCO8ukgAPUuOCAAwTYqAoD8SLmAK5sZgSIiWAG3hwmmP0UkAPpPtcbcVAdAMZukEEc8j8ukNMY0S8e8Z8f6K1BXoCdjhGOqDVmAG8R8Y4LJIAB89gASDVLgdiyRuAYJGHZpw5KY3GEp3HQAjHYawAADyJejxDRsxNq3JjJ4cgAImOBgsnYo5Cclam7j8lCmehMktT9yAATo4JPiUQHMEgLALYQqamqotSZbg8ZIRqVAB9ElL5AaaojkH6b5PuJVIIHVneMOo6d8rYWOnBJ6FSLoL0Z8ALgZJvmEFViAiRBRASE1uCK1gyucbmnWqEWYQUIYrST6ZAHQXISeIyDlIGcGf6fpPIIIJ4Y4OIFCtyOICeChE1lfIYZ+D+EyO2Z0Y4LXqiWmaJGEGAOCJjLhHicWeKiIjfnfqUCIsgM8uQMHvgf8XSTavjoADu1vkMETZNegAOQ1QpgCAAwq9iJ+PDIAAM9-8DWGE6oUQgAMuNWCACYNYYfaVAKuR-nyjui0GkAZkoiIR6VWc8Tar-riIhH8eKl-kGTau+LuFONmQYOqHBTiNyE1mAIAAQtDI7OM01oDGBmGQY6z43EuYnEeojggAE6tKwJgpiwTDqjAUUYBUU4V6QwnqhuASTGCryAAenYAL1TYAhC3IN4MQ-5kAzy4hlR++5JaQlJ0F0hUACRSRu+rJUABO6ot0YA5sjg2RjMiEiI0lM0d4LU+ogAEeuCDDrqIiJgVjongITZFUh5ERBFGyXyVkkLrKWqVekEHVlOCAAunQnGXuebpfjvpeqEZc4KFaZUiBZfeNZXZdro5c5a5QlR5QUcUcuVGskCIuauQMVtAKYqQLACbqkKokpkompeFoACKjgAg5ONZGTyFkhRWQAaANZyTyTqgtVgCAAvo-7AmIAFKjgAGqOCRgCXiOCAA0Y-TAoIAAXjbcjg4IWUuJEp8mUp4BsppJoF4FkFvyDVpWRk4gWpXVgADgv0VgBxiOCAAyrWAJ5GdVyQyfxNNY1YABntBIZem15F0qlFx8gAHF0JhanRhl4FmcLsVwAA1cUwTDoI5joI3kBUUOWkA6pgCqJfLiESIADk0pJJGQuNY6pm5m7F6iOqVFAA1GAECkMBgHgMbI4INIALsLWZPVvQ2R24yNqNFN8AmN2N0AeNBNe1RNY6vmAWVA5N6N8AY6eAIggAPXXdl5hgBniGVKyOCAAMPYABpzf1iNGVMtAtwwQt+Nu1kBYttmUtvQfNctYATU2tAIgAF3OAAFPTmGABeEjMYIAJQ90MjgPx3NiNslqitCd+NQ6OSmdRQV+51Z+ERERUXVu4Pgm83IWINuE52YSKXwcoelYAoJggSUs4S4-16QXFgAF02ACpsxuNDZxWOgSCYLHIORaFGYgGAMQLQnMBIusJAEMsEoohfhUpKlwIsi9KQF3WAEMfPp3ZAHUA8h8kSl3WOvKLJOxYgGOuTuONxMRdJVwHBFQbERUEnjakVGAM+T5eHZKhESlgSkGtZmqQCYaTaiGa2XIAVIVASLNCeGAPkchGAOxI4GZEOdORmZJEmG-cIDlEuH-VvXaQVUQHQOgQvsHfAL1sAbAGjhjlASdTat7PFBLIAO8DYAFCjCFCiFSQyFQJMVN1OD+DS4RDFC9MZl29eou4E0QgYA11QCYZAEu4q8n1YAQE-sqJXcYACtgAE5MMjRhMgfmODM44iqQjxn3iHGYLqgWOrOo8DGq9awABWTHIBYNQBhURXl7aUP1QC7iADPNWGYAJm98ogAxI2yQEguS5TTUZE5WeXeXGEJaJB5oZDe5R1EAi3m3QFKmbbiL-rTEpabZh2sA5DfTNVYikNEDYa5bukJoTHJByk5DGxgCs0eZWqsCoBfJhaVpgU5Dmy-0JzHRxj96VV35pPBp3FlNKxgCAAxa4hv8YNqFvADUCIskD8oNuFkqKrRU+PqE9hkqaVVo98sdTaj7WAIACUtgAi5OJNQBYoaa5ZVALqkATM8BTNQU2quCtMb6AAiDSs+WrNmymeiIvVTakbi0GAKc70BuGc502FvUxk5gzauU+xGc0g6HefZHVAMfT8yyVXk0dOlMHAPAHii8gmkVSVddkfXGIAJOdYAPwDWMIYANj9jHepAtVCadCsAmqtC7pMzUAHtt5n1E0YAgAOmuxyeAvNfJpAZalAVKGKTalA8A6o5AUs3lUtgA+0-G-MLpmopP7NQCs0AiAABvSuoY9OuoqwH+qK0auK5AJK2ADK5oA1jvl+ljUgOQMq6SzSTauq5q7Xi8zwOwDIuFt7IADfLuIHmbLsAk2MLf6kq3+2IuYwIgAGmuyW54NNQGFNdMlO326t-p6vvN3GWLo48AfKwDf7DrSm11gBYmPn6AAgLa5O6ZkCwDSkwu2jN42rnq5vKZ4CJvKZx66b5qkBZDxv1FJPsCXE5AUi6DdpEBDDTY5CAA6szyGAOBP7G20wFavTU4T4NIIO9+vAC0AgGgJKmRjc1AB2LjmAAeCeBO0WsgNAKgHOzhgu5AEu9ruOmu6xqgTO1uzu0xkCsqg8uFneLQLNLvSe+qblgm+OmAIAAMLwGSBcWsDUAuW6u5JK2YLFVPyLqTm4rd9-7dCVA1ZWuw6UHyQlburUSAzCAe7ep06TlNVRKtbr6tCFS6OSiVFK1c5WUZ5umueMi6QpiAwhuhbUAn5M1F4slZuoHGj0zca0xHu1+QF3LNqsdqImIuIjj0DCjumQhoRe7wjdBfctpZxkppRZAMT-jDh6lP+QnOI06lH+e1VeLJe6nf+OrwVXeUAT8uYOuumPykq+bdC8auQ96RALQE7LQTnT7kALnrnDnUALQliE7vnbnlinnSGRAgXQXwXkAoXYXamLQAAGhO3F-ekULps8rQAUJuXRxrpAD20x-eC22ALQA5WIrQmBT030-GbJYPj8nABoxIcFTBVAISExBXt8ogOdmImIfW0O+MAu2qeKgeR4T4ACAYIO4atiqVawKqwTsYMdIAJqj6t3IMnuYo5gI3Exg9I3721XnkA8y6NIhTbKndXanoeQ3+gI3qzjm43k3hOeo69NFcYyIy3nJVwqt63XnvBSFdCWqkq+3e5wX6p9XkAuggAlDN6CndPujfB2WtXfTdzcuyXBA94yCDPf1kbc-tIbvdQBm7oY7BbvSoQVhZ7vtzf3ZSjYne7jON9G6aLLnvkDcbV5QDKjLsMaZI7ouUVeT6O7QE9Z9YHdQCdN-oVrhZ3m7gARafpNylBsE85A63iDmxaeEtbtFM-eQAy9gAu1u0e1i9UcF689ED6bzrO6u4rNJMc+kk5DMluclMiI5CAAqXYAC5NnogAM82NVkhHb3rxYKd9dbOlUcpXZgW1fR0A+6C-TLFfC4nFFU+v5+-eaAAx60jIgdm1y2eoi1AIANdNbvnvhVxV8yxWkvJnd96icAOQZIgAlTWyUEd-qrZlXTEV9V-+85Dx3ZsTI5Czfq2BmXdkuQBFQEiAAxE4AC4LgAtZ1ZlojmNLhkiIhyiAKD9ZkJHik83z+BN3FjoImKi3VtzMiCCWOgMEjsSonF2UVT9D9yDV2w1UV51gBb-sRy54kN4h0ekbmiE7rlWVXzDseqtFRCjaFLj12yd-m-s+OvJQsPyTbFQG96xsNcd9frpAEAA5SwHEAA9o9OmIDV9de16OoAeDqADAhg7pPApAH35cUqInUZehxVP4Eg8BY6JOMlFnA1x9AJ-EumvV-qNUFABA3EuRy27oDZodQRtJtj-Q4CCBDjbXDDToHq9cwHtWgZRU9BTd2YsPJWNyEAAPo4AAaalgfP0RqABAZbwCQlvYnoD2qQMEGUVB+dEHEJ9TRBiCuKLAidugIADMGA2gFMCbQ3Z2SArbWjpGEZkDGqgATaaR4JgqinwIJDqB2IjVMAAdAJDNhA4oIWOHrRRo801BAgmuhLUCxeDMSq-IZmrR8G-1kQZA-5F4M9A+0-a3xeXO73-7qJUgmWXnpACmI2o2wc+WhL1hyDdgtO8LHIAOGnRut6E5uHIEzH7AQsxEAzHIIwmlDys-0HyHID8CWy6YKkSA+npAA8CzhMOSSQzN1xyAtMCw9Q0LPp0gQtQKuLPSxLswHqAtIB1ZQAKxz06eACtlgC7lIArsa0h+XlYnY-01xF4lqzdyeM4siWYAqwB46f4d0heeHISy45+MoAwg92kjDlCa1lQskOUIAAZFwAAiN7fKHp3zy4FdVERXLRqV1gBUVAASYT5dh0HuVEXHn-6EZ8+X6NIP8MgB8DYRE3eEdGERHIiSuvTNEWAExEFccRdIvEZnwGzSoxC0ACgAH3FTEij8NqQABATpdcEUcxFHyDbAZzZCh32NZQAERhXKVCiJZEMisRzIsrrJSmDFZPmv3JIHyPCwFgwAgAHjWJRcoa2FWElEXc4RMoyAHKKREKjaRZXZUUyMvy4ieCXjHPOLzN4qdu6zfUoZXi+6AtIAB0KgqQF061VehWEDvGrjoS8ZnWC6K3Mx3-4Fs+m0xHVHMAjzJiUBkAXUTkEBGa83OUoy0Z6SgDlgwABEEhI2EH5gBAA8D1gBDBaILMskLAA60tq2afEYSkJFqZUx6Y0Nn9yzEkiyR+Yi0RSKtHWxAACG2CACwm8CStyH8FMDOoTw9Hg3hYCEp1mdhLbtmJtRYJWE0kQgROwLHDiixgPHSOOKHBTjJKDAucXbEbDJCCQCgq+B+RbHyZ-+TlHVOQA-zKom0M9X4b6PgBpi6RnXPsfyKgDQi9xQ41ViWPNhWAKWgARB6lwhICwFSEAAtC4+JeHelJUs0ACRuOAlQiwAZnMAC51AljdCxOQCCUrCgnx9YJnoeCUhJQnIF-+cyUKNaz2Ffoux-4zMVhJV5gjCJkPA8TkDCAsw+4SPIEGAE6gsxuQgASeXC4HgXUKCNokY89MKHIAZhJJGAAXucACUy-HwUHG9zuRE3iTalzHx8P6BIVdp6AUEiAZK7vBvIpPdKWhCUYzNcb2I4nqTNJ8g7SffR4mqsDJc0E8MZJPCmT5B5kuSYULzwdj-irEjMdqN5EkihRbk-ceBOEmSUFAX1T0B-U9DHxAAEE2fAyB44QAL6jcoUSeIA-rHQV2fZNqiA1khMQhQgACS6qIEQMqeNUEDA0EwvZQQLpEAAtnZGC8Ebd5J4xPlMpKAmQAYp94AACyl1H2W3OKZ3xLHDS-JYADKVlN0FcVcpcoXsv2W2JSQKp1U2qXNJBqtSOpEYLqQULZFQBpUS+V5CmN-Hdj+p4WNprFLAlTThJVIJiD7SXAABOeaNGDaZUhAAFQsWTFxurVRBUmumLDgQCcO8CQiek+1xpvYyaSOOEkQznp0MN6R9KOY-S-p4GeSXMAgHriSR-yWpggHvDHh5o0M8LrDMPF4yzpO6MANTzAC2g-0K7I8PNDAA6oP8yDaAEFOOkwAl8tVUKR9z-ERTeumPEkeKLum6T4p3kgkIAGRh-gJ8FsDVh6QQoXKFECkgiVxKBgXcIAB8xtWTpHPH+CYQ6M1sZzKDS0BeZZDS6WxMik6iSR+oo0aLI8md9AACi1kgEww4UcAoCiDCUhwjgKcAbKfGcyNRYFU2Yan5k9jwuHE00ZWDtnSjDxJYycZ6CrCBTupu+a9upUFmATwss0Uun6DNHcTo5OQLWdyH4mCTAQRCcnEXInGbx45lYROZZK-S9SeuOMgaaNOzmRzc5xEm1M92GnOywAyoUuo4EACANf3JnCezFwVcq+L7NQlqYg0uBcoZbKIDhydIOcwcWLIekVhK5Q4auRPLomcz3kzAC6SHOBk2pAALOtxhCQbcvSVAFnCiVycq8fOtOH4ka09IEsLefJLGAjtD5A3dvMvPtlWiawuOAEEZEACT7eOEAA+C2AA7AWBi5JYugjXPR7-82WtCfeVdPYkkiho581VpNDjAEhgQgAQsHYFGM--nyj0QfICekwDkU-zwJ31wpoctTBxP1EkJQZ6CzvpONPgljpcAQ4cAwrRkczNu4qXrJKgwB-o6gWADLN8koUsTPuoTHILIP1KWdSAHQfhZangAVAMsgihvlEBZIHyUFA02yIwu-l5yO5wkzeK7EhCYKVwgAW5b5OBCzmQgomDB1SA4hT0ZbIBJaK55QsgaUNB7ma0o57cqAKUEGyGJoAYAFuoosEVgBbFYAYrKQHHoVJSAck5LgIqDlWyPFw0QAIs9EophVaJ6xviqZsAWJWAFCX0zbFQSqJWADrQ8K0eyBV4cOz-QjECOuKHkSdMvyEdOBIU8gHUDVR1Bd5xAfRoNOFFdUyBMUrwUKBI7rVf+I8MADFKEmOAyByYd0O6C8FgBu40oMACQiXDHxAAqE3shlBKNJrEhDABjUhJ6oE+YSG5C6R6YmdRsGiEADgHeNVdBSQYpQoMgVVM6j1htlxAugbJXw4tLTpd+ZiYdxul6KJFpjXAYtLHS3ThlYAUZVlHGVRAZoj4dUCWMhlIzPQ70z6RvipCABWhasWTyCSzS3FJMGsKBz-lgfNTkvOBUoU4MYKs0ZCuhWwrGw1oAgQuE3h3gSxzAwQBGEAAZM4AB-2uCASDNHk4DAVgWwIAAWZjeSd0cCABu0ev7w1EaPNaSPjjwAFhAAn51YhpQEkOUK1HJxkCVVQcBIbS3pYLEtwRZTmd8oJXGyklMxAHrbIGVgrbZtK9fmMrk5wrPw6tT0A7NPE6Ca6RorwWYP-5mqlEdQQfDzJJV9dqyIs21TXRFkOrSOsKmaB6vVlgA5AnoQAGBjM4-+hvzABAI5QCa-QLuDIHiivBpxT4DcvGrqhs15BMSoCE1nayYhp-c8ZLKxBBAi1OKqpbmgDVBqAlTE3paCPNEgqhYRkXQJ6EAAPI1iHspgre1Map1dNV7VWx9A3ERwMkOMAe1uQZA2wMLlPjHwD4Y4RZddVJC3UM129HZayN4V4r6lga50sy3o77CAeIEkxpStBU11oRXg3cHSudUzRk4jgSCUCLACUTSxOC2sKJ19kmEO1vy15JwMBm9Lbp94BGVDMjWn9YN0MUUVOphXvrPwEYLWrrXphSRbpBIVmnRDIFW0wViQhQGmwzbpk9lbWf1fisDUEj2lk2IlauN6Vbidxfah9WQJY18CUNcasAJxsIHjqa6n64eaxs9C2x5QiywABVrgACnGdCO4q+LqHFJfKaNdQF8QIulQvivxfTLpbs3aUYTShUA6EbhNzAET71PuQiGACrjGAyBz6j5ZRVfWOrUN01X3NCPVBkDGEjEQAMiN6oQACk9hCfVWSEAAyE5ZEhFQjuI6ob8hXEriAAfBv9goQFBxax8SBuU0MTDE4G7RFMHdK9LnJYALSfBroHZatJ3GtDRSyMklTPQ44SxcBrhwdqkRTEuoPXN6VDS7wo0kmR9xBUCdLNdaugUMts1cURlDmnjb7imUly5o1gfubuEaoRAVlZA4aWNq8FLgnAgAUM7W1SW89YSuKySo6gSiFOQ5NJV6jI594TOa1rNntbzNnWnVZHKK1OaN5skATaf0nGIRj4KUtWgYC8EVhKwjdKre2uU0BzwNDW-TdWTNEjSxpeWyis3IjlECwV-W2NWhs7m9yB5Q8j2UOCXBVhPtZ5ajWtrfnTBeldBL+RSqww11cdV2iZZjGzCYsgFoC5wEnEcB0E0dSmtbXMGqH89elTgTyEHC6rggKEgAC0HAADrWwQutlFVnXqt61jpod06iZViESKJrAAOe2AATZu-6xxi1llQAI41VpVinKG8itlBA6gAyo7QohChWIfcJboJF3oY6WlDybPqVXr4A6Ae6LGEAnSyhSsIRTwYwMBilZgAmaAurij1R9BYs7GkOmuoBoAYTLSaeKRwAfFCoSQFAdYrMoAB4u1CB7thQ5MWam1bXHKv1oTxPyYZYzHKCBQVA8UcodErgkeEi45Qk5Y+HKDbyIQA6kQ-Wj1UED5YhQWIDwZ8EACdS4ABGe8QF3TcCAAF5bHoGAlwgACeaJyu2OiD1SFAJaWOpAOoAGt6WMdLwCdMAKXSYiCBGqQgQAA-tTCLCOTyHJIQUIjHZfWGSZCAADiZmjHqFVeAQACBrgAFwnww+6qVvSAamRhdwnOIcoyvhhkCcKBIdar6oTjEIvdY6GrIsoMC8RQ+GCdHZzLNwz7lNjO5Bszpt1qd59zHUzTanLoeA5GEyoBoQnEA671Qeu+rBvQe5-9DZbak3jIicX2ErVanC3rmnA5bYKAuzRpaykUUcocgCi0RZyl0wqpJUB1SVGmLCw5AjcyOfCcSv4PYBdMRCkhcryqBKJiFTeeqv-zGa-I0sSiLAEwfO56IcgdkPJpgC1GQBIEwoCFnj2l62s-W4vX9JMMAAFDYAB3J4dN8ktC34EASHcVF8iTHqHIAExUoE5lTlbcoBdzMABnEyWHi7mxgDOASGfKbhZI3BNztig5RfCUBSTVcptugDPJ6EOQEmMAlGxBAzuMAVI5lyyM5HaEGAXpujl6Fnzwef7dHFgByDxRsjFR70dUZtTgQeQ0k1HtvIxlU97F9CFHIDmjEoNDEWqQxLuTTlQD9QvbQAD-dgABBrW2+i3xV3yhJgBAABOtYhT4SMQAJntLRHEJ6DGOfRjAUxmY1t2wxbABjBiM4Z10SPsB2lYONoTagyOU5qcOR640DJtRU46jXndtlthKMBjGE5R941ADTFF8bUgAAz7Qqbxv7hcc20AnvMdxkE9kbe61yp5pATbCG38XIMG5vYqAViBcBgAW2QRl4swjzImQwA91OUAJU-DYmW2BIVqIppiONt1U5xpgEkauOpBnjUAO468ceMsmcgHJ+o0Ua+NlGcjUJnILCceNMm6gQp248AhFP1HMBJwuhEIolNQA34IgYwLifhP-S1MTLYo9jszFQDAAHaPZg8TNqA018V+JNhOSBptSeqCaxOBQDGFCMFiEAAD3Z6B1Kxw+441CaoepgYan-icwXpskDG7IMixIx6stggEpGmzGUIdUGGYkhLh6cu4MkPQVf0WgYz6oNMvIBQiRxFNCJ-4lyJfHQAemaHACVAIk0WAPyDzHxRfMgCclSz0jMAIAFUG1tbisDQqoNGhZn7iGYB4flAAoqMVmIz1Z6cJrX-hgAezjgRsy-Ms6A4gJnZtTqEDACAAZRcTD9m5zi5gkIiFCrbh7wgAXB6PyvQbMA7O+hwQ7Uvhqc-EbcWYpw6OQfc0REXM5HQoGAaRDkC3Pqhbz6pjo1+nboD5iA-yO-MWerJUhAANd3YhAAGoNgBAAEn0HGYZ90q0QeGGnDTiAHAZKBEAhFCgmQys11RsS+KAAV+qhC7hAASY3qgILnoAmAKJsoLEgLWIYC33F1Cp7cp3IFSYAAuVlC-cfQv+ZUApQbkAbFnCOAvw8s9nPEq-QcoK+BZukZayV5-mAe2EFWp-R1r9m6WbgAEEAmzLmx1QkoT0DiQTjAhieOtMAPDHVZYRAAOwuehPIcYBLWADiFUACQLuMABHoe4cqfy6oUsw2CTlfpSAzqSVNH3UNPE1OcfeFGAFgH+wEBsxqs4+EcDHMpIvl-y-AN3DHxV441IcqOPECt6rS-hr4JvAJBxgWoAIS8MT0AAUQ4AAqavcGAEAC+Q7qBoqAAIGqA0CW1MvWVcaAKvXJBSg25WROJd1PVlvYiYePneomnQXDx8lo1RqrADQjHA9teM84BcCybdsKxcQNoMqiABHUYtCJWQtjgXHPlYUCAAKhsEDDX5rTZ0g-8QMQYBT01rCS2p1diAASRvj6ln+zAlYwElDkD+wCQ2YQAIYtuoDermEACyi97BphgBAAvuMJxSrc5TGIIHOuXWLABIfq1it2vySI8VqMorwfIDELsZGJkKi4HUKYxKzqrVwHQUcBwDEwp8JwNjDrARhWECYFqOKXGvqEFIjgQADINEjfi+u2JWI2vLReU9HUBEzhYDw4meo3kun3s3v8s0Lm38cgAupNsbNqTGecgAABWQW+CYaK9YxbRGCWweHmgy3wT5aAemBSEV82cgC0VWzDLCiri92CkPs2+eOl69rJsASNlAVApzBYMM58LFIACnq0wALURhP2fNjGBXbgAXhm1qy7D22AHkiAADTpQiMIsQugLsGAEAAgkw2DACTbBrTUQAKFdVgb8HGCFCMJnLOZpCgbZvbKMiWkRBAOg0xzQETr4WQxpzUSL-xEQxt05v2eVvzRP6WILCMYHipl2EidYR6pXa9sxW4rByhTVDYczEic78w8gHC1lLGIgcSS7y3qOVXs7grqrFVbdkcDC8vAX0YPo4CBszh5wlwEMODcNWQ2JzH5-Gcob-RW2scbiqg+FnKaeR9AUoT2T7X7NDyr7+gdUF20AA-tdyFajiAchqtdvbJtkiABW0fJtI7r7zd5pjpdkDOBsY39n1nWArW7gvacBXcOoEAAdy59oqXtGOskARfhQdzRQCLqcOJAaUxtTRDQ9coCy3KEtrg3tim5+KjrXbtPUjINJ77YqWJKi1i7mpBkmABnwTY78raHcjZwDPTERFkqVgzajmvTooCJI0INOmJEHWOOh4wABotioAAhCyV4hscgILZLsbUNbD5ipWbL9P6w+YZBv85TCuhuFUfBsUR6NV-u62l7a0wAgAVjHgLZ9VgKwBwdqZAiujY-MYwMerDW8eOqeWwBqBIn4A1+HIIQk9Cu8CMQTkJ-8h4APnvMqssfmc2eSsBgnm2K9hbhyB-qonWjtJyE9VxzBvMWs5J-Ky0aSpomOQGOLN1Kd5OAAWqQCiSgVj8PIaJ6wAadRIlScY1AwE-+J-MEAYdcgBHQb6FQRmCSrdEqVOwUZlOUAHCgRl6wiJJnvWRfN8m-yNdgxGAS5lsj3Z3MACvQXK7JDOZWpNnuWNi6UBtuwZIAZzsAH5acS6QJ4ezg52cyTHeYDJHmLtedJtS9rZhr498Rppec5BurU89sQGIHG6s2lOQGKTU0pkBjbpOhkNTkAjXJdXUJnSADbIyW6ZftqLiHVQSGB7zj5p86F3fh6PBp4AkvPQ20yJcIBQK9k4JyohdSou6XNj8gHgB5D45VlyKpcJS4bzhtcsp9jANGx97W6oAabcuG1RuEqVdGYdBSvnfCw8hAFYATSpFUxcvJoWsLeFjnyIdQA37aLDFn7pxY8uI2Ho4x000axYg++0T8Qjo5Wd8YoAtl2sUYKzJj4tHVryIu6R0eoixLgzVfuY2T2Wu0Mbr7RrcKyZGwtW-rnR7nZDcJVGWljsCpqlVQ3tNmVqHZns076HM2mfZzF0r09c9Cvn9jlKE9WqZZuumNL91uFhIS9sXpWg+PrJYcw2C1sSDFBjm1JT0FsEBIFO56DoYpOYnm2KwlCwDHqBYTYAOJgk1xb4tCWxLFVp315b8t5LjrdlsQEndGs0g5hWqpyz45QA+WE0PAHMyFYQtLWHPG1va007jORExmVINhlt528wA6fed862ICutbHNqT1jbF9YSHZDUhwNTt05E4D6FQKmq6oqEXCPLUOA3RWc1sU5A0Fzwva5AA0zKoaF-3NTrdk9tu24ctodGucJxzkEt43sLEBP3Dyt126U9HusclOQTIpkVqK5OQDHoT1J8U9Geky3nqQAx0VAGZLGyCX+KrdWAcgCvVF2q1bIKZLgMes2CL2JKkILEK8TjB0RAAb0PKy5Qdhwj7+KnrDoyPDyD7GOho9VG6PXdBj3PQXrD09gZSyKKp948-V2ENepGojRE9RnyUayB+M-GMASBAAM6vk9rS6F3bJHHYKOAIwMdwBIHB+wFx7PL8MAIAFp68+PKHnKcICPbdJT13WHSvYNEMeIlBp8gDj0tPsAej7PWJQL0AvSa3SLx9lW16UamwBrARALjrGSeTgeyi3Ri8d0u6JHkJHmabRY1lUmiC5Fa1eSOpK0oUFVJp5yUZedPWXpj2Om3auOjjvHmO9aEACdC4AGQarKBNEAAv7WAFG9yJeshXyz8V7SCJgUWHoOUMfGMACjAAOnPReiP9Xo5CMkMRnIpkhaIlNjQcOIBiAyQPr5PUG+MeF6piHgLd+GC8eZAuoeKMfGuqTGGsBIfaBgibB+ehQYoQABt1c5QAB0NYAKwtgNKqkAhQk2tz4Naw-X7-Q+yyao4EACBNQozdFQAGN02VIPcW1EX2cgD+ePrJCWxE+ASKWb4TGWdID5pigxBgxkEPwS25zTgTolw79i5gjO-xfgpQCgJc-v8c5zwvIQOxnM60XP6+pWRtSS++f2XVdvKxVRWog0HAeAKw6Cbf4tSdtFqEL74X1vRfGQNLJe6+ytusE7br8HGE7fEMM+p6sg5zxA5VBiFwaJjY-RbLAhyc+FDz+1hADdAgAA")); })() /***/ }), /***/ "./src/js/built-temp/base-nl.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-nl.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYPaGHjwAdmGjsANmAAmiWHPKJEPRaWRhi8RQCNSAVwDuYsADdE4gGaJd5HvADWps6QpadYVuVKyDAY3hyU1NEA1gNBUEgl0sJBHhZIX8NVik6GPMKZFMecRFxUlF4PNkeDDAMH1JFSREpM3gpWS5IABpwQkgpIowaekZIAG0eZAwAXWAAZSoAUQBBAFkAfXnUVGWASUX5gHFZgF8AejpYZWgjuAp4ZdZMG4weKy5HqyGj0YmAHVFmNk5ePxBMJTHUZPJFLJlKp1JptHpDCZxBZrLZ7E5TBp4iIkmAUsg0hlgllyDlxAgvD4-IFgvlxLJOPBKb4ArAHGAKWEIsgotAYuI8iDCsVSuVKtVauwmo1mlwwAARNzkDyKdKNWnmOIMyrwMzQjDa1yksRtMCOLEAKyZ6oZysF8Ik0mEwtgVTEDJkVrABlYVUQDKERhUyq9NjsDkcEmKUnSypRYCMFFksC4P3l1v1YFEwZJZITSdqCVxVRqQVNQb0OgxokhCjAXu1YfRkeQpE8BjUdhKDMKmkNmYQWFbngp5rJcoA8n2mRaO3AmSXREkIlYrKYKR7GuIOAZPUz54khDaggJxA6hrpxkUSkuxSWKXVpU1ZO9L2BhwhxBgVOITORnKIACEPxThCEijNI1rZKC0YSCoPD5uQPamh+9ZMo46QGBqZJYL2chQca5LWkEW5gAAtGAADCGi6HkIjKlS8CmiWYhMqYuhSGEJjikUy6kKumKaOq0D+MQPAxu66GYRqFLeCyNIhF+8B2B2kYMhwTJYoa0FEeYJEmmAHC+HWDYZioFRiUE2aIMqg7wKhjhxGOYipqI8pqI6TRgLoup1gAjAAHGAapNEIAAUADqOZeogMhYaYORMj5HBihwsWGTwFpAQAlChOY8JGPniCkNZ5AY3mcGKWIOmC3oeRSXY8D25HCMqcAqIojReYK2ppJYoh5BgwGiFFojFCeXo1U65qkKwtbiI49gWhUXoRPA36iBUESQvusCWPIPTFHp5DQA4crphpHjwFYiinMoYBWAYoj+Gy8BCKYXqLZlGDqKQkZrRtW01FmDjGJpNZGAVzhSINLk-Be4xTHtS6xdeYAAGpKh6YivuM8Mw3AePiIQQwAFTjAqRTOMSrZ+NAPyEGAZMUxOIq3hUXUyDy-5BLDogMyT5NgKzN5lBz9RwY0345PTxMQMzYCzPQ92za9suMwrABCeTFKI5qUHgADStihWAABkivFOQjzwIBYAABKzU0mWRiiiBWMIpT1ruCEAEwAAwB65GtC9rY1iPrsB4Is9FgAAMrqoUC-LQv200rDvplYBYn87DcHwx22hy4OwJDjjQ6YgAm5IA8H-w0cBOwETCO7PAfVLkyACqrAQm9uM-JskY+j3KqeTIwRYFIPJshUphyT5J5lIoGnU0KPLpewyomE4xdyG2QH44IjfJ0zQvo0EIliRJ7eeU+zSKXVsDyI8m2mGFtEWmYcqkLo7XQ9A2XHwVqgAwHANJSHCprTgFAKjaiwHqcy2lSTeR1iEUIVgsDQB6J+HUtFEjZw9jkSsdxYqwOUoiMQAC5YnwprMFwQQWCxVpgYQMOYsD6DBgKHQQhzTzn5lQhW8xLB3GgLoGy+4pQNGfLhIICh3BhUNg4IQ2oyCJyaNoJqzoeI1ApPGRcfEBKiFNHyPBCV6KUJDhTGOJ5oBKmwUaMkgChaoGCO1V66ofIIHsC-cQYU06Si8j0VWYB0p6izhgNsshALmMFjQ8QohSDiy8olcgw13gNybpedy-iZDAiduIGxWFAiAT7qITYiQYimEcuId+UJ7iiDlAPCq4hEAvQcB7HqTJ8TICemoAAnpouesdrLKliukCQBgMAYLVpotciRRH+H+uhF2991KaQzhSYoeYOnZwhlDZ2m05SQMcC7TOWUOTBBjKQMi+gkJZHcA6VwEkxa7TYOwUQbdUmXjjnkRw0ASlDHSY4imQwsJSAALzEFgLAVg0AcBHCOGUESSYuD4g+KIMwah4BHHtgAOQAOyzHRhwdG4wJyrh4P4Hg6V3JIqQu8UFRMLFM1BRCqFMK4VHDOE0HoKKNBHF0EcTYUwACKz1WAAClUCXBYHnPgiM9qsDeW3el5ApCMpicy1VrLoWwvhUYfVXBgiyEXry5ARxyDSv+ClUgiMDBdmNWoFVaqgWavBZCnVHLHiwGIHa01nLv6SAtbnAEcqpiGHIIEPEvgmRhV2Goe2drspOvVSnYFLL3XsvhV6n1ug-URB-t4S1edAT8p6AKnk84LVnEsJgqIRQLgACUFjykWLMLgyBZDjDTlIDOhDjp7XSKIZNdd0ntE6EQRFKQkLfL1oMMlVgKU8AANdjJpVO2QLVKIsEUH25AmVAKQE6AcDoRAMBltiowAgXQej+kGoMOO-oxBjsZpAIIPhyCDFmOQd9z6ujesMNAfa0B3IYttIMVoJ6ugMkpTyKQUxW42VkR+vA7Rf1EGgAYcltBL3jr-WQZhQHBiODQ10PdMY+C-EGIsEjRBaLkfrYMTWNGoBnHEjDBjKGqCHsZse3DkA8gLoGggQYAmSOQDZDkHDjMiDXngyVWQ8xwmDAAJfKfyfAeTC4mjlNEMxyAtA5O8WgIp0ggwAA8tAAB8EgNO8VMBPHTenryLDKggEzgwCiZ1EAYcIOp0g9j07QFz3mEDGaUyhiz1m90hfs9pgLkGX3XkdlhdzKHPM+eVA5+LuGiC0GSydVLUBIveg1Flp9CWujXnlIgXphXX2mCfn5xzFXcvVd6WF0zEWrNyDqU17L0mmC2aXNAKYZBKDmb5PJ6AlnoB6ei+EN68wlyGeG6NigDAIvzdC5ZzQZnJtGZm3p-DBWlzBYWyNsbG2ivHem+VMzW23o7cC2d0L5nusPd07h3jL7nDtak9J8TthBhUHmExlrUASpnFIFIQYlEqANrjnp2KV3IDzDjlx8Hr6RL-E-VMSienmBPBR1Me2mwABiGOctMDuIEQYUxUDzCoJsWY3HCAHCPZByADJWya36uff7RA2SwHSIMdMrZhIODE3kKHgxDZuAztqdqKNDqaU0KMpkj1nrTIpEUV0tJsZAVZ99qAPI8gx28wLqAfVel08grpirkBRKWAngk2HLAX49AwFLgk62piICligbAKHNg+8oPyMTeSw2FPgPbaXouPK1VyW8iQ4ailicnUmGdxGUPzsXSupka6kxkT5OQdUYAwqzA9+1GGGBspie0D2qgyhficWEyh7tvbPDqgHWIA9Du7CkCMCXqK5ABqbTpxQcgvS8o2TkAnp0tSYTBWd2lFAp40JaA7M87yPgh9BDtnL2a+F4j7VRkdCXmkPayEH6IG9G7RI+ByHc5U2knnlDYqXmyg0IN8cAwHnICcMo96icMgkWYmf+60gegBTQHces8SRgumOeogPkAEG60BMODukOZUQeUAZ8SEQQYmxQRguwgegwOKoMRgYAUw0gYmPIDImsNuKGLca8jgkISoYAZmXIY2ZEMMeslm4BdqRqi8gwDaiQwhHOnQXOVKnus2eAV6tG4QEQlGchVOkAf0c6hsem2MbeuBQQkMFoYGmO-glggQMOKGS23m6QBBmOreBBKGD6niemLie0427e58Lhn4Thb0OgIh3hDAmOWAsASMp+Kusu8ux+wRyu14Wh2mCAJBkmwekYW8igFYAgakbYemGK8ARgXcPcgwAAWuyLkQoNgJjswIPl3H6AGAUUUb6MoNUWUWQEYIbPAL0rRLeJtLIVAIUUyFMNGGtLAHyJ9jxg7hBL7v7pATkF+j+ioQNuJmoCLsHqHgkMqG+hQHpggAMG4YoGMWHhqPGF6BAdLEyMCHupggYKwTgKzhAMbkQLsUERMccVMAEIENAF0fIX+gsTgZAH7v-lpgAPfLH0SyAbGnCDDir7iPGB4CBCAYb+CvGPI6iAmsDrbAmtBfYO7HFxykD+hk6qBSDxSW6C5fGDB+KjwwlmhsA1CglbFQBkmcTNQHGQl-EUlnEEmXHXFgC3EQ5FALqki-GTHwDpjpA6EfHEnC7fGQKNBwBijqj6G2jlaqGbEo4RQiCKBejLwLwmRMhTReSQwyBymZQKmiAAD8nJ3JMAUJOQwpOgFG0x6xsxAOQuixuh5A8p-Imc5xrBNJKOZJhpBhHp8YiuVpJxQgbJFxUc5pDuzhNksAohAAjh2EakSSxiSTnqwANPAMYNnDCh4XQsEIfD6eCUyKhLqTILNJmdmbNO1GHnhNqHkPOORt4hyG2DvMIkMeiSMXxokGoC0W0aKOPo6S+s6d8XgftNYv0W2IMYqXMQGP4KLuQBcTmcfgMUIPxO+HOI4PEgruyDFFqIyA9E9K0kyGtAmOJGeRaBpIYvgkoEuUfrMHjtnJoJyGNLuPyJ2WztGX4X2e0WUJ0dRKIHyVPBRimfMRKb4XyLUJOVwjOQDnOfHooC4p4OlIcdBdOXEjmIrsjPIDZH+Y2bwbhHKBFOeQ2B5D5NKdPGIGaRiXxr9r+YNNAKIZBRONnvgEqWmVAH0U0KubFkhf4aofBShumFGNxVOUMRlGclgHxVmDmD6oUPYM-NpqePhXzAejRS+muAoPFExaxq0kUKBSOaLvZKQBfjESJMWcyPPPgUKIeVruyBSGwouQVK-GZppbAPFJZtlHPkyJmZWBfAVKIrPsCNstzqQJOHKSIBUFpC8lEUdKOHks-sfo8v5u-q1BYF4kNFGXxrJiGd8nuldmKameBUwc7PlcCcEpYAOpLIKbNpjoJVABCWaE9DujmKpvkiGcXBPCctoLoEVOvtqKFRfnKHge6S-klG9HtOOdVccTeTNArjFQdNeGpV2S+kPCUc8cgNzIwWxXMYZShuQVmdxGtQgH3gJW9POUJR5ClGcoaDIu3BlaCKUEIF6K4Pcp4JxAoHADqI+M0B4LoJGepV0D6FUW9JsDWFSKyCBUOZ8cVVAKzHrpJHFHUY+rVWdeZeYRJLmA1ruUyHJNSPRIoI4E9LrDgk5awYhM1FiMDfUW9DvLrm6O3IOi1HtlDptJZuqL5WKF6IYI2GiBGKYL5YBGZpcKzRgNZmSdTSjWRHtL1QySfnWNssEKJJ4voFuCoq7HEDVKJEEMgB+TcQ7hWsBrEfAABUBQZRxZAFKRNbKXoUaeHnVedRZUVJ1BLGwuQs0prV3rbQGRqGFGZikM1dZliN4BpoojvNdaINlHbKqZ4BqRiC-tqXPikeedflRVlS+hxAYK3F4oMTijULAT0AsokObbDZAHnRUL5TsgjYzSCQ7ejVAJrJxMYFCBcQBBJXEgkiDJ4PTfrs+HbJjFIBEKQAhMksFCAWuZoJdDrjWAzQbnrVyQ7nRQORgNAGDVDtSGyPpdDeKS6WXYoaldAGhUMWZRdVAFkuSdoNdC7V5IfaJTBfSOyA6DyOXM7BaCvM-YJDxBSE2PzbpOwkiHKLHieBHa1DZT+AOjPsqEZNbD1uqUyCzT4Gzccm-YoMMsfrfYPWJWIMLXAIg2LULXYJZmZoQxwSkNqP4JxG8WCgAORL0dEYDUOWZw4I7C1kPwDWYADUEg6QbyeAfI6QL0scnmbCDgG6WI8VrAy6GoRwx0o1LkxD5A1m-t0aeIlD0ANDdDf5DDlmJO5OVArD0almeAyWG6sMLd5NWIySCpmoZ4ngYCVgpC-9bZH16FXACjSjbDqjiAVDtDrR9Fm0jDaO+jRwbDRjDsPNp4WA5jsIx+9gytg0NjwUeS2ooi7ceEG40IDgv4fOE0TIl0fUn1KY7j6dXQ-gwQJRiwNk1MJdu9B1YM74VTvM4+ddp9kALc10I8nmHi1YggyVPlKgutYAjVRNNY2cf0NlCDvQlmFKbgNYVoODot1m8Ynm9iLZuobYuE5eZQM48DiAWgwQVgYKXwkAGauqRwWRf4XAwa+cpAxzHINkgRRzkAywHElgjgxzlmlk5AwtiA1mIzLVAEdemOI5swwhKGoLHklTPMH6gNRA3M1MYupAeVagoF9VkAwzzVDTs+pcIgDT0LfMXgLj4lIVxlcoh+81J+sVUE7gnmvQpVmKQQyibYnM6iG68LTTuEy1n5fGhtlE4QptPApINTkpicMpFQW5PAiqsFL6aLjVztekXkbtHCFVtjhNA0UrPiyjgdT5lIodtNFIEdUdYAMdcDhk8dsDG+i8Z54Ie81FK1XQdAKJlAUwZTBQ5RsAI+Y+Xu29RVu9SsTrKxEgrrYg7rJ9FlPVigP4WAcCDWidFoiI3k3jwI+pwgtAAbHpsUsJwbvwZAKYYA8w4CG+wjPgDUSbQgEblJD9igckrxy+m0q+k9mUdIoD9jR47B0DmzYEhxToZT3jkKXL+tPL3j0AfLsAYNGG5KlKYgsAArQrPrYFu9VtYrZo6rbyYbKGGLozDoXold6oSoPQpE0VNmAjr0zjiAL9QExrapG+mpCdprDoKbErGrdrbOEhdxm0pB0NkAmjDFE46onE21hVkA4u8AlTrAjG2RkVN8kizQBO2mL0msHYzQDFdO8HgbIjxdZREQrAqAnEgQZIxO2H74ngBT6FThNQJRiH4kWjC58EOCiIemfUgQiwu4bIhIgwuHHUYZwJMQXhwk8AE46INYdaiBcNYwGIjLmk9gS6wnr0Whggtg6Q8w4QpAgnWTe0m9onPxTu0MwSKnZEFAy6sn7IHY-Fu1CSZ6MeBgIJ5hlgZERwHcagGkUKpg9sHc8ojHeH8AVHyHg5UAnHn19HxgemrrFTjTyG-nRLeL1Md6DtIpo5VkDg08jH3jCAD6cAjdWd3gceKGnHkYRLigWA5okjS6kn3kTdRg5jemhdjgkCg97kStmngwLcKkBUSTbyKT+0hLfOH6mObcVsUwkMsAokUwTU3x8omTsTFKkKCTQZuNnE4cvXqh-g4Q8GJ7UNUAhs6rIXs0vSa3GmTXKGcukj9EIX6QNk+3elWnFhb51iaHkufXkrOgOhkAqAT3ZnAO0AQ3okD6vS-OKGxFbxASdSJTCh1Hg0nH+H07oF-gvSFD3nSHWj6MX+lVXRkAE3d5GcZmv2Qdz5zC4l6VVKNY64TIkMQPg6P+cxubv2D6PkZhdJNQv2eA2PrR-BmOAmpA-QgxKZ6GUoNnnF0YrLzGRAzeWAEHBZxG4O6GEQygYv6ZtaXuUvUA14mwCAaAQQK2-PkAfkz+f4GcMjqNA2dxav0AqAGvQ2WvxWr1bpQQyeBvwvUAmKyApv5v8miodqu9YUtAvsQLVOxJ6QaPxWdk4CnJNxsLUAIUUg1EBI8XedbIC6xhh3O1AOkfVAFt6BHBkfbPy3qQ8XWvA9Q9TUemT0NXXPc6M9vdv1ZmwQQYSElmp1cxugihRQOKpw6BgwA9uE2o7f4fkA8S8fFKIn7xqhRBlRNNn6do70AtFBTIktKT51YkjggVKSemTxExWvjViea5vob0nEhFoPTAZA4H87e1UAY-KNemTfUKRQBdpACygw5-DIGxDgEXZdPAjQYQHBVmz-QQtPoUjAQwP3lAE2AO9IAmwEAUrzAHgDQBmwdGKALgGQD0YEAoAZACQHICjeuBcAegKN5gCAAGqAPwFU5xgmOHkLQFGAGBkA7fFDDsFwHbB5gaOMADilgELAO45eLilIFZZgBaA-tLCLSFgAsdB6nlA-jAA06HwKUw-XahbWCJsgZS1YLQgoEQBR4I0b0HnkwBl7F0fWw5C2mDRzIK8HeE6c6vYDmgbc2mIgG6MEkxr2JTAW8F-OyFmgYI9+pgEBtsjc6ax569rOYnjQCAaDk+GAhdt8RbheDAgjLfQVADnJGCk+pgq+hYLGRWDfwscbZsuStatgCOOoIIeVUTD4FryeQChswjaQch8eYgIIZ+HcHcs-BHod-jEH56FUtBpdFuCFCQihCuchgyVpEPabmD1cWNeIQvHZAuCO4msCmuxCgTWwWgofV9gNm5JEB4ko2f4KbwhqBAteX6dulmE7pYAXAOkNIfMLRIE4ZUb0M3uQBezfE9suw6bGABkbIBhBkFNkJ0XNwGBQK1uCTN8WoL1A2QBhS-ojwYqQ8fBpg-+tKy6B09BiXwrXtiQ65JRxy9uVQlfyUISCcBWBbzAl3wJtQ7coAq4Sh3TJqxQBZIO4ZxiCATIZKs+B0LcLGHs4PBLGFTvYFiix4awMI2obvQTQ9oVhYsM0o0UHxUiUcPRLQHHkxxiQGQbIunASRRa99M62daXF8Ii5AcUgcADjktFmy98gwvSFEtLhpFdB5Rio6kVRnC58wjsdqUkv0JPoRCTBhsGGC2E8DaheC1MbpIIC3JH4j8nmdlhlR1ZfN8RlAVsg5R-CmgMIbXPtNqCVqQodam5bcjq21D2iEmOib2saTcaEN3GGPSMEfhZ79l6GuPGyiGM2g7wP6AoVVpviaipUUoytU0OuUmZs1fRniS0dAGtGsAFmeDJMXaM1GpiKQ6Y5BBaBHgYI0OPHHBKI0p4A5QumnZ4vCTejQA4+TwQfpEKhYxdUxwIIcCoFYLz0LS0uGRK0kaBUByR0hYVsDmXEXpuRSo1Qdr2WB+Rlgd0FpDLw45RdPMhYsWvTRQTfMRaVY5cqeNwZTNKUPMBoNkErFTMgxB5aelCmCAXsG+OAvcb7GWAlRGgvSB0q6V-LH4Lxi3YjrdFMBnjLMPQUEYmyXCvi2aKrDfDmgIaKN3GafVgMz3vFs0jRbXUEFYQrHXi3xZo5JmCKXDQSN8pY38XMT3EABmfcWm32gIUKScE-YLMBxQoSxaXdQYqnVEDF5pAdsJxqPUglWx3o4gBCZJCQmU04QpotsDIAwaxgd4PkFgBT3cbYTJWxjCJnBN0YU5eJ1mMxouQsaaArGmQCSefDPafV74jlVSBwXwli0G0RknVlPSZCL4smpQkkWUNKbQ4KAyokXt8IbRuBa6qhN0E+iYI+A-htGAkpKQq56Y-ulyIwM13qCMcsI7HXLsGEN5djeklgWHHlPymY4jAYkF7sRQ+6rVno-k5MiVUqTSRL+eHVipAHyK18GAvfYNOjAcB-hVx9hEHpjnshzRtqkABOOtB26sBekfZMIiV2sSYQEAMOL7G+0P6zRH+Kgr9gCNArZgEiDdcEaaDwLYxlQFsJceHBD4tMDRW9AXmom7BcCeB36adgINgDWZAASYTXSiC90-gr32ix2FfBXQTad8XhrPwrY+o1oSYPYGcDuBK3W6TWDelgBnp3A16ax3emkjIANbfsQFI2mftNuq7AyJ5NMAWx2oyI06cDPOk-FBeV08GbwLukIyYZL07Im9OEF3Bpcd6edr9KoxiBNm+ZLcEDOMHEzQZZMm6XwOhmwyzM8MwQeaUWmQAm+4PTopbglncVUW10MIIPW3Esz7ClEsALziXCgDwhRMrTk3hrTpsggnUJUHrwMiejIwxEkQBnEsY8diQskIli5GJEfS6I4os6jYFY7KyMZkAf6ZeK1ktDuZWnALoMVvHrCkE65DCFmWVDRV3JVdLlBe28lGEWAeQRTjgRqFQAVZcNGepePLwtEoUg0X3uUL9mRDA52-GyqszDnSR3x0c3XLHIAhks4gLSP0asSkCORZ8mQ5qFgFI5wBvJvfJ6LaBLC9yXmcs+dgyDdlKzNBacz2UdOjC+yRIZ0rTg+jrDW8TZwoIuEqyRCaIZJ18VJs1GvzuBN58c9ikEF9geytpkAKeV5HIIf9yo0AyAdrP9n3oOouvW3piHupBd15pgTeZ1zSa7w95eSbuUjMkAwwXOLs2cgrPdnjy++nsvadpiW4FzZ5OsqjKxyeBHlNOEsCiNAu4oxCTi7yXzF1TfrZwy8nQwwNCnCAHy5i+IGnAVRQHpywB6KDZieDCgULDx+cnAXfMiGYx1oigHFkyE-lUTmogGPMNtDABtUyFXY1IIeLIh5B+OJ874mDVcDrQGFTCl6CwtAXwL75KGDhT9A5Bbx2usk7eaCEDzkhgYIix2UjJW7AL5Zo8qhX4JoVbdJWG8GeWUwQVHd1WRswiIk1VoC0cwdmVYkpGiE+QxutjKQDdFCCFtiFrAUhY5MWYFtnqJZVqmpg8DBLCuykMmrAFNAdsLWpkYJPdR1JNBzBHNJLuUDSXZLbQQgQJHNGPw8hRIdETUHACFpkS2axIzHImX9AyLZcWM5UGFGFQGB-QKiuCoXMNGuKuh6+LImNQp5RKqxMS2ifEvpCu0UlqkYpRkq7YeSmQ45YkAbmOic0fopoNZWUvlw7QGm1S8-Kl3qVOTEZ0mHyYOxfQlsSiIC-pVYraUoYQpKxQwigLYUmCJu8ENxXmAACc-scUI+nEDeipI4zRKKIpfTwkUpECmhc8ptnl5dlGgPpTKwGXEzPlS+OIWAD+UArmodkWZWaB6CRg8g4KroFYHp6pzIFp855SUXLyBR-YSKqDCiq05UrQsEgE4d5H6S0r8IEU6AP-N8nS8Wk1TYeWArHnfSX0NC4ItIGDCOK55dOBVJgu4VdC5QUyy6JXQEVsz1m60DdCMxJptyDIbcxQA6GLEkRjZtvbyCZUxAZwHQ5ok8B3IK68qrlpGHgLQC+lAcR5is6xTgNsXSQxAOEawm8sZWszNoXCnReHPihArPA6k3cBnHjD+hF4DgRoPiojk4Rv8pivlVblUDE87lyKh5dCqgX6RYFrCgNRoqCDmDX8KVLALmH6o8KfkJ4PIBEp3SmipIEcxJj6I0yNzTw9a4lROkMAcQU51CvNaXgYXyg7UdPelQYLUXsKS1ByjFdsmtV2gcFDag5aGrjD7kwARq+dZ2qaWqEWl1Q-tafLwJl4ulPS2QGOrCFFrXS5gpoM4DNCtSW1BETQJ5jWVNqsIXak3IK3fQ+DyVNCg9X6rgVOL1FF66ddDnLX3qq1wUGtRut8zArE1WEO9WurbWeIO1pC1NQ6sFznBiAli91Y8twJIcBoIic9tKucVQB5gfYuaATSQ2dR65mNKpNgnzJbKDVOgYauwWRxGlX1IgigPcGw1eyYUe-QjQBp+IuMR45qk6KJGBg-gn55AZPLNFNBCLPMt7HUsy3qCss65v4JMLFla7k1M23kTDGuHID2qF6fGHNPLJhjqhgCpm4FqQFv738UM4jEuLPW0wQi5ikfNbJQHMX3p0YiOOUYKz7WgKc1oqn6Z7MrxBAbYjkOnnxvYXsFq0vwANok1YjWwzoKGgzS+n9AogFhtwHwK8RsRZqGVfmr9Z7KNERyDOyAZwJJwLWqL-1kQloobOPzLqdWyzdYRQD176aLScWjAL0mWDSJlAR4oVSZq+nDTE4ZWv9KQBbhWwSiQW62ENMxjrEHauWvdd8XG02xOtSGcLSYNVLk1WtdghXOwQxUUgSoGGHILSGa0O5IYwQQCT4DeJoj-NzQ2bTYvy0mxwEaQTKI4Vvnnqfij2i0IoDaqUk6e6+bhWxoO1SUuNxsOnvIsB0vaJ1JgzRcGtxahbTYaqoxZ9rUzNbxZVwKfKIVr5JAZZNfXCoBMUJBBlg+0ZYNWmYA9TcCGwuxRq3XYNVcl-1Y-HBKfYbxXJPdRGhugogXR0IQyjFRpI9jxg4JnijCrPh8VM6X4Dcg5YZxk6iDbYWkwhvkWgSZLwY9kgqDog2EmBJkbgNQDsvupCA4J5ShjZRrgCuS2dHkZNsGCxBtcvQKzXDYIFESRgeqOoGNteUSHq4WEt0edWaA0Au1R8hSn6AOyS1dBsdSEZYDcscIn8LasK2kFTvR7wMzlJbG2a5NyQV8WdLUMkp5O+WmAsVINcNUuoJXEd4AM4r8hjtuAZqQ9V20-qgP0iOb+l9dKPRMqmbqh1Q8etconprotR4aschMHWFq1hQj8qyYJcGMsAv8tArZF6hsOrnfjYAXlUwPiHaKxwn6ngFZtkDA316TwWIaOcut7zS7FGqAKYHgCmWfRvVyBXghumdqmhgQJ4O8Ys3X2H7SgTCaAPHrxUNk5pBFXvMIID2yBlge6Z1dlp3rfECtYa4jt4kj3CU4Jvqq8WcopLM6W9FEFrmTSTpvydWCqq-WmPVVZ6KoPqBkbzrOWxq1A8a59YRGfgYAjJvui0m-uWDtQi63+31k8LlUfVBt461ppu1QblQMV0+52aYgOVwT8ZTQYMEQYVDYL61gYNTUpFYPjRbkoSoQCqpUBfUr1OYdstYKENmta9bNeHXAg2ayAjJSqwtiqqS5wRfVoOrVcTXkNZCesqmpCHrvg3K1jVjW01XzvNWFBSJ4Bq1RBrSEFdiDBenHYArUAl6gOZe6gkAs8SXBDFoO39VXtabCVukg9ZBXZWvBjI4Jx4WMI3qrr2bfqFEMklUkGFKQNNMTe8JkB-rVg1J7tH+cqDiMmrJNBiwRVBAUWFAPYYY-AoOiZ1l4LJxIXhXJI31RjCGr+7IjjvcrHTSdZ8wwxgTRphHo9izHo9GESOQGPQrOoZuhExbeYJNUm1+WvPvgtH9F9IdgrYWkl-zOjhe4PfjshV9Hw9r8BFcgHpXNDq9jVCtisxR6jM5uShsWrHtK3C7q6Ux5PZ4EeOUAFjJPTtiCsJWXspwI8BqIUf4YHdY4WSj40XFglnLzGG+I-NQyoDUMEDhQ5EDcewQUgyeIJ0QEQZ2M47Pp5AQCYnOzC9q+jOc64RgAM6ZzFukey48pA4NnLSTg0Ck66EvHPHkjkSPg5dHSNwS9EVwAxEUbgBhrXJaDJ9UkcvHQBywwYXeSGDYiTsjOiGnkyuDXALQ4gY+pwABDcN8ZSDvc4LT4AHkAiidL-ZYMfND2l1z5MgS+UgGvnYDkVFxmnTBJRMUjbjq6uCWMaaCsnK+0x9nVdEvVQnFmOR4kBL3lIIBeJmiT6Ji21CunC28xtwOkRpbNycwmx3RYbl76kHPDwCwCeIpeh9G5F9Cug2ettN-V7TUaAkIeOtCom4NcRyTgkYaV8TJjz4FqOfVB3Q6eFastY7ofXDGKkdOJwPeYs8TLAd1fR7pf6DAAU612LTcNrSdLnlm7j9Ojpe6aT1G61WrQ4ZYKDiOD6BTF7e-d10C7xhuFGp65V0cD0MzM1ywa-B7x81OkLaw63ql5GX2V6bTDBu01OcdOUa8VlZwdWAcWZJGPTbxlIkEE02FtSEiYc-PmsgbHRzBLpnRTtoUUww36rkvtF9tq2ChO5iTPc92ff3Hm+zA5k07vSHMbo7z1Jp89cZfMVmzly+z8zeLrMpGHYXtcgJeubk3r-QzeV80lUX2PqclMGlfimcPPv7UdnGnC39J42YAm+AkPM+ccfOFnnzRPFi9qDiNW78Njgec1AZou1BBNS85+fYZbJFn5NQ+1RBwO7D7n-dPF5YFYGCCtwAOfR9GEtFHiR6ySE4poBGTtiTRJzDoOI0tHERumazQdZvVMbtjn1umAEWsMkvgSYBEEeYN2B7HmP6l0gzgLCHeCqMVJbkuqy9rGjk3QIDIZZCmjsTxVrQxwX1eJOLEREPxHKV07ZErkWrFAok6Fl5nFOy7qiBLjGCruYwAiEWmqozeYxsqZIPQ+a28enbNCkb3w+om5ry3bEu6BthGykURuXhMZUR4cccSJokFMm3R8kJEkwzRK9CljJ99IUycuWoaURET1UTwC2JPZtiMOG6CRgNfqSb7LMeXNusCDgmV0-QMgoyaaGcu06TwfOpq6ZLIhxDXJ1vRkeUDthhRhKqzRITu08CwwGhG6CNtlHz18Z4kQeni5Zehxd8eFIBVqxWwGi-Iu6xgJvS8frPeiPIkfMC+-FYtSBUbhkdKCeBsECAuEONofO3TtjXWwA2+6OFOI3x5G26ldRyCiUUAUQaTtOuCbFFcmrJhlthZUAVYBtRVdsZyufvqzs2V9sGI14QQjdIOmXLZFlhqxopRuyTI+keluGuBhiUoXldsWYKRHcpA8lwSoU0Jlf1VgbcrGgfK53WPDKhTObCGIBojKvYUz8tsMWQ6pgDPdLtHxfwXOmMEqDMCJRcJOiEClQAlt9PUwaNsGNzFmEQQNeiWpaTfEO4JeMAGnbosZ2kcsgVLd8PmCF2TCxdXvhLiKC85ZAGCeWWYHL6lw9kBFAnHtAIOyrMAsXVQnjWlHyQ5OQoxHtVhe6cFYAZEHuNZjXlhSX0nEOnjHcgAdgXWsUC85INLq52bAgQYvE7g3H+qIdxMscvdQ3SwIJQOiVdYrupinRM1a9vPXwdPCeJL7QbBhIPRWEVADwxYZSN43Ko96mQLiaHOEHZBdXXkiGBQGBdFuqxH6Zg7K2YB6B4JP7ulllldIvixQU1kA7HAH1UHoYfQ+O6ALBnjv5FY44cvIE0KwejJZc6QAh0ryCkYBdwNkKjE1A9BNDOI1sAIRKCaE+o5eDVCgfoDGFh8JhZRMpsBoiiX04MIbHAxilgCAcUBZe2XRoDIiqHnYGAIXuDoq2Q67qtoaG62Vkc14R4RkDQLkHCiljIYXkdctWgWR3AT1nYuYkMVOhshRH4jjAeg43hkGegUKzihg+VALcMADbQh044fn1sBmTQ8eFQ9f4uZjUTQJoTYClEoZ2BhD1xyZdS505XHIleaRgMuVpqiA7jnpWw-JVl6qAKgJO4Wp3tac97RcCM7k80OxDDZiD5siAxqSy9YgmRsmtZKcFNt3wCSV+pGEroUKrCsAX3ahpJW7hwE2bbcWXoHrlr77OtFbcTLJJ22o2MieSSPFqhH4+mYsMZ0ggfB25Eq8-ecGlS-wHIFQxuoQOriGH+Ul++UPFeVZ9tsaCkw2FjggF3V+Cy9YuDOBPC3wxSGVBTwYKNFENwHxN7UOsMlawV+Yt8fIASII3EBu2F+57Z8P9ryH+Abnn6iR1eYGkbkUoTgCZ1p0+cJCPIPzyaikQLAAvukKLweGoAwQ6coXW63atoC2lZOrzVMTILfrRey4w6QFkNuifojfgE1YUI25CjOG7w9YQQWG6AO9T2RVp-mmVlU1Fy0u8zU98oJCnvTTc2pyTqnJMKgAHMXExABtCUSGdSDyBreCjGAByeMOKpoRmVQDxybSmbKfkAACyWutAHAFp0Jjer-VTQ6oNZbE2uhqu111Kp0UZDAiZW0G6k64N0OVAcRMo5gh3edA8j-tzIO6Vp7BbUhMgyc2+iwbEuLP1qTwFIatJgBhJsbYo8o6APdMlZectXpdYubnsRGlFt7Sj4mRi56GRs4gvzpeP0-U2FHjroJxluV0yikRsw25wYoNBk3AxSKigYws9G4oRvCwj8vBZGHE0bweQusRQAZKoCnh8MPYNjfxF01siY7P+0kkqPNj6v1xJ0ytya6gA1vbBigUzvLUbdXxQGaws8Du-XD7vuOJ4GZ-oGajJXNDSiA8qA9WX1ucX6Spt4UHGY+RiEd8YQOkAI6mBz32oDuJsGOg3JNm-zoRQ6AiWjMgwNkI-JdFPu4vjDR7R-WwHXyZXn60MZZLZDiW1zyXAOEDgR2eHwv7nFtSBKroYoYMFHh7ojeXubyqPdLiTkePPF+o+Qt4WioMOHFyaAmsGyBJMKTQWXmPPufPTd10AwwOPMEg+eJxvDrYeO-H5DpgN496m+OUA-j9aIE-bsoxcKYTuJ5E+nkaeYAMT8J8TgScYMmhd0YV1IHa3WfP0ysEQJoDs9ACUnvTogGIGTlmmpg3MaFEW4gW+GYYm1JkGaZynlaj3kAE9985-ePydwV7yMwc5U7AUL4OyeJNvlWPgjZGdtQ7cLHGYjNLWcQVL9w1bj3wig2X1KuV-+cxn8vPtUYUq8xwYoMAxQFzsW93qdT2vPhRR7F5dYsBoY068oB19PASmDl6tOp-M+1pIJr8fLoqywSXjGQDlCAX5ACyI9v103aNq8tm-I-JaVOEBXOxYDJUIvS6ynCIBARzuZqTvDLlDJAmA8GrWyFgc9vM6dBchIgMg0SLoJcZyhhmntA1YPoa9LOxQiUB+Ag4rj1JQBc4z-CH3HkyZigH+1zN8R15nZwgTQ0uKQCR8xY0evsMAIcPvM4CF0jQbH+dkGAABWfH8j8J+7UxApP17Chj8j-KCfGPpEGI-p8ivIAAcKnzFhp9wUFOvarXo51dAQvoYIJLzy15z4lmEOHwzaGDSsCdZRXVB2HJmYcpkJjAHPUkFEArd-rYv8v7INr4TBsvE41SMJOr-Xl22gP-5rhWJokimA5KYAahl1r4DQBqGSqrXRlB2Y2UfIF8JaBilTGoJmkVgHj1ozY2Ipk5o7G0ggE9ZB2zvu9Qb5C5kBPtzm4Y6m9lNEga-mypnO75xVJeP3tQqHkTT6khipjIP7IO2zYOjYm+O9Qn816PXkDiAmf-yrRrPB8BWUuFHO+xWIBT9ukCvDsyX3MT8+9rqIPQcgI3VKAd4XVcf3-QfpDdLh6X-X1jwn+G-HR-KV8ZRFGr3QhOmagoH14nUyuZtJb-zUeNYLNcb4r9c-4-dOzY3B6KMDBHzjR1C9h6KOp7FT2I-YBvyc-kAWYAxff9aYnGuuMu7BIdwJ8Y+iL-uX7BggoM5ZGyb1KqBccySp3IMa-1GO6VsWgPtCpQzToJ5fOL1OzYW2BPOfDVK6-vuC2IzbsqwYmo7olo+SxuN+x+My9MqIh2ZnnfRkcDuGJA1gwODpL4+7NqfaJMzDHHCmgC7pohBMdsEAzGgsxuICkUzZLsqaIk4i-RxuJ4J3IOyX5JBQ-kdARBSeAGDDxSE+juJHYUAvSH-xw+V2nHaDA8wIqhG22vnpiDQnss8J5OYqv7jlAInGQR2BUlK87IyXnARzHiXHC4GG0Y1hqJvE79utw6+AOJLK+cK9KlK-CfPq4EZ2BHIsC+AQ4v9yRcXHAxQ-g7ZFqIfSryLH7kKvJIKwXC93qKzJcmOPMhNSNAIuSK8qhDyCsAMQY0BdwEHPx5PkZAK7gkCbAJUHwADaDK4o49HlBxoMxYtF6kYTQeaqKgCBDUFQcGgB9SlBcxOUHNBCcDdBDB60M6LgaesD0FEAgQJmpgczXHsxoMT9LQ7TeupLfCT2FHmwBSOyAGDQFEbgJoBkOZQQcGnBE4Oj4oYhwQ-Ahc5TAgCjifWqW41i+LM0xlBYgAYATgbyGtjH8Z-MjQNEnwd5g-BYgNIJo80gmIJyCFmpMjpACaFrxUAFnGMhucHnDCGWciblMD6+wOEiEJuSbqYDpgTfBUBYhBQUPJQAIIrJIayewS+hpmJemx77SxfPdT9yS4IPIiq-Rr0YkCzsg3YAyIRhCp46r-KOY8h-ui-59asKqVot2Aqn1oSq3BtQ4chX+iQ4RyPquqpiWmFn1o-qYlsToYaGivJY265HBpzwAAjuJDwAkPEzJQARxhEF7GciufCgcsQQuh9agiO8jDsg0HgCihJHj8b4q4zOcHkKcPOkAP+g0MjwvmaPIDz8MBQpbaagL5i4ElQQFJUxvEUfiKwUUoPsOy5OjXsaQhc3oQjxSyoQQDyCAwYXgGkBSIHNjDsY1sESuEm3MaKaImCJbKJUIJoIwR6jQW8RFhaHAW6ZSnFK2IngTRv-6iMXgYWFoc1EONJTSDgHdwBBnnFEHTsNKMnIXeqnEJyiCPMnn56c3ILyDfeOMmC4osfXF5xNhi7LBbtI4gJ3IL+Xdl5yWhJ0H9LFaHpHEwzcqYrl6ayfXKlzwA6XLACZcIomwG5cnEPlzwBOoMVzLoZXK8zN0pkgWH1hPYTcGYykrN9SthtyGdZ6YjrL7jZsobOCxpsqJCeAg+FaqIinQBzoWzuwIfp3bjBfQY0B4klaDMHP20YLGDVcd-LVzcUDXAdwgys4ReGyAZEP1y1qEQV9xqAokGRFXc2JAsijcT-E+E9ceAEGG3mcQKeFkmjHO9wvcb3OwBGucLF8GUQPQHyD8i57kSJlE33MQC-c8QcNK9YGgOQGDoBdkXYYWGWqjL8h0kEVpWCYlq1rtaS2t1pQAC2g4CmR02qoQna82lbAha92n7Z+6kALYDEKMsmXp-stbjZb94vgENLn0W-DmSggqeGxAugZcGL5FGHBHszEABzE8ynMnqGoA5oeaAGjeAdzC4SPMxzDVZvMHzIiG0Q3jFQR1WUlD8zWYYUFax9UBULDbXWPwHvqaQgHlnApstSLhDMQezA35zBnBPszXQTzGZjZoHvD8iWYqUQ8w6ATzJlF6wHzNcyAgy5N1G6ARUZGJYShDGmDz4epHlGV0rYJO46gW8F9RGQr8sy7IcFaoXi3IXSD0hiOa6rxCWMzTmCBM0-NnkyGAQoGUoaIH4EYaMkzplFExRxzGZgZ4SEOaJ9RkAPcyGuQ0a8wjRkAJZh7RG6CXgN6RwL8zl46quAgDo5QFHSVRbkCWQgIEYBSSTi57GwTuAbUdFEdRxzHFHwoVzrIAUMPNH6iiRniPtrOwzCP1G-RGUf9HvMgMWbyKoQxEVHJ6WcPZYmAO0TNFEMc0aICIhqlsDApsXos04++OiEJwbomMS9EnMbKGcyTRfqFjaUMo9ogDEAUgJTHpRzzDTEfM5BBhDeMTMT5AN+bdBRCy6r8kUCXQa9jLx8AxeP2Jh0RkOVBWstUPEjD0flJNS2MN5lD7iyTuB7iu4X7GXpbozuE0Cu44sqFQyyblPFCz2zhIZybQ8RJz4CkxxEICeIEyBpIuB9xINARxEISGRCA9xPbSqE14BHHIsKOPUKjADLLchCKX2kcSkERhMwjcgPABpAqB9DGjx8sVwB55H0LgRBGUAg0LzjSRMEQbJxgwGj2SIRZbMm7BIwfvUA0c7UoHabQcfPMAWA4kMnJkEOhj77VKJzkFR4qoVB+Ts4BwEAA")); })() /***/ }), /***/ "./src/js/built-temp/base-no.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-no.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpY8cgNhhorHgBsJo0sjAsAdgBMJgsLLABTsACMAnhixgAZoh3keAa0trjFLWEQBXWLMSwe0QfDCtypJSdLaAArUgV1DDBLWR0eBURQ8McANxMKZDVMpTAAD5tlHxjkVlVgngQRVm14ESd4QokeKPhg1kRC8galH3Na2C5IABpwQkgJcIwaekZIAG0eZAwAXWAAZSoAUQBBAFkAfW3UVH2ASV3tgHFNgF8AejpYckS7uAp4ffasfYweYy5fsY5ndFisADoKNYsdjcPgCIS1UTiKQyOSKFRqDTafSGHymcxWGxCOxCbTOVzIdyeby+fyBYJhCKkKLFOIJJIRRBpEmZITZPIFHrRWSlVrQCqI6rCMD1RrNARtDo9LqFXRdWADMAANXgOVUKUEHS8qTAQpJ8DETkoeIyDR8KUkpqcwuQmTADuVPh4SMkqhEzLAEk0xtIrFY6jDGGeyviWGJ9m0+TxiGtESl+Is1gapviEM2GrUxANlFR6S6Yly5C8qk53NtQiT5CG7sdgXdADOumAFLklCIPNJtC4PcmCVmIkp4mWHMhcghhAgq6xK9XswBaMCnLNgDCqOTl6BWrwKeDNtsO6Q6Jrd3v9x1D2Aj9TF02IuY6ZaynpNIx9AuwYEPwAQghNYEhLK8eCENsez7MABwcUolWTcg40iMBKVUMtMhPHNcP5Ho5A3ABpWJ4jUche1PHdKIUXCAyvTQUKMA8j1sBNaQCJwvC7EloEsEJ4CkZpmMxKJMJtcheQw3VXzkEkHAHYwuiUOBfR8fpBArKshIaLgIQAEU0n0pERFghAARgADk4qMLXFA1ux4FImKEAAKAA5UgfGgDQdCtIUyAkIUeiiUNWFgdwRG9YxVC7DxpMQUyVPgICAEoZIiQSolUXEhDgRBJyiBCFD0DUwHiBQgpyDcjJELI9B8jQ1CQhQJEwWAQIUYiQlycMuRMv0dyg19iskDAOjG6QegiZSKlgOAmNVYsOWzXy0RTDDJp8AdcowaBjCcBQGXCMSnRbaRmWgbRjG0AcJoUKbuz0YcrFUM0jpOk9yH0hR32WAAxCwNUW7pJO-QRAOWCE5iaOBoYiQg5gAKmWMBdkrSx0a46AIUIMAUbRgBVHR4DshQvCFHUeFYT7FzxpHUbAImwZ-HwABlMAsR6DskQQGYgQmwCodTDHFOi1OEx7+cRwWmdI101GgcDYDwdndQUWMzrgSjkCAsA1isRcMNIEQ3NkJ4GlgDLoAkFwEFrMAACknGvAAmAAGT3fvxoWFek5WU1VsAAbinwPOc1yBYJpmRakdwsjJhwSQW4yHwdSwsOYNhOF4fhABNyQB4P5hu44dgBH-qB+BkA8IqfAAeTDJQE+5uMoYhJ2k-C5vFyV5EhoNYL5VIYx5wDPxchfbQ-Hsr06IEJkm5b2MKtfERkHiOAfCLNQglSmGy4R32mYBih+ME4Tfw6M6XBJJRW7UNz-jFLhdGvvlZOIeJ7618g0ujoWlxNDGzcvqNQM0yyWmtNhbM-JESk3Jl4f0yByCaCFHcUQ-QZI5BxJraWf8AFM02BEL+bwLDVxxq+IQuDf7yE2tmPwnhCFo1IgoYwzQrSCB0JtSwQcsDfXcPYNyrD2EYE4UIViOlyB3B5IIZscBKxdAkF4O4lRYDEFqPI+AskAy8n-rLGOaNQ40lgHodg8YpIy2PmjAAmggZRFoSSkx-vgsAbk1j90RAJSsagkphyFA9fivRnjpWYWAeu4lGoyXIF1YEh8YYfjqvOMQ6l6qknYBESwkgegxB6EBduCgAASBo5DrXkEJOA0QOi6B4PfRAzZO4tCEIgSwHgUjRQUCkUgEhizRVECgQ6dFEQBj4o2BwGBtAYEEnRDQfjJK20wOhSK8FJDcJsJkIej1V6kyeC02AeCojKjXvCDCrtmivzWJWKICltChFaDYeCSiJi+GvkNDe5UFIaKwgaKwQdaixI-OrY6kM7gfgPp4cuYS5hWgkAAXmIBqVg0AcB3DuJOaAABjCgSguBYuQCCTpEo7iFI8gAdk2FqDgWplj12MOw8UQlpAGU8Fi8gShgQwqPozNG0LyBwoRbAJFKLVFPNILi2QoK7inDWAARQUBi1gTtUCvGhJwPgyxqa8MoByvlXK5Y8phfCxFyLUUAHdzVcBUpOAYeK7jSOzjCdVawnB9CUNanVEg9WGIJoagVQrUW-HUS68V+LXA6DEPa1VsJSDLGItk1oAQfBuUuBUQpLq0oeq9ULXl-LjXCsDcQYNtqw0RpVTnaNoKJg6DuJSLe0jdkU3ah4cI0A7gACUdgGV2JsLgyAlDLEKRfcMCFtCkBWppTNJdD7DFGEQdFrKlDs3iJYWYtL6U8EZWAZlmLsVgA3AAYRYOvWSmQMBAUgKMG4IwiC7lINwiQjACBjAmIVWMsxOZ1pnfjSAgh-DkFmADeAkgv1jHUaQbiSpoDMpHP+vAwwQNzvgBixYSU1jwHaM8VwsGoCDGvWMQ8dKeC0EfbO0DZAIPKGgLMFdeHv0b2Ei22YuwENjDiAximswABCLGiBPF9HwDjcGqAXvxle0jkB4jsM1ggWYkmWOQAStgPAT7v2nTQ1i5Q2wMCkFmFgrwlgjo5HFDNHjUBaDqfCKpLTOm4MAB5aAAD5MEGc6KIWpDRTOQFOrseILh4DWd0+VDeCh7ZuZM7RsYtAfMhYQNAALdnHMYV8wWfK7mFCedOoU8D5B4tQGzIpsLHmItEFoFlo8uXID2ac4p1L4XSNEFOgZRAegKvZmblEYzRX6tmaa3oOL2nZhVdNJgJWaXPNeA06pKEFAGB2Ym5Z6ADmqPFagMFvzcXlAWco9Nygg21uxYc3IWz83KNLc8+Rqs2xlDRfWzt2bUBbMXcWyIWz+2LSHc81F5LFpBuJf24uEThAxPfpsH1kj+NeNmFmFQbY3GVuQA008bpsx91UDbezTzSV7uQG2OzYT8OLQYpzrMTYax93ja-qPWYaxCmnABvj7rMB2gYqU1Abt7N2b112G2rngOIA3EvXhyAhFSCcY6N9KjynxMeFgKoWYRlkD8B1FWRk8n4hI+p7wulo0TDAwWrAJaQoVqMmnNoTQrBcJzJMJ9VaMTAfA9W4geIuwGhOHB2MJCehqf93kxixQWAJgYBJ8oVuzAIUUEJGrkoM21hcjJigVnkBTjR+tP+iLXmMlrGyyzwp6v5fGRSaZNJWgMnRHjbk1K8n53YqXcdVdhGGVMpZbutD5Bizya+awKgzxG0J1mIOoS4Yx1aX6LGc96fzCkFNTxAA6imA5XHWjtTjM2HCg1ERqAElbU30RepdmgHsnwUpJwRBPBqVQPF9ZrC18YHXc0QYG7Bu6LSjJmyMrUO1SpJ4ciHv8G6BSECh0pkEYoog8x4uG4mB+BoE0mQ6sg8swEcLkYAVW8mUB8esB8Ag8RMx0CgU+6WcGRMW+CgIgiBmgvu4QHgIWiep8lASCDA6eJ4pqlwCeCBZUIgHivo8mlIPQnGXucGnMWAIgA0tm5IZA5Aa4TQx0DmqBLqVqFQswbauo1q9uQuk4SUV07uRA-kGojGUuEOUApAK6cG9cxEnmEMMmcGawfo9BjORO8qQksw2wKQ5gZUnmTagg1OdoXQnm5YkUu2xhyABUu28O5YtQCBrsyiu0nmghawkUyg6hJ4AGN0euoMhQZhukCAzBmQswjSz+IgRYiAYA2UO4e+nmDo8ApqRMrAPcieWong4SS8i4b68OzAU+VRUYhUP2cGdR0ADRrAHRMY+CFOU+xE8AegbIJ++0nhYAaalAzQkUn6pGDuRAiwrAMeceMB8Amw5Af6mhoGFQcucGyeaxqesYvRxgQGD68OCAMwcGxER0uEhIXoKevcgYXMZx7CNYOAfOYAyxUAqx6x0BCezqGKLO0Aku+AjOMuhxUAAhoenxFULxggNh+hCmjw8uU4cJHxjoV49ojKegWY0USJlAgwSx6emx7MpAhUAMTuds3hehEOCmBxieWJPMnx2YagVEy+KJjJNx2O9xQyFU24n+84lUbxUY2JXxPxfxCO4Q7CUkseQJmQRkforOKm+xsuienGrQXQo8og1hzRUJ6JcG2x504oWYQgUo7g50uQFMRIDgtsxky+8JfMCgAA-NKenmgZsSqbUAJtsbsQyd+tCYngKY8duI6QWJ5nybMGGV6BGdYT4M6ZKQ0N8WSeJr4UHIoQAI5OBQS6h7G8bMmrqBF+EiCwQGjKDNDRnGlQAGTOjIC3Jlk+SeJVDaClQfIcTLLejmBBAVQUy7Rawnikmibp66gVCjHjHfxvpBkakwmQDEL3w+CzEeAYALE8nfo9CYrQ7kAElYxSiWAJBhgcnJSnL6ZHml7niOgDgQxv6nmE45w75cguEIAjlA7p6hGwCTkTFnH7pylQSUjNr4GQmokhnhFSCSzSArnzGJAA7w5bkYr54FgXTdgRGQU+BW6FpzFrmwVqADhrI7SOgFTxFsqvw6h0Q-iVKkyWC6kDCeniag4-k8yKFIL1xGEgW8nFlwbQU4V1qoUQUDgbljAIX95Wirnrl2h0LUJNDlQhYCWSB3gSAEUrLSDEXNxsrnrpnfoXHuCcIsV8YYpAWFlQBgVwYK5K4v7hDpHblmXOgTwpBCjYgNBsE+ChQmjZiDJfRuK2Y6WwCcIOY2waBPEnL3TTIB7yjegi56TagBRqC3I354gpGP7LSWWzT2CAERE+DhRgIOIKCaWjniZqYbEJ5LrvLGVMmamL6IKIisn7Tslp6M4iW2VVITjOgsALzikumXRyAPT8Krwi7P4q6nQKBkUNBtTNCVKRkiAQJigQreCFB3lxSiA3667zSpFG6pX5XvniZODVEJzOqugph8EcXBlcVQAeR6AgE1GtxATj6NWE795qBPUh5Dk+RpZuaVJtiF4IBpkFXfq7UDEWinDEF0hOCGUCblWmVQAACjFuDckY0YgghpqJTVUA2wwBd6gkrSklbYfgOM3gQgvCEQkEaoQQilDg5u9ECNnRD8QgG4x2SOj0DmW4DyXJZMhy5EO4KAWEGYTxMStmrwjNGATmjc-RiN8J18EQLUn+PEIgk8Wk5NxAuQegXYUo58ggOEb5-O6etaUGGR8Af5bCAFkNZ1kA2pNF8AepU1yNjJqNkA9Zy1SUKlDpiZW00sugBgByj8tmWKR0sATmNyHYXYPYegeyzQaU+sppX1fNvgZI01zotpQSpIJRPia8CAHpWlYwut+6Lght8pyAJtlVcG5ttFYAxETQYYNtm5D1zVmcNM5iMo6820HtGAXt7kPt4GxBAdHEKQnYPgIdYdGAEdYAUdzo5p9pVp8deQdpcVKdXYPQBYGdf1rGds6G3MC0XksA2BEwGKNgSghd85LNPglNG+8R1liFcGAMERxglYTkSBFkbsO+J9ugQYMQ4gggW12tDFYxTF+0wNSOgQ4NVls5RZRd51bBIk8gYlMFn68FNdUAHBReUlbtRgWF4luF+UGgUyt9C9C8mcNI2IBgRgZCo4mYRIr8hST1QguBHlmgq+a0VyO+DN-gTNdy24LgUD2FEl5AAtOskwDmQEtm5gDmQj5ATmHdQoGKMtsKAA5IxdOY9DIw5qjujgLVij0E5gANRbrPB4A6gSAtDIKoI9BcCiPiPqM+BSOJDQCyPyNVmKMOY0505UBqOJoOZ4BZbBSPJ7mIiB1ITgk0ixQ0gDTZg0KPSmPCPIEWNgBWPgm2M-0KMYBKO44uN3AWPuObidLImYjkLEGJAm4DT+Oy29BCSLgRNiP0XfoYpdAJy7AphEgH2J4XXoz1OVjn2zAppbTkCWA+JS3HoHIHQRHllcgKBnjOhE2RDXT9mZxOCejIF8NM1ggkAzbRBjFLO8NC1OYhP+g6BY1mxZ5yBtgTP8IE0+AiHyC6mwpLN+omp3DlGmqCBcAOq5x8BLPwQpiCFXOQD7BXgdCWBLMOYaI8N3CIABXRnMmbDKEmnWotPdMeGZ1ECUhwvkDmWlXyEgNQB20O0TMuZ0LwT8BIs9NdBCCRUUKDUhC+QngjUGwrVuX3766G54lDVpVCAupkwqiUw+CEs+J24It5a0AnGwBrDVPaIUxkCwBz7kAL4YsVXzmbBtAzZKxb5SRsY9DtPNXmhQLzg1AKup69DxomjcLHh4SliIjq0qvxpkWdjqDhqx2ODTXGQTPLLtRbK1zThrRYZvxeDNgBjegrTzimAog0Xth3Lr7TXzRuJpr8QODOl4grjWyf2-E63WM52wDA0EbsLIZWx53G0ytQ2QA5tSQxMuDqtQA2LgYxPVK4FCF0q7quAvJbzwSkKOA1P6zbBdh6AVuHgdsVumodD9j8AYocMVBL1A6C6jASaPQsGzmQB2OTHQD1zFjtTHXqmIvD51OsCL7QHja6SGWcZ5mbJTHdFCRhQoJoLYAtGuCsCoDtQs44TY6xHhS+Ay1I2PQ+GmwJz7vZIzlQBtqmxqBhNB7w5IQs67CuweCiizA3vWO2Bhw+GYEj71y5ORRGUBGVn+jIevtAeNWeBmCqDbAuCkBIcbp5Ood1lICtLOS+KEeAWeBYwR5WxYfRnMi7jwBpr73HvBBYSXAcsWjSZCVEAgfwBfuHtQcvvUKe1V1jAiu1P1MeH8GLJ1PdNtNwOqmzAAAbEMhgnm7QW8H6sAnGq9jCxB76iw-ZLLFgv4r9oYPAbhpAu92pEgsAzKXQQDwFOOlHL4OgmgygrUe081OnLr30awpqFQfuhsarl9Fd4Y3nvnLr-nKonmQ7Qru7ZHkA5d9dzMAnUAWKrAegaGqgbnsZNnHh8OUjSA5ABXSGaXAMgkUr2oSUa5F7jO4g7AUZcGqANMmk42oXsAfunMjUVY1OvXfubxg3VGfLkA-k37j00Hd7Vs5VGKeg5XInkxWoKYPA-bEJkA3ee5yBoO3dydBoXHXLjKGgKQG3-bdoEBqJ4roOnMpMD63FpsoOeAtmB3nmkmpA0wC0xlRAYg2iHHUAhSsFzQGi2XRAPeWA76DQGAarK2-3WGI2767xb7CPBhJ4pwCAaAggW2QPkAFkNrezYAGC+mhmpmKx2P0AqAuPSGlmv2TmmNrQxspPFP-xVPNPlXdPygBk4GuJswbktAbsaUbPTJF+DPYA5Afm-63WAuy9RAOVf5JQqpm9fwPAROZHq7UAOVIsYDkApByBOV0hZXIoqp+PV9UgN9wRjOR0O9lgP3swsNZ+yBXQfbbKAjnm2hrgCgHkjwcBDhcGvvjbpBlTYw1bavGvAmEJWvkAjB7RiNwez0IBgNrcIV40YVQkzQd1qJmxipBZlhrZOY5UH+XMtQWtSbkBZAm7ebptotKfv8nv9s4Q299n7FkAdf4t4L8n51kcyBjmXf5AD3FSjAcw3WRApwovpwE-6PSeU-k-WoovC-M-Wo0-Y-UAK-q-+hRAG-m-W-SeAAGqL4f91ssPDpSLQIsE4MgP7092ztsMRGsGAB5KcFqNDZG6DxgOD2ALQD7VaCqLAGByc5gtJuBUDwGpAxTR8oSptWIlSDUjWAzC7gRAFnitBgk-uTALDPnxOp7982cJMIuj0QyYoLAEUCGt0WpBCACiprIQLGz6RkADQSgQDnpB+Ly9GSeNQBpgK16nU9eqAUGrLTZ4EDqmNMNLj0V8QY1dmzPSSl8lIZPE0wPAgms2GXR2xPQzSC7hTGyZE9xBP0JgdtS36YtM+xYdgWv1Abzl-e1vHQfwKIFCCyB6g7GpgzkAf4EOJYBCLQN1AMCRqWg-nLL3hy4EoQOcanqDRZz49gafVJnjYOQaQRyorA7iMiVEDaAXWa5G7oyWebU9BAN2Cwg9iSFOYMEBdEAaPh5gu4Qs5VT3Ipm9ypJakjfGbvtDm6YCzaknIYvDke4LQqh+PRznBUZxe9dCWAqphQV8zUEZsdBUXnQTOKzBgaA5fjHULX6QAcIbuITKshaSEVpAzgpQDhC9yy9JuflLDJtwkC55iCkA0CqbW7yw9wEbVIdB6RaJkBTU2w7HD0XkB554cX8HoJcPfRBAV0k3K8PUGM6wAqh2GGPlijgDFc4ACQfepNz7ZmJSA6uXYYyRBFrFwRTGVpg1Vu4up+8w+egbUOw4o1CcFgkgevwaA6wl8hIDqtywsTjJtA1qZsErRVp4jrAO+KalyzhF6QzGZjXblSPe4JN7GwtHfMvg0gRBCRuuQogoE0C90VQQoLeEoEWpqBmG-DckV0DrrWANmLDdkYHU5EEi4RdrC7gYyMbnsEhVTGpkBRBJgloAqvTNlSGAZs56mKoF+kmRGx0VJu6uQ0ODQNBUBCOFgJKI01XRhgJAnYKTkQC-g7C0BBPfYBZH2CPBnghlCgGJxg4IgIgEopmi4DqRxg5R-DO1le1LwhMoxCzYWuKDhbSAeQCYpmtSO5quUGg2fPfoGLdj7ANMBoTtthnS53osIsY54HGFgSyREQ0Y4Wg2jEAzZYuSgXMeyKcHIjXBgjYRoyJpjIp5mmzJkfR0OTPAexTmBoYiH5DIAIMxY1EoGIADMQYgVkqCQrzhxR6Y5msRGIibAZx0oWpKoDXCF4JA+sXgoYBMBhxG6cYmkAxFKbsRk6-IjCJoCGjPAk68AcpiI2EYiwhUMxbpDkFbGONac9OY8X43E54g7x9YkbF0B9ZRBeyWMUCW2kgkcR-ArxQiOXw8HMDZSEwIbjKxUgKFew0RLoB5jgw8dbS6WeoavS4xBhPMjUKQFPg6auwdOVoSDvwV9CIAkuoddzvuj4meZTUX8NIZAGKTyF4cR0LFAROqFBCPKHzZrqiV+a716JiAFSSANVR1EKi3fGPjgMwCeZq4EUY6jt1kBJdQwegScijnMll0xi0pcdv9yr7x9OiEIrQqU3KoJBsixdZ8U2C3QQoLA2hHlmAAABkwsI6O-nhG20MRggrEWJI-5f8f+Q7HYlbEAH+0wAgAJMJv+tmRgilOkKTdgsOkxnB5MTxExYAD4iKdXUIHRSTRsUtSJ-0RAJS-+yU8Dk5gyk-9spzU0PoJ38D6iz47k6dlAHuIahYwzYP9k0S2QhSYBkENHvdUqnEDqpIPWqfFN-5JTiCOU9KZlPalADOpUAdoOrh-Yx8ipTGKwOLCiAhS6mkhNEZFNmlpcFpq5JaYlP-5rTWpWUiojlLslf0tCB7ednsUgCFodA5Vb8FR2rEmDmOLfFSXBkVHBgsqYYNwghwkB3ZkuswTWC5G2lTc3JMrHoKYHA5+jDpQmHvB2MoBdjReCFTEdVO7xGhBWBNawYuDJHAT0IdSHfEU0CZhwcJvxPKeRG+H3UsZTnHGf1MgAlSypxMqKXNPc7QcAmQgYfJGOwgCBTypgVCJJEUjSiHkLgVmX8SIB+4ncCQfnhiyIC4yoAAshsY-B6i6h4AIvGfiTKqmizxOz4Z6tLPCkmAFJO+S2Ow01DERqkMQXEr0W9Bb4TGWguXtoLGCGZBAUYTukoB+bozOhug7mfdg4FQA9ZO3MKVICFnXSYpnMaCEnGQk7RE5S1QOu2MpldgQhxsIORJ1bq0InxTnR5n7OuIbpyAbsXmZ5KgCOiTwKIA3nP3NnCy0uacnXJnPgjZyXxisimYqwLliDQhxclum3XQhzjNBqwvCWIBkoA4MZltZwDzJ1lxy+ZJUwSCkG+jJyBBIspjOBz+A25GQm6DcB4mJaOAnORRTAsQUbqSzVZJvEoGpJjkTD45seRWI2m0BuRig7QVpGbImEWy95lhIMPlBQBr562U852v0Hvm2ERQT8tcPEHHT1zE8b8nCLbE-nfy9kf8nQcLg7kxSrCmgEBe-Pxa6BvJkCjUKrMm7JcF5kcnBdHKQWxl7YpXf+bguqmDTjYhc2wM8HxbDocSDxdCGIBcqssRACCVBklAcq6QfoY4+UQ5nEm9E2w3CffLwkvBS8HkM1XCHEAdjyJGGgdNmriFfCcgQ8+rB2DLLii9ELwxyIMMaC8BnoZxVcxnLmUKj0K7ijC9yAABY1w1MaAFgr34AK0ubCzECPONgIRXFNSMplIv4ayLzoCinyEotJqqKOS6iiUKM1EDaKOIuiowBAiVBdgNFJ5UxShVwaWKfIZMQRoLWkV+zJumEluADKXnYzV5sfPmaNKYXYLfFMUxpRLMCWJwcgmcQwgUGbAABOD2DRBprQLUSoJU1E4t-b-t3IuwU2NEAmDjhvF6IlOdVLaXUysgsy7peOH6WDKU+IyxkrFAmWQBRpCcNxNZA9iLKrpu8tLsctiyiBVUvRfQGADOWjRyJ0AChbPMii70Cp6IuhXUtfmRRcS5Uy5aTPc6TSlqIirKh0skWRKhQwVCZiTQKi4kRAnWGsPtGbDmKpRPkAFRfhtnpyDFS5d5QHMRZEZvlkU35ZHN1l8yaS8sjeMECaU+KWF7nHzHSqED1s5ZaEA-EQroEOBfmqoX2TPKJU7TNZ1CmPpjOXnPzsF8c86fSqWVXKYp0q8gbpDWVtln8A5LsJVF6rYIHZ8s2aFwvlpVhRSdEXqnss3J88YSsc+pQ3MgAKq3EvPHQI9wuUVS5V1Um1ZIOVWqicRlsczpqv5DsqPKeq-1nPCnbhM7FqJBxUDwtVSqkoj8AGPmV6qCBHVwlRlQBgUmRid4hNC7nUhvkDQOFx6HIHxC3yXxRI08-QmrNWxQQ-0BgyVXzIVU7yQVsIpam6tzUeq1VQan1bJD9W6rCi+qxthqsmiEqPpoGL8cQGqXkrI1fMy5MeQkC8IAmday2dDk2iLBZlHC4kFwqtydYJZUQdJeAh-Ehx7AfiWuCavwxI9oefyvmbVWgA6BDCy2Zhcsvc64CJZxYWKL2EgYrqfWYYSBREAdDgkqkunCUK7OqQk1kJyKjQBsgmDIBkyWyBSJLNihlQB1Ffb9KF3pI0KxVtSilWvKtXEJg5l1GfPmTnWAK0azE6fGAE7bOh62eclZl4QwB6B4NMpQqCoICGfBup9kMMYvLHUvy+Zf5AiZk16QyrgV86uDNsFBLoYFojgGJt0nsD2BnmjgZQP2V6RezrRpayblRr0A-AvCgiTmeiKaDt4zKegvjbxlICXB1NCALDahGMk0F0i7G6tZhu+jUawARmgRFhnw1pcHNhoW5Spo9riaKYV-FeEkNo3p4kNHwapqQHBJDC2N4qw5bhq7AeJ55+mpNXeu9wyVeihRDzYFv7LkbTUYqUNYyV5BxhIt+ZdGMHLi3mCBNbOIrb0VgCZaF42GsAIFq9nEF+Ap0WjfZPQEUA9AihN3qpB+mu8UwYcqhYIH2BKh9guyZgK6OcXlR64UK0tvbWdAn1yy-QUMOEqZoGYUsx4jcBAhW3sKoVq8NlVwtAnJjna-kOiMeKcBcgNEj0eUANEqUchBxYjMxlGyxjaBLADocqG5X5BY4UlU6sUVWCW3C0skS1XBtYodlwA1te69OchR5AfizIm0L6n1DKAwdklZSbdc0kvm40XF-VIsajJ61sp9glSkVVAL15tKvRugmyukM2ZtL5qx48yC-QjahVDhP4fWEZAiCYSqZK6rVZsoKBgABlQy5UOXxlLY6w5u04gqSs4HzlzpxOnBaTsqx7iFVDQKnZtHCGKUpk9O+UBuEoY3yOGfqyRDxDcRq1QFXLYBE1EObOhsGH8HICuoygBhWQHM45HAh2bE9vQEkc0YHQkivhbtf4sRqgDWAeNv150WwApKmmiiYhJyXBtmFAmK5Ag5xewH6sD3wBjx3oTeIOXwSJt+dFRXrfsA3i0ARdc5aggpNpU8RptoE6lVgHz2U7SliY6nYrpUrK7pYP4PdGXTIjfRiFWu9CKBN5U5BhR+uhQMeIIhjVegqIzHRUrT046CoXyzTZxT14oKcRQYOLZLovp1lxmVbW5EGH6REKC1F8NmDAjN2-alsXetBWXr3FXj2aba7aOoqaD5Qgw5UTlThEQnyBfdoevkGciQnn7Xwz7CMSIG5WdZHY6arJdRCNw4lHQ+2x0HLvL1M0KGvup4s2EgjkDla6qo1ZNB31MySwks48ZWVxHerJoKej8sPrDlzz5o2eowb0LZQSK7gU+j+bPqxawID5nlVaMAVAl3wJFIBvcWEPnnV6M+de2qNmHhUqKLQztQhnooURJSHZY4e0tyu0D0HsUSqgMGgtX1r4V1x4hCEE3ij4zBWXY93WYyx04HhtDxAPjQvzZNzGUhevcQYdMjd7QD7Iyvawbp217VdW6RfafjugqGh5kKvZrvFcwUbCZpChiAPu30zQsDGZLQ3joG1jKxtbODZfMs50s7W402h2tTspo7iv1l3bNWkFAlRGD9mzevUzpUruEJEH7W3CbBEAc6ixYOnlUQ0LHJLB4UQNI+aIDD7bdyVImRlQBkY75jujpGSMxLkAXdnRwuk8DOP8PfoBdGejmeWJYDxA8OapAnfOWNlCgDZ8EmI21U2hzad9PsnwHBMbFmHD9W6NaGDCECgSYMb1XCOWDYjAtmDCEX-feMNn74SRRQapNJEtoXFPO+RRjo3Ul4Whjj-RsYIMeLkhzDM4cpzsNprn7A65NfPXiYekCtzd+Tq+XAsfSTO9swpUd0EkaEIpG9xflZuTWFB1ZHqdoE1FV2CVmYFakPQGcbfqObVIro2IF1iFHmSFrN9aJ9-LhH5EfHIeWhvAylnLGwLDKoRmsY-NaRZdN5C+OBlLtiOLG4a9URI90eRM76XA-J9I9IsyPZhtMfYTaPWz7WuJpDwC1-dfvyzAG8qmhzreWJcX7Bw1XJ9xZ4rLr2wJdWLGEyXjhPinNuyR5Yy4qYMZHODEQdqOnMORSHttYpb0PQYK0QwTjGRuajNAUjRL8WTJqAIMaF2Lh9gSgM1RMb2F687Vj3FphdPmPIMlj2YLo-aclPh7o1KoTEx5SOiNjbBiJ8auJHzP0MZBIW2eOfP22NbttWDU-cSeFDebeQAHFMFyO1VGBgzDQBSK4AjOQAozwqgbcaZBPzlY1XQeNT9vF3TTZV0JjM6KY6rZn+2JoPM2HA2MumtjbpmHUnFd3prXw0gHNR0o6STgPQ9QJzoOcGNkJke45lkqj32hgB92dKCg-Axm2LnbTiJiU2ub3HQA4drQBHYWZ3MenOqLhjQSAU-Utgf1OEOHpXiH36nlI2iT3FyaBieAfcgp+fe+czh-I14jO2bUufoMWALxJsSPX0a2PIUdkKte1jAlwhqA3xSkISEVB3BeFkS+sNyEDAJLRQsw9DElnRGqgnI-OHUacPS3WpMsbtIveC+nreFr0YRd5+iZoDfo1z0zEzN8aBMUuPicoiwINceIDMmhea44PCPrH0aGN1AZ7IUG5E8Y5BKoPgFRuzHkQkiuFC4iDGlGbBPA9uUzGRvumaOB11L89MvgyOEalVCxHSKWrsb3HBUOiYAls22EbKcRI9NINvdZ3EBrLAzcpwOrdEl5oJnaC9Ni3VHOhn4r2gYBwQgDSh86GCpAXHTga5NB95wyMsghhe3H91I4iICaDriHIkKJA1E4aZlG7AWh5wpu3C8gSHGRMvdeAfdsQaFKs0tOGSqcPyMFFP59LWMWqGRpVBoRQJcyHS2Bexq4RjwgTDiKBOfqlRCKj0Po6jNwKVWEL5E5C3JcD59WmrKMhq5RMwyuwCat1MHb4QaA8XzO-F6Wh0G5LCWkqjLQajdvekIamAuQo9lgNlaJ502SevLeng15kwGOLksYCc2eC39IArm9G55iiHkB-6ggUwCzlmBEwdd+N8gITcUmMl6NHQAIY4SUAMaCyk3FaAJjFxKAsAKNxDCkGJuPg3oEugqL8DfZHEWcJ4OghUkpvfpWBUHUGl9FRnTdgoTWUSdeMELIF3Aa4Gosb3EztRHuHNqAHmWFbRq-R+bHjjiL44Rt+ISUHie3IS0mlDF+UWAIojFtphsQPB1CLx2VjzRX4xt1Qe7f-AoUU4B+K-Uou8APLEg0Q4-FOAaDg9ei2VXIO7cehVn9FjxUYVLD6pwAKRH8R6BAggTm2w4mgmfpimjU63v0h4cxPsGgCYQMb+jJizJS6xmCmAFd0zg7D4GRmyYrsFMLMHW7lnm74wBSdTic34CoAhaU9VABTQPQwBLwnQf7OYH-dgtUgGfBoiEhoYKYFQZyBUBXYTD82NBQQ0oi8C9Fjw4oNpP+uc0xTFy58osFJpxEr26wBqxRO1cfjEJjFi4rwMQBCAvX6op5XZLvXaBKBSrAwy+4fdMRoD-uu1AbbbBYnHsh4UQWPNjW7tgPxllhQ-N3anNt3qxndn8N3dMB-C4MbaRIK0lgcgPyA+wTB1cMYvygcH-EBgGvynuCq12JSK2B4kB6G3Ta2paAmLd6IsBFpeA29c6vc6n3CwXSCRLg+EXxphFCHDlUnH5F8hANLt95qAM4R0V877AXUEXfwwEOy7EweB9iMgcGxD8+pFiQPZgAaPqciDgx8g-dMd2-r1ZAx8Q4UJCP8HpdmxxA6YvkO8HBj4MdXCEiqbHHUAeVriJrhgAXHlDye54MZxxDTtw9i1fmzPkKXj71Uvh0iFQQ2BNQ6NLCJLNFsOIEQ1CWpA2IqjKRCi5xzOQXJZDVJ5rMoIApEW6BZ9st2lNCiKwonobobAGNCsqwLpW2eHSFE5B0FJiBsRAtyTxGG1XjlPzW8kewKTEqSLi692VOGV4FfgCk2DKuqIDFEBtP5jc4QI9f91DnQAwOCACNRvegE0VnQA0CQHoGVCxP3OkSsOr0nkQHPlBF8rCMc8xkPGym1TrOtxHV7bOq12A-Z1LxNBgdx6Zz-vL7sufIlrnUvW534jPKEh1nJlDRA3MifQD+42PS29w-rUQOOsiL6uIUVAR9YSeGETGL-Zn7qIPHKjudPUyYyYxu7P4BFO+jBxUOQnqJXUuWGIA4O0h8LyfZfzihnF0YH4gF9xXv3WnswFkVxa4uIAcBlqdXZAG-kMVXVl4bJaUWgezBAtg95ii8Waw5fB3okwoJKbyalDkjHxjRLDgdHlcm3JFSSG48zt1C42fAAML3aZZNaoB90Jyfs1OeheQAkoIIrZwfKE5MOuB1spQ+Lf40EaxJQLzziC7uf96bx5ipxNeDVFrkFwv18WSvEqgIQ2wz5XcsbAXqvwzXKlaAF0dnrVQfATjenL1aFDmJKQVLRTRDjLVeYXz5AS4So8afcV1cwUvoh6OiNtPUXUAeuMbunpJ0bhN8gMNlU9FbJUFZpTxJIuvyv2lq5JvBs+JlkePhdJLOJcHLdv8dEQyboiuwHFDsIHkdVnfA0HwZdhigbob0O2qMytlXXDQcY03OblrAkWgqW9gma+eT773PgME8VpJ3tPA+BCxwKG8oDNgkDK8AaHSdPLmLyQbgceyYDq64QjovYSsnXF0A+ccU5F+cO6Z1wzuGZ6p+ulnPRNyJ0IMGzqwh5A-gqX9xgaD2XxedEAHQrdbrnUvzZ1EaPGoXl2jT-dqBqPBV0sANZfuVgqWR+eKhK9gSYwNL8EMUMYsTJdhYhFoH8ZR6gDge0CZNtUT6-nIEdXAkG-aLaLbx+JmPkAJ2IeGNjn2JZo8FsqklAvJaaOsAywFm-sOTNrjwLvyyICGcOwioWoxkhp7VEkuMeHwN7LMEJ6pCIeoGTLUMZixdEoAj9Pzx+6IDsIDQQX9bLMAACs6MZLK0LrtokFAMX2LD58GXhegVoFB5sQVU1vZtunsRLzFmS9mDhcuHXEvjyMh2egnW-ah4Oq6GPy92X02MMDTsBKfQysC3k9eIGZfcpI+TKyh29K2QAaCMQVPP2R5CDeKYV6ulSy3Hm0IxDb8LsN+sLGBEyw1UV+JsGShmLqQvRUJhaBopUcHEk8g1mx4hSuv0U4x1Nr6QQCSsBmnX-PHZ7UBsLSDrtbYPTZTCOkcv8Wr9+R2e-NJPvOkZRGoUDxrQNAx7zhdXG7A-ujmLi14OJ81djUnlHsQZQwJLVVuCcWs1QFxooCGdv4lDCQOYke+X0A9khHIDMsj3aftgrHixOrSLWDVWkytUsGh7cqquBnGgNsP7vlmB7XXeOlm3oFW77S9nhOqZV6zDv8GBmpidgNp+KQAdUR8EMxNvG4j2lrtx81qh9WEUqLDVZ52pBec1DZuJmpT6SMUBThmBSmd++om2BHjzhWjS1MDRoEA9bIBo6+xlJA3R-NbB1s7Vkd9Jnb5seK3DDvHnhmGASHtPKng2AFsvNgi3VAGTTkBSaM6fAvwEC-67f2JueYEzsHrUErnYGkE35RJttw8hoVdoMxaBrxTK-qyE42mXckP2UTlU0bLowTe6N+QchPuU7K1YgyuKFSuQzQY0e5w8g9+4wEuoTve3DHp-LpdGaxlV05NouWms6+oa155hcZURvRMCCmB+SBc1JC7gAQEDV5aQx-PELl+jUXAJA2k8LPCZSErpL+ZWGmfOovgtpU56haktvnHAIqeZL-Myg0FUQAzHOJtMMs-mwCf+8AG2hg82OKHBsEMxLAYBuiLIAHD4vPKajuc4AeVC+8+9AAGsAQAerBU4UXBAHkUuIu-6wBBoDSSfoXktAQBOuDt4BJcjHOQAbsR0qpAl+nGOqCVA+AawAAAWqQCyAwNLMBsBQVHRDMB3AcgD1wJbHBj8BjdElw6i8AEpwNMCnFECSBKnIzhTCjcA0DTY1fF27U0gxPDbyBruIoGQgKHNtwwCYAh4DwC1xCxyqA7HB3Zig3HKu7zQzHIYCqANrmsDteNmNiIncIcLa4BgPQP5CLObCBkDTeBkgKwx4dTmKymwJOLqz6eSqkazg+dgsI7BQ0AVAANCO5IPKEySHuNilA+BtWIby18rPrfG-gL8bxBQmNnLv+HMtzaCyZXC4oMKKWO+woc3fEcpTK42J8pSBCDNiqz6metUHF61cMdKz60ZtUG1q1xMOrU4fUOwDTqMHJUEJw89nzBzcP7DUEV+nxh+wIAwNOOiU+e-tWLH+ggKf7OQeAKsqK4hRhEbZgvZjRK2Ey3KoBC+j0OtwSm23PE6nBOZrPq3+AFHUzgkt3lqQ6kltCIB3Bu9gaRzmLArhT6chnO8Lr0pnHIBikJIJZy9ASVrZxlchwcJyL+kNguTSuvXg3wAB4JNP5CsZZEiJeM7gVwqB0QRDJgIh0AEiFIhKUjTDzkxlreKPiZls0FT+qXH+R5cxXO-RCA3bsYyxBkwhSGFcsAKmzlBdQCID0h57Jv7zcxBNujjGKnkRzIcffk95-ujgOZ6QeDHIu7D+j7gSGcSUADQQk03oE777QEetxA8h8APMEj4wwlkwTe4HrRzRsHhrABdi6gJhztuoTq3wtCLnNVwn22PiUyXyrUNvItEI3MQDWhbnJSS70EXInjQcbUMfrkAY1hAGdYOnF1ztcUAJ1xtc2IZoEhY+6BMBeAKOLGE+A+Qm7jOhYXMQADc+-pYQuhY3Pv7w41NvYSC6zGuCSsaUALj5CAWoangGStmqpoN+TmjbY1aWNhppCSeGnWFmaYAFFrYASxC1puuV6kIFQ2+bN25p0xnkXjyYV6koDGS2bqq7F45uFwbl4iaOhCvQ+DLmaFExAJczXMeaAGgVAf0iGiqId6BGhvMfhJ8xLMPzC6z-MkAA5hUAd6Jtyr+xnPGIgsTmG5AL0O4h-BD0v4mYwQgMKgnQz0ydHEB1I8iFjRYwHDOcwrhltF8y2YBaC6iSElgA5j7hCkrABfMx4X8wAszzNGh2s4EToAC0oLK+HCMoEIXwXgWEMFSCi68E-qN0bWL4z9soPEoAPI26Auir6gyM7xS8ygMiqF87yCIDLWugLFQtgWYvKAk0-IFKBARq4ZVjV4bKJBHQRkAO8zyycEUeG8qp4Q5jURu6DxD6CZhqCzqG2EQoDswJzgTIb4VAlaJrmy4QJE3MwqL5CGYUjOBg4otqBGFaQV-JnzcQMERJHwR0kQCw08YYMeAYRTmGrrVIFEJoBYRYjBCBxw+pPbDyInrJFBUiCEMFgkKjbJWRRiekSBFrhgqLcxoR24ZrDYW0AGraIAxABIC2Rh4d8wORZ4RHDJRrkfXolSWZgQrJgoYhYD8A+QMbB4R8ZPErIUk4XiyzUdaJW4O4COP7hCQzID9L5sp9mcSkIGwvAJdhIuD9K+UnCDrZDmfVhHiPQWRCF6Y20yOFCMBlohKRskfMD94SYLxLGBTR23McRDynVCmQrRp0FNFos2ONqTVU5NNmBqevMF36jK3EBSA8AHAPAD5+bIttw0E5xgH4YMfgYKyxgYuHGEmkoQYWDhBodhEBlIbGB2GzyENpvROEtJOMbDC24NYbhUiznJBpO6vm+QC4NwEAA")); })() /***/ }), /***/ "./src/js/built-temp/base-pl.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-pl.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYsfhnKIwrUgBt4GRACtAoIABjUQDtRAIwCuAE1IB3RCp6awAM0TryATwDWPMIk2DkiWFY6aFi+LIF6KHPBG8GD2gEKASoHBYIFg0KTq8mCKFIgcYOqI5NocPD5xNqTIrBI8hQYqVorEYDbQHLCIYbAAz3pgamAurHkANLWtIh15XaKFgCKAylyQveCEkBKkKhg09IyQANo8yBgAusAAylQAogCCALIA+qeoqJcAkuenAOLHAL4A9HSwItAfcBR4JdWJggRgeKYuODTBsPts9gAdFTMNicXj8QRgYSifhaXR6EbmSy2fo2QaiRzOVzuTwhWD+chREb2ViM+D0rIcQwjFIidKZbK5fIcMKkQA+gEsqjU6g0mq12p1gtAJoomSFxATAJiAMrkSny0B4mtGPXgXDAqH4ujgWVVQWMYD0VhcMkq1Vq9UazTaGU1OTy9TEpDgmo1iEA4IAOrFs0JgUjadSLcpWAwRzRSVj1O2IfoWKxiRlWaAm+pWCNE6w2TVcJEAdT5MRCeg45CDCGQMTYpB+gXU+m5qjGHrlVn66l9QoDyE0Bqaga1MtLcX8CjMFgrmpz6jzXKLpEKPAj4lYVlgYAAtGAAHIjLniZA8NS+WTwbRqGyxjvxTLVUfj-3pKcZzCMAWw4AkVHkCMDSNToNnUXZhngZVSEmDglnyboRlhDJdgAQlrGxyBaWBvB9P0kIA6ceFne8KPDWpJAoPN7BcRYU2Ge93VlZo8wvC0IlVT8EjzQpFiI9pbXIfwVGkUh+iFRYZIwfh7GCdR-TsWTNzzTQOELGx6KIsUZIYsTmMDVi+wjGVPTcbTP3EfdD1IY9YGrFQqFEbFY1MeByFpMAAEYAA5A1yIpvVZUhhCQ5NXRqAAKMkWnIdV9AfSoMkXLlZE1BB80CdICXgKQsTjXIVFwgBKfpTlKxQeHkDBSt0bQUA6fQ6VSwBtQAa88wBrPJSufOAOxKQw+3i-CVAALUQGxNFYKM8za58wCtWAQ3W-hoBQcqhpk3w9D86BZB4UlyVGba2tgcoQlMTQVBsRRnxzAR5rFEINq23QOv8WNWUQFIKilMxHues73Lg3YDj28iJBMrkpDcWF4KRDZSjgXYkUIMANgAKgQqhrHUZI8mQSoccIAmEOveBopEIxVXQsRwbcARfisKmIBpq88gZ7lmc6UpVUyMaeF2+KsTychubxwmwAAETjVw7rAadGmKoxEDl3ma0I4jvDwVlAn8bRzKCPzwUQXClfkT7ol+hL0mETR1HqRAqoYyZRFKVhlDAAAmAAGEOQPc3G9YNkj4DwQbNW8XxxHC5A2l1hWLTAxAJFETi2qkXxQIJWR6JRdhuD4MBABNyQB4P-Rj5MdgbGVGh1AC3qMIQnm2BNGznguRe+BUeb04yV70oPFyqMjQFHJ+FVTUARja0RHbaCCtisJ6O78f+6BtaTasR8KbyXwUgEKxyPGaaMYlpv04QgAlFpjJCbpzMdLPtbABKVFYM1zhsG3BveohQ2r3iqg-c0ukOClQSsrFegkxTyDaplGycoYixmxEzNClR2wJA9qldsHwGzWmOu2PER8bBtEgSoSOCtiZWFJkSNMWRKj9HaMlawFCdBUPsIUD0nh5BQIANJLFMDwDAmgWwGARnmLAMkRCCHIMaH+YiVASKkf5QupAOD3iyGAEhGBF6CG6hGHcCQTAkPQc0TQ8lqLkBUCpB0hpE60PoQhZWN01ZuGPFxWyac6HUwVgAVXTJmb+jpVpON6vYBK3k-RNFELITQYpkhNE0u2XQlhAjVSgfcFxJVGyuJ8DfBud9m7Q08lGZJSFTwuSCHEUg0jvC4WHkiERiAxTmy6OKEI69D4CT0mGfoI02wODJHFG8iBDAyAlCDSMu5O6qhiRGewK92oDLZLINkEY9AljgJpOImgsBwGZA6XIkFAzaHVgYYxAMHwjEaMgfoGByICH4MgcUpRjpmjmsnR8cRDSYK+SuRoCYeCKCSD8Eqix7JoW-MMsQ8AwgQWNEabQLZlJ6HkDfeCAAZB8dh2kt0bs3DxeNpESAALzEFgLADMOAPgfG0BLXk2guApGQHCFQAA3HgCAPgAAlLwAHZjgADUOASt2AAeQkS9bOnRFZsooNoWEVLyXBIQhsKltL6WMuZTCiQixOVFA+OoD49wDgAEUVCKFYAAKVQP8Fg5c+C7EfqQRA2hugavIBILVPMFa6oDfqhl0AmUfD0DGrgqVtCsrclyj45BXWonCjDN28bE3+sDVA0NNK6URqjeCWAxA3Zmu5YId2rI03l3RLsMRNzABegERbQopHQ-2eAKoVbsqq5qDfLHVeqi2Go+KW8t6hK0fGrUWVNZc0R8AtYsS1Lg4B+RnYzaAOdYB8GRB8R+ZxFbnGOFwZA2hdgWlTmk9osAwiaBcLaIwmgB31zJTMOYRBWXQHZYSp66x5WQpLgjUQKqf1qv6haUCLgCRyAbF0CCuFIBzDeLMIgzUEjZ0YAQeYiwfUPgwOsQAgoA+smnkD9uNIB+RbOQdYNZCywHkD0YC6gIjaAo-MMtzTJbaGgCq-l2g-LrCgGh+YgmGqsQOPAEESiKDrGmKJog0BNCmAkbQbDn7ONkGnIYXj6w3DQA45R+8Jq92GbwJAZACMjPzHUqZpY5moBWfY4pzj5AeD2eROsBMKhkO41Q5pyAD4JFGAQOsQAeEQ2cgLu5A2A8A4co+hKTKQVDaFOMpdY0B4ALVS0aNsmgbNEFoMlpYvH0ukHWAAHloAAPjiNlx6Nz8uFagOhc4D4nDwHK+se8KgnB5fgFOFrkBaDtb6wgaA3WLPVbq71pwAhBsFdc0QdCQrmnkCm1AZSfoVADaG8tqAtA1vSMmxl6btWyo7YW-tzTK2ZKK0QFYTbkAr7XaW7dw7D3CzPZm+tIwb3htZZS7xg4ZBKBVaB6V6ANXDMHcsx1ibpxUsldS9AUHFAGDTbmxNmrvWwCVch6jmHw3tPkEm6lsbnW0dg8x1ASrpPofbfSJV7HSFccPmG6NhHSEqsXex35wgAXKM2HgIWDTuMiDgvWFQU4AAhYbKWfiSHWAAYSoI-fFw3s608gKcfFVBhtIWUOwdYxwDgq8B8QCEOuDhCvuAAMQN3DosQM4tQAOKgU4KvHWnAFxAN4KHRMvcG6QWXhhFGOYS1AXdsApB0ZOiXdaIeosPiV+sERi1kWoqSMdMnU9hAjiyrGeMiYrIuITvkB6T0Xo8CQ4HuYlnEAPnOEEAr8XAvjSsOsL1HBxArJ4LIKLiuOtu8gOotwfXPBRZknoZ4KBR+Xj7DUofLBlglWiusRWQoVBGHfDNfRvnXNBeKBj2GvLpDz-WPcE-lAp9H4aSoA463vBCtT+sZ4Qx0hdgMJQJ0DFBPtitotDtr6BOhIZH7fq-pEoAYKrAaZRZZSR+RKyqrZDgGBbEAlSsDEyGDbquCj5XovyRh3oPpAxMiaBoGUaWD6AIE1hsIEbrBtyBCAwewvIOClSNA1K9KfTrS5BJJ7KSBOKRhUDLj5AmzSASAoI2jwC2wZ5LTsDZ4OgJ5GgF5gASBuyBjqR+TpBiHNSSHkCVjJDEAtixYKaBa7Tn4yCxb4rwDn4SAMG6J8DtgzZRbmEX5WE2ElQhJPROJ6C+YWZ0wcBqCZTJyOFRYuCCay5d4WYf6iCOiFBBGiBiHM6Uhg5nilBPQ1YuFZoviJrd45ECoC5C5QCsrZzRSR6BZaD0oObi4S6QB7gAYiLDaCbIyj4hLKbjAK6GDeB2EWZI5ph34fYLB4G0YWaoAtDNrBCD5w6pQrw66Px1JZAMDTFITsh5FZZLGDFYCwAHCNCpalEyTp6Z7CCahNFFIIBz6xZ0bkz9DnwtjqQnFw78rwB6AhKsA3Sj4zSYaCQ7x9wDy5SW76CvHYiCaOaQAWgGRpJpjSYRLUQAl6AiKi7qSpYEagngldJgAiI5wEj1CMTggnGaZFFEDbDiCUBn5uHwDHDkA0Y1GUYx5x4Way5sahA36CAVCwlw4IBrD+EjA6BNA7TApcjEkY5l70ikDPjKTizKbLQ4B+5gCElQBCmkmIAWHz4HCaCKDeDQDlES7R4Cr0lQDX4kmni3gSzvY6nRbfDS7LheSf6thJIdiKmsmGCJFFBWDdQIx5DTAElH6WHwD4reraD25N5qGpQ0mcZ6mj6MkoIOiqgnjJj9jDack650zqxtSihApGh6CxmNARiinin8AmlSkF4ynemBYpYSLkDIBkm+mKxnFu5R6S4Rn2H0gyzaDNrqzKZsnYAcmWkWaOp1LwDdTIpaz9DcHVCanpDTiPRXKFkAD8sp8pMAyp5JtZyMe6lJ1J7e5pdJkZTJU5bJiAiZvZUAKZvJ6Z68U5EE5ibAppJZ-mR+MxjQlA8xAAjpoDwPGmGY2bHqPvRs6IYHmI+YsUeVyVADEQ6E6JgC6T4UpPwNIuqWQLRJEskCVCYDuIIPEAeX9KDBrIgMVOMF6feYFi+AKgiUwg+KyssF+bqT+esPvnkOMLUFiRLGhIsHiacT+usJeEDDwN1EYL4DYMxQGIkG2QVFUBLO+MgIWHpBdClHmOORRGJT0LtBGGoaTFmbxfxWAMcD+qiPZIYGmFZIRYLg+SsbAGRUiZRRgNACruIh+S4LuksNRdFk2RZjNDMeyJ4ExXhSxbiYaBxYoNLhSBDKIM2GZQFPsnpIcjyWQnkN-IJT5TiWxTwPYL9LoFJe6VLD-qYg1GaG3EGBwEaOIC2X5H6GGMZf7kfiLuRcicsNAPMesbKjYM5TuWseyBiUJaxdFClQFenp1X5aFXaVvGJXoERClqIL9LhfhdtBlXItUHXkRZRr5K4NIvAA1T8JCo5X4fgIMa1RZjWAnqBsnnDiCYFaMURFoCNOkMhO3DmZggiJAJVstT3KlDVg9bJdYIhGAGMttMGKwJlO0LnqdKlSHmaD3gYGklyAtEtCodoDnFnv9roN1LBtoLaNfAuffjJNWfPoSveLTg2TRfqZALjQKmAP8hLN6B-l3idUbnRooXniDV8lwYpeIDOG1HslYEMtEM+IJnQoWctHlS2PUEaFOYxQkPAIoJlGpR2NDQjTnkoctAtSZYFotO8WqcgC4NYC1a5SeUvj8RPPvDbL1RZoStaDEAfsXmAMIWKfkHabAJMSBLogXnoHYHecrZRotMCUhPcCoErtoOqVtdrbRRZmEtCUyIeTTZxftQcrdCMDYnZAMClOqC2P7QtFdf0F8hgEkGhNaKmGKCeF9HBeEoEIxReATkrssDVimUYPUIJCvKDOWLYLhJVv8BXRgHVnNDYFvNoAZGAA9aHRmOHQ9b9ZtP9bUqNO0IDI6O2BgClHgo7VIhVXKUfmunxnWbZRovZUHUTRaCVdkO2W0ZoF2cbVAIfQYAGLuOQEkB5qQGYqMCWHQglJVikI9LAHVhgP4KUGALEtAKKLElVLbCrnpB0Ikc8YIQpQGPERPpoFZPOaWZQWodJu5r7dAIvrAF4YsIoCLuxlubUXtVAP2bXbECmbKiXnuJNN2YMadesAcNUINtSF9TnZ6HmFdbaMXgmOQxUNIWAKcBUMpknA4UUCgOdEXnGBw+UOGEvYudVZZSiT7X7QHXutvfgQWDdJ0JiYlV1dbCfZAOBazdRG1HECSUkJYUaIUMgEifvPwp1TpMwRwKqLqIoKDHiPoBiqkg3WuLYGaLKpiHYBIL3ekEzMQP0FIIJNEHonFdRB8quGPKEGkuXS2JXdlTtFPWVSPSGCZOY5Y4PC3XAIk+3c3ZYDVpVkU-jikIJskDnFqdSgAOQyMUUEY1M1Zq4a4t3lPwB1YADU5obIDUTU3IscZNaQaggkBCXIKiv0hQPQZGiAHw+5-YXAJT5AdWz9cYIQigVT0AtT9TtVGATTtuDuVAbTazNWeAjBJ4BYLgsgo4eY+ymsB45eicwwaSPNjSlCMkNgizpTqzFTGziA1TdTiJDTywTTeuRzHw7TpzYApDo1LQEYFAcVjQL0RosVAFbojQ3UXyfTs9egXzyzGNZZqUeBgC+hQmuDtJOtkAi+naM0IzgRZQOjFoq0IDYERogRpBu+iAACfSAYCop8HYo1gQEYCTSw7dYC-icomguTbdNWH1eYXyn0vLVgCifkZelWogRh8Apg1KD1o6kazKTxueXAC6FcpAw9T5WxOrkAlwCYhgNgD1NWPcjQsgLdiANWph25EZxwuRFm3rJ4XltLHLDL8D8wmtIu5AtZXyJN+NVDtNFm5wPL11opBYuZVg-jloBgDoW80AiMdLu+9ggNCejNpAfy80me8haKQN+en1cNqgQ02wAqk0oM7L-e1CegStlVgWq9KuTgG9FZyAyjzZxU+9EFDUQR5GkdZ1UA9GY7-z11xjoQiwd9a6ekj9qzr979n99gP9f9DUADYAQDeYnQ7Avh88xAE5DEvtR8MDKYcDi18wdARptDqUQQzAXYtBji9B5L4ZwdUA1tbI4TjITgJgjddgOjc0tEjIc7EF2Wl9TpUEy4SQoHRoJchQMQQHp42WjMmgZoNYSlPqC060qSlenjdg70EyiqzNWUEYs8aEDoAh2YDgIDx0p4Cr-SGocYZeXIxUMJ-SwK0teFWQwKBegDwDx7YDZ7F7UD17sDBLxm-zNlTgPtymqmkKiLfbW93735O93+rZ7ZDUCcE7sbUdJ5IwbHF9CQIwycW7EYnQLtBcdodIsksY7s4z5BB7YnoDp7hhF7mIjofTYYd7gu9eRJywl+37kAOzVl0Asq5+Aaj2zlXy5+gCrA3eCFgORSigsAsu75Eg0XdFwzpBgOggrAqAOc3gsWvtDBbI1ojFqLYYw2LYjQCAOXHmVlAGlgcLGQvCHzw2403g5waYu6JQ+BdpgNJSUxgxqUcXWWsq7mQQzXSjFmMLRE8L83vt+8DxVDEsFgUgpwTgpAc3iLrgS307nNkQsY63SLU8lIQjbgKy8giZ0UzU8AvaODUAjBKKF3BIugKyt9ayvtfkvksgymfX5X8ArXeXX7H3Y33X5svXcOigRLCAJL4bND9IKU6QLb9LzVNNLR6wh9HRcOII66+K-z2XiDrIb++1gltt1o9tlcyE0zCyYzWQw2mDNgsuJUsAKqqUWXp3kAjCpM40Ph-Y70mLpA2LZptRIviiBwBIJExABwPAgmHXq3YgOcovmUGLWLjUhGiPTgUmoTgd+1J4-FCuLkVgRvEtJv7uUzxgk35pGzSA5A1v-PTlpvsZd9XI2PjnfXPA7A9Kv55FWhLneQZIIKQCgOCv1QZPVgJ0NDMfNQOc8fZOcn8wKQYk2ptRn5FmQDfk0k1NmxL721kAM0Q0kow2CYmgC+eQmhyoPAw28fJq+g6wgA3oAtA8R9fSIjfrD258DIygEK5WCGCq5WAlw+FF-ml6BW5hYMnURhBT+1GPSZ+AjveQCy4iDviiQUDS8INAzNUMnlfNUhtEBaBtcEZleu6VcxtO9VBSCQ9WUSpCeGCwCgncUNR8UD747VWytF4RNZg9kL-K9h61qJkBboouMnuoBKg0No4eASrL-2GzBZSAqwN-tRSUzsAXwNDPSOoEKBmIWsRARmFgAK7QR9eH2JTMolBD2FnwFMf7gQNawyR7gbYVAH5BRzr9AoYfbLKeBISw5yBCpNsNABYGu8JapWXnHVks5cDvQPA+gUFgEFCC2BysN2ETQSi0BA4VUGQbuikCglfsBkXyP4zaCyl-cp-KAFIFsK2VigLRNBhCEhQncPeO1c0qYJKhUBKWmcRwvjkcESBMiiPIoCNwQDr8QkKoXBBVjhyPQOeqAgDGQwkaCFKsqUH-NoBqwUFailRQQCoEvDfBrCthLiuTwyZ5hXBRQdPkQCcS7oFUtgrzFpygAz4gSIgVXv4U6jqxi6jndJv9WkLDZfSZJdfhaD+rLQYgQ1SUgBSkZH432qXcoS5V-aQAB6MJCOoMWSFLAMGkvQ-qfWLqJkZY9hFOPjlqzLC-IUAkqI5g2B8DIA9wGQfcEOEHYiAxwk4fsPuASoZB1w04VAAlQXCdSRAB4Y8KeGQAXhrw80vcAAAaMg34R9l2Bw4XAtAbYA+gyEwDRisqGaPcFlTnAwATwERAcAACaTwfFJeCRE-wDgOAvARGFoDP1pEqUX2oNwkBv11BxgmAItzOSKBs+FLMYTsWpBwBbAjfE6q4EQBP4WkPOcoRQLX7oCf2O9XpmQEdBcN6BX6I3O5lYC29IA9GZGnkFjyiAb6d9MQtUFAIgw3Q8db0O0AwBhA2g89d5gtCXr3tzSUUf2t4He4E1aR-IuMJoCiGUMnhYmMUQH0lHSjiocoh0DHSOTx08wxo60RQw3jpBraK4ZDhwgvjthWAnfb0ZMgNHu03hzRHgHFywFci+Ro+BBE+SFi2i7RxRB0RKIF7OjZR8NT0SPRtC4JC6cPKhCYC1E6jZIUYowTqXlKFDSAoOVEIIJTrqkExUATfvNAgoRim2aoocF6FxaW4mxQgynHPzpwLpochiLoBznJHrFd0dVFvH1mcqd4Yso+IBv8zABU0q+uXaLlf1NHrAcu8PMDnDmgEkjBB4Pdfp5Al7YtmR0wpwCkJpG1Fh8fWUfOPmvYDE7RMAdkHOOsoE9YqWYGQZVzbww9YWp4X6IBMMFylyRTrBFtnFfwoNB2oxLsGyEuos0igkvKwPOWdyCi4JOuNEmkhrDKg0gbQSsCThV6vdqeUACDjYHN7kjq+SDVPLuLJb2DHxrYdPAVQYDkiDAVgcQKngfFEAuJPE+CW5TzZlAbx5pSdPuJ67ZYNx2o3wkv0oynVxRkozEmUC0rY9d8qhZ4n-kPgNQG+g2LoNJULxbgMy20RCBKTELBA760tKek6BuZlQOy05cqks2KZFMP+mlb-ggKBa7M-+xkuAAyCRRhskCnQbqCnUI4-c9wJgaWiK0ro2SxKukySoZOlb5MfJeYPyQEEXB2dCJXIQ6KoT3BWNQBlGJHkgC2pqkNSSEVBl2GsHKBJRISZNkEJiAiTPmBQpgG6ngASo8gueBCTDxTjySH2xQNwAwQ1jpjCplvMiqrkt4YlRczUoLIDxED89z8VAA7u5iwwjD8GgvJadRDsJw4rcQk5ieaUCiXADp3wOaconsJkJ8ceTUVjVlg4-Bu4FAJKVdJAZgAgCcNEINFLFZ9ie4DELeA9Mrr2QJSUSYSGGESH7TLggcS4ClnPxWA5MiEoZGABulb9lEF0mVjr0l569yYv09uqZIrG+FnOeo8gs5OclQYfUiAeAZdMroqTqJ3-FkL0z178VMZdWVGdiwMmgJcUMgg6QAGZLgj7XTNLn4DvSq69wY4GAEdRm5wW5MrGd5Aeq-Q+8gQAyNrAeq2wDxXlLUE8yZl69vQ9gBGXdPEh2TAZW4diCWHUANQfAeLFycs2JltQzmBYbsJBV8ACyDmjuBmXZNZr3M9kQ0EINrLJAUA2gZoNyV-3tkSyasj8Z2UXjWgJA5pkjCCQHn8whcWpLkKoT6k5F7SoAJ42-rUTUCXELMl43Xk1BEaKwGMJMJaXmAABkVtR6EUgCpKSBeWIphDiLAB4jFABIhbsSLfpgBAASYQNzKsM+VuZkXJG9YmJBNSAJnOD7ZJxKw0+0T+mrl2DIAtc3Af9y7lNyqSLcobnVk7l4ie5q86aVFE1LxA0+IwkearlcR9BoWnXU8GXIOC08J+Rnc0opMdE1zsRC8xuc3KJGryO5XczeSSL7mGioAIIVPNDyHmHz42ZQTCgMzABlzAEbEAZlXPvkzy559c5+cvNflfz35G854r3IXJxzIA5-KHnVTDKQAJJIw2MXF03x2lyAqoJ7nMKwbeY8wYjUvCmHZ4eEJA6OSgE3Nwm6IBhFRbns5UEzmAhuvI4eeFz-aIArxevGQXfOzEzzsCyII0gFAkGTJ+gh8W2VcxjBKi6ZA+F2WNweZ+MDIUYmOdGKIADyRiKc0UXwpJECKgFUAY4HUFunezaMdw4PFPNgWl9OhmsJ6S9NKjqi9AdktaPrNLB6LEeLAB8Lt3rL7DLFkAaxXkx1k-wSMkwBCqAXUEOKJFko1xXhXcVtpPFn0toD4sbCXwgZ3LLOtR0DBDIWYmYVKNihLbRzyRjWK2C2Eaw2tuFRCrVo4HMWJjBFWcv9hXK2n7DklAvTOLIgHAcwcCRpa5EKAph-4e4MkKQMgACW7UZYgcCxUIvWlTLzQgjKcGAGOHiKsxKS3RAMqem3SZFGOUZeTHnqTKikMyvmCECGSpSBS5cqZcI1WUpwTA9wPRTOJKACoEAxioebwpaXpzzS4SnvPDCK5JLtlOYivlXmejj9MoF4Z+N53Nh5MmEmgORZoUmSKFZAsSOob9EdDoryq0c7wcUCBh-KM5SyojJEA0kJQxEBK72Y6ESU9LQVM80lbGXWiZsgwCQEyOrLzmRhXmKgWZU7x8GEqzwD4GbqEo-HhLGVOPNRPyupVWBaVH43pQysiArQWVX4dlSItzngguVL4IIK8p-mQA2Fnynhc0v4VtLwln3WdrjzpVOLJFpfKgNEALH2A4wq0XJQZ3yjiBZJdgM0ALP7Lul+E6U60AGDcDptMEPNHKW6uIkiNFoYDb-tBFHIhAa69jKKukExQnJ5Adk8JqrHoj4zm6rdZKXisGJvkfUiyjpWCVplvgf4FoVUHoDnoyqtlVqyUbarjqfSj2ogVUJ8rzBhhYMlAD1cjOSneqv6dqv1Y0ADBFR3RkKGoB2ocQIAbA-QSNb4WjWGhY1wwIhtJTChDV4Aaa6ZLdEzU9cFo2aoOVUt1VNdhihqsxUSsozhLZUlgIGMCstVI9nFava9RK2aAxBts4TECAhX0n7IDIHANoNJMCAyAhg-AAAJzBw4gJXIwLysfGKA9ARa0fJesjmCQEoZqngHJNqAywK5NgWVTGPpWl94Nj6+OhvAahzqSx-kaoCYC-VETjo74f9VkBxBgAQNYGlyBBrzXmlTAPRExfMABVdg8CP8EKMHCw23ycN3ebjRNjiCtToARePjUnhihIQdVBipgEizR5NLT1sG2AQXBvVyqhNFmS+eps4GRiRZg5L+vIvZjRBM6SQLcFBCvnoR+gxmzBFPXyA-U3w3dACvssaTpApAx0WQHJs7bGYeAtAQebGxU0mqll7WOiCAQxKMRxItau9davWChaPYpkJiNdEcaJaa2-JeAJoW83L0O8TeWaSet+Wqb422cTkNFunml8xEYkAKARq5AWRJeSQHfv5ELHkLixEpOMBkAimQaFJzSBMCKreHhLIFnIctXGCrWyBKgAm2ovKvK2Raqtn0jsLVqhSpaTAG0IsehFa03Jew+oiLZVrWiBwn17MdxgYC8BBQMgWQOdbopY21EC1ZosJSFuK2Mghtla6teNoUlaaoAFW3fmtAhLaAkgE6xYgYXjomBOgGUESJFpnX51DtSgJrULFBgNbfZF23zVSR5HBbi1A2xkKVvvUWZ3t2iEINVpdJYt6t02qHS1v4BtaNtOHA9fJuiy-BiA+W41RxsKFLLAAWoC0QGeFqzTXWr6UFhZAU4cOSivZjpAvtwofpBXRjBrR5mfs0KnhUzCdb5gAIEQMQOR2j5AEMgVdujti1FaVd17XneHwTq-Q9wPURSM51KB40cO8IvpD0Nzrqx867MVDriFXi90xCFbSJlywp0+b5gBIUMspoK2K7TciiDAHmEGihkQVHOmeXVDYgSboZJgTEAcrg7wy-dVgLLYuR9S8ouiL4YEC2F3kwyONweILfToqFLLbKYkDZXyj8gGrg9MWyUacDKkSiJNLayLZdzE2ogHAqWUICXsoASaBUieo-JbHID+7LgKrWTF8tjalASFFmVcnGKEwclSAzwHvXgWODx6++cmGmrnvNH57i18+q2HmBn2KJXAS+29WVvfyz7RNPe-3UXhSzKZesGARvewGgBd7AsHuoEEjyDAGg8FXuunavvaW-kPyIQA4O8qD72L99GO93H-tr1x7N9LiVKK3uj3+AZdhiq2AFtFVLLA9IQFvL3sn2AH1dUAVA6cj8D8AT9tzb-R3t9ok6ZIierBXLqsDzE4hD4yALEKyDaAIZd4vyJcF0yXBbpzALqSWsCCztogIiLJTBsnYRDxGk0fgD4SSArsj4moMmTK2Q1vgGZ-UBnjjtm3HtO+Paq6dMx8L8ALwbW2emlu2j3pQ5wQJGPAGMgjA2tCLBblY0KbLNnJrxKNb4BjVgBuC9LZdQGGCDjlqImTQTmEDsCKKlgHU9EgLLY4mSuQW6sMPIYvDcVAw3YDLXmAQCtblFtIANSYYYgBgLw8aplZFQYxodz4v0YIOZLZCaRsd9QDttlsox0HsglwI9QatWmUs8NygYIDo1IbCGKgoh-QOIbnaSHpDyU+o6QQZm2xejaK2JCEGA2gaAQ-1ewBwFfU3hGwWU4iQ8po0iBOF5R54vQeBC5aaj2etaZArIwTzRRJnSAM0foUTQ-oHRh+lIbUOV1AED9UQJAqETKAIjEFbJCgnbI6LEikiG-t6AShkSr2-eEIKhz20yrVFpAOGWtAF2fSHluYb6mlEsgphrD5smrKgAOB4A+1qkEYD91yCQNIt2SyMFNWd1uh2Wsgf2mtHXgCzV+KiCFC3q+SCZ+j00iowwfvD+ah9nrMYfFuyk3yJtcbKAEcc4YnGxD99VdhcYFlsmfU6ZLHW0EeMzQ4Z2gTNg1uAR3g6tlx9utSdQoOAE0cZXGcpHkN+htQ9gBAL4AkPBBSji5ek5cGtBYMEDeDSljpp8DQLBDy3SISIdOMCmujSpmrDaZLiqhHj1y5lYOG4jsx2g3K22P2U+hGa+d8raKNnTtKWaC41muIEkBKUmR2gAs7lXtoZlmhUTX1MzRbrurKhYzMkUkLNvED5g8KDmupG6a7o+pwomUNQPIYQB81NJnm406ZTiFmm-9mxoeWtMBUKRSCHwcVbvh0aDR18EKpxqNpCDSIOAKCNUG6cyCa9+GeoeQ0wz5LsNjjJkC8Am2cPRmIKhQW6oYBLF1Ssw5eBcG6FA6Bgkibp0CECuiDhBIgjQjlTi36OEyimdJ1Y5UcmVTLODi0j8-abHEysvzJURc70LoW8noVZuxVukE+VpB8wfYNJuIHIgUw6QaqtGXnObOBZTT1R5gxqRg21GxhvR6IMNqa4HEfzhxx060ewoOhgBp4AWb0YcaPH+lxW4vKNWvWHhaZxG0yRRp-VUaGwAGm2Dw2MkcAXGKYeSIV0Eg0X0g9gAWSM3cm+AamVAGpnZIAHawgBy0q9rSfJGmmjFEMoJWoB62cH6MY8k2WAFiVNzlRx0Jo6Rb5OgEKLKlqi0HK9mUD+jYFt6UHLEJFGy8xmqwNqbwM2LEZPsyemyBuRGBWCYEQ0DqCO1asuBcUBeX4oahG11Lr5hgzUt711LUsDSkkWwZlhgzPzXSx5Y4WeWfDJ5U7Eiy0csudof8nh2yyjK6VSsc1j0viEGAMaxFQrJYN0zuENAYB5DaJnHZIBV4BQILvwB5fd2lBEQ3+ekdFl0trwvnWzRYUoP-ohn8qsunB-s2UAi1UrWSvU-Y0VZ5NRC2jZVyixed0RAraLtVyupBi5087k6gQX1HwH53MqWg6LJC9i01kbwnEBoaE09KDNTW1j+q5g1ds4OyHOxFasCNWvMslXBCk-ayxVbdMA2DIdF3ZQxYC6AmnpZJhoH5HbWdrY6alw9QlfWOp5mDugJQb1otGjcZTLQMc-CNKLH1iL21p0xDfKuv83TqOrkI8a3wL9kknYsCLYEX6jAc4jIeSAICSBGQmYqapw2-GzgBQBZMpv07ZGbUgQ0goc8QJoREBHbHQXNEYKmYFBnbULKx1s3-NmmXA-rOFnTo9scRi2oFjR6mxZfBtWX6bvtRm3duZsnWsZ9VrOPDVhP0QvtP2jG-9s+mA75RO+EHWJG1vzBTTcuqgUbaV1QVVdltsG7tdub7WBZYiD2HDdduJEBRZeE9migVHws+dbQYO4QJxumAX2neT8yTCXAJA4wlQHRjER7jldnwAxq2-zKDk-AmE5d3sK+E8tO2Eh0LbHqIEED9AeAaSAsdAGhR+QoLA+30YsEwqkBbYCUFMmIW51eVHDqs4UIJ0oC30+oP1SepryBg1Ba29NYGgjVKRkjsbrZuiVT12mdnrTdDByhtczEHGNzilSC8ziDn28y8BbK+eGHkMLxYk5d58L4FA614hm2PFzoQnLU2zLmcGFpvijehqA-q0QNRU1C0pSV6g8gL2KpB4oBywANTFXPJaLwSkmefAFMGbOcn6x1N0QSS+rfLNtRKynUR44BBYrQXU6arV+02riA33XAEpruz-AQAfVGwW8L-oXUQR6RO43UGqEXlTiKAHQn94GdNKcRVGErnB7ivA9yFrKdGNAOhCESKBfUnVIDYQHGELyhMBdkgHwJlBSRpJGgNgW2E+eWbmhkTYAawiaF8DRAMjSKO+JMSUAeNiQ74eqzEZQkBgBZWR6KtUHkNeLIwYYiYqfBLBuh2QbAXe3ZIFnAWJGqYBodrCxuU75Hppou-AGkwp8lH2Q-6qo5TjV2lErCQeLbHOaxhv1Z0DhBNwFaLEN79gLexr2dJuh97VbFkCikOjGnyDX4lEvgrWltF7m-4o-NVNkjzc+JW2Wfext0bTPhs04PyPIyB6u5fxSBJZ+QHMDeAtc2gFPfajbG64dnqe9jOSJm57ow82gU5Iat5Tx488ogcGmKT7DFdMA0PKUYdXhl1B2A3CSwyBj64p0bnp0UQPlVTqjm1A00nBdoAeyjjZ55jHoObf5muAzw7xLwYFhzgnjJnkAd8rQ2zhE2rTdIgyPDXWfA9Qe5eg-W5SQpRNoMDiKA0Dx8DKYzQl8hi2OHeS6ASek0WIlMYkC+h9Jl5hSMzF-sBjnOWHAygVNqK6UtBvIpTJGvIBmnWIMzsPIKH4CAIt4IopgLK7i1JIVXtB6QKwmMVl84iyru4UQF5sK6oAisVJFMIzFQBy0Jrw4-o4piHk+B+in+Upif0moawGBEqFJmRACo4xAqKInntGFE0gGmgP+hGHOYQoxQCZEl0AbL7kuW1HgUN2JQjf9gPgjq4rdrBFeUYss3r3dPygGmJjJXnzs02xH3H0G6OLgA13wKUwluitlby11q6kS826K+ri1xmMgDmA4Am+c15q+UxFuO3OueV3PCVjdvHXH2OsU5lIDn4b+v+nJ9do-FrS24voeuSSWnDsnW3gmkPaX3opZhRknYo2Wh3CnvgV3CWxwwdpS3KgRr3oBKtiTQj+diAmb2XZgL0wFumAUr4t63wZJlv+An9UF4a6YA1vp2DHTV+Up1fNuub67t4f2+wF1yIP5pXt8wag+fuFXcQbEbB9qLHTBsJUKwJcEQ9WKfL9DD0v0lQ8QSaxEucd0MWWC9wTXH+taY6k1B6Q2d2Gzd3RVoiMU6PDH3DqOrpD3pH04deM7gcZAsxzzSyCWoEQXksRIzX1CzeE66f2AfRqEdCKUbd1LU0wEgKeTk+2o0eXBXTvMNYsZhq7JRc0aoAnBQArQhAn1Sejp-bBCvHY8NBoToimPWAXaPAM0CmIyZ0g02B7o+0dCLYC14dsu5pKjkG5+CBFa0mdow8VjNp5wYkpjxXoF4hmSoBbRM+utHYsVYiXH+Gb5FRVtl5wnUWA05ioiKBgvbYrT2MPC8BhBuDHrbuzri8zyEvX9PQMl44TiUEtU4Kr-l+iwYEOlpXomgmzcDtAYiCqQIlvq1rRvMDUokPvdq+T9ef4JcHNnmBIQmzxlVUB95Li6-JzV9X6LIAsMgAq4Tld9yjKUAwB0p1gjqf5lXdHe1jli2T5gI-DwKhfKWQDExAvNIYyiTDUbjA5KMzP6MSZk4fw0jPSALwAQseFDY06SBxg3vkb7+IFAAAsMP4gBwHkiseBARoFyIPCelHgRAvhJIED8EAg--Ad9CH8VCh9RMbPpux+9Ez0CsBF+V5J6fbiRPQmfVApubT+5B3FBOs5ADr9nC4nQBW5AfcHg97K8V9CIXYEyIJbtOff4vJhxL1m0iBxnogBlNQmtEEtej+ArsnynaBMCGmE90LbQBqDyCvgVr2LTuBKWUVi9r3aXsAI7KoAdfSAqmPyDhMmfadRu1Q8yItOUSbS9jhV0l9yd8jY7AwrvmMNBOWmlQ4LDjCTQXlc8qxbo+gM9kvkzuezplC3ZiLNKJd2Ii8Ib1wASGcjstogkf-z0QCCAhKvzUyg4JrQZQC+2la0pZ0d4W6qrRFnKvU10q9+bWffujHpI17l8Fn1YtEIhneeqsOADut9v4w5MzYCXfQ2vR63rzyrw34a4kYIGknF+5lm-fowjXrwGavJzYaSYIMVWQnsqV-S5lcJeUNAIAOv-KDADJCD6C+iag0YII0AM85ihkTVu-0aAvA6STlFL7qu8+w5+Gp61EI7dmQlQqyAtg2K5OmO5w4t3K4TrOKeuxo9eq4oVQAgd9LdxnghZHvycmzHmS7O6u7u+C4+5nhSBD+1ICP6oBa0MhzcsxkH3ZIc4MMiwgQOonkBpIygD4bpQhlqraKquKg4p425ADAFO+8wOhCXArOONJTi42NV5tuopHwHc4oJLZRBwggU4AHe8wBIjn4YgeNjJyu3vwAAArNIEbE9bvWaKBVOAIGBQoGvzh-u0WMdBXsOgRNgCBYcIYFVuxRDtw9a6-PRjJeJHpBJXegxFygggWXI-wEYPtKYAVYVfpSwOBF3C5ASwpYk9AGCY3jVKEQ8ZA8gd6MQNoC5QhlnqIaioDuMyxAyApWRAwUKrZKBg36vcbQm8PMyDos-rMBDrI7AE4wSIBkOj4IA1QDgikGBfjYG7QPWj2w88dZB+xGAr+gG5he53KMx5MgQA7BRM8zNrDRo4lOOxoerfjG4BBDjLGA9B0vpEhukLojnBeAfHEVQFgo-tyCRS6hP5zBKz6I8z5ARgGkj6BoGokEDi4AYMRF+jQZFqy46RNoBComBJaYsmRNELzf06YLLZymD-jPI1gT-jQGvwIDIyB-gjHFwhpQqdiuB9Q2ICMiM+X9GMiDk60Nrj+GcAPIAde1Rmc5WAngVRR+BuFmfKKE7aCcgXwrACYD4ybweVpdIPSL4ghBhHCCD3geUDiBnycrFMHNcRgHBSxUojq3rmwP3OPDBAZAXSC4gi4I6DTGtLoECjIhmvYC4BG8E-4X0wKBSE5AOkL34JqAzO2BC2Hnn4hHBZBm7qRcXkvlwRca0how3uA1FFg7SOuARLfq8xngB2Gc6g4YLqottuaDqSRukDQO-QNb4xgYLBU6z+uoE9LyhXQOyAGOtQN3R8e5ygtxw6plOsQWUwLD+JuUHlD3C+AWob5TJUwgUQBjOykNYDbCans5QD6K0lACnA7yhUElwSAmFzFqMRMNhqA5-qUJZCBIDICKoYPNfwLcv4vcwS+5pKvRu8OuDNDqQFAHUJzQvvBba3iF-O0HQuI1nmAHiVCGEGDE-XJh5EicYNYIJ88bAY7lBu+p9T0isGNrDTS3QD0DtBQ8uWSacMPHvRtkVfAfx0Y66BQpAibAAmzn4rxGlxugmoilAxhobAeGTua1JIgneFmI-AIU4Tlj7BCgxN0CHh8AMrC+EJ4TUDtA2gJ3zDYb4deHWEpgHMSPh7QB5ovhtYVeHn4QZOui6u5zEWD-g76tUAK4C3H5ApcdGG6ShSXlClwXhhimwCfERQD7TVcOAqUB9BXvo3isAhEcgCyoTgBEL5wfvIjzI88AKjxMSs8hjz3agbK2wARreLKjsAj+GQDDCiwmHQjOr4bxH8R9ImgLaazXAxhMiT3BgAvcb3CRFfcgkOFJ-cd9BwFp+8kS9z0+BwN4G+BMPBCQOOkKBKq6RMYGkGPoa0GlQZaJyDMxV8jSsIoN+ZAnB7tmbEd2ZDQGmsvypYtSoF4MGactLhdKAEQ+BsRkSrYqnSBvP-rKR5qo1wiabEWJZPOFprq4emnkb5pMmcWv+Cim-AOKYCGg4RsZsRTNomTU66wMzqyiA5tMSxR7rh5jwAu4i87wacLDFHNc8AD7TCqCbKygSI+UZOFlA04XgB1REYCtyi+HJoVL38EPNuIEYz-DZagk27oxQfsFVhbyb0lZNcZr0+PIhIbh7ZAMGDRGfMNEohIYZRLI+fYQjyvhCnPWH0i4OOdR6QZvr4A0y3BuorXM--CJbDIAEUdGZc2xM9F8+vfG5T3RaGv4xUhhCAOFQRWpPWG2Ux4LAJBBXlKzwAGRouDw38YGCEr7cggEdyWGTol0HpAt3MP6BE4Pldybc5YQNxDc-PqNxLmjFLegkwIwKizzhxPODzNRJ0HBoym6vKjGEB6MZdzHc1ASTx-RMvOTx+k5PJcE18F9vqFXytIa4D0hBQEEFNsyQWzz7hAMc9FNBmEQzy+A4MYbi0AT7EVKvs4AphGwcsimfBNASHKRwoc80AWQYc3-gZTs88wlzwkivPDbwC8jwSLwzM4vOqpoBSmEnxmx7vCoD+kWDMrw1CH3Jry7GNschZSIeAFNFgaiTHhG-yAfF+LB8StmArGa3oABBR8QIq3gq4U9h8QoAVMr4ALidsUwBJ8cfOOFQAXIMgDJx7oYuIQBhzns4MGO8uVJZ6Y+PXpBkbEJyyG48ev3pH65cdvpj2SMhvq96PVHDgP6m+P5CngrcVsRVAw3pgoqhFgM0hEqgbnBobibIFFjt2-roLw2k49PUj8RZ4PEAciYNLsoD4zpNCajQ55uqxgAmrNqy6sBqPqzjoAqJOjTos6KyDmsWQJawPUNrJrz2skADVhUAlnP8yiAv+sgxYAIgK6x1YCUJiAlwK3jY51Y9XkKHnsqEpI6RgRcGKTli1gP0BzoeFKJQ7xe8VayVYE6EoJEob1JADvQaBrABWst8XawOsqUMnAngCLA+jX6i6KIaiA3aGWhuweQF-EkOpTNUjeQ0QFuBbwxkgqw-IGgJwBuiIINrCdwDhm6qieMSH1BgY7KAUCLQe6LsG5wpAGOo1IboJEZsAWPtoBFU6UMEAyQQ5LoDXKEYL9AIJqUPvGPUkBGqjpENgOgmYJ18day2sT0A6ygoznAgS54oGCgTaAX8fCbOSYAIzomyYoL3Q5eoVkvj6m3QkubDUaUoJ7HsbIMkS7xOiVax6sUaMvGpYGzM0gcoyaIHyfKF+ol7Tgl8Vgk4J5iffGIm0mBmBF+X8f1CEMp4EqB7QCvAnoAJV4GMD+GEtLU4lQRyDqZkcViesqPgDQusqHwnphXwEg8AhqxhJB8cWjMoKCVOjJou+FUyIuiAMQASAqSaYm4JFiQ-HXgCVNAB5JF4FzyBMc7M5z7IYYgjDOc2CFEztAQZFlwIsGIHPHDAbyHmDGSCDtQSegLulgrVAsyOviEYGoZSys2QQBpIRMo-FgoAEBkVHjtuxUqtTouj5AizLAFxMoHnMTFg0bTIylN6AF4SAiyQEYgKaCSGkwpF2SSkEKaN6DE6EICnRs6wNGx5BsFJKRQJd9nqoawRQP3DwAQYbsyokJ0EsC-EXsZGFJU3VDF6UYj7BjgEYYeFlim4HzgilgKDASRzeOTTrrHocHgJhyEQhsTOJ9OywGgynAKeh5ghKXFAb6tg7npGAdOSeF8jGUAeG8BAAA")); })() /***/ }), /***/ "./src/js/built-temp/base-pt-BR.json": /*!*******************************************!*\ !*** ./src/js/built-temp/base-pt-BR.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYAS7ABXZGABWpDP2ikARuXhgAxqQB2ccsJ7kwAMwCHCnssTQANGETDYpZIlg8OiNQBN+iFeR6IA5wGP+JVVkOR41P0CwVyU9CntoFURXTwA3TjB7HkSQ1gAbOjMwNVFMtk9wvXCeWy5Ic3BCSFds1XJXABlwgGtGSAARVopXMAB5KuUfPLAAWjAAYXV08mhgux5pAEJ6xqI89Qwaej6AbR5kDABdYABlKgBRAEEAWQB9R9RUV4BJZ8eAcXuAF8APR0WDkMwguAUeCvViYOEYHh6LjIvQnEHnK4AHQ0LHY3D4ghEYkk0jAsgUaw0EO0ukMxlMFisNjsDicLncVi8PgCQRUdjCEX50Vi8SKphSYHSHDK2UFyHyhUSJTE9gRYEq1VqeMerAAz4lPPA1BD4BhPClEnFyAkwIoAI7aaA1ZJFVKkZQAK7ArHIUkULXIBmK-HJApi0Dk+2dSBDmXgeTI3iKCMhVmUSfgkN00GEnkZ3lMXDxizUtuQSnzVvg9jcnlYFH0EuNolNsEQlk9Pq1CbjrKrZsQeYL+iMxcbI88iDypjUvhHMzynjmzyKaiiqzA8GgccX0VIiUUymEKyP3a9vv98Em0BHoboCLcOj9Sf4Jzklw1FQrOtImJfpseIAEpsDwKRDggMpXjKiA8GACC6AOyDZLAZ4joKiiJEorDhJ2o5FJWkp2DuK6JHMiyhOESgnmesiJMsVbJheMo5lGO5WBwLp+tOfoBq4wgcK+bS7tEKI5h2Ym4fhmHETkpFJmmfH3o40B6IgHA5jyMT1ikpZqKMEhSPwqhmgIYgAIwABzFAAt+kCr+oGu6up6iQABQAIrCEo4ihjE6Tqi4SEwb2XrCAi3JNroKZmJsACUZQ4cIVgtJM6j8GopCeoK5nCNyZlwCFdZSbMYA0GIchmJ2ZprNknj+X6K5qPA4jusBahUf6XL8OGJlhb6SGhogWbQLIYAAAdsSsUS5AUnaWAOZmwBZDq3vRR5pSYfARNklhKLOa0tON-A9kNKByGtw2Zq5HhbXR56JAOqyQmIUamp6eSpBBR4GZ+lwAGohYiGjRGkObQHNdjKp2gGXHiJx5GhCNqIQYAnAAVJcYDPKQ3L3NAp4Bni6NYzjqDqLYiQxGAIHwHoObemokyeN8yOoZ27jQKThDk2APkhRByRKLTNyIOkiTs+cbopLzED8+WVQYBhvgAK9ickO3qPBPNo3z2NgPcYgAEKKOkeAAGJ8DhRuteQyKIJsYCoObaH8OmngeVkiSkKlQ5Hkl-BVO9SgAFLCCxYpgAATAADPHBlk4bxtgGb8AW7jutgAAcg58DZPLGOG88uE5pzou7p9pDfdpzBsJwvD8IAJuSAPB-iMgsjcCowDjzobOnLq2Jls2Bh0Dw3i9ypS1vgeP3yPOEPNpOr5dVQUoG8wqlCDDm4-Az5h7D7Im2WJKUMWUnWLhO4jXewKjyc4+uCI0xJih1bbUaIFUW0eRfdB1nyPwH8CkxDyDgAYU8+xoAJSLvzVAQkOAFE8vcM0igVaHRbHaRs8AWjShCKSTwBhFCeGwhCcIyJpR+1JCoHMtg8riGEGafgtMip0iXrA-WCtDYAFV1T434MQNCBpUxgHULTEitItBL0Qt6MQpRTwwjgbwsQWAgzNlpj+FQwgYSoQ4AYdI0wPJKw2GeWiG0nqWGIpYTs9YyCWBiBoYWMRLCrHXpxH2nDH5ZwVI4JsNNxTYL1t40uLFUwBLFG49gagyBgA8kZCMEhQwCU8HIOsiVlE43uJkbQ9CfadUxHfHuX5CbbkSQgMQygDQtApIgNJlBSCbAnmoQWeQ4y6HPvjGk5C5D0gOqlXcthUoclSCgMq1dvq-UVDyEITDnEb0Qh2fe2lbDWisIkfMWA4Aa1tgUUZuhg7wFwdVZQ3QdyVPUK6GIkJRTOl6n6I80B855C4C7PiohPB308PNeAnZDyJHyC4LansxH6FHgGSwm4ZCb33LWcGHT7BiOTO6MMiZUp3NcAGQ8FVFB5H2AUr8XQ1DdHHiCL8t8UaZIxmePIABeYgsBYCsGgDgEEIITptFcFwEIWI1A-QQCCAAEjnAA7PcQGHBAaXEGETYYYiJhTExDSh+BscYnBpfSxlzLWUgnNHi0g3K7BkpBN8G4XkWasDDqgaEBJOB8EuKgFqwK+LB3BQBEEyqqXqvIHShlTKWVsoAO7Bq4EGFosBDXIBBOQG1DdhKkEuDcYQ1JXDhqVT6lV3C1Uar9dqtlyJYDEGTZG3V4D-SxsJE3S48xqkbGDlTeAHl-g1EFcmhK6a8iZuLtmn1mr-U6oLUWuQJbbByGgOW+ula+Bkv2HIEECQkK6shBoFcjhLkghAk8fozx7hcGQK4S4jxGESMQpCQSwlyAdp7p3FGkBGhAgaEQDAs7ZyMAIE0fYWs1AYD6PMEc6Deo7HRpAHMAZyB9HuOQAMQGmiFr9veNw0BBg-WuX0Ooj6mgxEmPYPINx4Ce1sOBvA9QYNEHzHoKotA327Fg2QHRXJoB9AANKkaaKhPFu1GPEeeKxogYQOOXL6CbXjUByECY0H0Kgd70YPpo5AbUagajYGI5UVjkBHBVmo+jIg6h4B4bMq4R40g+ilFWCrPeVgIQGEYxh4DtB9PiOgEZ0gfQAA8tAAB8l9zPc0syGGzNGdOtWeOEGw8BnMmfVKF+hDh-MicgLQELJQEBOeM8R9zXnULJa2rF6z8XdOCr9uQCLxGPlgDin5vLtmmi0EK-RErUAMvlYoEUXLAXtNQF0-0RAABPBrkBSgtBnFZ9r2mEvdZ66llz6XPPiVayN+LqwDPQBuCmBg6WluOY86N4DWWwtObcA5xDq2KDrca3tlLHmxCuc24h7b8W6MrEeG4JL+2TuUDc496AHniBgFcxd3cV34uJei7uNzs2LtHmk4QWTwHujwEm1psbnY5CSceMJ6rRAVoBjyL+qgIEOjxdnGdyAjwOhScx1AXcph2AQZuPMRbQi9Ak5uIK74lsKeBaYAiLMdPUCPAAOOjGhxAIE96MPNDrKQE2Lh7ZcfwHJxwsACh9EBpDKI-QpdqfwtB4jqALS+R5MsKGpkYYLSnBmKMMZSBxkwqsooD0LEMW2OLxokAshqFLiUJHRBAU9b6GHKQI41MrVC8pqA5ZHAlGD9VyArVA3-DGX0HOOV+rGdj8oFg373w-uI-MLPWB9g-tj-mFN4a+j01TTUbXSpTvi3SJaTTxHvi18oDHuTpBok3CK1mQV+EIPjT8gNCpKha21PqbYbYseOXDCJb0YjMrOXyp2q+2PxAkysCoMu6Aq7w+k+PZgiEyQhI6Cn3J+wMQTb++I5bAu9CL6uesHB8gy4egebUwoUggbXoAHURyKe-T6E1yJkjnYEsDT2DhME+SWXOUvlSgiAb2SAoGdm6kUCN3V1NyVHNzEVSmqh4FoCUH4HzwDCrF4gzHkFCjKyfBzB4GZlZkVFhkQHQzk3vEQKrA6AziTGT2eT+08zU1YItDGQ4MMR4WJWykDTUG4MMUiTMnX0mHcGh1hygCGyL3l3fT4xsFsAkzwHUKaFIHnygFGBY0p0lwWj3013N3AxMPnCzFxzzxcFsPbw60gF3yIygEBhrgInizIRHBJ3pmqFZisK50gGwl+Qryri8JMKwFgBuFqhSH2Faj6FGDkFCmN2hiwN+UQHixiDMMTybygDwwQn4AHEGWoQ0i0j3nix+ngEDR4VYBSAQD6D7gLAXj8B2UZy-zqIwDPTB24yTBTB8B2yaGYC-yYwR2FBaG-Xl0gEjxxzBxoyUKIHOBihiIlkEKrEgzAx91gxqBV2I02JYSUGWNO0iBcxMIQGOGIzq3SEIX0FnBYCsH4GOLbzzHgFSkSXvG+lIBwBFzAEWKgGeNWLYL02EGUDGjUOCKVz2KgEDwpE+NykBKQPiwuJZzeOMjhNnFyjiAQkRMKlInzHBINV+P+MgEb3gA6FIGSEtngjyDMW2KIChL31hJkExOKN8gUCRPOPBD6GuKUDKw0mRUeKSCg0ENePeIGnhO+OJIz3UCqDtHr3WPgAsN+XD10IZN2L3xMWwV0DoGUFpJN2RO5OI0qloUoE4E8AHHaR3FoD1PpB3EH3RJZK+IAH5pSWC1iyTlS101ADi3C1TRMNS+hqTBTEBDjLDDTLioBeTbiBSHjQyxRLC4DHTKRWSfiFjY8fDKB6ZnQdBcF6SAzlc99HhRRWpwTiEfAIyScPDewbw7xSEC5FNAjQVEkQU2BkZTBdAihkACoXBFxoA6h0y5NcEagxiesJiKF8z1NAziNHg8gkI7dbwVxsjqc+hXZXJdoZxFk9SLTDcPp2oZRwgoERxwDUp7h6cyDvkHClJyAByZMMyIjRzxypitT7BvTJzGTwjVgCI8oIQa4wcTCoxlAB97wxFWBRQYh8DPAtpsc-zVQigYgqhFMZEopyBAhbyYdY94cxzwhJiMBoB6YvzRgDD-SpzCzPzMjdAYLkFlyiYkiFI0FYKsEUB1ovykCAU+J4KGZqhkLkhUKiTBzgNGYHAzECLyFlA3ydDITpz3CMCwBNdkAzjgjALVdYId4hlbpxpMJShHoJoPJXMhL0JFAPMkoBwoV7TYAApsgmw1AeCIgxQFLXlywrlJIxEUjtIIZZpMDGCLyeRnIsxrkXc7yO9WoFSySuhOZ3zpLIBmSUyviwAOZZZFLnDlLiNqzrwulFlOzokihSgPjWSHldBZRigPKTd7KDU6YpdRlQU6A0IypqEKDTQ4yZpSqflOxAqMK5NIoGiQTkB7ByBr8FdnCPziMU8qrmiB5F5Agz9kqVyZyczzKohWs5ycw2ixIowT0AAvuc84CGOUAcc6R04QNMoK4DSKbokWaAb4BiwScS3aSKsihfXca3W3XQZiAYswGioC40-GVrG0VsMAfa2CZyc9B5XSS+Dpe8NZEFK3WMXyTCN6igQY8qG7X879DzHOKIKMOkTwGsY0M0DYIiCcKA6ATYTYVzaEVGjALzIyFWHwaOBG8JUG6sbSU0bHJA1FecehfMdgbwDRXMmoFhTwBAFcdC0XWPBIJDbMBAF8+66EgYKWpwsbFK9w2CQZAKBWizVIcsraeQcQX5X+VzVQJhWALzEFV6a0hwUgBKZ2NKgG3ySiqmULEcV0gStjMwaAeYGwGWySoaqKl8zCNoRogC2alW3sNWrCOIs6bW32OQPW6mOJQ2v2M0U2lSFm2gS262sAW2q00PaPcgF2k6t28aT22AK68jBVDsb2wa5HP22UnQPqhYU7bAYO2i4jAATWoXnDDFgCsAozlXvxqiUELQVBHCQGdkeDQJ62oXzEnuoUDRCkQlMhsC1FgALo6uAxjF8n9HwmgBT1gFEP2FOTzJ9proeqgAxsOOjFhqQG5HggbE+rov4lIDjpyxws8DMttGYphptzhu5hQLNxVPlFVHzicj4m-rjAMGXD+jdLh3GJwooUuuutBIkuruA2GqgBoG3MSA2oQGyAfv2LgCHwpH8XzAQm7LdFAWFFWoiQQCwbttiFGh4GRlsRmUuXYUxqUHOrcDEiLGJrAEeHmsGUWryBVgSEsCzEoBRB4DjBmG3FphRoDDRuWCkY7PWUVCoZkVplofInJs0AOA8zJoUA81cyMb+1UFYXImgFpQAHIsKnyMBrGPN5h8cOhybzH4AvMABqfhqDGqEcPAPDAoDKOy4hJAHy1QPCEcdlBWm8kx8gLzROix92mxux+B79Rx1ndnKgNxrpDzPAdcOqGJRsbCV0HWaKPiVQQ+zCLWxmthaRHZLgOJhJ9xlQSxlJuBl8dJjzMnbJkEdxvJsAK65YaCNMI8HgJeRpoxmBpoZQEhBAdccgeHP0qSs+yAUazwBZ0wfkZEjU+4cvfY8NTCTZpAoIma1uqAfoX0UobKUgghV0DARTCYJAmxS6NaJsCRdKDc3QBR-R8+eAOMbKUfGpUgXRymrzWmfkiUV5DySmWmc2tRdmx-crRQPQWlHESAXNANEEaowNHMLgSdRuPgdFxCEcaItFyAV4GMFwbodFjzRAHM8mxAYy6ZogPqpZ+S0gcK6vE+4DZWyAW26AA0Jm3kTCdwBUPqqUWEOC5qjhhy-h1wHMjMEq9I7ykFCVk5sSJhmWLmI8dqsWoc2gFYm4WZo5fEUgWAP-cgAA3PVBnY1Z+4Q1k4yitgQyuFYWrIlur60O30cOm8Qh40a0lYrSxFGnV16Od18GSkMcaqVYV5PepQAcbICad55m3QGN2qaCAoZhHysrGNzh5dFxTiBwIQKsaABS4Vo-fZZskyPVv413JY79JPHlqAVJzpvC0YZYFcAakihS9IZ+PoPGZYRbbMcSk2bQPIXC6YwJ28L5sAUJj14ImEVgR1UaUqM0Vc6cU5sbAMTsBAMdph3Civc1xhnWLd4DQFLMZ4SOPxOWxYKpwq6O7wzglYeAUYbwDsDkdQPoIZuhbSRGj97ZgChqGMcLNkN9ngD9lB+WnfAmg5d94cUUJ-OwAwRwUwZEqQZ9eAVtVwJIqBb8-CHMDSXnEwi9+AfdidicvPNhrQV8XW-W+LE1hweABZpZ39VMV6kcSVs9zDKW8wwZGj7j33QejoGqE2Wk-DbwddqjlcXQLajTD2AMF++LQ+7oE2JMWAQYE8KDvuHgKtld1qdqdwXQWmQmXByEIY33Fqe2G4QNGoTPG4CCPfZtXMF2FqNqE5hjmwad26r9qjl4hjzvHrbzqDxYSJwTqAPU+MYLu64jcK9MMAadwD4IvCdgRlTUqmRAGYf4Y9izpgWz2ATPETnrSGSTAMVRv9C-D612rHGuCgCE5woMVXcufopKsbbo01pr9oZu4Izeos7iXHEw4r-VQNJovq98eLVgM8ZUI92gVr4DZQHrFwX9HwbKeLQNIRRo4jM2BwubpoKl05VcxQWweLJhSp2EHD4jPDC5cDarqAXpA9ihFdrMKCSchbyL8j3C4GVMM0aY-UX9v7LClOjMfZPkBph7c1rCkTtJOwqMiHhHPAVzQH+LSoUgI4WAerjrbnI5C7mSw++ZETIgZdLAIAtCAAI5ZgrMpzI0I0RAH1sDjAJ861am+AqX13ICOxx8gEshXrrDABBG8yYQUKp4BIqWgDZ45-By8yUzBn59y6WNF-F9vHEX6D9hA76A8loBjgSkZ6nOopmy80cGoq5zF0Lr2E4LyG6jML3pUc-ckObbN8MSoCirzmkNcz2STHf2sIAYQE5-LFtLsiF+CKYRU7R6AKeuvsRcUHnvaAMfi16UZXUBznBGEK4L13IANFoHOH4Bd64Nu7j3NZt+9Ix+A3jy6J6OTxyk8AZrppOmsueWmra7GQVM57w3FIpGxNis9FFr+JLzIFYFlr31CXety8gHj60IPq9AMMgCH5a3C6nJzCkKTF4M96kpzCh6THlxOC5yIG+B1++F3+F8gH34P+36gG+EBh14v8P8BhP8x-cP38v+P734AA0dfX+udLgTD7BM-uzkAU+Ye1mAAWcBj3AOguMAAIPP9fgRkDyGrjx4pBaYtAQ2meHfiwAr2c5Zlnn2KhqRUOxfO1nLVM4OA7IcAYmtkQcCIBu8Z4MaPmWp7ncaB+AvfKZx-rdc7+RAQCt4FYBQcHWPACYh4DtpCwEBlcLBPaBHD2AKi7oHCGIBrB5RNAwgUUFmDQSzhu+pvMbMDVBLH1bWvtVZq7HxhyDAgjPNgdTg4FcDM+vAxemsiIj-UBw9uHkNIN4amAn656SwIeVpI4UFOug+OgRztDDlo6XAZQevUx6mFdOkkHHv6TQZRVUE5oDBAYOUJGCeAnAmLlAG4FmD5IO4NBAbjEh2VpBdTPQaZA7CQgXkvxGTMbxMLZRVsDcMXgJHUGc8k+MSSFtghbAIQ1BwkaUMW1BQKUoIRJEwgSzF45hXsm3RrD0K8z89kALLJgL8ijx4UvcwgScn7g0x75KoTYaOMyTj7jtJ2T3DQTMWo5yD2iJhaHujw2Gc9TOBcczqsIT7aFNBMzR2iUHS74086OvL8pMOmKa5EK4zXYaf3dymgZhqVTwphHjJDgZhxvPPuhEIxTA+8P3Afn0B8juVj0iAV0t0LICBpwRJOPGJoFFZQEHsjnZEUGVvAsAbuKg0fuJ23pmgNhyzZwqoDgC-odEx3PPvPR6xNgd6k5OkQyIhHcZOOGrEfkOh5I8IMcSlOIQkN84R5kYy0UiPwDkDmsogu4dpNyG5AKUdEG8eRMFHIBccfKk3GTuI2FGG4CEYoiUSwn5r0JZR8GXCHxF1K0k7IUDV5E0yaYuwSmu0JQIjw6a4Uge3ydjjQnVZGdfKvhV8NKBqphBEO88HAn9j0Zo09S0jLUaKLADijYAmNfUSwmARGjQWijKmuE1dGlB3RzYQFlU2mCrAgmG5dwMwXJFzNdoSaMEq5Gt5PMoOxzD0bMx8D5ixhJABuIDAg64syRp9W9igAkHxZAEsAAavy00h8AAurAHrKOV-Sd4fAugfPGsXrFeDRojgdIFQDZCpgYeJFdBpAAXGgjV8wRIRKyMuFEBLIrwfceCEhDiUKAo46+jQh+Zo0jxltcgImP0awFsMcKMrJeKppxA6o0cZQHZGVGRwQWFNJMc6OtJH5zR+KHXvuJjivAzI6QKem4S2GlloIQQegJCEIzTJnxwYqmoMhOFC1t8QbIzogDvFo1LMQgHGtGzMDwBDG8TJpoMFMCWAXxHmUMSUSsC+NCG+E5MSaEIY6BvkEYuUasAb7OF9xAAZleBPguQdPe0WhPRoABh0YCxK8xCBcqA0cICMkaSN0pEY4H2IBKQlStOIGEjiexQzBmRbStHVynHV07AJs4kIPCJBCkiTMKJRjKiV2AF5oFaJmTDnDJPCa1dVGNTG2BpJvHSQRA24WiSBDckgpkQIYKBv2SKF1tih+rMjH3zL4XVtio-dTpOQiD5FIAxw3SZYBlQ9JtARnPyVQA2qtQ8GnrYwYkP5bvh5CIsMAEgOJioD0BJtMAIACTCaqa5njz1T38efLLAv3t5QBUpjAxCacU+qlTBR5U+AVVJqkoCOw7UpqS1LanXsOpBIvyndBWApSm2EeJupYBAjHtRQSgPGMOCwCjCSp8QqDnAK9DzIWptUqafNJmlIC5pGA+sQiHwiUdLhceNadPzQgYROIqAfCBhCGnHSypp0yqYgOQEikzQ005qbdJqLtTiS9bO7msIQaJSuRPUoIUO32LpDoh5xUgBPwO7EZoa4fZgYrWAzu9cMa2U8CTg6CAxCceffYZOQQrWA5y9A16WlIykZgt8LgcdCcVwk692B-0kaWzI0BBseeGgAANxlBCmDxP1qUwiDchDoTE6CCCjO6eTfBkUk3gEKIC2dFAtMhmPTLOxhDepb062IcTtg5hHY3M-kVBzZ4VxT07MoNjqXtiOx-BqsmKWxhoitjeW2s69ozL6kQYBphGM2UTGGl291p54qkGgXqGIpO6zYEFNeOAlMEVZ1hFgIpLV49SiA3s-Yr7ObAeReef6CCogG16H8eZAooOVsJDnyAw5iKYiIGLaA+UY5y4Jgi7Ayrm1kYloW+jgV-I4QM52ER2Xn0F4myAwgvSlslORl0zPZKc-WWlIKmtQBuHwwuRbPLhKZrZAsp1utGJgMQCqkY+CLNw-HbCZEm8MzmYEdnnEIO5AGOF7LemTyl+8wSxkoAf4FzzZZUy2QvKPxLyXiK8zaACmbB4Et5rCHeTsm0nsTzO3cgkeOmYZIQtZGkUebuPHnmE0I3ge7kZ39k1ii5A7a9iiFO4blpgcwbKXAu0AiBHm8QNdtBHtzGgcIigtZLz2IVqN7wAfA+fHOCK5BZxZ8tKSFjgAYQPRHkBhSePzkzz75I00QqLALA4QAFRQZ+RzLby4TJBhCQ+fQphiziZg4QY3KqQ+FpyoALC11uws4W2BuFd-SXAHN5nFz+F0QQReZUwmJBRFOElrJIo+RAK1ZEXTQt1JekjyGZY8pmel3EWni75ei5BX5z+SWCgkM0VDrOHcS4QqhcoeCsYqrBcxdwlo8SXhkGj+S-h2VM+IinTAIBIUW4GFL5APC0wsaAnHkH7CPxkE0lgYpSH2FDCexOyjg3IWTT-H6M6FzhDFEwrcU6tdA3kYQAYExSRR9g2iwIbPLKmLA28ajVIbzzuS-kil0SoMWCziUHV6MWVU0DlRSW+F4A6S6FPaVhTRxcldpB3DYHM4nkyIFQBMBUt8pVD+QNS8SSrLz7JBRkLMXBPCDK7LTwFOsppd+z5SQwNESgAZYgsDlNEswboW4tXLKISgi2WoV5WaRsXOzCex7MBcPI9nOKoFrio9p2GCYedPFSCqDs5xnB-V-FgLVYPjW5AphtasBAAJxxwwA51HRNIvJHKARuLilRZAC2lIq8xmc57I4BmAEreaPSs5mirKkYqhl-1HFR2CmRCw2VFAQlbzxJVkrIQFK+pWNj0DLjlFb0hlSe2lmZybIccTlUrV4XFzeVfi+0LzzVWSrrAEUoEcAqRWscYVECuFXrIRX7ElQTDFgAgtRXfLbVeEQUltDFaJBpe-ZBLhvGQTFAogk3a5Lz3NpzJuY4BHnu9FjHg1Qwis9mow0RTcglMYgKUfbTrEmrbF7ufAg4pIpOLdZCq5hR9LPTvLG62EL5fooHaFqrQxi0SGfAQyyjK120OcXHPTUQqoAj0uqG7J46Wq81Oiuld9OYThdDBXikLrVzQKFggVBHDicVTSFH4fRe4VNZxLECcTjOJoMhVaH1HNqOs-xVljoDAwaDrVfa-CB4p4XDr+lo6zBJXMnUZg7K+QlFCmvYiLrWGK6mdWenXWKA3QlKpWqr2hIHq3p-a5CR5H6BdKraZa7xcHNhB8rsVq62dWxOlGPrl1kbW9dKG5o0EKAn64DI0tpV-qj1rSnyB0q0BAINV7s09SNMfnQQzu3gZ1tKAxTLpoI0oSuQQjKzVyWgjMVAfAHBU99Fc5nYgI8sgW-q0pXQWbqBu06-K-kdyNpPbQjWcR3V-HA0DwFeT84QIjwBLvcGeCoBN06G4YjT2J5YbmZMIBnk6vLUzlsE4goWZIt1J3RLAbQsrDECQhZYUUNORhoIIU2NztI9GPEuWzKyCytG2+cUe0DGTMIONJJU0CbJ6yvAsA9sG8VrORioykh6MwmbBlID-AQtSE+AKglC0btIQy5btc8uIzJai1xnJQOlodiU8T13KkaU5TsCBJ7QIUlanbJNk+AgtseDWXCFmaPIEZFqp5bppgU-RZAhWsAIbLl6xCSNxc5DI5xoQ-xo4KWx2LAQ9WabWWJs7NfmsH6VqPRtMQbcJrKmGKPV+gbybTGm101eeogILbDJgCEYes9MaPq4DwEhEaiI4VwBBPsXkBXgXIV4EfmYCQifF9yeSPg29aRJnqvkahLRMDonM3JcwQOkINSFHwq+mReRuJOGZQE8g68NyThXwymhHEFSMqHCzHD-sEOU1K0aY3mB0IpGMjORszXiq6cXO3IZGLNz2UdgogtE7MGUovKVK1B-IMHW8gzCuQQlneI0ALX6TxV18YoBCGVhp2YSlou5WTQhHQjcg2SSgA6rGuKBKRa2JJKPvdteA7smOna9UqsyVVJcuVSRSZf+M13IqjObkjvuA1-rKSdVWK+0AKrxWCJRVvNYlaSvJXGqCRau9oPCDvrQqXpq4-9b9M9aG7aJ-6igObtIAIRLdN9fgHMAdZH4EIs4czACg2CdCFI+wbwL5g8ju1zgioM6LBEZhygCEuqswElDWDUQIgMwaCqRHDnv0PYOGnylXvT2n4Cd8TVADcACaBJwYc5AAC+NlSAB0TPoQwvHiSFKMo4nL3pMC-jxJxVAJK8KXgq77yV214KhAILa6CyctNRRhAsw1rftkAIyLRNQisKCt4eyPfjNtzchwdQoGiEYpIjYQElFmA-Q2q1hNq3JBCQZJxNUmnL6xnuh7cVCPpr7SKBAu1cikdV8jzmpOaQMDyBoZUQgVDBkP9W1FG79GgCe1aDtqVo1x6oQX6i+okGUh0iVDcha4lwgFRJIUg7SLGqhrp8f+Cyq0FBR2UOTXoDO8SXoEF7CxoAMkxymYFNxoJtaVmnA9KGDB35PAQgRncAYdUmhKkO1NyT6LXVrKF1C+uTD-teAgKagvulcVFWwU8Dcpx6g3cRn33iTND8CsPegeTHdltqLBinjrGmAW6z9Vu8qCm3BoJLym+k7Ya+HsFdl4IWk2iS0BQxuDOIcyCzF6rcm89kAcneIeRBMW6TyJxjKZnnyUPoQ1AU8z7Rg0KlcEg9ehpA2jVgCpG8gJ+-7RHwv38NIDaQaA6wmvitFdAXqykPIBkHsIdkCh4DEoc11IQIJ1K5I-Su2mLV8aIqkMKmF3220o91CMrCDxKjYpaJJuplbeJMNeY5gPNK2aFMwj27HAt9bo+yr4DOx0ALh1ScBP72XxcxumUFBMbKbNgxJYLSWXaLADWMqA1jHysThzARBCIjEEcCtxSwySGjTQJQ11Oe2Z476dSH9SswIGdzYCOcguAu10N-bBjqUfgIzqBO88pQoJt40bAKDCtGdLMFAOEDxFwFjwTuI8MFJdQ7Kto14wjLuEsAgpAaNZR5CaAGmvgdKVe4KAqC4qTA6CPgd44Tzu1e7e5DsfuW4EHlzk3tx814KfORmriL50wK+e7Rvm39NV4BgY7YfgBDHEU2UKqiMffHchaJ2RqeRzqZ0j5SgB+zw52TnBXkZJB0ElqEDeYZVYsaxTSgcgJNmLUjCoOyqW0RTIwimrJqAEoZUNpdvjsi8Su0cMPaGHaSoWcbtyHVet+WsESE7cRVPkafTfyNUwYdgVaHfoUx6fXMCZ2rs-lgkIoEhuzNqMmECowhG6du1L6yZLRzDX7trruLkI7SzpUAn6MRm5TCptIM8dGPxmwWIOs3dMfsPzyYzr84ZddnEmjKsUqS3cMEbEBFUJESSm-STW-3smHt7alo+4GTT-GtBctAPZbi6VgnpTYZ2U1fWYFNm4I33OjdCfEl4QB1HOiw8itz2gozzyE9BJHGPLJQn64JTwN4eMWpD-hu4cthUibDGmZBogPww3AiDJKENvPCcwIviizml9C5nMK8HLPqHtBP0jMM6Hw2bn6zvYSM8MZbOqmTzZxnDRzrmMLzbzAdFFCOcjaXqXwKGFouvCLMentNSi1c0WWUAbUzDRsizadHQu+hMLiKaM6LFwv-iadU+sFuVDI2yyxB8yyozvGNCrRbitm+edLMvI855ktFuc68D0CKB8MXbdo3jG5BdBUgms9I39qKgG4eAwgG2g2b3Nxh6qmRqmqPqNmJIYtigRE98FOiUgNgjzKAvQ0g0iDijeB-gAiwsEFAbxPgGi3EgvqXx+I8p08GASAY-l4AG1GWRAmaguB3OzhqCsmVaqNJtecR1S712JHo92jOgl+iPz5bOYoDFJuHe2bHGYQ1gMnPE2aQiR2CiapgZ2N5wuNlZ52cSesDvAlm2iymm5bRp4GcYE4i2cssve0KNGl7Ir40C49Y3mA3GFZY4yBiLT+xGMmmd7TCLRLMpCBaY51RcH+aECllXIhK5oa+FompDooinfWvVanCWhyAzsDyAI18gRHyTvoUaHUmoT7b4t5ABKN3xJLZQNdc5wq1Qaz72RDEu+44WDaX5mVkwlceAo1TKwngYYpoe8JYD1VVRzY8AZ0s7Bb0eY29+TFrroDMqbLXwTVpkFSdqrvi5gttWsg1Gjjqmfq7Brs65GL0fzCGvNbwe+PUkERaYIKbw3Kb+HzxB4OyN4-WIBtKH1LRyP3MDYz6g2bK4Nwy5AE2N1IBAGgcesjGsxo3s4K0eK9yB+gWY7KaRLyubhV2nbHhHW21oAb3yd4l4IeJjpAYg54Cn0KW19HlpWrTznC8o8gFdSQhEc98Ptwjqu2jg8J8w2tInK4GuX+Umi1yxcAoTz7G5doMuVwFsi1mpAw+uKr6OkFAPOFioyIQAsaQwkTcBIh3XQds2plrDusAwrYcAcRYOAZg3VFfkTLqQb9Jy2gY1rOAYuBDVxlsBtJtpGmzl5yoKWxC4FiT0aG02KHRO0t5qvJlNXgv21YDfrRrxIQ4KWQ5tIh5tp12EGuLkOxS18xmc43Y3qs0p5RlYqsaGAxRXA8hqcs4K0PwBRJdCPhRMDu07bGwobntZbWcAAKTQ80XY-zVeCGdfs4YAB+uAFgA8aMG4ZOFfbBB7dYEuFSWTnAtiwNgdFodNUAZtJaDqiRTRcJQ4IkhwEIB3yAoyeVTotXEEOiHRs86qMkQ5shkAKHDEYZrA2wTfyl9wsCvGZOPqBwEBTvjOBocchTA68V5LbVsRXQxADhr+HOOWt33j2SOsqPS20AFjAhXgohy-eAy6Zl9oOPoNz36FgPYMgaUgOo+Sy9EoAMcXGNFihzC8iAVQdIAY-2x9AAArKY+yxDaGSpoGxylk0ekrtHzj0TLizNBhaAc0xeOI47ZDePmgwHAoJz2AIjIkSp-J2bYrIxta8UP+dfEmDwxOI5xNQbth8NXFpPXQ-Gc6dyA4CkA7Afd4uQPZWq2CUbPArVoIOxRFPSIHkFJNim4mEFt4fsTPFFF+sPCqnGTnsfQLIyRRYLO+L-H0G-vaQOCzCGITAH2A0qoAEz47hY-dMQPg8I1CUDA50UaRKRxGECAYEsk6OBnPNNSzVFGeDPdAOzvZ1g6inaZt1UAXtoQpuDsB912TqKoDIKffJSeVYLLQw+07LUlWbEMaT-LEADh3nnznGkoDufTI77i5JAgo5zuPPrt-TpgKc+UMzOTnP9+Z-s6YCovYuSyKZ-ecgerPoHUzzZ34V2e-Qpnb9o51s4KKnO6YZLwPqwKpyITSoeQMLSS59nmh7A7ic5+S9ic4PnCLUFWLTxcWkOWg7IUp00V+fpWIIfAewK8ioCM21Gs6nYWJBapUwcFbwtanyVDu81bYKbZNcVEqMsxvekF-l2NnmUgc72FAMTjhUFQb4ltJDqKjpcFo96+9sL7c86qgCiWZQ5ZIiKBgC2dhnohuQiyPnJCYRtwB1Ha+PrdcyrBKkcPIAHI64iuoqNAS+-nlBMSviMAASZXlVaGw3IMNwcmTIULSlmeUEw3rcqVKGagbGguw9eQyo6+0hICxuGVbG3Mi82pgEnWu1XsfejMnJyU++dlS4lzc55tW3b6eXuyaardV-x0QmAe3Tzx16s2eAbVXQaHQdyNOHcE13AfB0I6u8LATueyHb9TOvnyLWqRTV8TN0kNlRurFkiKfIUoGMQyd+A-PQmMTCtruu0GJ7ox3rLYEjgp+r7s8Ji5cIbAGUv6J95c7ietq2Tkt5gGBAGFnuoqlsNhxTy3NcrPXkAaZdAfGi4K0x6gAWv1ssgAAWQj+Vg4BWbfnh+RAOnWjjCUJqpxKwPNTJOG4uHqwfcq6DMPs02gR3AN+Nc7Dp0IktH1oqKHUnE4D5gzVyy0D2xGTLYbemQY50hCGJ3E24LyjYBOZYIckAteKksiPezg6R0AeqeEdXZ9unXqC-IDtEEGXuMPh0Jtdu-MHYGchyFcuClYkYZL9jCl40IaF9gPJV3G5ToYRK8sHVLyNygoK8hcsTQhAf93Th3ffHFN1yp7CAC5KoBvhsErUNeNZNjd6EKMOYZESo-X0wLmQnEEEYjV1iWe4l0T2z6QFY23hRYfDIeouJ8AMm1AdybNmUiDwz28gx0JNrsepziJggdCQkwUFT2Rs57QdtoRI3vxUxdjIKIjlq2-KYF4As8bFBGCPcWuCgC4xI6k76pMoVwvOZN6swvkKgCOzcqSENt0Xlbi5gsbfR5LYrOC+K60O552V4eBLglwigJNACOvjRfX3qsL3fdeaiOezss8zt+Q1MFxbYIPhk8mptJ3RwaUQRQL21+ju7rnJhH6A8wmGd3GLquDE5kUs-ev4xetrH2JsNzU4zEWYMRDkBCjuqhapShhpMGYabkCgNQT6dyHvtHvmjidnrB92ekIfddnRj2M2D8RGyHP+g9d8XJzlC14hgvneVEEG8ckeQmu25IbgOoIVqgqUaHWADCM8WMg8DKi0Eusnifk2rmjjgqDMi2gLK0hCN7BDuNWs5IK8KSMEvSGsMqm4FGr1V4-iIQJfESIX-xWncyKgzo7eGd+iupxBjPqzIPxKBkSaKigocmkLINtsi-wiINSUJvM4ogriImjKvZ-p2Ro2jwz82+lOdxpP0YoEzBYFwZ-K9G+AlgGzXEJ2lah7AB0vy5kBz+vrEfKgtgeE-gAl0vS8AS1ta1y9W3070Tzsr1pk25uzSfPa0raQNLx-HqqkYIWo1MCQUIkLQAwEXiNkSxsgCE6pxYNNyvz+epou0upNpiWQ44pKwVYIJb8w4Fip21tpO0SmrjZisFNTNuJJxO9WAeAInZIyqCk6hBsyhYC40sCJenED0zOw9wH6ohuvPCxqSQbvjbZ-yP8p-poUamKESwAj5Gkx4U5FN+QP+1FBnj22FAD1jr8CbpOQRa7tn0D5am4s4QUIb0isKlC6-paBQcOcB6SDSJHDt6EKo4vAEAO7uO7TBcoztmD66Y2PdwUcUxE0SdgLEBEh0c1MBNzMBUEDpZSMJXNxj4wNvHlKMYnUmwBnmaAcjIm+9dKwFykfVHHyjQU-B4RzkCWqyxsAg7PAB1EA7DlDaQCsjtTxYGoKYEgQIHiiKWBugNDQbqtgSYGWBKvBIQWBywD5Rfy7AXYGWBHBMzg+BVgRxRyGD6u4GsApgdSTs2oQUb7Hg9LuwEKCSEP2x54t6hUZlACIFEEAAWsU7IAV1E0TOQ1BnPwageQXYCjANgCTzFQKHnPyMc8zH+4OKMxK6LqsvAbthfCowF3h98A7ITaDEtgR0Fd4u7NMSECsAMQKBKI-ACJXyR4Hvi34PxroDTC6HBgCYc2HLhzXsmEAQ5+2iwZhwyeNwGH4WBaIroA7BnEJri9IGAIMwVg7AdAD5chXL1iyBUAOU7W+E4h2LWgXYo6yUAxrBpZmsJOA6y2yacKRLnB+8teYt4iIIdI9cQ8le6Ah-MmIotKqHsMRmeXptUE5SyZidzcMXJl268mL-jka2Brshy6aSdQU9qjiVZuHaR2tyktKnQMEj+zng-Wp8omEzRk0FKqpujoav2Zqk0HGwrqg6pMhu2FmowSm+gVrRwAyv+TBE02mFpEBeISQErUa2kVr2ypWs4QwWMEqHpz872jxqxc+BOwEtaQZMSAmc0obCG+48Qmj6sBnYFlw5c3hFCrd+QiAUBPcz0h0aMqp7CaG7s8AJSGrA0gVUBNBzocfJ4Aeul0asqaxjqERcPWO9wB+GAF9wvG0xMGHUMAXH+B2g64ONBd+WgfXQ1WNpPqSSiwUJpQTcwnKJxEiknCTgbWsnNtTlszkEpzWE-oQUCc+ggcaRlcorDH7sM7ASpxqcc5Jpy3g2nE2ouBbnIZzFqXHhm7dC1wcQANhPnGoAUkpyA5wxAq5K2EnM+TD2T9aK4Ay5jYEtMFyxEvhNwEqwaBID6D07klWCLgpQZwEjsMRNuEGe03Jdwjss7OpLzsEwVuFBMsAKFy9ioXOOJzsJCO4HjQwXCXSEh35POwSBq7FBAyofxqBy2A4HJBxlSwBCO5wcEHHjoeANDnQ5ruyXMwF7ha5k55HWRNnj6S+bAW+FZgjof7agqoULjqdgzvpEZZaV-s7KQAH1lUHNs-fpdxlyhBI6Qf4+ML2KlIRDFC6VIY+B4AT4AoDtZVwfKDXAoYfPt8yeAxACizksmLAOg1AQ6COhlo5AMSwEQZLOiyUsLUDSyQAHmAq5hARQA86ScaiIyxeYWcg6SyAAyMIC-WuNniBxKOZObTY4SZuQDiMddBmBIsPEQzDksrmIOjLmb+GJHwOsAOSxSR1LLSwEsRIFlD+WgkcmiqRNkjEbxMeIAkgDQZlK9B00JDDwRuIrDN2SKYtToeTkAPBNyCL4cqNH5k+aKIkARgFEGAARwdULIxKA00LMgxRVUoCwWRvEeiyuYM+O0Aum3QB5gORDsL8jORVLMShuROYBxHGc-AElHtAqkdEZNMeoKeioG1RtlAZgHfIzB-KD+NxGlRGLFqhYsmkW4B6kfsFyg8oqXEhD5gzEKZY8wkACSx1RTkZJGNRMkXjb4YzKKaCqR5UKAFKALET7B+RPUWoDWwEQDI51QVmudQxAi3uQwxYwCGiTVu6JhSAlRVkeiz8R+aN5HDoPKIpjdA5EPXaIAxAHkC1REkRSy7RtLDnA8AIMWYDHRcwFdxhgmlBsiuQsAUoDUkJ4rzQHQDpIkglAaJplSHag+ssbe+nGljgF4OeHf5RUDweGGnaukNNiW2BlGYgv2t2jCDKReREY70q7+hhC6AGUZ3zmOwRICQUI3MdMR-oIpHdaOkGyKyQj8umNzFcs5MtqxxqNCHlRfEnnLohOA8ACgFts0xG6GqMmDORCvBKxBQgy4qwD7K-B5sUcR1QU6iED8AwIQdL1i5tt+h70jwKMhMMX4cngxiHMvLbQ2rbmVToUYuECBAAA")); })() /***/ }), /***/ "./src/js/built-temp/base-pt-PT.json": /*!*******************************************!*\ !*** ./src/js/built-temp/base-pt-PT.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYAS7ABXZGABWpDPwDGwyWFIAjcfFg8AbvyEzSAOzjlhPcmABmAQ6XkeMxNDCtE5RGETDYpZInUdnbsBkbRABzgGP+eHNhaAiwABMoswpvBywvAVgbOwc7eNcNTjBvHlyvVgAbOnswPVFitlcePTNmnk8uSAAacEJICv0MGnpGSABtHmQMAF1gAGUqAFEAQQBZAH1l1FR1gElV5YBxRYBfAHo6LPszuAp4dacsdYweMy4XszGzyZmAHQMWOxuHxBCIxJJpIF5PxlKp1FpQboDFljKZLNZbDUnC43B4vD4eH5TK4gjxQnEkjE4olzCkaulkJlsjU6mJvE4wM1Wnp2qQuGBlpE9Fl4Bh-DVkuRUo54PEePloF1OeQLA5WOQpORZSZavwIZFlaqEvBoEoBgBHYRIUzIeAVMjBNXOVyIGR2+AuYmODXxYThfj5MCwYSudHMrj-ACq3jAhQ4YEtUVc6tIchx7ltwpdgUQgb0AFvChUlQgVQ4aRn4FmvcHQ1ZmY5neZEBwPc23WAAAcOPTwN3QaDy3MmsAAWjA6BxpWgpBLHqNNLolQo-n4YyU03ZTRabU8Xw3jZxVaRV1MnnipAcl7AWrTM+gAEJ-gAlNhDzMIQ1q2+lfw05ClMGnqBHcDhRKwzSwOKDiStKuhiHaNTjgAwl4SjNK4163sI5D3saIFag4hRSnaLBKsRi5uBwwgVIeyY+sIHAmCOJRlIRYBRDEFijhUWJNhB1ZuDBdJpPAGRZJiZRiPwkHGJ4+HQAS0BmC2bb0amOGIBGeiLHAUT6iBWYgWIACMAActSFvApRgAAFAAilaxrEXE3jCh6o6fhpTgXgkmnuWADr2A+ACUDRgbcwiGXAiDuR+SZuHKMh8Ho-h6KQWhlO5ABfF4OOOAASFjFHJNS6L+aq8b2ubBf8grGeqzgjnqUizkG84OK6Jozl2sYerEsjlFUUFKomhmwAIYhmMIejJfoiAVEOiSdUlKWIKUSpRFByBKJNAQnvAuXXstVZaBUGjylhfZVgg8Xaeu0wAGqxVBWAGAkLWQvBlRqKQ+7TP8YyLXAAN6IQYBjAAVNMYCrKQvkmmmpD-ODUMw6szi6A4PCLQBUF5SjhBo2AcyIIUYq2tjO48p40CExAxMYzZiTcjwIQAK8mvTEPQ2AABCWqFPFeAAGJ8A4ABkYCLL25AvIgD4ToLgH8NimHmBhtE0gAUjRZBgAATAADMbdlsBqtCTDV8UhdpqO8wL8BCzd8B4EzPZWaU3PE6gl6Duhi1QaOtrGtAp2kOdanNIGrGKGAzBsJwvD8IAJuSAPB-gNnMDsCgw9yy1otfgcyO01AfY-11QXhIwhIrXmFqiZxS7HHtcK-BVSE-iiC6VdF3E7ADMUVbXueNQ1GHbm1XoQOAaD9vo405avB6LtgaHiCtNetmsBQHG0PAyDLg0ThSYoShwBYcgDNAIXe7zqCMRwVQOLZMsimKASwcm2p5t3YAWFqVwhEJJQQ4mcUgUV4JglqNlW0GowC43aLmAMUQkSGD9JzG+d90bw34MQQCABn4Iig9AViyug4uDhYAACuxD1DkLcbBYBkLBH9PhLcWVWgYBwhYQoNlX5yigqYfgehYEegNNtWK+sFTFAwoqeOB8XabQaKUW+YMia83dkGHgO9yxJBEmABkTJJJMK0bae0FAyR6JlOQL+s0oi2WWOwRSphfIGXEMVXQ5AtSmCUPYKCAUlAH1CkwxYJVeQqMfJnbOucNy6U-AZIQpB2BgxnDhDstkZAELlJCRAQTKCkBCg+CuehHILUTKYZxM5kzw1QfoCSShUSK2WKteaFR4pKkWFFCBIQ1wbmQHJP6ZwDwki8DNJa8BFZdNbvJKoZ54ZjwcNAYQWA4CYJblqdQwFEi8SoS9fgZh4Cyj8TIAA1gmEMbdHB+yshUfkcxRROX4LaKKIoKiDyUKQZw8Q6J9XYueGuGoEAmBQaHcO51Jg3VIE+aeG4AAyPAxSUJKTPEGTCxg4QqAAXmILAWArBoA4DOGcOU0AvHxC4PBb4egLoIDOAVAAcgAdkWI9Dgj1pgABFSjksUK0ZKC0viYrnhomGGLyDYtxfiwlxK3kDEpV4YZZxdhzHsrNVg2tUA3EBJwPg0xnykGBfAmkJ0aURwuh+IZwr0WYpxXiglRKzgAHcXVcC1PEQRCrkBnHINqxOTFSDTDmMIawspBFColSKhmvNxWSvtTKs4LxYDEBDV6s4nhz7qj9UCZO0xkLZMRQc+pDjDjtAKiGkKEaKhRp5mK21UqHXEqTSmpQaaM3QCzQnHNfBhkDCUGcVIpZ00uAMLxdQ+hoBnGfCsTlqxFhcGQPEaYyxxDCEDK4K4vomLkCrbnLOs9ui9CIKS8lCK9CnNGNyslFAfmkH5WSWiKF9DEUUsZQtD5IC9BOD0IgGA+0LUYAQPoAxczNAwKMZYOZvGimcIe8GkAPQanIKMRY3jSBwb6MmiBilSHQG5RdRIyG8DdAw8evsVsKgPLVp4IjUBOg-r6MsswrRaCAaPZhsgMRYrxGgKMC9DH4MAXeSlXjxHVikb6AHRaE7Rh8wk0QCSwmZPEaoJ+8G372OQC5LubAxGuQScgOoW0bHwZEH0PAB5SJ4jLGkKMYgxV6hh24aQ9DAm+i0Es-oHjNn0PEfs2AAAPLQAAfAo5zeV5NQHM6sZoHh4A+bsw5tksXPCRcgLQGLdQEDQAS354qQXQsASy5eNL5mCoQPILlqA-m-5BTS7QcrOEcu2by4FkLgUVy8bc2Z3snLEAAE8quQBq2IOUiB6t9f6813z1X8vtbG119jRAw5WegHMB0DBiMBZW156AwXFumagEVuLOXSGedw+tigm2oABeO9l4LYhtt9l2-ttLnHcLLFIZlk7l3KCjAC+9vbxBAt3ZNA9+r33sv-fa3dkr7GNPwdOfAKbJnTOGbyaMKgyw5PdagCeDUFRRjISoM+OFaWFrXcgMsOFqnccIbJYnFDcxkJpeYK8SncwCq7BFrTpbTAnBulGHMVAyxkKLDU4QE4X6GOQESMgUgfNYqy1E-gTT6hYBVFGI9fqcROUH1c5pyCGoiflHTH8gaDVhrJibMtM0pBExNSoQszqMEZpzVSotfIy0P3S96JAEoehVhVmEKjoglQBujG1lIWDbnIAyBYHoLAAxwPEeQgnpPUgDOTB3pQUm5MUC6agLsQ+V2Y+aeSVWOYFW3QFUgihvStdIQ6ALbk-JngP2x5PTes9F7iNXt5Xe2wD6DPEDtKwKgI7oBjsL1T1d66gwuC3SYDvmnrCkCdWHcgAB1ZwPJE+XsRjRJwSppQmgSXXbE10CI+MiQgm6BeArpXalFVK+eLzkEVqhQ+OJPqDUPsNGEKKPxHgWgdWePDUEONWIeCxT0EcDdEMPedgGwahWaMkejTTRSfPW0OFJ2O0UYBlW5NrYLAzTAmDbA3AioSMc9dKJ1PQfAwg5aJEUfZKC8AzE8WLGfVCYUWLMveDXsJ1Q4AvfAjKfgKPWzWPbwRIPmfrInYIXyHPQLdwLDcgHiZoU5Yg2PZZUND1doUYZ8MNXQ33Y9B9KQFXIDIgRpPFZTVXQ7SAUgXvKAAAeQAGk0sdk1AZ8nFMBeC0c7B7FCdU9Yo3ReJkM6dp9aNIAtEhFEg0tgFnBKd9D4J4BO5Qi+dIBCI1A9CTQ1AfD4MsBYA5gAl8gBhewTdv91YDJvoAC3D3QEBBDjNiNpkw4eA44xoVJek0sLp4AnVIxWB8gEAtc2xej+jsA6dmB19eiMBF8TRRg4ZDB-BJjpiDs0dxinVnDkd0JSEwMVdIjLxTwBQoILFeN4dY9s8rs88yD4BUMkNQ9MN2hNdGi0N8IzjKByQDdbCEARhHj4FEAZIS9XjhFn944yZLicAJcIAEc+gXiCiQSKYLNhAZB+wzC0j1cHioALi4TOR-j8Z3i0dPjKdHCgTSDMTkgWjoTkFjJ44ETuo+RwSwBITf0C84Uvl4gRZ1oKgcJC9zC7iNcZ9CSDIz9ioD4wBgDaBcT4N8SUMnjfioMtQxRASEAopiSC8wSTjNMkRWgpQMSC89dhouSUT7jOD9BNTvBTA7RJgMJ-Q0tJSVMqxOpAgPQEA-ALlwJNkqxloOJEFUpAT9QAB+OkhkpgWEnU2olKa4igW4hTQ0qU41KIc0orN460y4GM-gGU+MjCBU+AJU4M20VU9TWPOIygfQy0ZieISMqAVEmfBla6AcABEELUNoAVVIj45M4jVAH8RSaxBsnkJsuOAyKAtgRaOwYkBwAZfIPQTuaAToNU+DbUWAdY-rTYuUffPAbkqM3k2YtdfwfOBaMgZY+DRg0Yds7qNaAIBAGQXiRQIAw1akfgFweSMadUDw0hEcFmNocgJUCBaWBndgX5Pw4I5wac-MzTDI+cjY6ObYrgk0gkfQcswzaM4jfQsOIRA43ckrOnQ84jXYW4Q0G8bIlCgFK8BwHco435a8MOGIWMBaUCb0AQUcN8nkPKfkKCkwGMBQlSLQcgICyXWPJHRciCxPaAJCtQRwhwtcishCqAEivcvC5C5BfcvoTCpw4iw4mSyUFAWSnIvKMihwQidgeEa8DQai9idUOihiy6R8AM2PQ5HwTkpCiSGQcdOg1cg0jc4jbXXCXXfXGoslTHe-BvLqQjAIP+aaVAtpCZOyALGyoCeAYLMKMaPQCkC+BIUoHeHkIsXUMAPXeXZiideUD0F0eIEsmwH0uuKo36X5VwcxB0RAj0HgFAgVD6RvaFKy8vXsbU7Ai067cS+Cty9EnMkcRBHEhSsjXy4jJxKsLEWpKhNsRzAa-CPIAoIoVKc3LynKicXeDi3eLUeXQoOOZUkOOgQCZuL83MYqhKF9OIcqqCH3YC+DYQPonweE5AU0mQlyj4ySyABlDKHuEMQuN4lfWwpSqnEsjiOAOIGoMc2KSc0OCsMAbKCoIzJa+MMaCEfxV2Vq+61gKY4caAXYYUBiRylKOCysg-U0C0K0MkEQbGpYnymQTHZ3ISWkKUekMSRkBymoR8hiVsNUWpMQTfEQRSGRKA23Cm60amnGj08cbbLIQYYLBlakM-IwRZIMEMGCesSSNwbgsUR8ALG4WWxPULSDPJVwbSh6yWkcHeGkAW48epRfVwJ-Pw+SZZJAvgVxZiCJBGIIMIbiiEiQ+wPDWo+AFiqUEmz6kO00z0i01KK0jCxGevWAI0F0R4fwAZJBchFEShJUWyALXQGaWAULKAm20AzwIpMAGgd6EkR0zgRAf0mcyTDk+AdUSCaAb62AKggYM5WUMOvqqnaOB2pKxO0OO3B3VguOsa5SpWUgOEa8daUhAeotFwUbE0Eeq0eSz-IaHI2-AsPhJ0H-PRcm+3NerizGvoPipc7Y-G2W30Im2C96vEz66S68bKYFEaqAYG+JfSOuW6WMOs68J+hwMaGjb01ydadW5KWiUZZEIwNhGkHGl89WjEHIfkZYUGs-CGioZzeRaUGWjUQ24iV4TERQXSs-F6EcABvWwwOWh8ALawYLWh8gULXO2pQIXZaALFAAcnPoEowA4eC2J1Jz1t0ESFCwAGosqXAMA8AHkqh3dswAEkA-zkkyRTAzgo6EyuKGGmHhHUE2HOHuGtjE8+HOducqAhHalgs3YXo9onyBw1p5CmxdBO7-ANA6yyoJ1M7MEuAtHAsdHWGA79HwLDHeHgtqczGzgdHLGwB8biJPwprBxKFvG6HT6iAggkAEAMZyAkdaMerSbiNvqERMndA6bL1uJ7ROIxB0oQ4oFBwMAeR+VkESwUBdoxAraOpEoh95pTBcG5b6h2BG5ZAW9SBKGDaMBQsaQQq6R+RbJfZra2wsBF9+AAtXBiAtQzAsVfhht41HUuinUPQuAu0k4+BNmgxnB8iNnIB1gzRYpTlNngtEASy9bEA4rrTDTFhBEUNBF-Ain0N66iBTTsnsrSAEU8Y4LgaJrUpeaPTSQ-xSAbJTSsZaglrPL+AgWUGirUQohf9LcKqoCnHUxU7MZrxtMaZLxbqeLNNUhoBkIPAI6e60TIAI7-AvEBjx76bGiL57SWXU7SoM6YH1kc687hRC6mxi6fBClFYK6uXq6-A667q+glxzi0m7SyBYAd9yA98U8bCH7e7FhaAc8UK7BWAy58I+xyAwgSmVMopBT7T2A5RKkjx9XS8awEC-Ew5jJ+A-4jWTXFxvb+RfY0QyZd4f7hSnqJy4gxoVZrk5nTA+mIFdA78rkoC-43Wog075J4GKwJoh5oB5cRSxbVwgT9RyW-bKWA6aXYB8amN70bo6X76JTw7jTWKwCrtRi0jgaFbBoDBHlLbvDKlHGI5-BSH-5AFJW7T9oZXXAubnzoWrsyna6AyjCoAwMhD62oADHlyMBoBHDiJeI3rtXBMMp4AMZWBZij3myVj3RHK+ZjAKhN2diZHyMumR2kBWdPBWBUBeI3QPwicgjEIL34MgUnqb2cZN29CFlTA0FM6Ig0tw83RVgaJ1AfoTdnHTBXGbB0K0jBZ+p4BHCbB78nKsjYm2xLF79Y723fwzR4s8Q8OeACPia+8TRFp5TFB8Osw2ElCvALB1A7BrSpA-14By0yziMEV5Szg9cp9EV-ACpIxOVYOv34AQO72wMUOCXIOPGYGYO6c0mnrMnsnZCVGGhyBim469SyaUQTBYP0a4V-E+ZG7m7hQUPC2EajN+AzQrQHOGAwjUxTk+Y7RYBuVbxCPxr4R1Zw9qpLV8IoJ9KZi6dwvZY5gnV2h485h8rRgbPfIaQgPYHVYqokBLU0s5ACir3guoBUIATCvkl+tH3b7nKyvlHci+gLzrQavSvGW-2QjYOdE1ABi2zuuoJWckvYB48bP+t+pMcNQ7AFqUAapjj5WLDb3N3P2uof213Un+tmulPN3npghhQdjjy7Hn2As+KRWf8lBSwqLWEvG3tDU+KbOgkAipLVLSA8BjvkcNC0iuRSBhhYBkTDtlt2Bu73K7RUwJlIsiAR0sAIMKh-y23-umAaNMBPCWbWxUoCvccet4BdhbpUAPRzthOoATJOQf61GnMZox6+ciB2gD5oBcfyB8fodQtqf3pSfwfl3bpae8fntSFOUIEqPRhbJaADYQo2f4Ln5Gf2pdk6SIS-moAqgiwv8foEA27CG7BSuer5e7QqBPqCCMqAtNeKgPvbDrqgf6v-9fo0sZpO7Tkfv-stQnVvlxmV6C2LxAa0dLDPA9Bqz6AcCiwjzyACFLY82d68DZfIB0p1AGmnK-u0d+DFjhwE7ipSU0rCD6h0oERzbpi3e8iC8LiCfIBCTFTmraQWjuFvlkFfb6TNCyBT21uJLe74-lo0sPf9AO6fPRhG+4eH6PR6C9eQtXmPR7u7QVcxhKei9RfdhdgJ-J+J-HpRe5+MeoBHop-F-IBl+V+x+1-J+N-4fIBdgAANUXw-vnaYOnbwIP0QX3vA-JgAWcekWDhVhgAEH9-9hCTbJtdO6IraBc6cItRhQEOiNF5mHxijqA4AtgGPg211agD8w4AnIG4R8CIAq86SGYnX2Ww0ZTe4lKAQy2WAo9JqFPeHqNVJDGsGOUAEWAYiMQc1OoeA1KDIifzagzA+YOaA6QJoLRK+83NHCmBvqYCx+65Blu2XhiMRLobPIgTYBIF30yBFAtmsYhyAukgwCyT+BrSm5cDGISoZoBeWMAuZvQgg2mJyHchSgBAcoS8OwIpa78dkmgFeATywE8kGWb8OUlaBEHv1EYYgtruQJZqiRxIzIMCATR7Y9hIgcoRgcwLdCsC7k0vSXHzkDJEB0o62ROLT0Jqm8vqcQdSmIDnqBgVBTEGRF-A8Hs0vB6BWwoc057kBIcM+bbDqj2xgA1GyAFJkwB67bEg8dQOCuHn6xGYZ8NAEvPhH1DN9Fu2xZbm6Hz5cEKEmCZvv51p4Kd8+VARONlhvCDt3Ib9SAC3wMDllUm9SDgibm4J1BGu8GZCuoEEoH5WYlCUXpmBDzuUI4KFGUkcLCFS4OBhmPEMEAqC149u9LGfMeWSidl8IiAOfAuzGJkAnUDwynHMX2JJRxsdOfBIkD+GjARYfYFgMhjD7ucm6NgYUL0J751848exf3skV+bXCHe-WHeC3TgrYjcRjwsTESzmEtpPmrwJgSCGQg3QXAhONli4NIHtdoMH8KBG5xvKRBoAFSXyKyCM4Jsi6FOZwEqE+SwBqQHteSFAUiBelAKWjLRgd0HDzRAsG7MDKdxJDBBY2bIIlki1jCARfqC0T8lFB6aG1hRoohsp4BGZ4Mxmf5NUdAgRYiJ24BLWiGHFkb2NaS2nQBE5WDSIluoKvKPoyJ+aBA5Cf+KkkiVpJh9IIBVImoUCoC3Dh8KIvJlAGjE0Zh8IIvEWgMJ7rATI6wS4C4EcoRlU8EcAltAkNFjNsx4rcgOaLlocQxAyUGMIGGLHBYv4gQEwFfGcAVjDavyUsfmB4gKxRemYg2OsCRCFB+seYqAKJ3ViliaMwVR7FQ0NrRcPC0wqqAgDbGWjhS9rZIhDX4DvMKRzA6kSEJoZ0MtG3KOwK9xnFjNkIQ5VwEmG8T+JEAy40LPwDnGfhWRN4cVtnzRyZiAAzFmP1bcZRg2FeSPWIZQABhxwneNBD1ADI8oKoBvWgYEIWiscCcTRS2iTDe26YHYS8EBKwg1AmgZ5GAxfEQR8gd0GUXQyPGIA8Aco08vWJMY84wJeLAscOV-oYcwI9Ae8qBGURcZAsp44LM+FolNgsIEHEwVcNMFNcCxuEOCu6kGIkQLEaWKYkcjq5r8PQMROnHCIgzUQ6RaRMbu8nXwQZTSIPWDjhGQ6IVSAYpQrv1lihE4yQ6UNLE6nwS9coAAsIIuKT6Bu5RJCQh5NWIjLKSv2DhSAMeVSwgCdUj0OjnsxyauUGWyEGbgqDSwHxjW+7Nfi2D4CVdWA-WBckThYB7UaQWSCCONnhxLsSAySTvpAKgAPduqaRNHq0JQnyIr0DSYwO-hHBRAqA2UXsKUDpoMiJBCkr-l7iiA-80w--WAIAILpgBAASYRgAf+-BAacQTD5FZkRB7PoOVJQwsTEy9InRG10-6g8upo03-tBgAGIdQsI0sad0QmnVDIAKYEMWJJRHzT8xlAeAEqANRQQ2EUQOGFmCwBVDlp4g+SWtJYLDhNpvUm6BNOGmbTxpu046U4EggqcLpq7KADFjgCaQW4qAWSC4FakrTGRn07-ltL6n-T9pAWIGUAMXalsFuoHbYrcXmH+cwW8AFSIhyWFQBLpCYlCWAANSLiu+QNZwcjPakT5YoHaUvMTxp78gMYwoGxoRHlG0CDQzgFwDFCUaodGJ4sQSVNOaAzSeqLMdwIjSpnh9IZkAPVlcBoyi9GCbU+SahGcZVimxtYipqGDpCGJpBHNDsYtK7G8RBJ2nFgBhH55pjVZDRKABrNYmmBbIcwAQPhxF6r8dZrMvWfRMvHVirY+ESZizXNmeCiGUBTsd2P9YsMBa+LPIJEH5o+y6OMs64eTw9BTEIEpCK5qTJRGKzKZzsmmZAEam9h1JZglme9KPIeg8YW0SfAa38DYRcI14BQqKVBRQd+W9U05jFynKXC6c6gD0AbBVllyK5doMALr0nkz9-ZNctrnTwbkL4OZzc0wK3Lwgdz1oYpBahpwwS9zHxJoTOcJIB6BxSwZMimcrNLlqzqpNgRpJdAA5o4A5tcsTIh1eAzRKEY4LKoBFvnGBOQZfdpM3FHgu4OIrA4WsG0ZrjxEA+YBUHbLSLfRXQpU3fmXOhllx38dkRXlwD9mb8n5bXQkigs0hoLFeCC7QGCAKDOBLJn4TLoBB4DWBapFAfkLrCMgXgbIB83SjMKmE8joABCWBcb3KAILRwzQF9PqSQVqz8FizT2RgqwXVyyUus0YHgsAgELd4RC3MeBJjBGVdulCgMNQtoX3yGF+dU2nCz2T9yFxZDHsI5m4WXCw+RXM+UXPJlKzEF-3F2UaVeLv5tZ88xkeV1AQSgRISoTKWHKgKdzNoo2NWoeGyz8gqJSYFJDUC4zsQ-42IBAL4qVpwSAgECK4L8kSpCgggZMcUNoN9D+gaG+tC0ZNMOyRCoAloXMGPLVmeLkEnsspPECkWOKcFHirmd4vcFRychmtYUuUtlqhLD5nE0ZsFgeRuAolDgGJSODiXxEbpocLIMkpqCpKxZvSvegvRAVZL1FAQFQfkrvGWLrhQHGxbNLIwXyHFthMuQanyAPyDy7i9qacpdDCQ2lAATiNgAAuzKmHG4KZd25xaEFOWDvJ2gCELwUMSUu04yAnUlS12ZAGuUSLkIW+BpczJkWBzwO66W5dKAeXPKn8ry9QL5Hxx-03AAYD5e5C+VNUtQFQP5XwB4Vo4zAj3awU4oRX+BbI5kI2DCsfmXL5J1ypmlkLAD0rHlR8-GYxighd1QpzMw5aCpnyLBD4OMFgK4rnlwrn5bssVfaAMU2RmeU5EmFEAyXRthSNtOVRKsvCfluZo2U2mKNcCb5PEwchGKHNrEyQf6gYE0FyK0jbLj5R2EAvLPbZ2KS5+yuaaIoUXiKd55yxSsytmJerTaISrxHASuAaABA1iACDDPTCCJNAdqiIWH1Bn6Dz59i4VUeUgieTsF-qvrkZFNmRzKBDYa1aAsvGcirQ5AQMFAlGSuJLxxaqkq7XoWDz22fPNElSrLnwy24nszlA9QGCMqLl0qheZBBuXM1pQBazWjIhpGzcwatq0+FWoSA1rN0Rqh6nVQbURC6c5SqwZvzbUZralwgCwPECMDLhe1fq-tYyPbWgJFqFyXMCOkoV5qYwo6qblAi9a7wAhK8dyGSsEwmAkMPAkRWCrPWZrpFxAgdbmuHWuB71ptedfbSnVlqK1XgfaM+og01Q61y6k+gmuuFXBmAKat1a2rVkIoTJUqwDYyOWBugkEIChddYkIrEMEE8lFuMtBmU8BRwxgicKKxilah31vKlcFDyvlgrcB3gDgJNDcUnr2pPG1SCtWp7IAwICEWgCGLcDZs-4iQUsAmQrWNAvpiQBOTG0FoUl4InrNilzJpBXADAnyctQCtMxCSeVRAMkbYsWjEQUMPgsUHxzb5nJRgItZ3kfWtBpYDev2Ybh4HwKPQycYfJLlqEw2Xz3VUQtWWLE3EVAZBTkvtQRvamLzqeccfTZzOummtZY8sblVX00y5gjK9ieIA8Em40kBVTKoVVxpnwxN+oz6qIOVwE2xb5JRG6yKAifXCIoojYqIIIurqjh41JSsPlWBzn9ZngvWj2WTKs0zT1Ztm4ESiVICHBBtT1GWH1qPLOgaiJWkLdTLVnTbvVi4NLWSBq2yLiM62mtTnKppoJRA0cReqkAy2BlIAAW+4EED9hEzbFy27DWCv0LxL75+ETeG-VEHwq+8mgfKtAk3iekoths5hQPNXVpE4ECzNNfmN7C5jXESQcWDtu+1QBGFoCEHRrGvB2gotZi-mhYtQ3hCeVMAGjP1n0IO9y1RU9It0W+QDiPApYdYNxnWDobiATwk3ClppBZDLWUlOwG60oVRBRarmwtvWOqXv4wJ44d0ARC8VIrWa0c2QecOsigp6xNY63DiE7lgTo4Tdd0i7HihzrWOdHdjhEH3GMMtG1IygKr0QCeRedUQIBlECs0LLMuJoJAvEEpFtQcgXbLINivrHHgXA6iiwCLqY1TgBwbUC8MIHN3QJFoYpUaE5Fo1GATAxUYML5H4BjQKgJq1DiaBLaZbAOlO8tesF2XOqPqvdO6UtJdUT0C+-SopdcuF2FLKxpJYei72hTSwqg0wxFSBuyEyCagKKl5TdEugfRea+KjUN8rwrEr-llfS7fbyp1Jq9luTT6mes0gc6S99Yv9eWMr3tjq9fO0evwHHDuz1obgTBjNDVCIpLUZQAYDYG0q2RDiHrZsDzUpKtLUgYUOpDtAwgMbT4EcmME-gEiTiByIEI-cvmImMNUAcwaRvonYjFFYABCHsm1COoN56g9Y+XJlwpygHbAwzJfZaMhbGh9hmCNPSPsz15aAI+8IrdgJnxiLTaVW0CLPsJL1jCDFeriSXxr387fIT6e-StV9DuN2IPgL3RGvwjQHA1HTULmBKgTDtu5fofXcdNH1Z6Yo-K5nfmIYM1LZ9PmHEG0ykibF-A7KsDafCWZcSv8ihygwMuaQ7QVaE6mRBbngiaGMdSod1qwDXQrx+abYZOdRt4gXhOt3Yi8KYY9BxB6xoVOUAqDvHMV7ArulUBhyVAIbAwQRw1aCA91arENwpRXWBKCMlrbVGBgslgfWAdpT5uenVgyxvk0K6FvqCg-+qZXF6yDXEjI3fK0NFKSoiNejaFQ-kr6XNa+z+bMyiAC0uMDjHEAIZ1BhhNaJQGivWLDhqwtBdSGlIdq0FiboAvEnEOh3Fh9yPCutA8ckzD4iG8twYPQJXIkMJimpeBNlnItL1y0J5FQMCdUcPq1H6DnpcCNNUbADh-ASqmTWwfI2VSW4AhyhPEZAqJGc95AAccCpWPgrDUbxZhFCtn0SdV6SASA2ovIVkMmq9Y8vRQF93xbPwPoNKPwHRVd6sVGHHFd3uuS97joPywfXwEViTgoG6CG2W1CdFPsVq-ACE2aS2OG1bGQs1wBwyoAcMOx16cpiOUu4UKTQd4x4xntJ3YG5Zrx+PHPTyQtqwpIqxaQ9LTn4c-jNRteg3jUMDLN9k4jVenPgDsmJw9chLR7ppSGcfld4SINbIvCjHMIHgPvXvE1lsSbEeMU7aQuNMuA2ECEmtu5A5N9B5j6wbOXLA1Dk8C5iNBnXR1eOjy4xn1HY1PMIKzyi97LKAP8YLZAmHaP1Fk6Cd8j1idjvutoUWK4mdHiQMPP9neOUTyG9BpYXiCkSZpMGiIIJ2YaRq1DxweADpiHokeSPtBad8Cxyh8aKNZGGoxCiUwcalOfg-46i1ky2ccoGKKTYzJs-fN931aSNhZ0s5Ov0j6LOt2Oo1QQkrNQAnT1ij0OsHXUfHPFlu3dfuu7XRanBxe8M-zoCoxmAocZ9Q6XhKOVjxw0JupACWb3tLW9Emgc8Fm6XwJ4lbJpA6FmFJxh3hIyvyMFGEOJHx9K5oPU7PdW9V+BCMoNeHjbMAn0alp7s7GZlNFKF9vukWG7lPJaboEb+3eOlBZq0RpQp07qK4HrHjn2Vsu3Ng+JimIGqDx2orL5ETgoGmths78yajVoLmKdXJh4HPVp1rm-TvdafTiEtB7qD1vEGCxGc7PAmNFvOpC3LRQsfm6jqpz8G-uZaIa3z2uxsWBr0FygCMf1eKOxadO3BJGwitI8j1438aNjjHds4CYktkKpLYJribhuosDKFLUoBLc4F42TVTAwxmTUIDk0eFXLtAkkMpomT6XEjZgLUE3T3YfGxC7cTQIFosv1du23CY6orAPMO5pTT5mA9ixt1KmPzisf8fCcRT1MiGY0TACuDZUGILcCzSdQtHSaWIH8CARWLZE7btRvQTdOQM4k2jJVwuSAXyLHAOhHQyKxfa6tChF5zHEjcIzzkVL4HPCNQM9OYeC2kByHTjCuhruSacatj5Lb58sPATrBIMFYKq50QqL-gKNXAtkPmRNFaaCyXRzCEnI-yvFizz1sGu8uKxChZnrrCojhshHpN0TspmjGY4w31lpQ4gQgesTjWDC8hMzbV14TUBpDpCdQbhgxCmBnr6m44KdQiE1dQZWhdkcg10CbQbybb34zgW2MdPSjZ6sDHx9soH0mAiJbks+z+pZAypqqedL+KsCmhjC3hygdpRACfjmXehqbebM5RYEVg-7Qsf+vAAAEnoCNVNVVHsxb2law5gJQbqMfRKxyMLiBcFEHrFAKwJRFyXX4OiBARVYTYEi5KfFqZ9ca7J0m6QHJucXwrRyJoZTYD5B9abfvBK75OdC7QDAisbWMVDKsuAurQ9HqxSX6vFpBrEo4a5vXbx4z09NQvFPdtmngWZ8euNA7F3VJPUlrdHaa1ADegFVHukAfbVXLRwxAPQV9D0CpEFxYV9BFdi3WAEjDqB-qkqtItlr-b59lgOWzuKwTD4voUoiueIKsjJkaAya4KC1FCjfaYBwZbsgwOtF3MnSfQ-vQQVaVhGLc+sdkxlrvK73LNYA9FJ6kb2Ax5Jh+cFYwHMDsCCnd+8Y9WQzkvKBhwxtiLqIjplVU5EaBVRLTNz0DSJtwpYGu01Q8A4xCQNSlBjmfLtdQFEKoPCnKEzDUmYNYgVNlqMIgRxBDuKoEsn0vDtAcJvNiKKjvJltA2E+OQdgEERgLQ7Vq-K+6gJW3LYl1rx3NgtHzvBokCMoAZo4JgDeB3kdcxh4vyrPcJOuYmQwYlI4dy8zmM+Q4COiUm8DqsKyEVbheMxj9TNDq5bLdveRb5R8doB5AYDQe0p92VKi+6o-9h-2NpvkDgKQC8AP22uKduWa0WEBxBXl0AQgkkjACGPYNtkVlb5FYlXll5ZyHyIUjyGOLrH6j9oJo7EcwBKHSRgYCCpfkRIqgbcJh1Pm0kicx7-DinVw9gz5M6QRd3fipDgB6ELABE3c1sOCcZP-hgyG8Nk+EEyOwdthKqGX040rak76XfMInhDAmO-RW5AIBUHqdl9+QVACBVQkXx7ylkV1O2pkbZjrIzaDd-+3VLXhtMEIMULy7NCjv-nyn5KmiBUBkVySVZF9xYN7SAcgomn7UqW5zczBe5PohbAUghC2fhiQUlVaW7vCXB1UGqaBAUL+ZQch9aIT+SolHeM0cDlsecnjAhwQAbrz7n1CTgSDWUzhFh+G3beiSTChcnD68ULvIO0rkUJ0bG-5jEFsB-Pv1jii+8C9C42hsog4XjhC6R2QAhlILxpnC7jUIuVayAfF5JBRcVlR8rsrR-6YPj9nOhRLx+7pCcaj5EtrLpqgZEyQhF+AajQ-BqBJur9k0iibOweWcA+SuXOEXJ8BkRS4oicQrsITL0BVYdyZhEYgK+DsnMve6IsBuMIHucTaANkLkl1tHHb1B5cpLUwCZAAAsDr4gBwBPwtPQwxr0178jGjYtBwAyBvV4k2QNWkgnr1ArDaTAeAFo-9jjojXsD8gCr6q2SohyHatNFJRBsACLD-0KJeXkCcoJG7QWShjQqQMkL5EicdBG1thBaNiOgADSdECndZ422cY2mXOdbs140uzVQuZNca2F0AqZr3H1kSBNyNdHNbwmr29jMeKwAIRctg5HHbNrDxCJ9KE3QgeACWSMpluEoVJtaOxGolUAzTsUTXS7Hpd2FmMHoP4dK-r7pHOlqtJMWA12fyTSXMLwPUnyvfBgb3zMSJXC1TK-50WnTD3B0jBpWZUEjpDHVUAP3a7b7393yL-cbu7wfAQgGUi88NljQLcq+tetpTZ1myjV2eRaA00BLNAnd-L1qEe92qKJhQcwQHgC6xefVUZ+jtNhlEhR67FXsuDt5ADMe9gLkcQFUARNcDwfig9Hj8N8a4xaDKLF5CvqLw7RHIeMVMih0gRCexOoZRTst22934xOwno4+-Ew-sHcOoZvD5T44oKdZPuP0T-J-4k3IRIuPQ4Jh9mMUQVB+tBnxoixNZda6LP+QdV-SUWezlUoVHaMUsZUeml8U9b52RfYnmKr3IzHVeHe9GBlItBZL2F6MibeK0gwaxmyDtXPax7bjy0GHd1D-qdQ8Q3gHjsG-jc4VtoLTM025evEzOkvzUteLAGS+Pm6A0mzfJx-1wEZjBFbtHBdDqY9djLeehlkFPfs5FIvIXSlwUGaCj4Rocg0V1fmvBO0MTHELZ1tAoArVXAVQdoLDN8j4lcJNkSwBAyPecdSCZd8gGu4be91Dva70FDjSMocc8v3HTEEN7DPYP2PCeyxwcmNcHuAo2LS7y6Dy8Eg7Ad0cus0xsanHloZL4kCWW8e2Fb7a7895j3WCg5RgRPSHIq4UxOobboOHYgbFhgpZMOhAqAK0EKBw+UsZDyAAAFYsfxWT7ZhirCE+ssxPkyEbHJ94hKfKPm6P1vR+jBTYSP5n+-Uo5VB8+EnZjsgjc+yOzNIkw+Agq25gZ8ayQE7wy2l90gP5mU3eR-PrNQRKfzHwTfJJlhphz1W88N3oK-gPThlk1UcnsX3qyV9KOE3SpfGlnMIfD40PwyCCEDy55i8+AOUb6aDeAXpR70lAKeDoeBdSHhdVpq3Pe1PLLoPgUBdDwg0gNzZwRYFKPI7mviXOLyl7PSj-XgXfm6a8OUq0FCBDkESQaCltOrqNLSiX2ODSHp8M-O9XU0HZq9sKTUqO+sigHZ2jgFQx8qR3rwQdwRZU4DYB+71TnhfjGJQiGBq5zSchKXFLJgOIGjVKqQh3WkoV8r34QNHvdlvd-rJL5XI1OL7BethAoSQ5dzlfWnLNZr9-aBh9-0UaDu3APjWAzd7rQMC245tfG2EY0cynpH5DxIiD+w-uInLbCh2Wgc7DKndYKcAqnYh7bRuFuhm4eLwJZYGXnWXg+pEcH39rEft0Pl7VDV1jtIAJUV2E12MPye40KBSmGw68FTB0Q8Aeuz-tnSfgAEY4UXVR3cW4fgDCYpkZ+DK8rVOANXhFAVgEV8TjAlzWhLUCH0XN8KBcgvosAqAGEoUKABjYIM7CgH6wh+FZzgpc7WkQgxKgTEET80cFdjBUYrNLFfwpONrgZRgyZQPgw4OUj0pxfYLgPmh0ecHQDpWuIXHdBRTcKEUguhQmSECB-PAJ3loGPp3k4VuP6XhhCGcbjEwvAhpgmd8IXRF-cGrTEQdV-cNgAEgt2OCg1JWKNYWgpfVeYVdAfJfQllo+hHvjP42AOGEKBeiM9mIg-yK2DSx2QLIPgBnwZV3+Fz2K5zXEkEQoMyCj2XnloJcgtsACUt5WeyKCj2HAjMBygvII-0bVaDT09UmF2CKE2AInAnVASLcBqDWAAAC0jHZAHxpRgaYNg1mgCYIWDkARwm81iMFYKvIvOOBXdFj2WV1G0WEQzh+ZCg4PEcIUkS7Fr4oAQqROC6gM4MrwoIX7gTofAWAQK85hTwAwABOITggxcXcThNAI-GTjk4h5fjiqBM3OYHl8z2eYlMBQQluD1xGkDAAN9Z7EqUxw6ZBmTIZWcRQLxRRtIcybtbCF01zl3TJEJUw1jNJz6BppCIjlNcjeDGXMIiIXUpDHTL4z2VPjM5XHtxDRonCMcQtHBwNRtHIzh0CIKzlvt01DtWtIxZJnRE4QCWexz0lHHGHgBehSe0+N7pI-1sIc9crVwhj2PwO9Mz2AIW9M8AHfziBkIX4204NuKoA38MAHbgoUdiBDjOVjzKHG04m2KUAxgBwQPzXsmWM0gT8KQDUXONTJTbm6FHAy0OZZlfIYQyCBwVrkKJ4idEUO4VqB6xvElGW0BSIag4MJK5WuWt0MkoXI629IpZGoFOs5hKlla5UIZKRNw-rAIFOt3A79hugr0P32WAaONjgeDGRFPyModdMjghobvArxLDj2V+RTD17dYRDBTAJ-Cysd5BL1nsDAlULDg-xAY2ulhEasO+NOOZAFu8puDbxQkrOPSBs44AOzg84ERSnCBtASB-zc57OdcPjC1sErgrYWdFCmLC6cRVlzxlWAEENQFpVeQCBYHTCz-grYF6QmDigtkj0gIiYoLXk3wQiRdh3NHzj85EaQLj7A2ufOFT9HAPLhCCouSqUG5kuYgCAjauZkjORUuGIjbIII9-DwAJ8QsXbghfOLn6417eGX0p+go7GDxzxS8BnxIRPk1MB6hEPDGIhuEbgGwfAhMUm503P71m5yceIBy0+hfLVTBCtUcJfRKtZhDpCiAQbQwB+tOQLLFRgfbTQVNtQ7SIirtZiAhEQQePyi0Y7SEkgA8kVJWJltHZQDLNf8AzE+R4gOKQZtEkQICGY3ANvANBTUM6Fa9rkbphWY1mC5gbQE0ZtFTQqUdtHVATmIRHOZNmK5iqhbmSAGCwundCBqByPBEQWYnmULFsgz8Boy-IsyW2FFt-gIZRLJN8EcHxwhnD8gSAksTCHlUdkEOUUJAoByM2YAsFyLNA1CYLE8jBHWAAuZfIm5juZDmYEDtFDEdoBbQIopJkN06Gf4AZsYrWoCsc6qGpAHBCCCeAIcpNd0ACh4IcZH0dUWHlBvRDZYBlxVRyLMgcB9QfKCyonYKxBzY82VdGrAQ9GUmWYCo8mQuYAsLvHLVFoc9HKjIAU5jlg1AaqOuZz0OqI9BWvHsKmjr0ctQiiDdehg6i9ASDD8R56eOH0ByravXz9QEBQj2jVmA6M2YnIx1DSRSEC8ggQKUKlH0pSwZZHMQeAGIAqiroqqJ8jbo-yOCxceVgAJQqwCKM-l4-KICEA2SYUFVAeOPkASi9AMWD-clEaBEzYkwC2hrEoUFExeRrnYkAAhIQUGMKitmaVEdQSotNB5BTkXZB3tiACoHRjvIy5mxi7mBlB4BRY+wCJjxwdySZp0oc4yWRuoEZySBiFZE2iji+OoFmgN0PqL3hqFC8G4o1Ivk0TwQeLVm5IcAxlnTwbYiXDUi5cGbDtjoqTkmzsKdQyzAx6iYn3sp3AWMmBIsCNO0h9sSX2ILwdiYvGbkYA4OMuI5hczD9iQWXQjFC8YCklcA5qEOMK4YgTwAAhWwAQJ4YdiVCBhk847cme45hc8PQlFcEcIc9bw+8K8BtNT3yR4qhEAVqFE8Nunbt2SP33wJRRTmUQ8n8NFmdiQAE4CAA")); })() /***/ }), /***/ "./src/js/built-temp/base-ru.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-ru.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYgFAIwgWRBAQiCA+EDCAOEEDMIIAEQQAwgYSYEEQUXPFTRgVhBA3CCAZEDWAmEG1hAIiALAjCBypgLhAwgFhBdgeRAwCoxMA8IAtFTA7CAKgGIgUlJgKuJ+DgqAvCBSrqHiloBSINoOUtHasa5GKqaW4rrapiq64oBsINGA0iCAoiDmsoDCIHJg0UqW2iq24hmA4iDR4oCcIGC2CnI6XJAANOCEkAA2pAB2GDT0jJAA2jzIGAC6wADKVACiAIIAsgD6J6ioFwCSZycA4kcAvgD0dLDkiNDvcBR4BdWJggRgeAAzLjgiHrd5bXYAHQWzDYnF4-CEYkkskUyjC6k0OgMxlMFmsdkcLjcHnE3l8AWCoXCkRicWkymSqXSmXZOTyBSKYVKFRqdRkjWarXanR6fUGw1G2i4YEABCAKPxGKRGBT9HQqfRgIzSeSmBKiWxySo6vWmeq6erdQASILzXE5XPUOuI5K7zFYbLYpBMwIB+EHEJVMDnDoncgbAARDGhd0SqtR9Kka4SMXGRgHwQSSebQ+sD1Ey6KTdX0qRPhpQtcWNSpGhSeUM2BzaUQqD1livanyGlRGcSAORA-RTbPVg90JJYm-Uo0ZCqJhzZRIOayoVYA8EAcLU6wYy8as1t1Onx6czCmqh-annE6lc9YkYBnkiMTcsC87pkUKidUhyM4XZPko6wAEY7G0XpygMQwjDocKQQAhMigBIIF6xY6q2iZSB2IFhIWAE6uuYCBCYMYcpaCgqFohpSJ4oRmA0VoqoAWCB0pY6SAfUtpDH+VT9MGfh6JklSDMy3EKn+Wh6KE7qhgUjq+oofipmRFHiMaoTUQa54MUxLGVNOs7zouy6rnRYSbjmCyALQglG4koDFFKIYAAIwABwlhoRgZIMqlar4rgABR9ByXShAE-SePUbk6ioUqvjRlTIQAlIekiuGGajiM4KaSFGljuC4Y59B+CpdDo0RuQAtGAMatp4fQyOIpgJrobK+TE4ioQs+aTiGwwmlajg0W5UZqPUIZDIpujykaRa0UGQwPt6CjxIWnaOOIYbzbJBhVGS9TRLYTLBkoMa2GUpgfnNjqyTtU0zfYGRRH5kiqYo+QximlStmYJ1nXEni2RBOy5j6DH1IAkiDtCuSh7QtJhyMtSE7Mi6yzDwcAYwshBgOsABUOxgIARCDaM14lqtoZQMciBPE6TgC4INo4jyGylZ-aYgA4IJ2gYM4QTNgKz7OKLEXNHWAgCEIOI1Ti66gsQMLgAoILtBSxMS+hSy0agaP0Av40LJMy50Gh4JDWniFEYAAGRgHZGRyDIcTIWAgDoIAoIadbE3XhSFuGFnIfRpUlsraIE0gjtSABMAAM8dgK1US2YzJvS2b4h4IAiCAFPoLo+Vp-lK4TJv5pqBRaGAzWRgoBgF19Vg+KepGouw3B8GAgAm5IA8H+Y+82O45jkHZwusNSKYiTlYUWTo8igD0IMoXOGt042SFPWmlSN9QciGlQxiOBqctPwGGkKwz2IxsSxa2wxlA49Rlakegjn1WM47AeNp6T6p+OWvSVFMIqUQTZQhSGrPvNkoUWiByLMGYBTZEqJm0CGYCxgQZSDSiXYWuYNS6CbCFNWah3BWQTEmTI0RH4NjkDvRKYtOa8kpm2aM4tjBKHeFKfIeJWSxH6Fgo2ysTaqlpgxaQuUbArRkB2eMUQsgEjym5ZiEo5DYJNszcaih+yU2pjITIRYfDengqMMAYUNEDGGpeVG7CwCqSDkoJRjYwAcO9g+PoagVq5E8PEBqXAHBcH4d-MAaskYHW1oAhqUg97UNUaTQAxCAOmdL6Gs-hhxpC1m43wJinIlhujYqwD4FDbUXHncK1RvTiCdL1AJxtSaAAwQauLU2qOBoa1bQb8B4fzxuDByOIOZhGUBaK0IDWzgLKXuf6q0oyeGQnPBYgBsEBHPkQY94brxQyO4sIw5BhGFsJ1BwwZXAKFsL4D6JZV7GCocaOmalmTiESHDNhu9IGH0NH+FQ951CdkNPyNsqQRS+lCGGI0EQVkZMBTYaIp9gVGmvmySeog-DWkqCqVmx4vwOH0OeGsKMrL3jHJNScYBvjwFmPMMI75PGAp9i2KQb9ILSxUJUXQgZZnvyHgI0upN1gAFdyCzAALzEFgLAVg0AcDvHeAAExxgAYwoJKrgcrkDwgWAANx4Agd4AAJAAcgAdiOAANQ4IanY25mLBDrmEwYAARWV8q4S8tmF-GphMnWCuFaK8V7xiWktIIq0gyrwLvDuPsAAigsGVrAABSqB-gsHbnwCGPtKiOr5S6wRXL3VCpFWKiVAB3QtXByDwEldK2AAblXkHjWiDgSbpb+lSGktNzqYlur5R63N3rwSwGINy8ClafWkHAtAVg1a27oiTbUlQYzBKTJMU8DVWr+1pRbRmzl7aBU5q9RKntfaB1KqHSOsdNb24YneOBeYwbkC-AQNW74iAUSzEQLAPgKJ3gACVTg2rOEcLgyBJUQzpOIbog5QxFm0Kkuka7+6D0-pMaYRBpXQDleQSVAAZHgCwADWaxzVSEtYdamdqUPyrAPVbclgYa6m7OShpAxkKQGmK8KYRAMBXsQLMRgBAZjzEQNKpYaxPbyHqH4YYCGCaQHgOQcgFA8MAUsOJ1jMxe2kG5dAR9kroB2vVZK6TawoDKaQ-AGVWxOP7HgCCH4sA5N4EgOMIzTBuUQghDwWg3HEMqbIOpzT0A1i4cc0QZAPBSVvr83Zs4EmCZQHAiF7GixwtQAAEJRck98OLYW1hUCYwTFjnnIBYdcwsDV2A7OADwiVLUBX3IFK-gTzRBFjwAs3KhYkqTgYFIGsa2lCwjaEnNEB+UoAgOEq0QWgzXFhafa51uzAAeWgAA+Xr-WHAhUqKHFow3RtQEa2cLD3KEDTa63uHeV84o702woEbgWoC0D2wsA78BoBHbm4t6u6Q4prY2xqK723ICNa1Wp8gL2oDW3SMlRKl3rv1du4D3lz2OtrHm0t85WkQoKG+1tm7-2FjwBtYgAAniDyAYPoiOEyIaKHf3aD44JwjmbUBkeOH8iFZwmPfvY+gCZyb0B9hkEoEjrnLWtMLZUH94LD2EDPdaxN1rvP+cMDmxLx70AFutlm0Lnnou-vefINLyV92Vd84oIrxnuvVfdDALN5XUu1fU8N1LpHb2r7jE83lyT2H4B0489FqriBwJZZOCl7HLXvikC43ZgAwlQD96G-ucdN5AE46HsvY6ezKtEawjj7Ej395gkJE-7C1XcAAYqnmHMAQQytq5AXMqptzZ0AKggcycuEFeMx5TkA9PIFIElx9uO9c+5Uxq2YNeVaU3ELVFGtFnCVYKwsMPaxIZSESD6XwWKNaXKWlIEcJlEhNlUpYUogZuqkR+cOPwoLoy0tb+7qAN6sNnHgA9ofRBWDPoJ2sWpHN1xz5lSwJYElUgDANYaWEMcBcQewfwQsDIXhOfLYVgE3fYRAVVeADAFAGvWpTwMMUYOfUgdgBYfYIHavLVLDRPHpEaJQOhQZfeCZUZbrCZToKZRjRzLve1NDTDHDPDC1KQeqK1OdFWcBM2aHSTYgElVgKgH4J9F9GvfMe8F2fpEMCDKDaZOfcCWTfNLncgAAdUQHIGK0Ezs1qU1G4h0EykoLyR+kKTckLCcAoXfGbBdFbGsAUFEwgzdmX1X07EeiRi31Rh32kHLGPBEz8Eekj2IFkxq1fFMmUDUiOTpC0Fo0SlxDgmNCRjgiDmVDnw01QPQJq3Q3gFQIjygFiV8gpyt0W2yJQLQIwIKKKIAFUcMFhSB80Fg1hWYUl4Y51GgtIKc-9FhX0HtZCNAoxdA6Zf9WDcd80ngMD2itINowBv9FA58b09MktP87NZZWRdArdEADt+dapsYcMFtsj+0S0y0NU1gP1S1y1b9O9pVONgDEseMiBwIDsbMURX8ZhSBcM7MAB5AAaT+z01HwQDWFiSiHLAmIrwz0jRJSEyOSGX0D+2fTvSXwiBuj+xLTgD0MT1zAgwTE9HX2ROx2xPgET2lmsHDDoj+ywFgH2FgE00eNxyXxsC8I2V8LHGnx32BJJXJPgBmJqzWEXjiN32iKynJ06hHD+3VXgHzXqNYElRkPRPeQfDX0NEo2nkYTzzIHlNYAwB+D00S1r0gJ+1IniUdGTDiB1JaIBK91i1aywwwGNIGjNMNFiUTBKm1Ld1YIQKQOqLyPgCOBk1szq190gFfVgFH3kykEU2cmwO9F8D9mtOxwQFWDs1RQXDrnDHogTNGEAnmNInCHlhiEYRGmRVbwgDvyID9MoGQNyIwP2G5RlWr2gGeIr0jOjM2LlgVliDNHkFATzKTPmL6D+zTIpJ7NLL7PLJLGrG0CdHCgYhwOHJ1D6Fd1y1YMDPQ1IH4xL0QBC15VqxeOHyjJr23AU2GgCBCMDDHK+HaLtEhJzOCJoVCKLMnNgInnLPXLb1YJa1c3IGQHrJqJqxtT5LBLwGPKIE7NkOthXCLDSQfLrkYQcw7LvLszQibA7H6HQXSUkDKXX0QqhMHHfLLNxEqAAH5KywBqymAAyMDQLQS31gzZNyAvioKR8zyLylAsyZ4UzUL0yoBMzHyj4eKrJizezPyyLvyqzWDsTGTKBriABHblHgc4tiqrDi+8xIMZURJQn0QkjoW8gSyANCFsZoNmSwHS+8cDfSr2IkqyXEKccUucNsFyTWSnMxA2KQaS6i1g0tDVO0gnB0gTEAiCjszSowy-PRac6aRQJcV0XklDdohQMoRic8XZEhJ0HeKQII2wPoIaU7SoACeBNaGhMcfCx6TbFoboOiYMHK0IFoVKx6AAaqOBQwAG6qRXAHwYCKyfT8syTYBArgqnToBI9Fh-yb1X1Fh1KIyIqoBKSNBEpYqvSshEqZU1gKCVAqTaJ4pcgpQ9ZzFQgVr4q5EoDag4iuYQZFISx7xdBV5YgRwVR8wyg65eJiFFIHA4K5AEKfKaLIBPcgqsMQroBriudYA-jfiwzos5rTzQCdqSxPTTq+LwyjSNqMzPK4wTreLXBtryEqgdpyUHwKILkRwYYpALrqreRBggV6g7qHqd9GN+rJMIQkBYBDywb0sZVpq2iwrwzoK1hx97wp9t9Z9sc0a1gMLFI94Yxywj49oHpSJJpRBppZpAZTomQTFZtWaX1DyFsMpVoJBFAnxUhoxpp6xjQOxhbuTvKwApaVkfxXL2TMlOTFp-Cxw3wXK9p9A-BCzDBshKVzAgZghnBGImaNz8tGsgKtythLi+aYaBa7M5kDI3JxKpypB+h1rJamwHb9JCxSIJADBOhlA9xVASLpyyKjRydrbt9baXq3rsKYxgxRLzwMwHkVxH44YzQgjcIvCCK5pKEuTt9X4qL-ruVFSZCmzkAb1yANjoa0t5rIBmYrZJ5LAtS+yWCK8Ja7N3YOwj5oDor2REodBagcCSqpElA7o0jwxCg9wM68k-BKDywcBR7WDx6DT+Mns7gF9ZNJVmyebZrE6SiEkrTuqaCQFN7Ub09Jb9qzBvRPBjJDbvRwk7pkkK4ELgx5C4owA5xSJwFvbfbVzMLqRD9j8CydljqQHqbyMrc4BZMlgFtUUvp6gnQzxihhxmQYwrQyR-Q7BaVZt-gw8GG7aMqHBhp7RLTqGWgdKCI0i4q6Q3bqgMhWx6gZAHQRBqIWg-rWCb02yGL+TxqFhJrAHF78wvqUY0lDQeLtTxboH0KzI65nBHbmp2ZJAcpCQ+sTEJBegig8BZs5VuUF99a3YpasKcK9BtY8KHxHoVAOxOpSJsRKLmaZhL1uVLNyAyDoAdVSBYBGj5gZVPdJUTG4a7NG84ZzKBlLR95xAs67NAByECLB0DpjAG0HKaPAfCqYgY9ncCLAAnPHyHrjtF8n8j31qhco6aROkGqG0fy0BpGqWGgG-rDz-u5rfWKa7KgHzEKDUnCVaiAhqqAU6i1AAlqagDQhEAkAklNHo1aiTm9GcBqtqAyuOZKqNvCUSEKBkFXhHFTsJFCWMEkAGfzgpvHADBVDQgfHMq9CLvEHMMSGcACFwtoaEYwAW2xSLExVMF1kJC8sRripxoEbocWFReQlm3UIWzJfICW38dID0zABlWfTbP5QAHI5nganTmWFto9Y8BG5U9MlsABqMAfMGMcm9cPADCrhTkTqDZBSTocA5M1wDhaxrILgSl6lvl+Aelxl6AFltlx0pYTlovUvKgXl2l+ABbPACEosOmG0Mw5yg-DUQsdxUidZToGFmRNkfoNV8lq3TV7V34XV1l+09lw1hbZPU194TVy1xY6IFGFcgcKUJG3i38J11pwpBBp5roEwfoIsdSGeUQH1ql1+-LGVEtGQs4PQz3Vi+OhekpwSrSambwOQWwIsU5yAFWNhlp2KclDsOQV63Cs0LxYMK6XJK-HaYqIKQ0DXFF0XSAxQOGPswl2dqurUaRBxUaEKDiI2ppcdlQXRJ2chxN2bRAMACI+ACEflRESAbdPNd4WU-NaTLgCdDuUga9olPQukq9yAC4S9R9bDa9hbSIdofQARxAfWscjio4W4uzYRKIY5I96c5t1t5Y5JoLKt6TUCnvTDYLU3SCqAbes5nO8oR2lkKIAuvOYumOTZTQWoZD-RKuq2yfG256tk6wbwjfeaPw2ifFakNoP+FO9Sej3yGZyTXRsag7Qx4x2tk8jZk08x+Cx6D8fSycdtqW5T7QAIZxxpT13hLxkDDIbQPxgJoJtKEJ+cFGMSPfMACq88bEMIOJgcJJiOyTOgRAusst+AZ-ZgHJ3Q-Qp09ZmvOyWwasRMsIS0dISpGMNTpsMhakoI4QEL5co9s-BQLKnBjUHeY0Nd4oCL6IKLhQHcFw-uvyBiOFaz+z3OnB-eQ0YpQ6AsP5ChCZGsQIdocIVsBSIFypQYYqRFDkKIXJXCEwDZewdwEYDOvoHtgIFGK0scMi8On8-LcTyPA7b+6AZzVzUzZ-WAKT1S5AQL9EhTn6pTyoFT+oGLip3O0wMMCuIi3rNoI0YhKdi5neD58afQczksSzqoaz2z26U7zTxNooZztvDvaYefQMr4gGkNg150v41AvlQnWanvVAyt1gJfCDBwLUG6PsvPPk7mpLFS2YEG7O4rw0N7tQEkivAEVgVAZ9avGrBfVkvrRQYkh+wsRdieLEnJmQwnkLEK9ElGShUidx-WVT7Hd-RAavM4blWYV9d-GCp7qyN1yjmp0kwo6TLnP4jJ7bl9NZ2DyDbfU-Dy5NmxrenGf3UfE4A7UgbXngXXgBuzbcC0XQEcGq0idwCQWqXaH0OJssmBfFhK1M4A9jeAZdIpuzfEn0XZN3qyLVeom1P7SX6vPn4ngL2DtNl1w0UX8xc7kPcthASt8gat0AiIcjw0YT3k0EmvCEuuGkiX29eAdDW9JLWYNJsdMgmBmMZ7nKW+vTysJUMoFE0gAppLElWAO1EtVZma9CmP93w0WUHNvN6mb2LqLScm2wJP59BYAffYfNDVf-fYHgPTdEmAqFZ1xqTh8pAm1f32dfuwBQP7GVA7CzUfaf3moj2y6E8MuVVgAnV-kzI7ygAcQFWftJ-qPj0IAD3+eGUQDAXr4V5WAPAdgMKlkKRJ+Yj-TnPv1gD-5m+BOTXhj2j6u95+woTQCW0kxvF+eTpOnlL3gCM88OMJAnAy3gCp8QqhqPQjwEfSwBjS6iJqueFmyA0lsCkPSn1iIG+gdQNgGIBIGzA64cmgNZvuBHhJ2Y2IRzKQKwz8YCC-shWUgCsC4HqUiAo6LzhHwWqZxKe22IgFISwBrB1QKgXKPlC543Z9BNmH4JYLsyABSEHFj1U4YZgnbLjjuAIA0A0mWXEYMgDuRfkfiJxMthQq+4ay-g6AKgECHc5WsTuJbMgnCEcJcgtgKIdEIKyxD4h5AIITajUyXoa8IUWgDHDSjeC5qo+Y0kzl2SdhICVFKsmhygCj4ii41ZAArwQDZNX0m3PXjP3nq8YNeswKgIvVKK9Fog07VoSShOIh5A0nQ0tAiRm6ZA1eFeQJvk2ww6CYBnTSQLNhLT5o9CkqBbJAxhpvFhUiwHVF8DqKKCFqt9TuvfR6ImAJhZAmYM0R6E8AM8PNdsuGSmIKkP6J-DMivRLBUNpyytc2r1FpKNlqiwQpYlQXLqFdnh+gsgOjxk7sV62kAC0okjWrY5ThHxPJiPyhroiQG8A-mvbxrYlEyiEwiojMPCrSZ5BJKRLOsBhxEA7glQu4CyIcFQA2R7IpkZyMNSVC+RHIyAIam5HRCoAwokUdkPFESjwydwAABqVD5RMOHYNjhvS0Atg3KZAFcOKKQAM45SSnmAFoD+NeUJaBfDLzl5LYQo3gELv4gRFMBGSr6OAO8K+EJ1F60sGML4HcRKYt6L6RAEQV5Stk9BdowEEYPw51s5O7gtkCBG8HGYUMGTVgEAJNLDBEUOobaO6wrDwxhwNncWM4HJrVBaMG7KutUCsBZEeRNFSTGOlpbNkFhKIl0WiMtgpIwcUYjkTGLLZICExrpZMdYWYQNiHAOYiePmKMjBgdkRAhYjWELBlA4oBnJpGg1SQAsfKLnbISCR4AI9qxAwkkWiKITd8Z4Kw0US2LjHtjTSnY7aBu0QadA3mkYaMCVGcA-NaMxoIsZYHnGg9fcZYqAM0T5xog4hv9KscEMAAkIEZBaZtNruGgToh2CqBZDJME6OIdJgdw14NcCaJ7Etg4Qu5bRMAckoMWdJP4X8NYyAJLwJzVZMC8gQEUYB9BeI-sFAtPgs2oHV5gh+YQ6l5TInj84h9PVcZAA4hxttAubK0GRPeIJZAxkAUPPtmGLWwCg4xKnqKNQnCpRqyVOiTeUFGM9uUktPNnFH9pV0YC0pGHO3gXFQUbeGTTjKQQXzOiwxNeZmPUAqCIxgMMMfQJRU5y6l9JeJQ8YmzDAOAOgGocXhXmIDH8w+nfHeoiRq4oTUm6TMglRP0zYS5UcAUAhIAYjRhkSzQyAPsIJyIFMms1eKYlIMlrAeYIwFDpUB1z9o1grgwAAgg2cdavuP15QA5kbEHmDdWE5OVPaTYYQRfzoi0ZXolMJyrmAqnikxmDjIiiqHVbqseBaVUwPwJh4hUUcMRMjom2E5V0dAk4OGDTQiAEYQggRUIDO3oaos2pPMZdqtNGn74jQlQMns0lUa7t4YhUakONLkTCd4R+fNmm+ibItknsWTHJpCHeF9CP+kADKS2yLDVcdiZ00TjMDILSYper6VAlQB0kcDii+HWGnJ0ozKRce2ODyWlJrFEB3IFwZGV8B+Dc1QyJpBqXwKJYMNEuesI5EbU2nEsls9YFaSTI3ZZdzA8DIBC0gUDEzhGtUidjVxaZtJKhyMmOBcBayoECcmM2WNyE1imB8Z6gQmYYnJkMNF+HEosHSAZmot+k94ukKS3JbqszGLksTAoDwCixLKYOayh+H2mSzOJHIcWai0aqJtAUBSMVqB0EZbTq4RVScMcPDLIyAAzBcDc6aZNqL4Y2Yw0byyylsx-UfLVCcgeEWEAwfpnnALjCzFAxycpNpFWjsTOJWkPfC5WVoVhDQrXIInOD1hFAi2FLclqrKTHDArWfbW1l2y9nGsy8vsh1uz3hjK8ZQqvDRgTOjm+QLoyLLaR+krlMziJCgajHg2maNDqKsUuVPMEHzYS1KSggSOJFpIlpn8QmUSIJDIlt8a80sKSH9jwF+p80awQAGggegEBJnQl68oFeawP8YKCkGTyQ8BOR9GsGziAQRwhDM+RXnzQeTwKUAbOHoHvnhlAmQ84MVfPaDkROw887EfTwJENNg4k82KROkNT29H2ZIiGUAx1GlApAf2WgfGLnq14iSO4mGr-wJyBU1gIAlLjFNyxg9ER+BX4YaSexQ8FBcvWagsFmJKDs2Usq0MGF-hxMDooQe2GTBOgZBywxUtsaVJ1EmDSIho5-jJm25mjYAS2QAEmEBo2bFMTEUnFYpEuEKWuNfG0KoAasOcKvB4Xxi+FuopaoIqNEiLTRsvcRWACkWGjZFxi+RVpKgAVjWy0ACgIZJeGqKl6IwTTsMGDBoQF2ZZe2JRhSBpAPy2gLRQmN0XRTpFwik0bADkWmLpFFi80ShJBBkF0+yiyADQqFKbEiI-YacvbAGh-gvRUDWMbwv6H8K9R+i8JaIssXRLzFcpORaPSIUxYieJPGTpAEoX0CoGEIPYlQsRkqK0lwA+hZxMqFo0SpRSsmKwmS40JtoqQ-Oog2LmPRQgorWSEnMdZRUs+ULd1voE6CPjNJi3MTlhiUUQy9M7S4xXxNSVBcQuIspuQMvTxDLXpchGueeBaAOAwAdMUoIMESgbsaUS0-iDRAOih0VoTMoqCzMsRbh+5L4-iSwCwyW8jyPIlJc4uC6NyjaIUQAGQgKCG0YKMGWFKbldIO5ViyuxPKcqcEN5SxA+X1Uvlu1PQL8sWXMzSIQKlUDzBI5uRe+ptEiBE3CjhABZp8W8WRBQT6BNlsUwJnpnIAGk1MrWX9uP1moHKOlrS7IScrWAcKUwETS5QUu0VFLy4w4FwBMuULzTqV7QTMHVOti6cMEVEPpfokYibLUypImOMcucVyquFhoNkYqtbHKrMVt3Jxgys1WvlXkOq1GHqseU8JDVOkY1YoFNUgrwF7+DVGiWwkSqjlXSmFT0sgDMK5IWsB1dcvSmNJ1awMLoPwWpj1Q4qk3PNp9BoipDyV20c-GMibAW19qH4MtWaphJzDAZVquNfzP8WhJk1GK3BXSBDCEy509UAILChLW5Bbm3WHeHUItD1A3Yvi9lUUh1Bxyl+eIY0KThrU-8613NWqFhgR5c4G1S8tqM2qTVoqrlbauhdgS7XZrjwfavatoEHUnYhgy4e2WAAnX+LXVjgadQbIY7zr-FvK6xfxPeJ7Kt6F7SVZuqsGacaqm-PdUqoTG-xbKx4-8UOCLDVAsusQR+qEA-CpIq4iQa7gUC0jpBkUrckmdOgIb1BXAhddZevCvXnJSI9UEsBLAkBlBMWB0iUGKXSAKBKw3Y9BgC2UDEJyoiRZwKS2tkkyQV2OZSvxgA0G8-AwGkxAABYMK0zCoaBsdXgaNQkGxRP+PrCVgQExYMjbbS9l4a84fgAjRUx+QaaaGJ0CsNRto2XijAAEdoM4DqpU0WNs4lcOvA42YaQIPG3GaixDWfrZM9on9W0v-UxqZV6FBdj4AVWyaU1kfK2IoBqopilNyiPVRDitivLPkzKHFWAAACcccJOIoAfhZhF1mCmVBvP83OLPF3c4LQYBMSUY5AqK6FeiqdWC91oUWrsSeOYQnJ4tWyAkD6GZQNUlA6WzLVdk9BaRctLNcGdCoC1nMgtWsExF5Djgybqt+62rYFpK1QbYtSUKbb1uy0DaPN2ymYDiQKY+aYaUazpcoqICjbIA960wiFtm1ga+FZ2yFFOsRi+986hXMAI3hKAJBYgl3dmNg1wbEUBZVnNsO4GpjCBCgMBBlViuoydhaMDysAIUA-CgxNtMlJbm5j22SYDtUq74c4ulgZLmVBgVtfNqgD5SHAaSbUKyqx1di-5lELHvUCeYyRiQHEj9Vtrfz7kF8yOmYKjuE2bN52NEYDbjoTFsQadj3McJTOkCP0YdrjI0GMiUC6QDoTCfwDZSUIDY7A9oZwMHFcaDbWdRQjZqGO6UwVdIYmkKDHDQjSaedfCvnd8pi2NBsqIuyDGKCMBjItIpK6XSMkfp6V5daQScC4BV2tQ1dRAQTSGJG3OKclXOykCFEk1G7QtB6jnS6u2i5KadC-FKg-A9qdh42hoJrapCqCMQNInYGlN7vvyqUWKq4rXbGp11-hud4evHaxP505BBdLES3dDsgxi7bd1sSXTTtEhO65dmQN3Urs93iB6dCOtLD8GYDiq-10ao7drvSn9aW2GAy7XJr4VYFXI4u62IggpTaBag4iLoCqFiRUbygXYgzS+FwhnrDw7gAdSnH43U8nBoIdnZAAjGxBywXgsvQmOv1VxywC5T8pMs7DTLJAw2GIMjAan3h3EtK+lWIgIZ+1OVwwSsKSGBQaAJo1IGsCGE9DDA5E-gZ-Z0GkEaTYp+6IfdjAR6C1zNxIhOqQDxEFM1gTMiZn5OxxTDZgxuSgM-0TylFfpRAffiWiH2HLDthek7Y7CLC6JfA4BwMDTV8jWxjdKqiIGqsfUizogoXfMsbxEBOwXYT1eHb5Xyz8ZVUj6aicCFkx2LQy+y4fawf91xrak7E0YIYnJ1T7xJNWhMfofjY8Rtoxhh3bTokhBEN2vehQ65wHwYACcFwLAAPhfSaHf1WBpRR21wPf98DTwZ-ADIQBHBXDqClWC4F5IsG0dMNE7YAGQQPRKz0MTCAZDIQQQzcuAnoMq46RzgwETDCfIj8zgVwCeKcP-VGDQIMtqQDbJSTI12h+I5JhO0JqoSETZhKkhMOLi5t8m4Duqrcj5HnY3hHg-fWxT6r6wWPeERpJVHSYsAMC3Q1uoFmhIOjwkowFkdL6TqJo06wY1wfTEdAQWYxm2G+vSAVG6lMAJwQTmuL7C0MjiyAHsIOFczv15AC4JpguAPpB92EuBRBsB7Tk-xyiC7kRuLpvhKmVoIIl7P0rAbK5FGroA-UU3UI9Ve0Myl7Jg1yA4NMKfwJXIyDTdwEUUgZFM2UA2BMgMYJkErKpbqs71lgBFqVsibC7J2mLI+JCwfB26jANmpjYNLc0LYYTl4zjSBChNdULmYut0HXGbBNQJ9k4V5utA9Bb7xij3bQNZ2NCGdFI2Mj7ihPuNoYLgXmmQvMfXFyditnPQJbYySoZ8-AR+SAohxw0MMu5PciJr7PHVk4wwq4JjVonN2jQgUqONrVnOS1JQetHMdbagc81ykHjCS5ndqdrFydA9Lk9tr-FNMn4RyFp1FmGF112BbTQSRIAuFo1S6Jtsu55QQiuhPKgERyDkCeNDgJAuQO60wBetUDUJUiikJM620pUx6zdZ8NpL1PJaoB9geAF7UETuiQlMUkUWwCOwcLYsxe14FpvqK9nCI6YrYTtgYAkCxBhgtp1U4GfVPBZaALO1EXJ0x3zlMln5RFZpDWOGn0aUAaM2Qz9jxnRcpOrWCmZu2PRJjmeyiMaGxCtg-VK0fBjpr01eyrsROj6MUFJ1LteNDDBbn3pmBqnJUFwHbSX0+OL0bzu639UaagAUw9K3yYjqslXp+L0gUKJrV7MSDoXBZwOlM38ccSy60NILRvYuE5C4XrxIEFUF2be2hAsGbkb7XklC7-ICaQEKZHRv6QOAWkdIYMJFBwZjw3IyJ7dTyCqC+zWTzG95cLv+3DhbmZFpQF7JaAiguNmJ+xDXukui7WoQF5wyBeXNgXR02MFAaGaMlWCNQLCibRwibXnacdh50yyadPNxmXGrUdNcEEzVEZBg4Jsy4mptMAWSWz225uOzfMGBCGibBSGdPZBdcQW5IAMKGDihMJPLfRgFOSl+1ZBK5L63yKSdznFtYpoFt44E1xzDadTNeG1RdvyVHn41GoGM+aa9kq15VBgFM4hYxa7Tq49K0wGIYkMJsReD29-eFwvwL9A1oCA1dxqXPXGwLmpu9FzPy0HcFt1psrSFFXw+BBIM2sq3ZaqtnnxBUgSQeeatOlbnA4l5QPaeEMFBH1O10iE1prAtb3TBKpLYGDdh1MYiOfKyJWaHF7SiwSncbe0eWkcnGqA0sAMyyoDMsq5wgufgOFozjjBsG1yQTSkXM5W9LFwRRc8f-xM7IV01qAMipDALQ4V5yo2lGcqsOXVy551rhjbgiRzRZcga82Tiq5ezhB70RNkOE0A2IvVjKSudxdUaiJSbTclsJSrujyEEuZgMwH1hOSKmUkhQYYNqozDertL-1XK-ytmOyZ+VoquXm8dJEXBLVUFtESVbK32rbLxpta3GfKjUxIbNUc87Va4V7XfLS2RKF7K64cSxo9XSniOH2uXQjkuSHm61fJRGAOeibMQHMs4VyQpbslOGwZfDXSYuZy6poxpTREcQj1xyOdFZbwtiT9tdjY83jbNNnnOgMd0QHOiNtCWOTqkcy+Sv2tcmyzGFktSJfChFGzTYQ-Ovbtl2U7agZFrSAHYGpw2aDE133ajfjVAbg94mu2jUCb3LWk78Fiq-ZbTtxmc755iEw-z5MwmbuIh6PQpsB5nXlNCljk6poB4Q5fAlcz28dKHEDrJAz+2rkYCp3N3JMuV4MxNclQa6oVRVwWlsgWgRnS9cF8qyebHsE2J71NznSoGA30yLbNDGE99AKSpjCz++ABHNLrNwsXCxUEBNFvPNY8yQ-47rFpBIn2F9rRRn0CUcI31zScth9ozvdyhPqT7I1oM0zvbvcohN6t8M1-b1293DdA93G6PdjPv3xuW1z+3Wd-scn-7h1qPW5AfBxMaTjZ4iImzvgJ7XwSexpinqMin3dLo18C+fpcHJK4Fo8AWyrtMCP7b9Bp5+6tfxsxBmwEg4217NijhAW2UgGe9w-ntuQSy7lauz1ajDHhZEP+muX-t8DSPzBcNiENPNwmd3pYw4fIHuAWJOR22sSZsEgiUg1VSgBoN2K-aYe6PwTIiVsPTb8cLQyKKZighEGqrWFrOTWnQEhaTgpGeIN43Ggkl1Dp7OQqkRWSYlRTQREzockDsGBttxzqolEW-lYdkYD1UitddKMQ-VMBSO+CMxR4vRAVNNEFOthCygiatu3UL55+Vvgo5A5Atxp8DueNCQ1pdbb0VvhuZzaBrhV6MrUiCFGtb9t+wrgbluhmDDCD5l54BBk6H0AlmpQvA0wMy0jyA2mZXoUASRGbM5z1WGEbvsNEUt5B2gq-LOxw9naUq57lcIstoAe72dsI5lbSjrLcY5HhumSL2U1oUgD8mmHElM1u1KooMmwgJyQMCeVokJywaUeg6+NIAam9L3j24WTXuEUjE7KO5O5AB6RuQHh5RI8JCRFNShfTiDVlTS-JqDAogagN2K2apZgB2zeAOZJIwqbMNWGfEHUOlzboZjO6VCdZ4SnqimUcImaoqGglcDbXcglcn2-CcUh+AbolKhK3rfedAjJGqVi264-JeUvZHHjrzl48odLz+XdL8YQy9Z1Mvy43Fq8ZTDdhsRiEvgep+HKARVQiTiMH2K09oxCCNYHT-wjfjdxnHwa6E243AvUQySRnpbGQh1h16OK2MoRn4NqO3AqByoR0P7OpmkxLNpM7S6vF-hqhFgBb2FePJKmUNwkaJIxLUML0AQoT11b6PvJKiwCFuCOhROy4A9EBP3wyOJcEIYQ51OadkXR8sb-VZKaBNQz8FoP5IaX45n5OorhL85fS1QlSCAakZJmfSULR3kAFSvsAzya7oVXxtNk0HSA6A5ALblQMu6Hsz6ilkrN6+eFsSfTgD2OwwJ0FuYvvm3HEj9yqH0Ovv33Al-CIpFqjIIKgLU6uDRCdAxguIxvTldidojOPzQsJ+cmINWe3MiS+sNhOYWxAMqRgLYTsE0GxonW5INVBaN4H-CYfEOcQcCTDRQycZyFXS-QePVDvQAb0pKPDMvDQ8zx1lGdaMUwBE-aiMpkn3gzJ7uNoFZeehUAr7zgLNiWhn7GvLnHrgDBlPfaBR6dsIlUxM6pY6Y9TxqOkptCYhElBZhRAaplxGqOeoXrgV1NSw4Te26RF03eB1jkVM-ttG6BeeVwoSDJIaD89KAQo7rdoHYALBFUwEQRXIOIe9AtBsopZAwKS8qFc4nPQM1z4GIE-sBnj0AeYAVqgDbhxPthGeKOW08wAyv6UxrgVGU8loMAanskTqM0+aPdxUAdpeFLszZxKgh1ZT+t2K8XA+vieSr+UUzmEh+5TQ58eQcfRteL9MauBfPERQgbp9YWojls8egItKgmQu2vtWEGpJEEjnG-jpsLLkqM99Fz7YxZZlHgAgsoSWP9GTcLeK8EIWXrMFjFecP+7n0xhrEB2aMAvai6kFQyuajRo+WKgbPUAh3xAf83ydp4l3FiTdGbU55UKmeejhR8XVddItslro56YAwqrTDLwQB+7xJcCjCnP1ITH3ZJW3iPZAFotGg5+ywl6yDf7XtRafjbIWfzcFt9V3v4ZZAOpneGk+C9D7xelT6IG4pRMB3vPvT-L1M-hxbvVn7tPZ82EZfk4Qn72loE33shcCimN4HLIg+TKr17Zw1FQ+V0QoMG0QJ1CVbm-moG0bL4KO181ZR3KOqtrKspjpflP2MDAEKlAIURbfc3geQL5holpnXzAD9MqVW+DO14lEDeMjTFry+ExTPrLjRBauaxDE7kcTb3cSOBA6qUVQWZvYfCvc16m8X0MBwNCUrskSNHKjSY-BqNnAjnVyjg0FD-dwggYWoGRoKS1AE-ONFUBQSq500KcfTQ0CXnbPBh2g3ZtLqtGwL6Afmn0yd12Ne1OgM71cJr2uVP3hlOM8U6AGIqQHMS+JcCnmI0mohZ2mkAH-U8b8V8s++ge99qLInZDcm4ot4vaSj9e+KQIw1czntZtrOX1y18KHALngest6AD+L4IlxagOoAWwV20YHlAFQPbN+D9sbIGODlyVAIT6kALmNJh2SbvpHZUOzkgXJsKFJjDL2CyfjoqRSbkD3S+8nUDICOS1sGrJxgpZo6AKAtLssjBaEgjsSZixEpTDw+rEOTAu2uXFaCwOPvM-A1e4SEDqUwRJnqrBWV3iSCgeOIE25vukHkoAKQDjmLoPCkKGc6aeGoFTTcw-Jh8wXqV1K4DXs8lu+zaQImIT4o8Ovgvj7A7AGL4U+rogIpH2UgDjwo03RldpFKxhEF6p0jgTZQSBP-sLoLWLgdlA2AQBpd6rki0s8ybWKtKxA5etgVpiFeTmGN6leLRGJ7lE1XvYQjeDXnZh8wdhM151erXu14aeqQBkDKeE3lfJDes3nV6jeodmUFO84njN4aAynmjI6+swO4a1BUAHUz6UH4KvD9A4UA0E1MlnqH4uGkKiDI78DnjPQioh-jH5oisSFTCmAmtjm6mGPRnwo3+ognf4NQCLqECX+vIL7Z1Wttp7x0gPgHsZY0kJFRaQ6mQKZJSw6VthoUEo7Oho8OzWs4AuwVrqbZyQmgemKtgz+tOSvBGcoJYlgkJGJCE+6qBgC44KAkf4S+6QPoDeEyZN15uB37q9JoQavkaCQh0ISOQTwEphoDtQwWs1CPqqjPggaM4sM5DSsBgV2IzgZZNNLEIhPnsQ2YORPAC1u5AMoaFWevovQweRYFAE0gXvGnQfkSfksHuBr0h6T4sohpTDwIhZt34WEBwfSDHBtyFY6uq3YCqD5SDUPwEyIIHC1YVAbjAm4O2lTFL4e8tILVBchyFJUL-SDIZxg4BDWLjjw2+2Hu6hCPMB9jRcdXrAD5oFLjbh8eUANRw2hvbqUHLiQIM6HGkAAKxgA7oXFDKeCAAsAWhkuC6EhCGWoGGiAwYY+wL47hj6FrAicNGHKeyGJCrBCzvLf4DBoolsrWKRAEqhV4sACwJOk39BCAM4-3lHYdqXagsT6GcDHIDeAIdPiC70UCNUDG+ssNRDg6vDrOCKAr1C1Jzc0QHWENhARJ-qP+zgDeB-+nYlg4esILC4zjEckNB62a6QIOFBAT-t2EpU1hEkTKA4BB+59kIyAEEuELgZTCE+aYcUIrcE-GBTwAfnAYTOk4IWiKZh2oYaCQwqQLFS0woEp+SSAGFLZSxAUgIiCIgtfLxSLBcIdt6naLvG7xdiaQNmStQH4JPB5UVBGEIvh98K6CMQZznlBLg14uTRWaLfhpy9qIQO8Aqsi0gMxCg7kHHAZaOFoLYbaVnuGTP4kKuNTDyrfMDRao4hOuaycNeJOaiIM5n2bzmn7oy58hktEiGqQ-8FLDpAesMP41Qp4ji73BIhj8yUEZ+NvB22nEQ-xw6lEWH488PNOsTFh87hWFUOq4JCxAovgHAZDWxvmxDx61MPpFDWx4GGBXwXYg6blIogBiGG2n-n3z30qkF9Kzkv0OX7RAKoNLACmgwMObmIGRIAZMWC4FPBFA7wcX44QEGLf6LS4NjvACRFYOnpzKkSB8p+q3rPIZbKd+NDxA0sPBm6L0WbjixY0pvFiL5Y8MvZL4BrkhrIUmVJkixBWPtLxDngJzsGCoBHIBGx2m8kMwFuQaeigwsOYkd-6ugXHip7g0w1KGw3hmxAjR+RnjNjRB8ubggD5uBOHSLfes1J4YAypbuW5FwfbtjhOkziksTc+f2DQrAhL0slRagNASHRb8NAnQJ2WHPGbyC+gbFAKJ4J-iRykgf0IMCSs3oNxKUCCzCqT5RgEeWLMSdAmcC0sT0vgLZBYOMxBi2yDGqBpsP-ihI3orAIgIfRoUhNR7ch3N9SWMZElLwEi6iFjgV4MMf9GoECpJLQowrYSqJsAuMfAAfoPAH76J4aEEjQYKYnCTGkAqBIUKtEktAhri49MagQFEEIFTGi6T-NtzQSbAGsDIqNUDYBSGwCHL7XRrAAABapAIGjf0rJLGTlgHqmzFSxMscgB-EB2DAKQkeBpJiecFbBhwdeWxOXwBhmUm2wzGD2H8QEExuMiLAMNrq4Ficz+NygWxz+AyQvoxpG6JHBnotxFVYIfKPjh8BAiIKx8pEPHyJ8wfBgCh84-vsClhDOCZTU+64O8AfgscWP7tmHIEuHwMK4WOAPgeyHT7hkLSu2rxypsdTxhqRlnZYF2NlqsKtYctsT6K2ieJrbeuQWLsodeWNlHI42IeE8aAaomnYDc83mh156m1JnniMku2h14wWpVjDSrm-hluZCOsFuGQX2-ho-adxqZAPrEA4+sY55KKkd5p2eIWPABUSSSiZTjadcVADjWdIWqia88AP9HSormP4Z0qaQKDEGIcgBKx7xzWtqCta11h1rZxmCowKj4GkRgBsCukv0614kUWsGfkplPo5SCT-IjEAUlbHowXhyMSjCIR05BlI2CVsLcz-hU0T-wfxzAg0r1GmzAAnK+05LRIeMm3tdFtkt0S7EC4wMdfEP8RtPyYfgfvHIgU8vgGzHEJ+PPSTMJ+-ofL2M+0irwes9CRxKMJvOMwnjUf-O2pvOibPQn7xOEr9HbcJGJCrW8NmHbwO812qBHECBwd7xFqKbEmyB8RUdPHMSbCVDJPcoNtkBo+LkL1FaJMNMnxHx66pgQGGnVoaAqJwgbQmfkAfKtTsg6VlpBJ8jfM3xwArfO3wZMTPOhRK8IvDfTFB99Oi60wfCbdFnh2dF-zk8R+O9xIKtAO5z0knnN5xkA5BElxhc-IIMDZwGoE2DZceEKYDGEgQagmjx7MfAB7kcAP4axImEGWQ022PMUnnu+ImPxy8k-IAJ8KiISOKpiganOgtOvkBvx54WAv-gtJ7-NuQFMR-P8KbMMbr0l2AFsDglXUxQDuzRASfEgJoSqAkoQWgXsZADySkePMAbqPkp0wV8mQNKSYCB-MQC4CQMdgmECgcYOAIKbbh26qGtivdKYyFho0xGGFEBsnFubhh4bFu3hh17JGTsLfHSGBRt9EzAVRptQyGwxjKCjG-BiNgpuwFpAD+4amPEaQyZ5JYAjQsIa8S0sqCg5DOQfSNQSdMdBDOgMEt8MJKeAwYI3BWEZMqeznsl7Ney3s3aBqj7og6DZjHo5AO+zyUX7Ney-s2-AByQAC2GTCJAm1u1wyw++rogaAngGBwWi9nGzifO5LMiCK+TYH9wwoNcjRzbIojBsFcuKgCOA2w9UCexns4ft+yzYe6P2hHE2GAthspunrADfsXKf+yAcL7BiBV0RqeBASpMqVSzIg2KRYRHgc4J1DVcwKJfjlA9YPxyt+BnrczhA9yBmKX0jgEITegHYBiFNI4QC4QRO3yPOyqMLViCy4gNDKEyQeYXkiyjEooK5RsqO6ipL2AuqdSkGpyGKhiSoJqWamQAH7IKrkkVqX+w4YgHLkByAKMFTJpAmEB2ASpmVuqzIgDaCdBfU0fA5x6AwpiWn6ptKZ6h3s9ivyoMsamAqiHoyAnejrcNWNjDqY5qXWmWpnKY2k8pC2PEKwxuXhKk0M24IdaPgH7iwEupZqQsDqI4cPn7KAZnn0DFAnarRD5ALVqh5UMPbKzYSguxHqkXs37HSm7oDKf2iDoxWNhiMsx7ogDEAswOukcpP7NumAcOqDwCgZvwIen1Qr8o-QtAAELUApEVar1g2C99MaD1uTgp3BiAOKXiDzm7MDbBHgSrgCxQBrQPz46WYKkt5AEoVAMLIpoBNuGQEwujATU0dxODzd45Yflg607NNiSzUclBQBOkgpBGEQsNgu5HPc+oYgbyAmgh0Im4EmRgTGkWBGMp+05KFY4AoimdjiNYkmThxx0FXhzASw9hPqLdYoiPJkTwIyAORP86mDZjBYHAPABDR2UeiTSBwHi5KgQMkkoAChziTyEw0bnCplLAfeLslQAcKsuSymWSTkmrs+SYsS+0B4QlTgKaEk6TdCJwMoYhYKNhmQXiWPg4RMcItEm7fk7eK8BAAA")); })() /***/ }), /***/ "./src/js/built-temp/base-sv.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-sv.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYAE-Jh4sWGGjsANhNLIwGAKfCAruNaKwiMVrVztPaPHKIJAazaIAdgBNRWgG5gAZhWTGw7m2ABvF2-BgZnKsUnQ8COI8VnJgdlZgpAK2UjwY4nAUpg5CUvFckAA04ISQUqRWGDT0jJAA2jzIGAC6wADKVACiAIIAsgD63aio-QCSvd0A4p0AvgD0dLAm0HOZ5PD9rJgbGDzOXLvOdXONLQA6VsxsnLz8hloKKIGIAEakamAvKjx50RguiAAxrAKDx4NAwCDdCDkNpArBiIFAesDBUtLYwKxyKRAeDoH9Es4wNFkUh8ZUpABPMCAkJhWgSFjsCFA7HQFkJaLOaIReBUkS0La2Amw1hcMAAVVYaLsqQcxgJCMC6wAjipwQhvFdmWBKe8wAB3H4yLGkDDrdmGiLEaKQxGPdzo7wqKzlQFmMAqVjmxB2CFQyTweDO1i697CZxAkHkSlcC7df32uywjGuYTa8HEqykxBGaCFMMqK1SGQseWQ-jQQGIMKe0N6lQRqMUalQ9z2JVxeAp7wAWjAABEKgBycRprDiV7vcQW8O4xPvDDEAsN4ulxDlqF0IXeVmkS2duovZpcnkITxsY7HgCEFzapDRq6NJbAZfh-GQPAZtPK5A53i2aJxAbdMmUzI0ETtbswH7ABhOQXmiZVgwLc0gwSaxvBeKR1RpUhfzAWdG3nCtMWxGwVFxOI9mcYx4CscQfwof9MUQIDGWuCEIOIYlxADAxoGcVsk27TC4ysKgbQhDAnhcJBYEbTMAEYAA4yLNC18XLMJ5SkCEAAoAHUbUBHjmHePIgiDet9S+aBqTTV9wxZKQURsSlrwASk+D5RmHeRaUuWBrFgflfRsAkrHgA08IY+jxH7SS6OJFkwHKdQpGsKKbFvKxUGIlhyX+TsZMdXZ5QhVcgXnf1+E7OBMJrCpAnlP8+ASA0TJ4wqtBsCLYHams5O0RSWIbYcXxraB+HWXEeHLaq8VIqKDX5OxdNIdhvFokaLXEo9mjaYLbCaqKwG6GwHBC7ZoCvZoLjqVI4HuhJCDqAAqZpB0QcgPV6Ug7AuQgwA+r6JVdRpeW8QzEEpaUgOgIG3s+yUIc-TUwDaDd4FK8EkYgUHzr6iJBpkIwxD+RHXoJlH4M-SpZAqPBDJ4C0wAAMjAToovIDAPPOyGGcc-TsRUJcqW8+jvFIIkACkVH5AAmAAGFXxOBwm6YJaambAf71jAAAZeBdKpjWUe6EtSANCFHShZxGyVYR1r5TaOPYbg+DAQATckAeD+HrmJ7YBeg6ADE1EUyVWBsOFbrmY8LlGLR5C9GOBoZkrZNa6kZYQDCMSWSlFX4VgVGYdE6zT55xDCXNxBN4xqQNIMzFyx7DGD-GQZRgcaLohiL1YFjTJrMJKkzfT4AOcVRS461EheBrATCaBPK7wn8o4DgV7AfSBz5eaPE7VV1TgYN3cCbiHgtJYeGBc+fqQMA5gkewZZ8n4IsqVf14tiRo2pMgAGl9EQGy+J-Smr5sYPFpHAX+X14JWG5BgRsrxayigUPRYw2gKC70QcgyORFyC4lWGBCQPAODwDmPEfEsBKQFiMA-DEQD1hr2pt3L6F1+qk0hHDTM78Mxm2Rl9VAxg0wpioo0U08p3AMQMklB0zxXJIHcoRF0EIsSiDoYaPkUgvLwPOswyiPEWHwDboHDuIdjySXuLjFKiR2AJGmsRMxd14xWEpG8VR1YEiBVvl8BABY-LyCjIffk0QHD4XlN4W0nZaTIGQC6CI1JMJaDEN2VgfEZomzBDFUeEgxZYDgO1FiwUzCBFosGF4QIPRAX4IFfEdgTADTRJ1ZK0p2Q8GwlPMAAAhQI0BI5QlMvAd0iQPjIFbOsK2nxSA-W2rgzsDsXzYl9KKNux5DbRDMHHBOVh27PQMXURsUgAC8xAxBDxwHMahhhaTkBsFweJJwrAOF5HMAAEgAOQAOydAAGocH+c0AA8s4bkgIeBDV7lWCgNhjgnJeubL6xzyBnIubAK5Nyli6NIE8uQ8c5ijDaAARWzKwWWqBSHXA4HwZoAAlOZNhRQIrRUi4RIMTnnMudAa5cwDQCq4OsYmsB8XIDmOQalHs6VtBUC8YV-VWVSHZTTFFXKMVYrmLsBEcqxVzBBIvLEUqbgyrnEiYBu9JgRA+XKzySqVUcM5Wi7lmLeU3O1cQXVzyDWSElRmT2pB47lBeHMWEZ9JVLGsNATKLTLhzHpT0AcvROhcGQDYZoHy+ShkjZcGN8B7UByDs0IoJQiARVhQ8rZVgzC1DBRCqFMgYX3L7GAWCLBxBX3cNeSAJQZjFCIBgYNNZGAEFKOUX0fxaiG3Cj9EtwNIDGGxOQWonRyBLrnaUBE7xoCYWgL3N5TTagFH7aUOwkLYRSDaPALYzSKC1EKBuoggzwVfhHaWzdZAy67tqDWk987PwlhKbUXoj7SiIUAxUaAtRemgaILfCDlxahUB7cDPt77ICnisLyWoXJQOQAGu4N9wMiDNSvYFGw3QMCkFqM4Hwwh6KvzMC6LUwZrCwagLQMjFQbDQEo9RvAkBaPCAADy0AAHyMeYx4IwMcrDscgM1Xo0Q1DwD4zRujIgEj0w+DJtjf7Si0CU1YFTvGqPqZE+JzwymEDplY3J-TJGoofPDGpgTQnNOQkaI6XT9n31EFoM5xspn+NQHc6JiTBHYS2dk-J5qA5YaudCxphjMd-g+fk7QeLlJgvmbAOFuImAfqvxiw5pgozuPQDaGQSgtRhNGHI9AMTUHSuQG0wgXjtguO2Eq9VhgAnhNtfBGJ+QdXyvdaa-Jz9f5ui2CMyZqrFA+tQGE1Nxr4gBvWaG8gDLc32u1cs4N5d760PzvKdlojxH8OvCQ90GDLW-HYikLUWCVB6WG3kzWJbkBuiG2Qy18E1Z2ArraLBeTzA9hfbaAAaVGKHP7fmmBbFxMBzohtDbdC+W0dHkwUOEBmL2k9kBkykF6VlYwUG8CjrgxEMItR95ALAP88n7U8NAWxLUNoFhwWmHiC4cgHdFBSxasz5qCR3PaBrooHddZQyj1MA7atsbjDdoJyUVrbErC9HoioC7RBQiww59IRAeGR7j3KBgWoAAR2w-Pv7m4t-pjDyBpSUCxvKXGtRRjO8W9gvDm16L3hcR8oCdOtGmEDGEcQLBhA+FYI4oIANu2O-Lc2qtNaBN1rvmCF8Ta4WY2MK1PDiIpCsCoCYXNcJagfIAFYCBL55yaOgfCtWgAIMQiAk-ofldbIw5AYbkCw5UWooc6NSEULAAssiuziCEEEZIk4dAR-sBHorY-v4oHUJoL+nxsQ22V5jLnkYuxi-53AQXAQwAt-agx3RHhMp9VMDzVtxBsSOncwxl4becUy50nyIwx70Md13cnhjZdJagvl5pNBws8MgCcYQCG4pBwYzAYgDQ5MM8zBkhvAICHBFATcKh051Rh9FtW8xA8MVpJgnhwDKRF9pA8NYQ7BelKQOcLAthdwnBhNEA1BqtexUhq0xMYC5UFUIhah6Vgx+pccTsoAIomoMAKd8Au81AQRENKcEcFN08oAQUod5NZRRBsABN6VfRfd7trBcQnsBNugHB5VqD5M81l0BMr0rBH55Mb4fpIdgpKBTA5BnDwRRBagABRmzOAOvJ7FrCcI6RqcoKKZgxAbnPnAXIXbQvkXQigwjATWWTAS-ewK6bwavDI5AKXc8DAOjY3FrN5aKKUKuDnQIL0aOOEW3GSZdFrcyA0KUH0P0Wof5QwUwGotohUSoWdJosgA0KHeATxaIL+WQjoroyEawLABiRCYUfoo7VDR3KRRbN3OA9wVdddFQ4jKAAaUKPQqAL3F3WAWiEI1QhAGoATKHKTLMc8NYygbBCQG9bkKQHAXHCASQogR42ADY3GWVQEGqXXTdGnI4yANoV4n4Ykb3J4kwGweTK4r7XuJxKE9cYQbCeaCIGE047BR5T4sAb4qAXGQ2JlUONiHCdYEE6nQ4w3PkQQDE8gFTBgFrJE2oW4i-ICQIe-GOF4n6N4j447R3QKbkcgZAf4p4feSPI4qnUE2kgTfpMwcgAQZwYKQiQw+oxExYK3Z2IsVvcpYQDQNJcQCiS-Y0dUppcPaQUQAAfgJKJJgGxlxilNEHam2LvV2MuwONpxuLuK5ItKMMuO1N9M5LigDJMD5PIAFPtMdxcMoFELVFZmDGpP2LBNrWQAakoCCGVIcGayDOuKgAHCLBeHgGIGb2k3cLVNiCXzHA0wly0Dj1SFxAjOiCCJLEHwaIKCFPQ2DAiBGLGMWIt09PnW9PBOtxsAjOgEcJeBeGOjmJs0SKrCQxjDGWyhmPHjigSFv2EESWgGQLYHj1NLeUmleUwMQALG3JECrGuBcDrJ0A3CsOCi7JWPQwtFEH7IWImOgHwVZlhFjRTPwzTIEwCPJ1gGCIkGnNnNmPimMEXMBFD3bwTwSQ8HrPH1AuCNMDl3XPnM-I7KKwGhfEtIhAahOgeTnJgvIHFH+SKynPApxB4hLKVJVKfJjPQzO0-MplEPJhBXUNlJpJ9KgBAr-DAvbIJA3AgteCgo3IXJaz9HgvsMgvIrigH1MGjzADQuEuCNgGgBVxfPnR2gUnWC4tvmBBZ2HLlIEsgHp1ICvwqDgrpyLCE2gD8HPCsE0AYwVzMFjV3mEwMsUjE28mmnkH9NnwIqkAwGSEHTSGJC7CAVsqiisHFAADXWoch-h6y9yYij9ednBT9YBz87BMi2pRdbznYPKFZMof8ECjArBdK8dHdSMnSQDIYls+LUz5SoB+lzRkgd1vBkBIqtQ0TYLZKAcHKghrBPgfpVLTAGNJB+ToTx8FBFANyYrid4r6IqKaKrA6LTIZjZkszedjMrpy9CrLzMrYicq8qCrhdiqEq6qvjHdU44RZUEkfomDzL+LwSvlqQaiq56jO89iidRqBMPlZ8wabc-gfpHDX4EhTSaq64Xi+RDDBS9LSgvRejoBRgGJyJKJ-yPr2rLLDYpcZco5vR4S+iGj7LzCSx5c3APBTTTQKJmyit-B0QcgToIRxcdAx9pcaiZdej6iit+w6slgKgMAxMR9hKNN-Sv5TBSpKrIx5UeADTrxhNVhRbKgJMpQyaNTKZZFKQxdohLhVr7Bm8DYyyfRXw6MopN9zAhBZFnz6r0Mw090kiEAfyxSALRzoN4AmLVTTA3hKBgoMAOyqbCyix3D9rxAZJLgLBPBlqZJPhKQMAQ6NSfLaQXRYAJMubxBjqZraBEAvLPJrwwBLddSJABADTMRNB6yjzzSiiIy7B287Tuz51sJ1QsQEYvlSBYBwY3RykET8bAKOrIAsbzwaieaZ9fNAa5LwDNBf8ZAlJFZSrjS0opdui48wB6UIg8LKLWLTtRiOLv4x6cbTK7Kh7vbzDTzbBqkIylLYBcLIbGjVDZ6BN95EKI82bMCPBZroxPABrsL4pH6ljZB5AG7p80ov9H5V6Xhk7E61h5dXh+cDTxRQbhBZ83KfRJ9Zr4RzT6yRbsRNbggaasxAH5jxjd7HC1a4BCHxbVb5UxNhMGG8taRCrl5cxoBTlhx2Lxi-hhwxMXs3s1bWH4AJMABqQcEwPAf5OvavDzagzCnQYIVgMECMl+cmkwLgJh8gCTYTERmkTKdkLhnhwc-htoD5WHKgYR4BMTPAD5RQF8NcnOzETKZmlwMICMxwCQFAWEJOlOxwx5bR3R-R9hox7hw+3hyofhn7KxuYER2xsALG1qGzTw-neKVEBKrx-XZmwqpkksapWwLRhh-e0oHMBAXoH6A0r2oCqAb6vWSpujMOyASYQIXnLRTweiSmZZKQcQRw5AKwAsU01mnEHZTQbZHCS0jzAhsWsTYILM4IGwahjW8WrxjytwXeToqQcpE0osVmuYuiCM4gWfDg18dYZwU5M4SADVN1OYMo5uSi-1W4S5mY3mUQC5yAfobCawMwS5xhuYRAAKxEsEzocQgTcciMip36Rp1u0oKLA06yrZdGAC1+8O8arcjmqPUwWAHAi8KF9YYQHgWKmykXBK8UTnLKnnDyq6oXIq-EEq9-HQUgEs7qy4bQdEYKPREpogF22CNQD27bC+mpyARU5U-2sAKHVIOPJposoISV9gejJxP+-qyoLCOBgJjwfSPR94BibOu83OqagUQu2AYu0u8u-UjwI02uosY8mQBuyl5urlqAbcdY0keicyWAfvUOwVkezoQUH3ScjAsUiiZ3aVoseAVUsRcgRQGSQq+s51uEnnW0RW5B0BjzPc+24NsURnZIVIOYsAGIFJ1eputU1mtU9p4Ole3+3BapCEeimKt5dkRBl8MKxIXarwbM3MEeaiGgvke6wkx3HltQLG59eteKfl6pkekV5i0wCVngKVkapct+osNS-0qN3cHQbJ544tzw5ANdsxU1uIPUyulCnQOul8MwOV+1lu1DVXH4-o1I+Qg+gcr8kFVqTKd6x9y7OK+ACp1gYfKkdvMHJI4EXpb4X4b+Do2R3UYKMHEEVgVAVx7seKWoCw6NNQUwTdzUlrbEYKBAUDiBIffQnu542B-xjU+TTd3oBWAaUIcEhDoEZ45wDxko1Q9YFveAEFNJhiDJyDjEUEdJ-82Sro7pboPQTjsEbjvGqAI6SKrxzgmEASD0fjyTlnVks0QdeAG1QeqAGR2gSqj5CUAcCjxD-D8DocqAejtxxgsjhE+7FEcpyp2C+wlg0wSFswRpka6UpDAOxbCjuueAadOAXpHCa9W3L7Wdmh0wW0fnWAUOlrfu-pHp3uWaKT77Lyw+CMvJqQApnjfXHmJwlrPLnmNoCCUyNoHgOwXjgCTKfLtqErVQwENQK9MIM+tAqAWd+dhrzaSkZr0ZVLqHTaVRljwG5eJAcgXr1rkQt17IGsWz1QlR9gdJWoVAOdrRMHUr4gadSkcnaDagtKbYZYp2tusDiYyzpDhiACwESkUb0ziY6i-nEKOQyAMva7j0Nc4TM7CTSWmBqQAQPqFsuY2IY6qFZSgAwGsgWAM7adEsswqAZzSH0YvAD70Y-glrLkUgaobSlMp9dgZMkGuuNIREFkhHIgcvLAEQgQd0A9ObvYp9aMbYYfOjYHofUrRzeAUYBANAYwLrbTyAJSBeavX28QF+IwJjWwdjH4zn6AURcbsbXn-LJlwXry5+CQCXqAXkDMmXnnocOVSy-SWgRWTyNXwClefbCTfXMQO9BHfHVGogBeumWjhAbugaCFHjoeheqgIV7AqAhe1Hrr53aU3niwi9qamny7F0fuzH2obWyevLdYA0eZMTAGy7AJJQr5RYUAvkcAgQBqMAb3x1yAAtvYO+DJuQtqwv8onWyrgTbmfNn6uPAWgkUK40CKikNIZP+dAE7GXn3uHt9EyM7QaAR2h6wAsgP971yy1ojRp++TVPioPukZ6PqvwMwGgaJzqAT3jwaA1k1R6Hv-RgOoEn44430YUYE-0-k--5Y3q-1nnTs-2-yAf5C-h-p-5-o-0egADWN6-4R2aBa1hFoCNAVAyATPrD0gATAP+XyUYP8j8K7wPkBPJcPYFoB6NGw6wBiFRx6aAsYWdPASANEBBl9LiQrcIgNGKS-oX62gRAIHmITghseTAaMHj0-a08Ca4JSWnnUq638y0AOfnJkjMo6cuiO5ABkJjYEVI6aBLaiL4nigmBKqpHVOviSP5El50jNSiAwLaojkhWqAU+niWwAcCpCXAudql06I7phAWFcRPTSTZINla6kJmtgnICDMw8WYC9ioEtI7ldE1gFgN1iUFeVjAw-YjAoNPQHxWoKgo-p9SnQNx8WhhNXpwKrDcCDB-AlwKINTa-5wh-oc0tvlxDY0awAdNVr6B8E3s9ifgwvqQCqycQNBAMZQbzyxqJ1TBwgNSkoOZraVBAiVMHGBGl7GBds4JOrC0Ikwvxts2AsrBTG-ha5jMAFfXNQUaDglISfIAaGH2O4EdZCZ3XntZ1kHDVVCMPbSgsJEIVUcus-RQpBloGQA-EymFgcQS-zG9yY6cSYgJmHYiUpAu9Y3rIh1zAUbM7NbwC231oEkvifQ-DHoAe5SBg8ciCdpZX6RllWor4WvCXjtKDFrY-wr7IYKxZzs8y4PCrppxDz2EwKQ+L4e3VC5AQzudhRgaU33DhdCRATAvgnzhikAEYAFMkfDABECY3OdGFYeDzlRV4JQd2F+noJ4Hn0dOPVGzBezvhx0GMcLDTM4zH5bAG8MgeIAWAtrGA+R7oeXHqz2qB0TSG1IJkExe5jJkez7P4Lq2MGL4XOHmIURGCjYJAjqU1C-B0hJgVALyJYLfjQxmbSjfoTZCwEs1oY6jV6mVMUYKIabCAD0l+Wbi40H5g9LsZTdqICRqjO9i+1YVLvSJqE0UXO2lHwQ6S5ImBTK8oKgD8IbSAjwS6Y6MJmJaw2haR+I+dEpH6AljFgKY6MMt0Q4RkGM0zTWuWKNYUAXRMzXwKCNrF2jNakKX6HyGbGa0V6cbegCYFASUtaqxvEsYrH6CBR5QeoPEZAAG6Nl86kaLyhQC0znwtEdY8Wllxy69iVmLbbfJ6heD0MdGaohEUjw7Hi1Z2co1tjxAnKIAdxEmLcZhHsDttdy9EDvpdhLEABmfoNuEwgIU1Sxzc8WJlGBfIug94kQDoAq5hBewEeEuksPcY-1BxRrBkRGAVEh8Iy+RSPBJRnKPwimx4hhp7yuRgB7GL4DcWJmhyWNwJzjTDvLmY4CglxsAFCQWDrbWAXheWICfSiokKicOW7bsLkMJJfCmIf4ACsKhEI+AZhpQNCPRFqCTByAPgaeinxC7QYx88mbblbANAySFYFHRsLRynQ-BhuwYykGxgEzpjfo+4eTJ1GwwCZOixPQGi6CEkMDIAYKIQDG1n6uN1CwrdyQXwzCdFoo6-cvpfSgDTosAz9QGhkjoRIYvC92brv2WezddxWoxe0reyYBj8p+hhAgW3SmEAU+m4JelFsMwgFgYU-iNQChI5hgB0xVgV0AMXZHRD9BvAq5ggKJ5gBkBjXNdPFAwFZ0wAgAJMJmpwmFaB1P4JfD6Y-k1QjlJXRIT0udlBdsiDqlcjIA8A4pIgPEAtTUB7U6jhJh6nID+p60gvqaBqjMRsplBG4nKw7IFhGUNmAkJzHCKhBJ000mIfVIWkDQlpvU1qWgNgADTupvU7aZgN2ka4Lhh0h9p5MwgdkypocFyXFxqkzTORbXBqYtKakrS2p6A9aZ9K2nRQBpSUkfkQHARmcMpYGLKUPTsCRhqO+wsafoXyni8H+cle6XNLLxRpcSJgYQIryF5SiHGMgW0HW1vH9iN21Y2idgn4k28jusLJCHiPL6EzOCPTEmUdKgC+sGJd6SmRyNS64jTA5ZBVvELFIiAbREYFyVzPrhIThxx+fmfdhYDRA0EMpd-qTOlkTS-6+kAerkSN7yzap0MqsQxwjIqyPM4iDWR4xcDaznGDY-WfkHFYTVbZuYfmV8Kky8xRYtgT5vjKLG6CiZEs-GkQAtnPcXQUUC4kwKBqOzUuRNGzNRGKipzKq4cvxssMZm7VHxhTD4f20IHGBFYkswGRVLTnlTVGiTe-u-ypmzSYZOcswfnMqmVULQQWDwEXJkHqtS5PEcuXIPyFfDJAqQdJCLPZHxzWq5sqWZAGqQ1dmyxvduU7LpHUc9gLoSaWnJkD9gip-OL4DYK0AkNogpcBoXW2nBXyIQteZAKKkrkFD4kSOReRnOTlYxXqFeBooEBtkhAjW9stuQrPqltAx8BLMfpCBxbjzxREEp+db2inO4owvYCJOTjNkfzl5X8lMNGkKwGx-5SCouhvJAVzSwFygYkJAuxaaAYFLbLRKHNt5QBGus85FuG3FnvzaehfZeR1xvTaDgFWc+qVwo8DVC+cy1CsJvRbZvB0kCQG+WoCvmR0XgigXkiwCkCRJKKZEkFPIFNJSwEarE7+qrKUVXQGEuDRvLWSlqN0GMmEEwAWCyg-QIQwQZCmVQSDYQRmzxMNGYCQi1V7xz8lrGqF9B1zwSXC6BvpBJQqBfQQCjOZvP65ytBFCQwlkJDMWZRKK7E5ZmJnUWHtNMMcOAF-QCCqzZQhi2BfWScqMSzFToSxeiEcJ-gkK7gMqp8H7ouLcwbiu6p4ut5fCcOdRZhQvL8UiFiODMnheEuIUwzzpZ8oRQAE5lYCgDRobIa6AgNJicqAMnMGU9K8EsEQyGEvYURL6pCyorCMrGVAJtK+EIfl4tUJMdOlRHXDn-NUjKxVlM9fpV0rOXEUWhSdMABcq7BSSDlzS+hTAGCjugRp1yjpbMo4WAzrpCS3pWspuVoi2ACSz4Aos8IvAleoqMAKksKr+lWa0aYmjwDH4FgaJEIJulbUtpMyvB4gN2TivZqRc6Fgs7ll+B+WXYxZxM-5cnLBm8wvmpFEFdcr4VzTgujUYQJQu9mvNhAgPEJCKnmg1LgZfwMlZjNKCARlK7S1hScqgAMrB0AgFOgV14VQzUu8qorMXlppikGMRpXnCSsjRZglAK1dts4BclUsRFvOC2po0OUz13g3SWVZAHlW-clVeCosjOT5BXLqVYKuVS5K2WiDoauqlqDyJbKVAE6UNUwCarNUn4LVDGK1YgEmWA0fF2nVQXMuXlOrFVv83eMEtCVEK2VncjSnnJ5UKqlVfo8gILytoD4vGpg1cdLFSBx1TVvKhNV+1ZhLoghGCwGempdUsqvVea4fL6pqFI01ZU+QNQkH1UhqjVebSNa82jWw1Y1PgH0GKqrkjllgxAaVbStjlJzMFTFVgO4Iuks8VV1MmGVQCKxJsEhuVERVhUaS4I62hSjTMmHFDfdR40wptfOgQbk86Vaapnj9FukHqO5jPcgHnRjwt5ggYgXNjCrhUFgW2LnSFJEHFBQ4JqOijmqmxVlMdxJkgRbIuodIHjmFcodfpAEz7hDESpABfu6BQ7c116MuGwggQWyUBGFU6f5O9i+FGgqSBMlheupTUArwS3MYwHzDAAswqSDs1VfVMtjlAbYhYUiDmnQ1ZksEvMWMM-K+G+gro2YYMJsGxD7S55vymVR+sBnwQCISTYwDJV-VbyoA3QIEtegaGmAhJiQUCDeVSSoLKAEICIJhsdwya+Y-QfZreg01ercNs4qUhlyI0tN8uCAbjbJqIKhSvVfyjdamsBkhbeNgW7BJWME2HqZJMm2OJph43UhYGsUQZPTDSwtDnN6GZjRsGRD7giouM+dDSoTlRbONtQfjYEEhIzzDNfS3tfYRukWb0tsmq0AbDqSQgDQeKG1V+x41UrAaycurXrCG3hbWVQmuaVrleb+g+tHW3jUVsc0MR+AzUTDclM+UthRCCfB5OVqgDx95kk4xQsYH6CYR+gkaZgFmLI3iA+RceLVVUtDZr0z4YAavGXHEB80yJd27hVYHAn9hec326JdqsNKaAjmUgCNjOqSWui4O2ac0hIrzjgS5kuZdpn6FrZcdcO7UI8Yw2YZXp8lOgNUkqPPk9NWx5OEDRPjKU2LKl9NewPgyAkeiN67AYgKzL+3nQnA8QaGtYDCA2AQZMkJwLkX+ARQ0s263dRTQLDHltmpVOAHWRLA7Mswsin6H2wdKHaHk-QVpQuQn65Se6PHaabVg4ndLH4v29Wq6KgQYk5Q2JCegURLr7wEgPEhmUOo8CjLxladLwNND0iJjYy0UI7ZKvV2xzh6llXoA4wVBNMyJAe4FYbqAkm7ntDQvmv2BllDjGOZq4QPpE0SQpiKsQU0uAxNX+rEA3kOtnYoWIuK1xYudZoS0wkG6dZ8dBWnTQ8UMMgmqANoHgERVFhZ8DajAJiVTBG1sV9gdpmRIbXt6a4iq+AOBKZUxIgowRShh3gL7K6bA-QT8LQGG0WUWBLkkfRDKm267kl8qkfQbvAlqVMSbyD7Y2QKIwRxWCEYWVixxat6PA-KqHTM3CgkwnArelfX8HAntt2dWQmzoro927aZ9S8KphrvZKn78uT21msZiQoF6IyQirwGRIaj640B94uCdCrl1qAIQmJYQPnrP2FUb5GiwICiqgYoG2OFXUtRYtMB2KqlXYVetAbwPkLNo948UKkuRVyAyDlq+dRGWgPBR9cEIFWeBL1XBrJ9LSz3SrunkRAfdAUoVlKQ7JzAsFUaTKCHR-Vr636goneZ5SVwkMyJq8qNDYPog76ise+83YfsyVHyGMrNRDRkor0yDw8RSg2Mm2VpX76IsQWncktlAzVNZEgMfNQdDD4rYA4Eltkx2eLjysdQTKfQIZn0KRKpWff-SZNTlZ8dd-WICQ3L5Dh7klNSrEgftCAFEj5uzCaqAck30zw8hdQedkrUT5NUkdbYec7vPjxBP9r5YI6rq102ZJx0y67XSJ7qu6IQau1TpDLGpqVY+fNBjMDxCheMyJtu7fUbpbGGGEgY+XOYLsIj67vGVdXZa0ZLqPqdA5h4-GLqg7DG0B14m-ZrULirlz4w4KgMODMO-d-uctOw9gctD9HlK8BoI9-tn3CzJxxs6cgJVEMj0RiNgQXg2OXGTb-Bi7VFt0aP2fagJHxr41bJXHwHBwRhiar3uKLkJoa-cv8IIpMD5EvDoxvsS22IP0STAPx6TDXVPaZHVx9GcFEL3mi6zI0+sxE73iqPzpp9-QcOeaG1Yz61hF21Rv0FrkRGN+URmQJv2EBv95DAJ1fECc3oMYPEpakHpOHYJATQjacxI8bvGOR72xySqXW1MIiU8zA1Pe8cxN2pDMJqIzaAJoDn29g-yXbGUwkuhrGYaTpQOk0IdnmTiAFwIJo+1wAXK9ScNXXvMqoFNWVl2QpzJb0ZNHUhrjkpnY+LXUOXBNDcpsY1CYwhmbMkZ87lZfI+B1twGyYWBW+LuNHbGF9RpNU6cgDZrvAXC1fT2vkqCnhAPRkUwGfFMDHxKX2y9nAfRMrMFTkx7ubKznZiihFhLXvZSHiU-RwJHcYIvYHcy31z9igK06TxqPe7TtNgO1a8cIEj03VMPVvc6tkP7qvTMrQE36YrN18qzA8Gs0BM7W-zIzfYhUwrhCk0VYgfRzndFSXMZroGkYTJTlRcnLnbRyS7lUIsWoTqtDDZiTCxOvpNJJqNYsXNrP7M2iTFUC0cxmZV2TnyA-QHM5ybzMhLvAB5osxVuBqlmo9JNUU4Ge-XVmpTG+p87efrMR6mzBa6YzeZLXHVy1soVZsXvVm8MD06oGXWOYO01G316Cr0kK1YHfrv4XwEkzVhiPoXyzoYLCzueDPQHhdIUCmizut1r0pj15r9RGU8Mk0aFo6wwLYssAwbRAzFyAHSdyrWR32uZ0OPzmdXdqohJZ70woGrxwpWmWlwcEWEnrVFN6ve4y4PshPv1PgogSkP+YKUJCMGepHCM7n6qdJ0gmCHmFoJLr6QKAcyQtVyWwYEswjTOl8LPjy4JaV6l1eIhfnWq1Uje-B+41iM7qFi3jllberFxn4CWLLIBosF9sG7PE89QcENdwaRrGC2d5gpWq3GzZSA5G7TOQHu13iJW2ZCQQRobEGaTk7MHTPqmXHoieRtTPEPYx6GHCwRjjzjZRkN2nzihVRDDboEo3qtRcEgQgMif6R9AkCtTaSksiCItaaDWDQEmLh2UEiiCuJuozFoRAUXjXp8EV-eGkre2ZKkhWgzyO7vQwxBVdwR3M18hz5qksMOBaVvRAtOQFI9fwD-HyHkl-BsGJosG9NXIABHmG9evALjsxOQSwyt6xutFzGvhBw0T4gEG1eP0yszrbssiXLkatxAW92e4kHm2cZkSeaDO-mtPyWK3GvhgN3S+sGvQGX4LoN3PhDdwLlXZJEuQwEsbow3x6IcVxGrwSij9WGSAYoLWlapYZXCqWVxXZtvOGUwQSfu8EtcPH1lX0MUYnGPx320DpUtYA+LVIPkyTXyAY9MRAx2j695EmylSMMjhayKaTCjki6EptxAIkvh8VUnDYCKTMKHA0fbFqMj5GrnLsDUXYIR2OJVg3WX+FCxKvIjLcca+8gvtjJsDxYEA0RVgnlm0C9gq4fvedJlBh422oA3wNoNWFnMZzApzTZUpcCnLCH2QFgTKLmum0wzwWNFaMGEHKQJAjSLLdkFhnSTwrJ7Xdme1TojCLZIwJ1QIDW2wQaJNA6bMUhPR8Bd3KgKN4-NDVbI3CQZwQbGvhGY4CCVWmVTKEGMBrXlTesyp9F6FO3QAL0YA2VPKxnnSSdBMAD+3pLziRCWLKCBJeATcDDo-7CS99dJ0S3BCoAnqGB5AG5huBK5nw-IU0RK0lhjIQYS9G63v3JJ9hbdgAFoPhkAGBXNIT18JJa-1YLG3BqsbBz5KH-wDgGQ4Yyz59IVHZgG9pkBnU6E5AC3sFD+tnD8HA0ffR+xTUv35W-QaNNbA5yv20UCdHdNtj-uyOZlQUpRygGAc6WcYCsWdAJm7pilIH8DwTHXA5yQVtHgyaR-echwKOpyklNBwJIweqEauKCBnv8rbuQko2ZA5rQPatz0OXi3j8UCJqtLeO1bJhn6IhFvGp1tjrNPOg4LpBh4+24q-ShVWiHoQiHnFtJ4GxUdGbUu7l2fOsFINC5mk7oo3DFW6bb35AQ5tG1VVNg9JuYGSviC30iq5sogx+OImfhpZZWX1pQZxN1io6ahMn85gQEgqNhvaJJqFlrRoXkAaAGE6IkKXJxIadWnBvT7lmXDviDO217CtuwOFGdiiuHytfu8lozyzPFA8zyKihScD5JdyytNZ-sURAPsONnj6QMgfQjsC8n9UmRp1aVtvOaW+kFZ5kp6F0Yi699r0o85oHP2pClTYDCC9slMCoAubC5FOi+sMB5BCC1juGwtDEADCJdjx0QKAExoSkmE457Q5mdpK1KDGJSAABZqXxADgHbTFIFhMCEZX6nUUpiFQnpRPWNbPgNOL2lby+Ql88V9Fzq0IMuP6hy8amiBxQ79EthNWnNjJW81aUwKHHr2JANFtoNOLglnxr5ZCKAe55ABrBkjoAHUudoh2GeWVQ4HjTDnIdBXTOnJZzqxSQzKP-ninS9hzVAyIN+i8gM1CNoaWrGirzoOgFgNPjVJGleX9hpRpBmOhR5WZj+c+BRLhwGuZYtEcgDCPrshCTJCIsqTmNBBTRSXxmh155iHjbGFIuYqaOYHDwG1cwnoQozWWkgJ1xQkwHwPYtbajMzSjbLsJCvEoSgk4YVYivRGgaEsayFeu1hA1+7t4DY9ZUg7tZio1kDX37WRH8Vx7Jr3+bd+lAyL0ilkpX8LqbSc6gBD2ahjD+xzOVu1PBy8pVJjtQUjr4h-g21cuiYaPjQV5i1lsCwUoA5yuql1gMF6+pXcZu+nCjmR6Jvkff3NHj8yx8B4ExE1184Hv++sFAf6PamED9OQi9MdwBzHklXd+wqsenabHIH8nIpW0flikOVIfoHh5r6DjuwGQQj+i+cdhSXj8AeI5eiiyYpzX+Lkem0BY+mAG5YDmh4W9Bsg6rF3Ml2d0T4gFyWajBlCnoD-KGBleBOxbIkCsDiS0gpgceTK-sHNnnY0VfU1vggMKiSCapD4GaaKw3ylPgurFuJ7QOSfHrMxFAxhoG3zo3kIdLROxdX5CtOiVgQXqQT4+pc2gX+C1poDeSeeXPqlrZvYHAZVPBRILodxWsybJmNMSJSBpO+rgD6d0Dn0oPJ33DYxXbAG4dOx8so5eroL4cXNJ8U6Rks7UzvxzcXwKPYr7r4Rh7nCtJu0B+LIBTiQK8oyvCTbbvl0EQZjiUcVxeJ+Q-2TFFf-3bPB48ZjxdQB+eu2bR7AD60TeTMtQZeu0N+OA1uQ8oRb3tgEwABWPWJtjW9el6IW3yF9N7GWre5vzcBiJSBO9PcVY+3yb4yNQ-lpTZQfXMgs9DtMCBZ9CogK-KjC3c-gWNVwBa-8UunxALr8kMD58-8LFsRWNcujyRKCKNMLr2wzEBCQ6AtFmShtpS0tBrBR7wTyqZTux8QgEbe5fnA4BBmlHP4Brl790l5awAXSCAT1obfy8TCFnXjb7RKl1rfxjqdw6HyQoWdXPS1t16QublmqxA3XJNGwJoF8PoMEgSkZWGMp3RV1MqtnqOul6ICDu6f+ECgMF3GKZoS8C+tQSPU328EB95PfnzDO6DpdWoJnutdkBlF0I0ssQTT4WpXwCvxA6e5vVrPIDt6MABr9oxUEYIA-U7zzoVgsoJDyti5ATOAHDALcGCfo5aiH3QlDCS-0V0bGYxjpKpw1B3WPorEaXosVdGLPTdT4hTicGsyDjFHII-PVdpLGvSdORdkP-NBU0lNEveu8rxybaTGX5I2548UrPumtpQAsV9kIm8p88eOycH+dMBDWCwibqgDNfOi-Yrd3JUi9FQieJB7fAY5spTBMtNCPd5MD8pE0uGCVAiNwzGP3+kpPffvcIKjDGD356QAKHmvLyZsbLK1tdqhSGoCukAn2zbSxeTI4Sc83eWpg3AVPQTnm5EOJd2dlt-RO3-QOGCbi+wKmdkCK8dhOYSe42gC-3nIr-CVQgD2pAGGL4duATFxE9aPAO5BNDAvlFAVGCDiHoRSX8hkkAYChwUk26GpCQxjQapAsB5MUUH+h5QKUBklNAbWg4C2ALgPgBt6JcC+xJgTQA+R51LAO5ZBA4liHBUCXgLz5gwcfAEDWAIQONhVSRQJkYgoaQIYUKKX9hYCXwdGDzgvGHIDRR4gVQNIc5ALGlqArA3xmiBLAshxBQ1AWwLIdRPeTDKYf2RzlnFyWA529EOA7XBBRHEBbHH4oAbWkb4--f-kCDgg3DjQCMdUgSI0U6MIC05IpJIMCADOIzjU40g1VzaAgfELGe51OWsByDtjfeC+B-gdHln4Y5SADylijCmVUJbTH3RXlMhZTUO9IABk0jlmTKoKY8OA4WXGlZZVoKzM8NAJQE1WOOozw1NlEYIfsvlP-VgcIVT02bV59WcVN9OVUyygBoLPtV5hlzeYOXVcwVdWc5lSHdUkssOUYLOVjIH4HgBLOSdFOUV+S7DV12eV5DQV-oCKFIDZxJ4PwD6iPAE2VPAFo32UUoG4WocGua7jCAQ-DAHu4JTJ7lghKQEPlEtdAg4QqBRSZAEQDXaLzgExJgegOSAtMDhiVFg6CrwYUgQ+ABBCIQqEOkEm-WEJdp4A8IhqwQaVmVIYOZPTxs9MyGDn-44A4Dj+JWQ0110lrJKDll9TAagjllVCckNZD4IVgA-Y5xGqwjIFGYzgY4l3GFFNlROEEHE4BOUBXZ9xKTLxk89yazQk491B3HACGODkMspwiQnyCBjqGKhtc7cQfSlDcQfTSRNPcB4ITZoQfQHa8ijbLl3RlObUL84z4QLlgBguDujC52SHa1IYbrW11gD2QeAPp9-Qts2g4DJedHjY-iV1kuAIecaVyNXwQdWsMx7VNnAxJnKAE4DiWcknDR-2a90TY0sSCm2Cx0EZkS4GfJMkm57CL-GrpnQnLmnlrAMgKaINuZLj652oUkndByuavgs4auTQzwBGCDIAq5owiVVW4luQgLHCsPblm1xYIcoCMBnsOcMCAhhHXBbCIgUyC24CA6Tg259ubbmEk-bS6ADsZ9PaTxAPSKAF01cEa0MH8YwnmDc0n-SsRr4bw6kAdscEVoKK0V0R8L40kyDGSXUoAKcBcDzKY23TJQ3JrxQ8sZAGFFDZXECLVt-cJxDNRtjNQHlB3QQxkGNVKM5neZrmPlA9QvUAlB9QsQZ5ncIJwd5k+YauH5kgAxMKgCZYoUCEC8d4bcgDVoAWXeAKdhAfnT+sNrHRguAm9M0hfBiAcES2ACwYhkqpbQE5hfxw2d5mEwsI9vTMAxMfCJ+hCIy5mIjvmX5keYvYCe2tA5UeiLEw8JbHXYirASYSwkWAJFTDJgecQGQAfAavDadPQY6A6dIwbjmKRVfFPDhQsAWRA9EGMJkgHh6YKCIyN9qQqiUBXrQll5xhItCMuZhMByIeReCKSJkjXmWACIimVUiLExc8B5FfgANYwA0jMbHSMOd0w+nT9AUI05lEjLmDCJuR+nGwGXh3gR5GeRFuQImAED4MuEii5Ij5lijfmURDjwaqDSOP14BPaz5UYwZADSjpIqwBBRdqfEEyUp8f0npg4ASDRqRYFemE+BandmnLtco85nyieUTCLUiXgPVCwwQ+aAErtEAYgCkBaot5nkiGosiIgINo1qP7AJQKyJwIIDZsH5x9wPEGvxYxQqm3Ylbc+QnJrzVOQiA3lcVQOF3BLAHNxe-IVjbRoKP6M21icI2z8oLQESQ1BQQSoBSJTvSACEo2yL2Tmooyc4NaDfiP4FhinuE4n9YaKIalaDmoWGMRZhCKDxao8SNMwxY02NEg8D3tOQAoR4AQ-0HInuUOGiBUXZ4hPcpKTANaDYwv4FJx5wij2TDNVCm2QZxfeQA-xP4byS0Q-gZ3gsIKSU2VtDzwMKlb4oqcoKJYenCQhAAZgIAA")); })() /***/ }), /***/ "./src/js/built-temp/base-tr.json": /*!****************************************!*\ !*** ./src/js/built-temp/base-tr.json ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYPaGERgMKeMIBGpAK6wwkmTwA2AEx4A7DGABmiAMawKPeEKPC5pZIgRhYxCfvJJYfDcI2qw+q5M023MFIdAQ0nJGhNDGUAT28rVmU6MGY2UzAAdx57TQ9QnU1siWtWLkgAGnBCSGVSLRp6RkgAbR5kDABdYABlKgBRAEEAWQB9AdRUEYBJIYGAcT6AXwB6OlhyRGhluAp4EdZMPYweHS5jnWblts6AHQ1U9m4+ASERMWQJRGk5BSU1KN0BiM5BMZn4iEs1ls9kczgCdQ8XlY5FI+lMkS0QRCmnCmyisXiyESyQe6QMKOgr3cmgKGiKBLoB08AJKXDAAFVWAjVPBlDwAG7wEGYmFgZwARxkpgQXlJQhiskyKmUYGRpAwzkpSpy7lF70+njAMg0tX0AGsjawNYgeWCwAAJQCMgBxLWAFTJyIDDBQYlw7gMzA4wDzrIadBQUix2EIcXDoKZym7FVllCqWIK7PxoPpEElXe7PXpveQ4uYPvB5KKQ4hDQBaMAAETqAHJ5OHyFh5F9ZPJNbJyGjA7IMMRE+6lamwOmJOZGTWvOTSFrRc1JB0aYVbCVLmuAIR3bqkBHjlNpxAZss8WjxWrkKlIxCaeQFyNpIRZex2BzIMD1gDCviaBIziqImGrwPA7jzgoyhSjeEZ9h6g6ZqqKKqDIaLBicOhCpB8g+Le96qo+GjyHK2rEAIlZZgE0A6KWQbVp4foaFQxCCKI4i6C4HrpAAjAAHKh6qapEGZJIKyhCAAFAA6ux+iUcwshqGAZoQawSYyL80BxO2U79q8yhwqoMS7gAlL88hTM2P4+PcsA1rABI2uomIaPAGTxKReG-mAbG4S8whgLU8iJDWHmqPuGioEhLAYtoepcccgryoqBiDnaopwPOuZ1BIgp3oEGQKZR8XCKo6iuHUubcTYvFEe6zaTrm0D8M4aICp8+iZShHkZASPKSaQ7BeDh9Waixq4dN0jmeHlHlgAMqj8k5hzQDuHR3M0fJwFt7iEM0ABUHSNog5AWkMpA8nchBgMdp3siabRFF4smIDEXJPtAt2HSdHLPcgr1gN057wPqP0HRAD1LZV2RuLV8awK4WiQ3dMMAUDmJtXUeCyTwmpgAAZGAfQeR2ZlLS9mL6dJKIyCOsSWZBXjBGAABSMgEgATAADHzLHo-9mMAjjGh4FdzhgAAMvAklo39p0DKmpAZEIHwoToHowp6Q28iNr6PLw-CACbkgDwf9tyy7bA+3TQAYnIvEcqwqg2KYm13FMwg-jILsBCKQb6mAhVxMECBQYa6wxAC5isDIzB5L7ru2DYIURPIctCnEGQQWa0U7YINu-dD-0NthuGkWAJREYpuZJFo6TSfAZxstXFFBJIOX6Ek0DmcX93-bFHAcD3YDSQ2vJdZ6ooSlKcDwLKUYSB+lEiJq6w8IYC-CHCYDLCkFZYr8KhuRgvf9zDAwpMCcTINdy8OFLign1EQjTsFPhwBfwt1AUGAel8PMJRRCQSFDYCM0kAIaD-k7RCA54DbCXikHgHAEE8nuNkGIiZ4zb2gnfZwfcoYDyVnDaqGhaqwE+ukNmcpv6nVQEKdsoZMJtDVIKD4pEZIBU4hrXMJk4jkGNEIZEFZKGZF5MoCydClqGmQBhSi+D4D5ytoXW2a42IcSDhxEakEUj9jRLuD2GgBgaBiNIUy3gazeQ3ooBAiYbI-iBF1Akmh+SkGUIKLwuRRQ+GQHIukYjoI2AQESaiYo5YmC8nXFIDMsBwDcERRy6luIL0kAYC0T5+D2UiDyDYZDMiPwkFySkPBJBJDZAAIQkNAJ25hFLwHNEEH4yBSzOBVgoUg50xoRlFFrScKIbQlHzmuaWmgzQbWWGuba1t9pC1Os0D0ygAC8xBkasGgDgZYyx1DZgoKoLgvirgaH5EUZY9oAByAB2PoAA1DgNyOgAHkdAFH0DwWqZddnkFUJcRZszFb3UWSstZGytnrAkaQA5VhJnLCmN0AAimEVg7NUCILSBwPgHQABKnTVDbmWH86RCzyDLNWbAdZmzlgZGpVwECVUoXIGWOQNFjxMXdBkJIOl2Rfkkv+SXeZQKyUUq2ccewHKGXLCMJ3ZELLODGxmvoxw98x5zGyPaDl5keXKD5cQwFJLgXktBcsUVxBxWHKldAGVpInikEmbUSQyxrDz2ZesGs0BlDwnuMsLFgwGxDD6FwZAqgOj2l5JpV19wPUIC1bbFRe0KhVCIDsnw3zRkaDNE0Z5rz3kqk+Smrw-4WDyBXlXJRkAqiLEqEQaIpA0nKEYAQaotQbRRCaAATQAD9mnroABkAFTkATXdSAQoUQDrwJAe0NhECDuqPYWQ0B5zQDLic3JTRygzqTQ0touZujwAOHkigTQyhVuqDUl5V4G2JtnWQeOi6miSA3dUIGqYElNCGI+ogfgX11GgE0CpH6oAb2-fcJoVBy13UrVeyAG4AnYHHW1e4MgOCPsgK4D4l67pEHyru+yqgBgYFIPegmKQaw8BiBIAAb2EbAJ6h20Bw3UVQ0B8OEfHQAHloAAPhI3ScjYAqNogA5AfKQxNByHgCxojutEBmh4GaEQAmaNXqILQUTGhxPMYI00Dj3HXayfk-x6jQn8r2n7JJ8dfhPQLtTopoTtBTMek06xqAOmSM2aM7R6o+UGwfXM1ASzogO3uFs55lTPmYhOe01xwLwWPPKaYA0xj0BuhkEoNp+MuHoCcegBoITWMNMmNUAxzwyXUsMHY-lhAWXVAWjYxlpL2XcuhagDeu8hW1MaZSxQcrLnWtZYXWANjlXTCcZq3ZjrVWou6Zk3J6dV7INDvUhFjDmHUNfFAwMf9zXID2XWO4pof4qBYulkJ3MPXIADGlmB7bpgczsCaH0bof4hPMBOOd7o9oph22u-FmABxBPju6KgAYf4+jgcIIsCtJ7IAhlIBUiKQpf14EbUQVwzk4NQAnh5DW3QO3kA7cgDtKGnwoj-R22AQX+OoJfd2oUPBhAAHPrAZIZ94lAKQ8cE47SR2AjooLKD57ucHC2oDWE0EMSCMgVtEHCjETNMRyEodrg3WoGAmgT0APiAPbAD6gD27teuwBzCC8oDtGuieeeg0SbroNBT6iaAAaQ+o6eQnbacoZ0RoQ8SF4D2ifH+7SpAYjGkZ46C08mFcybUtdWCQuLfJr2WmjN46sWmGQD2xsgh80g2NBheOUuLcOGUKwKgGxI1uyaAAcblj28gfaJAxC6Y6H8FZY9Qc5areM5B3rkDpFoJoAAdjgGAgsdo4ImRQQQg-qd1OdJ3+g+fOldm6c8iBtdgAZ7mR02veca8dAoFQhR+27n8uz6AnPCc8758IAX7hBQN4ENHVUjCKChhjKz9wf5iAog1o5DYMRHTz7QAL5qRcweoaB87HpQYLq27iCyySRNC7onJ8Y6YobQHgywGZzKBPRmgaCqy5bjoVIH4aAfDkbuDxhIFKZDq7ZiYY6QATyrTN4MAW79RzDiDtp9DnLp6PJtrsjnIobWA8gVJy7sYQhzrkC1h8jprca-6IA6B86uzuAN6sCOhqCOioEcpcrnYp6kLC7Q7qB5RnzS7+ZyBGAgbI6-akBJ5QCPL25CY8hJAIAIE9onbbY5jUb1rjo9qsCOT1rbZRpCgIF1AbBCbrznTnZtqQQ8DoIKCr4eohGmAVgIGOhyEkrTrbadizS5S1AeSgan7n4SB07a52G8gVjwCsHobjrnL15sA75N705fpkYUAyDIBCYnKeScjJy0FG7uFJAfBJAgiG4Ub46kQdpJAvZkAZCcjWi2hNBzCTzb4Ex9F06DHOrjGqz27wBmKaCnxI5QBUAyBr726OgLoKipjnTAFzAUarHzYW6sLW5gz6h9DkCjpGGo7ZBjHjqO7-7Phdq9ESBFqbBqHbYICNDjqPJT5qQfSqB74xC-HwAaxpLa7nFAEcA4Dg4QAi5EB3GUA27oEfDso9ToivGAbvG0HgnB5fHQlgCu71zqBCYgnnbknuDh5UmInnExAepuhwnMhlA3FQb6jSy4p2yPiwTODEmoakny7B7SAcAyAZrAlrBSmKFwkImr7InOhol8lUG-yLG4n6gTwOEY4o6zqSmA4qAaw8Da69GFBBDkIclpG-YMlKnaSRDKAfAZLzzqAa6FAcDRHwm5BAwYgoIAD86JYAmJTADx4gBpFYbgTxLx5hmGJJ6OCB5pEgbJ5Axxzo9JipYJEJLJwBrpqpSJmZKJmpEGFuoRlAKekoBMC84paOHxUAERdI0RiJUa1gICzgsm-aOZoJmO8A3p2ucmfItOAxMgMQ-8HqzOAg7+k+OebokRbZsRNgKh1gAuvJFZUGC82QGxWxzIfeiZq2jZtB+xa+AwjkTqwBmulprgA622to+gTQF5KAkehcg5PpdgBxIgd+IgegT8lg0+MRQBGgiYv5Ag3htUFY7ps5uQfQ2YX52uxoIgaSIFm5EOlZCRsAe5fgB5Z8UCBQ5AUIbgDZppexBxS0l5gJ4BIMyRjoqRxR2Y-uAgVp8JCg5OlOsAFFU6655xNFq0d4TuYBwYHozRyFKQdFqRDeOYZobI0s5OOE7gNU9p-+Gg6FGJFuS2uFOxKeSMjyVhxpbxKZ46Z5lFr5HqmZElKRYB0JjFT5Jl3FVFFle+AlJxKhVi6EginZQB1l84joQuWp1Q40XFzgulG8hgJFR5Q6J56uoCOO5+5uv2j5sVd8S+7i1gDe7gAWFG1OfIGuEg0kbGwVvEnGzMII2uJBEgG+Au2+C+3AJ+P46CmxbQsFM+P4hUkQCo6ml+-OEBYZEZwmHkepsBL0PWhlyZTZkA3QC+JKe+TJYAlJQJSVt2sV2O1SCVng1SNoDSM48AFoAWgeweBZ4BLo7iXwB+5AclCluiAlZ1NFrpuQ4Fl5HO+OF+C6vOvVGgAVW5Q6Scbs7Kfi50wh+AjpZFkALZ9Ow+PR8JZaD5K1gOCIge5C0Ju+J1Chvwy+5CIC9cwYH5w5Y55ZGFUGvs0xpgUwpEaEGEZCpFxlUAcxfICxRFJRAxAwDOdlA+zgyMPA3pdILoj8YA2ue1Kg2Nt5ixzNrVIBZx4BHqDRno9YdWe2WgnG8FsmgInKs2zlJ1e+RZzVX1bG2witGA3G3RaIqYMN-RB8ZoHwQZYAe1pedVV+C6GuYAHacAakFGgtGIPIvwMtF1QZ3A-VFuTqS6JRCABFixNNk13QaZj+ylcRcNTF46FelhgII8IgSh2tB+-aNS6mLo0kz1Z1GwtWPgxosA3G21sA5kx+FSC5ShM575XpPpBRWMVcggPpoZgVn6sEe6wosA0A5ypAsAT0po6kqgkdtBoaGgo+IebpNoS1SZMO8NexmwHq3a5xjO9dc5fE3MbI5BZGzVdgr5yA05m+IFzo31RNi2mx2lr85Ne26EEVdQ49DuoBNYW+AuiFwgTl5x7NBBAeU+S+kgHasJFoeg6t8mFloQSJttsAJB9OZoZ19ptVpe6+Kdegadn9PFgJwc50lSxoFl6NaSHA7lllSFJo50iYr5ttLd6Vb5c5CtKIStXFa+WDmte+CDFN7ittbk+tcAjDRtu4bGnKnGQj5A3GbGPg3t3cmw0ASyzYWl2xUQzYnGh2x2+tkj8A3GAA1CDJzrTngNHW6XtRLbmFYvGAzlwKI+Ixo94B6pSHIwo3hcox9l9lQOo-fJxngMnd2tpBnVAyINBcYzwHOahSoXvlxVxRoFY4NjY9I-Y-I9fYo1oMo5dm48sBo549SUKEkIzSoLoo5Nrk3ihU5Gw4oVRiPnYIjuvhEiCJdVY4HVBriAgEMOdOpGOiDQvTFeOhDQtXUM0WADrudLGb-VAIM5zQaNOR-QFm3e1XTqBcIArnvhwK+fNGPGxiIF-vADoEsjcJAEKkam0TnJddasbLs4fR2BWDs5ACMGUjWGaLs5xooBsAofrYgNxu4gcSFedUkGiDzSgpZAFoLd2rkAw3UEbfGMgNICblPbw4bdxntUkORrLf7ZAZ06SX0FVA7n0z+GM7GXSI2KPpBGMZ3aLq00KBPHfKMkDGNctYnQOWtS9VzptSRjyCwqrRXYuZ6C9EELBNvgAsiz6WyNNeAXeM6JywIEDBLc9Wfq9dzpvl9Q00OsHX+HIOHURc-Z8angfXHQ6QvclUnWg4gBg34+pJ1RQDnUhmPAXRZZHhI7IKROXTyJXdXbXWwPXZ6dzU3dQwGW3bzR3T9dUIyNbuEJBMpLAN3r3mrlFSabTZAH0GaCgxgEMUFhTmflPcGFviIDJr-iM5AMKeA2-cQ+4HbVYkm8MamxU9CSWXvtm+dO664NnTnvVfJbAIpVhGaPJhnG5OPsA12vvoWF8CCAZsE7kBPpab0Ty+hGaBvsvqtGvmdbLcHP8cEiIIddPpa-JkyN8wTOpeGUHTIyq7AOTWetmnhGqy0dG0ZZNRsdAHA7aR9PHbS-ZVALuqznyMvsoc5R+1vrzkRXQ7kORggCSvAx9OQqjWKwqHnAtVqx6TKJ67zc3T6-7f6xDlDlUNBloGwdG5AI4zsY8oVB6sDeNZAHfIKC06wE0JOt2YfH0Ewb9vGD87ADXS-KjM+cJeYy9kYKwKgB6miBwuEdk-ANvjXiQenp5Z5SEYPW7Mx-8Iec2WwI6P-sGFRqoHjkJuFGiEMFzK4MSJXpYbBJyzk7ADXvER1fAI8iCHhJ6u2uU+m0B0IAztXveUlYIIAhJpYBZyYKRNZ2CUYMRRaDEOU7jfyFLFW3vpIPRTJvSeqNED7jIGPZ8a-eAfPjvB9KPhU4gAzssJu7q6thp-ADJ6fO2gp4Z0J8Z85wvU0-AC0xdAEd00KAM5Kx83yxV6tvYaUU4S4b9gcPPNLJsEx93ciH7gjTPu6ogLvt+8g0JiPVUsoLAGXB1NTSZavkUzEZ4HvuFOQ--oAcAWaEl+p2AeTN0B+IpNHTyE0HbHyJpJt+TMgud64XILuox5FVADe0Jj4KwDEE9w0kt69yNA3o+5V0kOdN94-fgS+-AAzj2mnpU2niPJQXlzwOwMjLQagF4YkdttACd8QH1+RneA7jYKGLjVrsJwOiS5AM-LJxgDxwYDDaROKfoDEN3AV38KfDcudO8pwsV8oeAe4P+d2uE3jv0UBCAkzkE-Q0ttIQceJahai6tmQLAEtn15ILyA7scR9O4ngGxpL0JjSKQA0H3cSUQE6MhuOibwBkQKXlgG+pBBir4fFkQDsBsNb+OhPFyBb1APlFMCEgwuQMVgl1AHxLbdrvfvvAurxgjwvUUMgNAL7-71NsH6HykE1g71ANH7H0KP702BypNdJLQNzOZB7xKT3An-JqTvFpDgG0QBJLyJjMSAgAPa4K8j5x06tjX8oFQGDd0Lcj2m2n0INu35xu9wkIaQH5AFQEfTZfPatvg6iGaAb8+QzioVSWxs4BkF0pxq3gvbYqYVUfQHAaryN0XenogXXoq9ULgU35vJ6rscR-1FMc87QT01gAzXeRrB8PyPoHIFv6tvqLiWP-NRZI7l-gu7AaspAo6XsJqXReYm-2ZpCYd+dQYenP1mIwCCY9JEwO0wuxIlOyKBYEhgOV68hdizQVPpACmBF8pgZA5rEQAoGUCSBUwG5EXwYFUCoANyWgUmSICsC2B7AyAJwK4EL0pgAADSL5CD4sHQbbNYFoBtBmiB-Dwi+0eTnIQYPfPvmPBN5gBaAEjD0M4FIhac5upVc-o70ciuB4k+gW-qDVjY9ocoRg1wGOTsJTovc8CUwewKYDAh6ykA6KmDQlyf85AHvTdNmBBDeEXukACXLVxdAZ00aKFLmMhXcBAtlQczVumaF-zAEk2zqHdmGSr55dKaaIAPuNXcGxt+8nNPJinycG+CnASPX7nm0HazYta7gPHKIk9bsUKc0QoWmbQGLJCgOBMShhsBdrDELarsdiMoF3bpCh09hKeK4Nb5OCJSsbGgO6haoYtChPgqAI+X8HlDgh6kF0LhULZvAoiuiIBo0IFrNDheogK4u0MuppDUOSZCMkQFwIpY3wqATIWMInSQRp67EBnIC2aHdDYyRjdQHLyHRyhfeE2WgnViXhZY94wYDNOTyRgowz4EudTOKVlxoYySEeTsss1DA8B4BrPV+DTyyHc8SG8A3kH3SxEPCJ+hTTsmklIjOV0RyMH9EbygDUF1MtBegigCL6QjX4z5BvKkVa4L0OEUucdCYhEAwjgGEgBsFRjOGV9L6s6SwCCFzC+4uekAyYZNTbSN5kAoZTHhMRlHnYvCueFYkByEzsQeQ6ogngcAYDk8ykUoIbqREJHtNiOn8c7FUnsL6CoA6-T6KQG+jiknRX0WUc2Qa7Q80R22U1A+nHT+osU9uPoAAC07KywwIYeGUC1hecGSPMBEU9DQ9hei0UVNgnG6xjQ8AgPMHjwlY2lXSljYRlY08Ff95AHDZoujVzHctmuIVTeiC1w5RBOMzYYptAETCgslaTtTMWaFhb8NuMeTUtF4LLHYsl8VYprryxCo-DqgTTNwASUyiN8Tg1-coYmMa704axolNQDIFAG3EfIGwCKoKH2LAgc0GrKAH0C1zGcWifo10W4MD4jA+IIwNYLuOBDq5HwUsWobA3F4gs+GYLUbC+IkBAs+QPY78S7VQTCh0yxGdsUbTfGbweAgEpWqV0Zo-8F6d47mCMHsh35D046fIbGTeSP4IJnGApqtzJHQlYJRtbMcUCFBrCReaSDXB6kEZFjhGmor-ngGJGES-KYAe6pDyXaH0SRxTdbjRX-KREyCXDZhtpH7F4S4xnJDMDKzhIkTN+RfO8QAGZ7xtAJkGPxrr9sOk2+EQBA07JrttI0kKInmH1CWQ8JPIb0soFknH5Q0PIHCEaA9QVV-27gPoX+SNackoJbyLiQRNJFsS8eRnHdlYysaMSZAeAQgt8l0ToM3JBQjyb5LK5i0Wcn4uFi42+yyTEKMvQEh-QiZgUJAeErFClJEn2luJrEviVfkC5T102qgFTnjkGHhlyeBEc1uKRAhq8iKzoafkOnAiQR20QnFQPAO7pvpzwvo37ORhVgZAECP9bbHHHIC6dAxh6VwplVAweg9uRrITCVCKB-pNiS07bMaDqmNTk8kEcZCgh6npJUyDeYgA6JIBpAbkkSOruMJjbXtCeNYCykJnhLeFgakACpKQCKKuF-ue5JoIAD1Ad4fbmugLlAZn3Uxv1TQ6O8yArAB-ttUcHVAVec3cUuQgqLL0eJYAeHOt0TA+Zd8vOefJAxJhUAgsEiAIgnVKEBCn6ZvMVuoK-7PE8IOgsumAEABJhGoLYz9R6ZQ-cnljGul38sOUALCe+IjFlDAhqg6mZoLpnaduMzM9QWzIllnS1QmUeqXKORm0Eb2HwLGZVKZrEwFqoHVfL+wAKtTqgSwoWRTKgAiyNBtM7QRLKZksyZZuguWSRChFIzeZkAR3JmWQadkSY70hvNYEFnkzweE6KmebK0GwB2Z1s6WZ5HZngyNK6HSnjsSMJ7MOU4pEYYVFAymBlA0PGBtFyQHmhF+7lGStN0wJdZKApYhAjcjbRnSEZNLPVlswhCIzrxkAZWbkTRkYzbKzAxen4ONn+y+gIfUxpZQInkBx86U8LgTGiIRT06gnRmjBRHa6hHYmkaSbTmqlijo5SrICFaOWp6BtONIhuc7P5k9p9APaIvkbL9l-piM-4+nOBS0HHAPh74+KTUJAkpj6cMUxmovNcIsB-AZSI0iQMbmYTOae89PNJFDE9owgNeP4oXzblHzyhhIoIIVGCikgggnobaShAfFAgqIbIP8FYhV7eA35kUReeT2NC5INQ9rVQDc3xFJya5m8+ud-L2JEz7eEwiBYEMVGfs+Knklbt5PJF8Ur8Z2eQlYnDzkILQtbTMsgG1rjcLKL80GkKG5hbyqF4-GhUtGwEiAKBh827JGJNng0FOmtRMF5N4nOQOFt+CQLgT-YqhGhxM4UNfg+ro1eFkeARU3mEU0TcGooiEYkGyA6i5RNk2uVXO4HSKscL-Zqm8iUUdzj5BrDJKxX5Dvt6wuwynMcG+R5MBiXU+QIXUjwRL3AS-M0O-VnzBhxuzueimIsq4JAgQUi52RUhAVlca8f8q1ntR7TKAwFJA+haor1z04tFa3aEjRQCwpLecS7DqMYxiFqAwJJKWKbUxyWrZfE-2WALWFcSI5P5Ew6RaFKM6lL955Ss0JUuqV0LlFncpoPUsKlsLmlw8z0G0pcq4Q0QFobpd7Usx+SBlDi9ITthMLcz157igpSjJdmmA-5-ismeUP+myYWhj8uUucXRpqld89+SQBRgtoZg5Mj884j+H3Qb4lOeynlrPgtCFQd2g2L8UrVPENcF0rLXpevlDy84lOe3KWop3NaFssI+VXZaHisSQqncSYC0IE0fw55YGTueZpBwGymsWqnlD0IIwNq9jRR22SUDaHuUqynl8y8eEMWcgdpll3A2pf7PeWxCBiFUygMRHIBQqUKQKoUGyDwmoqrM21TCK0uxWKd2GSXAlYJROrEqGuKS8ledGqrr1IOMDO9nSoyp84xwlhZlaYFZWiVyAHK5FUbQuXijLeUnFxTdM3Qby65Aai-s7OFGeBOc+gRKisoCVvKDhyxazM+Fs7e0AAnLzFxqdLlOEa-HKcIr6uF9AI0yhWGo1kdoo1Y8UGKnDbS2dKcNAO8D2nFXVzY1gQ6VZ8rcxJqypnFRHNsQkBpqM1O1LNapxzWDKh0OgWQTkKgBeKS1Za6SIJF5gNq2uqywJVABbWHDZ1fazCBVOzVVTvVy809I5HNA3Lq5QajxQvWkVfFyEyDfWS8pUX+yNlQnBvLip1mXrLqpMElYn17mQkI8l6k+hwAGxO09M9Oe9SIDahqAZs763nsBLmYSBLF367JTur3ZQYgYtAQ9QuuPX8qmgKedNNrLdl6ydu16tZYGKvDpBYAGQLJO4nNZGgEoFUKqF1BggswogbIDZZfMA204+i9OLQRaA+BGB0IBU05f0tSEV9yeBwJ8ChuGHkLg1467eQ8q9lz4DZYmptaoujGiAR52w1Wkkv2HAsSMztKJeoB5Cq0ONZEjpOyOHWGzZAH89DQQUDyyax4FeHtDoErr4al1U1LhjptU305ulhwoPGXz3yua9N7GvaYZukDGbuVv2XldkK-mFKrN23PfMKsoAm5518m15c2oRa5B+ajnGIM4D+Z89WmUzYjBxrzBBaawV5e6iIvsV5rfsQMZ4rsHC1TLItD6q9eAsXXlClNvmoWg0MpxnytNym6JX5vCRYb+xhW3NRcPJ6upmAZCtDUWoeUV4KMFHRrQpv9mhpPQpU6IlEt0SubPNKdBeKqoariA1KIWhek70OAWaBy7vObUltUWzcCY77ALGfS6HyZXYA7DBkBq-Y8guQoik-IUz-aQllCQBWFUXUlpgF3K++PkENswxLyENQ6LIGKVcXiaT1q2aRWTCFAAArenI7jKRLh88NSprYEMR3kAUdwgBIXW0pVO1RF8GgajaFWjUZiF8s9EBhJDWL0JtIaq4c7Mw0Wha1QgcNR2m3yRro1Eq7HRdry2QQr54FM+e4GY34t7OWarnRTiHVk6LcoCCmCMCwDkxwEa86uXyBTkmU05GcjHo6VIBzEVdCAXHRgFek9ooeRQ1DXcsm20FcdSO9PLvP3mOa41Hyw4RTnUhAdjGCu-HVBNB0QZyeUOvYE4CXAJQ4ZYmxnZJrPWAJ+A3jQjg1qx3zaT5noeTOjqxWpLCmNFUFXxgZykANcXC33T6qfRCgsAauzxc7LR21B0ZxS0ns8rO03r1lqtL3SB3R0Wt+2ZytAYJr927qYAN8FPOv2+Sh6oAa-LpKhOuXkARg84EYKNtOlyiumy6ipS0PTyqy9qubAYC6EUxIq4WLKt5ClMy7L8989YLfe5vjUDE8JXmn5VYj+WKdEAKUzPemRVVJ7sW2kRaB80Eo8sc6dEsRlY3twGrZ6mVVPbzgIY8LtYXMe1UaHUz0q2xnqzjEyu0kurGqbq2SXgwPjsAP5yCVBImEfiC1H81qrbVlWIwM4ZtHS9QMgAvq7rLenkYfSiEMGibbpDIjWehlJnpY4W4awdaWo7Q76l+qhY-CwZ50aaZV9ORNW6Fs49r01uSftZutYP56BqQ+75PsAdk0Gr2tBGTT7MYPsYoDMm6LRwb31+RQpRrPrRaCgnuB86joVgKkr4MtDlNfgSyBmG6VGbXyt8vrVfMK3RbAGp8+Na3v41616JYjc5I8ioB4BWdhw5yVHkI4LN6KGcG+SY3ZGAH3AeEgzWaGTZVwgZ6mFKXirALbsiovNUgxDuqAyHiFSGhQ1AIw0BbXZP7eiioafZMHexpRy9fPi0OqEdDvjBTgVNBWOH6ceEhFubX81YauNQMm-XmG82XqFW5PPIyMC7htNjxLsp9bhrk2LCl6F2SgFmLwkwaZj-Rv8cfvqJXb+l8AAVlkYGaq1bDg5BrplUyraTDqvtEHfGHMMW08JfG3JiDtkmOrxkwGlzQTFvJtbRdG+3sYS1AmfqL1esgXOQEslnTRjlqPkCjxL25DJqAwf-JmXnzLAilfS6vY7tUNQBvGugOoPtK6oGdTJQukotHG32cqgJu+ho-LSgPdyAe69SzKPNckiBGlREvfD8e7VhGNg-2jMHcbvK4RuxRJuCcEaAYgM1aQ7D9Xtw2Bfop5c5NI2-QuMEwP9IjYRiCYoOyHImHkMdWYMmqEyVTubPCRqd5D1GqS9YAYIsepU9yv29JkpuvQzAZ1IGXC+aO4CwCs5nAuxlBNkekOKniFVBt2GPp6iFr6ds+qaogFTilSR8uoRHEAu9o8GmaWpqAxGbYNlSUp-PXLdPE5zptMuH1PyCuoa5hEsxghoM2VMqaZHvaEhznEkFlrH4gF0DQJg4aLP44o1sJA+Azi4niShemZjYL9vtOWkP2dY9wM2CoDNhUpWNVCsCZGNumRgXMr09grc6THQxOILYxrF3kXjKjahuFtObCCzmJA7kmCTydIkknoSx+Fc28j6UawNzXx78epGZB-GZMbDE1Z6A3P9FPghO0UxdUQPoyKMHJcQ4gBYAwMPl9OKCT+BJ0fQMjGIF05hT73EL8FRe+mJ4BIVzdJ9GAkYJIpn1g0dTKoAYPIrACKLUT4NRUO-Fn4HqFw7EzyDgylGVw2YoocScaBVMpT6w3vKcJsGCi3GeAGAYvWKBrBYBHjiILSJYn5xtRW6tAWsBoFrBQhFIX4JcDOAouED2JqsY-NqZoWaAUpiJAzAFhl0ZcGcaZ+sOpOMWSFS0GgO3u0agPBGQG8Ybk1Ac8myKZdD8neHGNgqOcAdNYQC5oGAtQZQTTiiE6hLyWGBJjNARZbmjxOIsa9i5lzNGd8ubEt0veFKcEbNAdoGcfbJS8mblaqWr89YDZWab4no0fFxbE0+vQQAWgi0jkDw7k3dUKnQLI+1y2FsmNV4Mtg5IBYvq1ZRm4WN7aCWFa3PcZSCmxpM8MXitqX0Z2kGXdceWKtGKVnLEXqZJFUKqlVO+2ExkcctDpRjwmncSMFUBmamyxHP07Zvs0SBlDuXRLVUe-EaH9ZvPPCTEW1yKXiMyllMwlfcD1hpqzzDBcRmcP6zLD9OaqlvnoqJg9AnbE80rVaOdbqTkEeS1FrhUCA1NVmoa4tHRX9qAshW2iwOHOjTXcjI5ua0BxGBlXELsbYUXFu5ybW6rvYva-PgOsmWFLKFU63FcZxdX3lWl-mhSrPpZVMlMfMVgkv2pWbiC1FWxRZThvkHirh2l3r6bBpu9+AoMOxdFuxvfjptrAILPGZy07K7AJN1M4le6vS3PQCMq7W1YkoittJNoc6O+pe17ozqoYVm7DaKvD6dAzgPdIR0mMAA1ofHjjABXQx6mF+HCWWaXSWoDlt4fJ6FSp6n-KNtiiZwAkDvk6QONDzS2asutnYAPinlp83XEGAZMx+aSMEMjyBMxwkRWcnTjHKqgwCgOo-IX2HPFXTRPdK8TzamEr1Lz50XNvmyFMQbAVJuY+nM3pxZnasUBhBqDNj2aQM6yDey1E2avV1iMpjMgpxMgRHZpY-ZlsVxIEmP4QNXY4e8BUBvzykg5kLKVHmbv2GJazYP8H2ZEkDnNghYz-cIxBmUmUaV+RyGNwm63GttKoMvoUwFy74Upbd39t83FMJTexR91en1ZBApS3xbGoC2PFX2GZMIVWPkIwVcA81X75kLcVBlwIjA8jkxw8BoGP4gxq85GXNupL3rkZvaFGVTiqEg6UNvKQRGbMywErSXvD3GXw-4dJjUho4kQW2tAFVpgMhTV5nA++L8j8ygHj93sUkpSlB2pYeEl-qLSZqHDMuXZkiQIFWRkYDAV+M6jJXZsTrSAkDkc8bY0hm3UbUdXB4svgf8gz+mFmgOA36IutUursJO-i2Cap2Lam3TOxQBdMQyEsXNVjthz9Mwnzoj0i3DmAQAEZLOA+6tArtzAoDNTm0zvHfUYS08X6+KlLoabS4cBedQ6CnTWGxHjp6aOuNPEUXJ4dU3A8OVQHEjIX8gUBr-MWpx0wCtpumXaBjgLPGloQOasZFoiaNZ4+ZHCIhUZZ0V0yCdmQKGGWoQPFJKBugOYZayQLsd-5p65t5QI5y1xO7Ah3+4JzW16fhO8zQWx2N1TMm8PEVoT2Ei6DeQsAi2LU5JTlRHwkpTcRMo4VLCBWOdaczIEECDuwcKYBnH5dwEDAfPhcAES+AC6kXISy1Jxvwzp6YBpGO9fYQoMY+uVkGQB0T9uKK12gWEwBfnDuIF-KVT7kGpypdyoi-i8fMDq+50bm29N7aQvihLWBmLQXRMVI0XZwjEuVoO1B7Uw8kCCMoF3QYJXAJyShFvL9OKjUl5Dd2SIEnSUhNgdeVwMM9UX0u+c9k39nrfcCLR7tmt+KAuiEDuJ0IGuBcg88gbSRhSUsbK4J29JLt78i1vbszesGAhau74jgKA+ZGht4Y1LojlC6YBfOx97qVWHpwtCKi52IL81z6bUU2vEXg+8GFzFhdQAB6hikF3oDgCUdnQAuW16a5GDevzs6Jk3v69T7g6yDTaVizICO31y-TDYSpZy-9llx32czgq5Ug4rJKamSxJPQapS6dtUlzlAqWuMERulI7noC8OzloYN5Sz+21bH0ikghtwekmv0xPx-DxtS8ybh7OQ9XEQkEATgDtCr0ofTz5yQFZ6iW1WZI0it2DRyPyE6oFF1AIOoVlqpnB5FXq3tD-qWJM2O8iF0ALTjKFpdd90gfQHCAkP6LVXs8cAD0N295EJCTg3DF+DzROVZuD4QgLZntXRwDEak17stx6B3ei544m8A92MNbceDR8PaLXFe5Cq3uoAAwe9yEGAGN1mW6mwnBijTs-uQqkQ-PVG9RzfhJl3Av06zv8jwlASsHyAMR5CQs36zuQaSFCR5dZj94ZfB6aHl1dtyYQ1tD54sNaYE9S8AudF8UJqCMXVkbI5pfx-xc1SLh22ZwPI+YBYpy88brvtD1GKbAuqDoFqeR41VVwqM2QZNlPUmeLkA7MNKcC1JUE6uuS4yPalcb0lQRUlKXN4R8u9rPWHJv20d61b+Ime1nvwG605Lxp3lNAbILT1+mOAnEOFoQlfNrgGwT4HnY74PG0KFCN1ISUsYgOs5i12xUA3QSyKp21y1Dnn9byJ8oCdH7vtOSPXjgR7RaxsY92kRMWcoYPx7zt-s+D030ff-Bn3mKvxuYwPyt2J5-n1r92rHDNGYSPXsWnxkiAugyhUFJqpCQe3Bd2cW2p0-VXUk5UJEcmEGJ9m+xT2ZWKW4CmEy-JcVW7JXJ+bALfMLNwC0JHDzkaHTBAcI5AdUe49oPrK44DOL9hmFPE9pzx-Rcj5qOe8WmCi3pNDPw43wvqYTcJ4psQ1S5LPbavRB6Rwti9OSPzZx0IxRg1xaC8mYpl1RLWODw8Lvlw0XKQHYR4Rzein2NlRz2qHwUvxDcj5-lYvpAJigIN2qKEOZJHUoBSXREB4DjQbr6nSb5C8+qAm97vvwwN3a4QKmuUgtQEaU65gDi+EC0vyX84BheYCU8Cvr1-1wu6q-JfNSdgGPuDci+tfYAYUj68l8PjzaMQIN6r-HR9B6AzgPonEAN-GinBkby74GyedJB9iGgFU90GsCUB8uR72Np77CL+RxLUkcj6S+LYu+F4iYDTjHCD-vhlQFgPzgEE6cEhrf+PiQOJcyhA0FA+I6AGyA0RGQeLkENznaFUDO8vy7viS9BDoC9RlTEl08CAl7DwlU-+yfL9UBOQYAPIKPX35NUuLKB0rqgETpHwXUJ7YnQKvvyN7rtA+2QPfsf5rMndX4EjgtCy8x8WOVvqixDF7Qj5CMfQgge3Wt2mR9ICHStOP7bKISXBgx-H5AVaKqYmF+nHkCfjV18Wdy0UBeu+cj0yWDwsAtAAh0PPx7ytACl3O1H8xZ+IOv0RsgIPgASrs9-qt7h4T-lRQcI32quTSmpwm3Iial-q1Bceg1HsDDYTQEHw+Y+mFtaEepGqOZiYk2OOjcwZ0PgFeuXUMQHgG7zuOgAArBQGzYILuHA0BGmDgHpqeAcwGS+JGnhCm+w2LsSQAfMEwHyYILjshucY-PQQgQL1hJ6O+uPjtjuWTHBiJaA5NOGBd+DItkzp4VACNAGcjCnviEEvfjEoDSMag144imtMDpXye3FxRXm4NphAUAMPpmQ0U8XocrmG3tKkoLoc3NkpLQ+0ofT3uYUt+wQau+mvRXkXEpqCSs8Xic4CaUni5wLoH8oewxkCABGysixPteymAywN0CVKHIOyIkM15HLDSBhTOjKRcAno2qmB46HxC8w6apZhtANJhgwUquKlqzbAaZCxS9EKYicqTwWgkaDZBT+NRhtItdsFz5B4XEUFwahLqtiF+cQeRrkAFSJISqAoaEXiFGihsUZYa9uIka22mOiYF16Fvm+r5aCapDz+k2dESp6SCzA47L2o7o5zDkzkHXYbADZsXqQ8-Dgh7cMqqi36+qhgik4xAhXPk5M6RRsnh+qgQJIBxAscjHBUI5HotrfsCttzi6ICGLZbS0B9kIbpsRaPRTvaNXv0rIeKCN+xfsQBALxr0xPPM77BxqtF7sik+OQimIL1lrQsWRaFGgZGuCp3o5GOHIkx4UA+vKKnkFFC+S8UmZChjsQ9PJ4RxwTEmACqM0sImBJSVAFxKpMiFJrSVis+I86C4+vpLbwSsAvWagIY5DaSSmzNqSH-mHIpOKQAmoBWA4USTIYQOU55N-SOBe+NNS+USuG7CuOMQAQLB+cosrpgIfzuyCTkrrhUZR8mHA8pMkQmOQht+LfBOhDM7ugdy08-HJ1JIm5XHV5ciMjKDwhu+nNpCvsbQOiIsceofJzKEC1OrynEFIuNJle-HLbYLiiOEGGzKmspbYSIeuBe5nSJQKwDJB9OvZCEUF7K9xfAXMPAJHSsTnTh5YbAFdCCgnIO2jfKllKqh0cYYawCth8AFijCe72ONwiA3Yc2F9hqfk2AZAjXkiQYAe+GOHiCLYan6yw9moESckC4b9hogO4uRyUcHPI5BKcFnD4QEBRACUChiR4MgDk0xXAy72S44WeFWAjyN4Ljo7IMsxr0n0puFwgzTGSyYCy4j6JgAjyOOI3u4gpLiPI7AJ7hQyWTrw65ueWMBGgRmRIbyeElgoXAjkJMnrpMWSQOqhj8izulxLQWXI7hGi0XGhHwA6Xt0CqBzmHmwZeXEhPCKA2gAYEheNpKzTLAeETYB4iwauPysKIgC3KzGf2OCb+qdBMFYEmxgTPybUHYJBbEKlcqBg0KeWKvJlOxnCiabho+g7iCqB8tJ5+q10nQRTqETnurpIakeeq6y9FHHpciRGor4lG5xLUZZk6nPIaYCuNlxFT6leDNqSc1BvJB5MWIh8HqR2ag5Fuw5NGZxZhBQGpHw4QBB-QHiBjAGbtqwZvmZe0EgNWbvcTPEkDvBWgOzzEW8EYmGC8HVtiGM0w-NAiLELTJSAJB2LlGEgwaZNFHM8cUQmFqKyhEpzpud5M2GUgEYZkRpYBBEPJ7evsPWahhq2MHS1RJRIYD0ypXkoYjy4UrSbX4b9C1GD+J4eGGdRsAABCfcbHENFN2lJv6F8ceEJ8hucAwB5yWc3nOUJ3+VgAEBWuQXENADBCgEUHzR1XCV5TSXosGFi0SRuhCrMEDEdFeREyk3JFSVJLmbc4kuo5wnInItUA9cCAH1xwAUwWaK90gRKNweoE3Lfb0U1UcljjRh7NNE0UoMR9FEAQbDiTNuYbGTh7CHwCEL+akQD+AM2GbNWwE6ObIuEThgoHb5qRYbnvik+foX4Rz8s3PNx1kYPA9FbKG3BnayaZ9AToFA6OOlGY82PAtw-cbgIKTmgZ3KjxMx0WsxKz4IQJVFoC40kjyiIqPFLE9hbUZLh-gtQPGA28U9HWZMRcsb8LY8uPDmGfE90r55DkVUSf4rQ0TgvD7AKIArLGRWGuzpgAVeO9HQST0uTAm6Sup45PiFvuTD46-MvbHbYAej27I6qOlHo1IUcjSHdgj4TdKMhSpA6AyYDLq7AoY5iK9J5+PCH7ZiuoEXoje4HFnrC1Ao0AoBxA6zFOAyeVzPsyUoJqGajQoFqMiBnMv+J2BXMNzGAT3MkAJxjaBfgHRbdA5osXqvM3GPnTsQMYOrDwAoDgFLCMnsCEAngTkChC7YIILYjwAiYPUiNIPYINgbM+cbsxsYxcWUhjInGBXHIulzLsw1xdzA8wnMzwAiDLx7cdvZymYjHcAJxQcKRpcwqgBoCtgtFuyYQQ7gMUiRAqBivCzxeoB+EZ4XyF4C+I-iJgg7wRClXBxAEMH5BtoioMpBXx4SHXBxASOi6K6gQYLnGbM2zIvHx43yJIRmga8ZADnMVcVvG3M6aA8x5oeyAfCX+QoO3GymVjGfFBgbUPgquojSOvzqw21NnFzxecVswFxIKJShUJngN3CyA+yIcjI89nM0STw8cOvEXMsANXG4JdcZxgMIrAOsh-WywG8x+QoaM2CvAOcG1AfAx8eQkaAdsP4CpgWCFOBYuX4Hcx2gLSFn5u0xtl5xeACCQvF7MbCSKjZA-ohKh0ga9NAC1gfQsoDCJ2CdcziJDzOcgjkmwO3F+Q+MHOg-A-YF6CHiWYOiAJIX4JohcQl8apAeQMCu-B0ADdOhQi4O2J-4v86oPHIJuVVrrj64FoN0Qm4ZuLoTocsOPHLFUmoA1LSgxgFoDlEdAdYT5kTuDopGhFnn8S68VuJQBRAtSYIGACjSVeaKMkZttj5QtSVSzZAiemO6fq0JAVK3a-rg9w7AQMKgg6h9IfNIGh5lLD43kk8iNFQACMVCL+RShq+5oxlEuEiYxf2pHhVsWbA+Y+yEInUJaAjfAMCrQKgJOau8jfoyyE4zLFu4-AczvWgVoIAIsBAAA")); })() /***/ }), /***/ "./src/js/built-temp/base-zh-CN.json": /*!*******************************************!*\ !*** ./src/js/built-temp/base-zh-CN.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYgejNAAHKA+a0AU6oAPTQJ3xgUTTAIW6AGdUB-aoCg5QF96gAgTAp7qAg5UCADICvAwBVKgNGVA+K6ByuUBwcoBG-QBAqgCENABUqBYTUBC5nKWAjfTmAOO0DwRoBADJAANOCEkAA2pAB2GDT0jJAA2jzIGAC6wADKVACiAIIAsgD6BaioJQCSRQUA4nkAvgD0dLDkiNDNcBTwJayYfRg8AGZcwyPJzWmZADoxzGycvPw80GCIYBgo8BsARqQArrBge4c8kQAmPHFgI4gAxrAUPPDrzxvHpMiICGCwxF2D3ISFgfBiGxilzArHIpAeb2gNwwYFIIzAN2BSCRcUiAE8wA9vqxInQwIt2OtHnDoFSITcRjceAh8WA6AMociwD9WFwwABVVixMCXeCRHgAN3g5C5AN2IIAjoc3ghoRS3mA8UcwAB3C6RGFwjAg2m65nEG7-QFbHaQ6GHGLRB4AazAh1YxsQove-Gg7Hg9tYmqO5Duj2e5DxXHmBXe1tFPyhdwo5JYlIxMSxnTeIWDhzNkQNLCl-19D0QpLdQa1h1D9yeFAJH2Q8HgJzlIvgiehAFowAARWIAchOIwoWBOiAOxzAJpDCLjRwwxFzNYLRcQJY+7MQSeppFNHeSewyDKZfx5UxPAEJ5tlSMK13rC2Bi7tmzxaITSNFyHToQMNwnDWobquseoAlaXZgH2ADC3x7Dc8oBrmxqthCu7QnskTKt+v6zm884ah8sKkJchwIiKowjNK8AxCcRK-v+MKIEBqZLOB5oYu2vq-GsIxNvGXaYdGMRUBa6zbC2dygrWGoAIwAByGqQaG0pKuyklKkTrAAFAA6haDzEKmRxXGAzqttW2pnNABJjqGZC1lSkQgl6eLXgAlKcM5VEOyDfgssC7rArJetctwxPAOqBQg9EwWA4m0RiVJgNEJwkruUWXLeMSoLWxmdLK1pSbswxSusa6PAuPpQeSwVQhWsS7FKf7grqRkmSwVKXNcYKxBWMm-HJzE1kOL4VtA-AggiGkbA8NWlmAUU6qyoraaQ7DQjRw0mqJx4ZNkDWXE1UVgAUlwSiFgzQFeGTzMk4pwPdEKEMkABUGQDog5CukUZHwPMhBgB9X38o6aTMgGYD6YgeJCkB0BA29n0ChDyBQ9C2SbvApVI69ECg+dvXMuCg3QG2YJxPjwNE-BGO3FNsR4PpPAmmAABkYB5FF5AYB552Q7cDlgLpcKHMu+LeXR0JomAABShysgATAADGrom06j9NckzMR4P9IJgAAMvA2k0yjX0FIWpA6us0kfCMtZyqG61ipt7HsNwfBgIAJuSAPB-D3NE9sAvQdABixxyQKrAnQgt3NCe8xVBsAXunHxVlbarUEmicV2v8kayvwrCHMwkJVnHuy-Gl2InGb0oEjqrbOrlj1rKHyOE6j-bUbR8U8sxhWFnRWB6fA4x8oPZqQaQexwI8pLQJ5Xcg6j+UcBwS+i-2YoaaGHaKsqcDQ+qM8mZsJrtDwTzQz9SBgM05Jtqi6JnBcEUYMvq9EwU9WNtyAGHVkrvyuMidYb4NjfjgD-bWsRGQYFrFOSsPIth0WlL8FMul4IxAQdHOcBV4DdDTLsJEHAiGigWMyPEuYKZ3yTMgXoK8CZrytiTfqMRBqwHhhqOWYFYFfVQNKByiZKJpFIlKFs9E9JJRtNJCsblLgEnIA6dYsJKZNzFJELyAjzoMIoiZRhII27Bw7mHE84k1hyN2FYzadFyREWvHdGMMQ8QHCUYSXcsUZRnAQLmPyAVwwaVZDcCUP4pTQktB2IkyBkAOmoQXX4CBkCsB4gRCUrwYoVgNNACWY8OHMWCpZGSAY9iPFdEBfgRIqGig6Bw4BRshTqWwhPMAAAhUh0cPjGXgC6VEM5kBNhBDbU4pAfrbRTB2J2L44Reh5G3E8xsbjOgTknGI7dnq6OSLWSIABeYgsBYCsGgDgZozRrjQCJOQS4XAYnTBiBkhAzQAASAA5AA7HkAAahwL5GQADyIxGQPB4INXulyKCXCmDsl6WsvrbPIHsg5RyTlnPaFo0gtzviJ2aFUbIABFTMrB5aoGIUsDgfAMgACUxmXEvM0GFWydn7MOcc05zQdScq4CCdhWLkDNHIGSr2lLsiHD2Dyvq0LEWwstiDZlyK2VnOGACMVfLmjPHnrCIVywRVEW-KKUWdRmTPLFZ5KVkQZXd3hfK1lqLmjKuIKqu5Gq-SCvVN7Ugidoh7GaD8E+gr2i7mgJEPisQuhUsKP2IoeQuDIEuBkZ5YogyBoWCGhA5qw6mOeqEcIRALlXMuEsmIzokiAuBaCg04KC0JVgiwE4EFDHwGvJAcIjQwhEAwN6isjACARGiF6ZESQnCAF94wAtHI5uBpAaUcJyBJEAJipgB76InREAERxoCYWgL3DJtSkjLrzb0tIFZsjwAGHUigSQuB7qYIcIFn4e25pXU5ddUJoBJAANJXqIBjQs4JX14EgEUT9UBEI-rDUkNpQHIDX1AwsJIVAW3AzbQ+yAZ4YhQySBIQACmlXqg2kbAeBe2Tuase6plwCgYFIEkeSgAlz0ALJKkHaAkdiJcaA5HKP-oADy0AAHx0cg81IoNxjjwDY1RwAYEqAHyU+j7bgZQFoIJmIwnWMUaSFx7jknpMPqIM1Z5IZRP-vkoAeB1ABvppp2TcndPOX01ANTJmzOycgM1fscNrOQHkoASk17OTtoM5vEyn2M2Z455yDFNSPQGyGQSgqnQvMegLxyDDMlMFChExl9EWKAME44l+O6mwAcZiy++LMnJ1OT-Mly4CmlPpai5x0rcWTN5ey28IrWm5OVfjqpnjkmEOECQ5Oyyfn73mag1OODBQIPFYiNU9oP4kiwSoFS42kGKyZagAUY28HJtEDeOWdgSQ8jZFgiFi0IxVuQGyM8qo4dNutZgAMBESRABeXoAHgsesQEaK2mTkAEykDaVlaUf78DIbBKFfDUBAAo9oALk9AASTjhoCcIkiAHbgwAa8qABunQA017Q8AKdygBjyMAICpgABI0AJDmgB8pUAL8BgBAf5631qAPwbhFDoocIbERMp4iSIAAH1ADTmgEHDhU4juwwEkQAL2aAAbTQAp6aAHX9OHKSMvYylKVJIgAf7UAKaKOG7ExHvIQ55QEkiABpzAIgAn3XZ4ABLsqeTe+2sAtRaS3-sABnagBO0yrZCwAsOaAEKlQAFmo4cBJEVgVAOipt+GDyAgA6PUAJVKgBEI0ADdygBv-0AIvRZvkPitthTcgsNyBobiEkQAEfqAEajQAkta5n1-4MQgBlfVo4AeVtAATke7lQgB75TJ4ABfjAAyEYAZH9ABGhteMAgB-eUABSuYBa1wmkoANCNACgASjjH2PADp+oABiUheAF9NOQgBleUADFZwRzfrvlzsU22kkiABpvNTgBnRRwxv3GW+G6RHBs6GItsYhJEAFTmgBT9wP4AQ2VeexCpsqJIgBzv0ALd+PPzcrR1A7BJAi7-7IY-CihtJs7-qAA68iPoAFj-HGiAxwkWPY4oxa3Gx+YqEqzISQVKAYfU1OX21wTUX8zORAvizwsGBGt2pANuUAgAdh6AAl0ZBqKKSAgEkIAARKgAJmmQbliZhihJDI6AARtpBmmtKEkFjoAHAqkGV8P0Z2gAs4mAD0KmAcNiaG2EkAoYAHb+kGE4R0mEp0Qe4+mOrBYobY8AQBLYSQ4eD+gAygnh5iCABaCoAANygAEnKQYZLRSChVxJCACn5oANDuoux2tsgono3oSQgAfGaQ5qCACK3oAOLKgA5X7BE6hvrwBuI3CfyA6QBRGACQxoAHSpgAfdE6EPo05EDiKy44ylR5DkAzrkErrMikhK7K6LqQYICJD-p35k4q6AAG8nIIABragAxhbwFvZgClFQDlGUBy6n4tiioLSIh1FEAg6NH-oq6AAIRiTq0W0EkIMYANUR6xKuIxYxkApUxstK4crEOEIICxUASxQegxgA+saADy6pse0VAJ0T0f0UMYcebtUoyOQMgFMaVLvOwWDoRvUaDkkMwTwS8Wdt0QwYAFnagAgZE8GACb8YAFRygxgA6CqAD4-98chifkCWYRwtUbUTQcNrcVwdwS0VtjcVsR0WTjwb0YMXiZOnIZQPgUqGzAGNcbhhCf+oAADpiJyhqhDmbRsJgpwp-gWOgAKXo96AAbykLnIEUcECUebgGMyKkekZyJnmSaKQ0UHkLoAJym+RRRphlySQgA79E5GADQct0YAM8GiJvecg+RgAMP+j42ncyHZgB5GACm5iIcqSyREOobAJqYhNqV-Dgn8T8BwjyRSf+tocTvkWaQ8EkN0YAGA6QpWhiZeRLpFpzBKpiG5uA2YZmR+BFMsA-y9BYJix+pmhWZROSZNJ32O2SQ6xCZDZeRVOqpyGO0sAckZZ18Tw4IsZtZ-6UOsOTZ3oKZ-63RgAuDqACr0b3oAGFyHGvZck3G5OgQgAp9Hk5iDjmjqACwcrXj3oEBaYAMABgAimGAC0sYAA5yE+WOiOk+8+S+q+gZ2mUUgJW+kMq21ZNxo5UAgxgADqaADziZhoAGxKyZSQ+5gAV8pk6AC78n0UIIAL9ygxp5PBgA56aDGj7GHQ5dmFnIbpyB6iqxI-TQFA7kn-mQCi6ABmqgnsNlOZIdaYAFxyBgKggAhNYBBY4+mi5yCAChioAJ3aOAb5UA7oYRbwVQ9EcI5EQ5sQI5fJUA+OsRiRkFnGcAcIcQ3GB5iJgAAKmACD1t0YANJytGmgcgugFOHG3QM2Gl3RlggA4-FyDE7eCAC-CYAFjyOxPePpiRsRgQYAiRgAO8GACqymIIAPI6gAqnqADPyioIAEuRBZvW5ufqm6RJ8AkZbMyAclyxjBTB0Jk5LZM5GZPBWegAWJqxEumABjigwT6YAC-RROHGRIDosA3GgARnoU5gBwlIkomuGOE4nCWQDYTKiwiIyvKkCwDgxOiWSXDpVB53744qVQDdGAAb8YAIU2RO+OgAuyFKDk4U6AAx2qsULoVXIC-j6WtUoLFe9kWWkSWeAhJTNtJTGbqZOnGVAIAHnaPejZt2DF-66JAQRORVZOYegAtCZqC6ByC975E+VY7WkCCABuiqOnIEIIANlyLpgADdGT5iD5ZWUYDcYmlaEWVqWxCY2joBFQ2ABrcnIOZeKtxhxhTXlkSAag8CGrSLskOMWRkciEONxvNothZbTfANxmAAANRgCABrRkYPAYAJAJgAl0aABcyoAPvqWOLgYFQ+PBgQVN5AfNtVQC9NnQ0ATNLN4Z7NF2V2VA3NAM3GeAORgA8vJY6AB8ploYVWiSrdTRrXTQzTrczRdazXEOzetsbc0DzWbWAIALPKgAiCq22AAE8oAIAJgAZHqO1q09VZgIBFA-SWSzr3XgkZWQCADYSmoMoIAOAWSNs1kAgAm3551I2ADusUIGiXIIALAqgA6tqBDdG15Y5iB12jpODK6V3o3qWY2AC37oAMdygAgB640Y3cZY7t3eCBCAAQ-43c3Uga+CCCMLsrMJAAqnap4c3OQFwO6isMvf8D9BOEvZACUNhLuM6MvdxiiYADOJFliA3GZgqx-dA9gQgAkP+tH6l5CEH-of3MhgBJ2-QSHdmTo-D-3kC7yMJLIYw-nvW5VQB7kw6jrdGwXZ2AAkcmiaXaeThVjtnXtfnadaMfFdrbBMcClf8ZNZCUwYAFZKgA4EqF3pmInUNFUlXlVVU1V1X0RNUtVtWIkdVdW4mAMRDsiy5Yh0TMDDVp4Z6C5p01nyWQC6CABURkoLQxmYroAF+KvRwNCjgQgAQZqAA55r0YAF-qCgWegA5JoukKO2WADQXmmS5Vnm3i6YAChyRO9eiugAL4EBCACUuoAMF2eFcV4BhDxwEluSt6IKdEsAJDaVUjf5MjzB1DtDy1gAzbGAD4mp4F4D6YABk+gALLHomy0U5cPUPdUlGfbhAoZxDAFp2QB62ZH-KtQhpkW-mQCMJShJ2sBJCADfnkYMoCFmYU8G0ucGAtTEkJLbLSFs8KwKgCGgiFImdoADoKgARta22yHDWB69MfyDr-qAA28UYLEZBplAiEUErGCCSEHrbfbbIQ3H+PAP8jKKE6Grfv+iHQs5OWsMgiJl8Fc68PRLc0kAfoALepxg8JwdrRqkna8AJqE1-67OB+YAzy-I-YOzEz8AKz-TkjUAtt2zTZCd8Af9KdSQ2dpdphIJSQelOznQCAxspLbSOEJ6Mo9ESQmTKgld61Yh8IzoHSkQsAvcM0d1UAShPekdUdgAI5GABISvC-9uQNkBBMZNkDwKKEkMK+7oAEbGUgfBxwx6pIMldzUAsTGLm0eIarvS3LkACtfBpIP0+rGrQhwhktOzPA7AhyQeYtyOnuTZ0AkrxA5LeIAOSQErzIxkaUcMXr-DFBfTn84zjwXYoTPJDweI9NiLIbyIXyP0oK0iSQOReWA2fNeRWOktsRcpi+l6TZZAsAA25Lewgh-6gA1-qADuxnkXgBxhm5BgyKQAkLAIDr+UQH6K2OC1AIABKmgA4c5AZED+5YBJCADAwYAC9qg7TAEYgwSQ-FwFU7jmUUVQySQi4rvSzGVGaJzQ1Gi7UMyA0Aa7qW3bkAam27u7NJZRySh70ox7g4YqGdk9ysgAsAqv2Xt-lLydbcavatYfb4WTpaRij0xHMIBDVgjApfORNRDn5UCUX76AeRDcZH46spIgkns7WQYOhjUttJD44cYgg6jjLcZ0UOaUGxCvJtDb7ltQDWlCBH5BtQDX7gc3y3Ntu3YrShEdCyv-pE4i40UkeTqlRTEnuG4IV4NHGiMtNQePWQBKVJFNlkcxCjUstJDKVNlggSGcY8bye3YafkCltiiA7JCtZEBCCLuAAxcou4AJByi7gA22qLuAApcou4ALaKi7gAwHKLuADWiou4ALpyi7gAgsojEQAZBNk-C0BpCHDIBUeRBJCAAA5oABtZCRk9tVtYII9E+z7L3Gz7-br9DHMAwUYIcAN8bHFFMjgA+36ACF0YAIfygA9gasG-CICa7kALjXEdsRjcmRMPWUUG6AAlcoABtyU7+6lyMoqSw5-6URhjo6gA89aACznt4L131-Y3fk6SBXg-++ZlAKRNJR1+RRt9IxnZYIN1AFOSN4a1EcToAMbWYgOxlgKTIFLpgAoMqAA3RqOoAC+pFggAlk5re+N7fNniitQ7ftvp1B4R2AB98Ud82cN7a2d5Dt4GD4Y4AG56-XcggA+AmABlet9+9r+02dfhFhxKgFJRRDt5AAtctZYIAN9ygAqvIT3Hb4-SjtZB75YkJxZomPxgDdZ5fllUxfwM6KY8ms5ghWH-oBDGaveQagKZFhsIgnuxEgXi9iittS-E-8ty8KfHBUElcbeQDTZCZB6-6Ltc-gJJCmnvsNOM5JCAB7atPoANxygAMq6ABG6UF6MXl32RGBWtrim9J5RYKWHriS62QDqB72dlEWHpBhaKKEH98z8z1X1dS0BEr6nbt5OkSHAEkIKT1YR-DKQIjDyZnwjJ71APi4W2KkkIY8mad2N1AIAGe6eRgAz7HrPT6l0unhV5E8HoOq2U0U1pv1se3hl82l60YKCACdDni0oPnW6SPmIGLfCYALLyWhKgXd+N3GLfw93d3Go-+dBbt2Cd4IsxNUYHowLHhr6xG-SN4n5uQEGCQ5UoVAXwMo3aXvMjgAmqYWNh85+ddQDyQlBf9tAdANiJ+QA0aeNDSoADB1LwIAH-3QAJCBq-JfioGtqd1gBmNdnIAHHEwAFzmMAjSj6RRxgCBODmL-srBKDVIpQWoAAT3kX4aV+WGAzGmmV6IoDUBgAPfjAApcbT5DGKgcmmrQ76AAF40hzwEe8vRQAAT5udcgZjRtII8RaVA7jPy1wGTov+AAZhKA7goQSQFEsIM0oCAJBldQAEDGqAgIBTk0B7U5AdAwADEq-LbihWwUA7VAAd2651Y6nfNWmAG4HwFLaeWRAdxkNrXYJB3pH0iczRJ0CXSfeVQVSk8F5FAA06brNAAwdqR5vuf7H7lNh-AUBNerJYnoACK-QAE5BuhEEHRCSCAB-v3SEKcqWSQVankNuyesbYOoJIIABG84ocNlLjkAjmSQQANS+1QhzNG13BJBAASunNDJ0OoC0BwX-SABfNy6ERAHQjEXoCewkBDCKCEzegpAEACLeekM54kIvkmSTTkn2B5JBAAQjqQYuwqSMipAEex8FdWmpJIArUfqHEimHbMgKwE45eg3gdRXqgrx5KcIheUAflnoEADOeoAEMI1AXoEADlabYXL7Q9K+kAftjTVS6hMMuDVZ9mAEABJhHlhWiQisuPVBmKsPqbPCg8KAwEaN1kr-pQRKXGohCIOZZdYR8I6KIiOfY9VSINUBIU8LKZQAqGgAJyU9AYQvQIADANQAAfKWIw1niIeDgj0uRI6EXCI4wIiBRlI1iPRDWZrCiA6IpIIAHfbVIXoBUCTDjuO2CvjiN7Z9swRBI-kZl0FGkidQ5I84WdWKYS8je5TMtuyx5Kih7gBzVroxzpGQB+Wi7E7kCPVGQAG8EdD7oAEGVF0pbTEFGBvBdtNEvy2iF5cURifeptaOQKWiP+kAGURCzQHOjVRrozVoAO8Cj5AAORmpC4BWhH0igOJpRCneYxIgIVBuAvM7RcYh0YAD+UwAPD6dApMVD2xGpixA6YkfFmJzF5jkBBYwIE3R2JVjGBYgIQGXVDHrciADoWpMaCOBQhj6jwqDlGNtGxj4xUAf4Q2OBApikgTdQAHNyJNflkPliKABUvWtL24PR3o6Iep1eDkBlYFYpcZAHM4JEVxpvF0U2I3FY5txxNXcQeKPEnivRI42IR2xJDMgEAEY6BjaJjFSiIgN4r4agNXFqjUxhVcnIABQCBCWmWJyABk+OVzvDAA4upiZAAsonT40JKjM8dv2JDhhrxDowzIAGj1OwIAEFbaCY+OTHPj-0gAKKNUG6EuwAj2nyV1UJKjFQEROGwxJ7ssAHsKEgBygkTO9ol4ZAEok0S6J4kyHmuMYlQAWJaJNiRxK4k8Tfxxo5Pur1REgToxUDX7jeMZGyTfuT4w1mmW8CbiVA0+a0lQ3ZwI9uJKtVwbo0QaCkYaQgQAFLKyNSfExMABnyp5L0qABI4xdKAAyFUACYSsZJcpzMtAMBcypZTX5FimySoL0GRMknGTJ6tnYOm+zklmTgRaZdCSkyoarFbOgAdXUnJI9FydBTcmjohAJU7yUxJJpyAgpoUiKQyNQFRTZmMUuKa4KLF5c4QBXXSfRXgCgSDJWvG8WEJMla9cpboiyV4EABeGcZkAARKWEIACcqsDHolO34PByhi4h0RNMnqAAwBKWnZTTJDE8yd4COnLT1ma0jadj1uwjAYuu0ySTSgGmiwlIqsTyDBPXH-oXpgedYGBFOAEh3pnYNCG8EvS-tOewUF0INIczziwJQPSsZJI5GTShpjY8yQVO8CAAfowyaDjhxujA8mTh2KAAXt0YHYzm+UgFJm5Q5FiAq+FM7wCoHt7gzzMMQrSREAxi0AYZk6OGaNOGw3j5RKM2GWdOBE94nAgAVZt5RaZVBlmNlF2Ay6PpXqaOM27iigJVo4afpNSlB4lRAsrmULJmmAAXUzRLeBAAQbYqACpWYvibDKOAtINZSQLWZPUAAzyq+y+mKTIAgAGBVjMTFVicrhSZKiXSU3NikqOgrCFAA6AHIVzZm04bMlO7YIybxdszKSdKmm6zUxTFbwHIFs5okoqJsg8q7LkDhy7pw2DGDUTGE2z-0Ws52eZINnGzTZ3svOczJd4dBmAqskaSXKgCABg9UAB86oADcLcucCM3HE5059uYOtXO9EI89KkQwIIAA4bQADvxFsydD0A6AjsnpQeQAMtygAZL0e5bowABUKfRQqoAE15OQN6JdJE4hA8JbeSoEww9isc7lH0jASYqAAiu2omAAL1M0n4NkMjqPYKrP+6rDIA-XIFspxdBJAjqeOMQufmqywBeRZ2Y2F8iWx5c9QVxOcWrIXHgTpRDonmNKH5gwwuSG81MdbGiB2w8wS0FNH6AyxsheY-MJmbJhZmvzJ0XoK6AIUuD9A4Q1I4CUNOblLy5s8Q0MBJVagqz6JaM4EQUDmKpJUoow0MCmDPiYQMwPC9YMyAoWIY8u6CPmHiBKBYBeYmCFhYLK-kADgS+8IFnUEUWB40FSipIOHHPQ5U2FyCiSUHiMUYL9FaiiMNgqSB2KME8cUhegoJB7ACQ1SXJAzBRBgQ5FvWWBVyUIE0gcQZBBBRYpjkOjWYRsbIABPtazo+FCkw1nEvFCtsoEiijBXApsT0R+AsAHUJigjkOYWwfMTmQ5hvExLdgDOUpYkpylJykg1SseP8AKVuKlFZodmJUlRBRQAlWPeRazPy6Nh8ChHa5IkKgAEdxkhAnSeQBKCYQSggaRuY-wzqMjvAhdQALYGgAHNVcm+OFcq4OMkSDAgkUpid4FUFWSbJEgoqcgw8mBBAAFzaAB4Q0ZFyBB5Rg4yXIEAC45sHQkAH5bBHfFGkxIPKCk5AgAC4SxMgAEE1AAYC7BTwp6JdErEQ6kxTAgTFQACbW4eIut0VKqABwTR2Uj0O5nciQS6XCEuUmJxOa2oAG34wAN3KB8r0UFPP7IZxl1yEoP1MDwaKuuMjBaVdLWWbLui2y1QRNP2UEq2VYQjGV4Buk0qkhwyhhYBHohlL9ums5UfJKSAbKtleOLFWvy1n7KUBCNLMaLEACMOoAHmFboigO8BCBAA7BbeQ0yUNMQFrNHRWBvAgAZb87APpWaUqPYF2DuMqAbIPARcmABigyJypDAAT24ukm6YgIoqOl5aqD-VgAQisaxEgnxqzKHbRQJl7M6VVEwzoyysxHKpVSqqX78z9lMKmIr3lUFiz5REgyWTN2lmyyfSoqoMgmvpULxoZzK9Yf+g5EZquVyq1QcjP2XIyXKC5ZSUKtUHYyJBuM7RjoyJwKF2RQKsTOTLkDoS3K7a9kYOtpnTrlcKge3LGuoXVrxVJQP0GkpVmLKg8YmQAN2eVgdiS2u5WuCoJ+ysQMYwom6BR0LpKCYAHxYwAMSxqg9iUPkPUSD7a-LFQJSu+UU0eqdKhhX2RiBRRHp4E3khnQfHQNzS-6RVa2qzUaV-h+y7ooAAbnMQFuJ3HR09xMRQ8d+KXJrqjigGhlUsyAmEDtpZDf9JdLCGnq21rg3lfFKX5yBVBl0iQXm0CDok82TdKjeswnqS0JpgANkcpCORZelQGXq+lHWHGxfFWvjWbrwxhAlgGWOtl7qkgtY+sTlRg1zUz1I9VTWgIkGd5whZORJqoKYmAARWONxh1AASAlF0JBJNPwYAEromekLni79tDByAszQRvNxEbxx6C8WNOItGwA5lF4koFeOU3-o7xUG1GdOSgBwatNa-cLbYVzUCB-hcNNEmxvi01VXBQuQAP6pcgMOqhMAC7sQeuQ3zUm6sonvNnLkD-C82Hm2lTWoYXbrAJ0oQgSRKeAUaoA0k2iTRoQ2Y0L1DGjSnIDY0GbEmjAwAOvKXsl0uxNWLqSatYqiZRAtI1Ry2tkATKcZK62qC9lfWzGkxtcGZTWNUm8IU3XynezvARU0qYABgAg8tBQEBV9wqyDEqTNo3UTLJVpGy4FbIyr1MZOjssuepqi2QAYttGkemqs23cZttI9R2XtsCAHasc7sz2YbK8C+z-ZQc0OUhSzEPaZNT25WU1sW2haoAmU77dBt+3-but3GIHTtuDqDag1ldVOenKioqAjZFW1HQBrq1bqZ2i88DTJzXlrbXBOKiQQNqk3E0m6fRTeSfJAqUq0dYy5nSMEyGs4ltBgQAIyuUajld0UzWqD5dUa-ZWhu8DWMBAgAeLTUB99MmpPQPI95AAo0aABh-RdLh4KuQrMQBPl1xt1lce1AShTly6KzIARG2PgNQL4fbKKTLH7amTQ1N1VBCtTJhIPUY6A4awK-Dc4M5rGxvS-owQT6Ulq1TZaLpQTTkVgh5EFaf6tWpkwR6qCDyAgQALKKgATlimNwOl0t0UFIFrXB61Y5cDvSYZNei61QIHXq8ACBuigALCVO9yPGnnl2vwMq6tS22jshwJ3KC6Oy1QAGqagARqUXSgAMXkBAI+onC6o75gB3V8BGyhYHsqqDicEg5ym5Q8qqCvKMRfZT1QH1EapdVkWpsPro5K6KcvkwAGialuyPAbkADzftbtt2Y4HdTu-igRouFMBKYZotYRBqDwm9kM5YBABRmuajKO0BisDZAEABYCT3kw4p5rqwicNkkB7yAB2Iwd7LZLou4aXkkES49VWoSIWIH9kuBjxVZEoDnIAEXlaHLrhGaYBJRkAQACEZleBgzsykpJALuNYzg3lwl7OY+hUAQAHFySBISVXG4yAA0f1jw4YQ0FomAyJR4DZByw72uSTJ2wMO9jGhmRxf+kNJylND9vbQ4EEMMuUddgAAXcCi6KsTIAAr4vtoAEp-a2i6XRJFFAAzYrwlHDgAFetAA0fJr45JlyCsHcI-4dt3QTW6AD8ELBxcdD77DthEfgOABg+OiPiT41iCENAAIu6AAOPQh5pG2dkAeI8Ywh6OpcjsXAo+JKoVxqIgw3H8JEEMithIgx6KhGCEeR1N1DlFRw4AFcHQAPKmaPXQ1AH0MdHujk9QQYAC27QAHbxo+QAGeRgAcuNAA-ubP0-Dv3CmI0clDUI7RIR9gNMuDS2w4ugAOXkIeWxnaVAHiN7GYjEu1Iz9B4NZHTjkAe4Kn3-TxH4u+x0I9MtuNnYEuTvXpZQqbIho4ghwWdrGJk6ABb6MAAAUb0cgD6GQTgQYnHIDjyAAwtzl2ABK50ABt2pwMADZ8g4ycZk4rugAXtMtAo6NdRUaIDTIdIwjTVgjJk6AALRWCpgmqTD5J8gvgCAr5AggAUblP90OUdMeVnmVGpxLGfZqqArEydfmgAZ-Se2YJ35sThFNcmv0ZcG+HycB6tGZGwpwAApyYpn5hKaVNSmbigIF4eScooO9regADIywTktfUwacnqABH21SFD5AAorapD5ji7OUC2EUNczk6SQS09kZ4DLgzstpj4872ZlNkF6JoYgFSkDwCnKKEawAPtGgARIy+2egQAOxKIuGM2CZclyAoi7uAQGAHkgAAWLM88g4BgA5AuZMQFfSNIJmYzzh41QECboXcGCCgQAJwWgAO2NeiYVElU3kjOBAF9KZwAKyugAREDAA5AZk4DygAZ3kXSnA+LmWb7b15AAsmk7HAA5HqAVNTkACsJn2gCQjbWCLMMzI0KoKFHmdS-hW6PZxKF0SYtQAJ4ZBlKQtbWtKxE0yB5FyiIViKS1AggASW9XZIhoQETI9LuCqA3pRc2iBojkAg+zplNUHm4FWAX+YJgQCFKiLcC9AL-LHIACnlBGo1LDxgqccAQOQAKBTiABhRUAAEvoucaYRt6IcSrtpuYzrtN0eYJ-Q4ABETXVYABZNciz0dN6dsAwQF9Y2EbwVxc28+xji-ca4vXGQQ5x9I1ceSNQBXjSQeIxWyeMbGSgYl-9IAD10jI5JeuO-8I2+IGS6Szi6SWyj+chzHRBea38QNYobIMAyOQbmATlFQAF5mZOf4budOn7nUxvLKQi6Vtr-DjMLlNMnvNy3R1Wm3BHyoiqf0i1-hTdCtij0ABfKQUX+EukELPlg8oAFH9REpVtsKLmMkGAKKPa1ItB5AAqmaAACMzBO8scrLpNMmFSiqABeEMvq5zUhcpc0y6SFz8VAAyGaABQNMADf0YAHDTXXIueQLPAT8aB8gFdDA26mZGxgBCq90AApaWCeLOX0pjYFXogEEKpZbReCFIQGxQn5bUKTvzdEpuT3ZSrerk0NY1AGaglAms4mCTBD3yWkBDrQmDrP+mVjdZrjjIKUBdcUxXWoAAAVlusiWoMdER60pioyqx3re3RYs3HojKKmsWRNWP9YBsW510LSE9r819PlH11yfFrbACRafwJKY4DK0kEAB9PoAADvWIrVzBP2HDM+NmroAFUdSHIADELYdYAGUjdnM5a0KxFjM15g8oAFjFKIrEUqqAA4MyMFKBAA4k4uloK7NmIujyHwk1AKDZxcxcheZEMOWSVcRkAYGsZ1fm1DZoDwUABm0YACkVZMzo1puFXWbYgahqPh4LyRVYqsfmozaiKa3aui5vSy0ngi-hKWGRRND7mTUyqkgkamsWCbRMI1bDWY0yoAHdFQIJYNowl5BBrTQAM+BWYszSuuMwukwqK6lylESzHV1AAD56LnGVHCKAqjclGK2g8SNQAGP6sRQeWCam5CBAA3j6xFXKSNC2oABAVViktbkBhDB5w67oq-oyNiBs5sRMuxRIMqvcqGCrZw2iSKIuU7NAQIXE4EABIQYACAEl+TEJpwVNe+mRe4TJ2xpe4dc-6Rwb3n7wLZjYegL83oB9oU4US8NNQGIDRYxFjMROCrT2x0YLHq15ZUMp7XCVQBtCq9n4oHigN4gDOOkHkqoowTwGkDjbUppJJFKTpOEKVyDlAEABjkVFVFaTNI2-6Wy8Uu1rmszsgATyNgK1rNXqswGb-pYi1bPInA8IuwB-o1wRkF60QcM2YigAO-lAADpmEOwxbAVgAreIm4JUq5DcXuUiSCAAV+It4JY2A-0KUIKFtn8PWAgj+AFSk9MHIkg4VUR+I8HA6hUx1pOR6QClCmxTsSQKvnwVCb082AlvFgQoFEcAAtB8MgAkpJBraBR0LmwBMffB-kxwJIETb4JuRE6ydb+afwSyM5-k7ADXFcNU4JFAqnjxTN47oj6FW2SQSroE-U7AtSQYLDnAfhhZwtonGAEFuHHdXo2AskASFvOasCABgGPnIE2FOs414dHRCzxLd1UAKCZhyhA+aeTM4sCZAAi3FKkIAAtTdvymVJBVtAZkjd-ImlMH61SQZGQlk-Dfz+ZJLS-gAPx3kkG5xAJIDisWYDTDIFweAFLxYMCr1mCzwPNwtEmkPD+38uh7WzACGkmK3GvgjG1JDZ24gibe-gX0gA5sYiebQ4Ww-+JJ1aQwJcwuQwwfZVt+5zuNjg+ft3OJa6LW7AlVQf6EasUALnBg6wcguUH3TWAKg7XP1D-0kte2sM2se0hUH8EVgHsONZNldmxD8FC8wKBvNrmnzQ1iIX+aAt8XCLJFxnV-xIPJ0BL7ZxcySAPMtCTo-F6S3gDks4AlLfqjSzOz0shAgAAn0-dsLzF-C5ltJBtWt2QRpMVJOiMzsqjBRio6lDnF-USQEK+02ZYug2WHLLkha3-S8t+WwrELG605YGtwQpxF0NK245QB5W8BJVjaztbCG7nTrIJ4cFgjRAKYc2H11UvN4us3WHrCh1AB9bgKTItTL1k2VoUEGAwjC+EIiHPT-p7bKYFl7wrldkLlFf9s9AAJsUEhnFubyDNkv2xZvMFVxQpv0qnBHAeZwF75iIdAfAYyIewovHLryybBiAC9Q+qvXZQOonU2KF1LCF3rBRSlsAQ+sfR+Nn1IA3GKgHPFBTrA4lNLLAOQBvrcZJ64eZ+uzloMukEe9jN-Sbhz3cZ5gLku0oACHlKwFu9zIBF2389YaYfQ4x9vsIyyI95AD3qjvx3J9YtOfW3o+xhQj71d4e-mBfV-Ahg2g4AEQdA8kuUAC3DoAFGDDC07muRgBAAfJ5S1Ty7dKPBhbnqdu73y9DjPmkhToFnQL7t9wfWXoTvT659BD9CDdzu5V3K+imvMCLxyAhTSptt1h67fL0e3ZyKaOOPppHAbkdyV1wDki57wy4w7-em2A-eTvz6QiVgMcjoiruwAYFGAkhOJoCA0SWeQAEsWcgQAJjygAFnlAPMQWLk5fDx2lAA+IaAAiGPDyxcF8gAaHNAA08o3vsPi9Tj7al7fmh+3-KNDM6AZo9gToxASIOJ-fdkfP3U77jK8h4A+fOginpCbo2WpWBSagAIH1AA+Ga6BJ69YN3qQGfp+B-AK+F0j+9IA3mXKfRMQLFXnt84sA0QFFmCRANJAGDkuIgsUx+z3C1yJoHklfBeBxBLCQRqAIACMDFwMySbITFue3XrIoACQFZXIN9oJRRuvEDXAv+li6FVK6U3-iWXGeAYxyEj98MlkTftyvaAQoSgMiD+y+uViKjeRoo056AG4gYHAoFdAuDlj-0cDdk0eRPLU4QAjQIAA")); })() /***/ }), /***/ "./src/js/built-temp/base-zh-TW.json": /*!*******************************************!*\ !*** ./src/js/built-temp/base-zh-TW.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBEDOAuCmBDAtgBUQc3pAXGUEEMAFgPYBOsAKvAB6y5TTGIAO8AXgHQCWpYgejNAAHKA+a0AU6kMDQCoEJHQFEJgbLTAIW6AGdUBo6oCg5QF96gAgTAp7qADvUCADICvAwKtKgNGVA+K6AiV0DgQYBFfQBAqgCENABUqBwSMA7aasBG+osBSCYBMRoBADJAANOCEkAA2pAB2GDT0jJAA2jzIGAC6wADKVACiAIIAsgD6RaioZQCSJUUA4gUAvgD0dLDkiNCtcBTwZayYAxg8AGZco2OprRnZYMxsnLz8wuJSctJKalp6RoDgOjYOLh7ePmbmASEAOnFigODGgFnavoCACYAqCYBf6sqAMfqAMP+ABvKAYHNAJJmgCxfQAocoBjyMAacmAX4DXIB8BJsikADaaAfKVYcFboA3VyevkUgA9TQDziYA8jVcgCEzAGAUf1ABAZgBeTQCiiv9FAZALJGsMAk4aADblAEBRgDrVMAAWkFYEAYvKAUiVABv6gAwowDjMYAEuwBgAB0wCBkWJUgAjLKbbaqGZa9SMrFxQCwcoBROW+-32qsA77aAJyDAGRygC6HXzqO1CkU2wAxKoBQX0MgALfQyAWdDAKdygFclbQowDyGXbALGK+1ddsAYfJvQAIRoA7t0AmFbGoLpwCySoBIc0AgsqAa0VADupAAoOYAnKMA+nKAAk1-oBN-SEgGM0wAK2oAwuQAlL9ADABgEQjQAhCQXABH6gCxNQAQUYBrV1+gEBjQAxfoAXsxRgFo5ACEt0APzGAdpjABbOgGmvQASTop-oBnZUAgyYFwCyGYA0TUA5oqATu1frXAYAqRUAEoqAUuNAB+RKMA0amAD5uT7GpqWSHied5PvqWS3Kk0Q8HAsFxIQYCpAAVFkYCAI+2dqANxygAyGbcqEYVhaiZtKxLSIACmmAGxKxGEKRYCABragApVlRdEMRATFLuOgC0UY8XFoZhYBnvsgAMSkmeCAN9pgBbvrYsLyuuYBZmIABMAAMmmAC56gDAcoAEOaAKl6FaAGe6gDPyt2gDyqoAaHLGiRIliZJeC8SiZaAIbKQlMYA1nqAJVKA6AD5+C5AQsLDsNwfBgIAJuSAPB-cGtAhSFwVqgBU5kmK4wbcA7koAHHorkEvyADB6gDY5rCgAWKkum5xPBiGwMh9lYSagAwKioqi2IAiMaAAxGFaAPMKAgFoAOWmAJiegCWTi13aeSJgDv8YAddoVmIaiAOvKdGAGhGgBXyrCgD+8oAFK6AJ5OjyaIAk96KIAowaAIM2gDQcu8vjjShjEiVIgDTIYdw2qqmgA05oogCipoA0XKAIRWgDw+hNWGAPfKgD9UYA5cYtZYqaABZqFYKq0vitIAY9qAGV6YOAC6mhiABVpgD6VtDgB0Xu2gCS3sTN31WAvG+ATgB6GUDYBBIAEqawoAC8aAOLKFZnht+aAE+6gDJviagD0yT29MjrxvGVTMCW1UlWSAJgJkhBAI-7yoo64ZXEgDfcoAqvKAF1ygC-CcDIaAEUxgDezr8A5iIAfJ6ACX+gCHEaOgDctoAAAGGIA6GqAGZRgB7aoAlfqAAJGBaKJogAO0Q6gCHbkSgDDyoAwAGAOSagBt2oogDwhoA0ZHBGAgBM1oAp+6AM5Rx2-FKnbaIAVFEDooYBUOQ8DRLEYCACmqktaoAxAmAAq+GvVYlt3cSJqQAK7kNEAC8xCwLArDQDgrStAAJohADGFDT1wC-ILMcQAG48AgrQABIAHIAOwFAAahwx9ZAA8mMYw8HPPCINEYAACLz4vMz99EdV3VhfcD8Po-j0nq0To1dYjL1IKvDUrQai5AAIpxDnqwAAUqgXooVOB8CyAAJVIIgaeyA2DvwHl-buP8P7-zHhPKeAB3WhXAq7T1nrAcBq9yBoKWBwTBuRe4agYUwohn96a-yHiPShQDRiwGIDwlhwDSAamgKwNhiwworCyLkUg-c57wDAAvae2iKwNC3jvHh3YBEkOEmQv+ojAFTwkVIjUMjYByIUUo9B4VSCtA1LEKBBC4DwDYZ0RAcRoDREQLAPgwTWhYOKE-EoBQuDIGnlkHe1dWBgECcE0JCAzFxWllkcIkQiCz2gAvcg08AAyPA4gAGsUhXxvnfB+z9X5lKFGAAAwiwWAYBqFb2IGAZA8B1yQEiM0CIRAMDeIfowAgURYh4KqRgFIrhACQ8auApqFID+PIBQFIgtAAlURsqIkiNHQCCdPaAL9N56PICkKA4yoh6LvgQ6IuR4BDC6E425eBIBcCOUQaAvdr48FoDMwpxyyC9zOXEC5KRADCyv8qIyAeA1widAFIgA-N0ADQhiKiAahRQheI6KflFkACCKuKoCdAJWilIgAxRRGahMZ4LIBVJvnELe2Afk0URZAcJgywWoSIPEeAbyF4wqKBgUgKQACMgAlzzzBSyAtBRXxAuRKqVPyAA8tAAB88rFXCpKFU3uCB1UysAGBKgAMFIVQ8zZtAjVxBNfAaAZqtW6qtTa8FQq4jwB3ho8grqoDSsAPA65JPWCqgLQP1-cXWSpSNqnVobw2CsgMKp+iAACegbIDSsAJSaya7XpozbGjVUAE35sVdAeAYqLm5DIJQeNVaa3QD1Yq5FjqEAuphSqmF0A60UAYFq9tTqW3mrAJqptqqW2ysVZC8gXbp4OpHf2htWq50ttDeO4dnbW22qiPa41nb43ustQywgTLNnVPgMWgVKbYCIA1CkKgRQABCiqxWdFINEFI7SqBYPKYqh+g6oBFHKVQRVzq55LBSAUXI7TK3EHGMByAuQd41AAGLgb3QCoYWiUiAC8vQAPBZnogM0UZDzIB6OQKQF9QSfXztvUQcJsBoicqgIAFHtABcnkeHlVTP0pEAE7OgA15QgiGGEAcMSAEB-s9F6oAEKqSUeAjrGNQFYKEjNKR-yAGnNIIPK54sASNXUgSyfkrkAKemgAYqN48gVgA7ciIHXvADAKA2OQEAHA6gBTRR5aQdgcR1GaN9XxlIb0gg8xVtJvdlGWkVKqbUn5gAM7UAJ2mL8SmL0AFzygBYcxhjy4gqTK5BJCWE1zvkByAEQFQA3-6AHtoiLzLeGkGoVW8gAB1RA5B2UJBSKOQAjUaAElrMIYAQuBDENiPMgB4B0AL2RMN1DA1hIAaQTAAyEYAS99ABGhspba+mdmDOWoAUADhOicAOn64klyAF9NRQgAVrMAOpZoRItnMc85wZ5T4COe-T8x7z3x26p5bdpzLm3vVwAKo1LiPVuIKRkpZ3cnp+I4THWucCjyn11CGguZSCiXTkWCF6JfRpn5gAdeW24ALH-NWIBNfWwUCEak6q+zwvhW8UhYPgIwun5HIhRYfsZ4l+BasmqccElTQq4tQEAF0egBYqMVXo1jCAUiAColQAJmnvqCVol7UAhOAAjbRVWT-EpEANJy3xFVVzgK15DgBZxMAPqq+vnXwBN4AO39FVYFgLke9ML2c+sE-tiC4vq5W-gMj-lPyBxZ0AMoJltABaCoAAblAA9eYqze8BqH-dYNPIrKRACn5oAaHcVwIfq-HjAXQ9Gc8gIAewzOOHTZqCTP1CADS178UwsWfnovgBIY0AK7JfFbfgtk0QDItnKD2buy5go5AdnfK5xG3lW9WMpEAPTKHmDmKoQMkH5bFp+AEZNQA6qYE5I2ADvUAu92Ycz9wZ3C55aOgJz2ZmzmMT5+dP1MaI58dBSEvjzt-N-b8gPd+A5TcHT3Q4gFF-c2Nz9jlx9XM2JABYE0AAHre-BfKANiFZDzNfDfdvSLMVG+cgZAXvA-eAJ+L3KXPAIApjEAlIUXOXaA5Df4IXR4FUOXOWNiQAOdVAB8f9fxu33w-xwMlwiQHyH350pSIJ+Tl1n2w0pQf0X1YjlzX2YOZQN3vUoAZwAEde4eAGEeCx8WNXNVQzcyCUh-gNDTcggQxAB1TS2kACjopcRQVvUIZA5lRnLeKvDNGvWeDrfAr1XgtQlIJcQATlNm9W9PcSkUhABpqIb3On+EAGeDFUbaRQZvX4HbII2DdpJvJMNXCwyQzZA3K3OwhwuvdpeINAghcJeIFQy-VzY3a3AOZvXwueFIOWfYQEEosopvX4fw0XSwxlSLK9ewqpRwjAaABnKtWAC+QXAg1wq-KAEozseoiolIW-MY+o6TKwzZMYJAWAAA3oqlOefI0HZw0fIolILjHjIQyjSDbQz2baTscdRYsJAAnVMADEYIasDEMQPY1cE0YGLaYIfw6OQAO0NdxRMBN9sTtzsrsUiohhVMCP9KlkVgMhjVCRjIA2JiQ6JJifknj1pABd+WYiEEAF+5Nid4uXQAKCC2Ids9tjw5jWjmVe4E8ituFkACFyAccR870+CoAVxOwatR889KifkQxzonRjB1BABCa30LShREUCfBwGBKIApJzzwWdRqDiE-Wnl7nWIiUKKZMgBhBLzLwOI5O0JsEADkExQAOXwI2QAaoitokxS9DpggJ1P0EgdUTQVRAB2pIgP+G1zzB0BZH0Ek01V6FtIwGuNL0AA8EvkMQQAeR1ABVPTMnUEACXIlo89DHboS5XA+AbIuIXI1Utwn5Eg+XbUo4n5K0ag2XCcQ6X4QANLshckxAAqqILE1QXl7nlJ1UACM9STCgqguWCPEPRgiUqALxXud5cgPjaAPeUgWAQHWIOeK9aeDM2E5KGEJEqAf4IcQAJJsCwYQgxVApNAAY7VTF4kUHciTDXNUDjNIzaOr06LrzlIVKVI2OnNc0ADPtLaco3Mvwn5BWIIMcccWEXyQAWhNNADBFBtpm905uSBBAA3RVXEUCEEAGy5X4aUfbMQG0nZO07w63H0uAJC-01cNPUCwANblFBJNx1eEdVNUiLx1dFtE55QlT9B4ABydozIhIGinVX9f9H08i64gAajAEADWjUwAnQMwAcZNAABZUAH31EMH2QAX4jlo5d04SLyBrjazSA9EdEqLoBaL6LzzGKdVUMMMqA2KlL4AdU8AG9AB5eRDEAD5Ta3ccSQWS0ixS5SyixM9Ss82vLS0DPS1odivAQAWeVABEFUssAGaFF4QANj1bL5LuzIA54q4isShWsr1h9oSdifkwxNAKJ5zIBAAzX3ImlEAHdYqQRQQAWBVAB1bWCH+CNjEGKtXFcA8ykEQviH9MAFv3QAY7lAAejzQr9J1RDGqt8HTkAAh-sqkMBCxAMAYgKuMYQea4SAaxKhVoGPahfxLgZRZYPgSa9JVre3CayAMoLxIJapSanVOWO2H0xAHVaGZqlq4IQASH+58QCCgmEYMmEwBYryB4qIraT4qcDqMIS6ctiU0dSflHjuNVx-h1oUrABLRUkGyveOJKPHDE0F4gomPK3wTNP3aRNVTPTN+ovzVNF0ACslc6dKgs-G4sg6Msis6sxS+s2AJslsyglUdszspg+YqIOgbvB3KK+AJTZgEclrNrRZW8lIAwQAKiNVBCb9gVRJ9AAvxWZH-JFuCEACDNQAHPNmQvhRxY5fgRa9TABoLxqNHGW1+EACxXQAZ8CCwZs3NAAXwKCGxEAEjjUk+M5lXxaANG2AOUwFYFO+JTWADGpQ5AAWn5b29AnRE1dKgATQ0R0SCTAGB26UQGvkXnSX4CGD8XSUQ2gDAFayQGUiKCrjAAzXDsBRzrzt7h6SCW6ScSDu6S3gAH5X8WdO8EgUcsaoANLXLuiL5HMB5M0VDqNHNYrWAUhABvz1MErS93WJfUUOiC6Pz0EtEsrScVYFQFCS0UGXlJSEAB0FQAI2tLL9cRyitx6UUuiUhABJeNMEOkVTU0QC0RKF7miHCTU1c0susotw7qrQvgHM9rCRVJ+T8u3u1MQgfVYyKBNVIDfp4A-pvJ+TLEAEjUswR4XyufYzSZX1XuKcn5f8MsHef7J+c+pe+Afeye-mn5Sys+g4jmmKuKrXZKzQbKz3SXVzZ08+7oBAcpJhl9aIPsxRILH5QAHpj1ApB1yNdSAJyX1q5YAX4q5lSCiflTctogrgrAB4yMAGClHBujfxXIXpWAfTXIHgPRFIJRmGQAbeNZB30TU3lWNJHNioB8bAyhN30fMM0zHq0IGoB3AJKbH31WNWtHGLGUhABQO3w3cYONYB4HYFHlc0AA4VQAETTK0NH9MWGM1-F891Gt59MwB1NEmIqNQJ6ujF7L74AV6oSXDIqM1KK8HsnFlj5Wt755T88G9NV2idUm8QxBLDpjCzs-kDiyBYB2iWGNRq4UhABr-UAHdjJvPAep69KnA41lUgJIWAM-FwnDTm1BqARmQAcOcKUiAuhDMUhAAR70AFh1DZpgL5YYFIR8IkQ51NH1GoBANANR6tVVGVSQVoGdIQzvG56AVAO5mtY9HVJ5l5hZnfd5z58gHtaeJ+DRLxVzXqtSQAWAVrrXneDWN88E1iMXCyMyTNlWNntsibM6HhzwkGlP6pGGTMWntq4qA1S-tH5NUsXq5JmimV576EBlnIBtzFV6zxzqlZmUgYRNUq5qFWtp4dU2SU0snR54g94OgqWUhzohAywIro7xhb4iW+cm6iBEds9c9XMCwRSVxAAzVRFc2Q-0wJZdC3RKRrf25v7rVeGNc01MVTFd5zHKEcF0gFLxusobLV1S1KKfCX8V6erk51SABcgEAE+NC5wAZpiLnABB5QucADCAi5wAWHkLnAAPNIucACXzC5wAGWMLnAA05wucAD+jTfCALIA4ghWgDIXuZAaVn5QAAHNAANrNBF6trP7irnlOvtvp1RhbWeuuZoBXvXCTgFvnme2LVMAEdfScWUQAKCjxcwlEB-NyAT8eD+3+hlmhjsbMyoBAAmRWYkOaKUgwHNYGccL04y+FXEAHnrAmXwHdwkIkJGjFiNVTHZRUrRNdgFwgzdyAGwPdqADkw949ovAOQAY2sxATTkRfBiRfhABQZUABujVcQAZNTrBhp737bH3f3q4eAO7Gdl3gDP33gf3DiSl-2v6oAi9XhPhlBFAERUYUPSM0WDjgc60lgPnn2lTsP8zlyCwbAdYeqENmPgWl08Cy0lqW0nmrUIq+iYdujFNlMbXIAL6M0+VXMghyR4OHXymEgPncGWXDpiQHXRGtO8mWW5G9ODjHWiUcPIrodjU4cFwLnJO68UgfCEXIAV7e4UgvZxI8Jgzi2t8+3KVgGByH4d5By-aoBVRfImCDjubqEQvV6fki9Z0dHAt4uoBoHMn2H+y+NcmtEEqGXSA4AUhVQIqBWM1bNQu5PSvyuamUgaHOmeEUgvgKjiPiXIBABFu0AAJ8kyJvBvCiQAZ9ij7xJABg7V+AbzMib32FApkrkoUqIrqZbq6J1UADz9EbQANMjVAUqpAKJoi6rkLxufSFgOrNvJBEawA-ZAzABZeWt0UERvfWio2KPxPyHJHKVag2PdvxSqhoir438UvvCUcyoEC-vmV0SrVMAE1TLWpLmrm1ogaVMoOHjoLodY3ZAG3b-0wAZHUfBAAyT0AAhA9qjCnVdQcy2q9C+qnVf8QAQuNcZ8eyekxhNMfDWU04e1IygxVHM87h9IAto0edU5Gae7T9hmRKfcYm4vxxIvh1ACKZuZuWZOMCctpmRAAOO0zB56CIdF4v5-9LkcZ82Th4AGYyhWbzkqieeTQBBNedUpBLLABo9SCEkx0F3OF69DkbSgGeUG3KzDCuItItl4J1Mp550swwt4SMfskGF9+G59J7tKwWD8AGnTI+ob0rFD9F1DqIBeWIBjOT5Qn5H0O3KuJTFIf0B1zLlIIMRVBJmuerFIQAYbzz7+576UhABqX3fQzSCRSEACV0xVahRDITyAQAXzd2WEEv1V2UhpAYxi-L7XW2HJ+JP0Fj4wH5q8vR3P3AATHQgxs1gHpMgHwzsdYAzTsJ-XsbAAP-bzrqYDIFYE1ZlJHaiD6dvpULiEbqgDkcMEAGc9QAQwjcZDBABytMD2a5CePZrMyKrbT2h22powswAgAJMJx0iOMAV2zepVJPW0JR-n7igCU9-+R7EjpACAEttB8oAm+uAKgEwDY8cAmFhFUURCNnU0ACgDf02QoDXMgAcCVAATkqGB4+hgG0I4AwGADVmwAvAe2wIFdsiBmqWAQILIH+d5Of+eUoQxJZRB6BKQe0IYDdBcCsBOAueCAP4GdsIB0A4QSQNEG10TyrOLJgfUc5N1IAd-QpuyXgBjASc9-GHlADkE-I5GFzP9gAKwGzYXgw0QAIMqo3Eyur1MBJhQ+yfcQe2iQFFM9E1gggZZwcFoCqezgg9q4Na5iBfAO2GMET2txJhKeOFJPr523xEB9MkggBoARDbRDIAgACeT-owvOIURwSGWNIASQnwCkLtBpCMhFPLIcEFNKlCvwEgHKkEIfaSkYU-iHPBohhTbVRGKhcITYIsGPtIAJQ3-lUKio1CUgRsJbrhTkbLRDohkc6IlncFeDk+BxP1uQDUhRCn+kACNqCDmEucXBmA1rssNWEhV1hB0TYdsI8GeDehqfHDAhDCZL8-qVgyYccNQGQAP+uMeYS11qHjgMQgAFAIIR+wAOIAA54jzK-0ADi6uakACyieJDhGS09h+XGzH93+GuZg01vRwIAEFbYEZcPiHXDahgAKKMIa8IxwIAFd5cSFIFhGS11AWI0fIyz+6CgqkL9IoWhxmEnCCRxI3GGAArDeUj63YEEYsJ+TUjJAtIhkUyJZFvCDBmyNQV8PGG-DIhdg-kQCOYGkiQ2Vw49gmB8BLd1A4kc6AwP-AOhmRslKPv6SVog1VQ4FIQIACllWCvtkpGAAz5RdHOlravwQAGQqgAcSVdRgITerNlxxS9fSBPHIQcQUJ4I8RKQXUb1UADbauanhb6jyRho+EYoF8AMDUwSYwAFIaNojqvaNWiOjVwQgfMW6MpG4VFAPo-0UGKYG4wQxG9MMRGNtFU40W4gnZAO1CGWCIhtgmQXQJOHx89RfIg0VgKNGAAwDPJCABdxPj4ABODSDR2jEMs541CeMT8hHG9VAAYAmzi0xY4jMRON8C7i5xR9RccuPo5FMxgIPYoScJwQ9iRR0qAABwaQJRZI6oRSPpy71O0IUZjmAA1AZowAz4jSGAD0Q55Oa0AP5J2L6FHNJ+vYn4f2KmGj4ShHA0cdMPHGtd9gWY3wIAB+jbht0IVqK0TQsIE0oABe3L8HhN+BmRZA2YnwICBNKAAo1zEAmQaJroQAEbpUEiNCn2VFIoQU8EzZBMM1GDjZBJw+0GhMsEfjDRENGMK4AIk5DxBQwH7t8IEkaiBx67ewScLdDiSfhkkicRjEkC+BAA6hrqAsxMYNkX9QhYjF1J2o1zFpN6qABNtLhaSjPxPyRqOSCdA0iPMtEt0L8HPb8k3Qq0VXIAHQArEjGEMmABM03MmbJYxb7PkSULslJjfK+49CYeNa4ug-ASYyQNGWMlNRFAZklcaPmRSD4R+Wo+KXaG0kqTdJmE-SUZJMleT8p0E94ZSi6DMB1RiEjcVAEADB6oAD51QAG4Wzk49ktwDiZTEsvlOqV4IdCAAOG0AAGCc6UT5RSogfQLoFgA6mQBAAkAqABqvQGlYCd244QABiZigLwb8ALBCBHgO7dQNRHaEhgzSSYXHE6EABFdkSMAABqcEFrbjhAAKXJwobK8kmCVNQa5ycJcmHT1pAEAAlclyAQbOsJyKQA8tCA1xktXk9aTRsHVezHwAM4g3pFXDal-DSpJwgoPRgwCASmsShbAO+IWEuSQMlfBrLnXDrl0MkCiAdGACUyDCM0nEwVNxORrMo8E68RXIzkGA7InuKPYSYcXak4yAR2RDPmADlId0EAtyUmaCJSBFBj87yOZunR0TD9yAYACgL+PYDp0YUYAbkf4hVlbxWZjKcQUzPIAEyygWAejGEkFnQlAZHdFIOwSBmyzfWpABoObKKx4zmZKQdDLslzIizhJ6rXGfjMAkeybZXybaa13Dm-cfx5sgmf+MAlipAU7aDANrOdQmzz06M4mazx2Sn4TBQswSWpNvEAiiZOdXIGpi3gyyo5tQiuZ8LTrDV45gEjGdoj4z8BYA1CUgJnJ4mbJBkFs-iSmhKFlztEimfua7IPFVTaho8rAGnQ7n8Am5PSYmWnTbmayfU3cvzqbJ4kwAvkGaBnAKzKS0CoA-LQVqzx5z+Iyg5yMoIElalyckqUAZgb4HSo89dRFvHmDCGCAmhAAa1G6jFAo034EN31iAhKRvgHnoACD1UicoAt65iwazor3jNzgqUiTQqoRQIAAuE81IAFUwwAGAuvowMQrAViHRmxYY4IE6EAAm1gOAyr-BSygATIVOwPPHqb1It7-ygFAccyoACYEwAN3Kh0zwT6ItaRZj5ZSMoN2KKzKTcOsJacaeKfntiRxr89+UN0BDiL4+2EnwOeN4VSFY8J8xSfKQHkftYSSg58pyWE4dUtJMi6EMEEp7QUYwEfLSZSJjBehfAHA34IAEYdI2OlMADqIXaGtJEUZuVCwANxRBOe0QIDtCAAnt1+Ct5VwNZdscEoBgW8jYgZVRakXUUCLkUtAbRba3kF2hJFHVe0DDBMWCgxAJC56KuG2g89ImrgDgRbxbiOAwaBMGMHbR7lHzEl08MoIbgnKpKYSrmDgZkoJ6oSTFhElcsbgYmoLzUvwVCYCE9gyilFPPPCRbwIlK0CwAyoZVRJonwj6JPPBiRb3EgsTFA8I9QIljqUcyEl+8ppQok+HVzb5apc1IACO01oPSK6Vk8gRvSsQLHGt4GBVwvwIEYAAKYwADUxPPekctCuUW9rKcjdQFwrgVEUIq-CppcsTiA+obxy-WEhcLCF5lDFBPX-r0v+CAA-5zEC3CcKawjYedB2GeDWSEKxpYIu-Hnzj86485Z+xPHx90qgACoM350IWhVIqPo5LWgh3AnooDaaCghuRsWlUfQIoqhAA05aaARu-hQSvHxhi-BAAbI7fBVegAHAIqAgAXAIm8DAgxqBWMIEwDu7Y-ZW-khVlAQh5AVniwCqSFCwuZQiobEP0WNoOq5Q4XhbzaZMrggQ3ZWFT0gqSA2mLqo2PsEp6S0kwigBUDzwCqAA9BIt4ZUax4fDaPtgVAswhMS4VwPW0Zh6q+FpK+sjciGHprRht9K+WA2NVHDqVsJM4YiokkGLIAPPYtYHkdVnZnVCsX-hEo6pLhAA7qmKAAqsIwALuxlyi3qVSHBGwbQW0XKb-zaYpq1FRy5pZXK+Gs8IEuGJCaIvxGEiSRdyu0oKJJHVrnVfKkMBMo8z0jGRsoxUSSrHWqiZZZQGKRapTG6iGVTKllR1XPWNidVHVblWdl5WABBRUACMUfSv2A+BAAA07kTmBToHnplLQX3qCe-YM3hDRHWHKNFkg49dPEsm8jGSn7RyVpMvV8wYQ16gnkhvKnAayej63lUbDunZR5G04eONtF+CighA-JdaFgp54Q1v12Gu0v2ECkhSaldoPsGBpY0QaogBqzRcetPWFrXMiU5DTaq1TtjjFkYsnolKdWyLyqUgfEJlOjLqBDJuU2pQepPlLSTm-GlIJtKXX+lNpa66TSGEADVZuSB3bQVAACubhTjpZzC6fEq42kqxg+fBThauMCABGVwBjpVAAtgaAAc1X+Atk0NPPVzdEvE12lJMWK3wDUQEB4xoY+FMAL1RNBbRAAKyaABh-QtiThFGYgCCG9CqoeZeIT4STL21+kGreyWXaHkLLvmQABGwmqAFit+D0qjYPPVxg6F4b0b-S-5QACAqkgNBQRUEpSBRKvVUyixXKSyrvgW0ZXrxUurDaG8NFdpDRUm7uBaIni+SoRXkquNTeAgQALKKgAbpjFAjC+laqEj4dV1yYAOjRyvbFJhAA9KZcgCKvVelYAG0lMGYoEADFCVBUuq2b1WpAQRY0otWyt5WVWyAHLDlYrlAAcs6ABXpTI0CAftBYKXl4tIqoBcgeAf4PqR23tiA4FvXwIApuk89LSB0btQqw+0GqHNnNJzZpp+Q-bPNPmyTB6NvAWxSs-MNLRluPDZbctj4PVWfxgBW4pOh89pU51twoEiskqd+ofImSezlckAGOV0G-QHEoU-iS8v4msF4Yfk-2RrJLK0XkB5dJMoplzJ5kssig08bmQgmw7iCX6ESWjNPBnnqj14mmQCEeDehz1MA0gyAIAAQM8bDbvPrPsUgQHf6K7vEFGDJ66aXvoAB7TYnLAEFCJ4EAOqFKjylCR38hdUARQrkCgxWSQ25WraIADYjQADKubE2OMGhrkpAPCxhNPZnuz3BBC9bEwENjFcV8QqF5qQABXxqzQAHR+5lX4ArFbyAAvG0eCN7AAK9aABo+WuwhsSkD8Z1DhwBQUlz50AF5KLtrY56EWAKCfSkEADA8dPvfYNKMAN9VrB7uygEdQk-chfbHAI5SIVpdbPfQC3Zn1KAUUVL9NECay5Zq4byYJFvEw5bx6S1k8rY3sAAS6YAHlTVGLnp+T5739X+3qh10zCAA-u0ABU8Tth-DgxAA-uavb7OXNB-ZvE37D6mAo+41SEir51tAAcvIEd0DVKqAPPuwMz6V9a+znkB031EHIA1gwrj8nn31scDqBsoFQeQwNtfOdHLiQcVCQJBe4GmoOWkp+SAA8qMAAAUT-qgD56hDwQAOIoCqyAAwtxc2ABK53jgsxAA2fK-BwQptWECB0AC9proFXD7Kz9UAMYDfWiBEdOaljF-WqUAAWioACLw8MiIcgDWHwyIYP4gCSCCXZgggAUYUGdR4VcK8QWkAphhFya+sy0s7lboGgAZ-TGYdh6BgHAiN+G5MUKW+EEfY68HudkDKBmEcABAVlEagYxGMjcR3lLllQHmHP2mewiHYcEqlGCIvVXCMtEABftnaFgMudJE+TIfXYKKRxUUguELfTwAwAjwUg9R1gxvLZkHExqBuYgFgiTxajytv0QADcmgAbgzVmhgQAOxKKIBY3YftGKAi8MMAQNKgAAsux4gBwEUCNExAh1TwisYWPN7AAxFZBAjYQHIXMoEACcFoAC2TZkDYdYXzZZjwQUUAIA2PSRAAZoGAByA1hAmhAAzvK-AWY9bC46sxmyABZNMwOAABPQJD5GH4pXaAGAJCa4MQjapccMbl-rpjJ5mmU3ArEDKABQDN1zmVzoh0fYCaEBBq5DoglYIMTEagB6hApEoIoHyoBN58jpAa+P4ji5zNsTn7WXrYAh52GBAfoovLL0MAQ8QwgAKeVoKNY3yJgshBBBFA-2GoIAGFFQAAS++Rnui0flIVylmQp2EkPWo52H89gAXFNuogAWgyzT3+lzgoiWax7NkgKdgGgdiB4HIAtbZbDgc9ML7fTFBquKvu30b6COTBhfQM3oPunGDTDFIIAD107KFGYoOI8Wj0QDNLGeoNQBa2UZk-ZeNHxKZChgPGFbftpJjwsTUxtUoAC8zWEL-3xMTyyZx7GRn8Esq-9yQgIfYPtNbUhUB6sudOCQup28Vf+RsAZgiEABXSXxF-6-B5TvZk0FSBVCKBf++RzeBgB9RhMTTrmQABFmgAAjM7DMjHc78H2ARloygAXhC7YeUu0MYWwi-Alwj4QAMhmgARtTAAAdGABw0xKoFSU0JOJxN9ll3kBuZcK6YeVrMArHVOdh8GLRCCDAWRSCx9OPStrBGxAAgZ5bQhufevkUpP-MumQSPqQ1YelczSpxOFBueThY7StGoAakAi8vsoNAziLI6FIAAFYKLaHJjEphotHofk0qDSIxaYu8p5q8pDM9ulIuQBNIXFscf-UhYss16W0QY6foOUpoORY9DThgDlJjBS0xR2EoAEB3QAKauh0QAIfygAewM7DgALAS9SReZ6IoE72rMkw9ehqmZenaAAxC3TiBjiIgHAsJWUABwZhxVUDdR8jxSQoc7XYLe5ea7WbohufXpbR8arQOXIoEABm0YACkVOwxFblyABQ2L1IcWNIjZZ6OSBNBF44r+Rws5C3FkUA2GnRFJNEHdOhWfkUS-6OscVr0rAlQS7bL8Bkadg5YAkJxUbDkNBBOw+RoRRsWxz4ND6lZz9oAFz5Q6DTGt50q5ZUoqAOe0kBjXreh5wEOanFDSgTK9K2tt8Ao0RF4+o09OErXpXZRso6qpqONaDik05YVxmbICCXCJZAA-fJKihjsmSAAtwLlAFUjUAFCjli4ZQBfe20QbYYE5OGB3KykOWFBU0BiBiGB0ckAWFymMxFaqFuzX0QyKaUQrPyEop9b50IABdGaANsYZULWzfuouwy1JamYN0AR6OIpo-xXMqsUgq3aMio2Xqe0Ug9ZlNI7W8bIZAAnkZEhBK6nYwZpxSCHRhmTeBmwadgAlAlKSrDJkQ2tyHRAAd-KAA-jOFvBC2AwTfm3J1QI+1iCYuMzjPx+SAAV+K9hto2A4txzPHhSDqAjbrAE2-ACwQ9G+jPyMyJbetvgtqEtQgmmW2NukBHMj2MYMhhMjvpPa-iPuh53F7KBLbAALVIAQI5SzNvfR7dYCR2IEF8ZGVAHr1L72R93eAM9VepUM6uRTNzhfF8z9prWUAIMnyDbRKZe4hdpTI7jCT54J2PnfYYg1YzGIWW6DTBtgybsYAkG6GOHcpdLSQB0GSJ2wKDA9j6X9OA4yAE4Oi4TqzlUAIEYPwzU7Is15glICWtZuIDOelQ0hmfM54XqRj5KzniOLt2tLOeqEttHxLPvlTGGSk829ff2EtTiAKQehTvR7HX6UU8AHLg7oUVH1X7RWKWYkyzsS2b4wMhW6MzAAeEnQAqlvqUwGsVMqmpdaegJVaZnY7GaZH2rFVPwBXe+ouLm6QVIYlNWMcDtW1ABaYHQjbp+dm7XdXRoCtMXNnmx7coej0HczDjEw3x+SCVrKs9Rh32mYfZE9+KQVxiLYKYpZChQDJxKA3AZYC1csDeBkE1wZsPYSgUFm5sgvpaIAH86VzD-WtzT2imSdZhqw0y6cNUukAXhnmCECABWfUq353Ey7N52ikFxoMCIMtANmgnvz7BIumU+SWiLSdte34Av+PxJz1HND1BGwjURuIycZYCZGcjJRjExSbEAInFjL-BOW0a6Mfk+jAnEY3PohMOdrmVADk-XNltK77SWIFWh-SlOR5lduJ5o2IDxMpbUAZJjU7SaZoMmBxLXQbqaUUCBZnPQqxrI0fVyDiTcq2Z7Mjk-JvZFssOSM-9lFMW5MGUOWAGHn6DZLkAB9BolnXvXIAZYAPRTc2QaglKW-QbC5uJwjUxqm1aauIj6TSIV4sieRIolWoyENqk1bapwb2qQAdUVAORPfDToVyByhmcgMdR1S9UBwl1ICL8AdDgh+YKsMFfJVuD2iQikcWwKC-8Jp5jno1KwZtU1R2IeEFOapDqnufrUrcm1Z57tX2pLV3Eq8sAFi41AAvoXeLuIG+UCCKAgIgARB0TQnYQAI2Ox0RQCllKTTwrYQld4tVTKw7bhqaL8apNU1TFJeXOLvF5ADWr9zYARLnajUn2o8v46GWQAJtK7Kk6tDvkozdbgg2RQJkaOeivTnk1c51PGoHprKKGiJeNc9CYyyU5GHKFPi4VdKuXn+1T5qwHHhKYAXElXHFCJwoCBJAo4QAEsWigQAJjygAFnlaXtwDaxbBCKAB8Q0AC40QOFranZAA0OaABp5VRdmupqACGalS5kTspqkVFUPYgGIDRBXXjzrasq9ec6o94PAUt90ABdQilaK5WwHhUAAOroAHwzAwL1Xl1fI+Al1K4Jdl+BkuVgNJwEMxDEBxknr+QwzLEBMwyCNnNuyzDJgoxUZVLzKC4ssQNwqFpCFARZL7kEuAAjAx9hsRFUu+SgMe5cz55p8l7g4sKhPffVmD44KQI+4ZZQonEyKDgPAGRut1amLeXnUU1ZoDpFktGMp9fklrC1Ra4ghzgkHxZFBuZKKc1QDSeIvE3iMmEAM0CAA")); })() /***/ }), /***/ "./src/js/built-temp/sfx.json": /*!************************************!*\ !*** ./src/js/built-temp/sfx.json ***! \************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4KABGBECuBOA2BnSAuMBtcEqIGYA8A6AWwAcBmSLAXQBotJFTYBLAFwFNUxRsoAjAIYATAOYcA+gDsA9mxa4WAY0HyZU7pj4QADPW1gAnADYA7IQCsAJgAc5ACz2zARis7nNrBDpeowjohssDIAnhL80CzwwixSopq+EM7OOnqJYE7mVik2NvbkFuSm9s72Fr4+fJAxgvAyohIcsMGwCQZWbmkGzoYWhDqmhuTGFgNDIx4V+tjVLLX1EjIA1m3a5OSp-anbO6kW03y5OoRlBaWm5IYdNqZTvpDwHABuHPASSjJkj5yrfI6pB2wG1SdyqpHggiUkn4rzYv2wplGXW0xnIhBsOl6VnIGKxRWMoJm4Mh0Mi0Vi8TQWm0NmMAPSG0M6JKVmMhjyrjZnj4lRmkXe8GUKyp6UMpnp3VchDFOmszgsJUM9nZBJ5gJgLEazRkrRF3TGTMMRuNJvZgIgGz6FzZxlKFlc9nF5TV935iAA7ixEAALCTelj+eFJDxG6Wm002c1gGx9RWjZLrUy0mxWQkQDUSD1e30+mTuoNgVzGsPh42R9LJKyEJOGZIWYxOKwWGzyipYAC+00YsCU8MYBBIFCo3hA7aAA")); })() /***/ }), /***/ "./src/js/changelog.js": /*!*****************************!*\ !*** ./src/js/changelog.js ***! \*****************************/ /*! exports provided: CHANGELOG */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CHANGELOG", function() { return CHANGELOG; }); const CHANGELOG = [ { version: "modZ 0.9.9", date: "by Dimava", entries: [ "Added new buildings: Checker, Counter, Unstacker, Combiner, Repeater, Quaduo Painter", "Added 11 new shapes. Use Combiner to obtain them.", "Made some levels for custom buildings (some are still missing)", "Fixed lower-that-written speeds of producers (tnx isa) and miners", "Added 2nd toolbar for modded buildings, toggle-building, and hotkey to toggle it (key Z)", "Added descriptions, toolbar icons and tutorial images for modded buildings (some are still missing)", "Added Freeplay levels with growing difficulty. Required shape count for freeplay was greatly reduced.", "Reduced required shapes for levels - you have probably finished the main game so you don't have to proof anything exept freeplay builds", "Made numbers longer (3 digits)", 'Added debug settings - basically a sandbox mode, as well as F6 key in-game. I highly recommend turning on the "Show chunk borders" permanently.', ], }, { version: "1.2.0", date: "unreleased", entries: [ "WIRES", "Reworked menu UI design (by dengr1605)", "Allow holding ALT in belt planner to reverse direction (by jakobhellermann)", "Clear cursor when trying to pipette the same building twice (by hexy)", "Fixed level 18 stacker bug: If you experienced it already, you know it, if not, I don't want to spoiler (by hexy)", "Added keybinding to close menus (by isaisstillalive / Sandwichs-del)", "Fix rare crash regarding the buildings toolbar (by isaisstillalive)", "Fixed some phrases (by EnderDoom77)", "Zoom towards mouse cursor (by Dimava)", "Added multiple settings to optimize the performance", "Updated the soundtrack again, it is now 40 minutes in total!", "Updated and added new translations (Thanks to all contributors!)", "Allow editing waypoints (by isaisstillalive)", "Show confirmation when cutting area which is too expensive to get pasted again (by isaisstillalive)", "Show mouse and camera tile on debug overlay (F4) (by dengr)", "Fix tunnels entrances connecting to exits sometimes when they shouldn't", "The initial belt planner direction is now based on the cursor movement (by MizardX)", "Fix preferred variant not getting saved when clicking on the hud (by Danacus)", ], }, { version: "1.1.19", date: "02.07.2020", entries: [ "There are now notifications every 15 minutes in the demo version to buy the full version (For further details and the reason, check the #surveys channel in the Discord)", "I'm still working on the wires update, I hope to release it mid july!", ], }, { version: "1.1.18", date: "27.06.2020", entries: [ "Huge performance improvements - up to double fps and tick-rate! This will wipe out all current items on belts.", "Reduce story shapes required until unlocking blueprints", "Allow clicking on variants to select them", "Add 'copy key' button to shape viewer", "Add more FPS to the belt animation and fix belt animation seeming to go 'backwards' on high belt speeds", "Fix deconstruct sound being played when right clicking hub", "Allow clicking 'Q' over a shape or color patch to automatically select the miner building (by Gerdon262)", "Update belt placement performance on huge factories (by Phlosioneer)", "Fix duplicate waypoints with a shape not rendering (by hexy)", "Fix smart tunnel placement deleting wrong tunnels (by mordof)", "Add setting (on by default) to store the last used rotation per building instead of globally storing it (by Magos)", "Added chinese (traditional) translation", "Updated translations", ], }, { version: "1.1.17", date: "22.06.2020", entries: [ "Color blind mode! You can now activate it in the settings and it will show you which color is below your cursor (Either resource or on the belt)", "Add info buttons to all shapes so you can figure out how they are built! (And also, which colors they have)", "Allow configuring autosave interval and disabling it in the settings", "The smart-tunnel placement has been reworked to properly replace belts. Thus the setting has been turned on again by default", "The soundtrack now has a higher quality on the standalone version than the web version", "Add setting to disable cut/delete warnings (by hexy)", "Fix bug where belts in blueprints don't orient correctly (by hexy)", "Fix camera moving weird after dragging and holding (by hexy)", "Fix keybinding for pipette showing while pasting blueprints", "Improve visibility of shape background in dark mode", "Added sound when destroying a building", "Added swedish translation", "Update tutorial image for tier 2 tunnels to explain mix/match (by jimmyshadow1)", ], }, { version: "1.1.16", date: "21.06.2020", entries: [ "You can now pickup buildings below your cursor with 'Q'!", "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen!", "Refactor keybindings overlay to show more appropriate keybindings", "Show keybindings for area-select in the upper left instead", "Automatically deselect area when selecting a new building", "Raise markers limit from 14 characters to 71 (by Joker-vD)", "Optimize performance by caching extractor items (by Phlosioneer)", "Added setting to enable compact building infos, which only show ratios and hide the image / description", "Apply dark theme to menu as well (by dengr1065)", "Fix belt planner not placing the last belt", "Fix buildings getting deleted when right clicking while placing a blueprint", "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)", "Fix buttons not responding when using right click directly after left click (by davidburhans)", "Fix hub marker being hidden by building info panel", "Disable dialog background blur since it can cause performance issues", "Added simplified chinese translations", "Update translations (Thanks to all translators!)", ], }, { version: "1.1.15", date: "17.06.2020", entries: [ "You can now place straight belts (and tunnels) by holding SHIFT! (For you, @giantwaffle ❤️)", "Added continue button to main menu and add seperate 'New game' button (by jaysc)", "Added setting to disable smart tunnel placement introduced with the last update", "Added setting to disable vignette", "Update translations", ], }, { version: "1.1.14", date: "16.06.2020", entries: [ "There is now an indicator (compass) to the HUB for the HUB Marker!", "You can now include shape short keys in markers to render shape icons instead of text!", "Added mirrored variant of the painter", "When placing tunnels, unnecessary belts inbetween are now removed!", "You can now drag tunnels and they will automatically expand! (Just try it out, its intuitive)", ], }, { version: "1.1.13", date: "15.06.2020", entries: [ "Added shift modifier for faster pan (by jaysc)", "Added Japanese translations", "Added Portuguese (Portugal) translations", "Updated icon for Spanish (Latin America) - It was showing a Spanish flag before", "Updated existing translations", ], }, { version: "1.1.12", date: "14.06.2020", entries: [ "Huge performance improvements! The game should now run up to 60% faster!", "Added norwegian translation", ], }, { version: "1.1.11", date: "13.06.2020", entries: [ "Pinned shapes are now smart, they dynamically update their goal and also unpin when no longer required. Completed objectives are now rendered transparent.", "You can now cut areas, and also paste the last blueprint again! (by hexy)", "You can now export your whole base as an image by pressing F3!", "Improve upgrade number rounding, so there are no goals like '37.4k', instead it will now be '35k'", "You can now configure the camera movement speed when using WASD (by mini-bomba)", "Selecting an area now is relative to the world and thus does not move when moving the screen (by Dimava)", "Allow higher tick-rates up to 500hz (This will burn your PC!)", "Fix bug regarding number rounding", "Fix dialog text being hardly readable in dark theme", "Fix app not starting when the savegames were corrupted - there is now a better error message as well.", "Further translation updates - Big thanks to all contributors!", ], }, { version: "1.1.10", date: "12.06.2020", entries: [ "There are now linux builds on steam! Please report any issues in the Discord!", "Steam cloud saves are now available!", "Added and update more translations (Big thank you to all translators!)", "Prevent invalid connection if existing underground tunnel entrance exists (by jaysc)", ], }, { version: "1.1.9", date: "11.06.2020", entries: [ "Support for translations! Interested in helping out? Check out the translation guide!", "Update stacker artwork to clarify how it works", "Update keybinding hints on the top left to be more accurate", "Make it more clear when blueprints are unlocked when trying to use them", "Fix pinned shape icons not being visible in dark mode", "Fix being able to select buildings via hotkeys in map overview mode", "Make shapes unpinnable in the upgrades tab (By hexy)", ], }, { version: "1.1.8", date: "07.06.2020", entries: [ "You can now purchase the standalone on steam! View steam page", "Added ability to create markers in the demo, but only two.", "Contest #01 has ended! I'll now work through the entries, select the 5 I like most and present them to the community to vote for!", ], }, { version: "1.1.7", date: "04.06.2020", entries: ["HOTFIX: Fix savegames not showing up on the standalone version"], }, { version: "1.1.6", date: "04.06.2020", entries: [ "The steam release will happen on the 7th of June - Be sure to add it to your wishlist! View on steam", "Fixed level complete dialog being blurred when the shop was opened before", "Standalone: Increased icon visibility for windows builds", "Web version: Fixed firefox not loading the game when browsing in private mode", ], }, { version: "1.1.5", date: "03.06.2020", entries: ["Added weekly contests!"], }, { version: "1.1.4", date: "01.06.2020", entries: ["Add 'interactive' tutorial for the first level to improve onboarding experience"], }, { version: "1.1.3", date: "01.06.2020", entries: [ "Added setting to configure zoom / mouse wheel / touchpad sensitivity", "Fix belts being too slow when copied via blueprint (by Dimava)", "Allow binding mouse buttons to actions (by Dimava)", "Increase readability of certain HUD elements", ], }, { version: "1.1.2", date: "30.05.2020", entries: [ "The official trailer is now ready! Check it out here!", "The steam page is now live!", "Experimental linux builds are now available! Please give me feedback on them in the Discord", "Allow hovering pinned shapes to enlarge them", "Allow deselecting blueprints with right click and 'Q'", "Move default key for deleting from 'X' to 'DEL'", "Show confirmation when deleting more than 100 buildings", "Reintroduce 'SPACE' keybinding to center on map", "Improved keybinding hints", "Fixed some keybindings showing as 'undefined'", ], }, { version: "1.1.1", date: "28.05.2020", entries: ["Fix crash when 'Show Hints' setting was turned off"], }, { version: "1.1.0", date: "28.05.2020", entries: [ "BLUEPRINTS! They are unlocked at level 12 and cost a special shape to build.", "MAP MARKERS! Press 'M' to create a waypoint and be able to jump to it", "Savegame levels are now shown in the main menu. For existing games, save them again to make the level show up.", "Allow holding SHIFT to rotate counter clockwise", "Added confirmation when deleting more than 500 buildings at a time", "Added background to toolbar to increase contrast", "Further decerase requirements of first levels", "Pinned shapes now are saved", "Allow placing extractors anywhere again, but they don't work at all if not placed on a resource", "Show dialog explaining some keybindings after completing level 4", "Fix keys being stuck when opening a dialog", "Swapped shape order for painting upgrades", "Allow changing all keybindings, including CTRL, ALT and SHIFT (by Dimava)", "Fix cycling through keybindings selecting locked buildings as well (by Dimava)", "There is now a github action, checking all pull requests with eslint. (by mrHedgehog)", ], }, { version: "1.0.4", date: "26.05.2020", entries: [ "Reduce cost of first painting upgrade, and change 'Shape Processing' to 'Cutting, Rotating & Stacking'", "Add dialog after completing level 2 to check out the upgrades tab.", "Allow changing the keybindings in the demo version", ], }, { version: "1.0.3", date: "24.05.2020", entries: [ "Reduced the amount of shapes required for the first 5 levels to make it easier to get into the game.", ], }, { version: "1.0.2", date: "23.05.2020", entries: [ "Introduced changelog", "Removed 'early access' label because the game isn't actually early access - its in a pretty good state already! (No worries, a lot more updates will follow!)", "Added a 'Show hint' button which shows a small video for almost all levels to help out", "Now showing proper descriptions when completing levels, with instructions on what the gained reward does.", "Show a landing page on mobile devices about the game not being ready to be played on mobile yet", "Fix painters and mixers being affected by the shape processors upgrade and not the painter one", "Added 'multiplace' setting which is equivalent to holding SHIFT all the time", "Added keybindings to zoom in / zoom out", "Tunnels now also show connection lines to tunnel exits, instead of just tunnel entries", "Lots of minor fixes and improvements", ], }, { version: "1.0.1", date: "21.05.2020", entries: ["Initial release!"], }, ]; /***/ }), /***/ "./src/js/core/animation_frame.js": /*!****************************************!*\ !*** ./src/js/core/animation_frame.js ***! \****************************************/ /*! exports provided: AnimationFrame */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationFrame", function() { return AnimationFrame; }); /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./signal */ "./src/js/core/signal.js"); /* harmony import */ var _webworkers_background_animation_frame_emittter_worker__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../webworkers/background_animation_frame_emittter.worker */ "./src/js/webworkers/background_animation_frame_emittter.worker.js"); /* harmony import */ var _webworkers_background_animation_frame_emittter_worker__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_webworkers_background_animation_frame_emittter_worker__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); // @ts-ignore const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("animation_frame"); const maxDtMs = 1000; const resetDtMs = 16; class AnimationFrame { constructor() { this.frameEmitted = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.bgFrameEmitted = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.lastTime = performance.now(); this.bgLastTime = performance.now(); this.boundMethod = this.handleAnimationFrame.bind(this); this.backgroundWorker = new _webworkers_background_animation_frame_emittter_worker__WEBPACK_IMPORTED_MODULE_1___default.a(); this.backgroundWorker.addEventListener("error", err => { logger.error("Error in background fps worker:", err); }); this.backgroundWorker.addEventListener("message", this.handleBackgroundTick.bind(this)); } handleBackgroundTick() { const time = performance.now(); let dt = time - this.bgLastTime; if (dt > maxDtMs) { dt = resetDtMs; } this.bgFrameEmitted.dispatch(dt); this.bgLastTime = time; } start() { window.assert(window.requestAnimationFrame, "requestAnimationFrame is not supported!"); this.handleAnimationFrame(); } handleAnimationFrame(time) { let dt = time - this.lastTime; if (dt > maxDtMs) { dt = resetDtMs; } this.frameEmitted.dispatch(dt); this.lastTime = time; window.requestAnimationFrame(this.boundMethod); } } /***/ }), /***/ "./src/js/core/assert.js": /*!*******************************!*\ !*** ./src/js/core/assert.js ***! \*******************************/ /*! no exports provided */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("assert"); let assertionErrorShown = false; function initAssert() { /** * Expects a given condition to be true * @param {Boolean} condition * @param {...String} failureMessage */ // @ts-ignore window.assert = function (condition, ...failureMessage) { if (!condition) { logger.error("assertion failed:", ...failureMessage); if (!assertionErrorShown) { // alert("Assertion failed (the game will try to continue to run): \n\n" + failureMessage); assertionErrorShown = true; } throw new Error("AssertionError: " + failureMessage.join(" ")); } }; } initAssert(); /***/ }), /***/ "./src/js/core/async_compression.js": /*!******************************************!*\ !*** ./src/js/core/async_compression.js ***! \******************************************/ /*! exports provided: compressionPrefix, asyncCompressor */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compressionPrefix", function() { return compressionPrefix; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asyncCompressor", function() { return asyncCompressor; }); /* harmony import */ var _webworkers_compression_worker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../webworkers/compression.worker */ "./src/js/webworkers/compression.worker.js"); /* harmony import */ var _webworkers_compression_worker__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_webworkers_compression_worker__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); // @ts-ignore const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("async_compression"); let compressionPrefix = String.fromCodePoint(1); function checkCryptPrefix(prefix) { try { window.localStorage.setItem("prefix_test", prefix); window.localStorage.removeItem("prefix_test"); return true; } catch (ex) { logger.warn("Prefix '" + prefix + "' not available"); return false; } } if (!checkCryptPrefix(compressionPrefix)) { logger.warn("Switching to basic prefix"); compressionPrefix = " "; if (!checkCryptPrefix(compressionPrefix)) { logger.warn("Prefix not available, ls seems to be unavailable"); } } /** * @typedef {{ * errorHandler: function(any) : void, * resolver: function(any) : void, * startTime: number * }} JobEntry */ class AsynCompression { constructor() { this.worker = new _webworkers_compression_worker__WEBPACK_IMPORTED_MODULE_0___default.a(); this.currentJobId = 1000; /** @type {Object.} */ this.currentJobs = {}; this.worker.addEventListener("message", event => { const { jobId, result } = event.data; const jobData = this.currentJobs[jobId]; if (!jobData) { logger.error("Failed to resolve job result, job id", jobId, "is not known"); return; } const duration = performance.now() - jobData.startTime; logger.log( "Got job", jobId, "response within", Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round2Digits"])(duration), "ms: ", result.length, "bytes" ); const resolver = jobData.resolver; delete this.currentJobs[jobId]; resolver(result); }); this.worker.addEventListener("error", err => { logger.error("Got error from webworker:", err, "aborting all jobs"); const failureCalls = []; for (const jobId in this.currentJobs) { failureCalls.push(this.currentJobs[jobId].errorHandler); } this.currentJobs = {}; for (let i = 0; i < failureCalls.length; ++i) { failureCalls[i](err); } }); } /** * Compresses any object * @param {any} obj */ compressObjectAsync(obj) { logger.log("Compressing object async (optimized)"); return this.internalQueueJob("compressObject", { obj, compressionPrefix, }); } /** * Queues a new job * @param {string} job * @param {any} data * @returns {Promise} */ internalQueueJob(job, data) { const jobId = ++this.currentJobId; return new Promise((resolve, reject) => { const errorHandler = err => { logger.error("Failed to compress job", jobId, ":", err); reject(err); }; this.currentJobs[jobId] = { errorHandler, resolver: resolve, startTime: performance.now(), }; logger.log("Posting job", job, "/", jobId); this.worker.postMessage({ jobId, job, data }); }); } } const asyncCompressor = new AsynCompression(); /***/ }), /***/ "./src/js/core/atlas_definitions.js": /*!******************************************!*\ !*** ./src/js/core/atlas_definitions.js ***! \******************************************/ /*! exports provided: AtlasDefinition, atlasFiles */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AtlasDefinition", function() { return AtlasDefinition; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "atlasFiles", function() { return atlasFiles; }); /** * @typedef {{ w: number, h: number }} Size * @typedef {{ x: number, y: number }} Position * @typedef {{ * frame: Position & Size, * rotated: boolean, * spriteSourceSize: Position & Size, * sourceSize: Size, * trimmed: boolean * }} SpriteDefinition * * @typedef {{ * app: string, * version: string, * image: string, * format: string, * size: Size, * scale: string, * smartupdate: string * }} AtlasMeta * * @typedef {{ * frames: Object., * meta: AtlasMeta * }} SourceData */ class AtlasDefinition { /** * @param {SourceData} sourceData */ constructor({ frames, meta }) { this.meta = meta; this.sourceData = frames; this.sourceFileName = meta.image; } getFullSourcePath() { return this.sourceFileName; } } /** @type {AtlasDefinition[]} **/ const atlasFiles = __webpack_require__("./res_built/atlas sync .*\\.json/") .keys() .map(f => f.replace(/^\.\//gi, "")) .map(f => __webpack_require__("./res_built/atlas sync recursive ^\\.\\/.*$")("./" + f)) .map(data => new AtlasDefinition(data)); /***/ }), /***/ "./src/js/core/background_resources_loader.js": /*!****************************************************!*\ !*** ./src/js/core/background_resources_loader.js ***! \****************************************************/ /*! exports provided: BackgroundResourcesLoader */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BackgroundResourcesLoader", function() { return BackgroundResourcesLoader; }); /* harmony import */ var _loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./loader */ "./src/js/core/loader.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./signal */ "./src/js/core/signal.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _atlas_definitions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./atlas_definitions */ "./src/js/core/atlas_definitions.js"); /* harmony import */ var _game_meta_building_registry__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game/meta_building_registry */ "./src/js/game/meta_building_registry.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("background_loader"); const essentialMainMenuSprites = [ "logo.png", ...["logo.png"].filter(src => src.startsWith("ui/") && src.indexOf(".gif") < 0), ]; const essentialMainMenuSounds = [ _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].uiClick, _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].uiError, _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].dialogError, _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].dialogOk, _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].swishShow, _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].swishHide, ]; const essentialBareGameAtlases = _atlas_definitions__WEBPACK_IMPORTED_MODULE_4__["atlasFiles"]; const essentialBareGameSprites = ["logo.png"].filter(src => src.indexOf(".gif") < 0); const essentialBareGameSounds = [_platform_sound__WEBPACK_IMPORTED_MODULE_3__["MUSIC"].theme]; const additionalGameSprites = []; // @ts-ignore const additionalGameSounds = [...Object.values(_platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"]), ...Object.values(_platform_sound__WEBPACK_IMPORTED_MODULE_3__["MUSIC"])]; class BackgroundResourcesLoader { /** * * @param {Application} app */ constructor(app) { this.app = app; this.registerReady = false; this.mainMenuReady = false; this.bareGameReady = false; this.additionalReady = false; this.signalMainMenuLoaded = new _signal__WEBPACK_IMPORTED_MODULE_2__["Signal"](); this.signalBareGameLoaded = new _signal__WEBPACK_IMPORTED_MODULE_2__["Signal"](); this.signalAdditionalLoaded = new _signal__WEBPACK_IMPORTED_MODULE_2__["Signal"](); this.numAssetsLoaded = 0; this.numAssetsToLoadTotal = 0; // Avoid loading stuff twice this.spritesLoaded = []; this.soundsLoaded = []; } getNumAssetsLoaded() { return this.numAssetsLoaded; } getNumAssetsTotal() { return this.numAssetsToLoadTotal; } getPromiseForMainMenu() { if (this.mainMenuReady) { return Promise.resolve(); } return new Promise(resolve => { this.signalMainMenuLoaded.add(resolve); }); } getPromiseForBareGame() { if (this.bareGameReady) { return Promise.resolve(); } return new Promise(resolve => { this.signalBareGameLoaded.add(resolve); }); } startLoading() { this.internalStartLoadingEssentialsForMainMenu(); } internalStartLoadingEssentialsForMainMenu() { logger.log("⏰ Start load: main menu"); this.internalLoadSpritesAndSounds(essentialMainMenuSprites, essentialMainMenuSounds) .catch(err => { logger.warn("⏰ Failed to load essentials for main menu:", err); }) .then(() => { logger.log("⏰ Finish load: main menu"); this.mainMenuReady = true; this.signalMainMenuLoaded.dispatch(); this.internalStartLoadingEssentialsForBareGame(); }); } internalStartLoadingEssentialsForBareGame() { logger.log("⏰ Start load: bare game"); this.internalLoadSpritesAndSounds( essentialBareGameSprites, essentialBareGameSounds, essentialBareGameAtlases ) .catch(err => { logger.warn("⏰ Failed to load essentials for bare game:", err); }) .then(() => { logger.log("⏰ Finish load: bare game"); this.bareGameReady = true; Object(_game_meta_building_registry__WEBPACK_IMPORTED_MODULE_5__["initBuildingCodesAfterResourcesLoaded"])(); this.signalBareGameLoaded.dispatch(); this.internalStartLoadingAdditionalGameAssets(); }); } internalStartLoadingAdditionalGameAssets() { const additionalAtlases = []; logger.log("⏰ Start load: additional assets (", additionalAtlases.length, "images)"); this.internalLoadSpritesAndSounds(additionalGameSprites, additionalGameSounds, additionalAtlases) .catch(err => { logger.warn("⏰ Failed to load additional assets:", err); }) .then(() => { logger.log("⏰ Finish load: additional assets"); this.additionalReady = true; this.signalAdditionalLoaded.dispatch(); }); } /** * @param {Array} sprites * @param {Array} sounds * @param {Array} atlases * @returns {Promise} */ internalLoadSpritesAndSounds(sprites, sounds, atlases = []) { this.numAssetsToLoadTotal = sprites.length + sounds.length + atlases.length; this.numAssetsLoaded = 0; let promises = []; for (let i = 0; i < sounds.length; ++i) { if (this.soundsLoaded.indexOf(sounds[i]) >= 0) { // Already loaded continue; } this.soundsLoaded.push(sounds[i]); promises.push( this.app.sound .loadSound(sounds[i]) .catch(err => { logger.warn("Failed to load sound:", sounds[i]); }) .then(() => { this.numAssetsLoaded++; }) ); } for (let i = 0; i < sprites.length; ++i) { if (this.spritesLoaded.indexOf(sprites[i]) >= 0) { // Already loaded continue; } this.spritesLoaded.push(sprites[i]); promises.push( _loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].preloadCSSSprite(sprites[i]) .catch(err => { logger.warn("Failed to load css sprite:", sprites[i]); }) .then(() => { this.numAssetsLoaded++; }) ); } for (let i = 0; i < atlases.length; ++i) { const atlas = atlases[i]; promises.push( _loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].preloadAtlas(atlas) .catch(err => { logger.warn("Failed to load atlas:", atlas.sourceFileName); }) .then(() => { this.numAssetsLoaded++; }) ); } return ( Promise.all(promises) // // Remove some pressure by waiting a bit // .then(() => { // return new Promise(resolve => { // setTimeout(resolve, 200); // }); // }) .then(() => { this.numAssetsToLoadTotal = 0; this.numAssetsLoaded = 0; }) ); } } /***/ }), /***/ "./src/js/core/buffer_maintainer.js": /*!******************************************!*\ !*** ./src/js/core/buffer_maintainer.js ***! \******************************************/ /*! exports provided: BufferMaintainer */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BufferMaintainer", function() { return BufferMaintainer; }); /* harmony import */ var _game_root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../game/root */ "./src/js/game/root.js"); /* harmony import */ var _buffer_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /** * @typedef {{ * canvas: HTMLCanvasElement, * context: CanvasRenderingContext2D, * lastUse: number, * }} CacheEntry */ const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("buffers"); const bufferGcDurationSeconds = 5; class BufferMaintainer { /** * @param {GameRoot} root */ constructor(root) { this.root = root; /** @type {Map>} */ this.cache = new Map(); this.iterationIndex = 1; this.lastIteration = 0; this.root.signals.gameFrameStarted.add(this.update, this); } /** * Returns the buffer stats */ getStats() { let stats = { rootKeys: 0, subKeys: 0, vramBytes: 0, }; this.cache.forEach((subCache, key) => { ++stats.rootKeys; subCache.forEach((cacheEntry, subKey) => { ++stats.subKeys; const canvas = cacheEntry.canvas; stats.vramBytes += canvas.width * canvas.height * 4; }); }); return stats; } /** * Goes to the next buffer iteration, clearing all buffers which were not used * for a few iterations */ garbargeCollect() { let totalKeys = 0; let deletedKeys = 0; const minIteration = this.iterationIndex; this.cache.forEach((subCache, key) => { let unusedSubKeys = []; // Filter sub cache subCache.forEach((cacheEntry, subKey) => { if (cacheEntry.lastUse < minIteration) { unusedSubKeys.push(subKey); Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["freeCanvas"])(cacheEntry.canvas); ++deletedKeys; } else { ++totalKeys; } }); // Delete unused sub keys for (let i = 0; i < unusedSubKeys.length; ++i) { subCache.delete(unusedSubKeys[i]); } }); // Make sure our backlog never gets too big Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["clearBufferBacklog"])(); const bufferStats = Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["getBufferStats"])(); const mbUsed = Object(_utils__WEBPACK_IMPORTED_MODULE_3__["round1Digit"])(bufferStats.vramUsage / (1024 * 1024)); logger.log( "GC: Remove", (deletedKeys + "").padStart(4), ", Remain", (totalKeys + "").padStart(4), "(", (bufferStats.bufferCount + "").padStart(4), "total", ")", "(", (bufferStats.backlog + "").padStart(4), "backlog", ")", "VRAM:", mbUsed, "MB" ); ++this.iterationIndex; } update() { const now = this.root.time.realtimeNow(); if (now - this.lastIteration > bufferGcDurationSeconds) { this.lastIteration = now; this.garbargeCollect(); } } /** * @param {object} param0 * @param {string} param0.key * @param {string} param0.subKey * @param {number} param0.w * @param {number} param0.h * @param {number} param0.dpi * @param {function(HTMLCanvasElement, CanvasRenderingContext2D, number, number, number, object?) : void} param0.redrawMethod * @param {object=} param0.additionalParams * @returns {HTMLCanvasElement} * */ getForKey({ key, subKey, w, h, dpi, redrawMethod, additionalParams }) { // First, create parent key let parent = this.cache.get(key); if (!parent) { parent = new Map(); this.cache.set(key, parent); } // Now search for sub key const cacheHit = parent.get(subKey); if (cacheHit) { cacheHit.lastUse = this.iterationIndex; return cacheHit.canvas; } // Need to generate new buffer const effectiveWidth = w * dpi; const effectiveHeight = h * dpi; const [canvas, context] = Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["makeOffscreenBuffer"])(effectiveWidth, effectiveHeight, { reusable: true, label: "buffer-" + key + "/" + subKey, smooth: true, }); redrawMethod(canvas, context, w, h, dpi, additionalParams); parent.set(subKey, { canvas, context, lastUse: this.iterationIndex, }); return canvas; } } /***/ }), /***/ "./src/js/core/buffer_utils.js": /*!*************************************!*\ !*** ./src/js/core/buffer_utils.js ***! \*************************************/ /*! exports provided: enableImageSmoothing, disableImageSmoothing, getBufferVramUsageBytes, getBufferStats, clearBufferBacklog, makeOffscreenBuffer, registerCanvas, freeCanvas */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableImageSmoothing", function() { return enableImageSmoothing; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "disableImageSmoothing", function() { return disableImageSmoothing; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBufferVramUsageBytes", function() { return getBufferVramUsageBytes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBufferStats", function() { return getBufferStats; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clearBufferBacklog", function() { return clearBufferBacklog; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeOffscreenBuffer", function() { return makeOffscreenBuffer; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "registerCanvas", function() { return registerCanvas; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "freeCanvas", function() { return freeCanvas; }); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("buffer_utils"); /** * Enables images smoothing on a context * @param {CanvasRenderingContext2D} context */ function enableImageSmoothing(context) { context.imageSmoothingEnabled = true; context.webkitImageSmoothingEnabled = true; // @ts-ignore context.imageSmoothingQuality = _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].smoothing.quality; } /** * Disables image smoothing on a context * @param {CanvasRenderingContext2D} context */ function disableImageSmoothing(context) { context.imageSmoothingEnabled = false; context.webkitImageSmoothingEnabled = false; } const registeredCanvas = []; const freeCanvasList = []; let vramUsage = 0; let bufferCount = 0; /** * * @param {HTMLCanvasElement} canvas */ function getBufferVramUsageBytes(canvas) { return canvas.width * canvas.height * 4; } /** * Returns stats on the allocated buffers */ function getBufferStats() { return { vramUsage, bufferCount, backlog: freeCanvasList.length, }; } function clearBufferBacklog() { while (freeCanvasList.length > 50) { freeCanvasList.pop(); } } /** * Creates a new offscreen buffer * @param {Number} w * @param {Number} h * @returns {[HTMLCanvasElement, CanvasRenderingContext2D]} */ function makeOffscreenBuffer(w, h, { smooth = true, reusable = true, label = "buffer" }) { window.assert(w > 0 && h > 0, "W or H < 0"); if (w % 1 !== 0 || h % 1 !== 0) { // console.warn("Subpixel offscreen buffer size:", w, h); } if (w < 1 || h < 1) { logger.error("Offscreen buffer size < 0:", w, "x", h); w = Math.max(1, w); h = Math.max(1, h); } const recommendedSize = 1024 * 1024; if (w * h > recommendedSize) { logger.warn("Creating huge buffer:", w, "x", h, "with label", label); } w = Math.floor(w); h = Math.floor(h); let canvas = null; let context = null; let bestMatchingOne = null; let bestMatchingPixelsDiff = 1e50; const currentPixels = w * h; // Ok, search in cache first for (let i = 0; i < freeCanvasList.length; ++i) { const { canvas: useableCanvas, context: useableContext } = freeCanvasList[i]; if (useableCanvas.width === w && useableCanvas.height === h) { // Ok we found one canvas = useableCanvas; context = useableContext; Object(_utils__WEBPACK_IMPORTED_MODULE_1__["fastArrayDelete"])(freeCanvasList, i); break; } const otherPixels = useableCanvas.width * useableCanvas.height; const diff = Math.abs(otherPixels - currentPixels); if (diff < bestMatchingPixelsDiff) { bestMatchingPixelsDiff = diff; bestMatchingOne = { canvas: useableCanvas, context: useableContext, index: i, }; } } // Ok none matching, reuse one though if (!canvas && bestMatchingOne) { canvas = bestMatchingOne.canvas; context = bestMatchingOne.context; canvas.width = w; canvas.height = h; Object(_utils__WEBPACK_IMPORTED_MODULE_1__["fastArrayDelete"])(freeCanvasList, bestMatchingOne.index); } // Reset context if (context) { // Restore past state context.restore(); context.save(); context.clearRect(0, 0, canvas.width, canvas.height); delete canvas.style.width; delete canvas.style.height; } // None found , create new one if (!canvas) { canvas = document.createElement("canvas"); context = canvas.getContext("2d" /*, { alpha } */); canvas.width = w; canvas.height = h; // Initial state context.save(); } canvas.label = label; if (smooth) { enableImageSmoothing(context); } else { disableImageSmoothing(context); } if (reusable) { registerCanvas(canvas, context); } return [canvas, context]; } /** * Frees a canvas * @param {HTMLCanvasElement} canvas */ function registerCanvas(canvas, context) { registeredCanvas.push({ canvas, context }); bufferCount += 1; vramUsage += getBufferVramUsageBytes(canvas); } /** * Frees a canvas * @param {HTMLCanvasElement} canvas */ function freeCanvas(canvas) { window.assert(canvas, "Canvas is empty"); let index = -1; let data = null; for (let i = 0; i < registeredCanvas.length; ++i) { if (registeredCanvas[i].canvas === canvas) { index = i; data = registeredCanvas[i]; break; } } if (index < 0) { logger.error("Tried to free unregistered canvas of size", canvas.width, canvas.height); return; } Object(_utils__WEBPACK_IMPORTED_MODULE_1__["fastArrayDelete"])(registeredCanvas, index); freeCanvasList.push(data); bufferCount -= 1; vramUsage -= getBufferVramUsageBytes(canvas); } /***/ }), /***/ "./src/js/core/cachebust.js": /*!**********************************!*\ !*** ./src/js/core/cachebust.js ***! \**********************************/ /*! exports provided: cachebust */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cachebust", function() { return cachebust; }); /** * Generates a cachebuster string. This only modifies the path in the browser version * @param {string} path */ function cachebust(path) { if (false) {} return path; } /***/ }), /***/ "./src/js/core/click_detector.js": /*!***************************************!*\ !*** ./src/js/core/click_detector.js ***! \***************************************/ /*! exports provided: MAX_MOVE_DISTANCE_PX, clickDetectorGlobals, ClickDetector */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MAX_MOVE_DISTANCE_PX", function() { return MAX_MOVE_DISTANCE_PX; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clickDetectorGlobals", function() { return clickDetectorGlobals; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClickDetector", function() { return ClickDetector; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /* harmony import */ var _vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./vector */ "./src/js/core/vector.js"); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _globals__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./globals */ "./src/js/core/globals.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("click_detector"); const MAX_MOVE_DISTANCE_PX = _config__WEBPACK_IMPORTED_MODULE_4__["IS_MOBILE"] ? 20 : 80; // For debugging const registerClickDetectors = true && true; if (registerClickDetectors) { /** @type {Array} */ window.activeClickDetectors = []; } // Store active click detectors so we can cancel them /** @type {Array} */ const ongoingClickDetectors = []; // Store when the last touch event was registered, to avoid accepting a touch *and* a click event let clickDetectorGlobals = { lastTouchTime: -1000, }; /** * Click detector creation payload typehints * @typedef {{ * consumeEvents?: boolean, * preventDefault?: boolean, * applyCssClass?: string, * captureTouchmove?: boolean, * targetOnly?: boolean, * maxDistance?: number, * clickSound?: string, * preventClick?: boolean, * }} ClickDetectorConstructorArgs */ // Detects clicks class ClickDetector { /** * * @param {Element} element * @param {object} param1 * @param {boolean=} param1.consumeEvents Whether to call stopPropagation * (Useful for nested elements where the parent has a click handler as wel) * @param {boolean=} param1.preventDefault Whether to call preventDefault (Usually makes the handler faster) * @param {string=} param1.applyCssClass The css class to add while the element is pressed * @param {boolean=} param1.captureTouchmove Whether to capture touchmove events as well * @param {boolean=} param1.targetOnly Whether to also accept clicks on child elements (e.target !== element) * @param {number=} param1.maxDistance The maximum distance in pixels to accept clicks * @param {string=} param1.clickSound Sound key to play on touchdown * @param {boolean=} param1.preventClick Whether to prevent click events */ constructor( element, { consumeEvents = false, preventDefault = true, applyCssClass = "pressed", captureTouchmove = false, targetOnly = false, maxDistance = MAX_MOVE_DISTANCE_PX, clickSound = _platform_sound__WEBPACK_IMPORTED_MODULE_5__["SOUNDS"].uiClick, preventClick = false, } ) { window.assert(element, "No element given!"); this.clickDownPosition = null; this.consumeEvents = consumeEvents; this.preventDefault = preventDefault; this.applyCssClass = applyCssClass; this.captureTouchmove = captureTouchmove; this.targetOnly = targetOnly; this.clickSound = clickSound; this.maxDistance = maxDistance; this.preventClick = preventClick; // Signals this.click = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.rightClick = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.touchstart = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.touchmove = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.touchend = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.touchcancel = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); // Simple signals which just receive the touch position this.touchstartSimple = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.touchmoveSimple = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); this.touchendSimple = new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"](); // Store time of touch start this.clickStartTime = null; // A click can be cancelled if another detector registers a click this.cancelled = false; this.internalBindTo(/** @type {HTMLElement} */ (element)); } /** * Cleans up all event listeners of this detector */ cleanup() { if (this.element) { if (registerClickDetectors) { const index = window.activeClickDetectors.indexOf(this); if (index < 0) { logger.error("Click detector cleanup but is not active"); } else { window.activeClickDetectors.splice(index, 1); } } const options = this.internalGetEventListenerOptions(); if (_config__WEBPACK_IMPORTED_MODULE_4__["SUPPORT_TOUCH"]) { this.element.removeEventListener("touchstart", this.handlerTouchStart, options); this.element.removeEventListener("touchend", this.handlerTouchEnd, options); this.element.removeEventListener("touchcancel", this.handlerTouchCancel, options); } this.element.removeEventListener("mouseup", this.handlerTouchStart, options); this.element.removeEventListener("mousedown", this.handlerTouchEnd, options); this.element.removeEventListener("mouseout", this.handlerTouchCancel, options); if (this.captureTouchmove) { if (_config__WEBPACK_IMPORTED_MODULE_4__["SUPPORT_TOUCH"]) { this.element.removeEventListener("touchmove", this.handlerTouchMove, options); } this.element.removeEventListener("mousemove", this.handlerTouchMove, options); } if (this.preventClick) { this.element.removeEventListener("click", this.handlerPreventClick, options); } this.click.removeAll(); this.touchstart.removeAll(); this.touchmove.removeAll(); this.touchend.removeAll(); this.touchcancel.removeAll(); // TODO: Remove pointer captures this.element = null; } } // INTERNAL METHODS /** * * @param {Event} event */ internalPreventClick(event) { window.focus(); event.preventDefault(); } /** * Internal method to get the options to pass to an event listener */ internalGetEventListenerOptions() { return { capture: this.consumeEvents, passive: !this.preventDefault, }; } /** * Binds the click detector to an element * @param {HTMLElement} element */ internalBindTo(element) { const options = this.internalGetEventListenerOptions(); this.handlerTouchStart = this.internalOnPointerDown.bind(this); this.handlerTouchEnd = this.internalOnPointerEnd.bind(this); this.handlerTouchMove = this.internalOnPointerMove.bind(this); this.handlerTouchCancel = this.internalOnTouchCancel.bind(this); if (this.preventClick) { this.handlerPreventClick = this.internalPreventClick.bind(this); element.addEventListener("click", this.handlerPreventClick, options); } if (_config__WEBPACK_IMPORTED_MODULE_4__["SUPPORT_TOUCH"]) { element.addEventListener("touchstart", this.handlerTouchStart, options); element.addEventListener("touchend", this.handlerTouchEnd, options); element.addEventListener("touchcancel", this.handlerTouchCancel, options); } element.addEventListener("mousedown", this.handlerTouchStart, options); element.addEventListener("mouseup", this.handlerTouchEnd, options); element.addEventListener("mouseout", this.handlerTouchCancel, options); if (this.captureTouchmove) { if (_config__WEBPACK_IMPORTED_MODULE_4__["SUPPORT_TOUCH"]) { element.addEventListener("touchmove", this.handlerTouchMove, options); } element.addEventListener("mousemove", this.handlerTouchMove, options); } if (registerClickDetectors) { window.activeClickDetectors.push(this); } this.element = element; } /** * Returns if the bound element is currently in the DOM. */ internalIsDomElementAttached() { return this.element && document.documentElement.contains(this.element); } /** * Checks if the given event is relevant for this detector * @param {TouchEvent|MouseEvent} event */ internalEventPreHandler(event, expectedRemainingTouches = 1) { if (!this.element) { // Already cleaned up return false; } if (this.targetOnly && event.target !== this.element) { // Clicked a child element return false; } // Stop any propagation and defaults if configured if (this.consumeEvents && event.cancelable) { event.stopPropagation(); } if (this.preventDefault && event.cancelable) { event.preventDefault(); } if (window.TouchEvent && event instanceof TouchEvent) { clickDetectorGlobals.lastTouchTime = performance.now(); // console.log("Got touches", event.targetTouches.length, "vs", expectedRemainingTouches); if (event.targetTouches.length !== expectedRemainingTouches) { return false; } } if (event instanceof MouseEvent) { if (performance.now() - clickDetectorGlobals.lastTouchTime < 1000.0) { return false; } } return true; } /** * Extracts the mous position from an event * @param {TouchEvent|MouseEvent} event * @returns {Vector} The client space position */ static extractPointerPosition(event) { if (window.TouchEvent && event instanceof TouchEvent) { if (event.changedTouches.length !== 1) { logger.warn( "Got unexpected target touches:", event.targetTouches.length, "->", event.targetTouches ); return new _vector__WEBPACK_IMPORTED_MODULE_3__["Vector"](0, 0); } const touch = event.changedTouches[0]; return new _vector__WEBPACK_IMPORTED_MODULE_3__["Vector"](touch.clientX, touch.clientY); } if (event instanceof MouseEvent) { return new _vector__WEBPACK_IMPORTED_MODULE_3__["Vector"](event.clientX, event.clientY); } window.assert(false, "Got unknown event: " + event); return new _vector__WEBPACK_IMPORTED_MODULE_3__["Vector"](0, 0); } /** * Cacnels all ongoing events on this detector */ cancelOngoingEvents() { if (this.applyCssClass && this.element) { this.element.classList.remove(this.applyCssClass); } this.clickDownPosition = null; this.clickStartTime = null; this.cancelled = true; Object(_utils__WEBPACK_IMPORTED_MODULE_2__["fastArrayDeleteValueIfContained"])(ongoingClickDetectors, this); } /** * Internal pointer down handler * @param {TouchEvent|MouseEvent} event */ internalOnPointerDown(event) { window.focus(); if (!this.internalEventPreHandler(event, 1)) { return false; } const position = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event); if (event instanceof MouseEvent) { const isRightClick = event.button === 2; if (isRightClick) { // Ignore right clicks this.rightClick.dispatch(position, event); this.cancelled = true; this.clickDownPosition = null; return; } } if (this.clickDownPosition) { logger.warn("Ignoring double click"); return false; } this.cancelled = false; this.touchstart.dispatch(event); // Store where the touch started this.clickDownPosition = position; this.clickStartTime = performance.now(); this.touchstartSimple.dispatch(this.clickDownPosition.x, this.clickDownPosition.y); // If we are not currently within a click, register it if (ongoingClickDetectors.indexOf(this) < 0) { ongoingClickDetectors.push(this); } else { logger.warn("Click detector got pointer down of active pointer twice"); } // If we should apply any classes, do this now if (this.applyCssClass) { this.element.classList.add(this.applyCssClass); } // If we should play any sound, do this if (this.clickSound) { _globals__WEBPACK_IMPORTED_MODULE_6__["GLOBAL_APP"].sound.playUiSound(this.clickSound); } return false; } /** * Internal pointer move handler * @param {TouchEvent|MouseEvent} event */ internalOnPointerMove(event) { if (!this.internalEventPreHandler(event, 1)) { return false; } this.touchmove.dispatch(event); const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event); this.touchmoveSimple.dispatch(pos.x, pos.y); return false; } /** * Internal pointer end handler * @param {TouchEvent|MouseEvent} event */ internalOnPointerEnd(event) { window.focus(); if (!this.internalEventPreHandler(event, 0)) { return false; } if (this.cancelled) { // warn(this, "Not dispatching touchend on cancelled listener"); return false; } if (event instanceof MouseEvent) { const isRightClick = event.button === 2; if (isRightClick) { return; } } const index = ongoingClickDetectors.indexOf(this); if (index < 0) { logger.warn("Got pointer end but click detector is not in pressed state"); } else { Object(_utils__WEBPACK_IMPORTED_MODULE_2__["fastArrayDelete"])(ongoingClickDetectors, index); } let dispatchClick = false; let dispatchClickPos = null; // Check for correct down position, otherwise must have pinched or so if (this.clickDownPosition) { const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event); const distance = pos.distance(this.clickDownPosition); if (!_config__WEBPACK_IMPORTED_MODULE_4__["IS_MOBILE"] || distance <= this.maxDistance) { dispatchClick = true; dispatchClickPos = pos; } else { console.warn("[ClickDetector] Touch does not count as click:", "(was", distance, ")"); } } this.clickDownPosition = null; this.clickStartTime = null; if (this.applyCssClass) { this.element.classList.remove(this.applyCssClass); } // Dispatch in the end to avoid the element getting invalidated // Also make sure that the element is still in the dom if (this.internalIsDomElementAttached()) { this.touchend.dispatch(event); this.touchendSimple.dispatch(); if (dispatchClick) { const detectors = ongoingClickDetectors.slice(); for (let i = 0; i < detectors.length; ++i) { detectors[i].cancelOngoingEvents(); } this.click.dispatch(dispatchClickPos, event); } } return false; } /** * Internal touch cancel handler * @param {TouchEvent|MouseEvent} event */ internalOnTouchCancel(event) { if (!this.internalEventPreHandler(event, 0)) { return false; } if (this.cancelled) { // warn(this, "Not dispatching touchcancel on cancelled listener"); return false; } this.cancelOngoingEvents(); this.touchcancel.dispatch(event); this.touchendSimple.dispatch(event); return false; } } /***/ }), /***/ "./src/js/core/config.js": /*!*******************************!*\ !*** ./src/js/core/config.js ***! \*******************************/ /*! exports provided: IS_DEBUG, IS_DEMO, SUPPORT_TOUCH, THIRDPARTY_URLS, globalConfig, IS_MOBILE */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IS_DEBUG", function() { return IS_DEBUG; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IS_DEMO", function() { return IS_DEMO; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SUPPORT_TOUCH", function() { return SUPPORT_TOUCH; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "THIRDPARTY_URLS", function() { return THIRDPARTY_URLS; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "globalConfig", function() { return globalConfig; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IS_MOBILE", function() { return IS_MOBILE; }); /* harmony import */ var _query_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./query_parameters */ "./src/js/core/query_parameters.js"); const IS_DEBUG = true || (false); const IS_DEMO = true ? false : undefined; const SUPPORT_TOUCH = false; const smoothCanvas = true; const THIRDPARTY_URLS = { discord: "https://discord.gg/HN7EVzV", github: "https://github.com/tobspr/shapez.io", reddit: "https://www.reddit.com/r/shapezio", standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/", }; const globalConfig = { // Size of a single tile in Pixels. // NOTICE: Update webpack.production.config too! tileSize: 32, halfTileSize: 16, // Which dpi the assets have assetsDpi: 192 / 32, assetsSharpness: 1.5, shapesSharpness: 1.4, // Production analytics statisticsGraphDpi: 2.5, statisticsGraphSlices: 100, analyticsSliceDurationSeconds: true ? 1 : undefined, minimumTickRate: 25, maximumTickRate: 500, // Map mapChunkSize: 16, mapChunkOverviewMinZoom: 0.9, mapChunkWorldSize: null, // COMPUTED // Belt speeds // NOTICE: Update webpack.production.config too! beltSpeedItemsPerSecond: 2, minerSpeedItemsPerSecond: 0, // COMPUTED defaultItemDiameter: 20, itemSpacingOnBelts: 0.63, wiresSpeedItemsPerSecond: 6, undergroundBeltMaxTilesByTier: [5, 8], buildingSpeeds: { cutter: 1 / 4, cutterQuad: 1 / 4, rotater: 1 / 1, rotaterCCW: 1 / 1, rotaterFL: 1 / 1, painter: 1 / 6, painterDouble: 1 / 8, painterQuad: 1 / 8, mixer: 1 / 5, stacker: 1 / 6, advancedProcessor: 1 / 3, filter: 1, }, // Zooming initialZoom: 1.9, minZoomLevel: 0.1, maxZoomLevel: 3, // Global game speed gameSpeed: 1, warmupTimeSecondsFast: 0.1, warmupTimeSecondsRegular: 1, smoothing: { smoothMainCanvas: smoothCanvas && true, quality: "low", // Low is CRUCIAL for mobile performance! }, rendering: {}, debug: IS_DEBUG ? __webpack_require__(/*! ./config.local */ "./src/js/core/config.local.js").default : {}, // Secret vars info: { // Binary file salt file: "Ec'])@^+*9zMevK3uMV4432x9%iK'=", // Savegame salt sgSalt: "}95Q3%8/.837Lqym_BJx%q7)pAHJbF", // Analytics key analyticsApiKey: "baf6a50f0cc7dfdec5a0e21c88a1c69a4b34bc4a", }, }; const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); // Automatic calculations globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5; globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize; // Dynamic calculations if (globalConfig.debug.disableMapOverview) { globalConfig.mapChunkOverviewMinZoom = 0; } // Stuff for making the trailer if (globalConfig.debug.renderForTrailer) { globalConfig.debug.framePausesBetweenTicks = 32; // globalConfig.mapChunkOverviewMinZoom = 0.0; // globalConfig.debug.instantBelts = true; // globalConfig.debug.instantProcessors = true; // globalConfig.debug.instantMiners = true; globalConfig.debug.disableSavegameWrite = true; // globalConfig.beltSpeedItemsPerSecond *= 2; } if (globalConfig.debug.fastGameEnter) { globalConfig.debug.noArtificalDelays = true; } /***/ }), /***/ "./src/js/core/config.local.js": /*!*************************************!*\ !*** ./src/js/core/config.local.js ***! \*************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = ({ // You can set any debug options here! /* ---dev:start */ // ----------------------------------------------------------------------------------- _fastGameEnter: "Quickly enters the game and skips the main menu - good for fast iterating", fastGameEnter: false, // ----------------------------------------------------------------------------------- _noArtificialDelays: "Skips any delays like transitions between states and such", noArtificialDelays: false, // ----------------------------------------------------------------------------------- _disableSavegameWrite: "Disables writing of savegames, useful for testing the same savegame over and over", disableSavegameWrite: false, // ----------------------------------------------------------------------------------- _showEntityBounds: "Shows bounds of all entities", showEntityBounds: false, // ----------------------------------------------------------------------------------- _showAcceptorEjectors: "Shows arrows for every ejector / acceptor", showAcceptorEjectors: false, // ----------------------------------------------------------------------------------- _disableMusic: "Disables the music (Overrides any setting, can cause weird behaviour)", disableMusic: false, // ----------------------------------------------------------------------------------- _doNotRenderStatics: "Do not render static map entities (=most buildings)", doNotRenderStatics: false, // ----------------------------------------------------------------------------------- _disableZoomLimits: "Allow to zoom freely without limits", disableZoomLimits: false, // ----------------------------------------------------------------------------------- _showChunkBorders: "Shows a border arround every chunk", showChunkBorders: false, // ----------------------------------------------------------------------------------- _rewardsInstant: "All rewards can be unlocked by passing just 1 of any shape", rewardsInstant: false, // ----------------------------------------------------------------------------------- _allBuildingsUnlocked: "Unlocks all buildings", allBuildingsUnlocked: false, // ----------------------------------------------------------------------------------- _blueprintsNoCost: "Disables cost of blueprints", blueprintsNoCost: false, // ----------------------------------------------------------------------------------- _upgradesNoCost: "Disables cost of upgrades", upgradesNoCost: false, // ----------------------------------------------------------------------------------- _disableUnlockDialog: "Disables the dialog when completing a level", disableUnlockDialog: false, // ----------------------------------------------------------------------------------- _disableLogicTicks: "Disables the simulation - This effectively pauses the game.", disableLogicTicks: false, // ----------------------------------------------------------------------------------- _testClipping: "Test the rendering if everything is clipped out properly", testClipping: false, // ----------------------------------------------------------------------------------- // Allows to render slower, useful for recording at half speed to avoid stuttering // framePausesBetweenTicks: 1, // ----------------------------------------------------------------------------------- _testTranslations: "Replace all translations with emojis to see which texts are translateable", testTranslations: false, // ----------------------------------------------------------------------------------- _enableEntityInspector: "Enables an inspector which shows information about the entity below the curosr", enableEntityInspector: false, // ----------------------------------------------------------------------------------- _testAds: "Enables ads in the local build (normally they are deactivated there)", testAds: false, // ----------------------------------------------------------------------------------- _noApiCalls: "Disables API calls", noApiCalls: true, // ----------------------------------------------------------------------------------- _disableMapOverview: "Disables the automatic switch to an overview when zooming out", disableMapOverview: false, // ----------------------------------------------------------------------------------- _disableUpgradeNotification: "Disables the notification when there are new entries in the changelog since last played", disableUpgradeNotification: false, // ----------------------------------------------------------------------------------- _instantBelts: "Makes belts almost infinitely fast", instantBelts: false, // ----------------------------------------------------------------------------------- _instantProcessors: "Makes item processors almost infinitely fast", instantProcessors: false, // ----------------------------------------------------------------------------------- _instantMiners: "Makes miners almost infinitely fast", instantMiners: false, // ----------------------------------------------------------------------------------- _resumeGameOnFastEnter: "When using fastGameEnter, controls whether a new game is started or the last one is resumed", resumeGameOnFastEnter: false, // ----------------------------------------------------------------------------------- _renderForTrailer: "Special option used to render the trailer", renderForTrailer: false, // ----------------------------------------------------------------------------------- _renderChanges: "Whether to render changes", renderChanges: false, // ----------------------------------------------------------------------------------- _renderBeltPaths: "Whether to render belt paths", renderBeltPaths: false, // ----------------------------------------------------------------------------------- _checkBeltPaths: "Whether to check belt paths", checkBeltPaths: false, // ----------------------------------------------------------------------------------- _showAtlasInfo: "Shows detailed information about which atlas is used", showAtlasInfo: false, // ----------------------------------------------------------------------------------- _renderWireRotations: "Renders the rotation of all wires", renderWireRotations: false, // ----------------------------------------------------------------------------------- _renderWireNetworkInfos: "Renders information about wire networks", renderWireNetworkInfos: false, // ----------------------------------------------------------------------------------- /* ---dev:end */ }); /***/ }), /***/ "./src/js/core/dpi_manager.js": /*!************************************!*\ !*** ./src/js/core/dpi_manager.js ***! \************************************/ /*! exports provided: getDeviceDPI, smoothenDpi, prepareHighDPIContext, resizeHighDPICanvas, resizeCanvas, resizeCanvasAndClear */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDeviceDPI", function() { return getDeviceDPI; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "smoothenDpi", function() { return smoothenDpi; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prepareHighDPIContext", function() { return prepareHighDPIContext; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resizeHighDPICanvas", function() { return resizeHighDPICanvas; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resizeCanvas", function() { return resizeCanvas; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resizeCanvasAndClear", function() { return resizeCanvasAndClear; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /** * Returns the current dpi * @returns {number} */ function getDeviceDPI() { return window.devicePixelRatio || 1; } /** * * @param {number} dpi * @returns {number} Smoothed dpi */ function smoothenDpi(dpi) { if (dpi < 0.02) { return 0.02; } else if (dpi < 0.1) { return Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(dpi); } else if (dpi < 1) { return Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round1Digit"])(dpi); } else { return Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round1Digit"])(Math.round(dpi / 0.5) * 0.5); } } // Initial dpi // setDPIMultiplicator(1); /** * Prepares a context for hihg dpi rendering * @param {CanvasRenderingContext2D} context */ function prepareHighDPIContext(context, smooth = true) { const dpi = getDeviceDPI(); context.scale(dpi, dpi); if (smooth) { context.imageSmoothingEnabled = true; context.webkitImageSmoothingEnabled = true; // @ts-ignore context.imageSmoothingQuality = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].smoothing.quality; } else { context.imageSmoothingEnabled = false; context.webkitImageSmoothingEnabled = false; } } /** * Resizes a high dpi canvas * @param {HTMLCanvasElement} canvas * @param {number} w * @param {number} h */ function resizeHighDPICanvas(canvas, w, h, smooth = true) { const dpi = getDeviceDPI(); const wNumber = Math.floor(w); const hNumber = Math.floor(h); const targetW = Math.floor(wNumber * dpi); const targetH = Math.floor(hNumber * dpi); if (targetW !== canvas.width || targetH !== canvas.height) { // console.log("Resize Canvas from", canvas.width, canvas.height, "to", targetW, targetH) canvas.width = targetW; canvas.height = targetH; canvas.style.width = wNumber + "px"; canvas.style.height = hNumber + "px"; prepareHighDPIContext(canvas.getContext("2d"), smooth); } } /** * Resizes a canvas * @param {HTMLCanvasElement} canvas * @param {number} w * @param {number} h */ function resizeCanvas(canvas, w, h, setStyle = true) { const actualW = Math.ceil(w); const actualH = Math.ceil(h); if (actualW !== canvas.width || actualH !== canvas.height) { canvas.width = actualW; canvas.height = actualH; if (setStyle) { canvas.style.width = actualW + "px"; canvas.style.height = actualH + "px"; } // console.log("Resizing canvas to", actualW, "x", actualH); } } /** * Resizes a canvas and makes sure its cleared * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h */ function resizeCanvasAndClear(canvas, context, w, h) { const actualW = Math.ceil(w); const actualH = Math.ceil(h); if (actualW !== canvas.width || actualH !== canvas.height) { canvas.width = actualW; canvas.height = actualH; canvas.style.width = actualW + "px"; canvas.style.height = actualH + "px"; // console.log("Resizing canvas to", actualW, "x", actualH); } else { context.clearRect(0, 0, actualW, actualH); } } /***/ }), /***/ "./src/js/core/draw_parameters.js": /*!****************************************!*\ !*** ./src/js/core/draw_parameters.js ***! \****************************************/ /*! exports provided: DrawParameters */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DrawParameters", function() { return DrawParameters; }); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /** * @typedef {import("../game/root").GameRoot} GameRoot * @typedef {import("./rectangle").Rectangle} Rectangle */ class DrawParameters { constructor({ context, visibleRect, desiredAtlasScale, zoomLevel, root }) { /** @type {CanvasRenderingContext2D} */ this.context = context; /** @type {Rectangle} */ this.visibleRect = visibleRect; /** @type {string} */ this.desiredAtlasScale = desiredAtlasScale; /** @type {number} */ this.zoomLevel = zoomLevel; // FIXME: Not really nice /** @type {GameRoot} */ this.root = root; } } /***/ }), /***/ "./src/js/core/draw_utils.js": /*!***********************************!*\ !*** ./src/js/core/draw_utils.js ***! \***********************************/ /*! exports provided: initDrawUtils, drawRotatedSprite, drawSpriteClipped */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initDrawUtils", function() { return initDrawUtils; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "drawRotatedSprite", function() { return drawRotatedSprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "drawSpriteClipped", function() { return drawSpriteClipped; }); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _rectangle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./rectangle */ "./src/js/core/rectangle.js"); /** * @typedef {import("./sprites").AtlasSprite} AtlasSprite * @typedef {import("./draw_parameters").DrawParameters} DrawParameters */ const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("draw_utils"); function initDrawUtils() { CanvasRenderingContext2D.prototype.beginRoundedRect = function (x, y, w, h, r) { this.beginPath(); if (r < 0.05) { this.rect(x, y, w, h); return; } if (w < 2 * r) { r = w / 2; } if (h < 2 * r) { r = h / 2; } this.moveTo(x + r, y); this.arcTo(x + w, y, x + w, y + h, r); this.arcTo(x + w, y + h, x, y + h, r); this.arcTo(x, y + h, x, y, r); this.arcTo(x, y, x + w, y, r); }; CanvasRenderingContext2D.prototype.beginCircle = function (x, y, r) { this.beginPath(); if (r < 0.05) { this.rect(x, y, 1, 1); return; } this.arc(x, y, r, 0, 2.0 * Math.PI); }; } /** * * @param {object} param0 * @param {DrawParameters} param0.parameters * @param {AtlasSprite} param0.sprite * @param {number} param0.x * @param {number} param0.y * @param {number} param0.angle * @param {number} param0.size * @param {number=} param0.offsetX * @param {number=} param0.offsetY */ function drawRotatedSprite({ parameters, sprite, x, y, angle, size, offsetX = 0, offsetY = 0 }) { if (angle === 0) { sprite.drawCachedCentered(parameters, x + offsetX, y + offsetY, size); return; } parameters.context.translate(x, y); parameters.context.rotate(angle); sprite.drawCachedCentered(parameters, offsetX, offsetY, size, false); parameters.context.rotate(-angle); parameters.context.translate(-x, -y); } let warningsShown = 0; /** * Draws a sprite with clipping * @param {object} param0 * @param {DrawParameters} param0.parameters * @param {HTMLCanvasElement} param0.sprite * @param {number} param0.x * @param {number} param0.y * @param {number} param0.w * @param {number} param0.h * @param {number} param0.originalW * @param {number} param0.originalH */ function drawSpriteClipped({ parameters, sprite, x, y, w, h, originalW, originalH }) { const rect = new _rectangle__WEBPACK_IMPORTED_MODULE_2__["Rectangle"](x, y, w, h); const intersection = rect.getIntersection(parameters.visibleRect); if (!intersection) { // Clipped if (++warningsShown % 200 === 1) { logger.warn( "Sprite drawn clipped but it's not on screen - perform culling before (", warningsShown, "warnings)" ); } if (_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.testClipping) { parameters.context.fillStyle = "yellow"; parameters.context.fillRect(x, y, w, h); } return; } parameters.context.drawImage( sprite, // src pos and size ((intersection.x - x) / w) * originalW, ((intersection.y - y) / h) * originalH, (originalW * intersection.w) / w, (originalH * intersection.h) / h, // dest pos and size intersection.x, intersection.y, intersection.w, intersection.h ); } /***/ }), /***/ "./src/js/core/error_handler.js": /*!**************************************!*\ !*** ./src/js/core/error_handler.js ***! \**************************************/ /*! exports provided: APPLICATION_ERROR_OCCURED */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "APPLICATION_ERROR_OCCURED", function() { return APPLICATION_ERROR_OCCURED; }); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); let APPLICATION_ERROR_OCCURED = false; /** * * @param {Event|string} message * @param {string} source * @param {number} lineno * @param {number} colno * @param {Error} source */ function catchErrors(message, source, lineno, colno, error) { let fullPayload = JSON.parse( Object(_logging__WEBPACK_IMPORTED_MODULE_0__["stringifyObjectContainingErrors"])({ message, source, lineno, colno, error, }) ); if (("" + message).indexOf("Script error.") >= 0) { console.warn("Thirdparty script error:", message); return; } if (("" + message).indexOf("NS_ERROR_FAILURE") >= 0) { console.warn("Firefox NS_ERROR_FAILURE error:", message); return; } if (("" + message).indexOf("Cannot read property 'postMessage' of null") >= 0) { console.warn("Safari can not read post message error:", message); return; } if (false) {} console.log("\n\n\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n\n\n"); console.log(" APPLICATION CRASHED "); console.log("\n\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n\n\n"); Object(_logging__WEBPACK_IMPORTED_MODULE_0__["logSection"])("APPLICATION CRASH", "#e53935"); console.error("Error:", message, "->", error); console.log("Payload:", fullPayload); if (window.Sentry && !window.anyModLoaded) { window.Sentry.withScope(scope => { window.Sentry.setTag("message", message); window.Sentry.setTag("source", source); window.Sentry.setExtra("message", message); window.Sentry.setExtra("source", source); window.Sentry.setExtra("lineno", lineno); window.Sentry.setExtra("colno", colno); window.Sentry.setExtra("error", error); window.Sentry.setExtra("fullPayload", fullPayload); try { const userName = window.localStorage.getItem("tracking_context") || null; window.Sentry.setTag("username", userName); } catch (ex) { // ignore } window.Sentry.captureException(error || source); }); } if (APPLICATION_ERROR_OCCURED) { console.warn("ERROR: Only showing and submitting first error"); return; } APPLICATION_ERROR_OCCURED = true; const element = document.createElement("div"); element.id = "applicationError"; const title = document.createElement("h1"); title.innerText = "Whoops!"; element.appendChild(title); const desc = document.createElement("div"); desc.classList.add("desc"); desc.innerHTML = ` It seems the application crashed - I am sorry for that!

An anonymized crash report has been sent, and I will have a look as soon as possible.

If you have additional information how I can reproduce this error, please E-Mail me:  bugs@shapez.io`; element.appendChild(desc); const details = document.createElement("pre"); details.classList.add("details"); details.innerText = (error && error.stack) || message; element.appendChild(details); const inject = function () { if (false) {} if (document.body.parentElement) { document.body.parentElement.appendChild(element); } else { document.body.appendChild(element); } }; if (document.body) { inject(); } else { setTimeout(() => { inject(); }, 200); } return true; } window.onerror = catchErrors; /***/ }), /***/ "./src/js/core/explained_result.js": /*!*****************************************!*\ !*** ./src/js/core/explained_result.js ***! \*****************************************/ /*! exports provided: ExplainedResult */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExplainedResult", function() { return ExplainedResult; }); class ExplainedResult { constructor(result = true, reason = null, additionalProps = {}) { /** @type {boolean} */ this.result = result; /** @type {string} */ this.reason = reason; // Copy additional props for (const key in additionalProps) { this[key] = additionalProps[key]; } } isGood() { return !!this.result; } isBad() { return !this.result; } static good() { return new ExplainedResult(true); } static bad(reason, additionalProps) { return new ExplainedResult(false, reason, additionalProps); } static requireAll(...args) { for (let i = 0; i < args.length; ++i) { const subResult = args[i].call(); if (!subResult.isGood()) { return subResult; } } return this.good(); } } /***/ }), /***/ "./src/js/core/factory.js": /*!********************************!*\ !*** ./src/js/core/factory.js ***! \********************************/ /*! exports provided: Factory */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Factory", function() { return Factory; }); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("factory"); // simple factory pattern class Factory { constructor(id) { this.id = id; // Store array as well as dictionary, to speed up lookups this.entries = []; this.entryIds = []; this.idToEntry = {}; } getId() { return this.id; } register(entry) { // Extract id const id = entry.getId(); window.assert(id, "Factory: Invalid id for class: " + entry); // Check duplicates window.assert(!this.idToEntry[id], "Duplicate factory entry for " + id); // Insert this.entries.push(entry); this.entryIds.push(id); this.idToEntry[id] = entry; } /** * Checks if a given id is registered * @param {string} id * @returns {boolean} */ hasId(id) { return !!this.idToEntry[id]; } /** * Finds an instance by a given id * @param {string} id * @returns {object} */ findById(id) { const entry = this.idToEntry[id]; if (!entry) { logger.error("Object with id", id, "is not registered on factory", this.id, "!"); window.assert(false, "Factory: Object with id '" + id + "' is not registered!"); return null; } return entry; } /** * Returns all entries * @returns {Array} */ getEntries() { return this.entries; } /** * Returns all registered ids * @returns {Array} */ getAllIds() { return this.entryIds; } /** * Returns amount of stored entries * @returns {number} */ getNumEntries() { return this.entries.length; } } /***/ }), /***/ "./src/js/core/game_state.js": /*!***********************************!*\ !*** ./src/js/core/game_state.js ***! \***********************************/ /*! exports provided: GameState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameState", function() { return GameState; }); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _click_detector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _input_receiver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /* harmony import */ var _request_channel__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./request_channel */ "./src/js/core/request_channel.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("game_state"); /** * Basic state of the game state machine. This is the base of the whole game */ class GameState { /** * Constructs a new state with the given id * @param {string} key The id of the state. We use ids to refer to states because otherwise we get * circular references */ constructor(key) { this.key = key; /** @type {StateManager} */ this.stateManager = null; /** @type {Application} */ this.app = null; // Store if we are currently fading out this.fadingOut = false; /** @type {Array} */ this.clickDetectors = []; // Every state captures keyboard events by default this.inputReciever = new _input_receiver__WEBPACK_IMPORTED_MODULE_3__["InputReceiver"]("state-" + key); this.inputReciever.backButton.add(this.onBackButton, this); // A channel we can use to perform async ops this.asyncChannel = new _request_channel__WEBPACK_IMPORTED_MODULE_5__["RequestChannel"](); } //// GETTERS / HELPER METHODS //// /** * Returns the states key * @returns {string} */ getKey() { return this.key; } /** * Returns the html element of the state * @returns {HTMLElement} */ getDivElement() { return document.getElementById("state_" + this.key); } /** * Transfers to a new state * @param {string} stateKey The id of the new state */ moveToState(stateKey, payload = {}, skipFadeOut = false) { if (this.fadingOut) { logger.warn("Skipping move to '" + stateKey + "' since already fading out"); return; } // Clean up event listeners this.internalCleanUpClickDetectors(); // Fading const fadeTime = this.internalGetFadeInOutTime(); const doFade = !skipFadeOut && this.getHasFadeOut() && fadeTime !== 0; logger.log("Moving to", stateKey, "(fading=", doFade, ")"); if (doFade) { this.htmlElement.classList.remove("arrived"); this.fadingOut = true; setTimeout(() => { this.stateManager.moveToState(stateKey, payload); }, fadeTime); } else { this.stateManager.moveToState(stateKey, payload); } } /** * * @param {string} nextStateId * @param {object=} nextStatePayload */ watchAdAndMoveToState(nextStateId, nextStatePayload = {}) { if (this.app.adProvider.getCanShowVideoAd() && this.app.isRenderable()) { this.moveToState( "WatchAdState", { nextStateId, nextStatePayload, }, true ); } else { this.moveToState(nextStateId, nextStatePayload); } } /** * Tracks clicks on a given element and calls the given callback *on this state*. * If you want to call another function wrap it inside a lambda. * @param {Element} element The element to track clicks on * @param {function():void} handler The handler to call * @param {import("./click_detector").ClickDetectorConstructorArgs=} args Click detector arguments */ trackClicks(element, handler, args = {}) { const detector = new _click_detector__WEBPACK_IMPORTED_MODULE_1__["ClickDetector"](element, args); detector.click.add(handler, this); if (true) { // Append a source so we can check where the click detector is from // @ts-ignore detector._src = "state-" + this.key; } this.clickDetectors.push(detector); } /** * Cancels all promises on the api as well as our async channel */ cancelAllAsyncOperations() { this.asyncChannel.cancelAll(); } //// CALLBACKS //// /** * Callback when entering the state, to be overriddemn * @param {any} payload Arbitrary data passed from the state which we are transferring from */ onEnter(payload) {} /** * Callback when leaving the state */ onLeave() {} /** * Callback before leaving the game state or when the page is unloaded */ onBeforeExit() {} /** * Callback when the app got paused (on android, this means in background) */ onAppPause() {} /** * Callback when the app got resumed (on android, this means in foreground again) */ onAppResume() {} /** * Render callback * @param {number} dt Delta time in ms since last render */ onRender(dt) {} /** * Background tick callback, called while the game is inactiev * @param {number} dt Delta time in ms since last tick */ onBackgroundTick(dt) {} /** * Called when the screen resized * @param {number} w window/screen width * @param {number} h window/screen height */ onResized(w, h) {} /** * Internal backbutton handler, called when the hardware back button is pressed or * the escape key is pressed */ onBackButton() {} //// INTERFACE //// /** * Should return how many mulliseconds to fade in / out the state. Not recommended to override! * @returns {number} Time in milliseconds to fade out */ getInOutFadeTime() { if (_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.noArtificialDelays) { return 0; } return 200; } /** * Should return whether to fade in the game state. This will then apply the right css classes * for the fadein. * @returns {boolean} */ getHasFadeIn() { return true; } /** * Should return whether to fade out the game state. This will then apply the right css classes * for the fadeout and wait the delay before moving states * @returns {boolean} */ getHasFadeOut() { return true; } /** * Returns if this state should get paused if it does not have focus * @returns {boolean} true to pause the updating of the game */ getPauseOnFocusLost() { return true; } /** * Should return the html code of the state. * @returns {string} */ getInnerHTML() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return ""; } /** * Returns if the state has an unload confirmation, this is the * "Are you sure you want to leave the page" message. */ getHasUnloadConfirmation() { return false; } /** * Should return the theme music for this state * @returns {string|null} */ getThemeMusic() { return _platform_sound__WEBPACK_IMPORTED_MODULE_6__["MUSIC"].menu; } //////////////////// //// INTERNAL //// /** * Internal callback from the manager. Do not override! * @param {StateManager} stateManager */ internalRegisterCallback(stateManager, app) { window.assert(stateManager, "No state manager"); window.assert(app, "No app"); this.stateManager = stateManager; this.app = app; } /** * Internal callback when entering the state. Do not override! * @param {any} payload Arbitrary data passed from the state which we are transferring from * @param {boolean} callCallback Whether to call the onEnter callback */ internalEnterCallback(payload, callCallback = true) { Object(_logging__WEBPACK_IMPORTED_MODULE_2__["logSection"])(this.key, "#26a69a"); this.app.inputMgr.pushReciever(this.inputReciever); this.htmlElement = this.getDivElement(); this.htmlElement.classList.add("active"); // Apply classes in the next frame so the css transition keeps up Object(_utils__WEBPACK_IMPORTED_MODULE_4__["waitNextFrame"])().then(() => { if (this.htmlElement) { this.htmlElement.classList.remove("fadingOut"); this.htmlElement.classList.remove("fadingIn"); } }); // Call handler if (callCallback) { this.onEnter(payload); } } /** * Internal callback when the state is left. Do not override! */ internalLeaveCallback() { this.onLeave(); this.htmlElement.classList.remove("active"); this.app.inputMgr.popReciever(this.inputReciever); this.internalCleanUpClickDetectors(); this.asyncChannel.cancelAll(); } /** * Internal callback *before* the state is left. Also is called on page unload */ internalOnBeforeExitCallback() { this.onBeforeExit(); } /** * Internal app pause callback */ internalOnAppPauseCallback() { this.onAppPause(); } /** * Internal app resume callback */ internalOnAppResumeCallback() { this.onAppResume(); } /** * Cleans up all click detectors */ internalCleanUpClickDetectors() { if (this.clickDetectors) { for (let i = 0; i < this.clickDetectors.length; ++i) { this.clickDetectors[i].cleanup(); } this.clickDetectors = []; } } /** * Internal method to get the HTML of the game state. * @returns {string} */ internalGetFullHtml() { return this.getInnerHTML(); } /** * Internal method to compute the time to fade in / out * @returns {number} time to fade in / out in ms */ internalGetFadeInOutTime() { if (_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.fastGameEnter) { return 1; } if (_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.noArtificialDelays) { return 1; } return this.getInOutFadeTime(); } } /***/ }), /***/ "./src/js/core/global_registries.js": /*!******************************************!*\ !*** ./src/js/core/global_registries.js ***! \******************************************/ /*! exports provided: gMetaBuildingRegistry, gBuildingsByCategory, gComponentRegistry, gGameSpeedRegistry, gItemRegistry, initBuildingsByCategory */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gMetaBuildingRegistry", function() { return gMetaBuildingRegistry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gBuildingsByCategory", function() { return gBuildingsByCategory; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gComponentRegistry", function() { return gComponentRegistry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gGameSpeedRegistry", function() { return gGameSpeedRegistry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gItemRegistry", function() { return gItemRegistry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initBuildingsByCategory", function() { return initBuildingsByCategory; }); /* harmony import */ var _singleton_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./singleton_factory */ "./src/js/core/singleton_factory.js"); /* harmony import */ var _factory__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./factory */ "./src/js/core/factory.js"); /** * @typedef {import("../game/time/base_game_speed").BaseGameSpeed} BaseGameSpeed * @typedef {import("../game/component").Component} Component * @typedef {import("../game/base_item").BaseItem} BaseItem * @typedef {import("../game/meta_building").MetaBuilding} MetaBuilding // These factories are here to remove circular dependencies /** @type {SingletonFactoryTemplate} */ let gMetaBuildingRegistry = new _singleton_factory__WEBPACK_IMPORTED_MODULE_0__["SingletonFactory"](); /** @type {Object.>>} */ let gBuildingsByCategory = null; /** @type {FactoryTemplate} */ let gComponentRegistry = new _factory__WEBPACK_IMPORTED_MODULE_1__["Factory"]("component"); /** @type {FactoryTemplate} */ let gGameSpeedRegistry = new _factory__WEBPACK_IMPORTED_MODULE_1__["Factory"]("gamespeed"); /** @type {FactoryTemplate} */ let gItemRegistry = new _factory__WEBPACK_IMPORTED_MODULE_1__["Factory"]("item"); // Helpers /** * @param {Object.>>} buildings */ function initBuildingsByCategory(buildings) { gBuildingsByCategory = buildings; } /***/ }), /***/ "./src/js/core/globals.js": /*!********************************!*\ !*** ./src/js/core/globals.js ***! \********************************/ /*! exports provided: GLOBAL_APP, setGlobalApp */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GLOBAL_APP", function() { return GLOBAL_APP; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setGlobalApp", function() { return setGlobalApp; }); /** * Used for the bug reporter, and the click detector which both have no handles to this. * It would be nicer to have no globals, but this is the only one. I promise! * @type {Application} */ let GLOBAL_APP = null; /** * @param {Application} app */ function setGlobalApp(app) { window.assert(!GLOBAL_APP, "Create application twice!"); GLOBAL_APP = app; } /***/ }), /***/ "./src/js/core/input_distributor.js": /*!******************************************!*\ !*** ./src/js/core/input_distributor.js ***! \******************************************/ /*! exports provided: InputDistributor */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputDistributor", function() { return InputDistributor; }); /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./signal */ "./src/js/core/signal.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("input_distributor"); class InputDistributor { /** * * @param {Application} app */ constructor(app) { this.app = app; /** @type {Array} */ this.recieverStack = []; /** @type {Array} */ this.filters = []; /** * All keys which are currently down */ this.keysDown = new Set(); this.bindToEvents(); } /** * Attaches a new filter which can filter and reject events * @param {function(any): boolean} filter */ installFilter(filter) { this.filters.push(filter); } /** * Removes an attached filter * @param {function(any) : boolean} filter */ dismountFilter(filter) { Object(_utils__WEBPACK_IMPORTED_MODULE_2__["fastArrayDeleteValue"])(this.filters, filter); } /** * @param {InputReceiver} reciever */ pushReciever(reciever) { if (this.isRecieverAttached(reciever)) { window.assert(false, "Can not add reciever " + reciever.context + " twice"); logger.error("Can not add reciever", reciever.context, "twice"); return; } this.recieverStack.push(reciever); if (this.recieverStack.length > 10) { logger.error( "Reciever stack is huge, probably some dead receivers arround:", this.recieverStack.map(x => x.context) ); } } /** * @param {InputReceiver} reciever */ popReciever(reciever) { if (this.recieverStack.indexOf(reciever) < 0) { window.assert(false, "Can not pop reciever " + reciever.context + " since its not contained"); logger.error("Can not pop reciever", reciever.context, "since its not contained"); return; } if (this.recieverStack[this.recieverStack.length - 1] !== reciever) { logger.warn( "Popping reciever", reciever.context, "which is not on top of the stack. Stack is: ", this.recieverStack.map(x => x.context) ); } Object(_utils__WEBPACK_IMPORTED_MODULE_2__["arrayDeleteValue"])(this.recieverStack, reciever); } /** * @param {InputReceiver} reciever */ isRecieverAttached(reciever) { return this.recieverStack.indexOf(reciever) >= 0; } /** * @param {InputReceiver} reciever */ isRecieverOnTop(reciever) { return ( this.isRecieverAttached(reciever) && this.recieverStack[this.recieverStack.length - 1] === reciever ); } /** * @param {InputReceiver} reciever */ makeSureAttachedAndOnTop(reciever) { this.makeSureDetached(reciever); this.pushReciever(reciever); } /** * @param {InputReceiver} reciever */ makeSureDetached(reciever) { if (this.isRecieverAttached(reciever)) { Object(_utils__WEBPACK_IMPORTED_MODULE_2__["arrayDeleteValue"])(this.recieverStack, reciever); } } /** * * @param {InputReceiver} reciever */ destroyReceiver(reciever) { this.makeSureDetached(reciever); reciever.cleanup(); } // Internal getTopReciever() { if (this.recieverStack.length > 0) { return this.recieverStack[this.recieverStack.length - 1]; } return null; } bindToEvents() { window.addEventListener("popstate", this.handleBackButton.bind(this), false); document.addEventListener("backbutton", this.handleBackButton.bind(this), false); window.addEventListener("keydown", this.handleKeyMouseDown.bind(this)); window.addEventListener("keyup", this.handleKeyMouseUp.bind(this)); window.addEventListener("mousedown", this.handleKeyMouseDown.bind(this)); window.addEventListener("mouseup", this.handleKeyMouseUp.bind(this)); window.addEventListener("blur", this.handleBlur.bind(this)); } forwardToReceiver(eventId, payload = null) { // Check filters for (let i = 0; i < this.filters.length; ++i) { if (!this.filters[i](eventId)) { return _signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]; } } const reciever = this.getTopReciever(); if (!reciever) { logger.warn("Dismissing event because not reciever was found:", eventId); return; } const signal = reciever[eventId]; window.assert(signal instanceof _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"], "Not a valid event id"); return signal.dispatch(payload); } /** * @param {Event} event */ handleBackButton(event) { event.preventDefault(); event.stopPropagation(); this.forwardToReceiver("backButton"); } /** * Handles when the page got blurred */ handleBlur() { this.forwardToReceiver("pageBlur", {}); this.keysDown.clear(); } /** * @param {KeyboardEvent | MouseEvent} event */ handleKeyMouseDown(event) { const keyCode = event instanceof MouseEvent ? event.button + 1 : event.keyCode; if ( keyCode === 4 || // MB4 keyCode === 5 || // MB5 keyCode === 9 || // TAB keyCode === 16 || // SHIFT keyCode === 17 || // CTRL keyCode === 18 || // ALT (keyCode >= 112 && keyCode < 122) // F1 - F10 ) { event.preventDefault(); } const isInitial = !this.keysDown.has(keyCode); this.keysDown.add(keyCode); if ( this.forwardToReceiver("keydown", { keyCode: keyCode, shift: event.shiftKey, alt: event.altKey, initial: isInitial, event, }) === _signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"] ) { return; } if (keyCode === 27) { // Escape key event.preventDefault(); event.stopPropagation(); return this.forwardToReceiver("backButton"); } } /** * @param {KeyboardEvent | MouseEvent} event */ handleKeyMouseUp(event) { const keyCode = event instanceof MouseEvent ? event.button + 1 : event.keyCode; this.keysDown.delete(keyCode); this.forwardToReceiver("keyup", { keyCode: keyCode, shift: event.shiftKey, alt: event.altKey, }); } } /***/ }), /***/ "./src/js/core/input_receiver.js": /*!***************************************!*\ !*** ./src/js/core/input_receiver.js ***! \***************************************/ /*! exports provided: InputReceiver */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputReceiver", function() { return InputReceiver; }); /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./signal */ "./src/js/core/signal.js"); class InputReceiver { constructor(context = "unknown") { this.context = context; this.backButton = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.keydown = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.keyup = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.pageBlur = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); // Dispatched on destroy this.destroyed = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); } cleanup() { this.backButton.removeAll(); this.keydown.removeAll(); this.keyup.removeAll(); this.destroyed.dispatch(); } } /***/ }), /***/ "./src/js/core/loader.js": /*!*******************************!*\ !*** ./src/js/core/loader.js ***! \*******************************/ /*! exports provided: Loader */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Loader", function() { return Loader; }); /* harmony import */ var _buffer_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _sprites__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sprites */ "./src/js/core/sprites.js"); /* harmony import */ var _cachebust__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cachebust */ "./src/js/core/cachebust.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /** * @typedef {import("../application").Application} Application * @typedef {import("./atlas_definitions").AtlasDefinition} AtlasDefinition; */ const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_3__["createLogger"])("loader"); const missingSpriteIds = {}; class LoaderImpl { constructor() { this.app = null; /** @type {Map} */ this.sprites = new Map(); this.rawImages = []; } /** * @param {Application} app */ linkAppAfterBoot(app) { this.app = app; this.makeSpriteNotFoundCanvas(); } /** * Fetches a given sprite from the cache * @param {string} key * @returns {BaseSprite} */ getSpriteInternal(key) { const sprite = this.sprites.get(key); if (!sprite) { if (!missingSpriteIds[key]) { // Only show error once missingSpriteIds[key] = true; logger.error("Sprite '" + key + "' not found!"); } return this.spriteNotFoundSprite; } return sprite; } /** * Returns an atlas sprite from the cache * @param {string} key * @returns {AtlasSprite} */ getSprite(key) { const sprite = this.getSpriteInternal(key); window.assert(sprite instanceof _sprites__WEBPACK_IMPORTED_MODULE_1__["AtlasSprite"] || sprite === this.spriteNotFoundSprite, "Not an atlas sprite"); return /** @type {AtlasSprite} */ (sprite); } /** * Returns a regular sprite from the cache * @param {string} key * @returns {RegularSprite} */ getRegularSprite(key) { const sprite = this.getSpriteInternal(key); window.assert( sprite instanceof _sprites__WEBPACK_IMPORTED_MODULE_1__["RegularSprite"] || sprite === this.spriteNotFoundSprite, "Not a regular sprite" ); return /** @type {RegularSprite} */ (sprite); } /** * * @param {string} key * @returns {Promise} */ internalPreloadImage(key) { const url = Object(_cachebust__WEBPACK_IMPORTED_MODULE_2__["cachebust"])("res/" + key); const image = new Image(); let triesSoFar = 0; return Promise.race([ new Promise((resolve, reject) => { setTimeout(reject, 10000); }), new Promise(resolve => { image.onload = () => { image.onerror = null; image.onload = null; if (typeof image.decode === "function") { // SAFARI: Image.decode() fails on safari with svgs -> we dont want to fail // on that // FIREFOX: Decode never returns if the image is in cache, so call it in background image.decode().then( () => null, () => null ); } resolve(image); }; image.onerror = reason => { logger.warn("Failed to load '" + url + "':", reason); if (++triesSoFar < 4) { logger.log("Retrying to load image from", url); image.src = url + "?try=" + triesSoFar; } else { logger.warn("Failed to load", url, "after", triesSoFar, "tries with reason", reason); image.onerror = null; image.onload = null; resolve(null); } }; image.src = url; }), ]); } /** * Preloads a sprite * @param {string} key * @returns {Promise} */ preloadCSSSprite(key) { return this.internalPreloadImage(key).then(image => { if (key.indexOf("game_misc") >= 0) { // Allow access to regular sprites this.sprites.set(key, new _sprites__WEBPACK_IMPORTED_MODULE_1__["RegularSprite"](image, image.width, image.height)); } this.rawImages.push(image); }); } /** * Preloads an atlas * @param {AtlasDefinition} atlas * @returns {Promise} */ preloadAtlas(atlas) { return this.internalPreloadImage(atlas.getFullSourcePath()).then(image => { // @ts-ignore image.label = atlas.sourceFileName; return this.internalParseAtlas(atlas, image); }); } /** * * @param {AtlasDefinition} atlas * @param {HTMLImageElement} loadedImage */ internalParseAtlas({ meta: { scale }, sourceData }, loadedImage) { this.rawImages.push(loadedImage); for (const spriteName in sourceData) { const { frame, sourceSize, spriteSourceSize } = sourceData[spriteName]; let sprite = /** @type {AtlasSprite} */ (this.sprites.get(spriteName)); if (!sprite) { sprite = new _sprites__WEBPACK_IMPORTED_MODULE_1__["AtlasSprite"](spriteName); this.sprites.set(spriteName, sprite); } const link = new _sprites__WEBPACK_IMPORTED_MODULE_1__["SpriteAtlasLink"]({ packedX: frame.x, packedY: frame.y, packedW: frame.w, packedH: frame.h, packOffsetX: spriteSourceSize.x, packOffsetY: spriteSourceSize.y, atlas: loadedImage, w: sourceSize.w, h: sourceSize.h, }); sprite.linksByResolution[scale] = link; } } /** * Makes the canvas which shows the question mark, shown when a sprite was not found */ makeSpriteNotFoundCanvas() { const dims = 128; const [canvas, context] = Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(dims, dims, { smooth: false, label: "not-found-sprite", }); context.fillStyle = "#f77"; context.fillRect(0, 0, dims, dims); context.textAlign = "center"; context.textBaseline = "middle"; context.fillStyle = "#eee"; context.font = "25px Arial"; context.fillText("???", dims / 2, dims / 2); // TODO: Not sure why this is set here // @ts-ignore canvas.src = "not-found"; const sprite = new _sprites__WEBPACK_IMPORTED_MODULE_1__["AtlasSprite"]("not-found"); ["0.1", "0.25", "0.5", "0.75", "1"].forEach(resolution => { sprite.linksByResolution[resolution] = new _sprites__WEBPACK_IMPORTED_MODULE_1__["SpriteAtlasLink"]({ packedX: 0, packedY: 0, w: dims, h: dims, packOffsetX: 0, packOffsetY: 0, packedW: dims, packedH: dims, atlas: canvas, }); }); this.spriteNotFoundSprite = sprite; } /** * Draw sprite with function */ drawSprite(name, callback, { w = 128, h = 128, smooth = false, mipmap = false }, url) { // TODO: mipmap const [canvas, context] = Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(w, h, { smooth, reusable: false, label: "not-found-sprite", }); const [canvas2, context2] = Object(_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(w, h, { smooth, reusable: true, label: "not-found-sprite", }); const resolution = 1; // mipmap scale, 1/0.75/0.5/... context.save(); // TODO: scale and translate to make mipmap state same callback({ canvas, context, canvas2, context2, w, h, smooth, mipmap, resolution }); const resolutions = ["0.1", "0.25", "0.5", "0.75", "1"]; const sprite = new _sprites__WEBPACK_IMPORTED_MODULE_1__["AtlasSprite"](name); // TODO: remake for mipmapping for (let i = 0; i < resolutions.length; ++i) { const res = resolutions[i]; const link = new _sprites__WEBPACK_IMPORTED_MODULE_1__["SpriteAtlasLink"]({ packedX: 0, packedY: 0, w, h, packOffsetX: 0, packOffsetY: 0, packedW: w, packedH: h, atlas: canvas, }); sprite.linksByResolution[res] = link; } context.restore(); this.sprites.set(name, sprite); canvas.src = url } } const Loader = new LoaderImpl(); /***/ }), /***/ "./src/js/core/logging.js": /*!********************************!*\ !*** ./src/js/core/logging.js ***! \********************************/ /*! exports provided: createLogger, serializeError, stringifyObjectContainingErrors, globalDebug, globalLog, globalWarn, globalError, logSection */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createLogger", function() { return createLogger; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeError", function() { return serializeError; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stringifyObjectContainingErrors", function() { return stringifyObjectContainingErrors; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "globalDebug", function() { return globalDebug; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "globalLog", function() { return globalLog; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "globalWarn", function() { return globalWarn; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "globalError", function() { return globalError; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logSection", function() { return logSection; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); const circularJson = __webpack_require__(/*! circular-json */ "./node_modules/circular-json/build/circular-json.node.js"); /* Logging functions - To be extended */ /** * Base logger class */ class Logger { constructor(context) { this.context = context; } debug(...args) { globalDebug(this.context, ...args); } log(...args) { globalLog(this.context, ...args); } warn(...args) { globalWarn(this.context, ...args); } error(...args) { globalError(this.context, ...args); } } function createLogger(context) { return new Logger(context); } function prepareObjectForLogging(obj, maxDepth = 1) { if (!window.Sentry) { // Not required without sentry return obj; } if (typeof obj !== "object" && !Array.isArray(obj)) { return obj; } const result = {}; for (const key in obj) { const val = obj[key]; if (typeof val === "object") { if (maxDepth > 0) { result[key] = prepareObjectForLogging(val, maxDepth - 1); } else { result[key] = "[object]"; } } else { result[key] = val; } } return result; } /** * Serializes an error * @param {Error|ErrorEvent} err */ function serializeError(err) { if (!err) { return null; } const result = { type: err.constructor.name, }; if (err instanceof Error) { result.message = err.message; result.name = err.name; result.stack = err.stack; result.type = "{type.Error}"; } else if (err instanceof ErrorEvent) { result.filename = err.filename; result.message = err.message; result.lineno = err.lineno; result.colno = err.colno; result.type = "{type.ErrorEvent}"; if (err.error) { result.error = serializeError(err.error); } else { result.error = "{not-provided}"; } } else { result.type = "{unkown-type:" + typeof err + "}"; } return result; } /** * Serializes an event * @param {Event} event */ function serializeEvent(event) { let result = { type: "{type.Event:" + typeof event + "}", }; result.eventType = event.type; return result; } /** * Prepares a json payload * @param {string} key * @param {any} value */ function preparePayload(key, value) { if (value instanceof Error || value instanceof ErrorEvent) { return serializeError(value); } if (value instanceof Event) { return serializeEvent(value); } if (typeof value === "undefined") { return null; } return value; } /** * Stringifies an object containing circular references and errors * @param {any} payload */ function stringifyObjectContainingErrors(payload) { return circularJson.stringify(payload, preparePayload); } function globalDebug(context, ...args) { if (true) { logInternal(context, console.log, prepareArgsForLogging(args)); } } function globalLog(context, ...args) { // eslint-disable-next-line no-console logInternal(context, console.log, prepareArgsForLogging(args)); } function globalWarn(context, ...args) { // eslint-disable-next-line no-console logInternal(context, console.warn, prepareArgsForLogging(args)); } function globalError(context, ...args) { args = prepareArgsForLogging(args); // eslint-disable-next-line no-console logInternal(context, console.error, args); if (window.Sentry) { window.Sentry.withScope(scope => { scope.setExtra("args", args); window.Sentry.captureMessage(internalBuildStringFromArgs(args), "error"); }); } } function prepareArgsForLogging(args) { let result = []; for (let i = 0; i < args.length; ++i) { result.push(prepareObjectForLogging(args[i])); } return result; } /** * @param {Array} args */ function internalBuildStringFromArgs(args) { let result = []; for (let i = 0; i < args.length; ++i) { let arg = args[i]; if ( typeof arg === "string" || typeof arg === "number" || typeof arg === "boolean" || arg === null || arg === undefined ) { result.push("" + arg); } else if (arg instanceof Error) { result.push(arg.message); } else { result.push("[object]"); } } return result.join(" "); } function logSection(name, color) { while (name.length <= 14) { name = " " + name + " "; } name = name.padEnd(19, " "); const lineCss = "letter-spacing: -3px; color: " + color + "; font-size: 6px; background: #eee; color: #eee;"; const line = "%c----------------------------"; console.log("\n" + line + " %c" + name + " " + line + "\n", lineCss, "color: " + color, lineCss); } function extractHandleContext(handle) { let context = handle || "unknown"; if (handle && handle.constructor && handle.constructor.name) { context = handle.constructor.name; if (context === "String") { context = handle; } } if (handle && handle.name) { context = handle.name; } return context + ""; } function logInternal(handle, consoleMethod, args) { const context = extractHandleContext(handle).padEnd(20, " "); const labelColor = handle && handle.LOG_LABEL_COLOR ? handle.LOG_LABEL_COLOR : "#aaa"; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.logTimestamps) { const timestamp = "⏱ %c" + (Math.floor(performance.now()) + "").padEnd(6, " ") + ""; consoleMethod.call( console, timestamp + " %c" + context, "color: #7f7;", "color: " + labelColor + ";", ...args ); } else { // if (!globalConfig.debug.disableLoggingLogSources) { consoleMethod.call(console, "%c" + context, "color: " + labelColor, ...args); // } else { // consoleMethod.call(console, ...args); // } } } /***/ }), /***/ "./src/js/core/lzstring.js": /*!*********************************!*\ !*** ./src/js/core/lzstring.js ***! \*********************************/ /*! exports provided: compressU8, compressU8WHeader, decompressU8WHeader, compressX64, decompressX64 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compressU8", function() { return compressU8; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compressU8WHeader", function() { return compressU8WHeader; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decompressU8WHeader", function() { return decompressU8WHeader; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compressX64", function() { return compressX64; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decompressX64", function() { return decompressX64; }); // Copyright (c) 2013 Pieroxy // This work is free. You can redistribute it and/or modify it // under the terms of the WTFPL, Version 2 // For more information see LICENSE.txt or http://www.wtfpl.net/ // // For more information, the home page: // http://pieroxy.net/blog/pages/lz-string/testing.html // // LZ-based compression algorithm, version 1.4.4 const fromCharCode = String.fromCharCode; const hasOwnProperty = Object.prototype.hasOwnProperty; const keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$"; const baseReverseDic = {}; function getBaseValue(alphabet, character) { if (!baseReverseDic[alphabet]) { baseReverseDic[alphabet] = {}; for (let i = 0; i < alphabet.length; i++) { baseReverseDic[alphabet][alphabet.charAt(i)] = i; } } return baseReverseDic[alphabet][character]; } //compress into uint8array (UCS-2 big endian format) function compressU8(uncompressed) { let compressed = compress(uncompressed); let buf = new Uint8Array(compressed.length * 2); // 2 bytes per character for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) { let current_value = compressed.charCodeAt(i); buf[i * 2] = current_value >>> 8; buf[i * 2 + 1] = current_value % 256; } return buf; } // Compreses with header /** * @param {string} uncompressed * @param {number} header */ function compressU8WHeader(uncompressed, header) { let compressed = compress(uncompressed); let buf = new Uint8Array(2 + compressed.length * 2); // 2 bytes per character buf[0] = header >>> 8; buf[1] = header % 256; for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) { let current_value = compressed.charCodeAt(i); buf[2 + i * 2] = current_value >>> 8; buf[2 + i * 2 + 1] = current_value % 256; } return buf; } //decompress from uint8array (UCS-2 big endian format) /** * * @param {Uint8Array} compressed */ function decompressU8WHeader(compressed) { // let buf = new Array(compressed.length / 2); // 2 bytes per character // for (let i = 0, TotalLen = buf.length; i < TotalLen; i++) { // buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1]; // } // let result = []; // buf.forEach(function (c) { // result.push(fromCharCode(c)); // }); let result = []; for (let i = 2, n = compressed.length; i < n; i += 2) { const code = compressed[i] * 256 + compressed[i + 1]; result.push(fromCharCode(code)); } return decompress(result.join("")); } //compress into a string that is already URI encoded function compressX64(input) { if (input == null) return ""; return _compress(input, 6, function (a) { return keyStrUriSafe.charAt(a); }); } //decompress from an output of compressToEncodedURIComponent function decompressX64(input) { if (input == null) return ""; if (input == "") return null; input = input.replace(/ /g, "+"); return _decompress(input.length, 32, function (index) { return getBaseValue(keyStrUriSafe, input.charAt(index)); }); } function compress(uncompressed) { return _compress(uncompressed, 16, function (a) { return fromCharCode(a); }); } function _compress(uncompressed, bitsPerChar, getCharFromInt) { if (uncompressed == null) return ""; let i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, // Compensate for the first entry which should not count context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii; for (ii = 0; ii < uncompressed.length; ii += 1) { context_c = uncompressed.charAt(ii); if (!hasOwnProperty.call(context_dictionary, context_c)) { context_dictionary[context_c] = context_dictSize++; context_dictionaryToCreate[context_c] = true; } context_wc = context_w + context_c; if (hasOwnProperty.call(context_dictionary, context_wc)) { context_w = context_wc; } else { if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) { if (context_w.charCodeAt(0) < 256) { for (i = 0; i < context_numBits; i++) { context_data_val = context_data_val << 1; if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } } value = context_w.charCodeAt(0); for (i = 0; i < 8; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } } else { value = 1; for (i = 0; i < context_numBits; i++) { context_data_val = (context_data_val << 1) | value; if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = 0; } value = context_w.charCodeAt(0); for (i = 0; i < 16; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } } context_enlargeIn--; if (context_enlargeIn == 0) { context_enlargeIn = Math.pow(2, context_numBits); context_numBits++; } delete context_dictionaryToCreate[context_w]; } else { value = context_dictionary[context_w]; for (i = 0; i < context_numBits; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } } context_enlargeIn--; if (context_enlargeIn == 0) { context_enlargeIn = Math.pow(2, context_numBits); context_numBits++; } // Add wc to the dictionary. context_dictionary[context_wc] = context_dictSize++; context_w = String(context_c); } } // Output the code for w. if (context_w !== "") { if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) { if (context_w.charCodeAt(0) < 256) { for (i = 0; i < context_numBits; i++) { context_data_val = context_data_val << 1; if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } } value = context_w.charCodeAt(0); for (i = 0; i < 8; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } } else { value = 1; for (i = 0; i < context_numBits; i++) { context_data_val = (context_data_val << 1) | value; if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = 0; } value = context_w.charCodeAt(0); for (i = 0; i < 16; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } } context_enlargeIn--; if (context_enlargeIn == 0) { context_enlargeIn = Math.pow(2, context_numBits); context_numBits++; } delete context_dictionaryToCreate[context_w]; } else { value = context_dictionary[context_w]; for (i = 0; i < context_numBits; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } } context_enlargeIn--; if (context_enlargeIn == 0) { context_enlargeIn = Math.pow(2, context_numBits); context_numBits++; } } // Mark the end of the stream value = 2; for (i = 0; i < context_numBits; i++) { context_data_val = (context_data_val << 1) | (value & 1); if (context_data_position == bitsPerChar - 1) { context_data_position = 0; context_data.push(getCharFromInt(context_data_val)); context_data_val = 0; } else { context_data_position++; } value = value >> 1; } // Flush the last char // eslint-disable-next-line no-constant-condition while (true) { context_data_val = context_data_val << 1; if (context_data_position == bitsPerChar - 1) { context_data.push(getCharFromInt(context_data_val)); break; } else context_data_position++; } return context_data.join(""); } function decompress(compressed) { if (compressed == null) return ""; if (compressed == "") return null; return _decompress(compressed.length, 32768, function (index) { return compressed.charCodeAt(index); }); } function _decompress(length, resetValue, getNextValue) { let dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 }; for (i = 0; i < 3; i += 1) { dictionary[i] = i; } bits = 0; maxpower = Math.pow(2, 2); power = 1; while (power != maxpower) { resb = data.val & data.position; data.position >>= 1; if (data.position == 0) { data.position = resetValue; data.val = getNextValue(data.index++); } bits |= (resb > 0 ? 1 : 0) * power; power <<= 1; } switch ((next = bits)) { case 0: bits = 0; maxpower = Math.pow(2, 8); power = 1; while (power != maxpower) { resb = data.val & data.position; data.position >>= 1; if (data.position == 0) { data.position = resetValue; data.val = getNextValue(data.index++); } bits |= (resb > 0 ? 1 : 0) * power; power <<= 1; } c = fromCharCode(bits); break; case 1: bits = 0; maxpower = Math.pow(2, 16); power = 1; while (power != maxpower) { resb = data.val & data.position; data.position >>= 1; if (data.position == 0) { data.position = resetValue; data.val = getNextValue(data.index++); } bits |= (resb > 0 ? 1 : 0) * power; power <<= 1; } c = fromCharCode(bits); break; case 2: return ""; } dictionary[3] = c; w = c; result.push(c); // eslint-disable-next-line no-constant-condition while (true) { if (data.index > length) { return ""; } bits = 0; maxpower = Math.pow(2, numBits); power = 1; while (power != maxpower) { resb = data.val & data.position; data.position >>= 1; if (data.position == 0) { data.position = resetValue; data.val = getNextValue(data.index++); } bits |= (resb > 0 ? 1 : 0) * power; power <<= 1; } switch ((c = bits)) { case 0: bits = 0; maxpower = Math.pow(2, 8); power = 1; while (power != maxpower) { resb = data.val & data.position; data.position >>= 1; if (data.position == 0) { data.position = resetValue; data.val = getNextValue(data.index++); } bits |= (resb > 0 ? 1 : 0) * power; power <<= 1; } dictionary[dictSize++] = fromCharCode(bits); c = dictSize - 1; enlargeIn--; break; case 1: bits = 0; maxpower = Math.pow(2, 16); power = 1; while (power != maxpower) { resb = data.val & data.position; data.position >>= 1; if (data.position == 0) { data.position = resetValue; data.val = getNextValue(data.index++); } bits |= (resb > 0 ? 1 : 0) * power; power <<= 1; } dictionary[dictSize++] = fromCharCode(bits); c = dictSize - 1; enlargeIn--; break; case 2: return result.join(""); } if (enlargeIn == 0) { enlargeIn = Math.pow(2, numBits); numBits++; } if (dictionary[c]) { // @ts-ignore entry = dictionary[c]; } else { if (c === dictSize) { entry = w + w.charAt(0); } else { return null; } } result.push(entry); // Add w+entry[0] to the dictionary. dictionary[dictSize++] = w + entry.charAt(0); enlargeIn--; w = entry; if (enlargeIn == 0) { enlargeIn = Math.pow(2, numBits); numBits++; } } } /***/ }), /***/ "./src/js/core/modal_dialog_elements.js": /*!**********************************************!*\ !*** ./src/js/core/modal_dialog_elements.js ***! \**********************************************/ /*! exports provided: Dialog, DialogLoading, DialogOptionChooser, DialogWithForm */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Dialog", function() { return Dialog; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DialogLoading", function() { return DialogLoading; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DialogOptionChooser", function() { return DialogOptionChooser; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DialogWithForm", function() { return DialogWithForm; }); /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./signal */ "./src/js/core/signal.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /* harmony import */ var _click_detector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _input_receiver__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _modal_dialog_forms__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./modal_dialog_forms */ "./src/js/core/modal_dialog_forms.js"); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../game/key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); const kbEnter = 13; const kbCancel = 27; const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_8__["createLogger"])("dialogs"); /** * Basic text based dialog */ class Dialog { /** * * Constructs a new dialog with the given options * @param {object} param0 * @param {Application} param0.app * @param {string} param0.title Title of the dialog * @param {string} param0.contentHTML Inner dialog html * @param {Array} param0.buttons * Button list, each button contains of up to 3 parts seperated by ':'. * Part 0: The id, one of the one defined in dialog_buttons.yaml * Part 1: The style, either good, bad or misc * Part 2 (optional): Additional parameters seperated by '/', available are: * timeout: This button is only available after some waiting time * kb_enter: This button is triggered by the enter key * kb_escape This button is triggered by the escape key * @param {string=} param0.type The dialog type, either "info" or "warn" * @param {boolean=} param0.closeButton Whether this dialog has a close button */ constructor({ app, title, contentHTML, buttons, type = "info", closeButton = false }) { this.app = app; this.title = title; this.contentHTML = contentHTML; this.type = type; this.buttonIds = buttons; this.closeButton = closeButton; this.closeRequested = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.buttonSignals = {}; for (let i = 0; i < buttons.length; ++i) { if (_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].debug.disableTimedButtons) { this.buttonIds[i] = this.buttonIds[i].replace(":timeout", ""); } const buttonId = this.buttonIds[i].split(":")[0]; this.buttonSignals[buttonId] = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); } this.timeouts = []; this.clickDetectors = []; this.inputReciever = new _input_receiver__WEBPACK_IMPORTED_MODULE_4__["InputReceiver"]("dialog-" + this.title); this.inputReciever.keydown.add(this.handleKeydown, this); this.enterHandler = null; this.escapeHandler = null; } /** * Internal keydown handler * @param {object} param0 * @param {number} param0.keyCode * @param {boolean} param0.shift * @param {boolean} param0.alt */ handleKeydown({ keyCode, shift, alt }) { if (keyCode === kbEnter && this.enterHandler) { this.internalButtonHandler(this.enterHandler); return _signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]; } if (keyCode === kbCancel && this.escapeHandler) { this.internalButtonHandler(this.escapeHandler); return _signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]; } } internalButtonHandler(id, ...payload) { this.app.inputMgr.popReciever(this.inputReciever); if (id !== "close-button") { this.buttonSignals[id].dispatch(...payload); } this.closeRequested.dispatch(); } createElement() { const elem = document.createElement("div"); elem.classList.add("ingameDialog"); this.dialogElem = document.createElement("div"); this.dialogElem.classList.add("dialogInner"); if (this.type) { this.dialogElem.classList.add(this.type); } elem.appendChild(this.dialogElem); const title = document.createElement("h1"); title.innerText = this.title; title.classList.add("title"); this.dialogElem.appendChild(title); if (this.closeButton) { this.dialogElem.classList.add("hasCloseButton"); const closeBtn = document.createElement("button"); closeBtn.classList.add("closeButton"); this.trackClicks(closeBtn, () => this.internalButtonHandler("close-button"), { applyCssClass: "pressedSmallElement", }); title.appendChild(closeBtn); this.inputReciever.backButton.add(() => this.internalButtonHandler("close-button")); } const content = document.createElement("div"); content.classList.add("content"); content.innerHTML = this.contentHTML; this.dialogElem.appendChild(content); if (this.buttonIds.length > 0) { const buttons = document.createElement("div"); buttons.classList.add("buttons"); // Create buttons for (let i = 0; i < this.buttonIds.length; ++i) { const [buttonId, buttonStyle, rawParams] = this.buttonIds[i].split(":"); const button = document.createElement("button"); button.classList.add("button"); button.classList.add("styledButton"); button.classList.add(buttonStyle); button.innerText = _translations__WEBPACK_IMPORTED_MODULE_9__["T"].dialogs.buttons[buttonId]; const params = (rawParams || "").split("/"); const useTimeout = params.indexOf("timeout") >= 0; const isEnter = params.indexOf("enter") >= 0; const isEscape = params.indexOf("escape") >= 0; if (isEscape && this.closeButton) { logger.warn("Showing dialog with close button, and additional cancel button"); } if (useTimeout) { button.classList.add("timedButton"); const timeout = setTimeout(() => { button.classList.remove("timedButton"); Object(_utils__WEBPACK_IMPORTED_MODULE_1__["arrayDeleteValue"])(this.timeouts, timeout); }, 5000); this.timeouts.push(timeout); } if (isEnter || isEscape) { // if (this.app.settings.getShowKeyboardShortcuts()) { // Show keybinding const spacer = document.createElement("code"); spacer.classList.add("keybinding"); spacer.innerHTML = Object(_game_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["getStringForKeyCode"])(isEnter ? kbEnter : kbCancel); button.appendChild(spacer); // } if (isEnter) { this.enterHandler = buttonId; } if (isEscape) { this.escapeHandler = buttonId; } } this.trackClicks(button, () => this.internalButtonHandler(buttonId)); buttons.appendChild(button); } this.dialogElem.appendChild(buttons); } else { this.dialogElem.classList.add("buttonless"); } this.element = elem; this.app.inputMgr.pushReciever(this.inputReciever); return this.element; } setIndex(index) { this.element.style.zIndex = index; } destroy() { if (!this.element) { window.assert(false, "Tried to destroy dialog twice"); return; } // We need to do this here, because if the backbutton event gets // dispatched to the modal dialogs, it will not call the internalButtonHandler, // and thus our receiver stays attached the whole time this.app.inputMgr.destroyReceiver(this.inputReciever); for (let i = 0; i < this.clickDetectors.length; ++i) { this.clickDetectors[i].cleanup(); } this.clickDetectors = []; this.element.remove(); this.element = null; for (let i = 0; i < this.timeouts.length; ++i) { clearTimeout(this.timeouts[i]); } this.timeouts = []; } hide() { this.element.classList.remove("visible"); } show() { this.element.classList.add("visible"); } /** * Helper method to track clicks on an element * @param {Element} elem * @param {function():void} handler * @param {import("./click_detector").ClickDetectorConstructorArgs=} args * @returns {ClickDetector} */ trackClicks(elem, handler, args = {}) { const detector = new _click_detector__WEBPACK_IMPORTED_MODULE_2__["ClickDetector"](elem, args); detector.click.add(handler, this); this.clickDetectors.push(detector); return detector; } } /** * Dialog which simply shows a loading spinner */ class DialogLoading extends Dialog { constructor(app) { super({ app, title: "", contentHTML: "", buttons: [], type: "loading", }); // Loading dialog can not get closed with back button this.inputReciever.backButton.removeAll(); this.inputReciever.context = "dialog-loading"; } createElement() { const elem = document.createElement("div"); elem.classList.add("ingameDialog"); elem.classList.add("loadingDialog"); this.element = elem; const loader = document.createElement("div"); loader.classList.add("prefab_LoadingTextWithAnim"); loader.classList.add("loadingIndicator"); loader.innerText = _translations__WEBPACK_IMPORTED_MODULE_9__["T"].global.loading; elem.appendChild(loader); this.app.inputMgr.pushReciever(this.inputReciever); return elem; } } class DialogOptionChooser extends Dialog { constructor({ app, title, options }) { let html = "
"; options.options.forEach(({ value, text, desc = null, iconPrefix = null }) => { const descHtml = desc ? `${desc}` : ""; let iconHtml = iconPrefix ? `` : ""; html += `
${iconHtml} ${text} ${descHtml}
`; }); html += "
"; super({ app, title, contentHTML: html, buttons: [], type: "info", closeButton: true, }); this.options = options; this.initialOption = options.active; this.buttonSignals.optionSelected = new _signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); } createElement() { const div = super.createElement(); this.dialogElem.classList.add("optionChooserDialog"); div.querySelectorAll("[data-optionvalue]").forEach(handle => { const value = handle.getAttribute("data-optionvalue"); if (!handle) { logger.error("Failed to bind option value in dialog:", value); return; } // Need click detector here to forward elements, otherwise scrolling does not work const detector = new _click_detector__WEBPACK_IMPORTED_MODULE_2__["ClickDetector"](handle, { consumeEvents: false, preventDefault: false, clickSound: null, applyCssClass: "pressedOption", targetOnly: true, }); this.clickDetectors.push(detector); if (value !== this.initialOption) { detector.click.add(() => { const selected = div.querySelector(".option.active"); if (selected) { selected.classList.remove("active"); } else { logger.warn("No selected option"); } handle.classList.add("active"); this.app.sound.playUiSound(_platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].uiClick); this.internalButtonHandler("optionSelected", value); }); } }); return div; } } class DialogWithForm extends Dialog { /** * * @param {object} param0 * @param {Application} param0.app * @param {string} param0.title * @param {string} param0.desc * @param {array=} param0.buttons * @param {string=} param0.confirmButtonId * @param {string=} param0.extraButton * @param {Array} param0.formElements */ constructor({ app, title, desc, formElements, buttons = ["cancel", "ok:good"], confirmButtonId = "ok" }) { let html = ""; html += desc + "
"; for (let i = 0; i < formElements.length; ++i) { html += formElements[i].getHtml(); } super({ app, title: title, contentHTML: html, buttons: buttons, type: "info", closeButton: true, }); this.confirmButtonId = confirmButtonId; this.formElements = formElements; this.enterHandler = confirmButtonId; } internalButtonHandler(id, ...payload) { if (id === this.confirmButtonId) { if (this.hasAnyInvalid()) { this.dialogElem.classList.remove("errorShake"); Object(_utils__WEBPACK_IMPORTED_MODULE_1__["waitNextFrame"])().then(() => { if (this.dialogElem) { this.dialogElem.classList.add("errorShake"); } }); this.app.sound.playUiSound(_platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].uiError); return; } } super.internalButtonHandler(id, payload); } hasAnyInvalid() { for (let i = 0; i < this.formElements.length; ++i) { if (!this.formElements[i].isValid()) { return true; } } return false; } createElement() { const div = super.createElement(); for (let i = 0; i < this.formElements.length; ++i) { const elem = this.formElements[i]; elem.bindEvents(div, this.clickDetectors); } Object(_utils__WEBPACK_IMPORTED_MODULE_1__["waitNextFrame"])().then(() => { this.formElements[0].focus(); }); return div; } } /***/ }), /***/ "./src/js/core/modal_dialog_forms.js": /*!*******************************************!*\ !*** ./src/js/core/modal_dialog_forms.js ***! \*******************************************/ /*! exports provided: FormElement, FormElementInput, FormElementCheckbox */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormElement", function() { return FormElement; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormElementInput", function() { return FormElementInput; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormElementCheckbox", function() { return FormElementCheckbox; }); /* harmony import */ var _click_detector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./click_detector */ "./src/js/core/click_detector.js"); class FormElement { constructor(id, label) { this.id = id; this.label = label; } getHtml() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return ""; } getFormElement(parent) { return parent.querySelector("[data-formId='" + this.id + "']"); } bindEvents(parent, clickTrackers) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } focus() {} isValid() { return true; } /** @returns {any} */ getValue() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } } class FormElementInput extends FormElement { constructor({ id, label = null, placeholder, defaultValue = "", inputType = "text", validator = null }) { super(id, label); this.placeholder = placeholder; this.defaultValue = defaultValue; this.inputType = inputType; this.validator = validator; this.element = null; } getHtml() { let classes = []; let inputType = "text"; let maxlength = 256; switch (this.inputType) { case "text": { classes.push("input-text"); break; } case "email": { classes.push("input-email"); inputType = "email"; break; } case "token": { classes.push("input-token"); inputType = "text"; maxlength = 4; break; } } return `
${this.label ? `` : ""}
`; } bindEvents(parent, clickTrackers) { this.element = this.getFormElement(parent); this.element.addEventListener("input", event => this.updateErrorState()); this.updateErrorState(); } updateErrorState() { this.element.classList.toggle("errored", !this.isValid()); } isValid() { return !this.validator || this.validator(this.element.value); } getValue() { return this.element.value; } focus() { this.element.focus(); } } class FormElementCheckbox extends FormElement { constructor({ id, label, defaultValue = true }) { super(id, label); this.defaultValue = defaultValue; this.value = this.defaultValue; this.element = null; } getHtml() { return `
${this.label ? `` : ""}
`; } bindEvents(parent, clickTrackers) { this.element = this.getFormElement(parent); const detector = new _click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](this.element, { consumeEvents: false, preventDefault: false, }); clickTrackers.push(detector); detector.click.add(this.toggle, this); } getValue() { return this.value; } toggle() { this.value = !this.value; this.element.classList.toggle("checked", this.value); } focus(parent) {} } /***/ }), /***/ "./src/js/core/polyfills.js": /*!**********************************!*\ !*** ./src/js/core/polyfills.js ***! \**********************************/ /*! no exports provided */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var whatwg_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! whatwg-fetch */ "./node_modules/whatwg-fetch/fetch.js"); function mathPolyfills() { // Converts from degrees to radians. Math.radians = function (degrees) { return (degrees * Math.PI) / 180.0; }; // Converts from radians to degrees. Math.degrees = function (radians) { return (radians * 180.0) / Math.PI; }; } function stringPolyfills() { // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart if (!String.prototype.padStart) { String.prototype.padStart = function padStart(targetLength, padString) { targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0; padString = String(typeof padString !== "undefined" ? padString : " "); if (this.length >= targetLength) { return String(this); } else { targetLength = targetLength - this.length; if (targetLength > padString.length) { padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed } return padString.slice(0, targetLength) + String(this); } }; } // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd if (!String.prototype.padEnd) { String.prototype.padEnd = function padEnd(targetLength, padString) { targetLength = targetLength >> 0; //floor if number or convert non-number to 0; padString = String(typeof padString !== "undefined" ? padString : " "); if (this.length > targetLength) { return String(this); } else { targetLength = targetLength - this.length; if (targetLength > padString.length) { padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed } return String(this) + padString.slice(0, targetLength); } }; } } function objectPolyfills() { // https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js // @ts-ignore const reduce = Function.bind.call(Function.call, Array.prototype.reduce); // @ts-ignore const isEnumerable = Function.bind.call(Function.call, Object.prototype.propertyIsEnumerable); // @ts-ignore const concat = Function.bind.call(Function.call, Array.prototype.concat); const keys = Reflect.ownKeys; // @ts-ignore if (!Object.values) { // @ts-ignore Object.values = function values(O) { return reduce( keys(O), (v, k) => concat(v, typeof k === "string" && isEnumerable(O, k) ? [O[k]] : []), [] ); }; } if (!Object.entries) { // @ts-ignore Object.entries = function entries(O) { return reduce( keys(O), (e, k) => concat(e, typeof k === "string" && isEnumerable(O, k) ? [[k, O[k]]] : []), [] ); }; } } function initPolyfills() { mathPolyfills(); stringPolyfills(); objectPolyfills(); } function initExtensions() { String.prototype.replaceAll = function (search, replacement) { var target = this; return target.split(search).join(replacement); }; } // Fetch polyfill // Other polyfills initPolyfills(); initExtensions(); /***/ }), /***/ "./src/js/core/query_parameters.js": /*!*****************************************!*\ !*** ./src/js/core/query_parameters.js ***! \*****************************************/ /*! exports provided: queryParamOptions */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queryParamOptions", function() { return queryParamOptions; }); const queryString = __webpack_require__(/*! query-string */ "./node_modules/query-string/index.js"); const options = queryString.parse(location.search); let queryParamOptions = { embedProvider: null, fullVersion: false, sandboxMode: false, }; if (options.embed) { queryParamOptions.embedProvider = options.embed; } // Allow testing full version outside of standalone if (options.fullVersion && !false) { queryParamOptions.fullVersion = true; } // Allow testing full version outside of standalone if (options.sandboxMode && !false) { queryParamOptions.sandboxMode = true; } /***/ }), /***/ "./src/js/core/read_write_proxy.js": /*!*****************************************!*\ !*** ./src/js/core/read_write_proxy.js ***! \*****************************************/ /*! exports provided: ReadWriteProxy */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReadWriteProxy", function() { return ReadWriteProxy; }); /* harmony import */ var _sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sensitive_utils.encrypt */ "./src/js/core/sensitive_utils.encrypt.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _platform_storage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../platform/storage */ "./src/js/platform/storage.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _explained_result__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./explained_result */ "./src/js/core/explained_result.js"); /* harmony import */ var _lzstring__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./lzstring */ "./src/js/core/lzstring.js"); /* harmony import */ var _async_compression__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./async_compression */ "./src/js/core/async_compression.js"); /* harmony import */ var _savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../savegame/savegame_compressor */ "./src/js/savegame/savegame_compressor.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("read_write_proxy"); const salt = Object(_utils__WEBPACK_IMPORTED_MODULE_3__["accessNestedPropertyReverse"])(_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"], ["file", "info"]); // Helper which only writes / reads if verify() works. Also performs migration class ReadWriteProxy { constructor(app, filename) { /** @type {Application} */ this.app = app; this.filename = filename; /** @type {object} */ this.currentData = null; // TODO: EXTREMELY HACKY! To verify we need to do this a step later if ( true && _config__WEBPACK_IMPORTED_MODULE_4__["IS_DEBUG"]) { setTimeout(() => { window.assert( this.verify(this.getDefaultData()).result, "Verify() failed for default data: " + this.verify(this.getDefaultData()).reason ); }); } } // -- Methods to override /** @returns {ExplainedResult} */ verify(data) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return _explained_result__WEBPACK_IMPORTED_MODULE_5__["ExplainedResult"].bad(); } // Should return the default data getDefaultData() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return {}; } // Should return the current version as an integer getCurrentVersion() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return 0; } // Should migrate the data (Modify in place) /** @returns {ExplainedResult} */ migrate(data) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return _explained_result__WEBPACK_IMPORTED_MODULE_5__["ExplainedResult"].bad(); } // -- / Methods // Resets whole data, returns promise resetEverythingAsync() { logger.warn("Reset data to default"); this.currentData = this.getDefaultData(); return this.writeAsync(); } getCurrentData() { return this.currentData; } /** * * @param {object} obj */ static serializeObject(obj) { const jsonString = JSON.stringify(Object(_savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_8__["compressObject"])(obj)); const checksum = Object(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["computeCrc"])(jsonString + salt); return _async_compression__WEBPACK_IMPORTED_MODULE_7__["compressionPrefix"] + Object(_lzstring__WEBPACK_IMPORTED_MODULE_6__["compressX64"])(checksum + jsonString); } /** * * @param {object} text */ static deserializeObject(text) { const decompressed = Object(_lzstring__WEBPACK_IMPORTED_MODULE_6__["decompressX64"])(text.substr(_async_compression__WEBPACK_IMPORTED_MODULE_7__["compressionPrefix"].length)); if (!decompressed) { // LZ string decompression failure throw new Error("bad-content / decompression-failed"); } if (decompressed.length < 40) { // String too short throw new Error("bad-content / payload-too-small"); } // Compare stored checksum with actual checksum const checksum = decompressed.substring(0, 40); const jsonString = decompressed.substr(40); const desiredChecksum = checksum.startsWith(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["CRC_PREFIX"]) ? Object(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["computeCrc"])(jsonString + salt) : Object(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["sha1"])(jsonString + salt); if (desiredChecksum !== checksum) { // Checksum mismatch throw new Error("bad-content / checksum-mismatch"); } const parsed = JSON.parse(jsonString); const decoded = Object(_savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_8__["decompressObject"])(parsed); return decoded; } /** * Writes the data asychronously, fails if verify() fails * @returns {Promise} */ writeAsync() { const verifyResult = this.internalVerifyEntry(this.currentData); if (!verifyResult.result) { logger.error("Tried to write invalid data to", this.filename, "reason:", verifyResult.reason); return Promise.reject(verifyResult.reason); } return _async_compression__WEBPACK_IMPORTED_MODULE_7__["asyncCompressor"] .compressObjectAsync(this.currentData) .then(compressed => { return this.app.storage.writeFileAsync(this.filename, compressed); }) .then(() => { logger.log("📄 Wrote", this.filename); }) .catch(err => { logger.error("Failed to write", this.filename, ":", err); throw err; }); } // Reads the data asynchronously, fails if verify() fails readAsync() { // Start read request return ( this.app.storage .readFileAsync(this.filename) // Check for errors during read .catch(err => { if (err === _platform_storage__WEBPACK_IMPORTED_MODULE_2__["FILE_NOT_FOUND"]) { logger.log("File not found, using default data"); // File not found or unreadable, assume default file return Promise.resolve(null); } return Promise.reject("file-error: " + err); }) // Decrypt data (if its encrypted) // @ts-ignore .then(rawData => { if (rawData == null) { // So, the file has not been found, use default data return JSON.stringify(Object(_savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_8__["compressObject"])(this.getDefaultData())); } if (rawData.startsWith(_async_compression__WEBPACK_IMPORTED_MODULE_7__["compressionPrefix"])) { const decompressed = Object(_lzstring__WEBPACK_IMPORTED_MODULE_6__["decompressX64"])(rawData.substr(_async_compression__WEBPACK_IMPORTED_MODULE_7__["compressionPrefix"].length)); if (!decompressed) { // LZ string decompression failure return Promise.reject("bad-content / decompression-failed"); } if (decompressed.length < 40) { // String too short return Promise.reject("bad-content / payload-too-small"); } // Compare stored checksum with actual checksum const checksum = decompressed.substring(0, 40); const jsonString = decompressed.substr(40); const desiredChecksum = checksum.startsWith(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["CRC_PREFIX"]) ? Object(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["computeCrc"])(jsonString + salt) : Object(_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_0__["sha1"])(jsonString + salt); if (desiredChecksum !== checksum) { // Checksum mismatch return Promise.reject( "bad-content / checksum-mismatch: " + desiredChecksum + " vs " + checksum ); } return jsonString; } else { if (false) {} } return rawData; }) // Parse JSON, this could throw but thats fine .then(res => { try { return JSON.parse(res); } catch (ex) { logger.error( "Failed to parse file content of", this.filename, ":", ex, "(content was:", res, ")" ); throw new Error("invalid-serialized-data"); } }) // Decompress .then(compressed => Object(_savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_8__["decompressObject"])(compressed)) // Verify basic structure .then(contents => { const result = this.internalVerifyBasicStructure(contents); if (!result.isGood()) { return Promise.reject("verify-failed: " + result.reason); } return contents; }) // Check version and migrate if required .then(contents => { if (contents.version > this.getCurrentVersion()) { return Promise.reject("stored-data-is-newer"); } if (contents.version < this.getCurrentVersion()) { logger.log( "Trying to migrate data object from version", contents.version, "to", this.getCurrentVersion() ); const migrationResult = this.migrate(contents); // modify in place if (migrationResult.isBad()) { return Promise.reject("migration-failed: " + migrationResult.reason); } } return contents; }) // Verify .then(contents => { const verifyResult = this.internalVerifyEntry(contents); if (!verifyResult.result) { logger.error( "Read invalid data from", this.filename, "reason:", verifyResult.reason, "contents:", contents ); return Promise.reject("invalid-data: " + verifyResult.reason); } return contents; }) // Store .then(contents => { this.currentData = contents; logger.log("📄 Read data with version", this.currentData.version, "from", this.filename); return contents; }) // Catchall .catch(err => { return Promise.reject("Failed to read " + this.filename + ": " + err); }) ); } /** * Deletes the file * @returns {Promise} */ deleteAsync() { return this.app.storage.deleteFileAsync(this.filename); } // Internal /** @returns {ExplainedResult} */ internalVerifyBasicStructure(data) { if (!data) { return _explained_result__WEBPACK_IMPORTED_MODULE_5__["ExplainedResult"].bad("Data is empty"); } if (!Number.isInteger(data.version) || data.version < 0) { return _explained_result__WEBPACK_IMPORTED_MODULE_5__["ExplainedResult"].bad( `Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})` ); } return _explained_result__WEBPACK_IMPORTED_MODULE_5__["ExplainedResult"].good(); } /** @returns {ExplainedResult} */ internalVerifyEntry(data) { if (data.version !== this.getCurrentVersion()) { return _explained_result__WEBPACK_IMPORTED_MODULE_5__["ExplainedResult"].bad( "Version mismatch, got " + data.version + " and expected " + this.getCurrentVersion() ); } const verifyStructureError = this.internalVerifyBasicStructure(data); if (!verifyStructureError.isGood()) { return verifyStructureError; } return this.verify(data); } } /***/ }), /***/ "./src/js/core/rectangle.js": /*!**********************************!*\ !*** ./src/js/core/rectangle.js ***! \**********************************/ /*! exports provided: Rectangle */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Rectangle", function() { return Rectangle; }); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); /* harmony import */ var _vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./vector */ "./src/js/core/vector.js"); class Rectangle { constructor(x = 0, y = 0, w = 0, h = 0) { this.x = x; this.y = y; this.w = w; this.h = h; } /** * Creates a rectangle from top right bottom and left offsets * @param {number} top * @param {number} right * @param {number} bottom * @param {number} left */ static fromTRBL(top, right, bottom, left) { return new Rectangle(left, top, right - left, bottom - top); } /** * Constructs a new square rectangle * @param {number} x * @param {number} y * @param {number} size */ static fromSquare(x, y, size) { return new Rectangle(x, y, size, size); } /** * * @param {Vector} p1 * @param {Vector} p2 */ static fromTwoPoints(p1, p2) { const left = Math.min(p1.x, p2.x); const top = Math.min(p1.y, p2.y); const right = Math.max(p1.x, p2.x); const bottom = Math.max(p1.y, p2.y); return new Rectangle(left, top, right - left, bottom - top); } /** * Returns if a intersects b * @param {Rectangle} a * @param {Rectangle} b */ static intersects(a, b) { return a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom; } /** * Copies this instance * @returns {Rectangle} */ clone() { return new Rectangle(this.x, this.y, this.w, this.h); } /** * Returns if this rectangle is empty * @returns {boolean} */ isEmpty() { return Object(_utils__WEBPACK_IMPORTED_MODULE_1__["epsilonCompare"])(this.w * this.h, 0); } /** * Returns if this rectangle is equal to the other while taking an epsilon into account * @param {Rectangle} other * @param {number} epsilon */ equalsEpsilon(other, epsilon) { return ( Object(_utils__WEBPACK_IMPORTED_MODULE_1__["epsilonCompare"])(this.x, other.x, epsilon) && Object(_utils__WEBPACK_IMPORTED_MODULE_1__["epsilonCompare"])(this.y, other.y, epsilon) && Object(_utils__WEBPACK_IMPORTED_MODULE_1__["epsilonCompare"])(this.w, other.w, epsilon) && Object(_utils__WEBPACK_IMPORTED_MODULE_1__["epsilonCompare"])(this.h, other.h, epsilon) ); } /** * @returns {number} */ left() { return this.x; } /** * @returns {number} */ right() { return this.x + this.w; } /** * @returns {number} */ top() { return this.y; } /** * @returns {number} */ bottom() { return this.y + this.h; } /** * Returns Top, Right, Bottom, Left * @returns {[number, number, number, number]} */ trbl() { return [this.y, this.right(), this.bottom(), this.x]; } /** * Returns the center of the rect * @returns {Vector} */ getCenter() { return new _vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](this.x + this.w / 2, this.y + this.h / 2); } /** * Sets the right side of the rect without moving it * @param {number} right */ setRight(right) { this.w = right - this.x; } /** * Sets the bottom side of the rect without moving it * @param {number} bottom */ setBottom(bottom) { this.h = bottom - this.y; } /** * Sets the top side of the rect without scaling it * @param {number} top */ setTop(top) { const bottom = this.bottom(); this.y = top; this.setBottom(bottom); } /** * Sets the left side of the rect without scaling it * @param {number} left */ setLeft(left) { const right = this.right(); this.x = left; this.setRight(right); } /** * Returns the top left point * @returns {Vector} */ topLeft() { return new _vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](this.x, this.y); } /** * Returns the bottom left point * @returns {Vector} */ bottomRight() { return new _vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](this.right(), this.bottom()); } /** * Moves the rectangle by the given parameters * @param {number} x * @param {number} y */ moveBy(x, y) { this.x += x; this.y += y; } /** * Moves the rectangle by the given vector * @param {Vector} vec */ moveByVector(vec) { this.x += vec.x; this.y += vec.y; } /** * Scales every parameter (w, h, x, y) by the given factor. Useful to transform from world to * tile space and vice versa * @param {number} factor */ allScaled(factor) { return new Rectangle(this.x * factor, this.y * factor, this.w * factor, this.h * factor); } /** * Expands the rectangle in all directions * @param {number} amount * @returns {Rectangle} new rectangle */ expandedInAllDirections(amount) { return new Rectangle(this.x - amount, this.y - amount, this.w + 2 * amount, this.h + 2 * amount); } /** * Returns if the given rectangle is contained * @param {Rectangle} rect * @returns {boolean} */ containsRect(rect) { return ( this.x <= rect.right() && rect.x <= this.right() && this.y <= rect.bottom() && rect.y <= this.bottom() ); } /** * Returns if this rectangle contains the other rectangle specified by the parameters * @param {number} x * @param {number} y * @param {number} w * @param {number} h * @returns {boolean} */ containsRect4Params(x, y, w, h) { return this.x <= x + w && x <= this.right() && this.y <= y + h && y <= this.bottom(); } /** * Returns if the rectangle contains the given circle at (x, y) with the radius (radius) * @param {number} x * @param {number} y * @param {number} radius * @returns {boolean} */ containsCircle(x, y, radius) { return ( this.x <= x + radius && x - radius <= this.right() && this.y <= y + radius && y - radius <= this.bottom() ); } /** * Returns if hte rectangle contains the given point * @param {number} x * @param {number} y * @returns {boolean} */ containsPoint(x, y) { return x >= this.x && x < this.right() && y >= this.y && y < this.bottom(); } /** * Returns the shared area with another rectangle, or null if there is no intersection * @param {Rectangle} rect * @returns {Rectangle|null} */ getIntersection(rect) { const left = Math.max(this.x, rect.x); const top = Math.max(this.y, rect.y); const right = Math.min(this.x + this.w, rect.x + rect.w); const bottom = Math.min(this.y + this.h, rect.y + rect.h); if (right <= left || bottom <= top) { return null; } return Rectangle.fromTRBL(top, right, bottom, left); } /** * Returns the union of this rectangle with another * @param {Rectangle} rect */ getUnion(rect) { if (this.isEmpty()) { // If this is rect is empty, return the other one return rect.clone(); } if (rect.isEmpty()) { // If the other is empty, return this one return this.clone(); } // Find contained area const left = Math.min(this.x, rect.x); const top = Math.min(this.y, rect.y); const right = Math.max(this.right(), rect.right()); const bottom = Math.max(this.bottom(), rect.bottom()); return Rectangle.fromTRBL(top, right, bottom, left); } /** * Good for caching stuff */ toCompareableString() { return ( Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.x) + "/" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.y) + "/" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.w) + "/" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.h) ); } /** * Good for printing stuff */ toString() { return ( "[x:" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.x) + "| y:" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.y) + "| w:" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.w) + "| h:" + Object(_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(this.h) + "]" ); } /** * Returns a new rectangle in tile space which includes all tiles which are visible in this rect * @returns {Rectangle} */ toTileCullRectangle() { return new Rectangle( Math.floor(this.x / _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize), Math.floor(this.y / _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize), Math.ceil(this.w / _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize), Math.ceil(this.h / _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize) ); } } /***/ }), /***/ "./src/js/core/request_channel.js": /*!****************************************!*\ !*** ./src/js/core/request_channel.js ***! \****************************************/ /*! exports provided: PROMISE_ABORTED, RequestChannel */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PROMISE_ABORTED", function() { return PROMISE_ABORTED; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RequestChannel", function() { return RequestChannel; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("request_channel"); // Thrown when a request is aborted const PROMISE_ABORTED = "promise-aborted"; class RequestChannel { constructor() { /** @type {Array} */ this.pendingPromises = []; } /** * * @param {Promise} promise * @returns {Promise} */ watch(promise) { // log(this, "Added new promise:", promise, "(pending =", this.pendingPromises.length, ")"); let cancelled = false; const wrappedPromise = new Promise((resolve, reject) => { promise.then( result => { // Remove from pending promises Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["fastArrayDeleteValueIfContained"])(this.pendingPromises, wrappedPromise); // If not cancelled, resolve promise with same payload if (!cancelled) { resolve.call(this, result); } else { logger.warn("Not resolving because promise got cancelled"); // reject.call(this, PROMISE_ABORTED); } }, err => { // Remove from pending promises Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["fastArrayDeleteValueIfContained"])(this.pendingPromises, wrappedPromise); // If not cancelled, reject promise with same payload if (!cancelled) { reject.call(this, err); } else { logger.warn("Not rejecting because promise got cancelled"); // reject.call(this, PROMISE_ABORTED); } } ); }); // Add cancel handler // @ts-ignore wrappedPromise.cancel = function () { cancelled = true; }; this.pendingPromises.push(wrappedPromise); return wrappedPromise; } cancelAll() { if (this.pendingPromises.length > 0) { logger.log("Cancel all pending promises (", this.pendingPromises.length, ")"); } for (let i = 0; i < this.pendingPromises.length; ++i) { // @ts-ignore this.pendingPromises[i].cancel(); } this.pendingPromises = []; } } /***/ }), /***/ "./src/js/core/rng.js": /*!****************************!*\ !*** ./src/js/core/rng.js ***! \****************************/ /*! exports provided: RandomNumberGenerator */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RandomNumberGenerator", function() { return RandomNumberGenerator; }); // ALEA RNG function Mash() { var n = 0xefc8249d; return function (data) { data = data.toString(); for (var i = 0; i < data.length; i++) { n += data.charCodeAt(i); var h = 0.02519603282416938 * n; n = h >>> 0; h -= n; h *= n; n = h >>> 0; h -= n; n += h * 0x100000000; // 2^32 } return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 }; } /** * @param {number|string} seed */ function makeNewRng(seed) { // Johannes Baagøe , 2010 var c = 1; var mash = Mash(); let s0 = mash(" "); let s1 = mash(" "); let s2 = mash(" "); s0 -= mash(seed); if (s0 < 0) { s0 += 1; } s1 -= mash(seed); if (s1 < 0) { s1 += 1; } s2 -= mash(seed); if (s2 < 0) { s2 += 1; } mash = null; var random = function () { var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32 s0 = s1; s1 = s2; return (s2 = t - (c = t | 0)); }; random.exportState = function () { return [s0, s1, s2, c]; }; random.importState = function (i) { s0 = +i[0] || 0; s1 = +i[1] || 0; s2 = +i[2] || 0; c = +i[3] || 0; }; return random; } class RandomNumberGenerator { /** * * @param {number|string=} seed */ constructor(seed) { this.internalRng = makeNewRng(seed || Math.random()); } /** * Re-seeds the generator * @param {number|string} seed */ reseed(seed) { this.internalRng = makeNewRng(seed || Math.random()); } /** * @returns {number} between 0 and 1 */ next() { return this.internalRng(); } /** * Random choice of an array * @param {array} array */ choice(array) { const index = this.nextIntRange(0, array.length); return array[index]; } /** * @param {number} min * @param {number} max * @returns {number} Integer in range [min, max[ */ nextIntRange(min, max) { window.assert(Number.isFinite(min), "Minimum is no integer"); window.assert(Number.isFinite(max), "Maximum is no integer"); window.assert(max > min, "rng: max <= min"); return Math.floor(this.next() * (max - min) + min); } /** * @param {number} min * @param {number} max * @returns {number} Integer in range [min, max] */ nextIntRangeInclusive(min, max) { window.assert(Number.isFinite(min), "Minimum is no integer"); window.assert(Number.isFinite(max), "Maximum is no integer"); window.assert(max > min, "rng: max <= min"); return Math.round(this.next() * (max - min) + min); } /** * @param {number} min * @param {number} max * @returns {number} Number in range [min, max[ */ nextRange(min, max) { window.assert(max > min, "rng: max <= min"); return this.next() * (max - min) + min; } /** * Updates the seed * @param {number} seed */ setSeed(seed) { this.internalRng = makeNewRng(seed); } } /***/ }), /***/ "./src/js/core/sensitive_utils.encrypt.js": /*!************************************************!*\ !*** ./src/js/core/sensitive_utils.encrypt.js ***! \************************************************/ /*! exports provided: sha1, getNameOfProvider, CRC_PREFIX, computeCrc */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sha1", function() { return sha1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNameOfProvider", function() { return getNameOfProvider; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CRC_PREFIX", function() { return CRC_PREFIX; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "computeCrc", function() { return computeCrc; }); /* harmony import */ var rusha__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rusha */ "./node_modules/rusha/dist/rusha.js"); /* harmony import */ var rusha__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(rusha__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var crc_crc32__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! crc/crc32 */ "./node_modules/crc/crc32.js"); /* harmony import */ var _lzstring__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lzstring */ "./src/js/core/lzstring.js"); function sha1(str) { return Object(rusha__WEBPACK_IMPORTED_MODULE_0__["createHash"])().update(str).digest("hex"); } // Window.location.host function getNameOfProvider() { return window[Object(_lzstring__WEBPACK_IMPORTED_MODULE_2__["decompressX64"])("DYewxghgLgliB2Q")][Object(_lzstring__WEBPACK_IMPORTED_MODULE_2__["decompressX64"])("BYewzgLgdghgtgUyA")]; } // Distinguish legacy crc prefixes const CRC_PREFIX = "crc32".padEnd(32, "-"); /** * Computes the crc for a given string * @param {string} str */ function computeCrc(str) { return CRC_PREFIX + Object(crc_crc32__WEBPACK_IMPORTED_MODULE_1__["default"])(str).toString(16).padStart(8, "0"); } /***/ }), /***/ "./src/js/core/signal.js": /*!*******************************!*\ !*** ./src/js/core/signal.js ***! \*******************************/ /*! exports provided: STOP_PROPAGATION, Signal */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "STOP_PROPAGATION", function() { return STOP_PROPAGATION; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Signal", function() { return Signal; }); const STOP_PROPAGATION = "stop_propagation"; class Signal { constructor() { this.receivers = []; this.modifyCount = 0; } /** * Adds a new signal listener * @param {function} receiver * @param {object} scope */ add(receiver, scope = null) { window.assert(receiver, "receiver is null"); this.receivers.push({ receiver, scope }); ++this.modifyCount; } /** * Dispatches the signal * @param {...any} payload */ dispatch() { const modifyState = this.modifyCount; const n = this.receivers.length; for (let i = 0; i < n; ++i) { const { receiver, scope } = this.receivers[i]; if (receiver.apply(scope, arguments) === STOP_PROPAGATION) { return STOP_PROPAGATION; } if (modifyState !== this.modifyCount) { // Signal got modified during iteration return STOP_PROPAGATION; } } } /** * Removes a receiver * @param {function} receiver */ remove(receiver) { let index = null; const n = this.receivers.length; for (let i = 0; i < n; ++i) { if (this.receivers[i].receiver === receiver) { index = i; break; } } window.assert(index !== null, "Receiver not found in list"); this.receivers.splice(index, 1); ++this.modifyCount; } /** * Removes all receivers */ removeAll() { this.receivers = []; ++this.modifyCount; } } /***/ }), /***/ "./src/js/core/singleton_factory.js": /*!******************************************!*\ !*** ./src/js/core/singleton_factory.js ***! \******************************************/ /*! exports provided: SingletonFactory */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SingletonFactory", function() { return SingletonFactory; }); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("singleton_factory"); // simple factory pattern class SingletonFactory { constructor(id) { this.id = id; // Store array as well as dictionary, to speed up lookups this.entries = []; this.idToEntry = {}; } getId() { return this.id; } register(classHandle) { // First, construct instance const instance = new classHandle(); // Extract id const id = instance.getId(); window.assert(id, "Factory: Invalid id for class " + classHandle.name + ": " + id); // Check duplicates window.assert(!this.idToEntry[id], "Duplicate factory entry for " + id); // Insert this.entries.push(instance); this.idToEntry[id] = instance; } /** * Checks if a given id is registered * @param {string} id * @returns {boolean} */ hasId(id) { return !!this.idToEntry[id]; } /** * Finds an instance by a given id * @param {string} id * @returns {object} */ findById(id) { const entry = this.idToEntry[id]; if (!entry) { logger.error("Object with id", id, "is not registered!"); window.assert(false, "Factory: Object with id '" + id + "' is not registered!"); return null; } return entry; } /** * Finds an instance by its constructor (The class handle) * @param {object} classHandle * @returns {object} */ findByClass(classHandle) { for (let i = 0; i < this.entries.length; ++i) { if (this.entries[i] instanceof classHandle) { return this.entries[i]; } } window.assert(false, "Factory: Object not found by classHandle (classid: " + classHandle.name + ")"); return null; } /** * Returns all entries * @returns {Array} */ getEntries() { return this.entries; } /** * Returns all registered ids * @returns {Array} */ getAllIds() { return Object.keys(this.idToEntry); } /** * Returns amount of stored entries * @returns {number} */ getNumEntries() { return this.entries.length; } } /***/ }), /***/ "./src/js/core/sprites.js": /*!********************************!*\ !*** ./src/js/core/sprites.js ***! \********************************/ /*! exports provided: ORIGINAL_SPRITE_SCALE, BaseSprite, SpriteAtlasLink, AtlasSprite, RegularSprite */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ORIGINAL_SPRITE_SCALE", function() { return ORIGINAL_SPRITE_SCALE; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSprite", function() { return BaseSprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteAtlasLink", function() { return SpriteAtlasLink; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AtlasSprite", function() { return AtlasSprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RegularSprite", function() { return RegularSprite; }); /* harmony import */ var _draw_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _rectangle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); const floorSpriteCoordinates = false; const ORIGINAL_SPRITE_SCALE = "0.75"; class BaseSprite { /** * Returns the raw handle * @returns {HTMLImageElement|HTMLCanvasElement} */ getRawTexture() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return null; } /** * Draws the sprite * @param {CanvasRenderingContext2D} context * @param {number} x * @param {number} y * @param {number} w * @param {number} h */ draw(context, x, y, w, h) { // eslint-disable-line no-unused-vars window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } } /** * Position of a sprite within an atlas */ class SpriteAtlasLink { /** * * @param {object} param0 * @param {number} param0.packedX * @param {number} param0.packedY * @param {number} param0.packOffsetX * @param {number} param0.packOffsetY * @param {number} param0.packedW * @param {number} param0.packedH * @param {number} param0.w * @param {number} param0.h * @param {HTMLImageElement|HTMLCanvasElement} param0.atlas */ constructor({ w, h, packedX, packedY, packOffsetX, packOffsetY, packedW, packedH, atlas }) { this.packedX = packedX; this.packedY = packedY; this.packedW = packedW; this.packedH = packedH; this.packOffsetX = packOffsetX; this.packOffsetY = packOffsetY; this.atlas = atlas; this.w = w; this.h = h; } } class AtlasSprite extends BaseSprite { /** * * @param {string} spriteName */ constructor(spriteName = "sprite") { super(); /** @type {Object.} */ this.linksByResolution = {}; this.spriteName = spriteName; } getRawTexture() { return this.linksByResolution[ORIGINAL_SPRITE_SCALE].atlas; } /** * Draws the sprite onto a regular context using no contexts * @see {BaseSprite.draw} */ draw(context, x, y, w, h) { if (true) { window.assert(context instanceof CanvasRenderingContext2D, "Not a valid context"); } const link = this.linksByResolution[ORIGINAL_SPRITE_SCALE]; window.assert( link, "Link not known: " + ORIGINAL_SPRITE_SCALE + " (having " + Object.keys(this.linksByResolution) + ")" ); const width = w || link.w; const height = h || link.h; const scaleW = width / link.w; const scaleH = height / link.h; context.drawImage( link.atlas, link.packedX, link.packedY, link.packedW, link.packedH, x + link.packOffsetX * scaleW, y + link.packOffsetY * scaleH, link.packedW * scaleW, link.packedH * scaleH ); } /** * * @param {DrawParameters} parameters * @param {number} x * @param {number} y * @param {number} size * @param {boolean=} clipping */ drawCachedCentered(parameters, x, y, size, clipping = true) { this.drawCached(parameters, x - size / 2, y - size / 2, size, size, clipping); } /** * * @param {CanvasRenderingContext2D} context * @param {number} x * @param {number} y * @param {number} size */ drawCentered(context, x, y, size) { this.draw(context, x - size / 2, y - size / 2, size, size); } /** * Draws the sprite * @param {DrawParameters} parameters * @param {number} x * @param {number} y * @param {number} w * @param {number} h * @param {boolean=} clipping Whether to perform culling */ drawCached(parameters, x, y, w = null, h = null, clipping = true) { if (true) { window.assert(parameters instanceof _draw_parameters__WEBPACK_IMPORTED_MODULE_0__["DrawParameters"], "Not a valid context"); window.assert(!!w && w > 0, "Not a valid width:" + w); window.assert(!!h && h > 0, "Not a valid height:" + h); } const visibleRect = parameters.visibleRect; const scale = parameters.desiredAtlasScale; const link = this.linksByResolution[scale]; if (!link) { window.assert(false, `Link not known: ${scale} (having ${Object.keys(this.linksByResolution)})`); } const scaleW = w / link.w; const scaleH = h / link.h; let destX = x + link.packOffsetX * scaleW; let destY = y + link.packOffsetY * scaleH; let destW = link.packedW * scaleW; let destH = link.packedH * scaleH; let srcX = link.packedX; let srcY = link.packedY; let srcW = link.packedW; let srcH = link.packedH; let intersection = null; if (clipping) { const rect = new _rectangle__WEBPACK_IMPORTED_MODULE_1__["Rectangle"](destX, destY, destW, destH); intersection = rect.getIntersection(visibleRect); if (!intersection) { return; } srcX += (intersection.x - destX) / scaleW; srcY += (intersection.y - destY) / scaleH; srcW *= intersection.w / destW; srcH *= intersection.h / destH; destX = intersection.x; destY = intersection.y; destW = intersection.w; destH = intersection.h; } if (floorSpriteCoordinates) { parameters.context.drawImage( link.atlas, // atlas src pos Math.floor(srcX), Math.floor(srcY), // atlas src size Math.floor(srcW), Math.floor(srcH), // dest pos Math.floor(destX), Math.floor(destY), // dest size Math.floor(destW), Math.floor(destH) ); } else { parameters.context.drawImage( link.atlas, // atlas src pos srcX, srcY, // atlas src siize srcW, srcH, // dest pos and size destX, destY, destW, destH ); } } /** * Renders into an html element * @param {HTMLElement} element * @param {number} w * @param {number} h */ renderToHTMLElement(element, w = 1, h = 1) { element.style.position = "relative"; element.innerHTML = this.getAsHTML(w, h); } /** * Returns the html to render as icon * @param {number} w * @param {number} h */ getAsHTML(w, h) { const link = this.linksByResolution["0.5"]; // Find out how much we have to scale it so that it fits const scaleX = w / link.w; const scaleY = h / link.h; // Find out how big the scaled atlas is const atlasW = link.atlas.width * scaleX; const atlasH = link.atlas.height * scaleY; // @ts-ignore const srcSafe = link.atlas.src.replaceAll("\\", "/"); // Find out how big we render the sprite const widthAbsolute = scaleX * link.packedW; const heightAbsolute = scaleY * link.packedH; // Compute the position in the relative container const leftRelative = (link.packOffsetX * scaleX) / w; const topRelative = (link.packOffsetY * scaleY) / h; const widthRelative = widthAbsolute / w; const heightRelative = heightAbsolute / h; // Scale the atlas relative to the width and height of the element const bgW = atlasW / widthAbsolute; const bgH = atlasH / heightAbsolute; // Figure out what the position of the atlas is const bgX = link.packedX * scaleX; const bgY = link.packedY * scaleY; // Fuck you, whoever thought its a good idea to make background-position work like it does now const bgXRelative = -bgX / (widthAbsolute - atlasW); const bgYRelative = -bgY / (heightAbsolute - atlasH); return ` `; } } class RegularSprite extends BaseSprite { constructor(sprite, w, h) { super(); this.w = w; this.h = h; this.sprite = sprite; } getRawTexture() { return this.sprite; } /** * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing * images into buffers * @param {CanvasRenderingContext2D} context * @param {number} x * @param {number} y * @param {number} w * @param {number} h */ draw(context, x, y, w, h) { window.assert(context, "No context given"); window.assert(x !== undefined, "No x given"); window.assert(y !== undefined, "No y given"); window.assert(w !== undefined, "No width given"); window.assert(h !== undefined, "No height given"); context.drawImage(this.sprite, x, y, w, h); } /** * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing * images into buffers * @param {CanvasRenderingContext2D} context * @param {number} x * @param {number} y * @param {number} w * @param {number} h */ drawCentered(context, x, y, w, h) { window.assert(context, "No context given"); window.assert(x !== undefined, "No x given"); window.assert(y !== undefined, "No y given"); window.assert(w !== undefined, "No width given"); window.assert(h !== undefined, "No height given"); context.drawImage(this.sprite, x - w / 2, y - h / 2, w, h); } } /***/ }), /***/ "./src/js/core/stale_area_detector.js": /*!********************************************!*\ !*** ./src/js/core/stale_area_detector.js ***! \********************************************/ /*! exports provided: StaleAreaDetector */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StaleAreaDetector", function() { return StaleAreaDetector; }); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _rectangle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("stale_areas"); class StaleAreaDetector { /** * * @param {object} param0 * @param {import("../game/root").GameRoot} param0.root * @param {string} param0.name The name for reference * @param {(Rectangle) => void} param0.recomputeMethod Method which recomputes the given area */ constructor({ root, name, recomputeMethod }) { this.root = root; this.name = name; this.recomputeMethod = recomputeMethod; /** @type {Rectangle} */ this.staleArea = null; } /** * Invalidates the given area * @param {Rectangle} area */ invalidate(area) { // logger.log(this.name, "invalidated", area.toString()); if (this.staleArea) { this.staleArea = this.staleArea.getUnion(area); } else { this.staleArea = area.clone(); } } /** * Updates the stale area */ update() { if (this.staleArea) { logger.log(this.name, "is recomputing", this.staleArea.toString()); if (_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.renderChanges) { this.root.hud.parts.changesDebugger.renderChange(this.name, this.staleArea, "#fd145b"); } this.recomputeMethod(this.staleArea); this.staleArea = null; } } } /***/ }), /***/ "./src/js/core/state_manager.js": /*!**************************************!*\ !*** ./src/js/core/state_manager.js ***! \**************************************/ /*! exports provided: StateManager */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StateManager", function() { return StateManager; }); /* harmony import */ var _game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logging */ "./src/js/core/logging.js"); /* harmony import */ var _error_handler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./error_handler */ "./src/js/core/error_handler.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); const logger = Object(_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("state_manager"); /** * This is the main state machine which drives the game states. */ class StateManager { /** * @param {Application} app */ constructor(app) { this.app = app; /** @type {GameState} */ this.currentState = null; /** @type {Object. GameState>} */ this.stateClasses = {}; } /** * Registers a new state class, should be a GameState derived class * @param {object} stateClass */ register(stateClass) { // Create a dummy to retrieve the key const dummy = new stateClass(); window.assert(dummy instanceof _game_state__WEBPACK_IMPORTED_MODULE_0__["GameState"], "Not a state!"); const key = dummy.getKey(); window.assert(!this.stateClasses[key], `State '${key}' is already registered!`); this.stateClasses[key] = stateClass; } /** * Constructs a new state or returns the instance from the cache * @param {string} key */ constructState(key) { if (this.stateClasses[key]) { return new this.stateClasses[key](); } window.assert(false, `State '${key}' is not known!`); } /** * Moves to a given state * @param {string} key State Key */ moveToState(key, payload = {}) { if (_error_handler__WEBPACK_IMPORTED_MODULE_2__["APPLICATION_ERROR_OCCURED"]) { console.warn("Skipping state transition because of application crash"); return; } if (this.currentState) { if (key === this.currentState.getKey()) { logger.error(`State '${key}' is already active!`); return false; } this.currentState.internalLeaveCallback(); // Remove all references for (const stateKey in this.currentState) { if (this.currentState.hasOwnProperty(stateKey)) { delete this.currentState[stateKey]; } } this.currentState = null; } this.currentState = this.constructState(key); this.currentState.internalRegisterCallback(this, this.app); // Clean up old elements Object(_utils__WEBPACK_IMPORTED_MODULE_3__["removeAllChildren"])(document.body); document.body.className = "gameState " + (this.currentState.getHasFadeIn() ? "" : "arrived"); document.body.id = "state_" + key; document.body.innerHTML = this.currentState.internalGetFullHtml(); const dialogParent = document.createElement("div"); dialogParent.classList.add("modalDialogParent"); document.body.appendChild(dialogParent); this.app.sound.playThemeMusic(this.currentState.getThemeMusic()); this.currentState.internalEnterCallback(payload); this.currentState.onResized(this.app.screenWidth, this.app.screenHeight); this.app.analytics.trackStateEnter(key); window.history.pushState( { key, }, key ); Object(_utils__WEBPACK_IMPORTED_MODULE_3__["waitNextFrame"])().then(() => { document.body.classList.add("arrived"); }); return true; } /** * Returns the current state * @returns {GameState} */ getCurrentState() { return this.currentState; } } /***/ }), /***/ "./src/js/core/textual_game_state.js": /*!*******************************************!*\ !*** ./src/js/core/textual_game_state.js ***! \*******************************************/ /*! exports provided: TextualGameState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextualGameState", function() { return TextualGameState; }); /* harmony import */ var _game_hud_parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../game/hud/parts/modal_dialogs */ "./src/js/game/hud/parts/modal_dialogs.js"); /* harmony import */ var _game_state__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /** * Baseclass for all game states which are structured similary: A header with back button + some * scrollable content. */ class TextualGameState extends _game_state__WEBPACK_IMPORTED_MODULE_1__["GameState"] { ///// INTERFACE //// /** * Should return the states inner html. If not overriden, will create a scrollable container * with the content of getMainContentHTML() * @returns {string} */ getInnerHTML() { return `
${this.getMainContentHTML()}
`; } /** * Should return the states HTML content. */ getMainContentHTML() { return ""; } /** * Should return the title of the game state. If null, no title and back button will * get created * @returns {string|null} */ getStateHeaderTitle() { return null; } ///////////// /** * Back button handler, can be overridden. Per default it goes back to the main menu, * or if coming from the game it moves back to the game again. */ onBackButton() { if (this.backToStateId) { this.moveToState(this.backToStateId, this.backToStatePayload); } else { this.moveToState(this.getDefaultPreviousState()); } } /** * Returns the default state to go back to */ getDefaultPreviousState() { return "MainMenuState"; } /** * Goes to a new state, telling him to go back to this state later * @param {string} stateId */ moveToStateAddGoBack(stateId) { this.moveToState(stateId, { backToStateId: this.key, backToStatePayload: { backToStateId: this.backToStateId, backToStatePayload: this.backToStatePayload, }, }); } /** * Goes to a new state, telling him to go back to this state later * @param {string} stateId */ switchToState(stateId) { // debugger; this.moveToState( stateId, { backToStateId: this.backToStateId, backToStatePayload: this.backToStatePayload, }, true ); } /** * Removes all click detectors, except the one on the back button. Useful when regenerating * content. */ clearClickDetectorsExceptHeader() { for (let i = 0; i < this.clickDetectors.length; ++i) { const detector = this.clickDetectors[i]; if (detector.element === this.headerElement) { continue; } detector.cleanup(); this.clickDetectors.splice(i, 1); i -= 1; } } /** * Overrides the GameState implementation to provide our own html */ internalGetFullHtml() { let headerHtml = ""; if (this.getStateHeaderTitle()) { headerHtml = `

${this.getStateHeaderTitle()}

`; } return ` ${headerHtml}
${this.getInnerHTML()}
`; } //// INTERNALS ///// /** * Overrides the GameState leave callback to cleanup stuff */ internalLeaveCallback() { super.internalLeaveCallback(); this.dialogs.cleanup(); } /** * Overrides the GameState enter callback to setup required stuff * @param {any} payload */ internalEnterCallback(payload) { super.internalEnterCallback(payload, false); if (payload.backToStateId) { this.backToStateId = payload.backToStateId; this.backToStatePayload = payload.backToStatePayload; } this.htmlElement.classList.add("textualState"); if (this.getStateHeaderTitle()) { this.htmlElement.classList.add("hasTitle"); } this.containerElement = this.htmlElement.querySelector(".widthKeeper .container"); this.headerElement = this.htmlElement.querySelector(".headerBar > h1"); if (this.headerElement) { this.trackClicks(this.headerElement, this.onBackButton); } this.dialogs = new _game_hud_parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_0__["HUDModalDialogs"](null, this.app); const dialogsElement = document.body.querySelector(".modalDialogParent"); this.dialogs.initializeToElement(dialogsElement); this.onEnter(payload); } } /***/ }), /***/ "./src/js/core/tracked_state.js": /*!**************************************!*\ !*** ./src/js/core/tracked_state.js ***! \**************************************/ /*! exports provided: TrackedState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrackedState", function() { return TrackedState; }); class TrackedState { constructor(callbackMethod = null, callbackScope = null) { this.lastSeenValue = null; if (callbackMethod) { this.callback = callbackMethod; if (callbackScope) { this.callback = this.callback.bind(callbackScope); } } } set(value, changeHandler = null, changeScope = null) { if (value !== this.lastSeenValue) { // Copy value since the changeHandler call could actually modify our lastSeenValue const valueCopy = value; this.lastSeenValue = value; if (changeHandler) { if (changeScope) { changeHandler.call(changeScope, valueCopy); } else { changeHandler(valueCopy); } } else if (this.callback) { this.callback(value); } else { window.assert(false, "No callback specified"); } } } setSilent(value) { this.lastSeenValue = value; } get() { return this.lastSeenValue; } } /***/ }), /***/ "./src/js/core/utils.js": /*!******************************!*\ !*** ./src/js/core/utils.js ***! \******************************/ /*! exports provided: isAndroid, isIos, getPlatformName, getIPCRenderer, make2DUndefinedArray, newEmptyMap, randomInt, accessNestedPropertyReverse, randomChoice, fastArrayDelete, fastArrayDeleteValue, fastArrayDeleteValueIfContained, arrayDelete, arrayDeleteValue, epsilonCompare, lerp, findNiceValue, findNiceIntegerValue, formatBigNumber, formatBigNumberFull, waitNextFrame, round1Digit, round2Digits, round3Digits, round4Digits, clamp, makeDiv, makeButtonElement, makeButton, removeAllChildren, quantizeFloat, checkTimerExpired, isSupportedBrowser, formatSecondsToTimeAgo, formatSeconds, formatItemsPerSecond, rotateFlatMatrix3x3, generateMatrixRotations, rotateDirectionalObject, safeModulo */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isAndroid", function() { return isAndroid; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isIos", function() { return isIos; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPlatformName", function() { return getPlatformName; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getIPCRenderer", function() { return getIPCRenderer; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "make2DUndefinedArray", function() { return make2DUndefinedArray; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "newEmptyMap", function() { return newEmptyMap; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "randomInt", function() { return randomInt; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "accessNestedPropertyReverse", function() { return accessNestedPropertyReverse; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "randomChoice", function() { return randomChoice; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fastArrayDelete", function() { return fastArrayDelete; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fastArrayDeleteValue", function() { return fastArrayDeleteValue; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fastArrayDeleteValueIfContained", function() { return fastArrayDeleteValueIfContained; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "arrayDelete", function() { return arrayDelete; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "arrayDeleteValue", function() { return arrayDeleteValue; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "epsilonCompare", function() { return epsilonCompare; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lerp", function() { return lerp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findNiceValue", function() { return findNiceValue; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findNiceIntegerValue", function() { return findNiceIntegerValue; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formatBigNumber", function() { return formatBigNumber; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formatBigNumberFull", function() { return formatBigNumberFull; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitNextFrame", function() { return waitNextFrame; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "round1Digit", function() { return round1Digit; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "round2Digits", function() { return round2Digits; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "round3Digits", function() { return round3Digits; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "round4Digits", function() { return round4Digits; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clamp", function() { return clamp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeDiv", function() { return makeDiv; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeButtonElement", function() { return makeButtonElement; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeButton", function() { return makeButton; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeAllChildren", function() { return removeAllChildren; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "quantizeFloat", function() { return quantizeFloat; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "checkTimerExpired", function() { return checkTimerExpired; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSupportedBrowser", function() { return isSupportedBrowser; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formatSecondsToTimeAgo", function() { return formatSecondsToTimeAgo; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formatSeconds", function() { return formatSeconds; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formatItemsPerSecond", function() { return formatItemsPerSecond; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rotateFlatMatrix3x3", function() { return rotateFlatMatrix3x3; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateMatrixRotations", function() { return generateMatrixRotations; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rotateDirectionalObject", function() { return rotateDirectionalObject; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "safeModulo", function() { return safeModulo; }); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); const bigNumberSuffixTranslationKeys = ["thousands", "millions", "billions", "trillions"]; /** * Returns if this platform is android * @returns {boolean} */ function isAndroid() { if (true) { return false; } const platform = window.device.platform; return platform === "Android" || platform === "amazon-fireos"; } /** * Returns if this platform is iOs * @returns {boolean} */ function isIos() { if (true) { return false; } return window.device.platform === "iOS"; } /** * Returns a platform name * @returns {"android" | "browser" | "ios" | "standalone" | "unknown"} */ function getPlatformName() { if (false) {} else if (true) { return "browser"; } else {} return "unknown"; } /** * Returns the IPC renderer, or null if not within the standalone * @returns {object|null} */ let ipcRenderer = null; function getIPCRenderer() { if (true) { return null; } if (!ipcRenderer) { ipcRenderer = eval("require")("electron").ipcRenderer; } return ipcRenderer; } /** * Makes a new 2D array with undefined contents * @param {number} w * @param {number} h * @returns {Array>} */ function make2DUndefinedArray(w, h) { const result = new Array(w); for (let x = 0; x < w; ++x) { result[x] = new Array(h); } return result; } /** * Creates a new map (an empty object without any props) */ function newEmptyMap() { return Object.create(null); } /** * Returns a random integer in the range [start,end] * @param {number} start * @param {number} end */ function randomInt(start, end) { return start + Math.round(Math.random() * (end - start)); } /** * Access an object in a very annoying way, used for obsfuscation. * @param {any} obj * @param {Array} keys */ function accessNestedPropertyReverse(obj, keys) { let result = obj; for (let i = keys.length - 1; i >= 0; --i) { result = result[keys[i]]; } return result; } /** * Chooses a random entry of an array * @template T * @param {T[]} arr * @returns {T} */ function randomChoice(arr) { return arr[Math.floor(Math.random() * arr.length)]; } /** * Deletes from an array by swapping with the last element * @param {Array} array * @param {number} index */ function fastArrayDelete(array, index) { if (index < 0 || index >= array.length) { throw new Error("Out of bounds"); } // When the element is not the last element if (index !== array.length - 1) { // Get the last element, and swap it with the one we want to delete const last = array[array.length - 1]; array[index] = last; } // Finally remove the last element array.length -= 1; } /** * Deletes from an array by swapping with the last element. Searches * for the value in the array first * @param {Array} array * @param {any} value */ function fastArrayDeleteValue(array, value) { if (array == null) { throw new Error("Tried to delete from non array!"); } const index = array.indexOf(value); if (index < 0) { console.error("Value", value, "not contained in array:", array, "!"); return value; } return fastArrayDelete(array, index); } /** * @see fastArrayDeleteValue * @param {Array} array * @param {any} value */ function fastArrayDeleteValueIfContained(array, value) { if (array == null) { throw new Error("Tried to delete from non array!"); } const index = array.indexOf(value); if (index < 0) { return value; } return fastArrayDelete(array, index); } /** * Deletes from an array at the given index * @param {Array} array * @param {number} index */ function arrayDelete(array, index) { if (index < 0 || index >= array.length) { throw new Error("Out of bounds"); } array.splice(index, 1); } /** * Deletes the given value from an array * @param {Array} array * @param {any} value */ function arrayDeleteValue(array, value) { if (array == null) { throw new Error("Tried to delete from non array!"); } const index = array.indexOf(value); if (index < 0) { console.error("Value", value, "not contained in array:", array, "!"); return value; } return arrayDelete(array, index); } /** * Compare two floats for epsilon equality * @param {number} a * @param {number} b * @returns {boolean} */ function epsilonCompare(a, b, epsilon = 1e-5) { return Math.abs(a - b) < epsilon; } /** * Interpolates two numbers * @param {number} a * @param {number} b * @param {number} x Mix factor, 0 means 100% a, 1 means 100%b, rest is interpolated */ function lerp(a, b, x) { return a * (1 - x) + b * x; } /** * Finds a value which is nice to display, e.g. 15669 -> 15000. Also handles fractional stuff * @param {number} num */ function findNiceValue(num) { if (num > 1e8) { return num; } if (num < 0.00001) { return 0; } let roundAmount = 1; if (num > 50000) { roundAmount = 10000; } else if (num > 20000) { roundAmount = 5000; } else if (num > 5000) { roundAmount = 1000; } else if (num > 2000) { roundAmount = 500; } else if (num > 1000) { roundAmount = 100; } else if (num > 100) { roundAmount = 20; } else if (num > 20) { roundAmount = 5; } const niceValue = Math.floor(num / roundAmount) * roundAmount; if (num >= 10) { return Math.round(niceValue); } if (num >= 1) { return Math.round(niceValue * 10) / 10; } return Math.round(niceValue * 100) / 100; } /** * Finds a nice integer value * @see findNiceValue * @param {number} num */ function findNiceIntegerValue(num) { return Math.ceil(findNiceValue(num)); } /** * Formats a big number * @param {number} num * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.') * @returns {string} */ function formatBigNumber(num, separator = _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.decimalSeparator) { const sign = num < 0 ? "-" : ""; num = Math.abs(num); if (num > 1e54) { return sign + _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.infinite; } if (num < 10 && !Number.isInteger(num)) { return sign + num.toFixed(2); } if (num < 50 && !Number.isInteger(num)) { return sign + num.toFixed(1); } num = Math.floor(num); if (num < 1000) { return sign + "" + num; } let leadingDigits = num; let suffix = ""; for (let suffixIndex = 0; suffixIndex < bigNumberSuffixTranslationKeys.length; ++suffixIndex) { leadingDigits = leadingDigits / 1000; suffix = _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.suffix[bigNumberSuffixTranslationKeys[suffixIndex]]; if (leadingDigits < 1000) { break; } } let mul = 1; while (leadingDigits > 1) { mul *= 10; leadingDigits /= 10; } const leadingDigitsRounded = (Math.round(+leadingDigits.toFixed(3) * 1e4) * mul) / 1e4; // const leadingDigitsRounded = round1Digit(leadingDigits); // const leadingDigitsRounded = leadingDigits.toFixed(); const leadingDigitsNoTrailingDecimal = leadingDigitsRounded .toString() .replace(/\.0*$/, "") .replace(".", separator); return sign + leadingDigitsNoTrailingDecimal + suffix; } /** * Formats a big number, but does not add any suffix and instead uses its full representation * @param {number} num * @param {string=} divider The divider for numbers like 50,000 (divider=',') * @returns {string} */ function formatBigNumberFull(num, divider = _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.thousandsDivider) { if (num < 1000) { return num + ""; } if (num > 1e54) { return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.infinite; } let rest = num; let out = ""; while (rest >= 1000) { out = (rest % 1000).toString().padStart(3, "0") + divider + out; rest = Math.floor(rest / 1000); } out = rest + divider + out; return out.substring(0, out.length - 1); } /** * Waits two frames so the ui is updated * @returns {Promise} */ function waitNextFrame() { return new Promise(function (resolve) { window.requestAnimationFrame(function () { window.requestAnimationFrame(function () { resolve(); }); }); }); } /** * Rounds 1 digit * @param {number} n * @returns {number} */ function round1Digit(n) { return Math.floor(n * 10.0) / 10.0; } /** * Rounds 2 digits * @param {number} n * @returns {number} */ function round2Digits(n) { return Math.floor(n * 100.0) / 100.0; } /** * Rounds 3 digits * @param {number} n * @returns {number} */ function round3Digits(n) { return Math.floor(n * 1000.0) / 1000.0; } /** * Rounds 4 digits * @param {number} n * @returns {number} */ function round4Digits(n) { return Math.floor(n * 10000.0) / 10000.0; } /** * Clamps a value between [min, max] * @param {number} v * @param {number=} minimum Default 0 * @param {number=} maximum Default 1 */ function clamp(v, minimum = 0, maximum = 1) { return Math.max(minimum, Math.min(maximum, v)); } /** * Helper method to create a new div element * @param {string=} id * @param {Array=} classes * @param {string=} innerHTML */ function makeDivElement(id = null, classes = [], innerHTML = "") { const div = document.createElement("div"); if (id) { div.id = id; } for (let i = 0; i < classes.length; ++i) { div.classList.add(classes[i]); } div.innerHTML = innerHTML; return div; } /** * Helper method to create a new div * @param {Element} parent * @param {string=} id * @param {Array=} classes * @param {string=} innerHTML */ function makeDiv(parent, id = null, classes = [], innerHTML = "") { const div = makeDivElement(id, classes, innerHTML); parent.appendChild(div); return div; } /** * Helper method to create a new button element * @param {Array=} classes * @param {string=} innerHTML */ function makeButtonElement(classes = [], innerHTML = "") { const element = document.createElement("button"); for (let i = 0; i < classes.length; ++i) { element.classList.add(classes[i]); } element.classList.add("styledButton"); element.innerHTML = innerHTML; return element; } /** * Helper method to create a new button * @param {Element} parent * @param {Array=} classes * @param {string=} innerHTML */ function makeButton(parent, classes = [], innerHTML = "") { const element = makeButtonElement(classes, innerHTML); parent.appendChild(element); return element; } /** * Removes all children of the given element * @param {Element} elem */ function removeAllChildren(elem) { if (elem) { var range = document.createRange(); range.selectNodeContents(elem); range.deleteContents(); } } /** * Fixes lockstep simulation by converting times like 34.0000000003 to 34.00. * We use 3 digits of precision, this allows us to store precision of 1 ms without * the risking simulation errors due to resync issues * @param {number} value */ function quantizeFloat(value) { return Math.round(value * 100000.0) / 100000.0; } /** * Safe check to check if a timer is expired. quantizes numbers * @param {number} now Current time * @param {number} lastTick Last tick of the timer * @param {number} tickRate Interval of the timer */ function checkTimerExpired(now, lastTick, tickRate) { if (true) { if (quantizeFloat(now) !== now) { console.error("Got non-quantizied time:" + now + " vs " + quantizeFloat(now)); now = quantizeFloat(now); } if (quantizeFloat(lastTick) !== lastTick) { // FIXME: REENABLE // console.error("Got non-quantizied timer:" + lastTick + " vs " + quantizeFloat(lastTick)); lastTick = quantizeFloat(lastTick); } } else {} /* Ok, so heres the issue (Died a bit while debugging it): In multiplayer lockstep simulation, client A will simulate everything at T, but client B will simulate it at T + 3. So we are running into the following precision issue: Lets say on client A the time is T = 30. Then on clientB the time is T = 33. Now, our timer takes 0.1 seconds and ticked at 29.90 - What does happen now? Client A computes the timer and checks T > lastTick + interval. He computes 30 >= 29.90 + 0.1 <=> 30 >= 30.0000 <=> True <=> Tick performed However, this is what it looks on client B: 33 >= 32.90 + 0.1 <=> 33 >= 32.999999999999998 <=> False <=> No tick performed! This means that Client B will only tick at the *next* frame, which means it from now is out of sync by one tick, which means the game will resync further or later and be not able to recover, since it will run into the same issue over and over. */ // The next tick, in our example it would be 30.0000 / 32.99999999998. In order to fix it, we quantize // it, so its now 30.0000 / 33.0000 const nextTick = quantizeFloat(lastTick + tickRate); // This check is safe, but its the only check where you may compare times. You always need to use // this method! return now >= nextTick; } /** * Returns if the game supports this browser */ function isSupportedBrowser() { // please note, // that IE11 now returns undefined again for window.chrome // and new Opera 30 outputs true for window.chrome // but needs to check if window.opr is not undefined // and new IE Edge outputs to true now for window.chrome // and if not iOS Chrome check // so use the below updated condition if (false) {} // @ts-ignore var isChromium = window.chrome; var winNav = window.navigator; var vendorName = winNav.vendor; // @ts-ignore var isIEedge = winNav.userAgent.indexOf("Edge") > -1; var isIOSChrome = winNav.userAgent.match("CriOS"); if (isIOSChrome) { // is Google Chrome on IOS return false; } else if ( isChromium !== null && typeof isChromium !== "undefined" && vendorName === "Google Inc." && isIEedge === false ) { // is Google Chrome return true; } else { // not Google Chrome return false; } } /** * Formats an amount of seconds into something like "5s ago" * @param {number} secs Seconds * @returns {string} */ function formatSecondsToTimeAgo(secs) { const seconds = Math.floor(secs); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (seconds < 60) { if (seconds === 1) { return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.oneSecondAgo; } return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.xSecondsAgo.replace("", "" + seconds); } else if (minutes < 60) { if (minutes === 1) { return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.oneMinuteAgo; } return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.xMinutesAgo.replace("", "" + minutes); } else if (hours < 24) { if (hours === 1) { return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.oneHourAgo; } return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.xHoursAgo.replace("", "" + hours); } else { if (days === 1) { return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.oneDayAgo; } return _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time.xDaysAgo.replace("", "" + days); } } /** * Formats seconds into a readable string like "5h 23m" * @param {number} secs Seconds * @returns {string} */ function formatSeconds(secs) { const trans = _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.time; secs = Math.ceil(secs); if (secs < 60) { return trans.secondsShort.replace("", "" + secs); } else if (secs < 60 * 60) { const minutes = Math.floor(secs / 60); const seconds = secs % 60; return trans.minutesAndSecondsShort .replace("", "" + seconds) .replace("", "" + minutes); } else { const hours = Math.floor(secs / 3600); const minutes = Math.floor(secs / 60) % 60; return trans.hoursAndMinutesShort.replace("", "" + minutes).replace("", "" + hours); } } /** * Formats a number like 2.5 to "2.5 items / s" * @param {number} speed * @param {boolean=} double * @param {string=} separator The decimal separator for numbers like 50.1 (separator='.') */ function formatItemsPerSecond(speed, double = false, separator = _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.decimalSeparator) { return speed === 1.0 ? _translations__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.oneItemPerSecond : _translations__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.itemsPerSecond.replace( "", round2Digits(speed).toString().replace(".", separator) ) + (double ? " " + _translations__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.itemsPerSecondDouble : ""); } /** * Rotates a flat 3x3 matrix clockwise * Entries: * 0 lo * 1 mo * 2 ro * 3 lm * 4 mm * 5 rm * 6 lu * 7 mu * 8 ru * @param {Array} flatMatrix */ function rotateFlatMatrix3x3(flatMatrix) { return [ flatMatrix[6], flatMatrix[3], flatMatrix[0], flatMatrix[7], flatMatrix[4], flatMatrix[1], flatMatrix[8], flatMatrix[5], flatMatrix[2], ]; } /** * Generates rotated variants of the matrix * @param {Array} originalMatrix * @returns {Object>} */ function generateMatrixRotations(originalMatrix) { const result = { 0: originalMatrix, }; originalMatrix = rotateFlatMatrix3x3(originalMatrix); result[90] = originalMatrix; originalMatrix = rotateFlatMatrix3x3(originalMatrix); result[180] = originalMatrix; originalMatrix = rotateFlatMatrix3x3(originalMatrix); result[270] = originalMatrix; return result; } /** * * @typedef {{ * top: any, * right: any, * bottom: any, * left: any * }} DirectionalObject */ /** * Rotates a directional object * @param {DirectionalObject} obj * @returns {DirectionalObject} */ function rotateDirectionalObject(obj, rotation) { const queue = [obj.top, obj.right, obj.bottom, obj.left]; while (rotation !== 0) { rotation -= 90; queue.push(queue.shift()); } return { top: queue[0], right: queue[1], bottom: queue[2], left: queue[3], }; } /** * Modulo which works for negative numbers * @param {number} n * @param {number} m */ function safeModulo(n, m) { return ((n % m) + m) % m; } /***/ }), /***/ "./src/js/core/vector.js": /*!*******************************!*\ !*** ./src/js/core/vector.js ***! \*******************************/ /*! exports provided: enumDirection, enumInvertedDirections, enumDirectionToAngle, enumAngleToDirection, arrayAllDirections, Vector, mixVector, enumDirectionToVector */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumDirection", function() { return enumDirection; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumInvertedDirections", function() { return enumInvertedDirections; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumDirectionToAngle", function() { return enumDirectionToAngle; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumAngleToDirection", function() { return enumAngleToDirection; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "arrayAllDirections", function() { return arrayAllDirections; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector", function() { return Vector; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mixVector", function() { return mixVector; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumDirectionToVector", function() { return enumDirectionToVector; }); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ "./src/js/core/config.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/js/core/utils.js"); const tileSize = _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const halfTileSize = _config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize; /** * @enum {string} */ const enumDirection = { top: "top", right: "right", bottom: "bottom", left: "left", }; /** * @enum {string} */ const enumInvertedDirections = { [enumDirection.top]: enumDirection.bottom, [enumDirection.right]: enumDirection.left, [enumDirection.bottom]: enumDirection.top, [enumDirection.left]: enumDirection.right, }; /** * @enum {number} */ const enumDirectionToAngle = { [enumDirection.top]: 0, [enumDirection.right]: 90, [enumDirection.bottom]: 180, [enumDirection.left]: 270, }; /** * @enum {enumDirection} */ const enumAngleToDirection = { 0: enumDirection.top, 90: enumDirection.right, 180: enumDirection.bottom, 270: enumDirection.left, }; /** @type {Array} */ const arrayAllDirections = [ enumDirection.top, enumDirection.right, enumDirection.bottom, enumDirection.left, ]; class Vector { /** * * @param {number=} x * @param {number=} y */ constructor(x, y) { this.x = x || 0; this.y = y || 0; } /** * return a copy of the vector * @returns {Vector} */ copy() { return new Vector(this.x, this.y); } /** * Adds a vector and return a new vector * @param {Vector} other * @returns {Vector} */ add(other) { return new Vector(this.x + other.x, this.y + other.y); } /** * Adds a vector * @param {Vector} other * @returns {Vector} */ addInplace(other) { this.x += other.x; this.y += other.y; return this; } /** * Substracts a vector and return a new vector * @param {Vector} other * @returns {Vector} */ sub(other) { return new Vector(this.x - other.x, this.y - other.y); } /** * Subs a vector * @param {Vector} other * @returns {Vector} */ subInplace(other) { this.x -= other.x; this.y -= other.y; return this; } /** * Multiplies with a vector and return a new vector * @param {Vector} other * @returns {Vector} */ mul(other) { return new Vector(this.x * other.x, this.y * other.y); } /** * Adds two scalars and return a new vector * @param {number} x * @param {number} y * @returns {Vector} */ addScalars(x, y) { return new Vector(this.x + x, this.y + y); } /** * Substracts a scalar and return a new vector * @param {number} f * @returns {Vector} */ subScalar(f) { return new Vector(this.x - f, this.y - f); } /** * Substracts two scalars and return a new vector * @param {number} x * @param {number} y * @returns {Vector} */ subScalars(x, y) { return new Vector(this.x - x, this.y - y); } /** * Returns the euclidian length * @returns {number} */ length() { return Math.hypot(this.x, this.y); } /** * Returns the square length * @returns {number} */ lengthSquare() { return this.x * this.x + this.y * this.y; } /** * Divides both components by a scalar and return a new vector * @param {number} f * @returns {Vector} */ divideScalar(f) { return new Vector(this.x / f, this.y / f); } /** * Divides both components by the given scalars and return a new vector * @param {number} a * @param {number} b * @returns {Vector} */ divideScalars(a, b) { return new Vector(this.x / a, this.y / b); } /** * Divides both components by a scalar * @param {number} f * @returns {Vector} */ divideScalarInplace(f) { this.x /= f; this.y /= f; return this; } /** * Multiplies both components with a scalar and return a new vector * @param {number} f * @returns {Vector} */ multiplyScalar(f) { return new Vector(this.x * f, this.y * f); } /** * Multiplies both components with two scalars and returns a new vector * @param {number} a * @param {number} b * @returns {Vector} */ multiplyScalars(a, b) { return new Vector(this.x * a, this.y * b); } /** * For both components, compute the maximum of each component and the given scalar, and return a new vector. * For example: * - new Vector(-1, 5).maxScalar(0) -> Vector(0, 5) * @param {number} f * @returns {Vector} */ maxScalar(f) { return new Vector(Math.max(f, this.x), Math.max(f, this.y)); } /** * Adds a scalar to both components and return a new vector * @param {number} f * @returns {Vector} */ addScalar(f) { return new Vector(this.x + f, this.y + f); } /** * Computes the component wise minimum and return a new vector * @param {Vector} v * @returns {Vector} */ min(v) { return new Vector(Math.min(v.x, this.x), Math.min(v.y, this.y)); } /** * Computes the component wise maximum and return a new vector * @param {Vector} v * @returns {Vector} */ max(v) { return new Vector(Math.max(v.x, this.x), Math.max(v.y, this.y)); } /** * Computes the component wise absolute * @returns {Vector} */ abs() { return new Vector(Math.abs(this.x), Math.abs(this.y)); } /** * Computes the scalar product * @param {Vector} v * @returns {number} */ dot(v) { return this.x * v.x + this.y * v.y; } /** * Computes the distance to a given vector * @param {Vector} v * @returns {number} */ distance(v) { return Math.hypot(this.x - v.x, this.y - v.y); } /** * Computes the square distance to a given vectort * @param {Vector} v * @returns {number} */ distanceSquare(v) { const dx = this.x - v.x; const dy = this.y - v.y; return dx * dx + dy * dy; } /** * Returns x % f, y % f * @param {number} f * @returns {Vector} new vector */ modScalar(f) { return new Vector(Object(_utils__WEBPACK_IMPORTED_MODULE_1__["safeModulo"])(this.x, f), Object(_utils__WEBPACK_IMPORTED_MODULE_1__["safeModulo"])(this.y, f)); } /** * Computes and returns the center between both points * @param {Vector} v * @returns {Vector} */ centerPoint(v) { const cx = this.x + v.x; const cy = this.y + v.y; return new Vector(cx / 2, cy / 2); } /** * Computes componentwise floor and returns a new vector * @returns {Vector} */ floor() { return new Vector(Math.floor(this.x), Math.floor(this.y)); } /** * Computes componentwise ceil and returns a new vector * @returns {Vector} */ ceil() { return new Vector(Math.ceil(this.x), Math.ceil(this.y)); } /** * Computes componentwise round and return a new vector * @returns {Vector} */ round() { return new Vector(Math.round(this.x), Math.round(this.y)); } /** * Converts this vector from world to tile space and return a new vector * @returns {Vector} */ toTileSpace() { return new Vector(Math.floor(this.x / tileSize), Math.floor(this.y / tileSize)); } /** * Converts this vector from world to street space and return a new vector * @returns {Vector} */ toStreetSpace() { return new Vector(Math.floor(this.x / halfTileSize + 0.25), Math.floor(this.y / halfTileSize + 0.25)); } /** * Converts this vector to world space and return a new vector * @returns {Vector} */ toWorldSpace() { return new Vector(this.x * tileSize, this.y * tileSize); } /** * Converts this vector to world space and return a new vector * @returns {Vector} */ toWorldSpaceCenterOfTile() { return new Vector(this.x * tileSize + halfTileSize, this.y * tileSize + halfTileSize); } /** * Converts the top left tile position of this vector * @returns {Vector} */ snapWorldToTile() { return new Vector(Math.floor(this.x / tileSize) * tileSize, Math.floor(this.y / tileSize) * tileSize); } /** * Normalizes the vector, dividing by the length(), and return a new vector * @returns {Vector} */ normalize() { const len = Math.max(1e-5, Math.hypot(this.x, this.y)); return new Vector(this.x / len, this.y / len); } /** * Normalizes the vector, dividing by the length(), and return a new vector * @returns {Vector} */ normalizeIfGreaterOne() { const len = Math.max(1, Math.hypot(this.x, this.y)); return new Vector(this.x / len, this.y / len); } /** * Returns the normalized vector to the other point * @param {Vector} v * @returns {Vector} */ normalizedDirection(v) { const dx = v.x - this.x; const dy = v.y - this.y; const len = Math.max(1e-5, Math.hypot(dx, dy)); return new Vector(dx / len, dy / len); } /** * Returns a perpendicular vector * @returns {Vector} */ findPerpendicular() { return new Vector(-this.y, this.x); } /** * Returns the unnormalized direction to the other point * @param {Vector} v * @returns {Vector} */ direction(v) { return new Vector(v.x - this.x, v.y - this.y); } /** * Returns a string representation of the vector * @returns {string} */ toString() { return this.x + "," + this.y; } /** * Compares both vectors for exact equality. Does not do an epsilon compare * @param {Vector} v * @returns {Boolean} */ equals(v) { return this.x === v.x && this.y === v.y; } /** * Rotates this vector * @param {number} angle * @returns {Vector} new vector */ rotated(angle) { const sin = Math.sin(angle); const cos = Math.cos(angle); return new Vector(this.x * cos - this.y * sin, this.x * sin + this.y * cos); } /** * Rotates this vector * @param {number} angle * @returns {Vector} this vector */ rotateInplaceFastMultipleOf90(angle) { // const sin = Math.sin(angle); // const cos = Math.cos(angle); // let sin = 0, cos = 1; window.assert(angle >= 0 && angle <= 360, "Invalid angle, please clamp first: " + angle); switch (angle) { case 0: case 360: { return this; } case 90: { // sin = 1; // cos = 0; const x = this.x; this.x = -this.y; this.y = x; return this; } case 180: { // sin = 0 // cos = -1 this.x = -this.x; this.y = -this.y; return this; } case 270: { // sin = -1 // cos = 0 const x = this.x; this.x = this.y; this.y = -x; return this; } default: { window.assert(false, "Invalid fast inplace rotation: " + angle); return this; } } // return new Vector(this.x * cos - this.y * sin, this.x * sin + this.y * cos); } /** * Rotates this vector * @param {number} angle * @returns {Vector} new vector */ rotateFastMultipleOf90(angle) { window.assert(angle >= 0 && angle <= 360, "Invalid angle, please clamp first: " + angle); switch (angle) { case 360: case 0: { return new Vector(this.x, this.y); } case 90: { return new Vector(-this.y, this.x); } case 180: { return new Vector(-this.x, -this.y); } case 270: { return new Vector(this.y, -this.x); } default: { window.assert(false, "Invalid fast inplace rotation: " + angle); return new Vector(); } } } /** * Helper method to rotate a direction * @param {enumDirection} direction * @param {number} angle * @returns {enumDirection} */ static transformDirectionFromMultipleOf90(direction, angle) { if (angle === 0 || angle === 360) { return direction; } window.assert(angle >= 0 && angle <= 360, "Invalid angle: " + angle); switch (direction) { case enumDirection.top: { switch (angle) { case 90: return enumDirection.right; case 180: return enumDirection.bottom; case 270: return enumDirection.left; default: window.assert(false, "Invalid angle: " + angle); return; } } case enumDirection.right: { switch (angle) { case 90: return enumDirection.bottom; case 180: return enumDirection.left; case 270: return enumDirection.top; default: window.assert(false, "Invalid angle: " + angle); return; } } case enumDirection.bottom: { switch (angle) { case 90: return enumDirection.left; case 180: return enumDirection.top; case 270: return enumDirection.right; default: window.assert(false, "Invalid angle: " + angle); return; } } case enumDirection.left: { switch (angle) { case 90: return enumDirection.top; case 180: return enumDirection.right; case 270: return enumDirection.bottom; default: window.assert(false, "Invalid angle: " + angle); return; } } default: window.assert(false, "Invalid angle: " + angle); return; } } /** * Compares both vectors for epsilon equality * @param {Vector} v * @returns {Boolean} */ equalsEpsilon(v, epsilon = 1e-5) { return Math.abs(this.x - v.x) < 1e-5 && Math.abs(this.y - v.y) < epsilon; } /** * Returns the angle * @returns {number} 0 .. 2 PI */ angle() { return Math.atan2(this.y, this.x) + Math.PI / 2; } /** * Serializes the vector to a string * @returns {string} */ serializeTile() { return String.fromCharCode(33 + this.x) + String.fromCharCode(33 + this.y); } /** * Creates a simple representation of the vector */ serializeSimple() { return { x: this.x, y: this.y }; } /** * @returns {number} */ serializeTileToInt() { return this.x + this.y * 256; } /** * * @param {number} i * @returns {Vector} */ static deserializeTileFromInt(i) { const x = i % 256; const y = Math.floor(i / 256); return new Vector(x, y); } /** * Deserializes a vector from a string * @param {string} s * @returns {Vector} */ static deserializeTile(s) { return new Vector(s.charCodeAt(0) - 33, s.charCodeAt(1) - 33); } /** * Deserializes a vector from a serialized json object * @param {object} obj * @returns {Vector} */ static fromSerializedObject(obj) { if (obj) { return new Vector(obj.x || 0, obj.y || 0); } } } /** * Interpolates two vectors, for a = 0, returns v1 and for a = 1 return v2, otherwise interpolate * @param {Vector} v1 * @param {Vector} v2 * @param {number} a */ function mixVector(v1, v2, a) { return new Vector(v1.x * (1 - a) + v2.x * a, v1.y * (1 - a) + v2.y * a); } /** * Mapping from string direction to actual vector * @enum {Vector} */ const enumDirectionToVector = { top: new Vector(0, -1), right: new Vector(1, 0), bottom: new Vector(0, 1), left: new Vector(-1, 0), }; /***/ }), /***/ "./src/js/game/automatic_save.js": /*!***************************************!*\ !*** ./src/js/game/automatic_save.js ***! \***************************************/ /*! exports provided: enumSavePriority, AutomaticSave */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumSavePriority", function() { return enumSavePriority; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AutomaticSave", function() { return AutomaticSave; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); // How important it is that a savegame is created /** * @enum {number} */ const enumSavePriority = { regular: 2, asap: 100, }; const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("autosave"); // Internals let MIN_INTERVAL_SECS = 60; class AutomaticSave { constructor(root) { /** @type {GameRoot} */ this.root = root; // Store the current maximum save importance this.saveImportance = enumSavePriority.regular; this.lastSaveAttempt = -1000; } setSaveImportance(importance) { this.saveImportance = Math.max(this.saveImportance, importance); } doSave() { if (_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.disableSavegameWrite) { return; } this.root.gameState.doSave(); this.saveImportance = enumSavePriority.regular; } update() { if (!this.root.gameInitialized) { // Bad idea return; } const saveInterval = this.root.app.settings.getAutosaveIntervalSeconds(); if (!saveInterval) { // Disabled return; } // Check when the last save was, but make sure that if it fails, we don't spam const lastSaveTime = Math.max(this.lastSaveAttempt, this.root.savegame.getRealLastUpdate()); const secondsSinceLastSave = (Date.now() - lastSaveTime) / 1000.0; let shouldSave = false; switch (this.saveImportance) { case enumSavePriority.asap: // High always should save shouldSave = true; break; case enumSavePriority.regular: // Could determine if there is a good / bad point here shouldSave = secondsSinceLastSave > saveInterval; break; default: window.assert(false, "Unknown save prio: " + this.saveImportance); break; } if (shouldSave) { logger.log("Saving automatically"); this.lastSaveAttempt = Date.now(); this.doSave(); } } } /***/ }), /***/ "./src/js/game/base_item.js": /*!**********************************!*\ !*** ./src/js/game/base_item.js ***! \**********************************/ /*! exports provided: itemTypes, BaseItem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "itemTypes", function() { return itemTypes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseItem", function() { return BaseItem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /** @type {ItemType[]} **/ const itemTypes = ["shape", "color", "boolean"]; /** * Class for items on belts etc. Not an entity for performance reasons */ class BaseItem extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["BasicSerializableObject"] { constructor() { super(); } static getId() { return "base_item"; } /** @returns {object} */ static getSchema() { return {}; } /** @returns {ItemType} **/ getItemType() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return "shape"; } /** * Returns if the item equals the other itme * @param {BaseItem} other * @returns {boolean} */ equals(other) { if (this.getItemType() !== other.getItemType()) { return false; } return this.equalsImpl(other); } /** * Override for custom comparison * @abstract * @param {BaseItem} other * @returns {boolean} */ equalsImpl(other) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } /** @returns {string} */ getHash() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return ""; } /** * Draws the item at the given position * @param {number} x * @param {number} y * @param {DrawParameters} parameters * @param {number=} diameter */ drawItemCenteredClipped(x, y, parameters, diameter = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter) { if (parameters.visibleRect.containsCircle(x, y, diameter / 2)) { this.drawItemCenteredImpl(x, y, parameters, diameter); } } /** * INTERNAL * @param {number} x * @param {number} y * @param {DrawParameters} parameters * @param {number=} diameter */ drawItemCenteredImpl(x, y, parameters, diameter = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } getBackgroundColorAsResource() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return ""; } static generateAsCanvas(hash, size) { if (hash.length % 9 == 8) { // @ts-ignore return BaseItem.ShapeDefinition.createFromHash(hash).generateAsCanvas(size); } if (hash.length == 1) { // @ts-ignore return BaseItem.ColorItem.createFromHash(hash).generateAsCanvas(size); } window.assert(false, "undrawable item"); } } /***/ }), /***/ "./src/js/game/belt_path.js": /*!**********************************!*\ !*** ./src/js/game/belt_path.js ***! \**********************************/ /*! exports provided: BeltPath */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BeltPath", function() { return BeltPath; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./item_resolver */ "./src/js/game/item_resolver.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("belt_path"); // Helpers for more semantic access into interleaved arrays const _nextDistance = 0; const _item = 1; const DEBUG = true && false; /** * Stores a path of belts, used for optimizing performance */ class BeltPath extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["BasicSerializableObject"] { static getId() { return "BeltPath"; } static getSchema() { return { entityPath: _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["types"].array(_savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["types"].entity), items: _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["types"].array(_savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["types"].pair(_savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["types"].ufloat, _item_resolver__WEBPACK_IMPORTED_MODULE_9__["typeItemSingleton"])), spacingToFirstItem: _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["types"].ufloat, }; } /** * Creates a path from a serialized object * @param {GameRoot} root * @param {Object} data * @returns {BeltPath|string} */ static fromSerialized(root, data) { // Create fake object which looks like a belt path but skips the constructor const fakeObject = /** @type {BeltPath} */ (Object.create(BeltPath.prototype)); fakeObject.root = root; // Deserialize the data const errorCodeDeserialize = fakeObject.deserialize(data); if (errorCodeDeserialize) { return errorCodeDeserialize; } // Compute other properties fakeObject.init(false); return fakeObject; } /** * @param {GameRoot} root * @param {Array} entityPath */ constructor(root, entityPath) { super(); this.root = root; window.assert(entityPath.length > 0, "invalid entity path"); this.entityPath = entityPath; /** * Stores the items sorted, and their distance to the previous item (or start) * Layout: [distanceToNext, item] * @type {Array<[number, BaseItem]>} */ this.items = []; /** * Stores the spacing to the first item */ this.init(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("constructor"); } } /** * Initializes the path by computing the properties which are not saved * @param {boolean} computeSpacing Whether to also compute the spacing */ init(computeSpacing = true) { this.onPathChanged(); this.totalLength = this.computeTotalLength(); if (computeSpacing) { this.spacingToFirstItem = this.totalLength; } /** * Current bounds of this path * @type {Rectangle} */ this.worldBounds = this.computeBounds(); // Connect the belts for (let i = 0; i < this.entityPath.length; ++i) { this.entityPath[i].components.Belt.assignedPath = this; } } /** * Returns whether this path can accept a new item * @returns {boolean} */ canAcceptItem() { return this.spacingToFirstItem >= _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; } /** * Tries to accept the item * @param {BaseItem} item */ tryAcceptItem(item) { if (this.spacingToFirstItem >= _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts) { // So, since we already need one tick to accept this item we will add this directly. const beltProgressPerTick = this.root.hubGoals.getBeltBaseSpeed() * this.root.dynamicTickrate.deltaSeconds * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; // First, compute how much progress we can make *at max* const maxProgress = Math.max(0, this.spacingToFirstItem - _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts); const initialProgress = Math.min(maxProgress, beltProgressPerTick); this.items.unshift([this.spacingToFirstItem - initialProgress, item]); this.spacingToFirstItem = initialProgress; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("accept-item"); } return true; } return false; } /** * SLOW / Tries to find the item closest to the given tile * @param {Vector} tile * @returns {BaseItem|null} */ findItemAtTile(tile) { // @TODO: This breaks color blind mode otherwise return null; } /** * Computes the tile bounds of the path * @returns {Rectangle} */ computeBounds() { let bounds = this.entityPath[0].components.StaticMapEntity.getTileSpaceBounds(); for (let i = 1; i < this.entityPath.length; ++i) { const staticComp = this.entityPath[i].components.StaticMapEntity; const otherBounds = staticComp.getTileSpaceBounds(); bounds = bounds.getUnion(otherBounds); } return bounds.allScaled(_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize); } /** * Recomputes cache variables once the path was changed */ onPathChanged() { this.acceptorTarget = this.computeAcceptingEntityAndSlot(); } /** * Called by the belt system when the surroundings changed */ onSurroundingsChanged() { this.onPathChanged(); } /** * Finds the entity which accepts our items * @return {{ entity: Entity, slot: number, direction?: enumDirection }} */ computeAcceptingEntityAndSlot() { const lastEntity = this.entityPath[this.entityPath.length - 1]; const lastStatic = lastEntity.components.StaticMapEntity; const lastBeltComp = lastEntity.components.Belt; // Figure out where and into which direction we eject items const ejectSlotWsTile = lastStatic.localTileToWorld(new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](0, 0)); const ejectSlotWsDirection = lastStatic.localDirectionToWorld(lastBeltComp.direction); const ejectSlotWsDirectionVector = _core_vector__WEBPACK_IMPORTED_MODULE_5__["enumDirectionToVector"][ejectSlotWsDirection]; const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector); // Try to find the given acceptor component to take the item const targetEntity = this.root.map.getLayerContentXY( ejectSlotTargetWsTile.x, ejectSlotTargetWsTile.y, "regular" ); if (targetEntity) { const targetStaticComp = targetEntity.components.StaticMapEntity; const targetBeltComp = targetEntity.components.Belt; // Check for belts (special case) if (targetBeltComp) { const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_5__["enumDirection"].top); if (ejectSlotWsDirection === beltAcceptingDirection) { return { entity: targetEntity, direction: null, slot: 0, }; } } // Check for item acceptors const targetAcceptorComp = targetEntity.components.ItemAcceptor; if (!targetAcceptorComp) { // Entity doesn't accept items return; } const ejectingDirection = targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection); const matchingSlot = targetAcceptorComp.findMatchingSlot( targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile), ejectingDirection ); if (!matchingSlot) { // No matching slot found return; } return { entity: targetEntity, slot: matchingSlot.index, direction: _core_vector__WEBPACK_IMPORTED_MODULE_5__["enumInvertedDirections"][ejectingDirection], }; } } // Following code will be compiled out outside of dev versions /* dev:start */ /** * Helper to throw an error on mismatch * @param {string} change * @param {Array} reason */ debug_failIntegrity(change, ...reason) { throw new Error("belt path invalid (" + change + "): " + reason.map(i => "" + i).join(" ")); } /** * Checks if this path is valid */ debug_checkIntegrity(currentChange = "change") { const fail = (...args) => this.debug_failIntegrity(currentChange, ...args); // Check for empty path if (this.entityPath.length === 0) { return fail("Belt path is empty"); } // Check for mismatching length const totalLength = this.computeTotalLength(); if (!Object(_core_utils__WEBPACK_IMPORTED_MODULE_4__["epsilonCompare"])(this.totalLength, totalLength, 0.01)) { return this.debug_failIntegrity( currentChange, "Total length mismatch, stored =", this.totalLength, "but correct is", totalLength ); } // Check for misconnected entities for (let i = 0; i < this.entityPath.length - 1; ++i) { const entity = this.entityPath[i]; if (entity.destroyed) { return fail("Reference to destroyed entity " + entity.uid); } const followUp = this.root.systemMgr.systems.belt.findFollowUpEntity(entity); if (!followUp) { return fail( "Follow up entity for the", i, "-th entity (total length", this.entityPath.length, ") was null!" ); } if (followUp !== this.entityPath[i + 1]) { return fail( "Follow up entity mismatch, stored is", this.entityPath[i + 1].uid, "but real one is", followUp.uid ); } if (entity.components.Belt.assignedPath !== this) { return fail( "Entity with uid", entity.uid, "doesn't have this path assigned, but this path contains the entity." ); } } // Check spacing if (this.spacingToFirstItem > this.totalLength + 0.005) { return fail( currentChange, "spacing to first item (", this.spacingToFirstItem, ") is greater than total length (", this.totalLength, ")" ); } // Check distance if empty if (this.items.length === 0 && !Object(_core_utils__WEBPACK_IMPORTED_MODULE_4__["epsilonCompare"])(this.spacingToFirstItem, this.totalLength, 0.01)) { return fail( currentChange, "Path is empty but spacing to first item (", this.spacingToFirstItem, ") does not equal total length (", this.totalLength, ")" ); } // Check items etc let currentPos = this.spacingToFirstItem; for (let i = 0; i < this.items.length; ++i) { const item = this.items[i]; if (item[_nextDistance] < 0 || item[_nextDistance] > this.totalLength + 0.02) { return fail( "Item has invalid offset to next item: ", item[_nextDistance], "(total length:", this.totalLength, ")" ); } currentPos += item[_nextDistance]; } // Check the total sum matches if (!Object(_core_utils__WEBPACK_IMPORTED_MODULE_4__["epsilonCompare"])(currentPos, this.totalLength, 0.01)) { return fail( "total sum (", currentPos, ") of first item spacing (", this.spacingToFirstItem, ") and items does not match total length (", this.totalLength, ") -> items: " + this.items.map(i => i[_nextDistance]).join("|") ); } // Check bounds const actualBounds = this.computeBounds(); if (!actualBounds.equalsEpsilon(this.worldBounds, 0.01)) { return fail("Bounds are stale"); } } /* dev:end */ /** * Extends the belt path by the given belt * @param {Entity} entity */ extendOnEnd(entity) { DEBUG && logger.log("Extending belt path by entity at", entity.components.StaticMapEntity.origin); const beltComp = entity.components.Belt; // Append the entity this.entityPath.push(entity); this.onPathChanged(); // Extend the path length const additionalLength = beltComp.getEffectiveLengthTiles(); this.totalLength += additionalLength; DEBUG && logger.log(" Extended total length by", additionalLength, "to", this.totalLength); // If we have no item, just update the distance to the first item if (this.items.length === 0) { this.spacingToFirstItem = this.totalLength; DEBUG && logger.log(" Extended spacing to first to", this.totalLength, "(= total length)"); } else { // Otherwise, update the next-distance of the last item const lastItem = this.items[this.items.length - 1]; DEBUG && logger.log( " Extended spacing of last item from", lastItem[_nextDistance], "to", lastItem[_nextDistance] + additionalLength ); lastItem[_nextDistance] += additionalLength; } // Assign reference beltComp.assignedPath = this; // Update bounds this.worldBounds = this.computeBounds(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("extend-on-end"); } } /** * Extends the path with the given entity on the beginning * @param {Entity} entity */ extendOnBeginning(entity) { const beltComp = entity.components.Belt; DEBUG && logger.log("Extending the path on the beginning"); // All items on that belt are simply lost (for now) const length = beltComp.getEffectiveLengthTiles(); // Extend the length of this path this.totalLength += length; // Simply adjust the first item spacing cuz we have no items contained this.spacingToFirstItem += length; // Set handles and append entity beltComp.assignedPath = this; this.entityPath.unshift(entity); this.onPathChanged(); // Update bounds this.worldBounds = this.computeBounds(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("extend-on-begin"); } } /** * Returns if the given entity is the end entity of the path * @param {Entity} entity * @returns {boolean} */ isEndEntity(entity) { return this.entityPath[this.entityPath.length - 1] === entity; } /** * Returns if the given entity is the start entity of the path * @param {Entity} entity * @returns {boolean} */ isStartEntity(entity) { return this.entityPath[0] === entity; } /** * Splits this path at the given entity by removing it, and * returning the new secondary paht * @param {Entity} entity * @returns {BeltPath} */ deleteEntityOnPathSplitIntoTwo(entity) { DEBUG && logger.log("Splitting path at entity", entity.components.StaticMapEntity.origin); // First, find where the current path ends const beltComp = entity.components.Belt; beltComp.assignedPath = null; const entityLength = beltComp.getEffectiveLengthTiles(); window.assert(this.entityPath.indexOf(entity) >= 0, "Entity not contained for split"); window.assert(this.entityPath.indexOf(entity) !== 0, "Entity is first"); window.assert(this.entityPath.indexOf(entity) !== this.entityPath.length - 1, "Entity is last"); let firstPathEntityCount = 0; let firstPathLength = 0; let firstPathEndEntity = null; for (let i = 0; i < this.entityPath.length; ++i) { const otherEntity = this.entityPath[i]; if (otherEntity === entity) { DEBUG && logger.log("Found entity at", i, "of length", firstPathLength); break; } ++firstPathEntityCount; firstPathEndEntity = otherEntity; firstPathLength += otherEntity.components.Belt.getEffectiveLengthTiles(); } DEBUG && logger.log( "First path ends at", firstPathLength, "and entity", firstPathEndEntity.components.StaticMapEntity.origin, "and has", firstPathEntityCount, "entities" ); // Compute length of second path const secondPathLength = this.totalLength - firstPathLength - entityLength; const secondPathStart = firstPathLength + entityLength; const secondEntities = this.entityPath.splice(firstPathEntityCount + 1); DEBUG && logger.log( "Second path starts at", secondPathStart, "and has a length of ", secondPathLength, "with", secondEntities.length, "entities" ); // Remove the last item this.entityPath.pop(); DEBUG && logger.log("Splitting", this.items.length, "items"); DEBUG && logger.log( "Old items are", this.items.map(i => i[_nextDistance]) ); // Create second path const secondPath = new BeltPath(this.root, secondEntities); // Remove all items which are no longer relevant and transfer them to the second path let itemPos = this.spacingToFirstItem; for (let i = 0; i < this.items.length; ++i) { const item = this.items[i]; const distanceToNext = item[_nextDistance]; DEBUG && logger.log(" Checking item at", itemPos, "with distance of", distanceToNext, "to next"); // Check if this item is past the first path if (itemPos >= firstPathLength) { // Remove it from the first path this.items.splice(i, 1); i -= 1; DEBUG && logger.log(" Removed item from first path since its no longer contained @", itemPos); // Check if its on the second path (otherwise its on the removed belt and simply lost) if (itemPos >= secondPathStart) { // Put item on second path secondPath.items.push([distanceToNext, item[_item]]); DEBUG && logger.log( " Put item to second path @", itemPos, "with distance to next =", distanceToNext ); // If it was the first item, adjust the distance to the first item if (secondPath.items.length === 1) { DEBUG && logger.log(" Sinc it was the first, set sapcing of first to", itemPos); secondPath.spacingToFirstItem = itemPos - secondPathStart; } } else { DEBUG && logger.log(" Item was on the removed belt, so its gone - forever!"); } } else { // Seems this item is on the first path (so all good), so just make sure it doesn't // have a nextDistance which is bigger than the total path length const clampedDistanceToNext = Math.min(itemPos + distanceToNext, firstPathLength) - itemPos; if (clampedDistanceToNext < distanceToNext) { DEBUG && logger.log( "Correcting next distance (first path) from", distanceToNext, "to", clampedDistanceToNext ); item[_nextDistance] = clampedDistanceToNext; } } // Advance items itemPos += distanceToNext; } DEBUG && logger.log( "New items are", this.items.map(i => i[_nextDistance]) ); DEBUG && logger.log( "And second path items are", secondPath.items.map(i => i[_nextDistance]) ); // Adjust our total length this.totalLength = firstPathLength; // Make sure that if we are empty, we set our first distance properly if (this.items.length === 0) { this.spacingToFirstItem = this.totalLength; } this.onPathChanged(); secondPath.onPathChanged(); // Update bounds this.worldBounds = this.computeBounds(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("split-two-first"); secondPath.debug_checkIntegrity("split-two-second"); } return secondPath; } /** * Deletes the last entity * @param {Entity} entity */ deleteEntityOnEnd(entity) { window.assert( this.entityPath[this.entityPath.length - 1] === entity, "Not actually the last entity (instead " + this.entityPath.indexOf(entity) + ")" ); // Ok, first remove the entity const beltComp = entity.components.Belt; const beltLength = beltComp.getEffectiveLengthTiles(); DEBUG && logger.log( "Deleting last entity on path with length", this.entityPath.length, "(reducing", this.totalLength, " by", beltLength, ")" ); this.totalLength -= beltLength; this.entityPath.pop(); this.onPathChanged(); DEBUG && logger.log( " New path has length of", this.totalLength, "with", this.entityPath.length, "entities" ); // This is just for sanity beltComp.assignedPath = null; // Clean up items if (this.items.length === 0) { // Simple case with no items, just update the first item spacing this.spacingToFirstItem = this.totalLength; } else { // Ok, make sure we simply drop all items which are no longer contained let itemOffset = this.spacingToFirstItem; let lastItemOffset = itemOffset; DEBUG && logger.log(" Adjusting", this.items.length, "items"); for (let i = 0; i < this.items.length; ++i) { const item = this.items[i]; // Get rid of items past this path if (itemOffset >= this.totalLength) { DEBUG && logger.log("Dropping item (current index=", i, ")"); this.items.splice(i, 1); i -= 1; continue; } DEBUG && logger.log("Item", i, "is at", itemOffset, "with next offset", item[_nextDistance]); lastItemOffset = itemOffset; itemOffset += item[_nextDistance]; } // If we still have an item, make sure the last item matches if (this.items.length > 0) { // We can easily compute the next distance since we know where the last item is now const lastDistance = this.totalLength - lastItemOffset; window.assert( lastDistance >= 0.0, "Last item distance mismatch: " + lastDistance + " -> Total length was " + this.totalLength + " and lastItemOffset was " + lastItemOffset ); DEBUG && logger.log( "Adjusted distance of last item: it is at", lastItemOffset, "so it has a distance of", lastDistance, "to the end (", this.totalLength, ")" ); this.items[this.items.length - 1][_nextDistance] = lastDistance; } else { DEBUG && logger.log(" Removed all items so we'll update spacing to total length"); // We removed all items so update our spacing this.spacingToFirstItem = this.totalLength; } } // Update bounds this.worldBounds = this.computeBounds(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("delete-on-end"); } } /** * Deletes the entity of the start of the path * @see deleteEntityOnEnd * @param {Entity} entity */ deleteEntityOnStart(entity) { window.assert( entity === this.entityPath[0], "Not actually the start entity (instead " + this.entityPath.indexOf(entity) + ")" ); // Ok, first remove the entity const beltComp = entity.components.Belt; const beltLength = beltComp.getEffectiveLengthTiles(); DEBUG && logger.log( "Deleting first entity on path with length", this.entityPath.length, "(reducing", this.totalLength, " by", beltLength, ")" ); this.totalLength -= beltLength; this.entityPath.shift(); this.onPathChanged(); DEBUG && logger.log( " New path has length of", this.totalLength, "with", this.entityPath.length, "entities" ); // This is just for sanity beltComp.assignedPath = null; // Clean up items if (this.items.length === 0) { // Simple case with no items, just update the first item spacing this.spacingToFirstItem = this.totalLength; } else { // Simple case, we had no item on the beginning -> all good if (this.spacingToFirstItem >= beltLength) { DEBUG && logger.log( " No item on the first place, so we can just adjust the spacing (spacing=", this.spacingToFirstItem, ") removed =", beltLength ); this.spacingToFirstItem -= beltLength; } else { // Welp, okay we need to drop all items which are < beltLength and adjust // the other item offsets as well DEBUG && logger.log( " We have at least one item in the beginning, drop those and adjust spacing (first item @", this.spacingToFirstItem, ") since we removed", beltLength, "length from path" ); DEBUG && logger.log( " Items:", this.items.map(i => i[_nextDistance]) ); // Find offset to first item let itemOffset = this.spacingToFirstItem; for (let i = 0; i < this.items.length; ++i) { const item = this.items[i]; if (itemOffset <= beltLength) { DEBUG && logger.log( " -> Dropping item with index", i, "at", itemOffset, "since it was on the removed belt" ); // This item must be dropped this.items.splice(i, 1); i -= 1; itemOffset += item[_nextDistance]; continue; } else { // This item can be kept, thus its the first we know break; } } if (this.items.length > 0) { DEBUG && logger.log( " Offset of first non-dropped item was at:", itemOffset, "-> setting spacing to it (total length=", this.totalLength, ")" ); this.spacingToFirstItem = itemOffset - beltLength; window.assert( this.spacingToFirstItem >= 0.0, "Invalid spacing after delete on start: " + this.spacingToFirstItem ); } else { DEBUG && logger.log(" We dropped all items, simply set spacing to total length"); // We dropped all items, simple one this.spacingToFirstItem = this.totalLength; } } } // Update bounds this.worldBounds = this.computeBounds(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("delete-on-start"); } } /** * Extends the path by the given other path * @param {BeltPath} otherPath */ extendByPath(otherPath) { window.assert(otherPath !== this, "Circular path dependency"); const entities = otherPath.entityPath; DEBUG && logger.log("Extending path by other path, starting to add entities"); const oldLength = this.totalLength; DEBUG && logger.log(" Adding", entities.length, "new entities, current length =", this.totalLength); // First, append entities for (let i = 0; i < entities.length; ++i) { const entity = entities[i]; const beltComp = entity.components.Belt; // Add to path and update references this.entityPath.push(entity); beltComp.assignedPath = this; // Update our length const additionalLength = beltComp.getEffectiveLengthTiles(); this.totalLength += additionalLength; } DEBUG && logger.log( " Path is now", this.entityPath.length, "entities and has a length of", this.totalLength ); // Now, update the distance of our last item if (this.items.length !== 0) { const lastItem = this.items[this.items.length - 1]; lastItem[_nextDistance] += otherPath.spacingToFirstItem; DEBUG && logger.log(" Add distance to last item, effectively being", lastItem[_nextDistance], "now"); } else { // Seems we have no items, update our first item distance this.spacingToFirstItem = oldLength + otherPath.spacingToFirstItem; DEBUG && logger.log( " We had no items, so our new spacing to first is old length (", oldLength, ") plus others spacing to first (", otherPath.spacingToFirstItem, ") =", this.spacingToFirstItem ); } DEBUG && logger.log(" Pushing", otherPath.items.length, "items from other path"); // Aaand push the other paths items for (let i = 0; i < otherPath.items.length; ++i) { const item = otherPath.items[i]; this.items.push([item[_nextDistance], item[_item]]); } // Update bounds this.worldBounds = this.computeBounds(); this.onPathChanged(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("extend-by-path"); } } /** * Computes the total length of the path * @returns {number} */ computeTotalLength() { let length = 0; for (let i = 0; i < this.entityPath.length; ++i) { const entity = this.entityPath[i]; length += entity.components.Belt.getEffectiveLengthTiles(); } return length; } /** * Performs one tick */ update() { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("pre-update"); } // Divide by item spacing on belts since we use throughput and not speed let beltSpeed = this.root.hubGoals.getBeltBaseSpeed() * this.root.dynamicTickrate.deltaSeconds * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.instantBelts) { beltSpeed *= 100; } let minimumDistance = 0; // Try to reduce spacing let remainingAmount = beltSpeed; for (let i = this.items.length - 1; i >= 0; --i) { const nextDistanceAndItem = this.items[i]; const minimumSpacing = minimumDistance; const takeAway = Math.max( 0, Math.min(remainingAmount, nextDistanceAndItem[_nextDistance] - minimumSpacing) ); remainingAmount -= takeAway; nextDistanceAndItem[_nextDistance] -= takeAway; this.spacingToFirstItem += takeAway; if (remainingAmount < 0.01) { break; } minimumDistance = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; } // Check if we have an item which is ready to be emitted const lastItem = this.items[this.items.length - 1]; if (lastItem && lastItem[_nextDistance] === 0 && this.acceptorTarget) { if (this.tryHandOverItem(lastItem[_item])) { this.items.pop(); } } if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_checkIntegrity("post-update"); } } /** * Tries to hand over the item to the end entity * @param {BaseItem} item */ tryHandOverItem(item) { if (!this.acceptorTarget) { return; } const targetAcceptorComp = this.acceptorTarget.entity.components.ItemAcceptor; // Check if the acceptor has a filter for example if (targetAcceptorComp && !targetAcceptorComp.canAcceptItem(this.acceptorTarget.slot, item)) { // Well, this item is not accepted return false; } // Try to pass over if ( this.root.systemMgr.systems.itemEjector.tryPassOverItem( item, this.acceptorTarget.entity, this.acceptorTarget.slot ) ) { // Trigger animation on the acceptor comp const targetAcceptorComp = this.acceptorTarget.entity.components.ItemAcceptor; if (targetAcceptorComp) { targetAcceptorComp.onItemAccepted( this.acceptorTarget.slot, this.acceptorTarget.direction, item ); } return true; } return false; } /** * Computes a world space position from the given progress * @param {number} progress * @returns {Vector} */ computePositionFromProgress(progress) { let currentLength = 0; // floating point issuses .. window.assert(progress <= this.totalLength + 0.02, "Progress too big: " + progress); for (let i = 0; i < this.entityPath.length; ++i) { const beltComp = this.entityPath[i].components.Belt; const localLength = beltComp.getEffectiveLengthTiles(); if (currentLength + localLength >= progress || i === this.entityPath.length - 1) { // Min required here due to floating point issues const localProgress = Math.min(1.0, progress - currentLength); window.assert(localProgress >= 0.0, "Invalid local progress: " + localProgress); const localSpace = beltComp.transformBeltToLocalSpace(localProgress); return this.entityPath[i].components.StaticMapEntity.localTileToWorld(localSpace); } currentLength += localLength; } window.assert(false, "invalid progress: " + progress + " (max: " + this.totalLength + ")"); } /** * * @param {DrawParameters} parameters */ drawDebug(parameters) { if (!parameters.visibleRect.containsRect(this.worldBounds)) { return; } parameters.context.fillStyle = "#d79a25"; parameters.context.strokeStyle = "#d79a25"; parameters.context.beginPath(); for (let i = 0; i < this.entityPath.length; ++i) { const entity = this.entityPath[i]; const pos = entity.components.StaticMapEntity; const worldPos = pos.origin.toWorldSpaceCenterOfTile(); if (i === 0) { parameters.context.moveTo(worldPos.x, worldPos.y); } else { parameters.context.lineTo(worldPos.x, worldPos.y); } } parameters.context.stroke(); // Items let progress = this.spacingToFirstItem; for (let i = 0; i < this.items.length; ++i) { const nextDistanceAndItem = this.items[i]; const worldPos = this.computePositionFromProgress(progress).toWorldSpaceCenterOfTile(); parameters.context.fillStyle = "#268e4d"; parameters.context.beginRoundedRect(worldPos.x - 5, worldPos.y - 5, 10, 10, 3); parameters.context.fill(); parameters.context.font = "6px GameFont"; parameters.context.fillStyle = "#111"; parameters.context.fillText( "" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_4__["round4Digits"])(nextDistanceAndItem[_nextDistance]), worldPos.x + 5, worldPos.y + 2 ); progress += nextDistanceAndItem[_nextDistance]; } for (let i = 0; i < this.entityPath.length; ++i) { const entity = this.entityPath[i]; parameters.context.fillStyle = "#d79a25"; const pos = entity.components.StaticMapEntity; const worldPos = pos.origin.toWorldSpaceCenterOfTile(); parameters.context.beginCircle(worldPos.x, worldPos.y, i === 0 ? 5 : 3); parameters.context.fill(); } for (let progress = 0; progress <= this.totalLength + 0.01; progress += 0.2) { const worldPos = this.computePositionFromProgress(progress).toWorldSpaceCenterOfTile(); parameters.context.fillStyle = "red"; parameters.context.beginCircle(worldPos.x, worldPos.y, 1); parameters.context.fill(); } const firstItemIndicator = this.computePositionFromProgress( this.spacingToFirstItem ).toWorldSpaceCenterOfTile(); parameters.context.fillStyle = "purple"; parameters.context.fillRect(firstItemIndicator.x - 3, firstItemIndicator.y - 1, 6, 2); } /** * Draws the path * @param {DrawParameters} parameters */ draw(parameters) { if (!parameters.visibleRect.containsRect(this.worldBounds)) { return; } if (this.items.length === 0) { // Early out return; } let currentItemPos = this.spacingToFirstItem; let currentItemIndex = 0; let trackPos = 0.0; // Iterate whole track and check items for (let i = 0; i < this.entityPath.length; ++i) { const entity = this.entityPath[i]; const beltComp = entity.components.Belt; const beltLength = beltComp.getEffectiveLengthTiles(); // Check if the current items are on the belt while (trackPos + beltLength >= currentItemPos - 1e-5) { // Its on the belt, render it now const staticComp = entity.components.StaticMapEntity; window.assert( currentItemPos - trackPos >= 0, "invalid track pos: " + currentItemPos + " vs " + trackPos + " (l =" + beltLength + ")" ); const localPos = beltComp.transformBeltToLocalSpace(currentItemPos - trackPos); const worldPos = staticComp.localTileToWorld(localPos).toWorldSpaceCenterOfTile(); const distanceAndItem = this.items[currentItemIndex]; distanceAndItem[_item].drawItemCenteredClipped( worldPos.x, worldPos.y, parameters, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter ); // Check for the next item currentItemPos += distanceAndItem[_nextDistance]; ++currentItemIndex; if (currentItemIndex >= this.items.length) { // We rendered all items return; } } trackPos += beltLength; } } } /***/ }), /***/ "./src/js/game/blueprint.js": /*!**********************************!*\ !*** ./src/js/game/blueprint.js ***! \**********************************/ /*! exports provided: Blueprint */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Blueprint", function() { return Blueprint; }); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("blueprint"); class Blueprint { /** * @param {Array} entities */ constructor(entities) { this.entities = entities; } /** * Returns the layer of this blueprint * @returns {Layer} */ get layer() { if (this.entities.length === 0) { return "regular"; } return this.entities[0].layer; } /** * Creates a new blueprint from the given entity uids * @param {GameRoot} root * @param {Array} uids */ static fromUids(root, uids) { const newEntities = []; let averagePosition = new _core_vector__WEBPACK_IMPORTED_MODULE_3__["Vector"](); // First, create a copy for (let i = 0; i < uids.length; ++i) { const entity = root.entityMgr.findByUid(uids[i]); window.assert(entity, "Entity for blueprint not found:" + uids[i]); const clone = entity.duplicateWithoutContents(); newEntities.push(clone); const pos = entity.components.StaticMapEntity.getTileSpaceBounds().getCenter(); averagePosition.addInplace(pos); } averagePosition.divideScalarInplace(uids.length); const blueprintOrigin = averagePosition.subScalars(0.5, 0.5).floor(); for (let i = 0; i < uids.length; ++i) { newEntities[i].components.StaticMapEntity.origin.subInplace(blueprintOrigin); } // Now, make sure the origin is 0,0 return new Blueprint(newEntities); } /** * Returns the cost of this blueprint in shapes */ getCost() { if (_core_config__WEBPACK_IMPORTED_MODULE_8__["globalConfig"].debug.blueprintsNoCost) { return 0; } return Object(_core_utils__WEBPACK_IMPORTED_MODULE_6__["findNiceIntegerValue"])(4 * Math.pow(this.entities.length, 1.1)); } /** * Draws the blueprint at the given origin * @param {DrawParameters} parameters */ draw(parameters, tile) { parameters.context.globalAlpha = 0.8; for (let i = 0; i < this.entities.length; ++i) { const entity = this.entities[i]; const staticComp = entity.components.StaticMapEntity; const newPos = staticComp.origin.add(tile); const rect = staticComp.getTileSpaceBounds(); rect.moveBy(tile.x, tile.y); if (!parameters.root.logic.checkCanPlaceEntity(entity, tile)) { parameters.context.globalAlpha = 0.3; } else { parameters.context.globalAlpha = 1; } staticComp.drawSpriteOnBoundsClipped(parameters, staticComp.getBlueprintSprite(), 0, newPos); } parameters.context.globalAlpha = 1; } /** * Rotates the blueprint clockwise */ rotateCw() { for (let i = 0; i < this.entities.length; ++i) { const entity = this.entities[i]; const staticComp = entity.components.StaticMapEntity; staticComp.rotation = (staticComp.rotation + 90) % 360; staticComp.originalRotation = (staticComp.originalRotation + 90) % 360; staticComp.origin = staticComp.origin.rotateFastMultipleOf90(90); } } /** * Rotates the blueprint counter clock wise */ rotateCcw() { // Well ... for (let i = 0; i < 3; ++i) { this.rotateCw(); } } /** * Checks if the blueprint can be placed at the given tile * @param {GameRoot} root * @param {Vector} tile */ canPlace(root, tile) { let anyPlaceable = false; for (let i = 0; i < this.entities.length; ++i) { const entity = this.entities[i]; if (root.logic.checkCanPlaceEntity(entity, tile)) { anyPlaceable = true; } } return anyPlaceable; } /** * @param {GameRoot} root */ canAfford(root) { return root.hubGoals.getShapesStoredByKey(_upgrades__WEBPACK_IMPORTED_MODULE_7__["blueprintShape"]) >= this.getCost(); } /** * Attempts to place the blueprint at the given tile * @param {GameRoot} root * @param {Vector} tile */ tryPlace(root, tile) { return root.logic.performBulkOperation(() => { let anyPlaced = false; for (let i = 0; i < this.entities.length; ++i) { const entity = this.entities[i]; if (!root.logic.checkCanPlaceEntity(entity, tile)) { continue; } const clone = entity.duplicateWithoutContents(); clone.components.StaticMapEntity.origin.addInplace(tile); root.logic.freeEntityAreaBeforeBuild(clone); root.map.placeStaticEntity(clone); root.entityMgr.registerEntity(clone); anyPlaced = true; } return anyPlaced; }); } } /***/ }), /***/ "./src/js/game/building_codes.js": /*!***************************************!*\ !*** ./src/js/game/building_codes.js ***! \***************************************/ /*! exports provided: gBuildingVariants, registerBuildingVariant, getBuildingDataFromCode, getCodeFromBuildingData */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gBuildingVariants", function() { return gBuildingVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "registerBuildingVariant", function() { return registerBuildingVariant; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBuildingDataFromCode", function() { return getBuildingDataFromCode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCodeFromBuildingData", function() { return getCodeFromBuildingData; }); /** * @typedef {{ * metaClass: typeof MetaBuilding, * metaInstance?: MetaBuilding, * variant?: string, * rotationVariant?: number, * tileSize?: Vector, * sprite?: AtlasSprite, * blueprintSprite?: AtlasSprite, * silhouetteColor?: string * }} BuildingVariantIdentifier */ /** * Stores a lookup table for all building variants (for better performance) * @type {Object} */ const gBuildingVariants = { // Set later }; /** * Registers a new variant * @param {number} id * @param {typeof MetaBuilding} meta * @param {string} variant * @param {number} rotationVariant */ function registerBuildingVariant( id, meta, variant = "default" /* FIXME: Circular dependency, actually its defaultBuildingVariant */, rotationVariant = 0 ) { window.assert(!gBuildingVariants[id], "Duplicate id: " + id); gBuildingVariants[id] = { metaClass: meta, variant, rotationVariant, // @ts-ignore tileSize: new meta().getDimensions(variant), }; } /** * * @param {number} code * @returns {BuildingVariantIdentifier} */ function getBuildingDataFromCode(code) { window.assert(gBuildingVariants[code], "Invalid building code: " + code); return gBuildingVariants[code]; } /** * Finds the code for a given variant * @param {MetaBuilding} metaBuilding * @param {string} variant * @param {number} rotationVariant */ function getCodeFromBuildingData(metaBuilding, variant, rotationVariant) { for (const key in gBuildingVariants) { const data = gBuildingVariants[key]; if ( data.metaInstance.getId() === metaBuilding.getId() && data.variant === variant && data.rotationVariant === rotationVariant ) { return +key; } } window.assert( false, "Building not found by data: " + metaBuilding.getId() + " / " + variant + " / " + rotationVariant ); return 0; } /***/ }), /***/ "./src/js/game/buildings/belt.js": /*!***************************************!*\ !*** ./src/js/game/buildings/belt.js ***! \***************************************/ /*! exports provided: MetaBeltBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaBeltBuilding", function() { return MetaBeltBuilding; }); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _belt_base__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./belt_base */ "./src/js/game/buildings/belt_base.js"); class MetaBeltBuilding extends _belt_base__WEBPACK_IMPORTED_MODULE_3__["MetaBeltBaseBuilding"] { constructor() { super("belt"); } getSilhouetteColor() { return "#777"; } getPlacementSound() { return _platform_sound__WEBPACK_IMPORTED_MODULE_2__["SOUNDS"].placeBelt; } getPreviewSprite(rotationVariant) { switch (_belt_base__WEBPACK_IMPORTED_MODULE_3__["arrayBeltVariantToRotation"][rotationVariant]) { case _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/belt_top.png"); } case _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/belt_left.png"); } case _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/belt_right.png"); } default: { window.assert(false, "Invalid belt rotation variant"); } } } getBlueprintSprite(rotationVariant) { switch (_belt_base__WEBPACK_IMPORTED_MODULE_3__["arrayBeltVariantToRotation"][rotationVariant]) { case _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/belt_top.png"); } case _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/belt_left.png"); } case _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/belt_right.png"); } default: { window.assert(false, "Invalid belt rotation variant"); } } } } /***/ }), /***/ "./src/js/game/buildings/belt_base.js": /*!********************************************!*\ !*** ./src/js/game/buildings/belt_base.js ***! \********************************************/ /*! exports provided: arrayBeltVariantToRotation, beltOverlayMatrices, MetaBeltBaseBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "arrayBeltVariantToRotation", function() { return arrayBeltVariantToRotation; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "beltOverlayMatrices", function() { return beltOverlayMatrices; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaBeltBaseBuilding", function() { return MetaBeltBaseBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_belt__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/belt */ "./src/js/game/components/belt.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); const arrayBeltVariantToRotation = [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right]; const beltOverlayMatrices = { [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["generateMatrixRotations"])([0, 1, 0, 0, 1, 0, 0, 1, 0]), [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["generateMatrixRotations"])([0, 0, 0, 1, 1, 0, 0, 1, 0]), [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["generateMatrixRotations"])([0, 0, 0, 0, 1, 1, 0, 1, 0]), }; class MetaBeltBaseBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_6__["MetaBuilding"] { getHasDirectionLockAvailable() { return true; } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const beltSpeed = root.hubGoals.getBeltBaseSpeed(); return [[_translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(beltSpeed)]]; } getStayInPlacementMode() { return true; } getRotateAutomaticallyWhilePlacing() { return true; } getPlacementSound() { return _platform_sound__WEBPACK_IMPORTED_MODULE_2__["SOUNDS"].placeBelt; } getSprite() { return null; } getIsReplaceable() { return true; } /** * * @param {number} rotation * @param {number} rotationVariant * @param {string} variant * @param {Entity} entity */ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { return beltOverlayMatrices[entity.components.Belt.direction][rotation]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_belt__WEBPACK_IMPORTED_MODULE_4__["BeltComponent"]({ direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, // updated later }) ); } /** * * @param {Entity} entity * @param {number} rotationVariant */ updateVariants(entity, rotationVariant) { entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant]; } /** * Should compute the optimal rotation variant on the given tile * @param {object} param0 * @param {GameRoot} param0.root * @param {Vector} param0.tile * @param {number} param0.rotation * @param {string} param0.variant * @param {Layer} param0.layer * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }} */ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { const topDirection = _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumAngleToDirection"][rotation]; const rightDirection = _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumAngleToDirection"][(rotation + 90) % 360]; const bottomDirection = _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumAngleToDirection"][(rotation + 180) % 360]; const leftDirection = _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumAngleToDirection"][(rotation + 270) % 360]; const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile); let hasBottomEjector = false; let hasRightEjector = false; let hasLeftEjector = false; let hasTopAcceptor = false; let hasLeftAcceptor = false; let hasRightAcceptor = false; // Check all ejectors for (let i = 0; i < ejectors.length; ++i) { const ejector = ejectors[i]; if (ejector.toDirection === topDirection) { hasBottomEjector = true; } else if (ejector.toDirection === leftDirection) { hasRightEjector = true; } else if (ejector.toDirection === rightDirection) { hasLeftEjector = true; } } // Check all acceptors for (let i = 0; i < acceptors.length; ++i) { const acceptor = acceptors[i]; if (acceptor.fromDirection === bottomDirection) { hasTopAcceptor = true; } else if (acceptor.fromDirection === rightDirection) { hasLeftAcceptor = true; } else if (acceptor.fromDirection === leftDirection) { hasRightAcceptor = true; } } // Soo .. if there is any ejector below us we always prioritize // this ejector if (!hasBottomEjector) { // When something ejects to us from the left and nothing from the right, // do a curve from the left to the top if (hasRightEjector && !hasLeftEjector) { return { rotation: (rotation + 270) % 360, rotationVariant: 2, }; } // When something ejects to us from the right and nothing from the left, // do a curve from the right to the top if (hasLeftEjector && !hasRightEjector) { return { rotation: (rotation + 90) % 360, rotationVariant: 1, }; } } // When there is a top acceptor, ignore sides // NOTICE: This makes the belt prefer side turns *way* too much! if (!hasTopAcceptor) { // When there is an acceptor to the right but no acceptor to the left, // do a turn to the right if (hasRightAcceptor && !hasLeftAcceptor) { return { rotation, rotationVariant: 2, }; } // When there is an acceptor to the left but no acceptor to the right, // do a turn to the left if (hasLeftAcceptor && !hasRightAcceptor) { return { rotation, rotationVariant: 1, }; } } return { rotation, rotationVariant: 0, }; } } /***/ }), /***/ "./src/js/game/buildings/constant_signal.js": /*!**************************************************!*\ !*** ./src/js/game/buildings/constant_signal.js ***! \**************************************************/ /*! exports provided: MetaConstantSignalBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaConstantSignalBuilding", function() { return MetaConstantSignalBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _components_constant_signal__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/constant_signal */ "./src/js/game/components/constant_signal.js"); class MetaConstantSignalBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_3__["MetaBuilding"] { constructor() { super("constant_signal"); } getSilhouetteColor() { return "#2bafda"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } /** @returns {"wires"} **/ getLayer() { return "wires"; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["WiredPinsComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalEjector, }, ], }) ); entity.addComponent(new _components_constant_signal__WEBPACK_IMPORTED_MODULE_5__["ConstantSignalComponent"]({})); } } /***/ }), /***/ "./src/js/game/buildings/cutter.js": /*!*****************************************!*\ !*** ./src/js/game/buildings/cutter.js ***! \*****************************************/ /*! exports provided: enumCutterVariants, MetaCutterBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumCutterVariants", function() { return enumCutterVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaCutterBuilding", function() { return MetaCutterBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /** @enum {string} */ const enumCutterVariants = { quad: "quad" }; class MetaCutterBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_7__["MetaBuilding"] { constructor() { super("cutter"); } getSilhouetteColor() { return "#7dcda2"; } getDimensions(variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 1); case enumCutterVariants.quad: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](4, 1); default: window.assert(false, "Unknown splitter variant: " + variant); } } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed( variant === enumCutterVariants.quad ? _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutterQuad : _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutter ); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * @param {GameRoot} root */ getAvailableVariants(root) { if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_cutter_quad)) { return [_meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"], enumCutterVariants.quad]; } return super.getAvailableVariants(root); } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_cutter_and_trash); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutter, }) ); entity.addComponent(new _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__["ItemEjectorComponent"]({})); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "shape", }, ], }) ); } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: { entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, ]); entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutter; break; } case enumCutterVariants.quad: { entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](3, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, ]); entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutterQuad; break; } default: window.assert(false, "Unknown painter variant: " + variant); } } } /***/ }), /***/ "./src/js/game/buildings/display.js": /*!******************************************!*\ !*** ./src/js/game/buildings/display.js ***! \******************************************/ /*! exports provided: MetaDisplayBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaDisplayBuilding", function() { return MetaDisplayBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _components_display__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/display */ "./src/js/game/components/display.js"); class MetaDisplayBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_3__["MetaBuilding"] { constructor() { super("display"); } getSilhouetteColor() { return "#aaaaaa"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getShowWiresLayerPreview() { return true; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["WiredPinsComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, ], }) ); entity.addComponent(new _components_display__WEBPACK_IMPORTED_MODULE_5__["DisplayComponent"]()); } } /***/ }), /***/ "./src/js/game/buildings/filter.js": /*!*****************************************!*\ !*** ./src/js/game/buildings/filter.js ***! \*****************************************/ /*! exports provided: MetaFilterBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaFilterBuilding", function() { return MetaFilterBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _components_lever__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/lever */ "./src/js/game/components/lever.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); class MetaFilterBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_3__["MetaBuilding"] { constructor() { super("filter"); } getSilhouetteColor() { return "#c45c2e"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 1); } getShowWiresLayerPreview() { return true; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["WiredPinsComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, ], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_6__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, ], }) ); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_7__["ItemEjectorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right, }, ], }) ); entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_8__["ItemProcessorComponent"]({ processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_8__["enumItemProcessorTypes"].filter, inputsPerCharge: 1, }) ); } } /***/ }), /***/ "./src/js/game/buildings/hub.js": /*!**************************************!*\ !*** ./src/js/game/buildings/hub.js ***! \**************************************/ /*! exports provided: MetaHubBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaHubBuilding", function() { return MetaHubBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_hub__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/hub */ "./src/js/game/components/hub.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); class MetaHubBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_5__["MetaBuilding"] { constructor() { super("hub"); } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](4, 4); } getSilhouetteColor() { return "#eb5555"; } getIsRotateable() { return false; } getBlueprintSprite() { return null; } getSprite() { // We render it ourself return null; } getIsRemovable() { return false; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent(new _components_hub__WEBPACK_IMPORTED_MODULE_1__["HubComponent"]()); entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].hub, }) ); entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_6__["WiredPinsComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 2), type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_6__["enumPinSlotType"].logicalEjector, direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, }, ], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_2__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 1), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 2), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 1), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 2), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 3), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right], }, ], }) ); } } /***/ }), /***/ "./src/js/game/buildings/lever.js": /*!****************************************!*\ !*** ./src/js/game/buildings/lever.js ***! \****************************************/ /*! exports provided: MetaLeverBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaLeverBuilding", function() { return MetaLeverBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _components_lever__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/lever */ "./src/js/game/components/lever.js"); class MetaLeverBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_3__["MetaBuilding"] { constructor() { super("lever"); } getSilhouetteColor() { // @todo: Render differently based on if its activated or not return "#1a678b"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } getIsRotateable() { return false; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getSprite() { return null; } getShowWiresLayerPreview() { return true; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["WiredPinsComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalEjector, }, ], }) ); entity.addComponent(new _components_lever__WEBPACK_IMPORTED_MODULE_5__["LeverComponent"]({})); } } /***/ }), /***/ "./src/js/game/buildings/logic_gate.js": /*!*********************************************!*\ !*** ./src/js/game/buildings/logic_gate.js ***! \*********************************************/ /*! exports provided: enumLogicGateVariants, enumVariantToGate, MetaLogicGateBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumLogicGateVariants", function() { return enumLogicGateVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumVariantToGate", function() { return enumVariantToGate; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaLogicGateBuilding", function() { return MetaLogicGateBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/logic_gate */ "./src/js/game/components/logic_gate.js"); /** @enum {string} */ const enumLogicGateVariants = { not: "not", xor: "xor", or: "or", transistor: "transistor", }; /** @enum {string} */ const enumVariantToGate = { [_meta_building__WEBPACK_IMPORTED_MODULE_3__["defaultBuildingVariant"]]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].and, [enumLogicGateVariants.not]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].not, [enumLogicGateVariants.xor]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].xor, [enumLogicGateVariants.or]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].or, [enumLogicGateVariants.transistor]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].transistor, }; class MetaLogicGateBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_3__["MetaBuilding"] { constructor() { super("logic_gate"); } getSilhouetteColor() { return "#89dc60"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } /** @returns {"wires"} **/ getLayer() { return "wires"; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getAvailableVariants() { return [ _meta_building__WEBPACK_IMPORTED_MODULE_3__["defaultBuildingVariant"], enumLogicGateVariants.not, enumLogicGateVariants.xor, enumLogicGateVariants.or, enumLogicGateVariants.transistor, ]; } getRenderPins() { // We already have it included return false; } /** * * @param {Entity} entity * @param {number} rotationVariant */ updateVariants(entity, rotationVariant, variant) { const gateType = enumVariantToGate[variant]; entity.components.LogicGate.type = gateType; const pinComp = entity.components.WiredPins; switch (gateType) { case _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].and: case _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].xor: case _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].or: { pinComp.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, ]); break; } case _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].transistor: { pinComp.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, ]); break; } case _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["enumLogicGateType"].not: { pinComp.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["enumPinSlotType"].logicalAcceptor, }, ]); break; } default: window.assert("unknown logic gate type: " + gateType); } } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_1__["WiredPinsComponent"]({ slots: [], }) ); entity.addComponent(new _components_logic_gate__WEBPACK_IMPORTED_MODULE_5__["LogicGateComponent"]({})); } } /***/ }), /***/ "./src/js/game/buildings/miner.js": /*!****************************************!*\ !*** ./src/js/game/buildings/miner.js ***! \****************************************/ /*! exports provided: enumMinerVariants, MetaMinerBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumMinerVariants", function() { return enumMinerVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaMinerBuilding", function() { return MetaMinerBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_miner__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/miner */ "./src/js/game/components/miner.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /** @enum {string} */ const enumMinerVariants = { chainable: "chainable" }; const overlayMatrix = [1, 1, 1, 1, 0, 1, 1, 1, 1]; class MetaMinerBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_4__["MetaBuilding"] { constructor() { super("miner"); } getSilhouetteColor() { return "#b37dcd"; } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getMinerBaseSpeed(); return [[_translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["formatItemsPerSecond"])(speed)]]; } /** * * @param {GameRoot} root */ getAvailableVariants(root) { if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_6__["enumHubGoalRewards"].reward_miner_chainable)) { return [_meta_building__WEBPACK_IMPORTED_MODULE_4__["defaultBuildingVariant"], enumMinerVariants.chainable]; } return super.getAvailableVariants(root); } /** * @param {number} rotation * @param {number} rotationVariant * @param {string} variant * @param {Entity} entity */ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { return overlayMatrix; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent(new _components_miner__WEBPACK_IMPORTED_MODULE_2__["MinerComponent"]({})); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_1__["ItemEjectorComponent"]({ slots: [{ pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }], }) ); } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { entity.components.Miner.chainable = variant === enumMinerVariants.chainable; } } /***/ }), /***/ "./src/js/game/buildings/mixer.js": /*!****************************************!*\ !*** ./src/js/game/buildings/mixer.js ***! \****************************************/ /*! exports provided: MetaMixerBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaMixerBuilding", function() { return MetaMixerBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); class MetaMixerBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_7__["MetaBuilding"] { constructor() { super("mixer"); } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 1); } getSilhouetteColor() { return "#cdbb7d"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_mixer); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].mixer); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]({ inputsPerCharge: 2, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].mixer, }) ); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__["ItemEjectorComponent"]({ slots: [{ pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "color", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "color", }, ], }) ); } } /***/ }), /***/ "./src/js/game/buildings/painter.js": /*!******************************************!*\ !*** ./src/js/game/buildings/painter.js ***! \******************************************/ /*! exports provided: enumPainterVariants, MetaPainterBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumPainterVariants", function() { return enumPainterVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaPainterBuilding", function() { return MetaPainterBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /** @enum {string} */ const enumPainterVariants = { mirrored: "mirrored", double: "double", quad: "quad" }; class MetaPainterBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_7__["MetaBuilding"] { constructor() { super("painter"); } getDimensions(variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: case enumPainterVariants.mirrored: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 1); case enumPainterVariants.double: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 2); case enumPainterVariants.quad: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](4, 1); default: window.assert(false, "Unknown painter variant: " + variant); } } getSilhouetteColor() { return "#cd9b7d"; } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: case enumPainterVariants.mirrored: { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painter); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } case enumPainterVariants.double: { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painterDouble); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed, true)]]; } case enumPainterVariants.quad: { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painterQuad); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } } } /** * @param {GameRoot} root */ getAvailableVariants(root) { let variants = [_meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"], enumPainterVariants.mirrored]; if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_painter_double)) { variants.push(enumPainterVariants.double); } if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_painter_quad)) { variants.push(enumPainterVariants.quad); } return variants; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_painter); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent(new _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]({})); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__["ItemEjectorComponent"]({ slots: [{ pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right }], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left], filter: "shape", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top], filter: "color", }, ], }) ); } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: case enumPainterVariants.mirrored: { entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left], filter: "shape", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), directions: [ variant === _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"] ? _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top : _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom, ], filter: "color", }, ]); entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painter; entity.components.ItemProcessor.inputsPerCharge = 2; entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right }, ]); break; } case enumPainterVariants.double: { entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left], filter: "shape", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 1), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left], filter: "shape", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top], filter: "color", }, ]); entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painterDouble; entity.components.ItemProcessor.inputsPerCharge = 3; entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right }, ]); break; } case enumPainterVariants.quad: { entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left], filter: "shape", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "color", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "color", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "color", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](3, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "color", }, ]); entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painterQuad; entity.components.ItemProcessor.inputsPerCharge = 5; entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }, ]); break; } default: window.assert(false, "Unknown painter variant: " + variant); } } } /***/ }), /***/ "./src/js/game/buildings/rotater.js": /*!******************************************!*\ !*** ./src/js/game/buildings/rotater.js ***! \******************************************/ /*! exports provided: enumRotaterVariants, MetaRotaterBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumRotaterVariants", function() { return enumRotaterVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaRotaterBuilding", function() { return MetaRotaterBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /** @enum {string} */ const enumRotaterVariants = { ccw: "ccw", fl: "fl" }; class MetaRotaterBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_7__["MetaBuilding"] { constructor() { super("rotater"); } getSilhouetteColor() { return "#7dc6cd"; } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotater); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } case enumRotaterVariants.ccw: { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotaterCCW); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } case enumRotaterVariants.fl: { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotaterFL); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } } } /** * * @param {GameRoot} root */ getAvailableVariants(root) { let variants = [_meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]]; if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_rotater_ccw)) { variants.push(enumRotaterVariants.ccw); } if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_rotater_fl)) { variants.push(enumRotaterVariants.fl); } return variants; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_rotater); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotater, }) ); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__["ItemEjectorComponent"]({ slots: [{ pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "shape", }, ], }) ); } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_7__["defaultBuildingVariant"]: { entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotater; break; } case enumRotaterVariants.ccw: { entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotaterCCW; break; } case enumRotaterVariants.fl: { entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotaterFL; break; } default: window.assert(false, "Unknown rotater variant: " + variant); } } } /***/ }), /***/ "./src/js/game/buildings/splitter.js": /*!*******************************************!*\ !*** ./src/js/game/buildings/splitter.js ***! \*******************************************/ /*! exports provided: enumSplitterVariants, MetaSplitterBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumSplitterVariants", function() { return enumSplitterVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaSplitterBuilding", function() { return MetaSplitterBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _components_belt_underlays__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../components/belt_underlays */ "./src/js/game/components/belt_underlays.js"); /** @enum {string} */ const enumSplitterVariants = { compact: "compact", compactInverse: "compact-inverse" }; class MetaSplitterBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_5__["MetaBuilding"] { constructor() { super("splitter"); } getDimensions(variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_5__["defaultBuildingVariant"]: return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 1); case enumSplitterVariants.compact: case enumSplitterVariants.compactInverse: return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); default: window.assert(false, "Unknown splitter variant: " + variant); } } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].splitter); return [[_translations__WEBPACK_IMPORTED_MODULE_8__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_9__["formatItemsPerSecond"])(speed)]]; } getSilhouetteColor() { return "#444"; } /** * @param {GameRoot} root */ getAvailableVariants(root) { if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_7__["enumHubGoalRewards"].reward_splitter_compact)) { return [ _meta_building__WEBPACK_IMPORTED_MODULE_5__["defaultBuildingVariant"], enumSplitterVariants.compact, enumSplitterVariants.compactInverse, ]; } return super.getAvailableVariants(root); } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_7__["enumHubGoalRewards"].reward_splitter); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_1__["ItemAcceptorComponent"]({ slots: [], // set later }) ); entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].splitter, }) ); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_2__["ItemEjectorComponent"]({ slots: [], // set later }) ); entity.addComponent(new _components_belt_underlays__WEBPACK_IMPORTED_MODULE_10__["BeltUnderlaysComponent"]({ underlays: [] })); } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_5__["defaultBuildingVariant"]: { entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, ]); entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }, ]); entity.components.BeltUnderlays.underlays = [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }, ]; break; } case enumSplitterVariants.compact: case enumSplitterVariants.compactInverse: { entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [ variant === enumSplitterVariants.compactInverse ? _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left : _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right, ], }, ]); entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }, ]); entity.components.BeltUnderlays.underlays = [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }, ]; break; } default: window.assert(false, "Unknown painter variant: " + variant); } } } /***/ }), /***/ "./src/js/game/buildings/stacker.js": /*!******************************************!*\ !*** ./src/js/game/buildings/stacker.js ***! \******************************************/ /*! exports provided: MetaStackerBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaStackerBuilding", function() { return MetaStackerBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); class MetaStackerBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_7__["MetaBuilding"] { constructor() { super("stacker"); } getSilhouetteColor() { return "#9fcd7d"; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 1); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].stacker); return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_stacker); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]({ inputsPerCharge: 2, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].stacker, }) ); entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__["ItemEjectorComponent"]({ slots: [{ pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top }], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "shape", }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], filter: "shape", }, ], }) ); } } /***/ }), /***/ "./src/js/game/buildings/toolbar_swapper.js": /*!**************************************************!*\ !*** ./src/js/game/buildings/toolbar_swapper.js ***! \**************************************************/ /*! exports provided: MetaToolbarSwapperBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaToolbarSwapperBuilding", function() { return MetaToolbarSwapperBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); class MetaToolbarSwapperBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_7__["MetaBuilding"] { constructor() { super("toolbar_swapper"); } getSilhouetteColor() { return "black"; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { return []; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return true; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) {} } /***/ }), /***/ "./src/js/game/buildings/trash.js": /*!****************************************!*\ !*** ./src/js/game/buildings/trash.js ***! \****************************************/ /*! exports provided: enumTrashVariants, MetaTrashBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumTrashVariants", function() { return enumTrashVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaTrashBuilding", function() { return MetaTrashBuilding; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _components_storage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/storage */ "./src/js/game/components/storage.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /** @enum {string} */ const enumTrashVariants = { storage: "storage" }; const trashSize = 5000; class MetaTrashBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_9__["MetaBuilding"] { constructor() { super("trash"); } getIsRotateable(variant) { return variant !== _meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"]; } getSilhouetteColor() { return "#cd7d86"; } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { if (variant === enumTrashVariants.storage) { return [[_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.buildingPlacement.infoTexts.storage, Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["formatBigNumber"])(trashSize)]]; } return []; } getDimensions(variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"]: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 1); case enumTrashVariants.storage: return new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](2, 2); default: window.assert(false, "Unknown trash variant: " + variant); } } /** * @param {GameRoot} root */ getAvailableVariants(root) { if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_11__["enumHubGoalRewards"].reward_storage)) { return [_meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"], enumTrashVariants.storage]; } return super.getAvailableVariants(root); } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_11__["enumHubGoalRewards"].reward_cutter_and_trash); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { // Required, since the item processor needs this. entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_4__["ItemEjectorComponent"]({ slots: [], }) ); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_3__["ItemAcceptorComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [ _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left, ], }, ], }) ); } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { switch (variant) { case _meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"]: { if (!entity.components.ItemProcessor) { entity.addComponent( new _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].trash, }) ); } if (entity.components.Storage) { entity.removeComponent(_components_storage__WEBPACK_IMPORTED_MODULE_6__["StorageComponent"]); } if (entity.components.WiredPins) { entity.removeComponent(_components_wired_pins__WEBPACK_IMPORTED_MODULE_7__["WiredPinsComponent"]); } entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [ _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom, _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left, ], }, ]); entity.components.ItemEjector.setSlots([]); entity.components.ItemProcessor.type = _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].trash; break; } case enumTrashVariants.storage: { if (entity.components.ItemProcessor) { entity.removeComponent(_components_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorComponent"]); } if (!entity.components.Storage) { entity.addComponent(new _components_storage__WEBPACK_IMPORTED_MODULE_6__["StorageComponent"]({})); } if (!entity.components.WiredPins) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_7__["WiredPinsComponent"]({ slots: [ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 1), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].right, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_7__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 1), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].left, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_7__["enumPinSlotType"].logicalEjector, }, ], }) ); } entity.components.Storage.maximumStorage = trashSize; entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 1), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 1), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], }, ]); entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](1, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, }, ]); break; } default: window.assert(false, "Unknown trash variant: " + variant); } } } /***/ }), /***/ "./src/js/game/buildings/underground_belt.js": /*!***************************************************!*\ !*** ./src/js/game/buildings/underground_belt.js ***! \***************************************************/ /*! exports provided: arrayUndergroundRotationVariantToMode, enumUndergroundBeltVariants, enumUndergroundBeltVariantToTier, MetaUndergroundBeltBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "arrayUndergroundRotationVariantToMode", function() { return arrayUndergroundRotationVariantToMode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumUndergroundBeltVariants", function() { return enumUndergroundBeltVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumUndergroundBeltVariantToTier", function() { return enumUndergroundBeltVariantToTier; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaUndergroundBeltBuilding", function() { return MetaUndergroundBeltBuilding; }); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/underground_belt */ "./src/js/game/components/underground_belt.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /** @enum {string} */ const arrayUndergroundRotationVariantToMode = [ _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].sender, _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].receiver, ]; /** @enum {string} */ const enumUndergroundBeltVariants = { tier2: "tier2" }; const enumUndergroundBeltVariantToTier = { [_meta_building__WEBPACK_IMPORTED_MODULE_6__["defaultBuildingVariant"]]: 0, [enumUndergroundBeltVariants.tier2]: 1, }; const overlayMatrices = [ // Sender Object(_core_utils__WEBPACK_IMPORTED_MODULE_10__["generateMatrixRotations"])([1, 1, 1, 0, 1, 0, 0, 1, 0]), // Receiver Object(_core_utils__WEBPACK_IMPORTED_MODULE_10__["generateMatrixRotations"])([0, 1, 0, 0, 1, 0, 1, 1, 1]), ]; class MetaUndergroundBeltBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_6__["MetaBuilding"] { constructor() { super("underground_belt"); } getSilhouetteColor() { return "#222"; } getFlipOrientationAfterPlacement() { return true; } getStayInPlacementMode() { return true; } /** * @param {number} rotation * @param {number} rotationVariant * @param {string} variant * @param {Entity} entity */ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { return overlayMatrices[rotationVariant][rotation]; } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const rangeTiles = _core_config__WEBPACK_IMPORTED_MODULE_8__["globalConfig"].undergroundBeltMaxTilesByTier[enumUndergroundBeltVariantToTier[variant]]; const beltSpeed = root.hubGoals.getUndergroundBeltBaseSpeed(); return [ [ _translations__WEBPACK_IMPORTED_MODULE_11__["T"].ingame.buildingPlacement.infoTexts.range, _translations__WEBPACK_IMPORTED_MODULE_11__["T"].ingame.buildingPlacement.infoTexts.tiles.replace("", "" + rangeTiles), ], [_translations__WEBPACK_IMPORTED_MODULE_11__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_core_utils__WEBPACK_IMPORTED_MODULE_10__["formatItemsPerSecond"])(beltSpeed)], ]; } /** * @param {GameRoot} root */ getAvailableVariants(root) { if (root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_underground_belt_tier_2)) { return [_meta_building__WEBPACK_IMPORTED_MODULE_6__["defaultBuildingVariant"], enumUndergroundBeltVariants.tier2]; } return super.getAvailableVariants(root); } /** * @param {number} rotationVariant * @param {string} variant */ getPreviewSprite(rotationVariant, variant) { let suffix = ""; if (variant !== _meta_building__WEBPACK_IMPORTED_MODULE_6__["defaultBuildingVariant"]) { suffix = "-" + variant; } switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { case _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].sender: return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/underground_belt_entry" + suffix + ".png"); case _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].receiver: return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/underground_belt_exit" + suffix + ".png"); default: window.assert(false, "Invalid rotation variant"); } } /** * @param {number} rotationVariant * @param {string} variant */ getBlueprintSprite(rotationVariant, variant) { let suffix = ""; if (variant !== _meta_building__WEBPACK_IMPORTED_MODULE_6__["defaultBuildingVariant"]) { suffix = "-" + variant; } switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { case _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].sender: return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/underground_belt_entry" + suffix + ".png"); case _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].receiver: return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/underground_belt_exit" + suffix + ".png"); default: window.assert(false, "Invalid rotation variant"); } } /** * @param {number} rotationVariant * @param {string} variant */ getSprite(rotationVariant, variant) { return this.getPreviewSprite(rotationVariant, variant); } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewards"].reward_tunnel); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { // Required, since the item processor needs this. entity.addComponent( new _components_item_ejector__WEBPACK_IMPORTED_MODULE_3__["ItemEjectorComponent"]({ slots: [], }) ); entity.addComponent(new _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["UndergroundBeltComponent"]({})); entity.addComponent( new _components_item_acceptor__WEBPACK_IMPORTED_MODULE_2__["ItemAcceptorComponent"]({ slots: [], }) ); } /** * Should compute the optimal rotation variant on the given tile * @param {object} param0 * @param {GameRoot} param0.root * @param {Vector} param0.tile * @param {number} param0.rotation * @param {string} param0.variant * @param {Layer} param0.layer * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }} */ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { const searchDirection = _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumAngleToDirection"][rotation]; const searchVector = _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirectionToVector"][searchDirection]; const tier = enumUndergroundBeltVariantToTier[variant]; const targetRotation = (rotation + 180) % 360; const targetSenderRotation = rotation; for ( let searchOffset = 1; searchOffset <= _core_config__WEBPACK_IMPORTED_MODULE_8__["globalConfig"].undergroundBeltMaxTilesByTier[tier]; ++searchOffset ) { tile = tile.addScalars(searchVector.x, searchVector.y); /* WIRES: FIXME */ const contents = root.map.getTileContent(tile, "regular"); if (contents) { const undergroundComp = contents.components.UndergroundBelt; if (undergroundComp && undergroundComp.tier === tier) { const staticComp = contents.components.StaticMapEntity; if (staticComp.rotation === targetRotation) { if (undergroundComp.mode !== _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].sender) { // If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that break; } return { rotation: targetRotation, rotationVariant: 1, connectedEntities: [contents], }; } else if (staticComp.rotation === targetSenderRotation) { // Draw connections to receivers if (undergroundComp.mode === _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].receiver) { return { rotation: rotation, rotationVariant: 0, connectedEntities: [contents], }; } else { break; } } } } } return { rotation, rotationVariant: 0, }; } /** * * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant]; switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { case _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].sender: { entity.components.UndergroundBelt.mode = _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].sender; entity.components.ItemEjector.setSlots([]); entity.components.ItemAcceptor.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].bottom], }, ]); return; } case _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].receiver: { entity.components.UndergroundBelt.mode = _components_underground_belt__WEBPACK_IMPORTED_MODULE_4__["enumUndergroundBeltMode"].receiver; entity.components.ItemAcceptor.setSlots([]); entity.components.ItemEjector.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_1__["enumDirection"].top, }, ]); return; } default: window.assert(false, "Invalid rotation variant"); } } } /***/ }), /***/ "./src/js/game/buildings/virtual_processor.js": /*!****************************************************!*\ !*** ./src/js/game/buildings/virtual_processor.js ***! \****************************************************/ /*! exports provided: enumVirtualProcessorVariants, enumVariantToGate, MetaVirtualProcessorBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumVirtualProcessorVariants", function() { return enumVirtualProcessorVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumVariantToGate", function() { return enumVariantToGate; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaVirtualProcessorBuilding", function() { return MetaVirtualProcessorBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/logic_gate */ "./src/js/game/components/logic_gate.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /** @enum {string} */ const enumVirtualProcessorVariants = { analyzer: "analyzer", rotater: "rotater", unstacker: "unstacker", shapecompare: "shapecompare", adder: "adder", }; /** @enum {string} */ const enumVariantToGate = { [_meta_building__WEBPACK_IMPORTED_MODULE_4__["defaultBuildingVariant"]]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].cutter, [enumVirtualProcessorVariants.analyzer]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].analyzer, [enumVirtualProcessorVariants.rotater]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].rotater, [enumVirtualProcessorVariants.unstacker]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].unstacker, [enumVirtualProcessorVariants.shapecompare]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].shapecompare, [enumVirtualProcessorVariants.adder]: _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].adder, }; class MetaVirtualProcessorBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_4__["MetaBuilding"] { constructor() { super("virtual_processor"); } getSilhouetteColor() { return "#823cab"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } /** @returns {"wires"} **/ getLayer() { return "wires"; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getAvailableVariants() { return [ _meta_building__WEBPACK_IMPORTED_MODULE_4__["defaultBuildingVariant"], enumVirtualProcessorVariants.rotater, enumVirtualProcessorVariants.unstacker, enumVirtualProcessorVariants.analyzer, enumVirtualProcessorVariants.shapecompare, enumVirtualProcessorVariants.adder, ]; } getRenderPins() { // We already have it included return false; } /** * * @param {Entity} entity * @param {number} rotationVariant */ updateVariants(entity, rotationVariant, variant) { const gateType = enumVariantToGate[variant]; entity.components.LogicGate.type = gateType; const pinComp = entity.components.WiredPins; switch (gateType) { case _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].cutter: case _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].analyzer: case _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].unstacker: { pinComp.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalAcceptor, }, ]); break; } case _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].rotater: { pinComp.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalAcceptor, }, ]); break; } case _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].adder: case _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["enumLogicGateType"].shapecompare: { pinComp.setSlots([ { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalEjector, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalAcceptor, }, { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right, type: _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["enumPinSlotType"].logicalAcceptor, }, ]); break; } default: window.assert("unknown logic gate type: " + gateType); } } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _components_wired_pins__WEBPACK_IMPORTED_MODULE_2__["WiredPinsComponent"]({ slots: [], }) ); entity.addComponent(new _components_logic_gate__WEBPACK_IMPORTED_MODULE_1__["LogicGateComponent"]({})); } } /***/ }), /***/ "./src/js/game/buildings/wire.js": /*!***************************************!*\ !*** ./src/js/game/buildings/wire.js ***! \***************************************/ /*! exports provided: arrayWireRotationVariantToType, wireOverlayMatrices, MetaWireBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "arrayWireRotationVariantToType", function() { return arrayWireRotationVariantToType; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wireOverlayMatrices", function() { return wireOverlayMatrices; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaWireBuilding", function() { return MetaWireBuilding; }); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _components_wire__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/wire */ "./src/js/game/components/wire.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); const arrayWireRotationVariantToType = [ _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].regular, _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn, _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split, _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].cross, ]; const wireOverlayMatrices = { [_components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].regular]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["generateMatrixRotations"])([0, 1, 0, 0, 1, 0, 0, 1, 0]), [_components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["generateMatrixRotations"])([0, 0, 0, 1, 1, 1, 0, 1, 0]), [_components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["generateMatrixRotations"])([0, 0, 0, 0, 1, 1, 0, 1, 0]), [_components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].cross]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["generateMatrixRotations"])([0, 1, 0, 1, 1, 1, 0, 1, 0]), }; class MetaWireBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_6__["MetaBuilding"] { constructor() { super("wire"); } getHasDirectionLockAvailable() { return true; } getSilhouetteColor() { return "#25fff2"; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](1, 1); } getStayInPlacementMode() { return true; } getPlacementSound() { return _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].placeBelt; } getRotateAutomaticallyWhilePlacing() { return true; } /** @returns {"wires"} **/ getLayer() { return "wires"; } getSprite() { return null; } getIsReplaceable() { return true; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { // @todo entity.addComponent(new _components_wire__WEBPACK_IMPORTED_MODULE_4__["WireComponent"]({})); } /** * * @param {Entity} entity * @param {number} rotationVariant */ updateVariants(entity, rotationVariant) { entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant]; } /** * * @param {number} rotation * @param {number} rotationVariant * @param {string} variant * @param {Entity} entity */ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { return wireOverlayMatrices[entity.components.Wire.type][rotation]; } getPreviewSprite(rotationVariant) { switch (arrayWireRotationVariantToType[rotationVariant]) { case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].regular: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/wire.png"); } case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/wire-turn.png"); } case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/wire-split.png"); } case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].cross: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/buildings/wire-cross.png"); } default: { window.assert(false, "Invalid wire rotation variant"); } } } getBlueprintSprite(rotationVariant) { switch (arrayWireRotationVariantToType[rotationVariant]) { case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].regular: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/wire.png"); } case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/wire-turn.png"); } case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/wire-split.png"); } case _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].cross: { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/blueprints/wire-cross.png"); } default: { window.assert(false, "Invalid wire rotation variant"); } } } /** * Should compute the optimal rotation variant on the given tile * @param {object} param0 * @param {GameRoot} param0.root * @param {Vector} param0.tile * @param {number} param0.rotation * @param {string} param0.variant * @param {string} param0.layer * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }} */ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { const connections = { top: root.logic.computeWireEdgeStatus({ tile, rotation, edge: _core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirection"].top }), right: root.logic.computeWireEdgeStatus({ tile, rotation, edge: _core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirection"].right }), bottom: root.logic.computeWireEdgeStatus({ tile, rotation, edge: _core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirection"].bottom }), left: root.logic.computeWireEdgeStatus({ tile, rotation, edge: _core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirection"].left }), }; let flag = 0; flag |= connections.top ? 0x1000 : 0; flag |= connections.right ? 0x100 : 0; flag |= connections.bottom ? 0x10 : 0; flag |= connections.left ? 0x1 : 0; let targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].regular; // First, reset rotation rotation = 0; switch (flag) { case 0x0000: // Nothing break; case 0x0001: // Left rotation += 90; break; case 0x0010: // Bottom // END break; case 0x0011: // Bottom | Left targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn; rotation += 90; break; case 0x0100: // Right rotation += 90; break; case 0x0101: // Right | Left rotation += 90; break; case 0x0110: // Right | Bottom targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn; break; case 0x0111: // Right | Bottom | Left targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split; break; case 0x1000: // Top break; case 0x1001: // Top | Left targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn; rotation += 180; break; case 0x1010: // Top | Bottom break; case 0x1011: // Top | Bottom | Left targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split; rotation += 90; break; case 0x1100: // Top | Right targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].turn; rotation -= 90; break; case 0x1101: // Top | Right | Left targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split; rotation += 180; break; case 0x1110: // Top | Right | Bottom targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].split; rotation -= 90; break; case 0x1111: // Top | Right | Bottom | Left targetType = _components_wire__WEBPACK_IMPORTED_MODULE_4__["enumWireType"].cross; break; } return { // Clamp rotation rotation: (rotation + 360 * 10) % 360, rotationVariant: arrayWireRotationVariantToType.indexOf(targetType), }; } } /***/ }), /***/ "./src/js/game/buildings/wire_tunnel.js": /*!**********************************************!*\ !*** ./src/js/game/buildings/wire_tunnel.js ***! \**********************************************/ /*! exports provided: enumWireTunnelVariants, MetaWireTunnelBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumWireTunnelVariants", function() { return enumWireTunnelVariants; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaWireTunnelBuilding", function() { return MetaWireTunnelBuilding; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _components_wire_tunnel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/wire_tunnel */ "./src/js/game/components/wire_tunnel.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /** @enum {string} */ const enumWireTunnelVariants = { coating: "coating", }; const wireTunnelOverlayMatrices = { [_meta_building__WEBPACK_IMPORTED_MODULE_2__["defaultBuildingVariant"]]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["generateMatrixRotations"])([0, 1, 0, 1, 1, 1, 0, 1, 0]), [enumWireTunnelVariants.coating]: Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["generateMatrixRotations"])([0, 1, 0, 0, 1, 0, 0, 1, 0]), }; class MetaWireTunnelBuilding extends _meta_building__WEBPACK_IMPORTED_MODULE_2__["MetaBuilding"] { constructor() { super("wire_tunnel"); } getSilhouetteColor() { return "#777a86"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { // @todo return true; } /** * * @param {number} rotation * @param {number} rotationVariant * @param {string} variant * @param {Entity} entity */ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { return wireTunnelOverlayMatrices[variant][rotation]; } getIsRotateable(variant) { return variant !== _meta_building__WEBPACK_IMPORTED_MODULE_2__["defaultBuildingVariant"]; } getDimensions() { return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getAvailableVariants() { return [_meta_building__WEBPACK_IMPORTED_MODULE_2__["defaultBuildingVariant"], enumWireTunnelVariants.coating]; } /** @returns {"wires"} **/ getLayer() { return "wires"; } getRotateAutomaticallyWhilePlacing() { return true; } getStayInPlacementMode() { return true; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent(new _components_wire_tunnel__WEBPACK_IMPORTED_MODULE_4__["WireTunnelComponent"]({})); } /** * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) { entity.components.WireTunnel.multipleDirections = variant === _meta_building__WEBPACK_IMPORTED_MODULE_2__["defaultBuildingVariant"]; } } /***/ }), /***/ "./src/js/game/camera.js": /*!*******************************!*\ !*** ./src/js/game/camera.js ***! \*******************************/ /*! exports provided: USER_INTERACT_MOVE, USER_INTERACT_ZOOM, USER_INTERACT_TOUCHEND, enumMouseButton, Camera */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "USER_INTERACT_MOVE", function() { return USER_INTERACT_MOVE; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "USER_INTERACT_ZOOM", function() { return USER_INTERACT_ZOOM; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "USER_INTERACT_TOUCHEND", function() { return USER_INTERACT_TOUCHEND; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumMouseButton", function() { return enumMouseButton; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return Camera; }); /* harmony import */ var _core_click_detector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("camera"); const USER_INTERACT_MOVE = "move"; const USER_INTERACT_ZOOM = "zoom"; const USER_INTERACT_TOUCHEND = "touchend"; const velocitySmoothing = 0.5; const velocityFade = 0.98; const velocityStrength = 0.4; const velocityMax = 20; const ticksBeforeErasingVelocity = 10; /** * @enum {string} */ const enumMouseButton = { left: "left", middle: "middle", right: "right", }; class Camera extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_7__["BasicSerializableObject"] { constructor(root) { super(); /** @type {GameRoot} */ this.root = root; // Zoom level, 2 means double size // Find optimal initial zoom this.zoomLevel = this.findInitialZoom(); this.clampZoomLevel(); /** @type {Vector} */ this.center = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); // Input handling this.currentlyMoving = false; this.lastMovingPosition = null; this.lastMovingPositionLastTick = null; this.numTicksStandingStill = null; this.cameraUpdateTimeBucket = 0.0; this.didMoveSinceTouchStart = false; this.currentlyPinching = false; this.lastPinchPositions = null; this.keyboardForce = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](); // Signal which gets emitted once the user changed something this.userInteraction = new _core_signal__WEBPACK_IMPORTED_MODULE_4__["Signal"](); /** @type {Vector} */ this.currentShake = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); /** @type {Vector} */ this.currentPan = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); // Set desired pan (camera movement) /** @type {Vector} */ this.desiredPan = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); // Set desired camera center /** @type {Vector} */ this.desiredCenter = null; // Set desired camera zoom /** @type {number} */ this.desiredZoom = null; /** @type {Vector} */ this.touchPostMoveVelocity = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); // Handlers this.downPreHandler = /** @type {TypedSignal<[Vector, enumMouseButton]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_4__["Signal"]()); this.movePreHandler = /** @type {TypedSignal<[Vector]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_4__["Signal"]()); // this.pinchPreHandler = /** @type {TypedSignal<[Vector]>} */ (new Signal()); this.upPostHandler = /** @type {TypedSignal<[Vector]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_4__["Signal"]()); this.internalInitEvents(); this.clampZoomLevel(); this.bindKeys(); if (true) { window.addEventListener("keydown", ev => { if (ev.key === "i") { this.zoomLevel = 3; } }); } } // Serialization static getId() { return "Camera"; } static getSchema() { return { zoomLevel: _savegame_serialization__WEBPACK_IMPORTED_MODULE_7__["types"].float, center: _savegame_serialization__WEBPACK_IMPORTED_MODULE_7__["types"].vector, }; } deserialize(data) { const errorCode = super.deserialize(data); if (errorCode) { return errorCode; } // Safety this.clampZoomLevel(); } // Simple geters & setters addScreenShake(amount) { const currentShakeAmount = this.currentShake.length(); const scale = 1 / (1 + 3 * currentShakeAmount); this.currentShake.x = this.currentShake.x + 2 * (Math.random() - 0.5) * scale * amount; this.currentShake.y = this.currentShake.y + 2 * (Math.random() - 0.5) * scale * amount; } /** * Sets a point in world space to focus on * @param {Vector} center */ setDesiredCenter(center) { this.desiredCenter = center.copy(); this.currentlyMoving = false; } /** * Sets a desired zoom level * @param {number} zoom */ setDesiredZoom(zoom) { this.desiredZoom = zoom; } /** * Returns if this camera is currently moving by a non-user interaction */ isCurrentlyMovingToDesiredCenter() { return this.desiredCenter !== null; } /** * Sets the camera pan, every frame the camera will move by this amount * @param {Vector} pan */ setPan(pan) { this.desiredPan = pan.copy(); } /** * Finds a good initial zoom level */ findInitialZoom() { const desiredWorldSpaceWidth = 15 * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize; const zoomLevelX = this.root.gameWidth / desiredWorldSpaceWidth; const zoomLevelY = this.root.gameHeight / desiredWorldSpaceWidth; const finalLevel = Math.min(zoomLevelX, zoomLevelY); window.assert( Number.isFinite(finalLevel) && finalLevel > 0, "Invalid zoom level computed for initial zoom: " + finalLevel ); return finalLevel; } /** * Clears all animations */ clearAnimations() { this.touchPostMoveVelocity.x = 0; this.touchPostMoveVelocity.y = 0; this.desiredCenter = null; this.desiredPan.x = 0; this.desiredPan.y = 0; this.currentPan.x = 0; this.currentPan.y = 0; this.currentlyPinching = false; this.currentlyMoving = false; this.lastMovingPosition = null; this.didMoveSinceTouchStart = false; this.desiredZoom = null; } /** * Returns if the user is currently interacting with the camera * @returns {boolean} true if the user interacts */ isCurrentlyInteracting() { if (this.currentlyPinching) { return true; } if (this.currentlyMoving) { // Only interacting if moved at least once return this.didMoveSinceTouchStart; } if (this.touchPostMoveVelocity.lengthSquare() > 1) { return true; } return false; } /** * Returns if in the next frame the viewport will change * @returns {boolean} true if it willchange */ viewportWillChange() { return this.desiredCenter !== null || this.desiredZoom !== null || this.isCurrentlyInteracting(); } /** * Cancels all interactions, that is user interaction and non user interaction */ cancelAllInteractions() { this.touchPostMoveVelocity = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); this.desiredCenter = null; this.currentlyMoving = false; this.currentlyPinching = false; this.desiredZoom = null; } /** * Returns effective viewport width */ getViewportWidth() { return this.root.gameWidth / this.zoomLevel; } /** * Returns effective viewport height */ getViewportHeight() { return this.root.gameHeight / this.zoomLevel; } /** * Returns effective world space viewport left */ getViewportLeft() { return this.center.x - this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel; } /** * Returns effective world space viewport right */ getViewportRight() { return this.center.x + this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel; } /** * Returns effective world space viewport top */ getViewportTop() { return this.center.y - this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel; } /** * Returns effective world space viewport bottom */ getViewportBottom() { return this.center.y + this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel; } /** * Returns the visible world space rect * @returns {Rectangle} */ getVisibleRect() { return _core_rectangle__WEBPACK_IMPORTED_MODULE_3__["Rectangle"].fromTRBL( Math.floor(this.getViewportTop()), Math.ceil(this.getViewportRight()), Math.ceil(this.getViewportBottom()), Math.floor(this.getViewportLeft()) ); } getIsMapOverlayActive() { return this.zoomLevel < _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].mapChunkOverviewMinZoom; } /** * Attaches all event listeners */ internalInitEvents() { this.eventListenerTouchStart = this.onTouchStart.bind(this); this.eventListenerTouchEnd = this.onTouchEnd.bind(this); this.eventListenerTouchMove = this.onTouchMove.bind(this); this.eventListenerMousewheel = this.onMouseWheel.bind(this); this.eventListenerMouseDown = this.onMouseDown.bind(this); this.eventListenerMouseMove = this.onMouseMove.bind(this); this.eventListenerMouseUp = this.onMouseUp.bind(this); if (_core_config__WEBPACK_IMPORTED_MODULE_1__["SUPPORT_TOUCH"]) { this.root.canvas.addEventListener("touchstart", this.eventListenerTouchStart); this.root.canvas.addEventListener("touchend", this.eventListenerTouchEnd); this.root.canvas.addEventListener("touchcancel", this.eventListenerTouchEnd); this.root.canvas.addEventListener("touchmove", this.eventListenerTouchMove); } this.root.canvas.addEventListener("wheel", this.eventListenerMousewheel); this.root.canvas.addEventListener("mousedown", this.eventListenerMouseDown); this.root.canvas.addEventListener("mousemove", this.eventListenerMouseMove); window.addEventListener("mouseup", this.eventListenerMouseUp); // this.root.canvas.addEventListener("mouseout", this.eventListenerMouseUp); } /** * Cleans up all event listeners */ cleanup() { if (_core_config__WEBPACK_IMPORTED_MODULE_1__["SUPPORT_TOUCH"]) { this.root.canvas.removeEventListener("touchstart", this.eventListenerTouchStart); this.root.canvas.removeEventListener("touchend", this.eventListenerTouchEnd); this.root.canvas.removeEventListener("touchcancel", this.eventListenerTouchEnd); this.root.canvas.removeEventListener("touchmove", this.eventListenerTouchMove); } this.root.canvas.removeEventListener("wheel", this.eventListenerMousewheel); this.root.canvas.removeEventListener("mousedown", this.eventListenerMouseDown); this.root.canvas.removeEventListener("mousemove", this.eventListenerMouseMove); window.removeEventListener("mouseup", this.eventListenerMouseUp); // this.root.canvas.removeEventListener("mouseout", this.eventListenerMouseUp); } /** * Binds the arrow keys */ bindKeys() { const mapper = this.root.keyMapper; mapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveUp).add(() => (this.keyboardForce.y = -1)); mapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveDown).add(() => (this.keyboardForce.y = 1)); mapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveRight).add(() => (this.keyboardForce.x = 1)); mapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveLeft).add(() => (this.keyboardForce.x = -1)); mapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapZoomIn) .add(() => (this.desiredZoom = this.zoomLevel * 1.2)); mapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapZoomOut) .add(() => (this.desiredZoom = this.zoomLevel * 0.8)); mapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.centerMap).add(() => this.centerOnMap()); } centerOnMap() { this.desiredCenter = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); } /** * Converts from screen to world space * @param {Vector} screen * @returns {Vector} world space */ screenToWorld(screen) { const centerSpace = screen.subScalars(this.root.gameWidth / 2, this.root.gameHeight / 2); return centerSpace.divideScalar(this.zoomLevel).add(this.center); } /** * Converts from world to screen space * @param {Vector} world * @returns {Vector} screen space */ worldToScreen(world) { const screenSpace = world.sub(this.center).multiplyScalar(this.zoomLevel); return screenSpace.addScalars(this.root.gameWidth / 2, this.root.gameHeight / 2); } /** * Returns if a point is on screen * @param {Vector} point * @returns {boolean} true if its on screen */ isWorldPointOnScreen(point) { const rect = this.getVisibleRect(); return rect.containsPoint(point.x, point.y); } /** * Returns if we can further zoom in * @returns {boolean} */ canZoomIn() { const maxLevel = this.root.app.platformWrapper.getMaximumZoom(); return this.zoomLevel <= maxLevel - 0.01; } /** * Returns if we can further zoom out * @returns {boolean} */ canZoomOut() { const minLevel = this.root.app.platformWrapper.getMinimumZoom(); return this.zoomLevel >= minLevel + 0.01; } // EVENTS /** * Checks if the mouse event is too close after a touch event and thus * should get ignored */ checkPreventDoubleMouse() { if (performance.now() - _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["clickDetectorGlobals"].lastTouchTime < 1000.0) { return false; } return true; } /** * Mousedown handler * @param {MouseEvent} event */ onMouseDown(event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } if (!this.checkPreventDoubleMouse()) { return; } this.touchPostMoveVelocity = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); if (event.button === 0) { this.combinedSingleTouchStartHandler(event.clientX, event.clientY); } else if (event.button === 1) { this.downPreHandler.dispatch(new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](event.clientX, event.clientY), enumMouseButton.middle); } else if (event.button === 2) { this.downPreHandler.dispatch(new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](event.clientX, event.clientY), enumMouseButton.right); } return false; } /** * Mousemove handler * @param {MouseEvent} event */ onMouseMove(event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } if (!this.checkPreventDoubleMouse()) { return; } if (event.button === 0) { this.combinedSingleTouchMoveHandler(event.clientX, event.clientY); } // Clamp everything afterwards this.clampZoomLevel(); return false; } /** * Mouseup handler * @param {MouseEvent=} event */ onMouseUp(event) { if (event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } } if (!this.checkPreventDoubleMouse()) { return; } this.combinedSingleTouchStopHandler(event.clientX, event.clientY); return false; } /** * Mousewheel event * @param {WheelEvent} event */ onMouseWheel(event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } const prevZoom = this.zoomLevel; const delta = Math.sign(event.deltaY) * -0.15 * this.root.app.settings.getScrollWheelSensitivity(); window.assert(Number.isFinite(delta), "Got invalid delta in mouse wheel event: " + event.deltaY); window.assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *before* wheel: " + this.zoomLevel); this.zoomLevel *= 1 + delta; window.assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *after* wheel: " + this.zoomLevel); this.clampZoomLevel(); this.desiredZoom = null; const mousePosition = this.root.app.mousePosition; if (mousePosition) { const worldPos = this.root.camera.screenToWorld(mousePosition); const worldDelta = worldPos.sub(this.center); const actualDelta = this.zoomLevel / prevZoom - 1; this.center = this.center.add(worldDelta.multiplyScalar(actualDelta)); this.desiredCenter = null; } return false; } /** * Touch start handler * @param {TouchEvent} event */ onTouchStart(event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["clickDetectorGlobals"].lastTouchTime = performance.now(); this.touchPostMoveVelocity = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); if (event.touches.length === 1) { const touch = event.touches[0]; this.combinedSingleTouchStartHandler(touch.clientX, touch.clientY); } else if (event.touches.length === 2) { // if (this.pinchPreHandler.dispatch() === STOP_PROPAGATION) { // // Something prevented pinching // return false; // } const touch1 = event.touches[0]; const touch2 = event.touches[1]; this.currentlyMoving = false; this.currentlyPinching = true; this.lastPinchPositions = [ new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](touch1.clientX, touch1.clientY), new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](touch2.clientX, touch2.clientY), ]; } return false; } /** * Touch move handler * @param {TouchEvent} event */ onTouchMove(event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["clickDetectorGlobals"].lastTouchTime = performance.now(); if (event.touches.length === 1) { const touch = event.touches[0]; this.combinedSingleTouchMoveHandler(touch.clientX, touch.clientY); } else if (event.touches.length === 2) { if (this.currentlyPinching) { const touch1 = event.touches[0]; const touch2 = event.touches[1]; const newPinchPositions = [ new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](touch1.clientX, touch1.clientY), new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](touch2.clientX, touch2.clientY), ]; // Get distance of taps last time and now const lastDistance = this.lastPinchPositions[0].distance(this.lastPinchPositions[1]); const thisDistance = newPinchPositions[0].distance(newPinchPositions[1]); // IMPORTANT to do math max here to avoid NaN and causing an invalid zoom level const difference = thisDistance / Math.max(0.001, lastDistance); // Find old center of zoom let oldCenter = this.lastPinchPositions[0].centerPoint(this.lastPinchPositions[1]); // Find new center of zoom let center = newPinchPositions[0].centerPoint(newPinchPositions[1]); // Compute movement let movement = oldCenter.sub(center); this.center.x += movement.x / this.zoomLevel; this.center.y += movement.y / this.zoomLevel; // Compute zoom center = center.sub(new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](this.root.gameWidth / 2, this.root.gameHeight / 2)); // Apply zoom window.assert( Number.isFinite(difference), "Invalid pinch difference: " + difference + "(last=" + lastDistance + ", new = " + thisDistance + ")" ); this.zoomLevel *= difference; // Stick to pivot point const correcture = center.multiplyScalar(difference - 1).divideScalar(this.zoomLevel); this.center = this.center.add(correcture); this.lastPinchPositions = newPinchPositions; this.userInteraction.dispatch(USER_INTERACT_MOVE); // Since we zoomed, abort any programmed zooming if (this.desiredZoom) { this.desiredZoom = null; } } } // Clamp everything afterwards this.clampZoomLevel(); return false; } /** * Touch end and cancel handler * @param {TouchEvent=} event */ onTouchEnd(event) { if (event) { if (event.cancelable) { event.preventDefault(); // event.stopPropagation(); } } _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["clickDetectorGlobals"].lastTouchTime = performance.now(); if (event.changedTouches.length === 0) { logger.warn("Touch end without changed touches"); } const touch = event.changedTouches[0]; this.combinedSingleTouchStopHandler(touch.clientX, touch.clientY); return false; } /** * Internal touch start handler * @param {number} x * @param {number} y */ combinedSingleTouchStartHandler(x, y) { const pos = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](x, y); if (this.downPreHandler.dispatch(pos, enumMouseButton.left) === _core_signal__WEBPACK_IMPORTED_MODULE_4__["STOP_PROPAGATION"]) { // Somebody else captured it return; } this.touchPostMoveVelocity = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); this.currentlyMoving = true; this.lastMovingPosition = pos; this.lastMovingPositionLastTick = null; this.numTicksStandingStill = 0; this.didMoveSinceTouchStart = false; } /** * Internal touch move handler * @param {number} x * @param {number} y */ combinedSingleTouchMoveHandler(x, y) { const pos = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](x, y); if (this.movePreHandler.dispatch(pos) === _core_signal__WEBPACK_IMPORTED_MODULE_4__["STOP_PROPAGATION"]) { // Somebody else captured it return; } if (!this.currentlyMoving) { return false; } let delta = this.lastMovingPosition.sub(pos).divideScalar(this.zoomLevel); if (_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.testCulling) { // When testing culling, we see everything from the same distance delta = delta.multiplyScalar(this.zoomLevel * -2); } this.didMoveSinceTouchStart = this.didMoveSinceTouchStart || delta.length() > 0; this.center = this.center.add(delta); this.touchPostMoveVelocity = this.touchPostMoveVelocity .multiplyScalar(velocitySmoothing) .add(delta.multiplyScalar(1 - velocitySmoothing)); this.lastMovingPosition = pos; this.userInteraction.dispatch(USER_INTERACT_MOVE); // Since we moved, abort any programmed moving if (this.desiredCenter) { this.desiredCenter = null; } } /** * Internal touch stop handler */ combinedSingleTouchStopHandler(x, y) { if (this.currentlyMoving || this.currentlyPinching) { this.currentlyMoving = false; this.currentlyPinching = false; this.lastMovingPosition = null; this.lastMovingPositionLastTick = null; this.numTicksStandingStill = 0; this.lastPinchPositions = null; this.userInteraction.dispatch(USER_INTERACT_TOUCHEND); this.didMoveSinceTouchStart = false; } this.upPostHandler.dispatch(new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](x, y)); } /** * Clamps the camera zoom level within the allowed range */ clampZoomLevel() { if (_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.disableZoomLimits) { return; } const wrapper = this.root.app.platformWrapper; window.assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel); this.zoomLevel = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["clamp"])(this.zoomLevel, wrapper.getMinimumZoom(), wrapper.getMaximumZoom()); window.assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *after* clamp: " + this.zoomLevel); if (this.desiredZoom) { this.desiredZoom = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["clamp"])(this.desiredZoom, wrapper.getMinimumZoom(), wrapper.getMaximumZoom()); } } /** * Updates the camera * @param {number} dt Delta time in milliseconds */ update(dt) { dt = Math.min(dt, 33); this.cameraUpdateTimeBucket += dt; // Simulate movement of N FPS const updatesPerFrame = 4; const physicsStepSizeMs = 1000.0 / (60.0 * updatesPerFrame); let now = this.root.time.systemNow() - 3 * physicsStepSizeMs; while (this.cameraUpdateTimeBucket > physicsStepSizeMs) { now += physicsStepSizeMs; this.cameraUpdateTimeBucket -= physicsStepSizeMs; this.internalUpdatePanning(now, physicsStepSizeMs); this.internalUpdateZooming(now, physicsStepSizeMs); this.internalUpdateCentering(now, physicsStepSizeMs); this.internalUpdateShake(now, physicsStepSizeMs); this.internalUpdateKeyboardForce(now, physicsStepSizeMs); } this.clampZoomLevel(); } /** * Prepares a context to transform it * @param {CanvasRenderingContext2D} context */ transform(context) { if (_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.testCulling) { context.transform(1, 0, 0, 1, 100, 100); return; } this.clampZoomLevel(); const zoom = this.zoomLevel; context.transform( // Scale, skew, rotate zoom, 0, 0, zoom, // Translate -zoom * this.getViewportLeft(), -zoom * this.getViewportTop() ); } /** * Internal shake handler * @param {number} now Time now in seconds * @param {number} dt Delta time */ internalUpdateShake(now, dt) { this.currentShake = this.currentShake.multiplyScalar(0.92); } /** * Internal pan handler * @param {number} now Time now in seconds * @param {number} dt Delta time */ internalUpdatePanning(now, dt) { const baseStrength = velocityStrength * this.root.app.platformWrapper.getTouchPanStrength(); this.touchPostMoveVelocity = this.touchPostMoveVelocity.multiplyScalar(velocityFade); // Check if the camera is being dragged but standing still: if not, zero out `touchPostMoveVelocity`. if (this.currentlyMoving && this.desiredCenter === null) { if ( this.lastMovingPositionLastTick !== null && this.lastMovingPositionLastTick.equalsEpsilon(this.lastMovingPosition) ) { this.numTicksStandingStill++; } else { this.numTicksStandingStill = 0; } this.lastMovingPositionLastTick = this.lastMovingPosition.copy(); if (this.numTicksStandingStill >= ticksBeforeErasingVelocity) { this.touchPostMoveVelocity.x = 0; this.touchPostMoveVelocity.y = 0; } } // Check influence of past points if (!this.currentlyMoving && !this.currentlyPinching) { const len = this.touchPostMoveVelocity.length(); if (len >= velocityMax) { this.touchPostMoveVelocity.x = (this.touchPostMoveVelocity.x * velocityMax) / len; this.touchPostMoveVelocity.y = (this.touchPostMoveVelocity.y * velocityMax) / len; } this.center = this.center.add(this.touchPostMoveVelocity.multiplyScalar(baseStrength)); // Panning this.currentPan = Object(_core_vector__WEBPACK_IMPORTED_MODULE_6__["mixVector"])(this.currentPan, this.desiredPan, 0.06); this.center = this.center.add(this.currentPan.multiplyScalar((0.5 * dt) / this.zoomLevel)); } } /** * Updates the non user interaction zooming * @param {number} now Time now in seconds * @param {number} dt Delta time */ internalUpdateZooming(now, dt) { if (!this.currentlyPinching && this.desiredZoom !== null) { const diff = this.zoomLevel - this.desiredZoom; if (Math.abs(diff) > 0.0001) { let fade = 0.94; if (diff > 0) { // Zoom out faster than in fade = 0.9; } window.assert(Number.isFinite(this.desiredZoom), "Desired zoom is NaN: " + this.desiredZoom); window.assert(Number.isFinite(fade), "Zoom fade is NaN: " + fade); this.zoomLevel = this.zoomLevel * fade + this.desiredZoom * (1 - fade); window.assert(Number.isFinite(this.zoomLevel), "Zoom level is NaN after fade: " + this.zoomLevel); } else { this.desiredZoom = null; } } } /** * Updates the non user interaction centering * @param {number} now Time now in seconds * @param {number} dt Delta time */ internalUpdateCentering(now, dt) { if (!this.currentlyMoving && this.desiredCenter !== null) { const diff = this.center.direction(this.desiredCenter); const length = diff.length(); const tolerance = 1 / this.zoomLevel; if (length > tolerance) { const movement = diff.multiplyScalar(Math.min(1, dt * 0.008)); this.center.x += movement.x; this.center.y += movement.y; } else { this.desiredCenter = null; } } } /** * Updates the keyboard forces * @param {number} now * @param {number} dt Delta time */ internalUpdateKeyboardForce(now, dt) { if (!this.currentlyMoving && this.desiredCenter == null) { const limitingDimension = Math.min(this.root.gameWidth, this.root.gameHeight); const moveAmount = ((limitingDimension / 2048) * dt) / this.zoomLevel; let forceX = 0; let forceY = 0; const actionMapper = this.root.keyMapper; if (actionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveUp).pressed) { forceY -= 1; } if (actionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveDown).pressed) { forceY += 1; } if (actionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveLeft).pressed) { forceX -= 1; } if (actionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveRight).pressed) { forceX += 1; } let movementSpeed = this.root.app.settings.getMovementSpeed() * (actionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].navigation.mapMoveFaster).pressed ? 4 : 1); this.center.x += moveAmount * forceX * movementSpeed; this.center.y += moveAmount * forceY * movementSpeed; } } } /***/ }), /***/ "./src/js/game/colors.js": /*!*******************************!*\ !*** ./src/js/game/colors.js ***! \*******************************/ /*! exports provided: enumColors, enumColorToShortcode, enumShortcodeToColor, enumColorsToHexCode, enumInvertedColors, enumColorMixingResults, allColorData, allowColorMixingMismatch, allowColorMixingOverride, allowColorMixingMissingSource, allowColorMixingMissingTarget, initColors */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumColors", function() { return enumColors; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumColorToShortcode", function() { return enumColorToShortcode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumShortcodeToColor", function() { return enumShortcodeToColor; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumColorsToHexCode", function() { return enumColorsToHexCode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumInvertedColors", function() { return enumInvertedColors; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumColorMixingResults", function() { return enumColorMixingResults; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allColorData", function() { return allColorData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allowColorMixingMismatch", function() { return allowColorMixingMismatch; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allowColorMixingOverride", function() { return allowColorMixingOverride; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allowColorMixingMissingSource", function() { return allowColorMixingMissingSource; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allowColorMixingMissingTarget", function() { return allowColorMixingMissingTarget; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initColors", function() { return initColors; }); /* harmony import */ var _custom_colors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./custom/colors */ "./src/js/game/custom/colors.js"); /** @enum {string} */ const enumColors = { red: "red", green: "green", blue: "blue", yellow: "yellow", magenta: "magenta", cyan: "cyan", white: "white", uncolored: "uncolored", black: "black", }; /** @enum {string} */ const enumColorToShortcode = { [enumColors.red]: "r", [enumColors.green]: "g", [enumColors.blue]: "b", [enumColors.yellow]: "y", [enumColors.magenta]: "m", [enumColors.cyan]: "c", [enumColors.white]: "w", [enumColors.uncolored]: "u", [enumColors.black]: "k", }; /** @enum {enumColors} */ const enumShortcodeToColor = {}; /** @enum {string} */ const enumColorsToHexCode = {}; /** @enum {enumColors} */ const enumInvertedColors = {}; const c = enumColors; /** @enum {Object.} */ const enumColorMixingResults = {}; /** * @typedef {Object} ColorData * @property {string} id * @property {string} code * @property {string} hex * @property {string[][] | string[]} [mixingFrom] * @property {Object.} [mixing] * @property {boolean} [spawnable] * @property {number} [minDistance] * @property {string} [inverted] * @property {number} [tier] */ /** @enum {ColorData} */ const allColorData = { uncolored: { id: "uncolored", code: "u", hex: "#aaaaaa", mixing: { any: "any", }, inverted: "this", tier: 0, }, red: { id: "red", code: "r", hex: "#ff666a", // no recipes spawnable: true, tier: 1, }, green: { id: "green", code: "g", hex: "#78ff66", // no recipes spawnable: true, tier: 1, }, blue: { id: "blue", code: "b", hex: "#66a7ff", // no recipes spawnable: true, minDistance: 3, tier: 1, }, cyan: { id: "cyan", code: "c", hex: "#00fcff", mixingFrom: ["green", "blue"], mixing: { green: "this", blue: "this", }, inverted: "red", tier: 2, }, magenta: { id: "magenta", code: "m", hex: "#dd66ff", mixingFrom: ["red", "blue"], mixing: { red: "this", blue: "this", }, inverted: "green", tier: 2, }, yellow: { id: "yellow", code: "y", hex: "#fcf52a", mixingFrom: ["red", "green"], mixing: { red: "this", green: "this", }, inverted: "blue", tier: 2, }, white: { id: "white", code: "w", hex: "#ffffff", mixing: { any: "white", }, mixingFrom: [ ["red", "cyan"], ["green", "magenta"], ["blue", "yellow"], ["cyan", "magenta"], ["cyan", "yellow"], ["magenta", "yellow"], ], inverted: "black", tier: 3, }, black: { id: "black", code: "k", hex: "#31383a", mixing: { any: "any", white: "uncolored", uncolored: "uncolored", }, tier: 4, }, }; /** * @param {Object} colorData * @property {string} colorData.id * @property {string} colorData.code * @property {string} colorData.hex * @property {Object.} [colorData.mixing] * @property {string[2][] | string[2]} [colorData.mixingFrom] */ function registerColor(colorData) { allColorData[colorData.id] = colorData; } let allowColorMixingMismatch = false; let allowColorMixingOverride = false; let allowColorMixingMissingSource = false; let allowColorMixingMissingTarget = false; for (let data of _custom_colors__WEBPACK_IMPORTED_MODULE_0__["customColors"]) { registerColor(data); } const mix = enumColorMixingResults; initColors(); function initColors() { for (let c1 in allColorData) { let data = allColorData[c1]; window.assert(data); window.assert(data.id == c1); window.assert(data.code.toLowerCase() == data.code); if (data.disabled) { continue; } if (data.spawnable && !data.minDistance) { data.minDistance = 0; } enumColors[c1] = c1; enumColorToShortcode[c1] = data.code; enumShortcodeToColor[data.code] = c1; enumColorsToHexCode[c1] = data.hex; if (!mix[c1]) { mix[c1] = {}; } let mixing = mix[c1]; if (data.mixing) { for (let c2 in data.mixing) { if (c2 == "any") { continue; } let result = data.mixing[c2] == "this" ? c1 : data.mixing[c2] == "any" ? c2 : data.mixing[c2]; if (mixing[c2] && mixing[c2] != result) { if (!allowColorMixingOverride) { window.assert( false, `Color mixing recipe overrides are not implemented (${c1}+${c2}=${mixing[c2]}->${result})` ); } } mixing[c2] = result; } } if (data.inverted) { if (data.inverted == "this") { enumInvertedColors[c1] = c1; } else { enumInvertedColors[c1] = data.inverted; } } } for (let id in allColorData) { let data = allColorData[id]; let mixingFrom = !data.mixingFrom ? [] : data.mixingFrom[0] instanceof Array ? data.mixingFrom : [data.mixingFrom]; for (let [c1, c2] of mixingFrom) { if (!c[c1] || !c[c2]) { if (!allowColorMixingMissingSource) { window.assert(false, `Color mixing recipe source is not known (${c1}+${c2}=${id})`); } continue; } if (mix[c1][c2] && mix[c1][c2] != id) { // TODO throw "wut"; } if (mix[c2][c1] && mix[c2][c1] != id) { // TODO throw "wut"; } mix[c1][c2] = id; } } for (let c1 in c) { for (let c2 in c) { if (mix[c1][c2] != mix[c2][c1]) { if (mix[c1][c2] && mix[c2][c1] && !allowColorMixingMismatch) { window.assert( false, `Color mixing recipe result mismatch (${c1}+${c2}=${mix[c1][c2]}/${mix[c2][c1]}}` ); } mix[c1][c2] = mix[c2][c1] = mix[c1][c2] || mix[c2][c1]; } } } for (let c1 in c) { if (!mix[c1][c1]) { mix[c1][c1] = c1; } } let anyPairs = {}; for (let c1 in c) { let mixing = allColorData[c1].mixing; if (!mixing || !mixing.any) { continue; } for (let c2 in c) { if (mix[c1][c2] || mix[c2][c1]) { continue; } if (anyPairs[`${c1}+${c2}`]) { throw "wut"; } anyPairs[`${c1}+${c2}`] = anyPairs[`${c2}+${c1}`] = true; mix[c1][c2] = mix[c2][c1] = mixing.any == "any" ? c2 : mixing.any; } } for (let c1 in c) { for (let c2 in c) { if (!mix[c1][c2]) { window.assert(false, "Color mixing of", c1, "with", c2, "is not defined"); } } } for (let c1 in c) { if (enumInvertedColors[c1] && !enumInvertedColors[enumInvertedColors[c1]]) { enumInvertedColors[enumInvertedColors[c1]] = c1; } } } /***/ }), /***/ "./src/js/game/component.js": /*!**********************************!*\ !*** ./src/js/game/component.js ***! \**********************************/ /*! exports provided: Component */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Component", function() { return Component; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); class Component extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["BasicSerializableObject"] { /** * Returns the components unique id * @returns {string} */ static getId() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return "unknown-component"; } /** * Should return the schema used for serialization */ static getSchema() { return {}; } /** * Should duplicate the component but without its contents * @returns {object} */ duplicateWithoutContents() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /* dev:start */ /** * Fixes typeof DerivedComponent is not assignable to typeof Component, compiled out * in non-dev builds */ constructor(...args) { super(); } /** * Returns a string representing the components data, only in dev builds * @returns {string} */ getDebugString() { return null; } /* dev:end */ } /** * TypeScript does not support Abstract Static methods (https://github.com/microsoft/TypeScript/issues/34516) * One workaround is to declare the type of the component and reference that for static methods * @typedef {typeof Component} StaticComponent */ /***/ }), /***/ "./src/js/game/component_registry.js": /*!*******************************************!*\ !*** ./src/js/game/component_registry.js ***! \*******************************************/ /*! exports provided: initComponentRegistry */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initComponentRegistry", function() { return initComponentRegistry; }); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _components_static_map_entity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/static_map_entity */ "./src/js/game/components/static_map_entity.js"); /* harmony import */ var _components_belt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/belt */ "./src/js/game/components/belt.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _components_miner__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/miner */ "./src/js/game/components/miner.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _components_underground_belt__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/underground_belt */ "./src/js/game/components/underground_belt.js"); /* harmony import */ var _components_hub__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/hub */ "./src/js/game/components/hub.js"); /* harmony import */ var _components_storage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/storage */ "./src/js/game/components/storage.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); /* harmony import */ var _components_belt_underlays__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/belt_underlays */ "./src/js/game/components/belt_underlays.js"); /* harmony import */ var _components_wire__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/wire */ "./src/js/game/components/wire.js"); /* harmony import */ var _components_constant_signal__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/constant_signal */ "./src/js/game/components/constant_signal.js"); /* harmony import */ var _components_logic_gate__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/logic_gate */ "./src/js/game/components/logic_gate.js"); /* harmony import */ var _components_lever__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/lever */ "./src/js/game/components/lever.js"); /* harmony import */ var _components_wire_tunnel__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./components/wire_tunnel */ "./src/js/game/components/wire_tunnel.js"); /* harmony import */ var _components_display__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./components/display */ "./src/js/game/components/display.js"); function initComponentRegistry() { _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_static_map_entity__WEBPACK_IMPORTED_MODULE_1__["StaticMapEntityComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_belt__WEBPACK_IMPORTED_MODULE_2__["BeltComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_item_ejector__WEBPACK_IMPORTED_MODULE_3__["ItemEjectorComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_item_acceptor__WEBPACK_IMPORTED_MODULE_4__["ItemAcceptorComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_miner__WEBPACK_IMPORTED_MODULE_5__["MinerComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_item_processor__WEBPACK_IMPORTED_MODULE_6__["ItemProcessorComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_underground_belt__WEBPACK_IMPORTED_MODULE_7__["UndergroundBeltComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_hub__WEBPACK_IMPORTED_MODULE_8__["HubComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_storage__WEBPACK_IMPORTED_MODULE_9__["StorageComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_wired_pins__WEBPACK_IMPORTED_MODULE_10__["WiredPinsComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_belt_underlays__WEBPACK_IMPORTED_MODULE_12__["BeltUnderlaysComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_wire__WEBPACK_IMPORTED_MODULE_13__["WireComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_constant_signal__WEBPACK_IMPORTED_MODULE_14__["ConstantSignalComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_logic_gate__WEBPACK_IMPORTED_MODULE_15__["LogicGateComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_lever__WEBPACK_IMPORTED_MODULE_16__["LeverComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_wire_tunnel__WEBPACK_IMPORTED_MODULE_17__["WireTunnelComponent"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(_components_display__WEBPACK_IMPORTED_MODULE_18__["DisplayComponent"]); for (let custom of _custom_modBuildings__WEBPACK_IMPORTED_MODULE_11__["allCustomBuildingData"]) { if (custom.component) { _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].register(custom.component); } } // IMPORTANT ^^^^^ UPDATE ENTITY COMPONENT STORAGE AFTERWARDS // Sanity check - If this is thrown, you (=me, lol) forgot to add a new component here window.assert( // @ts-ignore __webpack_require__("./src/js/game/components sync .*\\.js/").keys().length + _custom_modBuildings__WEBPACK_IMPORTED_MODULE_11__["allCustomBuildingData"].filter(e => e.component).length === _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].getNumEntries(), "Not all components are registered" ); console.log("📦 There are", _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gComponentRegistry"].getNumEntries(), "components"); } /***/ }), /***/ "./src/js/game/components sync .*\\.js/": /*!**********************************************************!*\ !*** ./src/js/game/components sync nonrecursive .*\.js/ ***! \**********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var map = { "./belt.js": "./src/js/game/components/belt.js", "./belt_underlays.js": "./src/js/game/components/belt_underlays.js", "./constant_signal.js": "./src/js/game/components/constant_signal.js", "./display.js": "./src/js/game/components/display.js", "./hub.js": "./src/js/game/components/hub.js", "./item_acceptor.js": "./src/js/game/components/item_acceptor.js", "./item_ejector.js": "./src/js/game/components/item_ejector.js", "./item_processor.js": "./src/js/game/components/item_processor.js", "./lever.js": "./src/js/game/components/lever.js", "./logic_gate.js": "./src/js/game/components/logic_gate.js", "./miner.js": "./src/js/game/components/miner.js", "./static_map_entity.js": "./src/js/game/components/static_map_entity.js", "./storage.js": "./src/js/game/components/storage.js", "./underground_belt.js": "./src/js/game/components/underground_belt.js", "./wire.js": "./src/js/game/components/wire.js", "./wire_tunnel.js": "./src/js/game/components/wire_tunnel.js", "./wired_pins.js": "./src/js/game/components/wired_pins.js" }; function webpackContext(req) { var id = webpackContextResolve(req); return __webpack_require__(id); } function webpackContextResolve(req) { if(!__webpack_require__.o(map, req)) { var e = new Error("Cannot find module '" + req + "'"); e.code = 'MODULE_NOT_FOUND'; throw e; } return map[req]; } webpackContext.keys = function webpackContextKeys() { return Object.keys(map); }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; webpackContext.id = "./src/js/game/components sync .*\\.js/"; /***/ }), /***/ "./src/js/game/components/belt.js": /*!****************************************!*\ !*** ./src/js/game/components/belt.js ***! \****************************************/ /*! exports provided: curvedBeltLength, FAKE_BELT_ACCEPTOR_SLOT, FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION, BeltComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "curvedBeltLength", function() { return curvedBeltLength; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FAKE_BELT_ACCEPTOR_SLOT", function() { return FAKE_BELT_ACCEPTOR_SLOT; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION", function() { return FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BeltComponent", function() { return BeltComponent; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _belt_path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../belt_path */ "./src/js/game/belt_path.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); const curvedBeltLength = /* Math.PI / 4 */ 0.78; /** @type {import("./item_acceptor").ItemAcceptorSlot} */ const FAKE_BELT_ACCEPTOR_SLOT = { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].bottom], }; /** @type {Object} */ const FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION = { [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top]: { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top, item: null, progress: 0, }, [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right]: { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right, item: null, progress: 0, }, [_core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left]: { pos: new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left, item: null, progress: 0, }, }; class BeltComponent extends _component__WEBPACK_IMPORTED_MODULE_3__["Component"] { static getId() { return "Belt"; } duplicateWithoutContents() { return new BeltComponent({ direction: this.direction }); } /** * * @param {object} param0 * @param {enumDirection=} param0.direction The direction of the belt */ constructor({ direction = _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top }) { super(); this.direction = direction; /** * The path this belt is contained in, not serialized * @type {BeltPath} */ this.assignedPath = null; } /** * Returns the effective length of this belt in tile space * @returns {number} */ getEffectiveLengthTiles() { return this.direction === _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top ? 1.0 : curvedBeltLength; } /** * Returns fake acceptor slot used for matching * @returns {import("./item_acceptor").ItemAcceptorSlot} */ getFakeAcceptorSlot() { return FAKE_BELT_ACCEPTOR_SLOT; } /** * Returns fake acceptor slot used for matching * @returns {import("./item_ejector").ItemEjectorSlot} */ getFakeEjectorSlot() { window.assert( FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION[this.direction], "Invalid belt direction: ", this.direction ); return FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION[this.direction]; } /** * Converts from belt space (0 = start of belt ... 1 = end of belt) to the local * belt coordinates (-0.5|-0.5 to 0.5|0.5) * @param {number} progress * @returns {Vector} */ transformBeltToLocalSpace(progress) { window.assert(progress >= 0.0, "Invalid progress ( < 0): " + progress); switch (this.direction) { case _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].top: window.assert(progress <= 1.02, "Invalid progress: " + progress); return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0.5 - progress); case _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].right: { window.assert(progress <= curvedBeltLength + 0.02, "Invalid progress 2: " + progress); const arcProgress = (progress / curvedBeltLength) * 0.5 * Math.PI; return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0.5 - 0.5 * Math.cos(arcProgress), 0.5 - 0.5 * Math.sin(arcProgress)); } case _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirection"].left: { window.assert(progress <= curvedBeltLength + 0.02, "Invalid progress 3: " + progress); const arcProgress = (progress / curvedBeltLength) * 0.5 * Math.PI; return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](-0.5 + 0.5 * Math.cos(arcProgress), 0.5 - 0.5 * Math.sin(arcProgress)); } default: window.assert(false, "Invalid belt direction: " + this.direction); return new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0); } } } /***/ }), /***/ "./src/js/game/components/belt_underlays.js": /*!**************************************************!*\ !*** ./src/js/game/components/belt_underlays.js ***! \**************************************************/ /*! exports provided: BeltUnderlaysComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BeltUnderlaysComponent", function() { return BeltUnderlaysComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); class BeltUnderlaysComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "BeltUnderlays"; } duplicateWithoutContents() { const beltUnderlaysCopy = []; for (let i = 0; i < this.underlays.length; ++i) { const underlay = this.underlays[i]; beltUnderlaysCopy.push({ pos: underlay.pos.copy(), direction: underlay.direction, }); } return new BeltUnderlaysComponent({ underlays: beltUnderlaysCopy, }); } /** * @param {object} param0 * @param {Array<{pos: Vector, direction: enumDirection}>=} param0.underlays Where to render belt underlays */ constructor({ underlays }) { super(); this.underlays = underlays; } } /***/ }), /***/ "./src/js/game/components/constant_signal.js": /*!***************************************************!*\ !*** ./src/js/game/components/constant_signal.js ***! \***************************************************/ /*! exports provided: ConstantSignalComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConstantSignalComponent", function() { return ConstantSignalComponent; }); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); class ConstantSignalComponent extends _component__WEBPACK_IMPORTED_MODULE_2__["Component"] { static getId() { return "ConstantSignal"; } static getSchema() { return { signal: _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].nullable(_item_resolver__WEBPACK_IMPORTED_MODULE_4__["typeItemSingleton"]), }; } duplicateWithoutContents() { return new ConstantSignalComponent({ signal: this.signal }); } /** * * @param {object} param0 * @param {BaseItem=} param0.signal The signal to store */ constructor({ signal = null }) { super(); this.signal = signal; } } /***/ }), /***/ "./src/js/game/components/display.js": /*!*******************************************!*\ !*** ./src/js/game/components/display.js ***! \*******************************************/ /*! exports provided: DisplayComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DisplayComponent", function() { return DisplayComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); class DisplayComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "Display"; } duplicateWithoutContents() { return new DisplayComponent(); } } /***/ }), /***/ "./src/js/game/components/hub.js": /*!***************************************!*\ !*** ./src/js/game/components/hub.js ***! \***************************************/ /*! exports provided: HubComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HubComponent", function() { return HubComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); class HubComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "Hub"; } } /***/ }), /***/ "./src/js/game/components/item_acceptor.js": /*!*************************************************!*\ !*** ./src/js/game/components/item_acceptor.js ***! \*************************************************/ /*! exports provided: ItemAcceptorComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemAcceptorComponent", function() { return ItemAcceptorComponent; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /** @typedef {{ * pos: Vector, * directions: enumDirection[], * filter?: ItemType * }} ItemAcceptorSlot */ /** * Contains information about a slot plus its location * @typedef {{ * slot: ItemAcceptorSlot, * index: number, * acceptedDirection: enumDirection * }} ItemAcceptorLocatedSlot */ /** @typedef {{ * pos: Vector, * directions: enumDirection[], * filter?: ItemType * }} ItemAcceptorSlotConfig */ class ItemAcceptorComponent extends _component__WEBPACK_IMPORTED_MODULE_3__["Component"] { static getId() { return "ItemAcceptor"; } duplicateWithoutContents() { const slotsCopy = []; for (let i = 0; i < this.slots.length; ++i) { const slot = this.slots[i]; slotsCopy.push({ pos: slot.pos.copy(), directions: slot.directions.slice(), filter: slot.filter, }); } return new ItemAcceptorComponent({ slots: slotsCopy, }); } /** * * @param {object} param0 * @param {Array} param0.slots The slots from which we accept items */ constructor({ slots = [] }) { super(); /** * Fixes belt animations * @type {Array<{ item: BaseItem, slotIndex: number, animProgress: number, direction: enumDirection }>} */ this.itemConsumptionAnimations = []; this.setSlots(slots); } /** * * @param {Array} slots */ setSlots(slots) { /** @type {Array} */ this.slots = []; for (let i = 0; i < slots.length; ++i) { const slot = slots[i]; this.slots.push({ pos: slot.pos, directions: slot.directions, // Which type of item to accept (shape | color | all) @see ItemType filter: slot.filter, }); } } /** * Returns if this acceptor can accept a new item at slot N * @param {number} slotIndex * @param {BaseItem=} item */ canAcceptItem(slotIndex, item) { const slot = this.slots[slotIndex]; return !slot.filter || slot.filter === item.getItemType(); } /** * Called when an item has been accepted so that * @param {number} slotIndex * @param {enumDirection} direction * @param {BaseItem} item */ onItemAccepted(slotIndex, direction, item) { this.itemConsumptionAnimations.push({ item, slotIndex, direction, animProgress: 0.0, }); } /** * Tries to find a slot which accepts the current item * @param {Vector} targetLocalTile * @param {enumDirection} fromLocalDirection * @returns {ItemAcceptorLocatedSlot|null} */ findMatchingSlot(targetLocalTile, fromLocalDirection) { // We need to invert our direction since the acceptor specifies *from* which direction // it accepts items, but the ejector specifies *into* which direction it ejects items. // E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction. const desiredDirection = _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumInvertedDirections"][fromLocalDirection]; // Go over all slots and try to find a target slot for (let slotIndex = 0; slotIndex < this.slots.length; ++slotIndex) { const slot = this.slots[slotIndex]; // Make sure the acceptor slot is on the right position if (!slot.pos.equals(targetLocalTile)) { continue; } // Check if the acceptor slot accepts items from our direction for (let i = 0; i < slot.directions.length; ++i) { // const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]); if (desiredDirection === slot.directions[i]) { return { slot, index: slotIndex, acceptedDirection: desiredDirection, }; } } } return null; } } /***/ }), /***/ "./src/js/game/components/item_ejector.js": /*!************************************************!*\ !*** ./src/js/game/components/item_ejector.js ***! \************************************************/ /*! exports provided: ItemEjectorComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemEjectorComponent", function() { return ItemEjectorComponent; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _belt_path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../belt_path */ "./src/js/game/belt_path.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); /** * @typedef {{ * pos: Vector, * direction: enumDirection, * item: BaseItem, * progress: number?, * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot, * cachedBeltPath?: BeltPath, * cachedTargetEntity?: Entity * }} ItemEjectorSlot */ class ItemEjectorComponent extends _component__WEBPACK_IMPORTED_MODULE_4__["Component"] { static getId() { return "ItemEjector"; } static getSchema() { // The cachedDestSlot, cachedTargetEntity fields are not serialized. return { slots: _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].array( _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].structured({ item: _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].nullable(_item_resolver__WEBPACK_IMPORTED_MODULE_6__["typeItemSingleton"]), progress: _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].float, }) ), }; } duplicateWithoutContents() { const slotsCopy = []; for (let i = 0; i < this.slots.length; ++i) { const slot = this.slots[i]; slotsCopy.push({ pos: slot.pos.copy(), direction: slot.direction, }); } return new ItemEjectorComponent({ slots: slotsCopy, }); } /** * * @param {object} param0 * @param {Array<{pos: Vector, direction: enumDirection }>=} param0.slots The slots to eject on */ constructor({ slots = [] }) { super(); this.setSlots(slots); /** * Whether this ejector slot is enabled */ this.enabled = true; } /** * @param {Array<{pos: Vector, direction: enumDirection }>} slots The slots to eject on */ setSlots(slots) { /** @type {Array} */ this.slots = []; for (let i = 0; i < slots.length; ++i) { const slot = slots[i]; this.slots.push({ pos: slot.pos, direction: slot.direction, item: null, progress: 0, cachedDestSlot: null, cachedTargetEntity: null, }); } } /** * Returns where this slot ejects to * @param {ItemEjectorSlot} slot * @returns {Vector} */ getSlotTargetLocalTile(slot) { const directionVector = _core_vector__WEBPACK_IMPORTED_MODULE_0__["enumDirectionToVector"][slot.direction]; return slot.pos.add(directionVector); } /** * Returns whether any slot ejects to the given local tile * @param {Vector} tile */ anySlotEjectsToLocalTile(tile) { for (let i = 0; i < this.slots.length; ++i) { if (this.getSlotTargetLocalTile(this.slots[i]).equals(tile)) { return true; } } return false; } /** * Returns if we can eject on a given slot * @param {number} slotIndex * @returns {boolean} */ canEjectOnSlot(slotIndex) { window.assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex); return !this.slots[slotIndex].item; } /** * Returns the first free slot on this ejector or null if there is none * @returns {number?} */ getFirstFreeSlot() { for (let i = 0; i < this.slots.length; ++i) { if (this.canEjectOnSlot(i)) { return i; } } return null; } /** * Tries to eject a given item * @param {number} slotIndex * @param {BaseItem} item * @returns {boolean} */ tryEject(slotIndex, item) { if (!this.canEjectOnSlot(slotIndex)) { return false; } this.slots[slotIndex].item = item; this.slots[slotIndex].progress = 0; return true; } /** * Clears the given slot and returns the item it had * @param {number} slotIndex * @returns {BaseItem|null} */ takeSlotItem(slotIndex) { const slot = this.slots[slotIndex]; const item = slot.item; slot.item = null; slot.progress = 0.0; return item; } } /***/ }), /***/ "./src/js/game/components/item_processor.js": /*!**************************************************!*\ !*** ./src/js/game/components/item_processor.js ***! \**************************************************/ /*! exports provided: enumItemProcessorTypes, ItemProcessorComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumItemProcessorTypes", function() { return enumItemProcessorTypes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemProcessorComponent", function() { return ItemProcessorComponent; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); /** @enum {string} */ const enumItemProcessorTypes = { splitter: "splitter", splitterWires: "splitterWires", cutter: "cutter", cutterQuad: "cutterQuad", rotater: "rotater", rotaterCCW: "rotaterCCW", rotaterFL: "rotaterFL", stacker: "stacker", trash: "trash", mixer: "mixer", painter: "painter", painterDouble: "painterDouble", painterQuad: "painterQuad", hub: "hub", filter: "filter", }; class ItemProcessorComponent extends _component__WEBPACK_IMPORTED_MODULE_2__["Component"] { static getId() { return "ItemProcessor"; } static getSchema() { return { nextOutputSlot: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].uint, inputSlots: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].array( _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].structured({ item: _item_resolver__WEBPACK_IMPORTED_MODULE_3__["typeItemSingleton"], sourceSlot: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].uint, }) ), itemsToEject: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].array( _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].structured({ item: _item_resolver__WEBPACK_IMPORTED_MODULE_3__["typeItemSingleton"], requiredSlot: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].nullable(_savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].uint), preferredSlot: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].nullable(_savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].uint), }) ), secondsUntilEject: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].float, }; } duplicateWithoutContents() { return new ItemProcessorComponent({ processorType: this.type, inputsPerCharge: this.inputsPerCharge, }); } /** * * @param {object} param0 * @param {enumItemProcessorTypes=} param0.processorType Which type of processor this is * @param {number=} param0.inputsPerCharge How many items this machine needs until it can start working * */ constructor({ processorType = enumItemProcessorTypes.splitter, inputsPerCharge = 1 }) { super(); // Which slot to emit next, this is only a preference and if it can't emit // it will take the other one. Some machines ignore this (e.g. the splitter) to make // sure the outputs always match this.nextOutputSlot = 0; // Type of the processor this.type = processorType; // How many inputs we need for one charge this.inputsPerCharge = inputsPerCharge; /** * Our current inputs * @type {Array<{ item: BaseItem, sourceSlot: number }>} */ this.inputSlots = []; /** * What we are currently processing, empty if we don't produce anything rn * requiredSlot: Item *must* be ejected on this slot * preferredSlot: Item *can* be ejected on this slot, but others are fine too if the one is not usable * @type {Array<{item: BaseItem, requiredSlot?: number, preferredSlot?: number}>} */ this.itemsToEject = []; /** * How long it takes until we are done with the current items */ this.secondsUntilEject = 0; } /** * Tries to take the item * @param {BaseItem} item * @param {number} sourceSlot */ tryTakeItem(item, sourceSlot) { if (this.type === enumItemProcessorTypes.hub || this.type === enumItemProcessorTypes.trash) { // Hub has special logic .. not really nice but efficient. this.inputSlots.push({ item, sourceSlot }); return true; } // Check that we only take one item per slot for (let i = 0; i < this.inputSlots.length; ++i) { const slot = this.inputSlots[i]; if (slot.sourceSlot === sourceSlot) { return false; } } this.inputSlots.push({ item, sourceSlot }); return true; } } /***/ }), /***/ "./src/js/game/components/lever.js": /*!*****************************************!*\ !*** ./src/js/game/components/lever.js ***! \*****************************************/ /*! exports provided: LeverComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LeverComponent", function() { return LeverComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); class LeverComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "Lever"; } duplicateWithoutContents() { return new LeverComponent({ toggled: this.toggled }); } /** * @param {object} param0 * @param {boolean=} param0.toggled */ constructor({ toggled = false }) { super(); this.toggled = toggled; } } /***/ }), /***/ "./src/js/game/components/logic_gate.js": /*!**********************************************!*\ !*** ./src/js/game/components/logic_gate.js ***! \**********************************************/ /*! exports provided: enumLogicGateType, LogicGateComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumLogicGateType", function() { return enumLogicGateType; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LogicGateComponent", function() { return LogicGateComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /** @enum {string} */ const enumLogicGateType = { and: "and", not: "not", xor: "xor", or: "or", transistor: "transistor", analyzer: "analyzer", rotater: "rotater", unstacker: "unstacker", cutter: "cutter", shapecompare: "shapecompare", adder: "adder", }; class LogicGateComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "LogicGate"; } duplicateWithoutContents() { return new LogicGateComponent({ type: this.type }); } /** * * @param {object} param0 * @param {enumLogicGateType=} param0.type */ constructor({ type = enumLogicGateType.and }) { super(); this.type = type; } } /***/ }), /***/ "./src/js/game/components/miner.js": /*!*****************************************!*\ !*** ./src/js/game/components/miner.js ***! \*****************************************/ /*! exports provided: MinerComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MinerComponent", function() { return MinerComponent; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); const chainBufferSize = 3; class MinerComponent extends _component__WEBPACK_IMPORTED_MODULE_2__["Component"] { static getId() { return "Miner"; } static getSchema() { // cachedMinedItem is not serialized. return { lastMiningTime: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].ufloat, itemChainBuffer: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].array(_item_resolver__WEBPACK_IMPORTED_MODULE_3__["typeItemSingleton"]), }; } duplicateWithoutContents() { return new MinerComponent({ chainable: this.chainable, }); } constructor({ chainable = false }) { super(); this.lastMiningTime = 0; this.chainable = chainable; /** * Stores items from other miners which were chained to this * miner. * @type {Array} */ this.itemChainBuffer = []; /** * @type {BaseItem} */ this.cachedMinedItem = null; } /** * * @param {BaseItem} item */ tryAcceptChainedItem(item) { if (this.itemChainBuffer.length > chainBufferSize) { // Well, this one is full return false; } this.itemChainBuffer.push(item); return true; } } /***/ }), /***/ "./src/js/game/components/static_map_entity.js": /*!*****************************************************!*\ !*** ./src/js/game/components/static_map_entity.js ***! \*****************************************************/ /*! exports provided: StaticMapEntityComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StaticMapEntityComponent", function() { return StaticMapEntityComponent; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_sprites__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/sprites */ "./src/js/core/sprites.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); class StaticMapEntityComponent extends _component__WEBPACK_IMPORTED_MODULE_7__["Component"] { static getId() { return "StaticMapEntity"; } static getSchema() { return { origin: _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__["types"].tileVector, rotation: _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__["types"].float, originalRotation: _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__["types"].float, // See building_codes.js code: _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__["types"].uint, }; } /** * Returns the effective tile size * @returns {Vector} */ getTileSize() { return Object(_building_codes__WEBPACK_IMPORTED_MODULE_6__["getBuildingDataFromCode"])(this.code).tileSize; } /** * Returns the sprite * @returns {AtlasSprite} */ getSprite() { return Object(_building_codes__WEBPACK_IMPORTED_MODULE_6__["getBuildingDataFromCode"])(this.code).sprite; } /** * Returns the blueprint sprite * @returns {AtlasSprite} */ getBlueprintSprite() { return Object(_building_codes__WEBPACK_IMPORTED_MODULE_6__["getBuildingDataFromCode"])(this.code).blueprintSprite; } /** * Returns the silhouette color * @returns {string} */ getSilhouetteColor() { return Object(_building_codes__WEBPACK_IMPORTED_MODULE_6__["getBuildingDataFromCode"])(this.code).silhouetteColor; } /** * Returns the meta building * @returns {import("../meta_building").MetaBuilding} */ getMetaBuilding() { return Object(_building_codes__WEBPACK_IMPORTED_MODULE_6__["getBuildingDataFromCode"])(this.code).metaInstance; } duplicateWithoutContents() { return new StaticMapEntityComponent({ origin: this.origin.copy(), rotation: this.rotation, originalRotation: this.originalRotation, code: this.code, }); } /** * * @param {object} param0 * @param {Vector=} param0.origin Origin (Top Left corner) of the entity * @param {Vector=} param0.tileSize Size of the entity in tiles * @param {number=} param0.rotation Rotation in degrees. Must be multiple of 90 * @param {number=} param0.originalRotation Original Rotation in degrees. Must be multiple of 90 * @param {number=} param0.code Building code */ constructor({ origin = new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](), tileSize = new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](1, 1), rotation = 0, originalRotation = 0, code = 0, }) { super(); window.assert( rotation % 90 === 0, "Rotation of static map entity must be multiple of 90 (was " + rotation + ")" ); this.origin = origin; this.rotation = rotation; this.code = code; this.originalRotation = originalRotation; } /** * Returns the effective rectangle of this entity in tile space * @returns {Rectangle} */ getTileSpaceBounds() { const size = this.getTileSize(); switch (this.rotation) { case 0: return new _core_rectangle__WEBPACK_IMPORTED_MODULE_2__["Rectangle"](this.origin.x, this.origin.y, size.x, size.y); case 90: return new _core_rectangle__WEBPACK_IMPORTED_MODULE_2__["Rectangle"](this.origin.x - size.y + 1, this.origin.y, size.y, size.x); case 180: return new _core_rectangle__WEBPACK_IMPORTED_MODULE_2__["Rectangle"](this.origin.x - size.x + 1, this.origin.y - size.y + 1, size.x, size.y); case 270: return new _core_rectangle__WEBPACK_IMPORTED_MODULE_2__["Rectangle"](this.origin.x, this.origin.y - size.x + 1, size.y, size.x); default: window.assert(false, "Invalid rotation"); } } /** * Transforms the given vector/rotation from local space to world space * @param {Vector} vector * @returns {Vector} */ applyRotationToVector(vector) { return vector.rotateFastMultipleOf90(this.rotation); } /** * Transforms the given vector/rotation from world space to local space * @param {Vector} vector * @returns {Vector} */ unapplyRotationToVector(vector) { return vector.rotateFastMultipleOf90(360 - this.rotation); } /** * Transforms the given direction from local space * @param {enumDirection} direction * @returns {enumDirection} */ localDirectionToWorld(direction) { return _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"].transformDirectionFromMultipleOf90(direction, this.rotation); } /** * Transforms the given direction from world to local space * @param {enumDirection} direction * @returns {enumDirection} */ worldDirectionToLocal(direction) { return _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"].transformDirectionFromMultipleOf90(direction, 360 - this.rotation); } /** * Transforms from local tile space to global tile space * @param {Vector} localTile * @returns {Vector} */ localTileToWorld(localTile) { const result = localTile.rotateFastMultipleOf90(this.rotation); result.x += this.origin.x; result.y += this.origin.y; return result; } /** * Transforms from world space to local space * @param {Vector} worldTile */ worldToLocalTile(worldTile) { const localUnrotated = worldTile.sub(this.origin); return this.unapplyRotationToVector(localUnrotated); } /** * Returns whether the entity should be drawn for the given parameters * @param {DrawParameters} parameters */ shouldBeDrawn(parameters) { let x = 0; let y = 0; let w = 0; let h = 0; const size = this.getTileSize(); switch (this.rotation) { case 0: { x = this.origin.x; y = this.origin.y; w = size.x; h = size.y; break; } case 90: { x = this.origin.x - size.y + 1; y = this.origin.y; w = size.y; h = size.x; break; } case 180: { x = this.origin.x - size.x + 1; y = this.origin.y - size.y + 1; w = size.x; h = size.y; break; } case 270: { x = this.origin.x; y = this.origin.y - size.x + 1; w = size.y; h = size.x; break; } default: window.assert(false, "Invalid rotation"); } return parameters.visibleRect.containsRect4Params( x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, w * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, h * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize ); } /** * Draws a sprite over the whole space of the entity * @param {DrawParameters} parameters * @param {AtlasSprite} sprite * @param {number=} extrudePixels How many pixels to extrude the sprite * @param {Vector=} overridePosition Whether to drwa the entity at a different location */ drawSpriteOnBoundsClipped(parameters, sprite, extrudePixels = 0, overridePosition = null) { if (!this.shouldBeDrawn(parameters) && !overridePosition) { return; } const size = this.getTileSize(); let worldX = this.origin.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; let worldY = this.origin.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; if (overridePosition) { worldX = overridePosition.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; worldY = overridePosition.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; } if (this.rotation === 0) { // Early out, is faster sprite.drawCached( parameters, worldX - extrudePixels * size.x, worldY - extrudePixels * size.y, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize * size.x + 2 * extrudePixels * size.x, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize * size.y + 2 * extrudePixels * size.y ); } else { const rotationCenterX = worldX + _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize; const rotationCenterY = worldY + _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize; parameters.context.translate(rotationCenterX, rotationCenterY); parameters.context.rotate(Math.radians(this.rotation)); sprite.drawCached( parameters, -_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize - extrudePixels * size.x, -_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize - extrudePixels * size.y, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize * size.x + 2 * extrudePixels * size.x, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize * size.y + 2 * extrudePixels * size.y, false // no clipping possible here ); parameters.context.rotate(-Math.radians(this.rotation)); parameters.context.translate(-rotationCenterX, -rotationCenterY); } } } /***/ }), /***/ "./src/js/game/components/storage.js": /*!*******************************************!*\ !*** ./src/js/game/components/storage.js ***! \*******************************************/ /*! exports provided: StorageComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StorageComponent", function() { return StorageComponent; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../items/shape_item */ "./src/js/game/items/shape_item.js"); class StorageComponent extends _component__WEBPACK_IMPORTED_MODULE_2__["Component"] { static getId() { return "Storage"; } static getSchema() { return { storedCount: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].uint, storedItem: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].nullable(_item_resolver__WEBPACK_IMPORTED_MODULE_3__["typeItemSingleton"]), }; } duplicateWithoutContents() { return new StorageComponent({ maximumStorage: this.maximumStorage }); } /** * @param {object} param0 * @param {number=} param0.maximumStorage How much this storage can hold */ constructor({ maximumStorage = 1e20 }) { super(); this.maximumStorage = maximumStorage; /** * Currently stored item * @type {BaseItem} */ this.storedItem = null; /** * How many of this item we have stored */ this.storedCount = 0; /** * We compute an opacity to make sure it doesn't flicker */ this.overlayOpacity = 0; } /** * Returns whether this storage can accept the item * @param {BaseItem} item */ canAcceptItem(item) { if (this.storedCount >= this.maximumStorage) { return false; } if (!this.storedItem || this.storedCount === 0) { return true; } const itemType = item.getItemType(); // Check type matches if (itemType !== this.storedItem.getItemType()) { return false; } if (itemType === "color") { return /** @type {ColorItem} */ (this.storedItem).color === /** @type {ColorItem} */ (item).color; } if (itemType === "shape") { return ( /** @type {ShapeItem} */ (this.storedItem).definition.getHash() === /** @type {ShapeItem} */ (item).definition.getHash() ); } return false; } /** * Returns whether the storage is full * @returns {boolean} */ getIsFull() { return this.storedCount >= this.maximumStorage; } /** * @param {BaseItem} item */ takeItem(item) { this.storedItem = item; this.storedCount++; } } /***/ }), /***/ "./src/js/game/components/underground_belt.js": /*!****************************************************!*\ !*** ./src/js/game/components/underground_belt.js ***! \****************************************************/ /*! exports provided: enumUndergroundBeltMode, UndergroundBeltComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumUndergroundBeltMode", function() { return enumUndergroundBeltMode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UndergroundBeltComponent", function() { return UndergroundBeltComponent; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); /** @enum {string} */ const enumUndergroundBeltMode = { sender: "sender", receiver: "receiver", }; /** * @typedef {{ * entity: Entity, * distance: number * }} LinkedUndergroundBelt */ class UndergroundBeltComponent extends _component__WEBPACK_IMPORTED_MODULE_3__["Component"] { static getId() { return "UndergroundBelt"; } static getSchema() { return { pendingItems: _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].array(_savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].pair(_item_resolver__WEBPACK_IMPORTED_MODULE_5__["typeItemSingleton"], _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].float)), }; } duplicateWithoutContents() { return new UndergroundBeltComponent({ mode: this.mode, tier: this.tier, }); } /** * * @param {object} param0 * @param {enumUndergroundBeltMode=} param0.mode As which type of belt the entity acts * @param {number=} param0.tier */ constructor({ mode = enumUndergroundBeltMode.sender, tier = 0 }) { super(); this.mode = mode; this.tier = tier; /** @type {Array<{ item: BaseItem, progress: number }>} */ this.consumptionAnimations = []; /** * Used on both receiver and sender. * Reciever: Used to store the next item to transfer, and to block input while doing this * Sender: Used to store which items are currently "travelling" * @type {Array<[BaseItem, number]>} Format is [Item, remaining seconds until transfer/ejection] */ this.pendingItems = []; /** * The linked entity, used to speed up performance. This contains either * the entrance or exit depending on the tunnel type * @type {LinkedUndergroundBelt} */ this.cachedLinkedEntity = null; } /** * Tries to accept an item from an external source like a regular belt or building * @param {BaseItem} item * @param {number} beltSpeed How fast this item travels */ tryAcceptExternalItem(item, beltSpeed) { if (this.mode !== enumUndergroundBeltMode.sender) { // Only senders accept external items return false; } if (this.pendingItems.length > 0) { // We currently have a pending item return false; } this.pendingItems.push([item, 0]); return true; } /** * Tries to accept a tunneled item * @param {BaseItem} item * @param {number} travelDistance How many tiles this item has to travel * @param {number} beltSpeed How fast this item travels */ tryAcceptTunneledItem(item, travelDistance, beltSpeed) { if (this.mode !== enumUndergroundBeltMode.receiver) { // Only receivers can accept tunneled items return false; } // Notice: We assume that for all items the travel distance is the same const maxItemsInTunnel = (2 + travelDistance) / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; if (this.pendingItems.length >= maxItemsInTunnel) { // Simulate a real belt which gets full at some point return false; } // NOTICE: // This corresponds to the item ejector - it needs 0.5 additional tiles to eject the item. // So instead of adding 1 we add 0.5 only. // Additionally it takes 1 tile for the acceptor which we just add on top. const travelDuration = (travelDistance + 1.5) / beltSpeed / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; this.pendingItems.push([item, travelDuration]); // Sort so we can only look at the first ones this.pendingItems.sort((a, b) => a[1] - b[1]); return true; } } /***/ }), /***/ "./src/js/game/components/wire.js": /*!****************************************!*\ !*** ./src/js/game/components/wire.js ***! \****************************************/ /*! exports provided: enumWireType, WireComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumWireType", function() { return enumWireType; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WireComponent", function() { return WireComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /** @enum {string} */ const enumWireType = { regular: "regular", turn: "turn", split: "split", cross: "cross", }; class WireComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "Wire"; } duplicateWithoutContents() { return new WireComponent({ type: this.type }); } /** * @param {object} param0 * @param {enumWireType=} param0.type */ constructor({ type = enumWireType.regular }) { super(); this.type = type; /** * @type {import("../systems/wire").WireNetwork} */ this.linkedNetwork = null; } /** * Returns the local connections * @returns {import("../../core/utils").DirectionalObject} */ getLocalConnections() { return { top: true, right: false, bottom: true, left: false, }; // switch (this.type) { // case enumWireType.regular: // return { // top: true, // right: false, // bottom: true, // left: false, // }; // case enumWireType.turn: // return { // top: false, // right: true, // bottom: true, // left: false, // }; // case enumWireType.split: // return { // top: false, // right: true, // bottom: true, // left: true, // }; // default: // assertAlways(false, "Invalid wire type: " + this.type); // } } } /***/ }), /***/ "./src/js/game/components/wire_tunnel.js": /*!***********************************************!*\ !*** ./src/js/game/components/wire_tunnel.js ***! \***********************************************/ /*! exports provided: WireTunnelComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WireTunnelComponent", function() { return WireTunnelComponent; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); class WireTunnelComponent extends _component__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return "WireTunnel"; } duplicateWithoutContents() { return new WireTunnelComponent({ multipleDirections: this.multipleDirections }); } /** * @param {object} param0 * @param {boolean=} param0.multipleDirections */ constructor({ multipleDirections = true }) { super(); this.multipleDirections = multipleDirections; /** * Linked network, only if its not multiple directions * @type {Array} */ this.linkedNetworks = []; } } /***/ }), /***/ "./src/js/game/components/wired_pins.js": /*!**********************************************!*\ !*** ./src/js/game/components/wired_pins.js ***! \**********************************************/ /*! exports provided: enumPinSlotType, WiredPinsComponent */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumPinSlotType", function() { return enumPinSlotType; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WiredPinsComponent", function() { return WiredPinsComponent; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _item_resolver__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../item_resolver */ "./src/js/game/item_resolver.js"); /** @enum {string} */ const enumPinSlotType = { logicalEjector: "logicalEjector", logicalAcceptor: "logicalAcceptor", }; /** @typedef {{ * pos: Vector, * type: enumPinSlotType, * direction: enumDirection * }} WirePinSlotDefinition */ /** @typedef {{ * pos: Vector, * type: enumPinSlotType, * direction: enumDirection, * value: BaseItem, * linkedNetwork: import("../systems/wire").WireNetwork * }} WirePinSlot */ class WiredPinsComponent extends _component__WEBPACK_IMPORTED_MODULE_2__["Component"] { static getId() { return "WiredPins"; } static getSchema() { return { slots: _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].array( _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].structured({ value: _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].nullable(_item_resolver__WEBPACK_IMPORTED_MODULE_4__["typeItemSingleton"]), }) ), }; } /** * * @param {object} param0 * @param {Array} param0.slots */ constructor({ slots = [] }) { super(); this.setSlots(slots); } duplicateWithoutContents() { const slots = []; for (let i = 0; i < this.slots.length; ++i) { const slot = this.slots[i]; slots.push({ pos: slot.pos.copy(), type: slot.type, direction: slot.direction, }); } return new WiredPinsComponent({ slots }); } /** * Sets the slots of this building * @param {Array} slots */ setSlots(slots) { /** @type {Array} */ this.slots = []; for (let i = 0; i < slots.length; ++i) { const slotData = slots[i]; this.slots.push({ pos: slotData.pos, type: slotData.type, direction: slotData.direction, value: null, linkedNetwork: null, }); } } } /***/ }), /***/ "./src/js/game/core.js": /*!*****************************!*\ !*** ./src/js/game/core.js ***! \*****************************/ /*! exports provided: GameCore */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameCore", function() { return GameCore; }); /* harmony import */ var _core_buffer_maintainer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/buffer_maintainer */ "./src/js/core/buffer_maintainer.js"); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_dpi_manager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/dpi_manager */ "./src/js/core/dpi_manager.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_savegame__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../savegame/savegame */ "./src/js/savegame/savegame.js"); /* harmony import */ var _savegame_savegame_serializer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../savegame/savegame_serializer */ "./src/js/savegame/savegame_serializer.js"); /* harmony import */ var _automatic_save__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./automatic_save */ "./src/js/game/automatic_save.js"); /* harmony import */ var _buildings_hub__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./buildings/hub */ "./src/js/game/buildings/hub.js"); /* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./camera */ "./src/js/game/camera.js"); /* harmony import */ var _dynamic_tickrate__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./dynamic_tickrate */ "./src/js/game/dynamic_tickrate.js"); /* harmony import */ var _entity_manager__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./entity_manager */ "./src/js/game/entity_manager.js"); /* harmony import */ var _game_system_manager__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./game_system_manager */ "./src/js/game/game_system_manager.js"); /* harmony import */ var _hub_goals__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./hub_goals */ "./src/js/game/hub_goals.js"); /* harmony import */ var _hud_hud__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./hud/hud */ "./src/js/game/hud/hud.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _logic__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./logic */ "./src/js/game/logic.js"); /* harmony import */ var _map_view__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./map_view */ "./src/js/game/map_view.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _production_analytics__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./production_analytics */ "./src/js/game/production_analytics.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _shape_definition_manager__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./shape_definition_manager */ "./src/js/game/shape_definition_manager.js"); /* harmony import */ var _sound_proxy__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./sound_proxy */ "./src/js/game/sound_proxy.js"); /* harmony import */ var _time_game_time__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./time/game_time */ "./src/js/game/time/game_time.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); /* harmony import */ var _core_sprites__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../core/sprites */ "./src/js/core/sprites.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_6__["createLogger"])("ingame/core"); // Store the canvas so we can reuse it later /** @type {HTMLCanvasElement} */ let lastCanvas = null; /** @type {CanvasRenderingContext2D} */ let lastContext = null; /** * The core manages the root and represents the whole game. It wraps the root, since * the root class is just a data holder. */ class GameCore { /** @param {Application} app */ constructor(app) { this.app = app; /** @type {GameRoot} */ this.root = null; /** * Set to true at the beginning of a logic update and cleared when its finished. * This is to prevent doing a recursive logic update which can lead to unexpected * behaviour. */ this.duringLogicUpdate = false; // Cached this.boundInternalTick = this.updateLogic.bind(this); } /** * Initializes the root object which stores all game related data. The state * is required as a back reference (used sometimes) * @param {import("../states/ingame").InGameState} parentState * @param {Savegame} savegame */ initializeRoot(parentState, savegame) { // Construct the root element, this is the data representation of the game this.root = new _root__WEBPACK_IMPORTED_MODULE_25__["GameRoot"](this.app); this.root.gameState = parentState; this.root.keyMapper = parentState.keyActionMapper; this.root.savegame = savegame; this.root.gameWidth = this.app.screenWidth; this.root.gameHeight = this.app.screenHeight; // Initialize canvas element & context this.internalInitCanvas(); // Members const root = this.root; // This isn't nice, but we need it right here root.keyMapper = new _key_action_mapper__WEBPACK_IMPORTED_MODULE_20__["KeyActionMapper"](root, this.root.gameState.inputReciever); // Needs to come first root.dynamicTickrate = new _dynamic_tickrate__WEBPACK_IMPORTED_MODULE_15__["DynamicTickrate"](root); // Init classes root.camera = new _camera__WEBPACK_IMPORTED_MODULE_14__["Camera"](root); root.map = new _map_view__WEBPACK_IMPORTED_MODULE_22__["MapView"](root); root.logic = new _logic__WEBPACK_IMPORTED_MODULE_21__["GameLogic"](root); root.hud = new _hud_hud__WEBPACK_IMPORTED_MODULE_19__["GameHUD"](root); root.time = new _time_game_time__WEBPACK_IMPORTED_MODULE_28__["GameTime"](root); root.automaticSave = new _automatic_save__WEBPACK_IMPORTED_MODULE_12__["AutomaticSave"](root); root.soundProxy = new _sound_proxy__WEBPACK_IMPORTED_MODULE_27__["SoundProxy"](root); // Init managers root.entityMgr = new _entity_manager__WEBPACK_IMPORTED_MODULE_16__["EntityManager"](root); root.systemMgr = new _game_system_manager__WEBPACK_IMPORTED_MODULE_17__["GameSystemManager"](root); root.shapeDefinitionMgr = new _shape_definition_manager__WEBPACK_IMPORTED_MODULE_26__["ShapeDefinitionManager"](root); root.hubGoals = new _hub_goals__WEBPACK_IMPORTED_MODULE_18__["HubGoals"](root); root.productionAnalytics = new _production_analytics__WEBPACK_IMPORTED_MODULE_24__["ProductionAnalytics"](root); root.buffers = new _core_buffer_maintainer__WEBPACK_IMPORTED_MODULE_0__["BufferMaintainer"](root); // Initialize the hud once everything is loaded this.root.hud.initialize(); // Initial resize event, it might be possible that the screen // resized later during init tho, which is why will emit it later // again anyways this.resize(this.app.screenWidth, this.app.screenHeight); if (true) { // @ts-ignore window.globalRoot = root; } } /** * Initializes a new game, this means creating a new map and centering on the * playerbase * */ initNewGame() { logger.log("Initializing new game"); this.root.gameIsFresh = true; this.root.map.seed = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["randomInt"])(0, 100000); // Place the hub const hub = _core_global_registries__WEBPACK_IMPORTED_MODULE_5__["gMetaBuildingRegistry"].findByClass(_buildings_hub__WEBPACK_IMPORTED_MODULE_13__["MetaHubBuilding"]).createEntity({ root: this.root, origin: new _core_vector__WEBPACK_IMPORTED_MODULE_9__["Vector"](-2, -2), rotation: 0, originalRotation: 0, rotationVariant: 0, variant: _meta_building__WEBPACK_IMPORTED_MODULE_23__["defaultBuildingVariant"], }); this.root.map.placeStaticEntity(hub); this.root.entityMgr.registerEntity(hub); } /** * Inits an existing game by loading the raw savegame data and deserializing it. * Also runs basic validity checks. */ initExistingGame() { logger.log("Initializing existing game"); const serializer = new _savegame_savegame_serializer__WEBPACK_IMPORTED_MODULE_11__["SavegameSerializer"](); try { this.root.savegame.migrateBeforeGameEnter(this.root.savegame.currentData); const status = serializer.deserialize(this.root.savegame.getCurrentDump(), this.root); if (!status.isGood()) { logger.error("savegame-deserialize-failed:" + status.reason); return false; } } catch (ex) { logger.error("Exception during deserialization:", ex); return false; } this.root.gameIsFresh = false; return true; } /** * Initializes the render canvas */ internalInitCanvas() { let canvas, context; if (!lastCanvas) { logger.log("Creating new canvas"); canvas = document.createElement("canvas"); canvas.id = "ingame_Canvas"; canvas.setAttribute("opaque", "true"); canvas.setAttribute("webkitOpaque", "true"); canvas.setAttribute("mozOpaque", "true"); this.root.gameState.getDivElement().appendChild(canvas); context = canvas.getContext("2d", { alpha: false }); lastCanvas = canvas; lastContext = context; } else { logger.log("Reusing canvas"); if (lastCanvas.parentElement) { lastCanvas.parentElement.removeChild(lastCanvas); } this.root.gameState.getDivElement().appendChild(lastCanvas); canvas = lastCanvas; context = lastContext; lastContext.clearRect(0, 0, lastCanvas.width, lastCanvas.height); } // globalConfig.smoothing.smoothMainCanvas = getDeviceDPI() < 1.5; // globalConfig.smoothing.smoothMainCanvas = true; canvas.classList.toggle("smoothed", _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].smoothing.smoothMainCanvas); // Oof, use :not() instead canvas.classList.toggle("unsmoothed", !_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].smoothing.smoothMainCanvas); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].smoothing.smoothMainCanvas) { Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["enableImageSmoothing"])(context); } else { Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["disableImageSmoothing"])(context); } this.root.canvas = canvas; this.root.context = context; Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["registerCanvas"])(canvas, context); } /** * Destructs the root, freeing all resources */ destruct() { if (lastCanvas && lastCanvas.parentElement) { lastCanvas.parentElement.removeChild(lastCanvas); } this.root.destruct(); delete this.root; this.root = null; this.app = null; } tick(deltaMs) { const root = this.root; // Extract current real time root.time.updateRealtimeNow(); // Camera is always updated, no matter what root.camera.update(deltaMs); // Perform logic ticks this.root.time.performTicks(deltaMs, this.boundInternalTick); // Update analytics root.productionAnalytics.update(); // Update automatic save after everything finished root.automaticSave.update(); return true; } shouldRender() { if (this.root.queue.requireRedraw) { return true; } if (this.root.hud.shouldPauseRendering()) { return false; } // Do not render if (!this.app.isRenderable()) { return false; } return true; } updateLogic() { const root = this.root; root.dynamicTickrate.beginTick(); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.disableLogicTicks) { root.dynamicTickrate.endTick(); return true; } this.duringLogicUpdate = true; // Update entities, this removes destroyed entities root.entityMgr.update(); // IMPORTANT: At this point, the game might be game over. Stop if this is the case if (!this.root) { logger.log("Root destructed, returning false"); root.dynamicTickrate.endTick(); return false; } root.systemMgr.update(); // root.particleMgr.update(); this.duringLogicUpdate = false; root.dynamicTickrate.endTick(); return true; } resize(w, h) { this.root.gameWidth = w; this.root.gameHeight = h; Object(_core_dpi_manager__WEBPACK_IMPORTED_MODULE_3__["resizeHighDPICanvas"])(this.root.canvas, w, h, _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].smoothing.smoothMainCanvas); this.root.signals.resized.dispatch(w, h); this.root.queue.requireRedraw = true; } postLoadHook() { logger.log("Dispatching post load hook"); this.root.signals.postLoadHook.dispatch(); if (!this.root.gameIsFresh) { // Also dispatch game restored hook on restored savegames this.root.signals.gameRestored.dispatch(); } this.root.gameInitialized = true; if (!this.root.gameIsFresh) { this.root.savegame.migrateAfterGameEnter(this.root.savegame.currentData, this.root); } } draw() { const root = this.root; const systems = root.systemMgr.systems; this.root.dynamicTickrate.onFrameRendered(); if (!this.shouldRender()) { // Always update hud tho root.hud.update(); return; } this.root.signals.gameFrameStarted.dispatch(); root.queue.requireRedraw = false; // Gather context and save all state const context = root.context; context.save(); if (true) { context.fillStyle = "#a10000"; context.fillRect(0, 0, window.innerWidth * 3, window.innerHeight * 3); } // Compute optimal zoom level and atlas scale const zoomLevel = root.camera.zoomLevel; const lowQuality = root.app.settings.getAllSettings().lowQualityTextures; const effectiveZoomLevel = (zoomLevel / _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].assetsDpi) * Object(_core_dpi_manager__WEBPACK_IMPORTED_MODULE_3__["getDeviceDPI"])() * _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].assetsSharpness; let desiredAtlasScale = "0.25"; if (effectiveZoomLevel > 0.8 && !lowQuality) { desiredAtlasScale = _core_sprites__WEBPACK_IMPORTED_MODULE_30__["ORIGINAL_SPRITE_SCALE"]; } else if (effectiveZoomLevel > 0.4 && !lowQuality) { desiredAtlasScale = "0.5"; } // Construct parameters required for drawing const params = new _core_draw_parameters__WEBPACK_IMPORTED_MODULE_4__["DrawParameters"]({ context: context, visibleRect: root.camera.getVisibleRect(), desiredAtlasScale, zoomLevel, root: root, }); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.testCulling) { context.clearRect(0, 0, root.gameWidth, root.gameHeight); } // Transform to world space if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.testClipping) { params.visibleRect = params.visibleRect.expandedInAllDirections( -200 / this.root.camera.zoomLevel ); } root.camera.transform(context); window.assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame start"); // Update hud root.hud.update(); // Main rendering order // ----- if (this.root.camera.getIsMapOverlayActive()) { // Map overview root.map.drawOverlay(params); } else { // Background (grid, resources, etc) root.map.drawBackground(params); // Belt items systems.belt.drawBeltItems(params); // Miner & Static map entities etc. root.map.drawForeground(params); // HUB Overlay systems.hub.draw(params); // Green wires overlay root.hud.parts.wiresOverlay.draw(params); if (this.root.currentLayer === "wires") { // Static map entities root.map.drawWiresForegroundLayer(params); } } if (true) { root.map.drawStaticEntityDebugOverlays(params); } if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.renderBeltPaths) { systems.belt.drawBeltPathDebug(params); } // END OF GAME CONTENT // ----- // Finally, draw the hud. Nothing should come after that root.hud.draw(params); window.assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame end before restore"); // Restore to screen space context.restore(); // Restore parameters params.zoomLevel = 1; params.desiredAtlasScale = _core_sprites__WEBPACK_IMPORTED_MODULE_30__["ORIGINAL_SPRITE_SCALE"]; params.visibleRect = new _core_rectangle__WEBPACK_IMPORTED_MODULE_7__["Rectangle"](0, 0, this.root.gameWidth, this.root.gameHeight); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.testClipping) { params.visibleRect = params.visibleRect.expandedInAllDirections(-200); } // Draw overlays, those are screen space root.hud.drawOverlays(params); window.assert(context.globalAlpha === 1.0, "context.globalAlpha not 1 on frame end"); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.simulateSlowRendering) { let sum = 0; for (let i = 0; i < 1e8; ++i) { sum += i; } if (Math.random() > 0.95) { console.log(sum); } } if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.showAtlasInfo) { context.font = "13px GameFont"; context.fillStyle = "blue"; context.fillText( "Atlas: " + desiredAtlasScale + " / Zoom: " + Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["round2Digits"])(zoomLevel) + " / Effective Zoom: " + Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["round2Digits"])(effectiveZoomLevel), 20, 600 ); const stats = this.root.buffers.getStats(); context.fillText( "Buffers: " + stats.rootKeys + " root keys, " + stats.subKeys + " sub keys / buffers / VRAM: " + Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["round2Digits"])(stats.vramBytes / (1024 * 1024)) + " MB", 20, 620 ); } if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.testClipping) { context.strokeStyle = "red"; context.lineWidth = 1; context.beginPath(); context.rect(200, 200, this.root.gameWidth - 400, this.root.gameHeight - 400); context.stroke(); } } } /***/ }), /***/ "./src/js/game/custom/colors.js": /*!**************************************!*\ !*** ./src/js/game/custom/colors.js ***! \**************************************/ /*! exports provided: customColors, registerCustomColor */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "customColors", function() { return customColors; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "registerCustomColor", function() { return registerCustomColor; }); /** @enum {string} */ const customColors = []; /** * @param {Object} colorData * @param {string} colorData.id * @param {string} colorData.code * @param {string} colorData.hex * @param {string[][] | string[]} [colorData.mixingFrom] * @param {Object.} [colorData.mixing] * @param {boolean} [colorData.spawnable] * @param {number} [colorData.minDistance] */ function registerCustomColor(colorData) { customColors.push(colorData); } // registerCustomColor({ // id: "black", // code: "k", // hex: "#333333", // mixing: { // white: "uncolored", // uncolored: "uncolored", // any: "black", // }, // spawnable: true, // minDistance: 5, // }); /***/ }), /***/ "./src/js/game/custom/gameData.js": /*!****************************************!*\ !*** ./src/js/game/custom/gameData.js ***! \****************************************/ /*! exports provided: Component, types, gItemRegistry, BaseItem, Vector, globalConfig, ItemAcceptorComponent, ItemEjectorComponent, enumItemProcessorTypes, ItemProcessorComponent, Entity, MetaBuilding, GameRoot, enumHubGoalRewards, T, formatItemsPerSecond, GameSystemWithFilter, DrawParameters, formatBigNumber, lerp, Loader, GameTime, ShapeItem, ColorItem, ShapeDefinition, enumInvertedColors, ModSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ModSystem", function() { return ModSystem; }); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../component */ "./src/js/game/component.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Component", function() { return _component__WEBPACK_IMPORTED_MODULE_0__["Component"]; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "types", function() { return _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"]; }); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "gItemRegistry", function() { return _core_global_registries__WEBPACK_IMPORTED_MODULE_2__["gItemRegistry"]; }); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseItem", function() { return _base_item__WEBPACK_IMPORTED_MODULE_3__["BaseItem"]; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector", function() { return _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"]; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "globalConfig", function() { return _core_config__WEBPACK_IMPORTED_MODULE_5__["globalConfig"]; }); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ItemAcceptorComponent", function() { return _components_item_acceptor__WEBPACK_IMPORTED_MODULE_6__["ItemAcceptorComponent"]; }); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ItemEjectorComponent", function() { return _components_item_ejector__WEBPACK_IMPORTED_MODULE_7__["ItemEjectorComponent"]; }); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "enumItemProcessorTypes", function() { return _components_item_processor__WEBPACK_IMPORTED_MODULE_8__["enumItemProcessorTypes"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ItemProcessorComponent", function() { return _components_item_processor__WEBPACK_IMPORTED_MODULE_8__["ItemProcessorComponent"]; }); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Entity", function() { return _entity__WEBPACK_IMPORTED_MODULE_9__["Entity"]; }); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MetaBuilding", function() { return _meta_building__WEBPACK_IMPORTED_MODULE_10__["MetaBuilding"]; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GameRoot", function() { return _root__WEBPACK_IMPORTED_MODULE_11__["GameRoot"]; }); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "enumHubGoalRewards", function() { return _tutorial_goals__WEBPACK_IMPORTED_MODULE_12__["enumHubGoalRewards"]; }); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "T", function() { return _translations__WEBPACK_IMPORTED_MODULE_13__["T"]; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "formatItemsPerSecond", function() { return _core_utils__WEBPACK_IMPORTED_MODULE_14__["formatItemsPerSecond"]; }); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GameSystemWithFilter", function() { return _game_system_with_filter__WEBPACK_IMPORTED_MODULE_15__["GameSystemWithFilter"]; }); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DrawParameters", function() { return _core_draw_parameters__WEBPACK_IMPORTED_MODULE_16__["DrawParameters"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "formatBigNumber", function() { return _core_utils__WEBPACK_IMPORTED_MODULE_14__["formatBigNumber"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "lerp", function() { return _core_utils__WEBPACK_IMPORTED_MODULE_14__["lerp"]; }); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Loader", function() { return _core_loader__WEBPACK_IMPORTED_MODULE_17__["Loader"]; }); /* harmony import */ var _time_game_time__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../time/game_time */ "./src/js/game/time/game_time.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GameTime", function() { return _time_game_time__WEBPACK_IMPORTED_MODULE_18__["GameTime"]; }); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../items/shape_item */ "./src/js/game/items/shape_item.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShapeItem", function() { return _items_shape_item__WEBPACK_IMPORTED_MODULE_19__["ShapeItem"]; }); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorItem", function() { return _items_color_item__WEBPACK_IMPORTED_MODULE_20__["ColorItem"]; }); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShapeDefinition", function() { return _shape_definition__WEBPACK_IMPORTED_MODULE_21__["ShapeDefinition"]; }); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../colors */ "./src/js/game/colors.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "enumInvertedColors", function() { return _colors__WEBPACK_IMPORTED_MODULE_22__["enumInvertedColors"]; }); /* harmony import */ var _systems_item_processor__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../systems/item_processor */ "./src/js/game/systems/item_processor.js"); /* harmony import */ var _components_storage__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../components/storage */ "./src/js/game/components/storage.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); // export { enumItemType } from "../base_item"; /** * @typedef {Object} ModProcessData * @property {BaseItem[]} items * @property {boolean} trackProduction * @property {Entity} entity * @property {Array<{item: BaseItem, requiredSlot?: number, preferredSlot?: number}>} outItems * @property {ItemProcessorSystem} system * @property {Array.<{ item: BaseItem, sourceSlot: number }>} itemsBySlot * @property {Array.<{ item: BaseItem, sourceSlot: number }>} itemsRaw */ /** * @callback ModProcess * @param {ModProcessData} data * @returns {boolean} trackProduction */ /** * @typedef {Object} ModData * @property {string} id * @property {typeof MetaBuilding} building * @property {typeof Component} [component] * @property {typeof GameSystemWithFilter} [system] * @property {number} toolbar * @property {Object|string} sprite * @property {Object|string} spriteBp * @property {ModProcess} process * @property {string} Tname * @property {string} Tdesc * @property {number} speed * @property {string} [speedClass] * @property {typeof MetaBuilding} meta * @property {number} variantId * @property {string|number} keyCode * @property {number} toolbarIndex * @property {{shape: string, required: number, reward: string, title: string, desc: string, tutorial?: Object, sort_index?: number}} [goal] * @property {Object} [goal.tutorial] */ /** * @typedef {Object} ModLevel * @property {string} id * @property {{ shape: string, required: number, reward: string, title: string, desc: string, sort_index?: number} | {fixed: true, title: string, desc: string, minLevel: number, maxLevel: number, baseCount: number, countPerLevel: number, shape: string, reward: string}} [goal] */ /** @param {ModProcessData} */ /** @type {ModData} */ // /** @typedef {import('../gameData').ModData} ModData */ // /** @typedef {import('../gameData').ModProcessData} ModProcessData */ function ModSystem(id, component) { return class ModSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_15__["GameSystemWithFilter"] { constructor(root) { super(root, [component]); this.drawnUids = new Set(); this.root.signals.gameFrameStarted.add(this.clearDrawnUids, this); } clearDrawnUids() { this.drawnUids.clear(); } update() { for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; let comp = entity.components[id]; this.updateEntity(entity, comp); } } /** * @param {Entity} entity * @param {Component} comp * @returns {any} */ updateEntity(entity, comp) { return "abstact"; } /** * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const comp = entity.components[id]; if (!comp) { continue; } if (this.drawnUids.has(entity.uid)) { continue; } this.drawnUids.add(entity.uid); this.drawEntity(parameters.context, entity, comp, parameters); } } /** * @param {CanvasRenderingContext2D} context * @param {Entity} entity * @param {Component} [comp] * @param {DrawParameters} [parameters] * @returns {any} */ drawEntity(context, entity, comp, parameters) { return "abstact"; } }; } /***/ }), /***/ "./src/js/game/custom/modBuildings.js": /*!********************************************!*\ !*** ./src/js/game/custom/modBuildings.js ***! \********************************************/ /*! exports provided: allCustomBuildingData, customBuildingData, getCustomBuildingSystemsNulled, internalInitSystemsAddAt */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allCustomBuildingData", function() { return allCustomBuildingData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "customBuildingData", function() { return customBuildingData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCustomBuildingSystemsNulled", function() { return getCustomBuildingSystemsNulled; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "internalInitSystemsAddAt", function() { return internalInitSystemsAddAt; }); /* harmony import */ var _hud_parts_buildings_toolbar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../hud/parts/buildings_toolbar */ "./src/js/game/hud/parts/buildings_toolbar.js"); /* harmony import */ var _hud_parts_tools_toolbar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../hud/parts/tools_toolbar */ "./src/js/game/hud/parts/tools_toolbar.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _modSpriteDrawer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modSpriteDrawer */ "./src/js/game/custom/modSpriteDrawer.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _hud_parts_interactive_tutorial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../hud/parts/interactive_tutorial */ "./src/js/game/hud/parts/interactive_tutorial.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./gameData */ "./src/js/game/custom/gameData.js"); let allCustomBuildingData = []; const customBuildingData = {}; const localMods = __webpack_require__("./src/js/game/custom/mods sync .*\\.js/"); for (let key of localMods.keys()) { let mod = localMods(key).default; if (!Array.isArray(mod)) { mod = [mod]; } for (let entry of mod) { allCustomBuildingData.push(entry); } } for (let custom of allCustomBuildingData) { if (!customBuildingData[custom.id]) { customBuildingData[custom.id] = custom; } else { customBuildingData[custom.id] = Object.assign({}, customBuildingData[custom.id], custom); } } allCustomBuildingData = Object.values(customBuildingData); allCustomBuildingData.sort((a, b) => (a.variantId || 1e4) - (b.variantId || 1e4)); for (let custom of allCustomBuildingData) { addCustom(custom); } globalThis.addCustom = addCustom; globalThis.gameData = _gameData__WEBPACK_IMPORTED_MODULE_8__; globalThis.addMod = addMod; function addMod(mod) { addCustom(mod(_gameData__WEBPACK_IMPORTED_MODULE_8__)); } function addCustom(custom) { Object.assign(customBuildingData[custom.id], custom); if (custom.goal) { if (!custom.goal.fixed) { if (_tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"].find(e => e.reward == custom.goal.reward)) { let index = _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"].findIndex(e => e.reward == custom.goal.reward); _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"].splice(index, 1); } _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"].push(custom.goal); _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"].sort((a, b) => (a.sort_index || a.required) - (b.sort_index || b.required)); } else { if (!custom.goal.reward) { custom.goal.reward = "no_reward_freeplay"; } custom.goal.shape = custom.goal.shape || {}; if (typeof custom.goal.shape != "string") { custom.goal.shape.holeTier = custom.goal.shape.holeTier || 1; custom.goal.shape.shapeTier = custom.goal.shape.shapeTier || 1; custom.goal.shape.colorTier = custom.goal.shape.colorTier || 1; custom.goal.shape.layerTier = custom.goal.shape.layerTier || 1; } custom.goal.minLevel = custom.goal.minLevel || 1; custom.goal.maxLevel = custom.goal.maxLevel || 1; _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["fixedGoals"].push(custom.goal); } if (custom.goal.reward) { if (!custom.goal.reward.includes("reward_")) { custom.goal.reward = "reward_" + custom.goal.reward; } _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["enumHubGoalRewards"][custom.goal.reward] = custom.goal.reward; if (!_translations__WEBPACK_IMPORTED_MODULE_3__["T"].storyRewards[custom.goal.reward]) { _translations__WEBPACK_IMPORTED_MODULE_3__["T"].storyRewards[custom.goal.reward] = { title: custom.goal.title || custom.Tname || custom.id, desc: "no description", }; } if (custom.goal.desc) { _translations__WEBPACK_IMPORTED_MODULE_3__["T"].storyRewards[custom.goal.reward].desc = custom.goal.desc; } } if (custom.goal.tutorial) { for (let step of custom.goal.tutorial) { _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.interactiveTutorial.hints[step.id] = step.Tdesc; } } } if (custom.building) { if (!custom.variant) { custom.variant = "default"; } if (custom.process) { _components_item_processor__WEBPACK_IMPORTED_MODULE_2__["enumItemProcessorTypes"][custom.id] = custom.id; } if (!custom.Tname) { custom.Tname = custom.id; } if (!custom.Tdesc) { custom.Tdesc = ""; } if (!_translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings[custom.id]) { _translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings[custom.id] = {}; } _translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings[custom.id][custom.variant] = { name: custom.Tname, description: custom.Tdesc, }; if (!custom.speed) { custom.speed = 1; } if (!custom.speedClass) { custom.speedClass = "belt"; } if (custom.meta && custom.toolbarIndex) { custom.meta.toolbarIndex = custom.toolbarIndex; } if (custom.meta && custom.toolbar == 0) { _hud_parts_buildings_toolbar__WEBPACK_IMPORTED_MODULE_0__["supportedBuildings"].push(custom.meta); sortToolbar(_hud_parts_buildings_toolbar__WEBPACK_IMPORTED_MODULE_0__["supportedBuildings"]); } if (custom.meta && custom.toolbar == 2) { _hud_parts_tools_toolbar__WEBPACK_IMPORTED_MODULE_1__["supportedBuildings"].push(custom.meta); sortToolbar(_hud_parts_tools_toolbar__WEBPACK_IMPORTED_MODULE_1__["supportedBuildings"]); } if (custom.keyCode) { _key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["KEYMAPPINGS"].buildings[custom.id] = { keyCode: Object(_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["keyCodeOf"])(custom.keyCode), id: custom.id }; _translations__WEBPACK_IMPORTED_MODULE_3__["T"].keybindings.mappings[custom.id] = custom.Tname; } } if (custom.sprite) { if (!(custom.sprite[0] || custom.sprite).sprite) { (custom.sprite[0] || custom.sprite).sprite = `sprites/buildings/${custom.id}${ custom.variant == "default" ? "" : "-" + custom.variant }.png`; } Object(_modSpriteDrawer__WEBPACK_IMPORTED_MODULE_4__["addSprite"])(custom.sprite); if (custom.spriteBp) { if (!(custom.spriteBp[0] || custom.spriteBp).sprite) { (custom.spriteBp[0] || custom.spriteBp).sprite = `sprites/blueprints/${custom.id}${ custom.variant == "default" ? "" : "-" + custom.variant }.png`; } (custom.spriteBp[0] || custom.spriteBp).blueprint = true; Object(_modSpriteDrawer__WEBPACK_IMPORTED_MODULE_4__["addSprite"])(custom.spriteBp); } } } function sortToolbar(toolbar) { let copy = _hud_parts_tools_toolbar__WEBPACK_IMPORTED_MODULE_1__["supportedBuildings"].slice().sort((a, b) => (a.toolbarIndex || 0) - (b.toolbarIndex || 0)); while (toolbar.length) toolbar.pop(); for (let meta of copy) { if (!meta.toolbarIndex) { toolbar.push(meta); } else { toolbar.splice(meta.toolbarIndex, 0, meta); } } } function getCustomBuildingSystemsNulled() { let r = {}; for (let k in allCustomBuildingData) { let data = allCustomBuildingData[k]; if (!data.system) { continue; } r[data.id] = null; } return r; } /** * @param {number} order */ function internalInitSystemsAddAt(order, add) { let systems = Object.values(allCustomBuildingData).filter(data => { if (!data.system) return false; if (order <= 0) return data.sysOrder && data.sysOrder < order; if (order) return data.sysOrder && order <= data.sysOrder && data.sysOrder < order + 1; // NaN/undefined goes here return !data.sysOrder; }); systems.sort((a, b) => a.sysOrder - b.sysOrder); for (let data of systems) { add(data.id, data.system); } } /***/ }), /***/ "./src/js/game/custom/modSpriteDrawer.js": /*!***********************************************!*\ !*** ./src/js/game/custom/modSpriteDrawer.js ***! \***********************************************/ /*! exports provided: addSprite */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addSprite", function() { return addSprite; }); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /** * draws building base on 192m*192n cells context * @param {CanvasRenderingContext2D} ctx * @param {string} path */ function drawBaseLayer(ctx, path, bp) { let p = new Path2D(path); ctx.save(); // shadow: ctx.save(); ctx.fillStyle = "#91949e"; ctx.globalAlpha = 0.2; ctx.translate(6, 8); ctx.fill(p); ctx.restore(); // base: ctx.fillStyle = !bp ? "#dee1ea" : "#6CD1FF"; ctx.strokeStyle = !bp ? "#64666e" : "#56A7D8"; ctx.lineWidth = 6; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.miterLimit = 4; ctx.fill(p); ctx.stroke(p); ctx.restore(); } /** * draws a color-filled path on 192m*192n cells context * @param {CanvasRenderingContext2D} ctx * @param {string} path */ function drawfillShape(ctx, path, color) { let p = new Path2D(path); ctx.save(); // shadow: ctx.save(); ctx.fillStyle = "#91949e"; ctx.globalAlpha = 0.2; ctx.translate(6, 8); ctx.fill(p); ctx.restore(); // base: ctx.fillStyle = color; ctx.strokeStyle = "#64666e"; ctx.lineWidth = 10; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.miterLimit = 4; ctx.stroke(p); ctx.fill(p); ctx.restore(); } function drawShape(ctx, path, color1, color2) { let p = new Path2D(path); ctx.save(); // base: ctx.fillStyle = color1; ctx.strokeStyle = color2; ctx.lineWidth = 10; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.miterLimit = 4; ctx.stroke(p); ctx.fill(p); ctx.restore(); } function addSprite(data) { let info = data[0] || data; if (info.url) { drawSpriteFromImage(info.sprite, info.url, info); return; } let layers = data.layers || data.slice(1); drawSpriteFromJson(info.sprite, layers, info); } function drawSpriteFromJson(sprite, layers, info) { function draw({ context, canvas2, context2 }) { if (info.transparent) { for (let layer of layers) { if (layer.fill && layer.stroke) { drawShape(context2, layer.path, layer.fill, layer.stroke); } else if (layer.fill) { drawfillShape(context, layer.path, layer.fill); } else if (layer.stroke) { throw "not implemented"; } else { drawBaseLayer(context, layer.path, true); } } context.save(); context.globalAlpha = 0x99 / 0xff; context.drawImage(canvas2, 0, 0); context.restore(); return; } for (let layer of layers) { if (layer.fill && layer.stroke) { drawShape(context, layer.path, layer.fill, layer.stroke); } else if (layer.fill) { drawfillShape(context, layer.path, layer.fill); } else if (layer.stroke) { throw "not implemented"; } else { drawBaseLayer(context, layer.path, false); } } } _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].drawSprite(sprite, draw, { w: info.w, h: info.h }); } function drawSpriteFromImage(sprite, url, { w, h }) { /** @param {{context:CanvasRenderingContext2D}} data */ function draw({ context }) { let img = new Image(); img.onload = function () { context.drawImage(img, 0, 0); }; img.onerror = function () { context.fillStyle = "red"; context.fillRect(0, 0, w, h); context.fillStyle = "black"; context.fillText(sprite.split("/").pop(), 0, 0, w); }; img.src = url; } _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].drawSprite(sprite, draw, { w, h }, url); } /***/ }), /***/ "./src/js/game/custom/mods sync .*\\.js/": /*!***********************************************************!*\ !*** ./src/js/game/custom/mods sync nonrecursive .*\.js/ ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var map = { "./adder.js": "./src/js/game/custom/mods/adder.js", "./checker.js": "./src/js/game/custom/mods/checker.js", "./combiner.js": "./src/js/game/custom/mods/combiner.js", "./counter.js": "./src/js/game/custom/mods/counter.js", "./inverter.js": "./src/js/game/custom/mods/inverter.js", "./levels.js": "./src/js/game/custom/mods/levels.js", "./painter1.js": "./src/js/game/custom/mods/painter1.js", "./painter2.js": "./src/js/game/custom/mods/painter2.js", "./quaduo.js": "./src/js/game/custom/mods/quaduo.js", "./repeater.js": "./src/js/game/custom/mods/repeater.js", "./test_levels.js": "./src/js/game/custom/mods/test_levels.js", "./unstacker.js": "./src/js/game/custom/mods/unstacker.js" }; function webpackContext(req) { var id = webpackContextResolve(req); return __webpack_require__(id); } function webpackContextResolve(req) { if(!__webpack_require__.o(map, req)) { var e = new Error("Cannot find module '" + req + "'"); e.code = 'MODULE_NOT_FOUND'; throw e; } return map[req]; } webpackContext.keys = function webpackContextKeys() { return Object.keys(map); }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; webpackContext.id = "./src/js/game/custom/mods sync .*\\.js/"; /***/ }), /***/ "./src/js/game/custom/mods/adder.js": /*!******************************************!*\ !*** ./src/js/game/custom/mods/adder.js ***! \******************************************/ /*! exports provided: Sprite, SpriteBp, data, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteBp", function() { return SpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "data", function() { return data; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); _gameData__WEBPACK_IMPORTED_MODULE_0__["T"].buildings.virtual_processor.adder = { name: "Adder", description: "Stacks shapes, paints shapes, mixes colors" }; const Sprite = { sprite: "sprites/buildings/virtual_processor-adder.png", url: "./res/adder.png", w: 142, h: 142, }; const SpriteBp = { sprite: "sprites/blueprints/virtual_processor-adder.png", url: "./res/adder.png", w: 142, h: 142, }; // TODO: keyCode, toolbarIndex /** @type {ModData} */ const data = { id: "adder", sprite: Sprite, spriteBp: SpriteBp, }; const color_magenta = { id: "magenta", sprite: [{ w: 49, h: 49, sprite: "sprites/wires/display/magenta.png", }, { path: "M 1 1 L 1 48 48 48 48 1 Z", fill: "magenta", }], } const color_black = { id: "black", sprite: [{ w: 49, h: 49, sprite: "sprites/wires/display/black.png", }, { path: "M 1 1 L 1 48 48 48 48 1 Z", fill: "black", }], } /* harmony default export */ __webpack_exports__["default"] = ([data, color_magenta, color_black]); /***/ }), /***/ "./src/js/game/custom/mods/checker.js": /*!********************************************!*\ !*** ./src/js/game/custom/mods/checker.js ***! \********************************************/ /*! exports provided: TargetShapeCheckerComponent, MetaTargetShapeCheckerBuilding, TargetShapeCheckerSystem, targetShapeCheckerProcess, tscSprite, tscSpriteBp, checker, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TargetShapeCheckerComponent", function() { return TargetShapeCheckerComponent; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaTargetShapeCheckerBuilding", function() { return MetaTargetShapeCheckerBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TargetShapeCheckerSystem", function() { return TargetShapeCheckerSystem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "targetShapeCheckerProcess", function() { return targetShapeCheckerProcess; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tscSprite", function() { return tscSprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tscSpriteBp", function() { return tscSpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "checker", function() { return checker; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "checker"; const color = "#ff6000"; class TargetShapeCheckerComponent extends _gameData__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return id; } static getSchema() { return { filter: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].string, filterIndex: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].int, filterType: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].string, isfil: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].bool, storedItem: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].nullable(_gameData__WEBPACK_IMPORTED_MODULE_0__["types"].obj(_gameData__WEBPACK_IMPORTED_MODULE_0__["gItemRegistry"])), }; } constructor({ filter = "unset", filterIndex = 0, filterType = "unset", isfil = false, storedItem = null, }) { super(); this.filter = filter; this.filterIndex = filterIndex; this.filterType = filterType; this.isfil = isfil; /** * Currently stored item * @type {BaseItem} */ this.storedItem = storedItem; } duplicateWithoutContents() { return new TargetShapeCheckerComponent(this); } } class MetaTargetShapeCheckerBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } getDimensions() { return new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getSilhouetteColor() { return color; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(`reward_${id}`); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(id); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: id, }) ); entity.addComponent(new TargetShapeCheckerComponent({})); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: "top", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: "right", }, ], }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: ["bottom"], }, ], }) ); } } class TargetShapeCheckerSystem extends Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["ModSystem"])(id, TargetShapeCheckerComponent) { constructor(root) { super(root); this.storageOverlaySprite = _gameData__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite("sprites/misc/storage_overlay.png"); this.goal = ""; } update() { let newGoal = this.root.hubGoals.currentGoal.definition.getHash(); if (newGoal != this.goal) { for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; let ejectorComp = entity.components.ItemEjector; for (let slot of ejectorComp.slots) { slot.item = null; } } this.goal = newGoal; } } /** * @param {CanvasRenderingContext2D} context * @param {Entity} entity * @param {TargetShapeCheckerComponent} [tscComp] * @param {DrawParameters} [parameters] */ drawEntity(context, entity, tscComp, parameters) { const staticComp = entity.components.StaticMapEntity; const storedItem = tscComp.storedItem; const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); if (storedItem !== null) { storedItem.drawItemCenteredClipped(center.x, center.y, parameters, 30); } this.storageOverlaySprite.drawCached(parameters, center.x - 15, center.y + 15, 30, 15); context.font = "bold 10px GameFont"; context.textAlign = "center"; context.fillStyle = "#64666e"; context.fillText(tscComp.filterType, center.x, center.y + 25.5); context.textAlign = "left"; } } /** @param {ModProcessData} */ function targetShapeCheckerProcess({ items, trackProduction, entity, outItems, system }) { // console.log("targetShapeChecker PROCESSES"); const inputItem = items[0]; trackProduction = false; const tscComponent = entity.components[id]; if (!tscComponent.isfil && inputItem instanceof _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"]) { // setting filter type: let item = inputItem.getHash(); // color: if ( item.match( /(.[^u-].[u-].[u-].[u-]|.[u-].[^u-].[u-].[u-]|.[u-].[u-].[^u-].[u-]|.[u-].[u-].[u-].[^u-])$/ ) ) { let m = item.match(/([^u-])(.[u-])*$/); tscComponent.filterType = "color"; tscComponent.filterIndex = m.index; tscComponent.filter = m[0].slice(0, 1); tscComponent.isfil = true; let layer = item.split(":").length; let index = ((m.index % 9) - 1) / 2; let topKey = `${"--".repeat(index)}C${tscComponent.filter}${"--".repeat(3 - index)}`; let key = (topKey + ":").repeat(layer - 1) + topKey; tscComponent.storedItem = _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(key); } //shape: else if (item.match(/([^-][^-]------|--[^-][^-]----|----[^-][^-]--|------[^-][^-])$/)) { let m = item.match(/([^-][^-])(--)*$/); tscComponent.filterType = "shape"; tscComponent.filterIndex = m.index; tscComponent.filter = m[0].slice(0, 1); tscComponent.isfil = true; let layer = item.split(":").length; let index = (m.index % 9) / 2; let topKey = `${"--".repeat(index)}${tscComponent.filter}u${"--".repeat(3 - index)}`; let key = (topKey + ":").repeat(layer - 1) + topKey; tscComponent.storedItem = _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(key); } // hole: else if ( item.match( /(--[^-][^-][^-][^-][^-][^-]|[^-][^-]--[^-][^-][^-][^-]|[^-][^-][^-][^-]--[^-][^-]|[^-][^-][^-][^-][^-][^-]--)$/ ) ) { let m = item.match(/(--)([^-][^-])*$/); tscComponent.filterType = "hole"; tscComponent.filterIndex = m.index; tscComponent.filter = m[0].slice(0, 1); tscComponent.isfil = true; let layer = item.split(":").length; let index = (m.index % 9) / 2; let topKey = `${"Cu".repeat(index)}--${"Cu".repeat(3 - index)}`; let key = (topKey + ":").repeat(layer - 1) + topKey; tscComponent.storedItem = _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(key); } // uncolored: else if ( item.match( /(.u.[^u-].[^u-].[^u-]|.[^u-].u.[^u-].[^u-]|.[^u-].[^u-].u.[^u-]|.[^u-].[^u-].[^u-].u)$/ ) ) { let m = item.match(/(u)(.[^u])*$/); tscComponent.filterType = "uncolored"; tscComponent.filterIndex = m.index; tscComponent.filter = m[0].slice(0, 1); tscComponent.isfil = true; let layer = item.split(":").length; let index = ((m.index % 9) - 1) / 2; let topKey = `${"--".repeat(index)}C${tscComponent.filter}${"--".repeat(3 - index)}`; let key = (topKey + ":").repeat(layer - 1) + topKey; tscComponent.storedItem = _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(key); } return false; } if (tscComponent.isfil) { let goal = system.root.hubGoals.currentGoal.definition.getHash(); let matches = true; if (tscComponent.filterType == "color") { matches = goal[tscComponent.filterIndex] == tscComponent.filter; } else if (tscComponent.filterType == "uncolored") { matches = !goal[tscComponent.filterIndex] || goal[tscComponent.filterIndex] == tscComponent.filter; } else if (tscComponent.filterType == "shape") { matches = goal[tscComponent.filterIndex] == tscComponent.filter; } else if (tscComponent.filterType == "hole") { matches = !goal[tscComponent.filterIndex] || goal[tscComponent.filterIndex] == tscComponent.filter; } outItems.push({ item: inputItem, requiredSlot: matches ? 0 : 1, }); } return false; } const tscSprite = [ { // data: w: 192, h: 192, }, { // base: path: "M 11,31 v 130 l 20,20 h 130 l 20,-20 v -130 l -20,-20 h -130 z", }, { // red cross: path: "M 175,40 l 12,12 -12,12 12,12 -12,12 -12,-12 -12,12 -12,-12 12,-12 -12,-12 12,-12 12,12 z", fill: "red", }, { // green arrow: path: "M 40,35 l 30,-30 30,30 z", fill: "lightgreen", }, ]; const tscSpriteBp = [ { // data: w: 192, h: 192, transparent: true, }, { // base: path: "M 11,31 v 130 l 20,20 h 130 l 20,-20 v -130 l -20,-20 h -130 z", fill: "#6CD1FF", stroke: "#56A7D8", }, { // red cross: path: "M 175,40 l 12,12 -12,12 12,12 -12,12 -12,-12 -12,12 -12,-12 12,-12 -12,-12 12,-12 12,12 z", fill: "#5EB7ED", stroke: "#56A7D8", }, { // green arrow: path: "M 40,35 l 30,-30 30,30 z", fill: "#5EB7ED", stroke: "#56A7D8", }, ]; const tutorial = [ { id: `checker_build`, /** @param {GameRoot} root */ condition(root) { let entities = root.entityMgr.getAllWithComponent(TargetShapeCheckerComponent); return !entities.length; }, Tdesc: "Checker is VERY HARD TO EXPLAIN so here's tutorial. Build one for a start.", }, { id: `checker_shapes`, /** @param {GameRoot} root */ condition(root) { let entities = root.entityMgr.getAllWithComponent(TargetShapeCheckerComponent); return ( !entities.find(e => e.components[id].filter == "C" && e.components[id].filterIndex == 0) || !entities.find(e => e.components[id].filter == "R" && e.components[id].filterIndex == 0) ); }, Tdesc: "Put in a single quad of a shape to make a SHAPE filter. Make circle and square filters to proceed.", }, { id: `checker_colors`, /** @param {GameRoot} root */ condition(root) { let entities = root.entityMgr.getAllWithComponent(TargetShapeCheckerComponent); return ( !entities.find(e => e.components[id].filter == "r" && e.components[id].filterIndex == 1) || !entities.find(e => e.components[id].filter == "g" && e.components[id].filterIndex == 1) ); }, Tdesc: "Put in a single quad of a colored shape to make a COLOR filter. Make red and greed filters to proceed.", }, { id: `checker_lines`, /** @param {GameRoot} root */ condition(root) { let entities = root.entityMgr.getAllWithComponent(TargetShapeCheckerComponent); return !entities.find(e => e.components[id].filter == "w"); }, Tdesc: "Checkers choose their output based on current goal. Any input is accepted. Make a white filter to proceed.", }, { id: `checker_advanced`, /** @param {GameRoot} root */ condition(root) { // AaAaAaAa:BbBbBbBb:CcCcCcCc:DdDdDdDd let entities = root.entityMgr.getAllWithComponent(TargetShapeCheckerComponent); return ( !entities.find( e => e.components[id].filter == "-" && e.components[id].filterIndex > 17 && e.components[id].filterIndex < 27 ) || !entities.find(e => e.components[id].filter == "u" && e.components[id].filterIndex > 27) ); }, Tdesc: ". Make filters for a hole on 3rd layer and for uncolored quad on 4th to finish tutorial.", }, ]; const goal = { shape: "RuCrSgWb:CcRmWySu:SwWwRwCw", required: 40e3, reward: "checker", title: "The Full Automation", desc: "Say hello to the Checker, the king of Automation." + " - Set it a simple filter - a shape quad or a colored quad" + " and it will select path depending on current Hub Goal, itself, forever!" + " In case you need some more advanced options, layer quads to filter a higher layer," + " color 3 of 4 quads for uncolored or leave a single hole to get a hole one", tutorial, }; /** @type {ModData} */ const checker = { id: "checker", component: TargetShapeCheckerComponent, building: MetaTargetShapeCheckerBuilding, toolbar: 2, system: TargetShapeCheckerSystem, process: targetShapeCheckerProcess, sprite: tscSprite, spriteBp: tscSpriteBp, variantId: 500, meta: MetaTargetShapeCheckerBuilding, speed: 2, Tname: "Checker", Tdesc: "Toggles output direction depending on current hub goal shape, allowing automation of random levels.", goal, keyCode: "0", toolbarIndex: 10, }; /* harmony default export */ __webpack_exports__["default"] = (checker); /***/ }), /***/ "./src/js/game/custom/mods/combiner.js": /*!*********************************************!*\ !*** ./src/js/game/custom/mods/combiner.js ***! \*********************************************/ /*! exports provided: MetaCombinerBuilding, CombinerProcess, Sprite, SpriteBp, unstackerBuildingData, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaCombinerBuilding", function() { return MetaCombinerBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CombinerProcess", function() { return CombinerProcess; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteBp", function() { return SpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unstackerBuildingData", function() { return unstackerBuildingData; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "combiner"; const color = "blue"; class MetaCombinerBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } getDimensions() { return new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 2); } getSilhouetteColor() { return color; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(`reward_${id}`); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(id); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 2, processorType: id, }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: "top", }, ], }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 1), directions: ["bottom"], filter: "shape", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1), directions: ["bottom"], filter: "shape", }, ], }) ); } } const components = { R: "R", C: "C", S: "S", W: "W", B: "RC", D: "RS", O: "RW", F: "CS", U: "CW", M: "SW", Z: "RCS", T: "RCW", L: "RSW", P: "CSW", Y: "RCSW", }; const recipes = {}; for (let s in components) { components[s] = components[s].split("").sort().join(""); } for (let s1 in components) { let res = {}; for (let s2 in components) { let cm = [...new Set(components[s1] + components[s2])].sort().join(""); for (let r in components) { if (cm == components[r]) { res[s2] = r; } } } recipes[s1] = res; } const cache = {}; function doCombine(it1, it2) { let quads1 = it1 .split(":") .flatMap(e => e.match(/../g)) .map(e => e[0]); let quads2 = it2 .split(":") .flatMap(e => e.match(/../g)) .map(e => e[0]); let r = []; for (let i = 0; i < Math.max(quads1.length, quads2.length); ++i) { if (!quads1[i] || !quads2[i]) { r.push(quads1[i] || quads2[i]); continue; } if (quads1[i] == "-" || quads2[i] == "-") { r.push(quads1[i] == "-" ? quads2[i] : quads1[i]); } else { r.push(recipes[quads1[i]][quads2[i]]); } } return r.map((e, i) => `${i && !(i % 4) ? ":" : ""}${e}${e == "-" ? "-" : "u"}`).join(""); } /** @param {ModProcessData} */ function CombinerProcess({ items, trackProduction, outItems }) { // console.log("Combiner PROCESSES"); let it1 = items[0].getHash(); let it2 = items[1].getHash(); let out = cache[it1 + "+" + it2] || (cache[it1 + "+" + it2] = doCombine(it1, it2)); outItems.push({ item: _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(out), }); return trackProduction; } const Sprite = { sprite: `sprites/buildings/${id}.png`, url: `./res/${id}.png`, w: 192 * 2, h: 192 * 2, }; const SpriteBp = { sprite: `sprites/blueprints/${id}.png`, url: `./res/${id}-bp.png`, w: 192 * 2, h: 192 * 2, }; /** @type {ModData} */ const unstackerBuildingData = { id: id, building: MetaCombinerBuilding, toolbar: 2, sprite: Sprite, spriteBp: SpriteBp, process: CombinerProcess, // TODO: keybinding in KEYMAPPINGS // TODO: T Tname: "Combiner", Tdesc: "Combines shapes into shapes of higher class. Works with shapes same as Merger works with colors.", speed: 1 / 5, speedClass: "processors", meta: MetaCombinerBuilding, variantId: 540, keyCode: "8", toolbarIndex: 8, }; /* harmony default export */ __webpack_exports__["default"] = (unstackerBuildingData); /***/ }), /***/ "./src/js/game/custom/mods/counter.js": /*!********************************************!*\ !*** ./src/js/game/custom/mods/counter.js ***! \********************************************/ /*! exports provided: ItemCounterComponent, CounterSystem, MetaCounterBuilding, counterProcess, counterSprite, counterSpriteBp, counterBuildingData, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemCounterComponent", function() { return ItemCounterComponent; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CounterSystem", function() { return CounterSystem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaCounterBuilding", function() { return MetaCounterBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "counterProcess", function() { return counterProcess; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "counterSprite", function() { return counterSprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "counterSpriteBp", function() { return counterSpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "counterBuildingData", function() { return counterBuildingData; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "counter"; class ItemCounterComponent extends _gameData__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return id; } static getSchema() { return { itemTickHistory: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].array(_gameData__WEBPACK_IMPORTED_MODULE_0__["types"].float), }; } duplicateWithoutContents() { return new ItemCounterComponent(); } constructor() { super(); /** * Maintained every TODO game tick, this aray contains the item counts for every tick in the past 1 second. * @type {number[]} */ this.itemTickHistory = Array(24).fill(0); /** @type {number} Calculated and set every second. This is a read only property. */ this.averageItemsPerSecond = 0; /** @type {number} - Last time the averageItemsPerSecond property was reset. */ this.lastResetTime = 0; } getCurrentTime() {} } class CounterSystem extends Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["ModSystem"])(id, ItemCounterComponent) { /** * @param {CanvasRenderingContext2D} context * @param {Entity} entity * @param {ItemCounterComponent} [counterComp] * @param {DrawParameters} [parameters] */ drawEntity(context, entity, counterComp, parameters) { const staticComp = entity.components.StaticMapEntity; // calc avg: // const analyzedTime = 5; let now = this.root.time.timeSeconds; // now = performance.now() / 1e3; const filtered = counterComp.itemTickHistory.map(e => now - e).filter(e => e < analyzedTime); const min = Math.min(analyzedTime / 2, ...filtered), max = Math.max(analyzedTime / 10, ...filtered); const avg = !filtered.length ? 0 : (filtered.length - 1) / (max - min); counterComp.averageItemsPerSecond = avg; // // // // // context.save(); context.globalAlpha = 1; const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); context.translate(center.x, center.y + 0.15); context.scale(0.8, 1); const size = counterComp.averageItemsPerSecond >= 9.95 ? 7 : 9; context.font = `bold ${size}px GameFont`; // GameFont does not work context.textAlign = "center"; context.textBaseline = "middle"; context.fillStyle = "#64666e"; context.fillStyle = "blue"; context.fillText(counterComp.averageItemsPerSecond.toFixed(1), 0, 0); context.restore(); } } class MetaCounterBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } /** * @returns {string} Colour used to represent this building when zoomed out. */ getSilhouetteColor() { return "#444e81"; // Dark Blue } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getBeltBaseSpeed("regular"); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * The counter is unlocked once the belt speed reaches 20 (items/s). This is around the time when items on * a belt begin to blurr. It is also late enough in the game that a player would understand and appreciate * this building. * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(`reward_${id}`); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: id, }) ); entity.addComponent(new ItemCounterComponent()); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [{ pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: "top" }], }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: ["bottom"], }, ], }) ); } } /** @param {ModProcessData} */ function counterProcess({ items, trackProduction, entity, outItems, system }) { // console.log("counter PROCESSES"); const inputItem = items[0]; trackProduction = false; /** @type {ItemCounterComponent} */ const counterComp = entity.components[id]; counterComp.itemTickHistory.shift(); let now = system.root.time.timeSeconds; // now = performance.now() / 1e3; counterComp.itemTickHistory.push(now); outItems.push({ item: inputItem, }); return trackProduction; } const counterSprite = { sprite: "sprites/buildings/counter.png", url: "./res/counter.png", w: 192, h: 192, }; const counterSpriteBp = { sprite: "sprites/blueprints/counter.png", url: "./res/counter-bp.png", w: 192, h: 192, }; /** @type {ModData} */ const counterBuildingData = { id, component: ItemCounterComponent, building: MetaCounterBuilding, toolbar: 2, system: CounterSystem, sprite: counterSprite, spriteBp: counterSpriteBp, process: counterProcess, // TODO: keybinding in KEYMAPPINGS // TODO: T Tname: "Counter", Tdesc: "Displays current throughput of a belt.", variantId: 510, meta: MetaCounterBuilding, speed: 2, keyCode: "5", toolbarIndex: 5, }; /* harmony default export */ __webpack_exports__["default"] = (counterBuildingData); /***/ }), /***/ "./src/js/game/custom/mods/inverter.js": /*!*********************************************!*\ !*** ./src/js/game/custom/mods/inverter.js ***! \*********************************************/ /*! exports provided: MetaInverterBuilding, Process, Sprite, SpriteBp, data, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaInverterBuilding", function() { return MetaInverterBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Process", function() { return Process; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteBp", function() { return SpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "data", function() { return data; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "inverter"; class MetaInverterBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } getSilhouetteColor() { return "#25d7b8"; } getDimensions(variant) { return new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 2); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(id); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(`reward_${id}`); } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 2, processorType: id, }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), direction: "right" }, // { pos: new Vector(1, 0), direction: enumDirection.top, layer: enumLayer.wires }, ], }) ); // entity.addComponent( // new EnergyConsumerComponent({ // bufferSize: 3, // perCharge: 1, // batteryPosition: new Vector(0.63, 0.7), // acceptorSlotIndex: 1, // ejectorSlotIndex: 1, // }) // ); // entity.addComponent( // new WiredPinsComponent({ // slots: [ // { // pos: new Vector(0, 0), // direction: "top", // type: "positiveEnergyAcceptor", // }, // { // pos: new Vector(1, 0), // direction: "top", // type: "negativeEnergyEjector", // }, // ], // }) // ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 1), directions: ["left"], filter: "color", }, // { // pos: new Vector(0, 0), // directions: ["top"], // filter: "positiveEnergy", // layer: "wires", // }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: ["top"], filter: "shape", }, ], }) ); } } /** @param {ModProcessData} */ function Process({ items, itemsBySlot, trackProduction, entity, outItems, system }) { const item = items[0]; const processorComp = entity.components.ItemProcessor; if (!processorComp.charges) { let hash = items[1].getHash().slice(0, 8); processorComp.charges = hash.split("").filter(e => e == "C").length - 1; } else { processorComp.inputSlots = itemsBySlot.slice(1); processorComp.charges--; } if (item.getItemType() === "color") { const colorItem = /** @type {ColorItem} */ (items[0]); const newColor = _gameData__WEBPACK_IMPORTED_MODULE_0__["enumInvertedColors"][colorItem.color]; outItems.push({ item: new _gameData__WEBPACK_IMPORTED_MODULE_0__["ColorItem"](newColor), requiredSlot: 0, }); } else if (item.getItemType() === "shape") { const shapeItem = /** @type {ShapeItem} */ (items[0]); const newItem = system.root.shapeDefinitionMgr.shapeActionInvertColors(shapeItem.definition); outItems.push({ item: new _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"](newItem), requiredSlot: 0, }); } else { window.assert(false, "Bad item type: " + item.getItemType() + " for advanced processor."); } return trackProduction; } const Sprite = { url: "./res/inverter.png", w: 384, h: 384, }; const SpriteBp = { url: "./res/inverter-bp.png", w: 384, h: 384, }; // TODO: keyCode, toolbarIndex /** @type {ModData} */ const data = { id, building: MetaInverterBuilding, toolbar: 2, process: Process, speed: 1 / 3, speedClass: "processors", meta: MetaInverterBuilding, variantId: 310, sprite: Sprite, spriteBp: SpriteBp, Tname: "Inverter", Tdesc: "Inverts colors of shapes and paints using flat Circles. Inverts 1 item per circle quad.", }; /* harmony default export */ __webpack_exports__["default"] = (data); /***/ }), /***/ "./src/js/game/custom/mods/levels.js": /*!*******************************************!*\ !*** ./src/js/game/custom/mods/levels.js ***! \*******************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /** @typedef {import('../gameData').ModLevel} ModLevel */ /** @type {ModLevel} */ const painter = { id: "painter42", goal: { shape: "CwCcCmCy:RwRcRmRy:SwScSmSy:WwWcWmWy", required: 20e3, reward: "quaduo", title: "Ultimate painting", desc: "You have unlocked the Quaduo painter - It can paints a whole belt.", }, }; /** @type {ModLevel} */ const inverter = { id: "advanced_processor", goal: { shape: "CwCrCgCb:CuCcCmCy:CwCrCgCb:CuCcCmCy", required: 30e3, reward: "advanced_processor", title: "Inversion", desc: "The new Inverter allows you to obtain a new black color as well as the good old grey.", }, }; /** @type {ModLevel} */ const counter = { id: "counter", goal: { shape: "RwCwSbCw:RcCwSrCw:RwCwSyCw", // onion rocket required: 12.5e3, reward: "counter", title: "The Speed Unravelled", desc: "The Counter will allow you to see the speed not onli as a blinking of insanely fast shapes.", }, }; /** @type {ModLevel} */ const combiner = { id: "combiner", goal: { shape: "CuRuSuWu:RrSrWrCr:SgWgCgRg:WbCbRbSb", required: 35e3, reward: "combiner", }, }; /** @type {ModLevel} */ const unstacker = { id: "unstacker", goal: { shape: "RyRyRcRc:SyScSySc:ScSyScSy:CyCyCcCc", // cyan-yellow stack required: 25e3, reward: "unstacker", title: "unstacker", desc: "unstacker is unlocked, no comments.", }, }; /** @type {ModLevel} */ const repeater = { id: "repeater", goal: { shape: "CuRuSuWu:CuRuSuWu:CuRuSuWu:CuRuSuWu", // <----------------------------------------- required: 7.5e3, reward: "repeater", }, }; /** @type {ModLevel[]} */ const levels = [inverter, counter, combiner, unstacker, painter, repeater]; let baseCount = 1000; let countPerLevel = 200; let freeplayIndex = 1; function makeFreeplay(minLevel, maxLevel, holeTier, colorTier, shapeTier, layerTier, etc) { let freeplayGoal = { id: `freeplay_${freeplayIndex}`, goal: { fixed: true, minLevel, maxLevel, baseCount: baseCount + minLevel * countPerLevel, countPerLevel, shape: { holeTier, shapeTier, colorTier, layerTier, }, reward: `no_reward_freeplay_${freeplayIndex}`, ...etc, }, }; levels.push(freeplayGoal); ++freeplayIndex; } levels.push({ id: "freeplay", goal: { reward: "freeplay", title: "The Freeplay", desc: "So, this was the first Freeplay level. Nothing really special, just a random shape." + " This one was easy, but next ones are going to be harder, slowly becoming harder and harder once a while to keep you stuffed." + " Make sure to use Checker and make a fully automated Ultimate Factory that can produce Anywhing! Onwards, to FREEPLAY!!!", shape: "CrRgSbWw", required: 5000, sort_index: 100e3, }, }); function makeNoDescFreeplay(minLevel, maxLevel, holeTier, colorTier, shapeTier, layerTier) { let args = [holeTier, colorTier, shapeTier, layerTier]; return makeFreeplay(minLevel, maxLevel, holeTier, colorTier, shapeTier, layerTier, { title: `Freeplay [${args}]`, desc: `I, Dimava, have not wrote all the descriptions yet. Hardness id [${args}]. Harder levels are to come...`, }); } let n = 25, h, c, s, l; makeNoDescFreeplay(25, (n = 34), (h = 1), (c = 1), (s = 1), (l = 1)); // base makeNoDescFreeplay((n += 1), (n += 4), h, (c = 2), s, l); // +cmy makeNoDescFreeplay((n += 1), (n += 4), h, (c = 3), s, l); // +w makeNoDescFreeplay((n += 1), (n += 4), (h = 2), c, (s = 2), l); // +uk +shape +COMBINER makeNoDescFreeplay((n += 1), (n += 4), h, (c = 4), s, (l = 2)); // +black +layer +INVERTOR makeNoDescFreeplay((n += 1), (n += 4), (h = 3), c, s, l); // +hole makeNoDescFreeplay((n += 1), (n += 4), h, c, s, (l = 3)); // + makeNoDescFreeplay((n += 1), (n += 4), h, c, (s = 3), l); // +shape3 makeNoDescFreeplay((n += 1), (n += 4), (h = 4), c, s, l); // +hole*2 makeNoDescFreeplay((n += 1), (n += 4), h, c, s, (l = 4)); // +layer makeFreeplay((n += 1), Math.max(100, (n += 4)), h, c, (s = 4), l, { // +shape4 title: "Freeplay [4, 4, 4, 4]", desc: "I, Dimava, have not wrote all the descriptions yet. Hardness id [4, 4, 4, 4]. This is the TOP hardness so far.", }); /* harmony default export */ __webpack_exports__["default"] = (levels); /***/ }), /***/ "./src/js/game/custom/mods/painter1.js": /*!*********************************************!*\ !*** ./src/js/game/custom/mods/painter1.js ***! \*********************************************/ /*! exports provided: Painter1Process, BuildingData, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Painter1Process", function() { return Painter1Process; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BuildingData", function() { return BuildingData; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "painter"; const cache = {}; function colorShape(shape, color) { const recipeId = shape + "+" + color; let out = cache[recipeId]; if (out) return out; let layers = shape.split(":").map(e => e.split("")); for (let i = 0; i < 4; i++) { let charges = 3; for (let j = layers.length - 1; j >= 0; --j) { if (layers[j][2 * i] != "-") { layers[j][2 * i + 1] = color; charges--; if (!charges) break; } } } let result = layers.map(e => e.join("")).join(":"); return (cache[recipeId] = result); } /** @param {ModProcessData} */ function Painter1Process({ items, trackProduction, entity, outItems, self }) { const shape = items[0].getHash(); const color = items[1].getHash(); outItems.push({ item: _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(colorShape(shape, color)), }); return trackProduction; } const BuildingData = { id: id, process: Painter1Process, }; /* harmony default export */ __webpack_exports__["default"] = (BuildingData); /***/ }), /***/ "./src/js/game/custom/mods/painter2.js": /*!*********************************************!*\ !*** ./src/js/game/custom/mods/painter2.js ***! \*********************************************/ /*! exports provided: Painter2Process, BuildingData, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Painter2Process", function() { return Painter2Process; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BuildingData", function() { return BuildingData; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "painterDouble"; const cache = {}; function colorShape(shape, color) { const recipeId = shape + "+" + color; let out = cache[recipeId]; if (out) return out; let layers = shape.split(":").map(e => e.split("")); for (let i = 0; i < 4; i++) { let charges = 2; for (let j = layers.length - 1; j >= 0; --j) { if (layers[j][2 * i] != "-") { layers[j][2 * i + 1] = color; charges--; if (!charges) break; } } } let result = layers.map(e => e.join("")).join(":"); return (cache[recipeId] = result); } /** @param {ModProcessData} */ function Painter2Process({ items, trackProduction, outItems }) { const shape1 = items[0].getHash(); const shape2 = items[1].getHash(); const color = items[2].getHash(); outItems.push({ item: _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(colorShape(shape1, color)), }); outItems.push({ item: _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(colorShape(shape2, color)), }); return trackProduction; } const BuildingData = { id: id, process: Painter2Process, }; /* harmony default export */ __webpack_exports__["default"] = (BuildingData); /***/ }), /***/ "./src/js/game/custom/mods/quaduo.js": /*!*******************************************!*\ !*** ./src/js/game/custom/mods/quaduo.js ***! \*******************************************/ /*! exports provided: MetaQuaduoPainterBuilding, QuaduoPainterProcess, Sprite, SpriteBp, unstackerBuildingData, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaQuaduoPainterBuilding", function() { return MetaQuaduoPainterBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuaduoPainterProcess", function() { return QuaduoPainterProcess; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteBp", function() { return SpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unstackerBuildingData", function() { return unstackerBuildingData; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); const id = "quaduo"; class MetaQuaduoPainterBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } getDimensions() { return new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](4, 2); } getSilhouetteColor() { return "#ff6000"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(`reward_${id}`); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(id); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed, true)]]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 6, processorType: id, }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 1), direction: "right", }, ], }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 1), directions: ["left"], filter: "shape", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: ["left"], filter: "shape", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 1), directions: ["bottom"], filter: "color", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1), directions: ["bottom"], filter: "color", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 1), directions: ["bottom"], filter: "color", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](3, 1), directions: ["bottom"], filter: "color", }, ], }) ); } } const cache = {}; function colorShape(shape, c1, c2, c3, c4) { const recipeId = `${shape}+${c1}+${c2}+${c3}+${c4}`; let out = cache[recipeId]; if (out) return out; let layers = shape.split(":").map(e => e.split("")); let colors = [c1, c2, c3, c4]; for (let i = 0; i < 4; i++) { for (let j = layers.length - 1; j >= 0; --j) { if (layers[j][2 * i] != "-") { layers[j][2 * i + 1] = colors[i]; } } } let result = layers.map(e => e.join("")).join(":"); return (cache[recipeId] = _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeDefinition"].fromShortKey(result)); } // returns trackProduction function QuaduoPainterProcess({ items, itemsBySlot, trackProduction, entity, outItems, self }) { // console.log("QuaduoPainter PROCESSES"); let input = items.map(e => e.getHash()); const processorComp = entity.components.ItemProcessor; if (!processorComp.slot1a) { processorComp.slot1a = items[0].getHash(); processorComp.slot2a = items[1].getHash(); processorComp.inputSlots = itemsBySlot.slice(2); return; } let out1 = colorShape(processorComp.slot1a, input[2], input[3], input[4], input[5]); outItems.push({ item: new _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"](out1), }); let out2 = colorShape(processorComp.slot2a, input[2], input[3], input[4], input[5]); outItems.push({ item: new _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"](out2), }); let out3 = colorShape(input[0], input[2], input[3], input[4], input[5]); outItems.push({ item: new _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"](out3), }); let out4 = colorShape(input[1], input[2], input[3], input[4], input[5]); outItems.push({ item: new _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"](out4), }); processorComp.slot1a = ""; processorComp.slot2a = ""; // trackProduction return true; } const Sprite = { sprite: `sprites/buildings/${id}.png`, url: `./res/${id}.png`, w: 756, h: 378, }; const SpriteBp = { sprite: `sprites/blueprints/${id}.png`, url: `./res/${id}.png`, // NOT BP ATM w: 756, h: 378, }; const unstackerBuildingData = { id, building: MetaQuaduoPainterBuilding, toolbar: 2, sprite: Sprite, spriteBp: SpriteBp, process: QuaduoPainterProcess, // TODO: keybinding in KEYMAPPINGS // TODO: T Tname: "QuaduoPainter", Tdesc: "Paints all layers of 2 shapes on insane speed.", speed: 1 / 2, speedClass: "processors", meta: MetaQuaduoPainterBuilding, variantId: 560, keyCode: "9", toolbarIndex: 9, }; /* harmony default export */ __webpack_exports__["default"] = (unstackerBuildingData); /***/ }), /***/ "./src/js/game/custom/mods/repeater.js": /*!*********************************************!*\ !*** ./src/js/game/custom/mods/repeater.js ***! \*********************************************/ /*! exports provided: RepeaterComponent, MetaRepeaterBuilding, RepeaterSystem, repeaterProcess, tscSprite, tscSpriteBp, repeater, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RepeaterComponent", function() { return RepeaterComponent; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaRepeaterBuilding", function() { return MetaRepeaterBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RepeaterSystem", function() { return RepeaterSystem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeaterProcess", function() { return repeaterProcess; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tscSprite", function() { return tscSprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tscSpriteBp", function() { return tscSpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeater", function() { return repeater; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "repeater"; const color = "#ff6000"; class RepeaterComponent extends _gameData__WEBPACK_IMPORTED_MODULE_0__["Component"] { static getId() { return id; } static getSchema() { return { itemHash: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].string, storedItem: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].nullable(_gameData__WEBPACK_IMPORTED_MODULE_0__["types"].obj(_gameData__WEBPACK_IMPORTED_MODULE_0__["gItemRegistry"])), charges: _gameData__WEBPACK_IMPORTED_MODULE_0__["types"].int, }; } constructor({ itemHash = "", storedItem = null, charges = 0 }) { super(); this.itemHash = itemHash; /** * Currently stored item * @type {BaseItem} */ this.storedItem = storedItem; this.charges = charges; } duplicateWithoutContents() { return new RepeaterComponent({ itemHash: this.itemHash, storedItem: this.storedItem }); } } class MetaRepeaterBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } getDimensions() { return new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 1); } getSilhouetteColor() { return color; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return true; // is a debug building // return root.hubGoals.isRewardUnlocked(`reward_${ id }`); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(id); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: id, }) ); entity.addComponent(new RepeaterComponent({})); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: "top", }, ], }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: ["bottom"], }, ], }) ); } } class RepeaterSystem extends Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["ModSystem"])(id, RepeaterComponent) { update() { const storedShapes = this.root.hubGoals.storedShapes; for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; /** @type {RepeaterComponent} */ const comp = entity.components[id]; let processorComp = entity.components.ItemProcessor; while (processorComp.inputSlots.length) { let inputSlot = processorComp.inputSlots.pop(); if (inputSlot.item.getHash() != comp.itemHash) { comp.storedItem = inputSlot.item; comp.itemHash = inputSlot.item.getHash(); comp.charges = 0; } comp.charges = Math.min(comp.charges + 1, 500); } let item = comp.storedItem; let hash = comp.itemHash; if (item) { let slots = entity.components.ItemEjector.slots; for (let i = 0; i < slots.length; ++i) { if (!slots[i].item) { if (_gameData__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.blueprintsNoCost) { comp.charges = 500; } if (!comp.charges) { if (!storedShapes[hash]) break; storedShapes[hash]--; comp.charges++; } comp.charges--; slots[i].item = item instanceof _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"] ? _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(comp.itemHash) : _gameData__WEBPACK_IMPORTED_MODULE_0__["ColorItem"].createFromHash(comp.itemHash); } } } } } /** * @param {CanvasRenderingContext2D} context * @param {Entity} entity * @param {RepeaterComponent} [comp] * @param {DrawParameters} [parameters] */ drawEntity(context, entity, comp, parameters) { const staticComp = entity.components.StaticMapEntity; const storedItem = comp.storedItem; const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); if (storedItem !== null) { storedItem.drawItemCenteredClipped(center.x, center.y, parameters, 24); } // leave here for case it will show count // this.storageOverlaySprite.drawCached(parameters, center.x - 15, center.y + 15, 30, 15); } } /** @param {ModProcessData} */ function repeaterProcess({ items, trackProduction, entity, outItems }) { // console.log("repeater PROCESSES"); const inputItem = /** @type {ShapeItem} */ (items[0]); trackProduction = false; const comp = entity.components[id]; if (inputItem.getHash() != comp.itemHash) { comp.storedItem = inputItem; comp.itemHash = inputItem.getHash(); comp.charges = 0; } comp.charges = Math.min(comp.charges + 1, 500); return trackProduction; } const tscSprite = [ { // data: sprite: `sprites/buildings/${id}.png`, w: 192, h: 192, }, { // base: path: "M 11,31 v 130 l 20,20 h 130 l 20,-20 v -130 l -20,-20 h -130 z", }, // { // // red cross: // path: "M 175,40 l 12,12 -12,12 12,12 -12,12 -12,-12 -12,12 -12,-12 12,-12 -12,-12 12,-12 12,12 z", // fill: "red", // }, { // green arrow: path: "M 35,45 l 30,-30 30,30 z", fill: "lightgreen", }, { // green arrow: path: "M 156,45 l -30,-30 -30,30 z", fill: "lightgreen", }, { // blue arrow: path: "M 60,45 l 35,-35 35,35 z", fill: "lightyellow", }, ]; const tscSpriteBp = [ { // data: sprite: `sprites/blueprints/${id}.png`, w: 192, h: 192, transparent: true, }, { // base: path: "M 11,31 v 130 l 20,20 h 130 l 20,-20 v -130 l -20,-20 h -130 z", fill: "#6CD1FF", stroke: "#56A7D8", }, // { // // red cross: // path: "M 175,40 l 12,12 -12,12 12,12 -12,12 -12,-12 -12,12 -12,-12 12,-12 -12,-12 12,-12 12,12 z", // fill: "#5EB7ED", // stroke: "#56A7D8", // }, { // green arrow: path: "M 35,45 l 30,-30 30,30 z", fill: "#56A7D8", }, { // green arrow: path: "M 156,45 l -30,-30 -30,30 z", fill: "#56A7D8", }, { // blue arrow: path: "M 60,45 l 35,-35 35,35 z", fill: "#5EB7ED", stroke: "#56A7D8", }, ]; /** @type {ModData} */ const repeater = { id, component: RepeaterComponent, building: MetaRepeaterBuilding, toolbar: 2, system: RepeaterSystem, process: repeaterProcess, sprite: tscSprite, spriteBp: tscSpriteBp, variantId: 550, meta: MetaRepeaterBuilding, speed: 2, Tname: "Repeater", Tdesc: "Duplicates shapes or colors, taking them from hub. Can store up to 1000 items itself.", keyCode: "4", toolbarIndex: 4, }; /* harmony default export */ __webpack_exports__["default"] = (repeater); /***/ }), /***/ "./src/js/game/custom/mods/test_levels.js": /*!************************************************!*\ !*** ./src/js/game/custom/mods/test_levels.js ***! \************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /** @typedef {import('../gameData').ModLevel} ModLevel */ /** @type {ModLevel[]} */ let levels = []; let lvl = 100; let colors = "rgbcmywku"; for (let c of colors) { let shape = `C${c}C${c}C${c}C${c}:`.repeat(4).slice(0, -1); levels.push({ id: "test_freeplay_" + c, goal: { fixed: true, title: "Test level [" + c + "]", desc: "a test level", minLevel: ++lvl, maxLevel: lvl, baseCount: 100, countPerLevel: 0, shape, reward: "no_reward_test_freeplay_" + c, }, }); } let shapes = "RCSWBDOFUMPLTZY"; for (let c of shapes) { let shape = `${c}u${c}u${c}u${c}u:`.repeat(4).slice(0, -1); levels.push({ id: "test_freeplay_" + c, goal: { fixed: true, title: "Test level [" + c + "]", desc: "a test level", minLevel: ++lvl, maxLevel: lvl, baseCount: 100, countPerLevel: 0, shape, reward: "no_reward_test_freeplay_" + c, }, }); } /* harmony default export */ __webpack_exports__["default"] = (levels); /***/ }), /***/ "./src/js/game/custom/mods/unstacker.js": /*!**********************************************!*\ !*** ./src/js/game/custom/mods/unstacker.js ***! \**********************************************/ /*! exports provided: MetaUnstackerBuilding, UnstackerProcess, Sprite, SpriteBp, unstackerBuildingData, default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaUnstackerBuilding", function() { return MetaUnstackerBuilding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnstackerProcess", function() { return UnstackerProcess; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteBp", function() { return SpriteBp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unstackerBuildingData", function() { return unstackerBuildingData; }); /* harmony import */ var _gameData__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gameData */ "./src/js/game/custom/gameData.js"); /** @typedef {import('../gameData').ModData} ModData */ /** @typedef {import('../gameData').ModProcessData} ModProcessData */ const id = "unstacker"; class MetaUnstackerBuilding extends _gameData__WEBPACK_IMPORTED_MODULE_0__["MetaBuilding"] { constructor() { super(id); } getDimensions() { return new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](2, 1); } getSilhouetteColor() { return "#ff6000"; } /** * @param {GameRoot} root */ getIsUnlocked(root) { return root.hubGoals.isRewardUnlocked(`reward_${id}`); } /** * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { const speed = root.hubGoals.getProcessorBaseSpeed(id); return [[_gameData__WEBPACK_IMPORTED_MODULE_0__["T"].ingame.buildingPlacement.infoTexts.speed, Object(_gameData__WEBPACK_IMPORTED_MODULE_0__["formatItemsPerSecond"])(speed)]]; } /** * Creates the entity at the given location * @param {Entity} entity */ setupEntityComponents(entity) { entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemProcessorComponent"]({ inputsPerCharge: 1, processorType: id, }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemEjectorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), direction: "top", }, { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](1, 0), direction: "top", }, ], }) ); entity.addComponent( new _gameData__WEBPACK_IMPORTED_MODULE_0__["ItemAcceptorComponent"]({ slots: [ { pos: new _gameData__WEBPACK_IMPORTED_MODULE_0__["Vector"](0, 0), directions: ["bottom"], filter: "shape", }, ], }) ); } } /** @param {ModProcessData} */ function UnstackerProcess({ items, trackProduction, outItems }) { // console.log("Unstacker PROCESSES"); let it = items[0].getHash(); let out = []; let a = it.split(":"); let top = a.shift(); let right = a.join(":"); out = [top, right]; for (let i = 0; i < out.length; ++i) { if (!out[i]) continue; outItems.push({ item: _gameData__WEBPACK_IMPORTED_MODULE_0__["ShapeItem"].createFromHash(out[i]), requiredSlot: i, }); } return trackProduction; } const Sprite = { sprite: "sprites/buildings/unstacker.png", url: "./res/unstacker.png", w: 192 * 2, h: 192, }; const SpriteBp = { sprite: "sprites/blueprints/unstacker.png", url: "./res/unstacker-bp.png", w: 192 * 2, h: 192, }; /** @type {ModData} */ const unstackerBuildingData = { id, building: MetaUnstackerBuilding, toolbar: 2, sprite: Sprite, spriteBp: SpriteBp, process: UnstackerProcess, // TODO: keybinding in KEYMAPPINGS // TODO: T Tname: "Unstacker", Tdesc: "Splits lowest layer out of a shape.", speed: 1 / 4, speedClass: "processors", meta: MetaUnstackerBuilding, variantId: 530, keyCode: "7", toolbarIndex: 7, }; /* harmony default export */ __webpack_exports__["default"] = (unstackerBuildingData); /***/ }), /***/ "./src/js/game/custom/shapes.js": /*!**************************************!*\ !*** ./src/js/game/custom/shapes.js ***! \**************************************/ /*! exports provided: customShapes, registerCustomShape */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "customShapes", function() { return customShapes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "registerCustomShape", function() { return registerCustomShape; }); /** @enum {string} */ const customShapes = []; /** * @callback DrawShape * @param {Object} args */ /** * @typedef {Object} ShapeData * @property {string} id * @property {string} code * @property {boolean} [spawnable] * @property {string} [spawnColor] * @property {number} [maxQuarters] * @property {number} [minDistance] * @property {number} [minChance] * @property {number} [distChance] * @property {number} [maxChance] * @property {DrawShape|string} draw * @property {number} tier */ /** * @param {ShapeData} shapeData */ function registerCustomShape(shapeData) { customShapes.push(shapeData); } let customDefaults = { spawnable: false, spawnColor: "uncolored", maxQuarters: 4, minDistance: 6, minChance: 4, distChance: 1 / 3, maxChance: 12, tier: 2, }; registerCustomShape({ id: "clover", code: "L", ...customDefaults, spawnColor: "green", draw({ dims, innerDims, layer, quad, context, color, begin }) { begin({ size: 1.3, path: true, zero: true }); const inner = 0.5; const inner_center = 0.45; context.lineTo(0, inner); context.bezierCurveTo(0, 1, inner, 1, inner_center, inner_center); context.bezierCurveTo(1, inner, 1, 0, inner, 0); }, tier: 3, }); registerCustomShape({ id: "star8", code: "T", ...customDefaults, draw({ dims, innerDims, layer, quad, context, color, begin }) { begin({ size: 1.22, path: true, zero: true }); const inner = 0.5; context.lineTo(0, inner); context.lineTo(Math.sin(Math.PI / 8), Math.cos(Math.PI / 8)); context.lineTo(inner * Math.sin(Math.PI / 4), inner * Math.cos(Math.PI / 4)); context.lineTo(Math.sin((Math.PI * 3) / 8), Math.cos((Math.PI * 3) / 8)); context.lineTo(inner, 0); }, tier: 3, }); registerCustomShape({ id: "rhombus", code: "B", ...customDefaults, draw({ dims, innerDims, layer, quad, context, color, begin }) { begin({ size: 1.2, path: true, zero: true }); const rad = 0.001; // with rounded borders context.arcTo(0, 1, 1, 0, rad); context.arcTo(1, 0, 0, 0, rad); }, }); registerCustomShape({ id: "plus", code: "P", ...customDefaults, draw: "M 0 0 L 1.1 0 1.1 0.5 0.5 0.5 0.5 1.1 0 1.1 z", tier: 3, }); registerCustomShape({ id: "saw", code: "Z", ...customDefaults, draw({ dims, innerDims, layer, quad, context, color, begin }) { begin({ size: 1.1, path: true, zero: true }); const inner = 0.5; context.lineTo(inner, 0); context.bezierCurveTo(inner, 0.3, 1, 0.3, 1, 0); context.bezierCurveTo( 1, inner, inner * Math.SQRT2 * 0.9, inner * Math.SQRT2 * 0.9, inner * Math.SQRT1_2, inner * Math.SQRT1_2 ); context.rotate(Math.PI / 4); context.bezierCurveTo(inner, 0.3, 1, 0.3, 1, 0); context.bezierCurveTo( 1, inner, inner * Math.SQRT2 * 0.9, inner * Math.SQRT2 * 0.9, inner * Math.SQRT1_2, inner * Math.SQRT1_2 ); }, tier: 3, }); registerCustomShape({ id: "sun", code: "U", ...customDefaults, spawnColor: "yellow", draw({ dims, innerDims, layer, quad, context, color, begin }) { begin({ size: 1.3, path: true, zero: true }); const PI = Math.PI; const PI3 = ((PI * 3) / 8) * 0.75; const c = 1 / Math.cos(Math.PI / 8); const b = c * Math.sin(Math.PI / 8); context.moveTo(0, 0); context.rotate(Math.PI / 2); context.arc(c, 0, b, -PI, -PI + PI3); context.rotate(-Math.PI / 4); context.arc(c, 0, b, -PI - PI3, -PI + PI3); context.rotate(-Math.PI / 4); context.arc(c, 0, b, PI - PI3, PI); }, }); registerCustomShape({ id: "leaf", code: "F", ...customDefaults, draw: "M 0 0 v 0.5 a 0.5 0.5 0 0 0 0.5 0.5 h 0.5 v -0.5 a 0.5 0.5 0 0 0 -0.5 -0.5 z", }); registerCustomShape({ id: "diamond", code: "D", ...customDefaults, draw: "M 0 0 l 0 0.5 0.5 0.5 0.5 0 0 -0.5 -0.5 -0.5 z", }); registerCustomShape({ id: "mill", code: "M", ...customDefaults, draw: "M 0 0 L 0 1 1 1 Z", }); // registerCustomShape({ // id: "halfleaf", // code: "H", // ...customDefaults, // draw: "100 M 0 0 L 0 100 A 45 45 0 0 0 30 30 A 45 45 0 0 0 100 0 Z", // }) registerCustomShape({ id: "yinyang", code: "Y", ...customDefaults, // draw({ dims, innerDims, layer, quad, context, color, begin }) { // begin({ size: 1/(0.5+Math.SQRT1_2), path: true }); // /** @type{CanvasRenderingContext2D} */ // let ctx = context; // with (ctx) { with (Math) { // //////////////////////// // // draw mostly in [0,1]x[0,1] square // // draw: "100 M 0 50 A 50 50 0 1 1 85 85 A 121 121 0 0 1 -85 85 A 50 50 0 0 0 0 50", // moveTo(0, 0.5); // arc(0.5, 0.5, 0.5, PI, PI/4) // arc(0, 0, 0.5+SQRT1_2, PI/4, PI/4+PI/2, 0) // arc(-0.5, 0.5, 0.5, 3*PI/4, 0, 1) // moveTo(0.6, 0.5) // arc(0.5, 0.5, 0.1, 0, 2*PI) // }} // }, draw: "120.71 M 0 50 A 50 50 0 1 1 85.355 85.355 A 120.71 120.71 0 0 1 -85.355 85.355 A 50 50 0 0 0 0 50 Z M 40 50 A 10 10 0 1 0 40 49.99 Z", tier: 4, }); registerCustomShape({ id: "octagon", code: "O", ...customDefaults, draw: "M 0 0 L 0 1 0.4142 1 1 0.4142 1 0 Z", }); /***/ }), /***/ "./src/js/game/dynamic_tickrate.js": /*!*****************************************!*\ !*** ./src/js/game/dynamic_tickrate.js ***! \*****************************************/ /*! exports provided: DynamicTickrate */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DynamicTickrate", function() { return DynamicTickrate; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("dynamic_tickrate"); const fpsAccumulationTime = 1000; class DynamicTickrate { /** * * @param {GameRoot} root */ constructor(root) { this.root = root; this.currentTickStart = null; this.capturedTicks = []; this.averageTickDuration = 0; this.accumulatedFps = 0; this.accumulatedFpsLastUpdate = 0; this.averageFps = 60; this.setTickRate(60); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.renderForTrailer) { this.setTickRate(300); } } onFrameRendered() { ++this.accumulatedFps; const now = performance.now(); const timeDuration = now - this.accumulatedFpsLastUpdate; if (timeDuration > fpsAccumulationTime) { const avgFps = (this.accumulatedFps / fpsAccumulationTime) * 1000; this.averageFps = avgFps; this.accumulatedFps = 0; this.accumulatedFpsLastUpdate = now; } } /** * Sets the tick rate to N updates per second * @param {number} rate */ setTickRate(rate) { logger.log("Applying tick-rate of", rate); this.currentTickRate = rate; this.deltaMs = 1000.0 / this.currentTickRate; this.deltaSeconds = 1.0 / this.currentTickRate; } /** * Increases the tick rate marginally */ increaseTickRate() { if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.renderForTrailer) { return; } const desiredFps = this.root.app.settings.getDesiredFps(); this.setTickRate(Math.round(Math.min(desiredFps, this.currentTickRate * 1.2))); } /** * Decreases the tick rate marginally */ decreaseTickRate() { if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.renderForTrailer) { return; } const desiredFps = this.root.app.settings.getDesiredFps(); this.setTickRate(Math.round(Math.max(desiredFps / 2, this.currentTickRate * 0.8))); } /** * Call whenever a tick began */ beginTick() { window.assert(this.currentTickStart === null, "BeginTick called twice"); this.currentTickStart = performance.now(); if (this.capturedTicks.length > this.currentTickRate * 2) { // Take only a portion of the ticks this.capturedTicks.sort(); this.capturedTicks.splice(0, 10); this.capturedTicks.splice(this.capturedTicks.length - 11, 10); let average = 0; for (let i = 0; i < this.capturedTicks.length; ++i) { average += this.capturedTicks[i]; } average /= this.capturedTicks.length; this.averageTickDuration = average; const desiredFps = this.root.app.settings.getDesiredFps(); if (this.averageFps > desiredFps * 0.9) { // if (average < maxTickDuration) { this.increaseTickRate(); } else if (this.averageFps < desiredFps * 0.7) { this.decreaseTickRate(); } this.capturedTicks = []; } } /** * Call whenever a tick ended */ endTick() { window.assert(this.currentTickStart !== null, "EndTick called without BeginTick"); const duration = performance.now() - this.currentTickStart; this.capturedTicks.push(duration); this.currentTickStart = null; } } /***/ }), /***/ "./src/js/game/entity.js": /*!*******************************!*\ !*** ./src/js/game/entity.js ***! \*******************************/ /*! exports provided: Entity */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Entity", function() { return Entity; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _entity_components__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./entity_components */ "./src/js/game/entity_components.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); class Entity extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["BasicSerializableObject"] { /** * @param {GameRoot} root */ constructor(root) { super(); /** * Handle to the global game root */ this.root = root; /** * The components of the entity */ this.components = new _entity_components__WEBPACK_IMPORTED_MODULE_4__["EntityComponentStorage"](); /** * Whether this entity was registered on the @see EntityManager so far */ this.registered = false; /** * On which layer this entity is * @type {Layer} */ this.layer = "regular"; /** * Internal entity unique id, set by the @see EntityManager */ this.uid = 0; } static getId() { return "Entity"; } /** * @see BasicSerializableObject.getSchema * @returns {import("../savegame/serialization").Schema} */ static getSchema() { return { uid: _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].uint, components: _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].keyValueMap(_savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].objData(_core_global_registries__WEBPACK_IMPORTED_MODULE_7__["gComponentRegistry"]), false), }; } /** * Returns a clone of this entity without contents */ duplicateWithoutContents() { const clone = new Entity(this.root); for (const key in this.components) { clone.components[key] = this.components[key].duplicateWithoutContents(); } clone.layer = this.layer; return clone; } /** * Internal destroy callback */ internalDestroyCallback() { window.assert(!this.destroyed, "Can not destroy entity twice"); this.destroyed = true; } /** * Adds a new component, only possible until the entity is registered on the entity manager, * after that use @see EntityManager.addDynamicComponent * @param {Component} componentInstance * @param {boolean} force Used by the entity manager. Internal parameter, do not change */ addComponent(componentInstance, force = false) { if (!force && this.registered) { this.root.entityMgr.attachDynamicComponent(this, componentInstance); return; } window.assert(force || !this.registered, "Entity already registered, use EntityManager.addDynamicComponent"); const id = /** @type {typeof Component} */ (componentInstance.constructor).getId(); window.assert(!this.components[id], "Component already present"); this.components[id] = componentInstance; } /** * Removes a given component, only possible until the entity is registered on the entity manager, * after that use @see EntityManager.removeDynamicComponent * @param {typeof Component} componentClass * @param {boolean} force */ removeComponent(componentClass, force = false) { if (!force && this.registered) { this.root.entityMgr.removeDynamicComponent(this, componentClass); return; } window.assert( force || !this.registered, "Entity already registered, use EntityManager.removeDynamicComponent" ); const id = componentClass.getId(); window.assert(this.components[id], "Component does not exist on entity"); delete this.components[id]; } /** * Draws the entity, to override use @see Entity.drawImpl * @param {DrawParameters} parameters */ drawDebugOverlays(parameters) { const context = parameters.context; const staticComp = this.components.StaticMapEntity; if (staticComp && _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.showEntityBounds) { if (staticComp) { const transformed = staticComp.getTileSpaceBounds(); context.strokeStyle = "rgba(255, 0, 0, 0.5)"; context.lineWidth = 2; // const boundsSize = 20; context.beginPath(); context.rect( transformed.x * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, transformed.y * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, transformed.w * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, transformed.h * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize ); context.stroke(); } } if (staticComp && _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.showAcceptorEjectors) { const ejectorComp = this.components.ItemEjector; if (ejectorComp) { const ejectorSprite = _core_loader__WEBPACK_IMPORTED_MODULE_5__["Loader"].getSprite("sprites/debug/ejector_slot.png"); for (let i = 0; i < ejectorComp.slots.length; ++i) { const slot = ejectorComp.slots[i]; const slotTile = staticComp.localTileToWorld(slot.pos); const direction = staticComp.localDirectionToWorld(slot.direction); const directionVector = _core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirectionToVector"][direction]; const angle = Math.radians(_core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirectionToAngle"][direction]); context.globalAlpha = slot.item ? 1 : 0.2; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_6__["drawRotatedSprite"])({ parameters, sprite: ejectorSprite, x: (slotTile.x + 0.5 + directionVector.x * 0.37) * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, y: (slotTile.y + 0.5 + directionVector.y * 0.37) * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, angle, size: _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize * 0.25, }); } } const acceptorComp = this.components.ItemAcceptor; if (acceptorComp) { const acceptorSprite = _core_loader__WEBPACK_IMPORTED_MODULE_5__["Loader"].getSprite("sprites/misc/acceptor_slot.png"); for (let i = 0; i < acceptorComp.slots.length; ++i) { const slot = acceptorComp.slots[i]; const slotTile = staticComp.localTileToWorld(slot.pos); for (let k = 0; k < slot.directions.length; ++k) { const direction = staticComp.localDirectionToWorld(slot.directions[k]); const directionVector = _core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirectionToVector"][direction]; const angle = Math.radians(_core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirectionToAngle"][direction] + 180); context.globalAlpha = 0.4; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_6__["drawRotatedSprite"])({ parameters, sprite: acceptorSprite, x: (slotTile.x + 0.5 + directionVector.x * 0.37) * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, y: (slotTile.y + 0.5 + directionVector.y * 0.37) * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, angle, size: _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize * 0.25, }); } } } context.globalAlpha = 1; } // this.drawImpl(parameters); } ///// Helper interfaces ///// Interface to override by subclasses /** * override, should draw the entity * @param {DrawParameters} parameters */ drawImpl(parameters) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } } /***/ }), /***/ "./src/js/game/entity_components.js": /*!******************************************!*\ !*** ./src/js/game/entity_components.js ***! \******************************************/ /*! exports provided: EntityComponentStorage */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EntityComponentStorage", function() { return EntityComponentStorage; }); /** * Typedefs for all entity components. These are not actually present on the entity, * thus they are undefined by default */ class EntityComponentStorage { constructor() { } } /***/ }), /***/ "./src/js/game/entity_manager.js": /*!***************************************!*\ !*** ./src/js/game/entity_manager.js ***! \***************************************/ /*! exports provided: EntityManager */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EntityManager", function() { return EntityManager; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./component */ "./src/js/game/component.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_5__["createLogger"])("entity_manager"); // Manages all entities // NOTICE: We use arrayDeleteValue instead of fastArrayDeleteValue since that does not preserve the order // This is slower but we need it for the street path generation class EntityManager extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_4__["BasicSerializableObject"] { constructor(root) { super(); /** @type {GameRoot} */ this.root = root; /** @type {Array} */ this.entities = []; // We store a seperate list with entities to destroy, since we don't destroy // them instantly /** @type {Array} */ this.destroyList = []; // Store a map from componentid to entities - This is used by the game system // for faster processing /** @type {Object.>} */ this.componentToEntity = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["newEmptyMap"])(); // Store the next uid to use this.nextUid = 10000; } static getId() { return "EntityManager"; } static getSchema() { return { nextUid: _savegame_serialization__WEBPACK_IMPORTED_MODULE_4__["types"].uint, }; } getStatsText() { return this.entities.length + " entities [" + this.destroyList.length + " to kill]"; } // Main update update() { this.processDestroyList(); } /** * Registers a new entity * @param {Entity} entity * @param {number=} uid Optional predefined uid */ registerEntity(entity, uid = null) { window.assert(this.entities.indexOf(entity) < 0, `RegisterEntity() called twice for entity ${entity}`); window.assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`); if ( true && uid !== null) { window.assert(!this.findByUid(uid, false), "Entity uid already taken: " + uid); } if (uid !== null) { window.assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid); } this.entities.push(entity); // Register into the componentToEntity map for (const componentId in entity.components) { if (entity.components[componentId]) { if (this.componentToEntity[componentId]) { this.componentToEntity[componentId].push(entity); } else { this.componentToEntity[componentId] = [entity]; } } } // Give each entity a unique id entity.uid = uid ? uid : this.generateUid(); entity.registered = true; this.root.signals.entityAdded.dispatch(entity); } /** * Sorts all entitiy lists after a resync */ sortEntityLists() { this.entities.sort((a, b) => a.uid - b.uid); this.destroyList.sort((a, b) => a.uid - b.uid); for (const key in this.componentToEntity) { this.componentToEntity[key].sort((a, b) => a.uid - b.uid); } } /** * Generates a new uid * @returns {number} */ generateUid() { return this.nextUid++; } /** * Call to attach a new component after the creation of the entity * @param {Entity} entity * @param {Component} component */ attachDynamicComponent(entity, component) { entity.addComponent(component, true); const componentId = /** @type {typeof Component} */ (component.constructor).getId(); if (this.componentToEntity[componentId]) { this.componentToEntity[componentId].push(entity); } else { this.componentToEntity[componentId] = [entity]; } this.root.signals.entityGotNewComponent.dispatch(entity); } /** * Call to remove a component after the creation of the entity * @param {Entity} entity * @param {typeof Component} component */ removeDynamicComponent(entity, component) { entity.removeComponent(component, true); const componentId = /** @type {typeof Component} */ (component.constructor).getId(); Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["fastArrayDeleteValue"])(this.componentToEntity[componentId], entity); this.root.signals.entityComponentRemoved.dispatch(entity); } /** * Finds an entity buy its uid, kinda slow since it loops over all entities * @param {number} uid * @param {boolean=} errorWhenNotFound * @returns {Entity} */ findByUid(uid, errorWhenNotFound = true) { const arr = this.entities; for (let i = 0, len = arr.length; i < len; ++i) { const entity = arr[i]; if (entity.uid === uid) { if (entity.queuedForDestroy || entity.destroyed) { if (errorWhenNotFound) { logger.warn("Entity with UID", uid, "not found (destroyed)"); } return null; } return entity; } } if (errorWhenNotFound) { logger.warn("Entity with UID", uid, "not found"); } return null; } /** * Returns all entities having the given component * @param {typeof Component} componentHandle * @returns {Array} entities */ getAllWithComponent(componentHandle) { return this.componentToEntity[componentHandle.getId()] || []; } /** * Return all of a given class. This is SLOW! * @param {object} entityClass * @returns {Array} entities */ getAllOfClass(entityClass) { // FIXME: Slow const result = []; for (let i = 0; i < this.entities.length; ++i) { const entity = this.entities[i]; if (entity instanceof entityClass) { result.push(entity); } } return result; } /** * Unregisters all components of an entity from the component to entity mapping * @param {Entity} entity */ unregisterEntityComponents(entity) { for (const componentId in entity.components) { if (entity.components[componentId]) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["arrayDeleteValue"])(this.componentToEntity[componentId], entity); } } } // Processes the entities to destroy and actually destroys them /* eslint-disable max-statements */ processDestroyList() { for (let i = 0; i < this.destroyList.length; ++i) { const entity = this.destroyList[i]; // Remove from entities list Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["arrayDeleteValue"])(this.entities, entity); // Remove from componentToEntity list this.unregisterEntityComponents(entity); entity.registered = false; entity.internalDestroyCallback(); this.root.signals.entityDestroyed.dispatch(entity); } this.destroyList = []; } /** * Queues an entity for destruction * @param {Entity} entity */ destroyEntity(entity) { if (entity.destroyed) { logger.error("Tried to destroy already destroyed entity:", entity.uid); return; } if (entity.queuedForDestroy) { logger.error("Trying to destroy entity which is already queued for destroy!", entity.uid); return; } if (this.destroyList.indexOf(entity) < 0) { this.destroyList.push(entity); entity.queuedForDestroy = true; this.root.signals.entityQueuedForDestroy.dispatch(entity); } else { window.assert(false, "Trying to destroy entity twice"); } } } /***/ }), /***/ "./src/js/game/game_loading_overlay.js": /*!*********************************************!*\ !*** ./src/js/game/game_loading_overlay.js ***! \*********************************************/ /*! exports provided: GameLoadingOverlay */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameLoadingOverlay", function() { return GameLoadingOverlay; }); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); class GameLoadingOverlay { /** * * @param {Application} app * @param {HTMLElement} parent */ constructor(app, parent) { this.app = app; this.parent = parent; /** @type {HTMLElement} */ this.element = null; } /** * Removes the overlay if its currently visible */ removeIfAttached() { if (this.element) { this.element.remove(); this.element = null; } } /** * Returns if the loading overlay is attached */ isAttached() { return this.element; } /** * Shows a super basic overlay */ showBasic() { window.assert(!this.element, "Loading overlay already visible, cant show again"); this.element = document.createElement("div"); this.element.classList.add("gameLoadingOverlay"); this.parent.appendChild(this.element); this.internalAddSpinnerAndText(this.element); } /** * Adds a text with 'loading' and a spinner * @param {HTMLElement} element */ internalAddSpinnerAndText(element) { const inner = document.createElement("span"); inner.classList.add("prefab_LoadingTextWithAnim"); inner.innerText = _translations__WEBPACK_IMPORTED_MODULE_0__["T"].global.loading; element.appendChild(inner); } } /***/ }), /***/ "./src/js/game/game_speed_registry.js": /*!********************************************!*\ !*** ./src/js/game/game_speed_registry.js ***! \********************************************/ /*! exports provided: initGameSpeedRegistry */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initGameSpeedRegistry", function() { return initGameSpeedRegistry; }); /* harmony import */ var _time_regular_game_speed__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./time/regular_game_speed */ "./src/js/game/time/regular_game_speed.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); function initGameSpeedRegistry() { _core_global_registries__WEBPACK_IMPORTED_MODULE_1__["gGameSpeedRegistry"].register(_time_regular_game_speed__WEBPACK_IMPORTED_MODULE_0__["RegularGameSpeed"]); // Others are disabled for now } /***/ }), /***/ "./src/js/game/game_system.js": /*!************************************!*\ !*** ./src/js/game/game_system.js ***! \************************************/ /*! exports provided: GameSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameSystem", function() { return GameSystem; }); /** * A game system processes all entities which match a given schema, usually a list of * required components. This is the core of the game logic. */ class GameSystem { /** * @param {GameRoot} root */ constructor(root) { this.root = root; } ///// PUBLIC API ///// /** * Updates the game system, override to perform logic */ update() {} /** * Override, do not call this directly, use startDraw() * @param {DrawParameters} parameters */ draw(parameters) {} /** * Should refresh all caches */ refreshCaches() {} /** * @see GameSystem.draw Wrapper arround the draw method * @param {DrawParameters} parameters */ startDraw(parameters) { this.draw(parameters); } } /***/ }), /***/ "./src/js/game/game_system_manager.js": /*!********************************************!*\ !*** ./src/js/game/game_system_manager.js ***! \********************************************/ /*! exports provided: GameSystemManager */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameSystemManager", function() { return GameSystemManager; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _systems_belt__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./systems/belt */ "./src/js/game/systems/belt.js"); /* harmony import */ var _systems_item_ejector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./systems/item_ejector */ "./src/js/game/systems/item_ejector.js"); /* harmony import */ var _systems_map_resources__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./systems/map_resources */ "./src/js/game/systems/map_resources.js"); /* harmony import */ var _systems_miner__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./systems/miner */ "./src/js/game/systems/miner.js"); /* harmony import */ var _systems_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./systems/item_processor */ "./src/js/game/systems/item_processor.js"); /* harmony import */ var _systems_underground_belt__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./systems/underground_belt */ "./src/js/game/systems/underground_belt.js"); /* harmony import */ var _systems_hub__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./systems/hub */ "./src/js/game/systems/hub.js"); /* harmony import */ var _systems_static_map_entity__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./systems/static_map_entity */ "./src/js/game/systems/static_map_entity.js"); /* harmony import */ var _systems_item_acceptor__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./systems/item_acceptor */ "./src/js/game/systems/item_acceptor.js"); /* harmony import */ var _systems_storage__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./systems/storage */ "./src/js/game/systems/storage.js"); /* harmony import */ var _systems_wired_pins__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./systems/wired_pins */ "./src/js/game/systems/wired_pins.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); /* harmony import */ var _systems_belt_underlays__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./systems/belt_underlays */ "./src/js/game/systems/belt_underlays.js"); /* harmony import */ var _systems_wire__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./systems/wire */ "./src/js/game/systems/wire.js"); /* harmony import */ var _systems_constant_signal__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./systems/constant_signal */ "./src/js/game/systems/constant_signal.js"); /* harmony import */ var _systems_logic_gate__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./systems/logic_gate */ "./src/js/game/systems/logic_gate.js"); /* harmony import */ var _systems_lever__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./systems/lever */ "./src/js/game/systems/lever.js"); /* harmony import */ var _systems_display__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./systems/display */ "./src/js/game/systems/display.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("game_system_manager"); class GameSystemManager { /** * * @param {GameRoot} root */ constructor(root) { this.root = root; this.systems = { }; for (let custom of _custom_modBuildings__WEBPACK_IMPORTED_MODULE_12__["allCustomBuildingData"]) { if (custom.system) { this.systems[custom.id] = null; } } this.systemUpdateOrder = []; this.internalInitSystems(); } /** * Initializes all systems */ internalInitSystems() { const add = (id, systemClass) => { this.systems[id] = new systemClass(this.root); this.systemUpdateOrder.push(id); }; // Order is important! add("belt", _systems_belt__WEBPACK_IMPORTED_MODULE_1__["BeltSystem"]); add("undergroundBelt", _systems_underground_belt__WEBPACK_IMPORTED_MODULE_6__["UndergroundBeltSystem"]); add("miner", _systems_miner__WEBPACK_IMPORTED_MODULE_4__["MinerSystem"]); add("storage", _systems_storage__WEBPACK_IMPORTED_MODULE_10__["StorageSystem"]); add("itemProcessor", _systems_item_processor__WEBPACK_IMPORTED_MODULE_5__["ItemProcessorSystem"]); add("itemEjector", _systems_item_ejector__WEBPACK_IMPORTED_MODULE_2__["ItemEjectorSystem"]); add("mapResources", _systems_map_resources__WEBPACK_IMPORTED_MODULE_3__["MapResourcesSystem"]); add("hub", _systems_hub__WEBPACK_IMPORTED_MODULE_7__["HubSystem"]); add("staticMapEntities", _systems_static_map_entity__WEBPACK_IMPORTED_MODULE_8__["StaticMapEntitySystem"]); add("wiredPins", _systems_wired_pins__WEBPACK_IMPORTED_MODULE_11__["WiredPinsSystem"]); add("beltUnderlays", _systems_belt_underlays__WEBPACK_IMPORTED_MODULE_13__["BeltUnderlaysSystem"]); add("constantSignal", _systems_constant_signal__WEBPACK_IMPORTED_MODULE_15__["ConstantSignalSystem"]); for (let custom of _custom_modBuildings__WEBPACK_IMPORTED_MODULE_12__["allCustomBuildingData"]) { if (custom.system) { add(custom.id, custom.system); } } // IMPORTANT: Must be after belt system since belt system can change the // orientation of an entity after it is placed -> the item acceptor cache // then would be invalid add("itemAcceptor", _systems_item_acceptor__WEBPACK_IMPORTED_MODULE_9__["ItemAcceptorSystem"]); // WIRES section add("lever", _systems_lever__WEBPACK_IMPORTED_MODULE_17__["LeverSystem"]); // IMPORTANT: We have 2 phases: In phase 1 we compute the output values of all gates, // processors etc. In phase 2 we propagate it through the wires network add("logicGate", _systems_logic_gate__WEBPACK_IMPORTED_MODULE_16__["LogicGateSystem"]); // Wires must be after all gate, signal etc logic! add("wire", _systems_wire__WEBPACK_IMPORTED_MODULE_14__["WireSystem"]); add("display", _systems_display__WEBPACK_IMPORTED_MODULE_18__["DisplaySystem"]); logger.log("📦 There are", this.systemUpdateOrder.length, "game systems"); } /** * Updates all systems */ update() { for (let i = 0; i < this.systemUpdateOrder.length; ++i) { const system = this.systems[this.systemUpdateOrder[i]]; system.update(); } } refreshCaches() { for (let i = 0; i < this.systemUpdateOrder.length; ++i) { const system = this.systems[this.systemUpdateOrder[i]]; system.refreshCaches(); } } } /***/ }), /***/ "./src/js/game/game_system_with_filter.js": /*!************************************************!*\ !*** ./src/js/game/game_system_with_filter.js ***! \************************************************/ /*! exports provided: GameSystemWithFilter */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameSystemWithFilter", function() { return GameSystemWithFilter; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _game_system__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./game_system */ "./src/js/game/game_system.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); class GameSystemWithFilter extends _game_system__WEBPACK_IMPORTED_MODULE_1__["GameSystem"] { /** * Constructs a new game system with the given component filter. It will process * all entities which have *all* of the passed components * @param {GameRoot} root * @param {Array} requiredComponents */ constructor(root, requiredComponents) { super(root); this.requiredComponents = requiredComponents; this.requiredComponentIds = requiredComponents.map(component => component.getId()); /** * All entities which match the current components * @type {Array} */ this.allEntities = []; this.root.signals.entityAdded.add(this.internalPushEntityIfMatching, this); this.root.signals.entityGotNewComponent.add(this.internalReconsiderEntityToAdd, this); this.root.signals.entityComponentRemoved.add(this.internalCheckEntityAfterComponentRemoval, this); this.root.signals.entityQueuedForDestroy.add(this.internalPopEntityIfMatching, this); this.root.signals.postLoadHook.add(this.internalPostLoadHook, this); this.root.signals.bulkOperationFinished.add(this.refreshCaches, this); } /** * @param {Entity} entity */ internalPushEntityIfMatching(entity) { for (let i = 0; i < this.requiredComponentIds.length; ++i) { if (!entity.components[this.requiredComponentIds[i]]) { return; } } window.assert(this.allEntities.indexOf(entity) < 0, "entity already in list: " + entity); this.internalRegisterEntity(entity); } /** * * @param {Entity} entity */ internalCheckEntityAfterComponentRemoval(entity) { if (this.allEntities.indexOf(entity) < 0) { // Entity wasn't interesting anyways return; } for (let i = 0; i < this.requiredComponentIds.length; ++i) { if (!entity.components[this.requiredComponentIds[i]]) { // Entity is not interesting anymore Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["arrayDeleteValue"])(this.allEntities, entity); } } } /** * * @param {Entity} entity */ internalReconsiderEntityToAdd(entity) { for (let i = 0; i < this.requiredComponentIds.length; ++i) { if (!entity.components[this.requiredComponentIds[i]]) { return; } } if (this.allEntities.indexOf(entity) >= 0) { return; } this.internalRegisterEntity(entity); } refreshCaches() { this.allEntities.sort((a, b) => a.uid - b.uid); // Remove all entities which are queued for destroy for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; if (entity.queuedForDestroy || entity.destroyed) { this.allEntities.splice(i, 1); } } } /** * Recomputes all target entities after the game has loaded */ internalPostLoadHook() { this.refreshCaches(); } /** * * @param {Entity} entity */ internalRegisterEntity(entity) { this.allEntities.push(entity); if (this.root.gameInitialized && !this.root.bulkOperationRunning) { // Sort entities by uid so behaviour is predictable this.allEntities.sort((a, b) => a.uid - b.uid); } } /** * * @param {Entity} entity */ internalPopEntityIfMatching(entity) { if (this.root.bulkOperationRunning) { // We do this in refreshCaches afterwards return; } const index = this.allEntities.indexOf(entity); if (index >= 0) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["arrayDelete"])(this.allEntities, index); } } } /***/ }), /***/ "./src/js/game/hub_goals.js": /*!**********************************!*\ !*** ./src/js/game/hub_goals.js ***! \**********************************/ /*! exports provided: HubGoals */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HubGoals", function() { return HubGoals; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./colors */ "./src/js/game/colors.js"); /* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./shapes */ "./src/js/game/shapes.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); /* harmony import */ var _core_rng__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../core/rng */ "./src/js/core/rng.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./items/color_item */ "./src/js/game/items/color_item.js"); class HubGoals extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["BasicSerializableObject"] { static getId() { return "HubGoals"; } static getSchema() { return { level: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].uint, storedShapes: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].keyValueMap(_savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].uint), upgradeLevels: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].keyValueMap(_savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].uint), currentGoal: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].structured({ definition: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].knownType(_shape_definition__WEBPACK_IMPORTED_MODULE_7__["ShapeDefinition"]), required: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].uint, reward: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].nullable(_savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].enum(_tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["enumHubGoalRewards"])), }), }; } deserialize(data) { const errorCode = super.deserialize(data); if (errorCode) { return errorCode; } // Compute gained rewards for (let i = 0; i < this.level - 1; ++i) { if (i < _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"].length) { const reward = _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"][i].reward; this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1; } } for (let i = 0; i < _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["fixedGoals"].length; ++i) { if (_tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["fixedGoals"][i].minLevel < this.level) { const reward = _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["fixedGoals"][i].reward; this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + Math.min(_tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["fixedGoals"][i].maxLevel, this.level) - _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["fixedGoals"][i].minLevel; } } // Compute upgrade improvements for (const upgradeId in _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"]) { const upgradeHandle = _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"][upgradeId]; const level = this.upgradeLevels[upgradeId] || 0; let totalImprovement = upgradeHandle.baseValue || 1; for (let i = 0; i < level; ++i) { totalImprovement += upgradeHandle.tiers[i].improvement; } this.upgradeImprovements[upgradeId] = totalImprovement; } // Compute current goal this.createNextGoal(); } /** * @param {GameRoot} root */ constructor(root) { super(); this.root = root; this.level = 1; /** * Which story rewards we already gained * @type {Object.} */ this.gainedRewards = {}; /** * Mapping from shape hash -> amount * @type {Object} */ this.storedShapes = {}; /** * Stores the levels for all upgrades * @type {Object} */ this.upgradeLevels = {}; /** * Stores the improvements for all upgrades * @type {Object} */ this.upgradeImprovements = {}; for (const key in _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"]) { this.upgradeImprovements[key] = _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"][key].baseValue || 1; } this.createNextGoal(); // Allow quickly switching goals in dev mode if (true) { window.addEventListener("keydown", ev => { if (ev.key === "b") { // root is not guaranteed to exist within ~0.5s after loading in if (this.root && this.root.app && this.root.app.gameAnalytics) { this.onGoalCompleted(); } } }); } } /** * Returns how much of the current shape is stored * @param {ShapeDefinition} definition * @returns {number} */ getShapesStored(definition) { return this.storedShapes[definition.getHash()] || 0; } /** * @param {string} key * @param {number} amount */ takeShapeByKey(key, amount) { window.assert(this.getShapesStoredByKey(key) >= amount, "Can not afford: " + key + " x " + amount); window.assert(amount >= 0, "Amount < 0 for " + key); window.assert(Number.isInteger(amount), "Invalid amount: " + amount); this.storedShapes[key] = (this.storedShapes[key] || 0) - amount; return; } /** * @param {string} key * @param {number} amount */ putShapeByKey(key, amount) { window.assert(amount >= 0, "Amount < 0 for " + key); window.assert(Number.isInteger(amount), "Invalid amount: " + amount); this.storedShapes[key] = (this.storedShapes[key] || 0) + amount; return; } /** * Returns how much of the current shape is stored * @param {string} key * @returns {number} */ getShapesStoredByKey(key) { return this.storedShapes[key] || 0; } /** * Returns how much of the current goal was already delivered */ getCurrentGoalDelivered() { return this.getShapesStored(this.currentGoal.definition); } /** * Returns the current level of a given upgrade * @param {string} upgradeId */ getUpgradeLevel(upgradeId) { return this.upgradeLevels[upgradeId] || 0; } /** * Returns whether the given reward is already unlocked * @param {enumHubGoalRewards} reward */ isRewardUnlocked(reward) { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.allBuildingsUnlocked) { return true; } return !!this.gainedRewards[reward]; } /** * Handles the given definition, by either accounting it towards the * goal or otherwise granting some points * @param {ShapeDefinition} definition */ handleDefinitionDelivered(definition) { const hash = definition.getHash(); this.storedShapes[hash] = (this.storedShapes[hash] || 0) + 1; this.root.signals.shapeDelivered.dispatch(hash); // Check if we have enough for the next level const targetHash = this.currentGoal.definition.getHash(); if (this.storedShapes[targetHash] >= this.currentGoal.required || _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.rewardsInstant) { this.onGoalCompleted(); } } /** * Handles the given hash, by either accounting it towards the * goal or otherwise granting some points * @param {string} hash */ handleDeliveredByHash(hash) { this.storedShapes[hash] = (this.storedShapes[hash] || 0) + 1; this.root.signals.shapeDelivered.dispatch(hash); // Check if we have enough for the next level const targetHash = this.currentGoal.definition.getHash(); if (this.storedShapes[targetHash] >= this.currentGoal.required || _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.rewardsInstant) { this.onGoalCompleted(); } } /** * Creates the next goal */ createNextGoal() { const storyIndex = this.level - 1; if (storyIndex < _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"].length) { const { shape, required, reward } = _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"][storyIndex]; this.currentGoal = { /** @type {ShapeDefinition} */ definition: this.root.shapeDefinitionMgr.getShapeFromShortKey(shape), required, reward, }; return; } for (let fixed of _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["fixedGoals"]) { if (fixed.minLevel > this.level || fixed.maxLevel < this.level) { continue; } let definition = null; if (typeof fixed.shape === "string") { definition = this.root.shapeDefinitionMgr.getShapeFromShortKey(fixed.shape); } else { definition = this.createRandomShapeOfTiers(fixed.shape); } this.currentGoal = { definition, required: fixed.baseCount + (this.level - fixed.minLevel) * fixed.countPerLevel, reward: fixed.reward, }; return; } this.currentGoal = { /** @type {ShapeDefinition} */ definition: this.createRandomShape(), required: 5000 + Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["findNiceIntegerValue"])((this.level - _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"].length) * 200), reward: _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["enumHubGoalRewards"].no_reward_freeplay, }; } /** * Called when the level was completed */ onGoalCompleted() { const reward = this.currentGoal.reward; this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1; this.root.app.gameAnalytics.handleLevelCompleted(this.level); ++this.level; this.createNextGoal(); this.root.signals.storyGoalCompleted.dispatch(this.level - 1, reward); } /** * Returns whether we are playing in free-play */ isFreePlay() { return this.level >= _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"].length; } /** * Returns whether a given upgrade can be unlocked * @param {string} upgradeId */ canUnlockUpgrade(upgradeId) { const handle = _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"][upgradeId]; const currentLevel = this.getUpgradeLevel(upgradeId); if (currentLevel >= handle.tiers.length) { // Max level return false; } if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.upgradesNoCost) { return true; } const tierData = handle.tiers[currentLevel]; for (let i = 0; i < tierData.required.length; ++i) { const requirement = tierData.required[i]; if ((this.storedShapes[requirement.shape] || 0) < requirement.amount) { return false; } } return true; } /** * Returns the number of available upgrades * @returns {number} */ getAvailableUpgradeCount() { let count = 0; for (const upgradeId in _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"]) { if (this.canUnlockUpgrade(upgradeId)) { ++count; } } return count; } /** * Tries to unlock the given upgrade * @param {string} upgradeId * @returns {boolean} */ tryUnlockUpgrade(upgradeId) { if (!this.canUnlockUpgrade(upgradeId)) { return false; } const handle = _upgrades__WEBPACK_IMPORTED_MODULE_9__["UPGRADES"][upgradeId]; const currentLevel = this.getUpgradeLevel(upgradeId); const tierData = handle.tiers[currentLevel]; if (!tierData) { return false; } if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.upgradesNoCost) { // Dont take resources } else { for (let i = 0; i < tierData.required.length; ++i) { const requirement = tierData.required[i]; // Notice: Don't have to check for hash here this.storedShapes[requirement.shape] -= requirement.amount; } } this.upgradeLevels[upgradeId] = (this.upgradeLevels[upgradeId] || 0) + 1; this.upgradeImprovements[upgradeId] += tierData.improvement; this.root.signals.upgradePurchased.dispatch(upgradeId); this.root.app.gameAnalytics.handleUpgradeUnlocked(upgradeId, currentLevel); return true; } /** * @returns {ShapeDefinition} */ createRandomShape() { return this.createRandomShapeOfTiers({ holeTier: 4, shapeTier: 4, colorTier: 4, layerTier: 4, }); } /** * @param {object} arg * @param {number} arg.holeTier * @param {number} arg.shapeTier * @param {number} arg.colorTier * @param {number} arg.layerTier * @returns {ShapeDefinition} */ createRandomShapeOfTiers({ holeTier, shapeTier, colorTier, layerTier }) { const layerCount = layerTier; /** @type {Array} */ let layers = []; const rng = new _core_rng__WEBPACK_IMPORTED_MODULE_11__["RandomNumberGenerator"](this.level + "|" + this.root.map.seed); // @ts-ignore const availableColors = Object.values(_colors__WEBPACK_IMPORTED_MODULE_3__["allColorData"]) .filter(e => e.id != _colors__WEBPACK_IMPORTED_MODULE_3__["enumColors"].uncolored) .filter(e => e.tier <= colorTier) .map(e => e.id); // @ts-ignore const availableShapes = Object.values(_shapes__WEBPACK_IMPORTED_MODULE_4__["allShapeData"]) .filter(e => e.tier <= shapeTier) .map(e => e.id); const randomColor = () => rng.choice(availableColors); const randomShape = () => rng.choice(availableShapes); let layerWith2Holes = -1; if (holeTier >= 2) { availableColors.push(_colors__WEBPACK_IMPORTED_MODULE_3__["enumColors"].uncolored); } if (holeTier >= 4) { layerWith2Holes = rng.nextIntRange(0, layerCount); } for (let i = 0; i < layerCount; ++i) { /** @type {import("./shape_definition").ShapeLayer} */ const layer = [null, null, null, null]; for (let quad = 0; quad < 4; ++quad) { layer[quad] = { subShape: randomShape(), color: randomColor(), }; } if (holeTier >= 3) { let holeIndex = rng.nextIntRange(0, 8); if (holeIndex < 4) { layer[holeIndex] = null; } if (i == layerWith2Holes) { layer[holeIndex % 4] = null; let hole2Index = rng.nextIntRange(0, 4); layer[hole2Index] = null; } } layers.push(layer); } const definition = new _shape_definition__WEBPACK_IMPORTED_MODULE_7__["ShapeDefinition"]({ layers }); return this.root.shapeDefinitionMgr.registerOrReturnHandle(definition); } ////////////// HELPERS /** * Belt speed * @returns {number} items / sec */ getBeltBaseSpeed() { return _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.belt; } /** * Underground belt speed * @returns {number} items / sec */ getUndergroundBeltBaseSpeed() { return _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.belt; } /** * Miner speed * @returns {number} items / sec */ getMinerBaseSpeed() { return _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].minerSpeedItemsPerSecond * this.upgradeImprovements.miner; } /** * Processor speed * @param {enumItemProcessorTypes} processorType * @returns {number} items / sec */ getProcessorBaseSpeed(processorType) { switch (processorType) { case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].splitterWires: return _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].wiresSpeedItemsPerSecond * 2; case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].trash: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].hub: return 1e30; case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].splitter: return _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2; case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].filter: return _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.belt; case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].mixer: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painter: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painterDouble: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].painterQuad: { window.assert( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType], "Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType ); return ( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.painting * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType] ); } case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutter: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].cutterQuad: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotater: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotaterCCW: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].rotaterFL: case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].stacker: { window.assert( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType], "Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType ); return ( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.processors * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType] ); } case _components_item_processor__WEBPACK_IMPORTED_MODULE_5__["enumItemProcessorTypes"].advancedProcessor: { return ( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements.painting * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType] ); } default: { if (_custom_modBuildings__WEBPACK_IMPORTED_MODULE_10__["customBuildingData"][processorType]) { let custom = _custom_modBuildings__WEBPACK_IMPORTED_MODULE_10__["customBuildingData"][processorType]; _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType] = custom.speed; return ( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond * this.upgradeImprovements[custom.speedClass] * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].buildingSpeeds[processorType] ); } window.assert(false, "invalid processor type: " + processorType); } } return 1 / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].beltSpeedItemsPerSecond; } } /***/ }), /***/ "./src/js/game/hud/base_hud_part.js": /*!******************************************!*\ !*** ./src/js/game/hud/base_hud_part.js ***! \******************************************/ /*! exports provided: BaseHUDPart */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseHUDPart", function() { return BaseHUDPart; }); /* harmony import */ var _core_click_detector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../key_action_mapper */ "./src/js/game/key_action_mapper.js"); class BaseHUDPart { /** * @param {GameRoot} root */ constructor(root) { this.root = root; /** @type {Array} */ this.clickDetectors = []; } /** * Should create all require elements * @param {HTMLElement} parent */ createElements(parent) {} /** * Should initialize the element, called *after* the elements have been created */ initialize() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Should update any required logic */ update() {} /** * Should draw the hud * @param {DrawParameters} parameters */ draw(parameters) {} /** * Should draw any overlays (screen space) * @param {DrawParameters} parameters */ drawOverlays(parameters) {} /** * Should return true if the widget has a modal dialog opened and thus * the game does not need to update / redraw * @returns {boolean} */ shouldPauseRendering() { return false; } /** * Should return false if the game should be paused * @returns {boolean} */ shouldPauseGame() { return false; } /** * Should return true if this overlay is open and currently blocking any user interaction */ isBlockingOverlay() { return false; } /** * Cleans up the hud element, if overridden make sure to call super.cleanup */ cleanup() { this.cleanupClickDetectors(); } /** * Cleans up all click detectors */ cleanupClickDetectors() { if (this.clickDetectors) { for (let i = 0; i < this.clickDetectors.length; ++i) { this.clickDetectors[i].cleanup(); } this.clickDetectors = []; } } /** * Should close the element, in case its supported */ close() {} // Helpers /** * Helper method to construct a new click detector * @param {Element} element The element to listen on * @param {function} handler The handler to call on this object * @param {import("../../core/click_detector").ClickDetectorConstructorArgs=} args Click detector arguments * */ trackClicks(element, handler, args = {}) { const detector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](element, args); detector.click.add(handler, this); this.registerClickDetector(detector); } /** * Registers a new click detector * @param {ClickDetector} detector */ registerClickDetector(detector) { this.clickDetectors.push(detector); if (true) { // @ts-ignore detector._src = "hud-" + this.constructor.name; } } /** * Closes this element when its background is clicked * @param {HTMLElement} element * @param {function} closeMethod */ closeOnBackgroundClick(element, closeMethod = null) { const bgClickDetector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](element, { preventDefault: true, targetOnly: true, applyCssClass: null, consumeEvents: true, clickSound: null, }); // If the state defines a close method, use that as fallback // @ts-ignore bgClickDetector.touchend.add(closeMethod || this.close, this); this.registerClickDetector(bgClickDetector); } /** * Forwards the game speed keybindings so you can toggle pause / Fastforward * in the building tooltip and such * @param {KeyActionMapper} sourceMapper */ forwardGameSpeedKeybindings(sourceMapper) { sourceMapper.forward(this.root.keyMapper, ["gamespeed_pause", "gamespeed_fastforward"]); } /** * Forwards the map movement keybindings so you can move the map with the * arrow keys * @param {KeyActionMapper} sourceMapper */ forwardMapMovementKeybindings(sourceMapper) { sourceMapper.forward(this.root.keyMapper, [ "mapMoveUp", "mapMoveRight", "mapMoveDown", "mapMoveLeft", ]); } } /***/ }), /***/ "./src/js/game/hud/dynamic_dom_attach.js": /*!***********************************************!*\ !*** ./src/js/game/hud/dynamic_dom_attach.js ***! \***********************************************/ /*! exports provided: DynamicDomAttach */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DynamicDomAttach", function() { return DynamicDomAttach; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); // Automatically attaches and detaches elements from the dom // Also supports detaching elements after a given time, useful if there is a // hide animation like for the tooltips // Also attaches a class name if desired class DynamicDomAttach { constructor(root, element, { timeToKeepSeconds = 0, attachClass = null } = {}) { /** @type {GameRoot} */ this.root = root; /** @type {HTMLElement} */ this.element = element; this.parent = this.element.parentElement; this.attachClass = attachClass; this.timeToKeepSeconds = timeToKeepSeconds; this.lastVisibleTime = 0; // We start attached, so detach the node first this.attached = true; this.internalDetach(); this.internalIsClassAttached = false; this.classAttachTimeout = null; } internalAttach() { if (!this.attached) { this.parent.appendChild(this.element); window.assert(this.element.parentElement === this.parent, "Invalid parent #1"); this.attached = true; } } internalDetach() { if (this.attached) { window.assert(this.element.parentElement === this.parent, "Invalid parent #2"); this.element.parentElement.removeChild(this.element); this.attached = false; } } isAttached() { return this.attached; } update(isVisible) { if (isVisible) { this.lastVisibleTime = this.root ? this.root.time.realtimeNow() : 0; this.internalAttach(); } else { if (!this.root || this.root.time.realtimeNow() - this.lastVisibleTime >= this.timeToKeepSeconds) { this.internalDetach(); } } if (this.attachClass && isVisible !== this.internalIsClassAttached) { // State changed this.internalIsClassAttached = isVisible; if (this.classAttachTimeout) { clearTimeout(this.classAttachTimeout); this.classAttachTimeout = null; } if (isVisible) { this.classAttachTimeout = setTimeout(() => { this.element.classList.add(this.attachClass); }, 15); } else { this.element.classList.remove(this.attachClass); } } } } /***/ }), /***/ "./src/js/game/hud/hud.js": /*!********************************!*\ !*** ./src/js/game/hud/hud.js ***! \********************************/ /*! exports provided: GameHUD */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameHUD", function() { return GameHUD; }); /* harmony import */ var _trailer_maker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./trailer_maker */ "./src/js/game/hud/trailer_maker.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _parts_buildings_toolbar__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./parts/buildings_toolbar */ "./src/js/game/hud/parts/buildings_toolbar.js"); /* harmony import */ var _parts_building_placer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./parts/building_placer */ "./src/js/game/hud/parts/building_placer.js"); /* harmony import */ var _parts_blueprint_placer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./parts/blueprint_placer */ "./src/js/game/hud/parts/blueprint_placer.js"); /* harmony import */ var _parts_keybinding_overlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./parts/keybinding_overlay */ "./src/js/game/hud/parts/keybinding_overlay.js"); /* harmony import */ var _parts_unlock_notification__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./parts/unlock_notification */ "./src/js/game/hud/parts/unlock_notification.js"); /* harmony import */ var _parts_game_menu__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./parts/game_menu */ "./src/js/game/hud/parts/game_menu.js"); /* harmony import */ var _parts_shop__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./parts/shop */ "./src/js/game/hud/parts/shop.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _parts_mass_selector__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./parts/mass_selector */ "./src/js/game/hud/parts/mass_selector.js"); /* harmony import */ var _parts_vignette_overlay__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./parts/vignette_overlay */ "./src/js/game/hud/parts/vignette_overlay.js"); /* harmony import */ var _parts_statistics__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./parts/statistics */ "./src/js/game/hud/parts/statistics.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _parts_pinned_shapes__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./parts/pinned_shapes */ "./src/js/game/hud/parts/pinned_shapes.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _parts_notifications__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./parts/notifications */ "./src/js/game/hud/parts/notifications.js"); /* harmony import */ var _parts_settings_menu__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./parts/settings_menu */ "./src/js/game/hud/parts/settings_menu.js"); /* harmony import */ var _parts_debug_info__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./parts/debug_info */ "./src/js/game/hud/parts/debug_info.js"); /* harmony import */ var _parts_entity_debugger__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./parts/entity_debugger */ "./src/js/game/hud/parts/entity_debugger.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _parts_watermark__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./parts/watermark */ "./src/js/game/hud/parts/watermark.js"); /* harmony import */ var _parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./parts/modal_dialogs */ "./src/js/game/hud/parts/modal_dialogs.js"); /* harmony import */ var _parts_tutorial_hints__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./parts/tutorial_hints */ "./src/js/game/hud/parts/tutorial_hints.js"); /* harmony import */ var _parts_waypoints__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./parts/waypoints */ "./src/js/game/hud/parts/waypoints.js"); /* harmony import */ var _parts_interactive_tutorial__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./parts/interactive_tutorial */ "./src/js/game/hud/parts/interactive_tutorial.js"); /* harmony import */ var _parts_screenshot_exporter__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./parts/screenshot_exporter */ "./src/js/game/hud/parts/screenshot_exporter.js"); /* harmony import */ var _parts_color_blind_helper__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./parts/color_blind_helper */ "./src/js/game/hud/parts/color_blind_helper.js"); /* harmony import */ var _parts_shape_viewer__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./parts/shape_viewer */ "./src/js/game/hud/parts/shape_viewer.js"); /* harmony import */ var _parts_wires_overlay__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./parts/wires_overlay */ "./src/js/game/hud/parts/wires_overlay.js"); /* harmony import */ var _parts_debug_changes__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./parts/debug_changes */ "./src/js/game/hud/parts/debug_changes.js"); /* harmony import */ var _core_query_parameters__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../../core/query_parameters */ "./src/js/core/query_parameters.js"); /* harmony import */ var _parts_sandbox_controller__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./parts/sandbox_controller */ "./src/js/game/hud/parts/sandbox_controller.js"); /* harmony import */ var _parts_wires_toolbar__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./parts/wires_toolbar */ "./src/js/game/hud/parts/wires_toolbar.js"); /* harmony import */ var _parts_tools_toolbar__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./parts/tools_toolbar */ "./src/js/game/hud/parts/tools_toolbar.js"); /* harmony import */ var _parts_wire_info__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./parts/wire_info */ "./src/js/game/hud/parts/wire_info.js"); /* harmony import */ var _parts_lever_toggle__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./parts/lever_toggle */ "./src/js/game/hud/parts/lever_toggle.js"); /* harmony import */ var _parts_layer_preview__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./parts/layer_preview */ "./src/js/game/hud/parts/layer_preview.js"); /* dev:start */ /* dev:end */ class GameHUD { /** * @param {GameRoot} root */ constructor(root) { this.root = root; } /** * Initializes the hud parts */ initialize() { this.parts = { buildingsToolbar: new _parts_buildings_toolbar__WEBPACK_IMPORTED_MODULE_3__["HUDBuildingsToolbar"](this.root), wiresToolbar: new _parts_wires_toolbar__WEBPACK_IMPORTED_MODULE_34__["HUDWiresToolbar"](this.root), toolsToolbar: new _parts_tools_toolbar__WEBPACK_IMPORTED_MODULE_35__["HUDToolsToolbar"](this.root), blueprintPlacer: new _parts_blueprint_placer__WEBPACK_IMPORTED_MODULE_5__["HUDBlueprintPlacer"](this.root), buildingPlacer: new _parts_building_placer__WEBPACK_IMPORTED_MODULE_4__["HUDBuildingPlacer"](this.root), unlockNotification: new _parts_unlock_notification__WEBPACK_IMPORTED_MODULE_7__["HUDUnlockNotification"](this.root), gameMenu: new _parts_game_menu__WEBPACK_IMPORTED_MODULE_8__["HUDGameMenu"](this.root), massSelector: new _parts_mass_selector__WEBPACK_IMPORTED_MODULE_11__["HUDMassSelector"](this.root), shop: new _parts_shop__WEBPACK_IMPORTED_MODULE_9__["HUDShop"](this.root), statistics: new _parts_statistics__WEBPACK_IMPORTED_MODULE_13__["HUDStatistics"](this.root), waypoints: new _parts_waypoints__WEBPACK_IMPORTED_MODULE_25__["HUDWaypoints"](this.root), wireInfo: new _parts_wire_info__WEBPACK_IMPORTED_MODULE_36__["HUDWireInfo"](this.root), leverToggle: new _parts_lever_toggle__WEBPACK_IMPORTED_MODULE_37__["HUDLeverToggle"](this.root), // Must always exist pinnedShapes: new _parts_pinned_shapes__WEBPACK_IMPORTED_MODULE_15__["HUDPinnedShapes"](this.root), notifications: new _parts_notifications__WEBPACK_IMPORTED_MODULE_17__["HUDNotifications"](this.root), settingsMenu: new _parts_settings_menu__WEBPACK_IMPORTED_MODULE_18__["HUDSettingsMenu"](this.root), // betaOverlay: new HUDBetaOverlay(this.root), debugInfo: new _parts_debug_info__WEBPACK_IMPORTED_MODULE_19__["HUDDebugInfo"](this.root), dialogs: new _parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_23__["HUDModalDialogs"](this.root), screenshotExporter: new _parts_screenshot_exporter__WEBPACK_IMPORTED_MODULE_27__["HUDScreenshotExporter"](this.root), shapeViewer: new _parts_shape_viewer__WEBPACK_IMPORTED_MODULE_29__["HUDShapeViewer"](this.root), wiresOverlay: new _parts_wires_overlay__WEBPACK_IMPORTED_MODULE_30__["HUDWiresOverlay"](this.root), layerPreview: new _parts_layer_preview__WEBPACK_IMPORTED_MODULE_38__["HUDLayerPreview"](this.root), // Typing hints }; this.signals = { buildingSelectedForPlacement: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), shapePinRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), buildingsSelectedForCopy: /** @type {TypedSignal<[Array]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), pasteBlueprintRequested: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), viewShapeDetailsRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_1__["Signal"]()), }; if (!_core_config__WEBPACK_IMPORTED_MODULE_10__["IS_MOBILE"]) { this.parts.keybindingOverlay = new _parts_keybinding_overlay__WEBPACK_IMPORTED_MODULE_6__["HUDKeybindingOverlay"](this.root); } if (_core_config__WEBPACK_IMPORTED_MODULE_10__["globalConfig"].debug.enableEntityInspector) { this.parts.entityDebugger = new _parts_entity_debugger__WEBPACK_IMPORTED_MODULE_20__["HUDEntityDebugger"](this.root); } if (_core_config__WEBPACK_IMPORTED_MODULE_10__["IS_DEMO"]) { this.parts.watermark = new _parts_watermark__WEBPACK_IMPORTED_MODULE_22__["HUDWatermark"](this.root); } if (_core_config__WEBPACK_IMPORTED_MODULE_10__["globalConfig"].debug.renderChanges) { this.parts.changesDebugger = new _parts_debug_changes__WEBPACK_IMPORTED_MODULE_31__["HUDChangesDebugger"](this.root); } if (this.root.app.settings.getAllSettings().offerHints) { this.parts.tutorialHints = new _parts_tutorial_hints__WEBPACK_IMPORTED_MODULE_24__["HUDPartTutorialHints"](this.root); this.parts.interactiveTutorial = new _parts_interactive_tutorial__WEBPACK_IMPORTED_MODULE_26__["HUDInteractiveTutorial"](this.root); } if (this.root.app.settings.getAllSettings().vignette) { this.parts.vignetteOverlay = new _parts_vignette_overlay__WEBPACK_IMPORTED_MODULE_12__["HUDVignetteOverlay"](this.root); } if (this.root.app.settings.getAllSettings().enableColorBlindHelper) { this.parts.colorBlindHelper = new _parts_color_blind_helper__WEBPACK_IMPORTED_MODULE_28__["HUDColorBlindHelper"](this.root); } if (_core_query_parameters__WEBPACK_IMPORTED_MODULE_32__["queryParamOptions"].sandboxMode || _core_config__WEBPACK_IMPORTED_MODULE_10__["IS_DEBUG"]) { this.parts.sandboxController = new _parts_sandbox_controller__WEBPACK_IMPORTED_MODULE_33__["HUDSandboxController"](this.root); } const frag = document.createDocumentFragment(); for (const key in this.parts) { this.parts[key].createElements(frag); } document.body.appendChild(frag); for (const key in this.parts) { this.parts[key].initialize(); } this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_21__["KEYMAPPINGS"].ingame.toggleHud).add(this.toggleUi, this); /* dev:start */ if (_core_config__WEBPACK_IMPORTED_MODULE_10__["globalConfig"].debug.renderForTrailer) { this.trailerMaker = new _trailer_maker__WEBPACK_IMPORTED_MODULE_0__["TrailerMaker"](this.root); } /* dev:end*/ } /** * Attempts to close all overlays */ closeAllOverlays() { for (const key in this.parts) { this.parts[key].close(); } } /** * Returns true if the game logic should be paused */ shouldPauseGame() { for (const key in this.parts) { if (this.parts[key].shouldPauseGame()) { return true; } } return false; } /** * Returns true if the rendering can be paused */ shouldPauseRendering() { for (const key in this.parts) { if (this.parts[key].shouldPauseRendering()) { return true; } } return false; } /** * Returns true if the rendering can be paused */ hasBlockingOverlayOpen() { if (this.root.camera.getIsMapOverlayActive()) { return true; } for (const key in this.parts) { if (this.parts[key].isBlockingOverlay()) { return true; } } return false; } /** * Toggles the ui */ toggleUi() { document.body.classList.toggle("uiHidden"); } /** * Updates all parts */ update() { if (!this.root.gameInitialized) { return; } for (const key in this.parts) { this.parts[key].update(); } /* dev:start */ if (this.trailerMaker) { this.trailerMaker.update(); } /* dev:end*/ } /** * Draws all parts * @param {DrawParameters} parameters */ draw(parameters) { const partsOrder = [ "massSelector", "buildingPlacer", "blueprintPlacer", "colorBlindHelper", "changesDebugger", ]; for (let i = 0; i < partsOrder.length; ++i) { if (this.parts[partsOrder[i]]) { this.parts[partsOrder[i]].draw(parameters); } } } /** * Draws all part overlays * @param {DrawParameters} parameters */ drawOverlays(parameters) { const partsOrder = ["waypoints", "watermark", "wireInfo"]; for (let i = 0; i < partsOrder.length; ++i) { if (this.parts[partsOrder[i]]) { this.parts[partsOrder[i]].drawOverlays(parameters); } } } /** * Cleans up everything */ cleanup() { for (const key in this.parts) { this.parts[key].cleanup(); } for (const key in this.signals) { this.signals[key].removeAll(); } } } /***/ }), /***/ "./src/js/game/hud/parts/base_toolbar.js": /*!***********************************************!*\ !*** ./src/js/game/hud/parts/base_toolbar.js ***! \***********************************************/ /*! exports provided: HUDBaseToolbar */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDBaseToolbar", function() { return HUDBaseToolbar; }); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../root */ "./src/js/game/root.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../buildings/toolbar_swapper */ "./src/js/game/buildings/toolbar_swapper.js"); class HUDBaseToolbar extends _base_hud_part__WEBPACK_IMPORTED_MODULE_6__["BaseHUDPart"] { /** * @param {GameRoot} root * @param {object} param0 * @param {Array} param0.supportedBuildings * @param {function} param0.visibilityCondition * @param {string} param0.htmlElementId */ constructor(root, { supportedBuildings, visibilityCondition, htmlElementId }) { super(root); this.supportedBuildings = supportedBuildings; this.visibilityCondition = visibilityCondition; this.htmlElementId = htmlElementId; /** @type {Object.} */ this.buildingHandles = {}; } /** * Should create all require elements * @param {HTMLElement} parent */ createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(parent, this.htmlElementId, ["ingame_buildingsToolbar"], ""); } initialize() { const actionMapper = this.root.keyMapper; const items = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.element, null, ["buildings"]); for (let i = 0; i < this.supportedBuildings.length; ++i) { const metaBuilding = _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].findByClass(this.supportedBuildings[i]); const mapping = _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].buildings[metaBuilding.getId()]; const binding = mapping && actionMapper.getBinding(mapping); const itemContainer = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(items, null, ["building"]); itemContainer.style.backgroundImage = "url(./res/ui/building_icons/" + metaBuilding.getId() + ".png)"; itemContainer.setAttribute("data-icon", "building_icons/" + metaBuilding.getId() + ".png"); if (binding) { binding.add(() => this.selectBuildingForPlacement(metaBuilding)); } else { console.warn(`${metaBuilding.getId()} has no keybinding`); } this.trackClicks(itemContainer, () => this.selectBuildingForPlacement(metaBuilding), { clickSound: null, }); this.buildingHandles[metaBuilding.id] = { metaBuilding, element: itemContainer, unlocked: false, selected: false, index: i, }; } this.root.hud.signals.selectedPlacementBuildingChanged.add( this.onSelectedPlacementBuildingChanged, this ); // Probably not the best location, but the one which makes most sense this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].ingame.switchToolbar).add(this.switchToolbar, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_7__["DynamicDomAttach"](this.root, this.element, { timeToKeepSeconds: 0.12, attachClass: "visible", }); this.lastSelectedIndex = 0; actionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].placement.cycleBuildings).add(this.cycleBuildings, this); } switchToolbar() { this.root.currentToolbar = (this.root.currentToolbar + 1) % 2; } /** * Updates the toolbar */ update() { const visible = this.visibilityCondition(); this.domAttach.update(visible); if (visible) { for (const buildingId in this.buildingHandles) { const handle = this.buildingHandles[buildingId]; let newStatus = handle.metaBuilding.getIsUnlocked(this.root); if (_core_config__WEBPACK_IMPORTED_MODULE_8__["globalConfig"].debug.allBuildingsUnlocked) { newStatus = true; } if (handle.unlocked !== newStatus) { handle.unlocked = newStatus; handle.element.classList.toggle("unlocked", newStatus); } } } } /** * Cycles through all buildings */ cycleBuildings() { const visible = this.visibilityCondition(); if (!visible) { return; } let newBuildingFound = false; let newIndex = this.lastSelectedIndex; for (let i = 0; i < this.supportedBuildings.length; ++i, ++newIndex) { newIndex %= this.supportedBuildings.length; const metaBuilding = _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].findByClass(this.supportedBuildings[newIndex]); const handle = this.buildingHandles[metaBuilding.id]; if (!handle.selected && handle.unlocked) { newBuildingFound = true; break; } } if (!newBuildingFound) { return; } const metaBuildingClass = this.supportedBuildings[newIndex]; const metaBuilding = _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].findByClass(metaBuildingClass); this.selectBuildingForPlacement(metaBuilding); } /** * Called when the selected building got changed * @param {MetaBuilding} metaBuilding */ onSelectedPlacementBuildingChanged(metaBuilding) { for (const buildingId in this.buildingHandles) { const handle = this.buildingHandles[buildingId]; const newStatus = handle.metaBuilding === metaBuilding; if (handle.selected !== newStatus) { handle.selected = newStatus; handle.element.classList.toggle("selected", newStatus); } if (handle.selected) { this.lastSelectedIndex = handle.index; } } this.element.classList.toggle("buildingSelected", !!metaBuilding); } /** * @param {MetaBuilding} metaBuilding */ selectBuildingForPlacement(metaBuilding) { if (!this.visibilityCondition()) { // Not active return; } if (!metaBuilding.getIsUnlocked(this.root)) { if ( false || !_core_config__WEBPACK_IMPORTED_MODULE_8__["globalConfig"].debug.allBuildingsUnlocked) { this.root.soundProxy.playUiError(); return _core_signal__WEBPACK_IMPORTED_MODULE_1__["STOP_PROPAGATION"]; } } // Allow clicking an item again to deselect it for (const buildingId in this.buildingHandles) { const handle = this.buildingHandles[buildingId]; if (handle.selected && handle.metaBuilding === metaBuilding) { metaBuilding = null; break; } } if (metaBuilding && metaBuilding.id == "toolbar_swapper") { this.switchToolbar(); metaBuilding = null; } this.root.soundProxy.playUiClick(); this.root.hud.signals.buildingSelectedForPlacement.dispatch(metaBuilding); this.onSelectedPlacementBuildingChanged(metaBuilding); } } /***/ }), /***/ "./src/js/game/hud/parts/blueprint_placer.js": /*!***************************************************!*\ !*** ./src/js/game/hud/parts/blueprint_placer.js ***! \***************************************************/ /*! exports provided: HUDBlueprintPlacer */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDBlueprintPlacer", function() { return HUDBlueprintPlacer; }); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/tracked_state */ "./src/js/core/tracked_state.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../camera */ "./src/js/game/camera.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _blueprint__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../blueprint */ "./src/js/game/blueprint.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../platform/sound */ "./src/js/platform/sound.js"); class HUDBlueprintPlacer extends _base_hud_part__WEBPACK_IMPORTED_MODULE_9__["BaseHUDPart"] { createElements(parent) { const blueprintCostShape = this.root.shapeDefinitionMgr.getShapeFromShortKey(_upgrades__WEBPACK_IMPORTED_MODULE_8__["blueprintShape"]); const blueprintCostShapeCanvas = blueprintCostShape.generateAsCanvas(80); this.costDisplayParent = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(parent, "ingame_HUD_BlueprintPlacer", [], ``); Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(this.costDisplayParent, null, ["label"], _translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.blueprintPlacer.cost); const costContainer = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(this.costDisplayParent, null, ["costContainer"], ""); this.costDisplayText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(costContainer, null, ["costText"], ""); costContainer.appendChild(blueprintCostShapeCanvas); } initialize() { this.root.hud.signals.buildingsSelectedForCopy.add(this.createBlueprintFromBuildings, this); /** @type {TypedTrackedState} */ this.currentBlueprint = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_2__["TrackedState"](this.onBlueprintChanged, this); /** @type {Blueprint?} */ this.lastBlueprintUsed = null; const keyActionMapper = this.root.keyMapper; keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["KEYMAPPINGS"].general.back).add(this.abortPlacement, this); keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["KEYMAPPINGS"].placement.pipette).add(this.abortPlacement, this); keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["KEYMAPPINGS"].placement.rotateWhilePlacing).add(this.rotateBlueprint, this); keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["KEYMAPPINGS"].massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this); this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); this.root.hud.signals.selectedPlacementBuildingChanged.add(this.abortPlacement, this); this.root.signals.editModeChanged.add(this.onEditModeChanged, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_10__["DynamicDomAttach"](this.root, this.costDisplayParent); this.trackedCanAfford = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_2__["TrackedState"](this.onCanAffordChanged, this); } abortPlacement() { if (this.currentBlueprint.get()) { this.currentBlueprint.set(null); return _core_signal__WEBPACK_IMPORTED_MODULE_1__["STOP_PROPAGATION"]; } } /** * Called when the layer was changed * @param {Layer} layer */ onEditModeChanged(layer) { // Check if the layer of the blueprint differs and thus we have to deselect it const blueprint = this.currentBlueprint.get(); if (blueprint) { if (blueprint.layer !== layer) { this.currentBlueprint.set(null); } } } /** * Called when the blueprint is now affordable or not * @param {boolean} canAfford */ onCanAffordChanged(canAfford) { this.costDisplayParent.classList.toggle("canAfford", canAfford); } update() { const currentBlueprint = this.currentBlueprint.get(); this.domAttach.update(currentBlueprint && currentBlueprint.getCost() > 0); this.trackedCanAfford.set(currentBlueprint && currentBlueprint.canAfford(this.root)); } /** * Called when the blueprint was changed * @param {Blueprint} blueprint */ onBlueprintChanged(blueprint) { if (blueprint) { this.lastBlueprintUsed = blueprint; this.costDisplayText.innerText = "" + blueprint.getCost(); } } /** * mouse down pre handler * @param {Vector} pos * @param {enumMouseButton} button */ onMouseDown(pos, button) { if (button === _camera__WEBPACK_IMPORTED_MODULE_6__["enumMouseButton"].right) { if (this.currentBlueprint.get()) { this.abortPlacement(); return _core_signal__WEBPACK_IMPORTED_MODULE_1__["STOP_PROPAGATION"]; } } const blueprint = this.currentBlueprint.get(); if (!blueprint) { return; } if (!blueprint.canAfford(this.root)) { this.root.soundProxy.playUiError(); return; } const worldPos = this.root.camera.screenToWorld(pos); const tile = worldPos.toTileSpace(); if (blueprint.tryPlace(this.root, tile)) { const cost = blueprint.getCost(); this.root.hubGoals.takeShapeByKey(_upgrades__WEBPACK_IMPORTED_MODULE_8__["blueprintShape"], cost); const leftover = this.root.hubGoals.getShapesStoredByKey(_upgrades__WEBPACK_IMPORTED_MODULE_8__["blueprintShape"]); if (leftover < 50) { this.root.hubGoals.putShapeByKey(_upgrades__WEBPACK_IMPORTED_MODULE_8__["blueprintShape"], 50 - leftover); } this.root.soundProxy.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_12__["SOUNDS"].placeBuilding); } } /** * Mose move handler */ onMouseMove() { // Prevent movement while blueprint is selected if (this.currentBlueprint.get()) { return _core_signal__WEBPACK_IMPORTED_MODULE_1__["STOP_PROPAGATION"]; } } /** * Called when an array of bulidings was selected * @param {Array} uids */ createBlueprintFromBuildings(uids) { if (uids.length === 0) { return; } this.currentBlueprint.set(_blueprint__WEBPACK_IMPORTED_MODULE_11__["Blueprint"].fromUids(this.root, uids)); } /** * Attempts to rotate the current blueprint */ rotateBlueprint() { if (this.currentBlueprint.get()) { if (this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_7__["KEYMAPPINGS"].placement.rotateInverseModifier).pressed) { this.currentBlueprint.get().rotateCcw(); } else { this.currentBlueprint.get().rotateCw(); } } } /** * Attempts to paste the last blueprint */ pasteBlueprint() { if (this.lastBlueprintUsed !== null) { if (this.lastBlueprintUsed.layer !== this.root.currentLayer) { // Not compatible this.root.soundProxy.playUiError(); return; } this.root.hud.signals.pasteBlueprintRequested.dispatch(); this.currentBlueprint.set(this.lastBlueprintUsed); } else { this.root.soundProxy.playUiError(); } } /** * * @param {DrawParameters} parameters */ draw(parameters) { const blueprint = this.currentBlueprint.get(); if (!blueprint) { return; } const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return; } const worldPos = this.root.camera.screenToWorld(mousePosition); const tile = worldPos.toTileSpace(); blueprint.draw(parameters, tile); } } /***/ }), /***/ "./src/js/game/hud/parts/building_placer.js": /*!**************************************************!*\ !*** ./src/js/game/hud/parts/building_placer.js ***! \**************************************************/ /*! exports provided: HUDBuildingPlacer */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDBuildingPlacer", function() { return HUDBuildingPlacer; }); /* harmony import */ var _core_click_detector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../theme */ "./src/js/game/theme.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _building_placer_logic__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./building_placer_logic */ "./src/js/game/hud/parts/building_placer_logic.js"); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../root */ "./src/js/game/root.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../building_codes */ "./src/js/game/building_codes.js"); class HUDBuildingPlacer extends _building_placer_logic__WEBPACK_IMPORTED_MODULE_12__["HUDBuildingPlacerLogic"] { /** * @param {HTMLElement} parent */ createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(parent, "ingame_HUD_PlacementHints", [], ``); this.buildingInfoElements = {}; this.buildingInfoElements.label = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(this.element, null, ["buildingLabel"], "Extract"); this.buildingInfoElements.desc = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(this.element, null, ["description"], ""); this.buildingInfoElements.descText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(this.buildingInfoElements.desc, null, ["text"], ""); this.buildingInfoElements.additionalInfo = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])( this.buildingInfoElements.desc, null, ["additionalInfo"], "" ); this.buildingInfoElements.hotkey = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(this.buildingInfoElements.desc, null, ["hotkey"], ""); this.buildingInfoElements.tutorialImage = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(this.element, null, ["buildingImage"]); this.variantsElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(parent, "ingame_HUD_PlacerVariants"); const compact = this.root.app.settings.getAllSettings().compactBuildingInfo; this.element.classList.toggle("compact", compact); this.variantsElement.classList.toggle("compact", compact); } initialize() { super.initialize(); // Bind to signals this.signals.variantChanged.add(this.rerenderVariants, this); this.root.hud.signals.buildingSelectedForPlacement.add(this.startSelection, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_11__["DynamicDomAttach"](this.root, this.element, {}); this.variantsAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_11__["DynamicDomAttach"](this.root, this.variantsElement, {}); this.currentInterpolatedCornerTile = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](); this.lockIndicatorSprites = {}; _root__WEBPACK_IMPORTED_MODULE_14__["layers"].forEach(layer => { this.lockIndicatorSprites[layer] = this.makeLockIndicatorSprite(layer); }); // /** * Stores the click detectors for the variants so we can clean them up later * @type {Array} */ this.variantClickDetectors = []; } /** * Makes the lock indicator sprite for the given layer * @param {Layer} layer */ makeLockIndicatorSprite(layer) { const dims = 48; const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_13__["makeOffscreenBuffer"])(dims, dims, { smooth: true, reusable: false, label: "lock-direction-indicator", }); context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_10__["THEME"].map.directionLock[layer].color; context.strokeStyle = _theme__WEBPACK_IMPORTED_MODULE_10__["THEME"].map.directionLock[layer].color; context.lineWidth = 2; const padding = 5; const height = dims * 0.5; const bottom = (dims + height) / 2; context.moveTo(padding, bottom); context.lineTo(dims / 2, bottom - height); context.lineTo(dims - padding, bottom); context.closePath(); context.stroke(); context.fill(); return canvas; } /** * Rerenders the building info dialog */ rerenderInfoDialog() { const metaBuilding = this.currentMetaBuilding.get(); if (!metaBuilding) { return; } const variant = this.currentVariant.get(); this.buildingInfoElements.label.innerHTML = _translations__WEBPACK_IMPORTED_MODULE_7__["T"].buildings[metaBuilding.id][variant].name; this.buildingInfoElements.descText.innerHTML = _translations__WEBPACK_IMPORTED_MODULE_7__["T"].buildings[metaBuilding.id][variant].description; const mapping = _key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].buildings[metaBuilding.getId()]; if (mapping) { const binding = this.root.keyMapper.getBinding(mapping); this.buildingInfoElements.hotkey.innerHTML = _translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.buildingPlacement.hotkeyLabel.replace( "", "" + binding.getKeyCodeString() + "" ); } else { this.buildingInfoElements.hotkey.innerHTML = ""; } this.buildingInfoElements.tutorialImage.style.backgroundImage = `url(./res/ui/building_tutorials/${metaBuilding.getId()}${ variant === _meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"] ? "" : "-" + variant }.png)`; this.buildingInfoElements.tutorialImage.setAttribute( "data-icon", "building_tutorials/" + metaBuilding.getId() + (variant === _meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"] ? "" : "-" + variant) + ".png" ); Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["removeAllChildren"])(this.buildingInfoElements.additionalInfo); const additionalInfo = metaBuilding.getAdditionalStatistics(this.root, this.currentVariant.get()); for (let i = 0; i < additionalInfo.length; ++i) { const [label, contents] = additionalInfo[i]; this.buildingInfoElements.additionalInfo.innerHTML += ` ${contents} `; } } cleanup() { super.cleanup(); this.cleanupVariantClickDetectors(); } /** * Cleans up all variant click detectors */ cleanupVariantClickDetectors() { for (let i = 0; i < this.variantClickDetectors.length; ++i) { const detector = this.variantClickDetectors[i]; detector.cleanup(); } this.variantClickDetectors = []; } /** * Rerenders the variants displayed */ rerenderVariants() { Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["removeAllChildren"])(this.variantsElement); this.rerenderInfoDialog(); const metaBuilding = this.currentMetaBuilding.get(); // First, clear up all click detectors this.cleanupVariantClickDetectors(); if (!metaBuilding) { return; } const availableVariants = metaBuilding.getAvailableVariants(this.root); if (availableVariants.length === 1) { return; } Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])( this.variantsElement, null, ["explanation"], _translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.buildingPlacement.cycleBuildingVariants.replace( "", "" + this.root.keyMapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.cycleBuildingVariants) .getKeyCodeString() + "" ) ); const container = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(this.variantsElement, null, ["variants"]); for (let i = 0; i < availableVariants.length; ++i) { const variant = availableVariants[i]; const element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(container, null, ["variant"]); element.classList.toggle("active", variant === this.currentVariant.get()); Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(element, null, ["label"], variant); const iconSize = 64; const dimensions = metaBuilding.getDimensions(variant); const sprite = metaBuilding.getPreviewSprite(0, variant); const spriteWrapper = Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["makeDiv"])(element, null, ["iconWrap"]); spriteWrapper.setAttribute("data-tile-w", dimensions.x); spriteWrapper.setAttribute("data-tile-h", dimensions.y); spriteWrapper.innerHTML = sprite.getAsHTML(iconSize * dimensions.x, iconSize * dimensions.y); const detector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](element, { consumeEvents: true, targetOnly: true, }); detector.click.add(() => this.setVariant(variant)); } } /** * * @param {DrawParameters} parameters */ draw(parameters) { if (this.root.camera.zoomLevel < _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].mapChunkOverviewMinZoom) { // Dont allow placing in overview mode this.domAttach.update(false); this.variantsAttach.update(false); return; } this.domAttach.update(this.currentMetaBuilding.get()); this.variantsAttach.update(this.currentMetaBuilding.get()); const metaBuilding = this.currentMetaBuilding.get(); if (!metaBuilding) { return; } // Draw direction lock if (this.isDirectionLockActive) { this.drawDirectionLock(parameters); } else { this.drawRegularPlacement(parameters); } if (metaBuilding.getShowWiresLayerPreview()) { this.drawLayerPeek(parameters); } } /** * * @param {DrawParameters} parameters */ drawLayerPeek(parameters) { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return; } const worldPosition = this.root.camera.screenToWorld(mousePosition); // Draw peeker this.root.hud.parts.layerPreview.renderPreview( parameters, worldPosition, 1 / this.root.camera.zoomLevel ); } /** * @param {DrawParameters} parameters */ drawRegularPlacement(parameters) { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return; } const metaBuilding = this.currentMetaBuilding.get(); const worldPos = this.root.camera.screenToWorld(mousePosition); const mouseTile = worldPos.toTileSpace(); // Compute best rotation variant const { rotation, rotationVariant, connectedEntities, } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile({ root: this.root, tile: mouseTile, rotation: this.currentBaseRotation, variant: this.currentVariant.get(), layer: metaBuilding.getLayer(), }); // Check if there are connected entities if (connectedEntities) { for (let i = 0; i < connectedEntities.length; ++i) { const connectedEntity = connectedEntities[i]; const connectedWsPoint = connectedEntity.components.StaticMapEntity.getTileSpaceBounds() .getCenter() .toWorldSpace(); const startWsPoint = mouseTile.toWorldSpaceCenterOfTile(); const startOffset = connectedWsPoint .sub(startWsPoint) .normalize() .multiplyScalar(_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize * 0.3); const effectiveStartPoint = startWsPoint.add(startOffset); const effectiveEndPoint = connectedWsPoint.sub(startOffset); parameters.context.globalAlpha = 0.6; // parameters.context.lineCap = "round"; parameters.context.strokeStyle = "#7f7"; parameters.context.lineWidth = 10; parameters.context.beginPath(); parameters.context.moveTo(effectiveStartPoint.x, effectiveStartPoint.y); parameters.context.lineTo(effectiveEndPoint.x, effectiveEndPoint.y); parameters.context.stroke(); parameters.context.globalAlpha = 1; // parameters.context.lineCap = "square"; } } // Synchronize rotation and origin const staticComp = this.fakeEntity.components.StaticMapEntity; staticComp.origin = mouseTile; staticComp.rotation = rotation; metaBuilding.updateVariants(this.fakeEntity, rotationVariant, this.currentVariant.get()); staticComp.code = Object(_building_codes__WEBPACK_IMPORTED_MODULE_15__["getCodeFromBuildingData"])( this.currentMetaBuilding.get(), this.currentVariant.get(), rotationVariant ); const canBuild = this.root.logic.checkCanPlaceEntity(this.fakeEntity); // Fade in / out parameters.context.lineWidth = 1; // Determine the bounds and visualize them const entityBounds = staticComp.getTileSpaceBounds(); const drawBorder = -3; if (canBuild) { parameters.context.strokeStyle = "rgba(56, 235, 111, 0.5)"; parameters.context.fillStyle = "rgba(56, 235, 111, 0.2)"; } else { parameters.context.strokeStyle = "rgba(255, 0, 0, 0.2)"; parameters.context.fillStyle = "rgba(255, 0, 0, 0.2)"; } parameters.context.beginRoundedRect( entityBounds.x * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize - drawBorder, entityBounds.y * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize - drawBorder, entityBounds.w * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize + 2 * drawBorder, entityBounds.h * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize + 2 * drawBorder, 4 ); parameters.context.stroke(); // parameters.context.fill(); parameters.context.globalAlpha = 1; // HACK to draw the entity sprite const previewSprite = metaBuilding.getBlueprintSprite(rotationVariant, this.currentVariant.get()); staticComp.origin = worldPos.divideScalar(_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize).subScalars(0.5, 0.5); staticComp.drawSpriteOnBoundsClipped(parameters, previewSprite); staticComp.origin = mouseTile; // Draw ejectors if (canBuild) { this.drawMatchingAcceptorsAndEjectors(parameters); } } /** * @param {DrawParameters} parameters */ drawDirectionLock(parameters) { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return; } const mouseWorld = this.root.camera.screenToWorld(mousePosition); const mouseTile = mouseWorld.toTileSpace(); parameters.context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_10__["THEME"].map.directionLock[this.root.currentLayer].color; parameters.context.strokeStyle = _theme__WEBPACK_IMPORTED_MODULE_10__["THEME"].map.directionLock[this.root.currentLayer].background; parameters.context.lineWidth = 10; parameters.context.beginCircle(mouseWorld.x, mouseWorld.y, 4); parameters.context.fill(); if (this.lastDragTile) { const startLine = this.lastDragTile.toWorldSpaceCenterOfTile(); const endLine = mouseTile.toWorldSpaceCenterOfTile(); const midLine = this.currentDirectionLockCorner.toWorldSpaceCenterOfTile(); parameters.context.beginCircle(startLine.x, startLine.y, 8); parameters.context.fill(); parameters.context.beginPath(); parameters.context.moveTo(startLine.x, startLine.y); parameters.context.lineTo(midLine.x, midLine.y); parameters.context.lineTo(endLine.x, endLine.y); parameters.context.stroke(); parameters.context.beginCircle(endLine.x, endLine.y, 5); parameters.context.fill(); // Draw arrow const arrowSprite = this.lockIndicatorSprites[this.root.currentLayer]; const path = this.computeDirectionLockPath(); for (let i = 0; i < path.length - 1; i += 1) { const { rotation, tile } = path[i]; const worldPos = tile.toWorldSpaceCenterOfTile(); const angle = Math.radians(rotation); parameters.context.translate(worldPos.x, worldPos.y); parameters.context.rotate(angle); parameters.context.drawImage( arrowSprite, -6, -_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].halfTileSize - Object(_core_utils__WEBPACK_IMPORTED_MODULE_5__["clamp"])((this.root.time.realtimeNow() * 1.5) % 1.0, 0, 1) * 1 * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize + _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].halfTileSize - 6, 12, 12 ); parameters.context.rotate(-angle); parameters.context.translate(-worldPos.x, -worldPos.y); } } } /** * @param {DrawParameters} parameters */ drawMatchingAcceptorsAndEjectors(parameters) { const acceptorComp = this.fakeEntity.components.ItemAcceptor; const ejectorComp = this.fakeEntity.components.ItemEjector; const staticComp = this.fakeEntity.components.StaticMapEntity; const beltComp = this.fakeEntity.components.Belt; const goodArrowSprite = _core_loader__WEBPACK_IMPORTED_MODULE_4__["Loader"].getSprite("sprites/misc/slot_good_arrow.png"); const badArrowSprite = _core_loader__WEBPACK_IMPORTED_MODULE_4__["Loader"].getSprite("sprites/misc/slot_bad_arrow.png"); // Just ignore the following code please ... thanks! const offsetShift = 10; let acceptorSlots = []; let ejectorSlots = []; if (ejectorComp) { ejectorSlots = ejectorComp.slots.slice(); } if (acceptorComp) { acceptorSlots = acceptorComp.slots.slice(); } if (beltComp) { const fakeEjectorSlot = beltComp.getFakeEjectorSlot(); const fakeAcceptorSlot = beltComp.getFakeAcceptorSlot(); ejectorSlots.push(fakeEjectorSlot); acceptorSlots.push(fakeAcceptorSlot); } for (let acceptorSlotIndex = 0; acceptorSlotIndex < acceptorSlots.length; ++acceptorSlotIndex) { const slot = acceptorSlots[acceptorSlotIndex]; const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos); const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile(); // Go over all slots for ( let acceptorDirectionIndex = 0; acceptorDirectionIndex < slot.directions.length; ++acceptorDirectionIndex ) { const direction = slot.directions[acceptorDirectionIndex]; const worldDirection = staticComp.localDirectionToWorld(direction); // Figure out which tile ejects to this slot const sourceTile = acceptorSlotWsTile.add(_core_vector__WEBPACK_IMPORTED_MODULE_6__["enumDirectionToVector"][worldDirection]); let isBlocked = false; let isConnected = false; // Find all entities which are on that tile const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y); // Check for every entity: for (let i = 0; i < sourceEntities.length; ++i) { const sourceEntity = sourceEntities[i]; const sourceEjector = sourceEntity.components.ItemEjector; const sourceBeltComp = sourceEntity.components.Belt; const sourceStaticComp = sourceEntity.components.StaticMapEntity; const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile); // If this entity is on the same layer as the slot - if so, it can either be // connected, or it can not be connected and thus block the input if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) { // This one is connected, all good isConnected = true; } else if ( sourceBeltComp && sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) === _core_vector__WEBPACK_IMPORTED_MODULE_6__["enumInvertedDirections"][worldDirection] ) { // Belt connected isConnected = true; } else { // This one is blocked isBlocked = true; } } const alpha = isConnected || isBlocked ? 1.0 : 0.3; const sprite = isBlocked ? badArrowSprite : goodArrowSprite; parameters.context.globalAlpha = alpha; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_3__["drawRotatedSprite"])({ parameters, sprite, x: acceptorSlotWsPos.x, y: acceptorSlotWsPos.y, angle: Math.radians(_core_vector__WEBPACK_IMPORTED_MODULE_6__["enumDirectionToAngle"][_core_vector__WEBPACK_IMPORTED_MODULE_6__["enumInvertedDirections"][worldDirection]]), size: 13, offsetY: offsetShift + 13, }); parameters.context.globalAlpha = 1; } } // Go over all slots for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorSlots.length; ++ejectorSlotIndex) { const slot = ejectorSlots[ejectorSlotIndex]; const ejectorSlotLocalTile = slot.pos.add(_core_vector__WEBPACK_IMPORTED_MODULE_6__["enumDirectionToVector"][slot.direction]); const ejectorSlotWsTile = staticComp.localTileToWorld(ejectorSlotLocalTile); const ejectorSLotWsPos = ejectorSlotWsTile.toWorldSpaceCenterOfTile(); const ejectorSlotWsDirection = staticComp.localDirectionToWorld(slot.direction); let isBlocked = false; let isConnected = false; // Find all entities which are on that tile const destEntities = this.root.map.getLayersContentsMultipleXY( ejectorSlotWsTile.x, ejectorSlotWsTile.y ); // Check for every entity: for (let i = 0; i < destEntities.length; ++i) { const destEntity = destEntities[i]; const destAcceptor = destEntity.components.ItemAcceptor; const destStaticComp = destEntity.components.StaticMapEntity; const destLocalTile = destStaticComp.worldToLocalTile(ejectorSlotWsTile); const destLocalDir = destStaticComp.worldDirectionToLocal(ejectorSlotWsDirection); if (destAcceptor && destAcceptor.findMatchingSlot(destLocalTile, destLocalDir)) { // This one is connected, all good isConnected = true; } else if (destEntity.components.Belt && destLocalDir === _core_vector__WEBPACK_IMPORTED_MODULE_6__["enumDirection"].top) { // Connected to a belt isConnected = true; } else { // This one is blocked isBlocked = true; } } const alpha = isConnected || isBlocked ? 1.0 : 0.3; const sprite = isBlocked ? badArrowSprite : goodArrowSprite; parameters.context.globalAlpha = alpha; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_3__["drawRotatedSprite"])({ parameters, sprite, x: ejectorSLotWsPos.x, y: ejectorSLotWsPos.y, angle: Math.radians(_core_vector__WEBPACK_IMPORTED_MODULE_6__["enumDirectionToAngle"][ejectorSlotWsDirection]), size: 13, offsetY: offsetShift, }); parameters.context.globalAlpha = 1; } } } /***/ }), /***/ "./src/js/game/hud/parts/building_placer_logic.js": /*!********************************************************!*\ !*** ./src/js/game/hud/parts/building_placer_logic.js ***! \********************************************************/ /*! exports provided: HUDBuildingPlacerLogic */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDBuildingPlacerLogic", function() { return HUDBuildingPlacerLogic; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/tracked_state */ "./src/js/core/tracked_state.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../camera */ "./src/js/game/camera.js"); /* harmony import */ var _components_static_map_entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../components/static_map_entity */ "./src/js/game/components/static_map_entity.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../entity */ "./src/js/game/entity.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _buildings_miner__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../buildings/miner */ "./src/js/game/buildings/miner.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _buildings_hub__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../buildings/hub */ "./src/js/game/buildings/hub.js"); /** * Contains all logic for the building placer - this doesn't include the rendering * of info boxes or drawing. */ class HUDBuildingPlacerLogic extends _base_hud_part__WEBPACK_IMPORTED_MODULE_10__["BaseHUDPart"] { /** * Initializes the logic * @see BaseHUDPart.initialize */ initialize() { /** * We use a fake entity to get information about how a building will look * once placed * @type {Entity} */ this.fakeEntity = null; // Signals this.signals = { variantChanged: new _core_signal__WEBPACK_IMPORTED_MODULE_2__["Signal"](), draggingStarted: new _core_signal__WEBPACK_IMPORTED_MODULE_2__["Signal"](), }; /** * The current building * @type {TypedTrackedState} */ this.currentMetaBuilding = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_3__["TrackedState"](this.onSelectedMetaBuildingChanged, this); /** * The current rotation * @type {number} */ this.currentBaseRotationGeneral = 0; /** * The current rotation preference for each building. * @type{Object.} */ this.preferredBaseRotations = {}; /** * Whether we are currently dragging * @type {boolean} */ this.currentlyDragging = false; /** * Current building variant * @type {TypedTrackedState} */ this.currentVariant = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_3__["TrackedState"](() => this.signals.variantChanged.dispatch()); /** * Whether we are currently drag-deleting * @type {boolean} */ this.currentlyDeleting = false; /** * Stores which variants for each building we prefer, this is based on what * the user last selected * @type {Object.} */ this.preferredVariants = {}; /** * The tile we last dragged from * @type {Vector} */ this.lastDragTile = null; /** * The side for direction lock * @type {number} (0|1) */ this.currentDirectionLockSide = 0; /** * Whether the side for direction lock has not yet been determined. * @type {boolean} */ this.currentDirectionLockSideIndeterminate = true; this.initializeBindings(); } /** * Initializes all bindings */ initializeBindings() { // KEYBINDINGS const keyActionMapper = this.root.keyMapper; keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.rotateWhilePlacing).add(this.tryRotate, this); keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.cycleBuildingVariants).add(this.cycleVariants, this); keyActionMapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.switchDirectionLockSide) .add(this.switchDirectionLockSide, this); keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].general.back).add(this.abortPlacement, this); keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.pipette).add(this.startPipette, this); this.root.gameState.inputReciever.keyup.add(this.checkForDirectionLockSwitch, this); // BINDINGS TO GAME EVENTS this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this); this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this); this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch()); this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch()); this.root.signals.editModeChanged.add(this.onEditModeChanged, this); // MOUSE BINDINGS this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); this.root.camera.upPostHandler.add(this.onMouseUp, this); } /** * Called when the edit mode got changed * @param {Layer} layer */ onEditModeChanged(layer) { const metaBuilding = this.currentMetaBuilding.get(); if (metaBuilding) { if (metaBuilding.getLayer() !== layer) { // This layer doesn't fit the edit mode anymore this.currentMetaBuilding.set(null); } } } /** * Returns the current base rotation for the current meta-building. * @returns {number} */ get currentBaseRotation() { if (!this.root.app.settings.getAllSettings().rotationByBuilding) { return this.currentBaseRotationGeneral; } const metaBuilding = this.currentMetaBuilding.get(); if (metaBuilding && this.preferredBaseRotations.hasOwnProperty(metaBuilding.getId())) { return this.preferredBaseRotations[metaBuilding.getId()]; } else { return this.currentBaseRotationGeneral; } } /** * Sets the base rotation for the current meta-building. * @param {number} rotation The new rotation/angle. */ set currentBaseRotation(rotation) { if (!this.root.app.settings.getAllSettings().rotationByBuilding) { this.currentBaseRotationGeneral = rotation; } else { const metaBuilding = this.currentMetaBuilding.get(); if (metaBuilding) { this.preferredBaseRotations[metaBuilding.getId()] = rotation; } else { this.currentBaseRotationGeneral = rotation; } } } /** * Returns if the direction lock is currently active * @returns {boolean} */ get isDirectionLockActive() { const metaBuilding = this.currentMetaBuilding.get(); return ( metaBuilding && metaBuilding.getHasDirectionLockAvailable() && this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.lockBeltDirection).pressed ); } /** * Returns the current direction lock corner, that is, the corner between * mouse and original start point * @returns {Vector|null} */ get currentDirectionLockCorner() { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return null; } if (!this.lastDragTile) { // Haven't dragged yet return null; } // Figure which points the line visits const worldPos = this.root.camera.screenToWorld(mousePosition); const mouseTile = worldPos.toTileSpace(); // Figure initial direction const dx = Math.abs(this.lastDragTile.x - mouseTile.x); const dy = Math.abs(this.lastDragTile.y - mouseTile.y); if (dx === 0 && dy === 0) { // Back at the start. Try a new direction. this.currentDirectionLockSideIndeterminate = true; } else if (this.currentDirectionLockSideIndeterminate) { this.currentDirectionLockSideIndeterminate = false; this.currentDirectionLockSide = dx <= dy ? 0 : 1; } if (this.currentDirectionLockSide === 0) { return new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](this.lastDragTile.x, mouseTile.y); } else { return new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](mouseTile.x, this.lastDragTile.y); } } /** * Aborts the placement */ abortPlacement() { if (this.currentMetaBuilding.get()) { this.currentMetaBuilding.set(null); return _core_signal__WEBPACK_IMPORTED_MODULE_2__["STOP_PROPAGATION"]; } } /** * Aborts any dragging */ abortDragging() { this.currentlyDragging = true; this.currentlyDeleting = false; this.initialPlacementVector = null; this.lastDragTile = null; } /** * @see BaseHUDPart.update */ update() { // Always update since the camera might have moved const mousePos = this.root.app.mousePosition; if (mousePos) { this.onMouseMove(mousePos); } // Make sure we have nothing selected while in overview mode if (this.root.camera.getIsMapOverlayActive()) { if (this.currentMetaBuilding.get()) { this.currentMetaBuilding.set(null); } } } /** * Tries to rotate the current building */ tryRotate() { const selectedBuilding = this.currentMetaBuilding.get(); if (selectedBuilding) { if (this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.rotateInverseModifier).pressed) { this.currentBaseRotation = (this.currentBaseRotation + 270) % 360; } else { this.currentBaseRotation = (this.currentBaseRotation + 90) % 360; } const staticComp = this.fakeEntity.components.StaticMapEntity; staticComp.rotation = this.currentBaseRotation; } } /** * Tries to delete the building under the mouse */ deleteBelowCursor() { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return false; } const worldPos = this.root.camera.screenToWorld(mousePosition); const tile = worldPos.toTileSpace(); const contents = this.root.map.getTileContent(tile, this.root.currentLayer); if (contents) { if (this.root.logic.tryDeleteBuilding(contents)) { this.root.soundProxy.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_11__["SOUNDS"].destroyBuilding); return true; } } return false; } /** * Starts the pipette function */ startPipette() { // Disable in overview if (this.root.camera.getIsMapOverlayActive()) { return; } const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return; } const worldPos = this.root.camera.screenToWorld(mousePosition); const tile = worldPos.toTileSpace(); const contents = this.root.map.getTileContent(tile, this.root.currentLayer); if (!contents) { const tileBelow = this.root.map.getLowerLayerContentXY(tile.x, tile.y); // Check if there's a shape or color item below, if so select the miner if (tileBelow) { this.currentMetaBuilding.set(_core_global_registries__WEBPACK_IMPORTED_MODULE_1__["gMetaBuildingRegistry"].findByClass(_buildings_miner__WEBPACK_IMPORTED_MODULE_12__["MetaMinerBuilding"])); // Select chained miner if available, since thats always desired once unlocked if (this.root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_13__["enumHubGoalRewards"].reward_miner_chainable)) { this.currentVariant.set(_buildings_miner__WEBPACK_IMPORTED_MODULE_12__["enumMinerVariants"].chainable); } } else { this.currentMetaBuilding.set(null); } return; } // Try to extract the building const buildingCode = contents.components.StaticMapEntity.code; const extracted = Object(_building_codes__WEBPACK_IMPORTED_MODULE_14__["getBuildingDataFromCode"])(buildingCode); // Disable pipetting the hub if (extracted.metaInstance.getId() === _core_global_registries__WEBPACK_IMPORTED_MODULE_1__["gMetaBuildingRegistry"].findByClass(_buildings_hub__WEBPACK_IMPORTED_MODULE_15__["MetaHubBuilding"]).getId()) { this.currentMetaBuilding.set(null); return; } // If the building we are picking is the same as the one we have, clear the cursor. if ( this.currentMetaBuilding.get() && extracted.metaInstance.getId() === this.currentMetaBuilding.get().getId() && extracted.variant === this.currentVariant.get() ) { this.currentMetaBuilding.set(null); return; } this.currentMetaBuilding.set(extracted.metaInstance); this.currentVariant.set(extracted.variant); this.currentBaseRotation = contents.components.StaticMapEntity.rotation; } /** * Switches the side for the direction lock manually */ switchDirectionLockSide() { this.currentDirectionLockSide = 1 - this.currentDirectionLockSide; } /** * Checks if the direction lock key got released and if such, resets the placement * @param {any} args */ checkForDirectionLockSwitch({ keyCode }) { if ( keyCode === this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.lockBeltDirection).keyCode ) { this.abortDragging(); } } /** * Tries to place the current building at the given tile * @param {Vector} tile */ tryPlaceCurrentBuildingAt(tile) { if (this.root.camera.zoomLevel < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkOverviewMinZoom) { // Dont allow placing in overview mode return; } const metaBuilding = this.currentMetaBuilding.get(); const { rotation, rotationVariant } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile({ root: this.root, tile, rotation: this.currentBaseRotation, variant: this.currentVariant.get(), layer: metaBuilding.getLayer(), }); const entity = this.root.logic.tryPlaceBuilding({ origin: tile, rotation, rotationVariant, originalRotation: this.currentBaseRotation, building: this.currentMetaBuilding.get(), variant: this.currentVariant.get(), }); if (entity) { // Succesfully placed, find which entity we actually placed this.root.signals.entityManuallyPlaced.dispatch(entity); // Check if we should flip the orientation (used for tunnels) if ( metaBuilding.getFlipOrientationAfterPlacement() && !this.root.keyMapper.getBinding( _key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.placementDisableAutoOrientation ).pressed ) { this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; } // Check if we should stop placement if ( !metaBuilding.getStayInPlacementMode() && !this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.placeMultiple).pressed && !this.root.app.settings.getAllSettings().alwaysMultiplace ) { // Stop placement this.currentMetaBuilding.set(null); } return true; } else { return false; } } /** * Cycles through the variants */ cycleVariants() { const metaBuilding = this.currentMetaBuilding.get(); if (!metaBuilding) { this.currentVariant.set(_meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"]); } else { const availableVariants = metaBuilding.getAvailableVariants(this.root); const index = availableVariants.indexOf(this.currentVariant.get()); window.assert( index >= 0, "Current variant was invalid: " + this.currentVariant.get() + " out of " + availableVariants ); const newIndex = (index + 1) % availableVariants.length; const newVariant = availableVariants[newIndex]; this.setVariant(newVariant); } } /** * Sets the current variant to the given variant * @param {string} variant */ setVariant(variant) { const metaBuilding = this.currentMetaBuilding.get(); this.currentVariant.set(variant); this.preferredVariants[metaBuilding.getId()] = variant; } /** * Performs the direction locked placement between two points after * releasing the mouse */ executeDirectionLockedPlacement() { const metaBuilding = this.currentMetaBuilding.get(); if (!metaBuilding) { // No active building return; } // Get path to place const path = this.computeDirectionLockPath(); // Store if we placed anything let anythingPlaced = false; // Perform this in bulk to avoid recalculations this.root.logic.performBulkOperation(() => { for (let i = 0; i < path.length; ++i) { const { rotation, tile } = path[i]; this.currentBaseRotation = rotation; if (this.tryPlaceCurrentBuildingAt(tile)) { anythingPlaced = true; } } }); if (anythingPlaced) { this.root.soundProxy.playUi(metaBuilding.getPlacementSound()); } } /** * Finds the path which the current direction lock will use * @returns {Array<{ tile: Vector, rotation: number }>} */ computeDirectionLockPath() { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return []; } let result = []; // Figure which points the line visits const worldPos = this.root.camera.screenToWorld(mousePosition); let endTile = worldPos.toTileSpace(); let startTile = this.lastDragTile; // if the alt key is pressed, reverse belt planner direction by switching start and end tile if (this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.placeInverse).pressed) { let tmp = startTile; startTile = endTile; endTile = tmp; } // Place from start to corner const pathToCorner = this.currentDirectionLockCorner.sub(startTile); const deltaToCorner = pathToCorner.normalize().round(); const lengthToCorner = Math.round(pathToCorner.length()); let currentPos = startTile.copy(); let rotation = (Math.round(Math.degrees(deltaToCorner.angle()) / 90) * 90 + 360) % 360; if (lengthToCorner > 0) { for (let i = 0; i < lengthToCorner; ++i) { result.push({ tile: currentPos.copy(), rotation, }); currentPos.addInplace(deltaToCorner); } } // Place from corner to end const pathFromCorner = endTile.sub(this.currentDirectionLockCorner); const deltaFromCorner = pathFromCorner.normalize().round(); const lengthFromCorner = Math.round(pathFromCorner.length()); if (lengthFromCorner > 0) { rotation = (Math.round(Math.degrees(deltaFromCorner.angle()) / 90) * 90 + 360) % 360; for (let i = 0; i < lengthFromCorner + 1; ++i) { result.push({ tile: currentPos.copy(), rotation, }); currentPos.addInplace(deltaFromCorner); } } else { // Finish last one result.push({ tile: currentPos.copy(), rotation, }); } return result; } /** * Selects a given building * @param {MetaBuilding} metaBuilding */ startSelection(metaBuilding) { this.currentMetaBuilding.set(metaBuilding); } /** * Called when the selected buildings changed * @param {MetaBuilding} metaBuilding */ onSelectedMetaBuildingChanged(metaBuilding) { this.abortDragging(); this.root.hud.signals.selectedPlacementBuildingChanged.dispatch(metaBuilding); if (metaBuilding) { const variant = this.preferredVariants[metaBuilding.getId()] || _meta_building__WEBPACK_IMPORTED_MODULE_9__["defaultBuildingVariant"]; this.currentVariant.set(variant); this.fakeEntity = new _entity__WEBPACK_IMPORTED_MODULE_7__["Entity"](null); metaBuilding.setupEntityComponents(this.fakeEntity, null); this.fakeEntity.addComponent( new _components_static_map_entity__WEBPACK_IMPORTED_MODULE_6__["StaticMapEntityComponent"]({ origin: new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](0, 0), rotation: 0, tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(), code: Object(_building_codes__WEBPACK_IMPORTED_MODULE_14__["getCodeFromBuildingData"])(metaBuilding, variant, 0), }) ); metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get()); } else { this.fakeEntity = null; } // Since it depends on both, rerender twice this.signals.variantChanged.dispatch(); } /** * mouse down pre handler * @param {Vector} pos * @param {enumMouseButton} button */ onMouseDown(pos, button) { if (this.root.camera.getIsMapOverlayActive()) { // We do not allow dragging if the overlay is active return; } const metaBuilding = this.currentMetaBuilding.get(); // Placement if (button === _camera__WEBPACK_IMPORTED_MODULE_5__["enumMouseButton"].left && metaBuilding) { this.currentlyDragging = true; this.currentlyDeleting = false; this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); // Place initial building, but only if direction lock is not active if (!this.isDirectionLockActive) { if (this.tryPlaceCurrentBuildingAt(this.lastDragTile)) { this.root.soundProxy.playUi(metaBuilding.getPlacementSound()); } } return _core_signal__WEBPACK_IMPORTED_MODULE_2__["STOP_PROPAGATION"]; } // Deletion if (button === _camera__WEBPACK_IMPORTED_MODULE_5__["enumMouseButton"].right && !metaBuilding) { this.currentlyDragging = true; this.currentlyDeleting = true; this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); if (this.deleteBelowCursor()) { return _core_signal__WEBPACK_IMPORTED_MODULE_2__["STOP_PROPAGATION"]; } } // Cancel placement if (button === _camera__WEBPACK_IMPORTED_MODULE_5__["enumMouseButton"].right && metaBuilding) { this.currentMetaBuilding.set(null); } } /** * mouse move pre handler * @param {Vector} pos */ onMouseMove(pos) { if (this.root.camera.getIsMapOverlayActive()) { return; } // Check for direction lock if (this.isDirectionLockActive) { return; } const metaBuilding = this.currentMetaBuilding.get(); if ((metaBuilding || this.currentlyDeleting) && this.lastDragTile) { const oldPos = this.lastDragTile; let newPos = this.root.camera.screenToWorld(pos).toTileSpace(); // Check if camera is moving, since then we do nothing if (this.root.camera.desiredCenter) { this.lastDragTile = newPos; return; } // Check if anything changed if (!oldPos.equals(newPos)) { // Automatic Direction if ( metaBuilding && metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) && !this.root.keyMapper.getBinding( _key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.placementDisableAutoOrientation ).pressed ) { const delta = newPos.sub(oldPos); const angleDeg = Math.degrees(delta.angle()); this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360; // Holding alt inverts the placement if (this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placementModifiers.placeInverse).pressed) { this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; } } // bresenham let x0 = oldPos.x; let y0 = oldPos.y; let x1 = newPos.x; let y1 = newPos.y; var dx = Math.abs(x1 - x0); var dy = Math.abs(y1 - y0); var sx = x0 < x1 ? 1 : -1; var sy = y0 < y1 ? 1 : -1; var err = dx - dy; let anythingPlaced = false; let anythingDeleted = false; while (this.currentlyDeleting || this.currentMetaBuilding.get()) { if (this.currentlyDeleting) { // Deletion const contents = this.root.map.getLayerContentXY(x0, y0, this.root.currentLayer); if (contents && !contents.queuedForDestroy && !contents.destroyed) { if (this.root.logic.tryDeleteBuilding(contents)) { anythingDeleted = true; } } } else { // Placement if (this.tryPlaceCurrentBuildingAt(new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](x0, y0))) { anythingPlaced = true; } } if (x0 === x1 && y0 === y1) break; var e2 = 2 * err; if (e2 > -dy) { err -= dy; x0 += sx; } if (e2 < dx) { err += dx; y0 += sy; } } if (anythingPlaced) { this.root.soundProxy.playUi(metaBuilding.getPlacementSound()); } if (anythingDeleted) { this.root.soundProxy.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_11__["SOUNDS"].destroyBuilding); } } this.lastDragTile = newPos; return _core_signal__WEBPACK_IMPORTED_MODULE_2__["STOP_PROPAGATION"]; } } /** * Mouse up handler */ onMouseUp() { if (this.root.camera.getIsMapOverlayActive()) { return; } // Check for direction lock if (this.lastDragTile && this.currentlyDragging && this.isDirectionLockActive) { this.executeDirectionLockedPlacement(); } this.abortDragging(); } } /***/ }), /***/ "./src/js/game/hud/parts/buildings_toolbar.js": /*!****************************************************!*\ !*** ./src/js/game/hud/parts/buildings_toolbar.js ***! \****************************************************/ /*! exports provided: supportedBuildings, HUDBuildingsToolbar */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportedBuildings", function() { return supportedBuildings; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDBuildingsToolbar", function() { return HUDBuildingsToolbar; }); /* harmony import */ var _buildings_belt_base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../buildings/belt_base */ "./src/js/game/buildings/belt_base.js"); /* harmony import */ var _buildings_cutter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../buildings/cutter */ "./src/js/game/buildings/cutter.js"); /* harmony import */ var _buildings_miner__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../buildings/miner */ "./src/js/game/buildings/miner.js"); /* harmony import */ var _buildings_mixer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../buildings/mixer */ "./src/js/game/buildings/mixer.js"); /* harmony import */ var _buildings_painter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../buildings/painter */ "./src/js/game/buildings/painter.js"); /* harmony import */ var _buildings_rotater__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../buildings/rotater */ "./src/js/game/buildings/rotater.js"); /* harmony import */ var _buildings_splitter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../buildings/splitter */ "./src/js/game/buildings/splitter.js"); /* harmony import */ var _buildings_stacker__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../buildings/stacker */ "./src/js/game/buildings/stacker.js"); /* harmony import */ var _buildings_trash__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../buildings/trash */ "./src/js/game/buildings/trash.js"); /* harmony import */ var _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../buildings/underground_belt */ "./src/js/game/buildings/underground_belt.js"); /* harmony import */ var _base_toolbar__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./base_toolbar */ "./src/js/game/hud/parts/base_toolbar.js"); /* harmony import */ var _buildings_lever__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../buildings/lever */ "./src/js/game/buildings/lever.js"); /* harmony import */ var _buildings_filter__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../buildings/filter */ "./src/js/game/buildings/filter.js"); /* harmony import */ var _buildings_display__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../buildings/display */ "./src/js/game/buildings/display.js"); /* harmony import */ var _buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../buildings/toolbar_swapper */ "./src/js/game/buildings/toolbar_swapper.js"); const supportedBuildings = [ _buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_14__["MetaToolbarSwapperBuilding"], _buildings_belt_base__WEBPACK_IMPORTED_MODULE_0__["MetaBeltBaseBuilding"], _buildings_splitter__WEBPACK_IMPORTED_MODULE_6__["MetaSplitterBuilding"], _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_9__["MetaUndergroundBeltBuilding"], _buildings_miner__WEBPACK_IMPORTED_MODULE_2__["MetaMinerBuilding"], _buildings_cutter__WEBPACK_IMPORTED_MODULE_1__["MetaCutterBuilding"], _buildings_rotater__WEBPACK_IMPORTED_MODULE_5__["MetaRotaterBuilding"], _buildings_stacker__WEBPACK_IMPORTED_MODULE_7__["MetaStackerBuilding"], _buildings_mixer__WEBPACK_IMPORTED_MODULE_3__["MetaMixerBuilding"], _buildings_painter__WEBPACK_IMPORTED_MODULE_4__["MetaPainterBuilding"], _buildings_trash__WEBPACK_IMPORTED_MODULE_8__["MetaTrashBuilding"], _buildings_lever__WEBPACK_IMPORTED_MODULE_11__["MetaLeverBuilding"], _buildings_filter__WEBPACK_IMPORTED_MODULE_12__["MetaFilterBuilding"], _buildings_display__WEBPACK_IMPORTED_MODULE_13__["MetaDisplayBuilding"], ]; class HUDBuildingsToolbar extends _base_toolbar__WEBPACK_IMPORTED_MODULE_10__["HUDBaseToolbar"] { constructor(root) { super(root, { supportedBuildings, visibilityCondition: () => !this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "regular" && this.root.currentToolbar === 0, htmlElementId: "ingame_HUD_buildings_toolbar", }); } } /***/ }), /***/ "./src/js/game/hud/parts/color_blind_helper.js": /*!*****************************************************!*\ !*** ./src/js/game/hud/parts/color_blind_helper.js ***! \*****************************************************/ /*! exports provided: HUDColorBlindHelper */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDColorBlindHelper", function() { return HUDColorBlindHelper; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/tracked_state */ "./src/js/core/tracked_state.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../colors */ "./src/js/game/colors.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../theme */ "./src/js/game/theme.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); class HUDColorBlindHelper extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.belowTileIndicator = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_ColorBlindBelowTileHelper", []); } initialize() { this.trackedColorBelowTile = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_2__["TrackedState"](this.onColorBelowTileChanged, this); } /** * Called when the color below the current tile changed * @param {enumColors|null} color */ onColorBelowTileChanged(color) { this.belowTileIndicator.classList.toggle("visible", !!color); if (color) { this.belowTileIndicator.innerText = _translations__WEBPACK_IMPORTED_MODULE_8__["T"].ingame.colors[color]; } } /** * Computes the color below the current tile * @returns {enumColors} */ computeColorBelowTile() { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return null; } if (this.root.currentLayer !== "regular") { // Not in regular mode return null; } const worldPos = this.root.camera.screenToWorld(mousePosition); const tile = worldPos.toTileSpace(); const contents = this.root.map.getTileContent(tile, this.root.currentLayer); if (contents && !contents.components.Miner) { const beltComp = contents.components.Belt; // Check if the belt has a color item if (beltComp) { const item = beltComp.assignedPath.findItemAtTile(tile); if (item && item.getItemType() === "color") { return /** @type {ColorItem} */ (item).color; } } // Check if we are ejecting an item, if so use that color const ejectorComp = contents.components.ItemEjector; if (ejectorComp) { for (let i = 0; i < ejectorComp.slots.length; ++i) { const slot = ejectorComp.slots[i]; if (slot.item && slot.item.getItemType() === "color") { return /** @type {ColorItem} */ (slot.item).color; } } } } else { // We hovered a lower layer, show the color there const lowerLayer = this.root.map.getLowerLayerContentXY(tile.x, tile.y); if (lowerLayer && lowerLayer.getItemType() === "color") { return /** @type {ColorItem} */ (lowerLayer).color; } } return null; } update() { this.trackedColorBelowTile.set(this.computeColorBelowTile()); } /** * Draws the currently selected tile * @param {DrawParameters} parameters */ draw(parameters) { const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen return null; } const below = this.computeColorBelowTile(); if (below) { // We have something below our tile const worldPos = this.root.camera.screenToWorld(mousePosition); const tile = worldPos.toTileSpace().toWorldSpace(); parameters.context.strokeStyle = _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].map.colorBlindPickerTile; parameters.context.lineWidth = 1; parameters.context.beginPath(); parameters.context.rect(tile.x, tile.y, _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize); parameters.context.stroke(); } } } /***/ }), /***/ "./src/js/game/hud/parts/debug_changes.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/debug_changes.js ***! \************************************************/ /*! exports provided: HUDChangesDebugger */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDChangesDebugger", function() { return HUDChangesDebugger; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /** * @typedef {{ * label: string, * area: Rectangle, * hideAt: number, * fillColor: string * }} DebugChange */ class HUDChangesDebugger extends _base_hud_part__WEBPACK_IMPORTED_MODULE_3__["BaseHUDPart"] { createElements(parent) {} initialize() { /** @type {Array} */ this.changes = []; } /** * Renders a new change * @param {string} label Text to display * @param {Rectangle} area Affected area world space * @param {string} fillColor Color to display (Hex) * @param {number=} timeToDisplay How long to display the change */ renderChange(label, area, fillColor, timeToDisplay = 0.3) { this.changes.push({ label, area: area.clone(), fillColor, hideAt: this.root.time.realtimeNow() + timeToDisplay, }); } update() { const now = this.root.time.realtimeNow(); // Detect outdated changes for (let i = 0; i < this.changes.length; ++i) { const change = this.changes[i]; if (change.hideAt <= now) { this.changes.splice(i, 1); i -= 1; continue; } } } /** * * @param {DrawParameters} parameters */ draw(parameters) { for (let i = 0; i < this.changes.length; ++i) { const change = this.changes[i]; parameters.context.fillStyle = change.fillColor; parameters.context.globalAlpha = 0.2; parameters.context.fillRect( change.area.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, change.area.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, change.area.w * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, change.area.h * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize ); parameters.context.fillStyle = "#222"; parameters.context.globalAlpha = 1; parameters.context.font = "bold 8px GameFont"; parameters.context.fillText( change.label, change.area.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + 2, change.area.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + 12 ); } } } /***/ }), /***/ "./src/js/game/hud/parts/debug_info.js": /*!*********************************************!*\ !*** ./src/js/game/hud/parts/debug_info.js ***! \*********************************************/ /*! exports provided: HUDDebugInfo */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDDebugInfo", function() { return HUDDebugInfo; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/tracked_state */ "./src/js/core/tracked_state.js"); /** @enum {string} */ const enumDebugOverlayMode = { disabled: "disabled", regular: "regular", detailed: "detailed" }; /** * Specifies which mode follows after which mode * @enum {enumDebugOverlayMode} */ const enumDebugOverlayModeNext = { [enumDebugOverlayMode.disabled]: enumDebugOverlayMode.regular, [enumDebugOverlayMode.regular]: enumDebugOverlayMode.detailed, [enumDebugOverlayMode.detailed]: enumDebugOverlayMode.disabled, }; const UPDATE_INTERVAL_SECONDS = 0.25; class HUDDebugInfo extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_DebugInfo", []); const tickRateElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["tickRate"]); this.trackedTickRate = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](str => (tickRateElement.innerText = str)); const tickDurationElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["tickDuration"]); this.trackedTickDuration = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](str => (tickDurationElement.innerText = str)); const fpsElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["fps"]); this.trackedFPS = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](str => (fpsElement.innerText = str)); const mousePositionElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["mousePosition"]); this.trackedMousePosition = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](str => (mousePositionElement.innerHTML = str)); const cameraPositionElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["cameraPosition"]); this.trackedCameraPosition = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](str => (cameraPositionElement.innerHTML = str)); this.versionElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["version"], "version unknown"); } initialize() { this.lastTick = 0; this.trackedMode = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](this.onModeChanged, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_2__["DynamicDomAttach"](this.root, this.element); this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].ingame.toggleFPSInfo).add(() => this.cycleModes()); // Set initial mode this.trackedMode.set(enumDebugOverlayMode.disabled); } /** * Called when the mode changed * @param {enumDebugOverlayMode} mode */ onModeChanged(mode) { this.element.setAttribute("data-mode", mode); this.versionElement.innerText = `${"modZ 1.0.3"} @ ${"dev"} @ ${"4bbf0823"}`; } /** * Updates the labels */ updateLabels() { this.trackedTickRate.set("Tickrate: " + this.root.dynamicTickrate.currentTickRate); this.trackedFPS.set( "FPS: " + Math.round(this.root.dynamicTickrate.averageFps) + " (" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["round2Digits"])(1000 / this.root.dynamicTickrate.averageFps) + " ms)" ); this.trackedTickDuration.set( "Tick: " + Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["round3Digits"])(this.root.dynamicTickrate.averageTickDuration) + "ms" ); } /** * Updates the detailed information */ updateDetailedInformation() { const mousePos = this.root.app.mousePosition || new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](0, 0); const mouseTile = this.root.camera.screenToWorld(mousePos).toTileSpace(); const cameraTile = this.root.camera.center.toTileSpace(); this.trackedMousePosition.set(`Mouse: ${mouseTile.x} / ${mouseTile.y}`); this.trackedCameraPosition.set(`Camera: ${cameraTile.x} / ${cameraTile.y}`); } /** * Cycles through the different modes */ cycleModes() { this.trackedMode.set(enumDebugOverlayModeNext[this.trackedMode.get()]); } update() { const visible = this.trackedMode.get() !== enumDebugOverlayMode.disabled; this.domAttach.update(visible); if (!visible) { return; } // Periodically update the text const now = this.root.time.realtimeNow(); if (now - this.lastTick > UPDATE_INTERVAL_SECONDS) { this.lastTick = now; this.updateLabels(); } // Also update detailed information if required if (this.trackedMode.get() === enumDebugOverlayMode.detailed) { this.updateDetailedInformation(); } } } /***/ }), /***/ "./src/js/game/hud/parts/entity_debugger.js": /*!**************************************************!*\ !*** ./src/js/game/hud/parts/entity_debugger.js ***! \**************************************************/ /*! exports provided: HUDEntityDebugger */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDEntityDebugger", function() { return HUDEntityDebugger; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); class HUDEntityDebugger extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])( parent, "ingame_HUD_EntityDebugger", [], ` Tile below cursor:
Chunk below cursor:
` ); /** @type {HTMLElement} */ this.mousePosElem = this.element.querySelector(".mousePos"); /** @type {HTMLElement} */ this.chunkPosElem = this.element.querySelector(".chunkPos"); this.entityInfoElem = this.element.querySelector(".entityInfo"); } initialize() { this.root.camera.downPreHandler.add(this.onMouseDown, this); } update() { const mousePos = this.root.app.mousePosition; if (!mousePos) { return; } const worldPos = this.root.camera.screenToWorld(mousePos); const worldTile = worldPos.toTileSpace(); const chunk = worldTile.divideScalar(_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkSize).floor(); this.mousePosElem.innerText = worldTile.x + " / " + worldTile.y; this.chunkPosElem.innerText = chunk.x + " / " + chunk.y; const entity = this.root.map.getTileContent(worldTile, this.root.currentLayer); if (entity) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["removeAllChildren"])(this.entityInfoElem); let html = "Entity"; const flag = (name, val) => `${name} ${val}`; html += "
"; html += flag("registered", entity.registered); html += flag("uid", entity.uid); html += flag("destroyed", entity.destroyed); html += "
"; html += "
"; for (const componentId in entity.components) { const data = entity.components[componentId]; html += "
"; html += "" + componentId + ""; html += ""; html += "
"; } html += "
"; this.entityInfoElem.innerHTML = html; } } onMouseDown() {} } /***/ }), /***/ "./src/js/game/hud/parts/game_menu.js": /*!********************************************!*\ !*** ./src/js/game/hud/parts/game_menu.js ***! \********************************************/ /*! exports provided: HUDGameMenu */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDGameMenu", function() { return HUDGameMenu; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _notifications__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./notifications */ "./src/js/game/hud/parts/notifications.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); class HUDGameMenu extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_GameMenu"); const buttons = [ { id: "shop", label: "Upgrades", handler: () => this.root.hud.parts.shop.show(), keybinding: _key_action_mapper__WEBPACK_IMPORTED_MODULE_5__["KEYMAPPINGS"].ingame.menuOpenShop, badge: () => this.root.hubGoals.getAvailableUpgradeCount(), notification: /** @type {[string, enumNotificationType]} */ ([ _translations__WEBPACK_IMPORTED_MODULE_4__["T"].ingame.notifications.newUpgrade, _notifications__WEBPACK_IMPORTED_MODULE_3__["enumNotificationType"].upgrade, ]), visible: () => !this.root.app.settings.getAllSettings().offerHints || this.root.hubGoals.level >= 3, }, { id: "stats", label: "Stats", handler: () => this.root.hud.parts.statistics.show(), keybinding: _key_action_mapper__WEBPACK_IMPORTED_MODULE_5__["KEYMAPPINGS"].ingame.menuOpenStats, visible: () => !this.root.app.settings.getAllSettings().offerHints || this.root.hubGoals.level >= 3, }, ]; /** @type {Array<{ * badge: function, * button: HTMLElement, * badgeElement: HTMLElement, * lastRenderAmount: number, * condition?: function, * notification: [string, enumNotificationType] * }>} */ this.badgesToUpdate = []; /** @type {Array<{ * button: HTMLElement, * condition: function, * domAttach: DynamicDomAttach * }>} */ this.visibilityToUpdate = []; this.buttonsElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["buttonContainer"]); buttons.forEach(({ id, label, handler, keybinding, badge, notification, visible }) => { const button = document.createElement("button"); button.setAttribute("data-button-id", id); this.buttonsElement.appendChild(button); this.trackClicks(button, handler); if (keybinding) { const binding = this.root.keyMapper.getBinding(keybinding); binding.add(handler); binding.appendLabelToElement(button); } if (visible) { this.visibilityToUpdate.push({ button, condition: visible, domAttach: new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_6__["DynamicDomAttach"](this.root, button), }); } if (badge) { const badgeElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(button, null, ["badge"]); this.badgesToUpdate.push({ badge, lastRenderAmount: 0, button, badgeElement, notification, condition: visible, }); } }); const menuButtons = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["menuButtons"]); this.musicButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(menuButtons, null, ["button", "music"]); this.sfxButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(menuButtons, null, ["button", "sfx"]); this.saveButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(menuButtons, null, ["button", "save", "animEven"]); this.settingsButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(menuButtons, null, ["button", "settings"]); this.trackClicks(this.musicButton, this.toggleMusic); this.trackClicks(this.sfxButton, this.toggleSfx); this.trackClicks(this.saveButton, this.startSave); this.trackClicks(this.settingsButton, this.openSettings); this.musicButton.classList.toggle("muted", this.root.app.settings.getAllSettings().musicMuted); this.sfxButton.classList.toggle("muted", this.root.app.settings.getAllSettings().soundsMuted); } initialize() { this.root.signals.gameSaved.add(this.onGameSaved, this); } update() { let playSound = false; let notifications = new Set(); // Update visibility of buttons for (let i = 0; i < this.visibilityToUpdate.length; ++i) { const { button, condition, domAttach } = this.visibilityToUpdate[i]; domAttach.update(condition()); } // Check for notifications and badges for (let i = 0; i < this.badgesToUpdate.length; ++i) { const { badge, button, badgeElement, lastRenderAmount, notification, condition, } = this.badgesToUpdate[i]; if (condition && !condition()) { // Do not show notifications for invisible buttons continue; } // Check if the amount shown differs from the one shown last frame const amount = badge(); if (lastRenderAmount !== amount) { if (amount > 0) { badgeElement.innerText = amount; } // Check if the badge increased, if so play a notification if (amount > lastRenderAmount) { playSound = true; if (notification) { notifications.add(notification); } } // Rerender notifications this.badgesToUpdate[i].lastRenderAmount = amount; button.classList.toggle("hasBadge", amount > 0); } } if (playSound) { this.root.soundProxy.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_2__["SOUNDS"].badgeNotification); } notifications.forEach(([notification, type]) => { this.root.hud.signals.notification.dispatch(notification, type); }); } onGameSaved() { this.saveButton.classList.toggle("animEven"); this.saveButton.classList.toggle("animOdd"); } startSave() { this.root.gameState.doSave(); } openSettings() { this.root.hud.parts.settingsMenu.show(); } toggleMusic() { const newValue = !this.root.app.settings.getAllSettings().musicMuted; this.root.app.settings.updateSetting("musicMuted", newValue); this.musicButton.classList.toggle("muted", newValue); } toggleSfx() { const newValue = !this.root.app.settings.getAllSettings().soundsMuted; this.root.app.settings.updateSetting("soundsMuted", newValue); this.sfxButton.classList.toggle("muted", newValue); } } /***/ }), /***/ "./src/js/game/hud/parts/interactive_tutorial.js": /*!*******************************************************!*\ !*** ./src/js/game/hud/parts/interactive_tutorial.js ***! \*******************************************************/ /*! exports provided: tutorialsByLevel, HUDInteractiveTutorial */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tutorialsByLevel", function() { return tutorialsByLevel; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDInteractiveTutorial", function() { return HUDInteractiveTutorial; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../root */ "./src/js/game/root.js"); /* harmony import */ var _components_miner__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../components/miner */ "./src/js/game/components/miner.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/tracked_state */ "./src/js/core/tracked_state.js"); /* harmony import */ var _core_cachebust__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/cachebust */ "./src/js/core/cachebust.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../tutorial_goals */ "./src/js/game/tutorial_goals.js"); const tutorialsByLevel = [ // Level 1 [ // 1.1. place an extractor { id: "1_1_extractor", condition: /** @param {GameRoot} root */ root => { return root.entityMgr.getAllWithComponent(_components_miner__WEBPACK_IMPORTED_MODULE_3__["MinerComponent"]).length === 0; }, }, // 1.2. connect to hub { id: "1_2_conveyor", condition: /** @param {GameRoot} root */ root => { return root.hubGoals.getCurrentGoalDelivered() === 0; }, }, // 1.3 wait for completion { id: "1_3_expand", condition: () => true, }, ], ]; class HUDInteractiveTutorial extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])( parent, "ingame_HUD_InteractiveTutorial", ["animEven"], ` ${_translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.interactiveTutorial.title} ` ); this.elementDescription = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["desc"]); this.elementGif = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["helperGif"]); } initialize() { this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_4__["DynamicDomAttach"](this.root, this.element); this.currentHintId = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_5__["TrackedState"](this.onHintChanged, this); for (let i = 0; i < _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"].length; ++i) { if (_tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"][i].tutorial) { tutorialsByLevel[i + 1] = _tutorial_goals__WEBPACK_IMPORTED_MODULE_8__["tutorialGoals"][i].tutorial; } } } onHintChanged(hintId) { this.elementDescription.innerHTML = _translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.interactiveTutorial.hints[hintId]; this.elementGif.style.backgroundImage = "url('" + Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_6__["cachebust"])("res/ui/interactive_tutorial.noinline/" + hintId + ".gif") + "')"; this.element.classList.toggle("animEven"); this.element.classList.toggle("animOdd"); } update() { // Compute current hint const thisLevelHints = tutorialsByLevel[this.root.hubGoals.level - 1]; let targetHintId = null; if (thisLevelHints) { for (let i = 0; i < thisLevelHints.length; ++i) { const hint = thisLevelHints[i]; if (hint.condition(this.root)) { targetHintId = hint.id; break; } } } this.currentHintId.set(targetHintId); this.domAttach.update(!!targetHintId); } } /***/ }), /***/ "./src/js/game/hud/parts/keybinding_overlay.js": /*!*****************************************************!*\ !*** ./src/js/game/hud/parts/keybinding_overlay.js ***! \*****************************************************/ /*! exports provided: HUDKeybindingOverlay */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDKeybindingOverlay", function() { return HUDKeybindingOverlay; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); const DIVIDER_TOKEN = "/"; const ADDER_TOKEN = "+"; /** * @typedef {{ keyCode: number }} KeyCode */ /** * @typedef {{ * condition: () => boolean, * keys: Array, * label: string, * cachedElement?: HTMLElement, * cachedVisibility?: boolean * }} KeyBinding */ class HUDKeybindingOverlay extends _base_hud_part__WEBPACK_IMPORTED_MODULE_3__["BaseHUDPart"] { initialize() {} /** * HELPER / Returns if there is a building selected for placement * @returns {boolean} */ get buildingPlacementActive() { const placer = this.root.hud.parts.buildingPlacer; return !this.mapOverviewActive && placer && !!placer.currentMetaBuilding.get(); } /** * HELPER / Returns if there is a building selected for placement and * it supports the belt planner * @returns {boolean} */ get buildingPlacementSupportsBeltPlanner() { const placer = this.root.hud.parts.buildingPlacer; return ( !this.mapOverviewActive && placer && placer.currentMetaBuilding.get() && placer.currentMetaBuilding.get().getHasDirectionLockAvailable() ); } /** * HELPER / Returns if there is a building selected for placement and * it has multiplace enabled by default * @returns {boolean} */ get buildingPlacementStaysInPlacement() { const placer = this.root.hud.parts.buildingPlacer; return ( !this.mapOverviewActive && placer && placer.currentMetaBuilding.get() && placer.currentMetaBuilding.get().getStayInPlacementMode() ); } /** * HELPER / Returns if there is a blueprint selected for placement * @returns {boolean} */ get blueprintPlacementActive() { const placer = this.root.hud.parts.blueprintPlacer; return placer && !!placer.currentBlueprint.get(); } /** * HELPER / Returns if the belt planner is currently active * @returns {boolean} */ get beltPlannerActive() { const placer = this.root.hud.parts.buildingPlacer; return !this.mapOverviewActive && placer && placer.isDirectionLockActive; } /** * HELPER / Returns if there is a last blueprint available * @returns {boolean} */ get lastBlueprintAvailable() { const placer = this.root.hud.parts.blueprintPlacer; return placer && !!placer.lastBlueprintUsed; } /** * HELPER / Returns if there is anything selected on the map * @returns {boolean} */ get anythingSelectedOnMap() { const selector = this.root.hud.parts.massSelector; return selector && selector.selectedUids.size > 0; } /** * HELPER / Returns if there is a building or blueprint selected for placement * @returns {boolean} */ get anyPlacementActive() { return this.buildingPlacementActive || this.blueprintPlacementActive; } /** * HELPER / Returns if the map overview is active * @returns {boolean} */ get mapOverviewActive() { return this.root.camera.getIsMapOverlayActive(); } /** * Initializes the element * @param {HTMLElement} parent */ createElements(parent) { const mapper = this.root.keyMapper; const k = _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYMAPPINGS"]; /** @type {Array} */ this.keybindings = [ { // Move map - Including mouse label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.moveMap, keys: [ _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_LMB"], DIVIDER_TOKEN, k.navigation.mapMoveUp, k.navigation.mapMoveLeft, k.navigation.mapMoveDown, k.navigation.mapMoveRight, ], condition: () => !this.anyPlacementActive, }, { // Move map - No mouse label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.moveMap, keys: [ k.navigation.mapMoveUp, k.navigation.mapMoveLeft, k.navigation.mapMoveDown, k.navigation.mapMoveRight, ], condition: () => this.anyPlacementActive, }, { // [OVERVIEW] Create marker with right click label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.createMarker, keys: [_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_RMB"]], condition: () => this.mapOverviewActive && !this.blueprintPlacementActive, }, { // Pipette label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.pipette, keys: [k.placement.pipette], condition: () => !this.mapOverviewActive && !this.blueprintPlacementActive, }, { // Cancel placement label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.stopPlacement, keys: [_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_RMB"]], condition: () => this.anyPlacementActive, }, { // Delete with right click label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.delete, keys: [_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_RMB"]], condition: () => !this.anyPlacementActive && !this.mapOverviewActive && !this.anythingSelectedOnMap, }, { // Area select label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.selectBuildings, keys: [k.massSelect.massSelectStart, ADDER_TOKEN, _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_LMB"]], condition: () => !this.anyPlacementActive && !this.anythingSelectedOnMap, }, { // Place building label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.placeBuilding, keys: [_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_LMB"]], condition: () => this.anyPlacementActive, }, { // Rotate label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.rotateBuilding, keys: [k.placement.rotateWhilePlacing], condition: () => this.anyPlacementActive && !this.beltPlannerActive, }, { // [BELT PLANNER] Flip Side label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.plannerSwitchSide, keys: [k.placement.switchDirectionLockSide], condition: () => this.beltPlannerActive, }, { // Place last blueprint label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.pasteLastBlueprint, keys: [k.massSelect.pasteLastBlueprint], condition: () => !this.blueprintPlacementActive && this.lastBlueprintAvailable, }, { // Belt planner label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.lockBeltDirection, keys: [k.placementModifiers.lockBeltDirection], condition: () => this.buildingPlacementSupportsBeltPlanner && !this.beltPlannerActive, }, { // [SELECTION] Destroy label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.delete, keys: [k.massSelect.confirmMassDelete], condition: () => this.anythingSelectedOnMap, }, { // [SELECTION] Cancel label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.clearSelection, keys: [k.general.back], condition: () => this.anythingSelectedOnMap, }, { // [SELECTION] Cut label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.cutSelection, keys: [k.massSelect.massSelectCut], condition: () => this.anythingSelectedOnMap, }, { // [SELECTION] Copy label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.copySelection, keys: [k.massSelect.massSelectCopy], condition: () => this.anythingSelectedOnMap, }, { // Switch layers label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.switchLayers, keys: [k.ingame.switchLayers], condition: () => true, }, ]; if (!this.root.app.settings.getAllSettings().alwaysMultiplace) { this.keybindings.push({ // Multiplace label: _translations__WEBPACK_IMPORTED_MODULE_1__["T"].ingame.keybindingsOverlay.placeMultiple, keys: [k.placementModifiers.placeMultiple], condition: () => this.anyPlacementActive && !this.buildingPlacementStaysInPlacement, }); } this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["makeDiv"])(parent, "ingame_HUD_KeybindingOverlay", []); for (let i = 0; i < this.keybindings.length; ++i) { let html = ""; const handle = this.keybindings[i]; for (let k = 0; k < handle.keys.length; ++k) { const key = handle.keys[k]; switch (key) { case _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_LMB"]: html += ``; break; case _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_RMB"]: html += ``; break; case _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_MMB"]: html += ``; break; case DIVIDER_TOKEN: html += ``; break; case ADDER_TOKEN: html += `+`; break; default: html += `${Object(_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["getStringForKeyCode"])( mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode )}`; } } html += ``; handle.cachedElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["makeDiv"])(this.element, null, ["binding"], html); handle.cachedVisibility = false; } } update() { for (let i = 0; i < this.keybindings.length; ++i) { const handle = this.keybindings[i]; const visibility = handle.condition(); if (visibility !== handle.cachedVisibility) { handle.cachedVisibility = visibility; handle.cachedElement.classList.toggle("visible", visibility); } } } } /***/ }), /***/ "./src/js/game/hud/parts/layer_preview.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/layer_preview.js ***! \************************************************/ /*! exports provided: HUDLayerPreview */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDLayerPreview", function() { return HUDLayerPreview; }); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../theme */ "./src/js/game/theme.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /** * Helper class which allows peaking through to the wires layer */ class HUDLayerPreview extends _base_hud_part__WEBPACK_IMPORTED_MODULE_6__["BaseHUDPart"] { initialize() { this.initializeCanvas(); this.root.signals.aboutToDestruct.add(() => Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["freeCanvas"])(this.canvas)); this.root.signals.resized.add(this.initializeCanvas, this); this.previewOverlay = _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/wires_preview.png"); } /** * (re) initializes the canvas */ initializeCanvas() { if (this.canvas) { Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["freeCanvas"])(this.canvas); delete this.canvas; delete this.context; } // Compute how big the preview should be this.previewSize = Math.round( Math.min(1024, Math.min(this.root.gameWidth, this.root.gameHeight) * 0.8) ); const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(this.previewSize, this.previewSize, { smooth: true, label: "layerPeeker", reusable: true, }); context.clearRect(0, 0, this.previewSize, this.previewSize); this.canvas = canvas; this.context = context; } /** * Prepares the canvas to render at the given worldPos and the given camera scale * * @param {Vector} worldPos * @param {number} scale 1 / zoomLevel */ prepareCanvasForPreview(worldPos, scale) { this.context.clearRect(0, 0, this.previewSize, this.previewSize); this.context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_5__["THEME"].map.wires.previewColor; this.context.fillRect(0, 0, this.previewSize, this.previewSize); const dimensions = scale * this.previewSize; const startWorldX = worldPos.x - dimensions / 2; const startWorldY = worldPos.y - dimensions / 2; const startTileX = Math.floor(startWorldX / _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize); const startTileY = Math.floor(startWorldY / _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize); const tileDimensions = Math.ceil(dimensions / _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize); this.context.save(); this.context.scale(1 / scale, 1 / scale); this.context.translate( startTileX * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize - startWorldX, startTileY * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize - startWorldY ); for (let dx = 0; dx < tileDimensions; ++dx) { for (let dy = 0; dy < tileDimensions; ++dy) { const tileX = dx + startTileX; const tileY = dy + startTileY; const content = this.root.map.getLayerContentXY(tileX, tileY, "wires"); if (content) { _map_chunk_view__WEBPACK_IMPORTED_MODULE_4__["MapChunkView"].drawSingleWiresOverviewTile({ context: this.context, x: dx * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, y: dy * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, entity: content, tileSizePixels: _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize, }); } } } this.context.restore(); this.context.globalCompositeOperation = "destination-in"; this.previewOverlay.draw(this.context, 0, 0, this.previewSize, this.previewSize); this.context.globalCompositeOperation = "source-over"; return this.canvas; } /** * Renders the preview at the given position * @param {import("../../../core/draw_utils").DrawParameters} parameters * @param {Vector} worldPos * @param {number} scale 1 / zoomLevel */ renderPreview(parameters, worldPos, scale) { if (this.root.currentLayer !== "regular") { // Only supporting wires right now return; } const canvas = this.prepareCanvasForPreview(worldPos, scale); parameters.context.globalAlpha = 0.3; parameters.context.drawImage( canvas, worldPos.x - (scale * this.previewSize) / 2, worldPos.y - (scale * this.previewSize) / 2, scale * this.previewSize, scale * this.previewSize ); parameters.context.globalAlpha = 1; } } /***/ }), /***/ "./src/js/game/hud/parts/lever_toggle.js": /*!***********************************************!*\ !*** ./src/js/game/hud/parts/lever_toggle.js ***! \***********************************************/ /*! exports provided: HUDLeverToggle */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDLeverToggle", function() { return HUDLeverToggle; }); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../camera */ "./src/js/game/camera.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); class HUDLeverToggle extends _base_hud_part__WEBPACK_IMPORTED_MODULE_3__["BaseHUDPart"] { initialize() { this.root.camera.downPreHandler.add(this.downPreHandler, this); } /** * @param {Vector} pos * @param {enumMouseButton} button */ downPreHandler(pos, button) { const tile = this.root.camera.screenToWorld(pos).toTileSpace(); const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular"); if (contents) { const leverComp = contents.components.Lever; if (leverComp) { if (button === _camera__WEBPACK_IMPORTED_MODULE_2__["enumMouseButton"].left) { leverComp.toggled = !leverComp.toggled; return _core_signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]; } else if (button === _camera__WEBPACK_IMPORTED_MODULE_2__["enumMouseButton"].right) { this.root.logic.tryDeleteBuilding(contents); return _core_signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]; } } } } } /***/ }), /***/ "./src/js/game/hud/parts/mass_selector.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/mass_selector.js ***! \************************************************/ /*! exports provided: HUDMassSelector */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDMassSelector", function() { return HUDMassSelector; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../entity */ "./src/js/game/entity.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../camera */ "./src/js/game/camera.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../theme */ "./src/js/game/theme.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _blueprint__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../blueprint */ "./src/js/game/blueprint.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_9__["createLogger"])("hud/mass_selector"); class HUDMassSelector extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) {} initialize() { this.currentSelectionStartWorld = null; this.currentSelectionEnd = null; this.selectedUids = new Set(); this.root.signals.entityQueuedForDestroy.add(this.onEntityDestroyed, this); this.root.hud.signals.pasteBlueprintRequested.add(this.clearSelection, this); this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); this.root.camera.upPostHandler.add(this.onMouseUp, this); this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].general.back).add(this.onBack, this); this.root.keyMapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].massSelect.confirmMassDelete) .add(this.confirmDelete, this); this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].massSelect.massSelectCut).add(this.confirmCut, this); this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].massSelect.massSelectCopy).add(this.startCopy, this); this.root.hud.signals.selectedPlacementBuildingChanged.add(this.clearSelection, this); this.root.signals.editModeChanged.add(this.clearSelection, this); } /** * Handles the destroy callback and makes sure we clean our list * @param {Entity} entity */ onEntityDestroyed(entity) { this.selectedUids.delete(entity.uid); } /** * */ onBack() { // Clear entities on escape if (this.selectedUids.size > 0) { this.selectedUids = new Set(); return _core_signal__WEBPACK_IMPORTED_MODULE_2__["STOP_PROPAGATION"]; } } /** * Clears the entire selection */ clearSelection() { this.selectedUids = new Set(); } confirmDelete() { if ( !this.root.app.settings.getAllSettings().disableCutDeleteWarnings && this.selectedUids.size > 100 ) { const { ok } = this.root.hud.parts.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.massDeleteConfirm.title, _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.massDeleteConfirm.desc.replace( "", "" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_7__["formatBigNumberFull"])(this.selectedUids.size) ), ["cancel:good:escape", "ok:bad:enter"] ); ok.add(() => this.doDelete()); } else { this.doDelete(); } } doDelete() { const entityUids = Array.from(this.selectedUids); for (let i = 0; i < entityUids.length; ++i) { const uid = entityUids[i]; const entity = this.root.entityMgr.findByUid(uid); if (!this.root.logic.tryDeleteBuilding(entity)) { logger.error("Error in mass delete, could not remove building"); this.selectedUids.delete(uid); } } } startCopy() { if (this.selectedUids.size > 0) { if (!this.root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_14__["enumHubGoalRewards"].reward_blueprints)) { this.root.hud.parts.dialogs.showInfo( _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.blueprintsNotUnlocked.title, _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.blueprintsNotUnlocked.desc ); return; } this.root.hud.signals.buildingsSelectedForCopy.dispatch(Array.from(this.selectedUids)); this.selectedUids = new Set(); this.root.soundProxy.playUiClick(); } else { this.root.soundProxy.playUiError(); } } confirmCut() { if (!this.root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_14__["enumHubGoalRewards"].reward_blueprints)) { this.root.hud.parts.dialogs.showInfo( _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.blueprintsNotUnlocked.title, _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.blueprintsNotUnlocked.desc ); } else if ( !this.root.app.settings.getAllSettings().disableCutDeleteWarnings && this.selectedUids.size > 100 ) { const { ok } = this.root.hud.parts.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.massCutConfirm.title, _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.massCutConfirm.desc.replace( "", "" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_7__["formatBigNumberFull"])(this.selectedUids.size) ), ["cancel:good:escape", "ok:bad:enter"] ); ok.add(() => this.doCut()); } else { this.doCut(); } } doCut() { if (this.selectedUids.size > 0) { const entityUids = Array.from(this.selectedUids); const cutAction = () => { // copy code relies on entities still existing, so must copy before deleting. this.root.hud.signals.buildingsSelectedForCopy.dispatch(entityUids); for (let i = 0; i < entityUids.length; ++i) { const uid = entityUids[i]; const entity = this.root.entityMgr.findByUid(uid); if (!this.root.logic.tryDeleteBuilding(entity)) { logger.error("Error in mass cut, could not remove building"); this.selectedUids.delete(uid); } } }; const blueprint = _blueprint__WEBPACK_IMPORTED_MODULE_15__["Blueprint"].fromUids(this.root, entityUids); if (blueprint.canAfford(this.root)) { cutAction(); } else { const { cancel, ok } = this.root.hud.parts.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.massCutInsufficientConfirm.title, _translations__WEBPACK_IMPORTED_MODULE_11__["T"].dialogs.massCutInsufficientConfirm.desc, ["cancel:good:escape", "ok:bad:enter"] ); ok.add(cutAction); } this.root.soundProxy.playUiClick(); } else { this.root.soundProxy.playUiError(); } } /** * mouse down pre handler * @param {Vector} pos * @param {enumMouseButton} mouseButton */ onMouseDown(pos, mouseButton) { if (!this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].massSelect.massSelectStart).pressed) { return; } if (mouseButton !== _camera__WEBPACK_IMPORTED_MODULE_10__["enumMouseButton"].left) { return; } if (!this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].massSelect.massSelectSelectMultiple).pressed) { // Start new selection this.selectedUids = new Set(); } this.currentSelectionStartWorld = this.root.camera.screenToWorld(pos.copy()); this.currentSelectionEnd = pos.copy(); return _core_signal__WEBPACK_IMPORTED_MODULE_2__["STOP_PROPAGATION"]; } /** * mouse move pre handler * @param {Vector} pos */ onMouseMove(pos) { if (this.currentSelectionStartWorld) { this.currentSelectionEnd = pos.copy(); } } onMouseUp() { if (this.currentSelectionStartWorld) { const worldStart = this.currentSelectionStartWorld; const worldEnd = this.root.camera.screenToWorld(this.currentSelectionEnd); const tileStart = worldStart.toTileSpace(); const tileEnd = worldEnd.toTileSpace(); const realTileStart = tileStart.min(tileEnd); const realTileEnd = tileStart.max(tileEnd); for (let x = realTileStart.x; x <= realTileEnd.x; ++x) { for (let y = realTileStart.y; y <= realTileEnd.y; ++y) { const contents = this.root.map.getLayerContentXY(x, y, this.root.currentLayer); if (contents && this.root.logic.canDeleteBuilding(contents)) { this.selectedUids.add(contents.uid); } } } this.currentSelectionStartWorld = null; this.currentSelectionEnd = null; } } /** * * @param {DrawParameters} parameters */ draw(parameters) { const boundsBorder = 2; if (this.currentSelectionStartWorld) { const worldStart = this.currentSelectionStartWorld; const worldEnd = this.root.camera.screenToWorld(this.currentSelectionEnd); const realWorldStart = worldStart.min(worldEnd); const realWorldEnd = worldStart.max(worldEnd); const tileStart = worldStart.toTileSpace(); const tileEnd = worldEnd.toTileSpace(); const realTileStart = tileStart.min(tileEnd); const realTileEnd = tileStart.max(tileEnd); parameters.context.lineWidth = 1; parameters.context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_13__["THEME"].map.selectionBackground; parameters.context.strokeStyle = _theme__WEBPACK_IMPORTED_MODULE_13__["THEME"].map.selectionOutline; parameters.context.beginPath(); parameters.context.rect( realWorldStart.x, realWorldStart.y, realWorldEnd.x - realWorldStart.x, realWorldEnd.y - realWorldStart.y ); parameters.context.fill(); parameters.context.stroke(); parameters.context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_13__["THEME"].map.selectionOverlay; for (let x = realTileStart.x; x <= realTileEnd.x; ++x) { for (let y = realTileStart.y; y <= realTileEnd.y; ++y) { const contents = this.root.map.getLayerContentXY(x, y, this.root.currentLayer); if (contents && this.root.logic.canDeleteBuilding(contents)) { const staticComp = contents.components.StaticMapEntity; const bounds = staticComp.getTileSpaceBounds(); parameters.context.beginRoundedRect( bounds.x * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize + boundsBorder, bounds.y * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize + boundsBorder, bounds.w * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize - 2 * boundsBorder, bounds.h * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize - 2 * boundsBorder, 2 ); parameters.context.fill(); } } } } parameters.context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_13__["THEME"].map.selectionOverlay; this.selectedUids.forEach(uid => { const entity = this.root.entityMgr.findByUid(uid); const staticComp = entity.components.StaticMapEntity; const bounds = staticComp.getTileSpaceBounds(); parameters.context.beginRoundedRect( bounds.x * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize + boundsBorder, bounds.y * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize + boundsBorder, bounds.w * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize - 2 * boundsBorder, bounds.h * _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].tileSize - 2 * boundsBorder, 2 ); parameters.context.fill(); }); } } /***/ }), /***/ "./src/js/game/hud/parts/modal_dialogs.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/modal_dialogs.js ***! \************************************************/ /*! exports provided: HUDModalDialogs */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDModalDialogs", function() { return HUDModalDialogs; }); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/modal_dialog_elements */ "./src/js/core/modal_dialog_elements.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); class HUDModalDialogs extends _base_hud_part__WEBPACK_IMPORTED_MODULE_2__["BaseHUDPart"] { constructor(root, app) { // Important: Root is not always available here! Its also used in the main menu super(root); /** @type {Application} */ this.app = root ? root.app : app; this.dialogParent = null; this.dialogStack = []; } // For use inside of the game, implementation of base hud part initialize() { this.dialogParent = document.getElementById("ingame_HUD_ModalDialogs"); this.domWatcher = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_1__["DynamicDomAttach"](this.root, this.dialogParent); } shouldPauseRendering() { return this.dialogStack.length > 0; } shouldPauseGame() { return this.shouldPauseRendering(); } createElements(parent) { return Object(_core_utils__WEBPACK_IMPORTED_MODULE_4__["makeDiv"])(parent, "ingame_HUD_ModalDialogs"); } // For use outside of the game initializeToElement(element) { window.assert(element, "No element for dialogs given"); this.dialogParent = element; } // Methods /** * @param {string} title * @param {string} text * @param {Array} buttons */ showInfo(title, text, buttons = ["ok:good"]) { const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_3__["Dialog"]({ app: this.app, title: title, contentHTML: text, buttons: buttons, type: "info", }); this.internalShowDialog(dialog); if (this.app) { this.app.sound.playUiSound(_platform_sound__WEBPACK_IMPORTED_MODULE_0__["SOUNDS"].dialogOk); } return dialog.buttonSignals; } /** * @param {string} title * @param {string} text * @param {Array} buttons */ showWarning(title, text, buttons = ["ok:good"]) { const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_3__["Dialog"]({ app: this.app, title: title, contentHTML: text, buttons: buttons, type: "warning", }); this.internalShowDialog(dialog); if (this.app) { this.app.sound.playUiSound(_platform_sound__WEBPACK_IMPORTED_MODULE_0__["SOUNDS"].dialogError); } return dialog.buttonSignals; } /** * @param {string} feature * @param {string} textPrefab */ showFeatureRestrictionInfo(feature, textPrefab = _translations__WEBPACK_IMPORTED_MODULE_5__["T"].dialogs.featureRestriction.desc) { const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_3__["Dialog"]({ app: this.app, title: _translations__WEBPACK_IMPORTED_MODULE_5__["T"].dialogs.featureRestriction.title, contentHTML: textPrefab.replace("", feature), buttons: ["cancel:bad", "getStandalone:good"], type: "warning", }); this.internalShowDialog(dialog); if (this.app) { this.app.sound.playUiSound(_platform_sound__WEBPACK_IMPORTED_MODULE_0__["SOUNDS"].dialogOk); } this.app.analytics.trackUiClick("demo_dialog_show"); dialog.buttonSignals.cancel.add(() => { this.app.analytics.trackUiClick("demo_dialog_cancel"); }); dialog.buttonSignals.getStandalone.add(() => { this.app.analytics.trackUiClick("demo_dialog_click"); window.open(_core_config__WEBPACK_IMPORTED_MODULE_6__["THIRDPARTY_URLS"].standaloneStorePage); }); return dialog.buttonSignals; } showOptionChooser(title, options) { const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_3__["DialogOptionChooser"]({ app: this.app, title, options, }); this.internalShowDialog(dialog); return dialog.buttonSignals; } // Returns method to be called when laoding finishd showLoadingDialog() { const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_3__["DialogLoading"](this.app); this.internalShowDialog(dialog); return this.closeDialog.bind(this, dialog); } internalShowDialog(dialog) { const elem = dialog.createElement(); dialog.setIndex(this.dialogStack.length); // Hide last dialog in queue if (this.dialogStack.length > 0) { this.dialogStack[this.dialogStack.length - 1].hide(); } this.dialogStack.push(dialog); // Append dialog dialog.show(); dialog.closeRequested.add(this.closeDialog.bind(this, dialog)); // Append to HTML this.dialogParent.appendChild(elem); document.body.classList.toggle("modalDialogActive", this.dialogStack.length > 0); // IMPORTANT: Attach element directly, otherwise double submit is possible this.update(); } update() { if (this.domWatcher) { this.domWatcher.update(this.dialogStack.length > 0); } } closeDialog(dialog) { dialog.destroy(); let index = -1; for (let i = 0; i < this.dialogStack.length; ++i) { if (this.dialogStack[i] === dialog) { index = i; break; } } window.assert(index >= 0, "Dialog not in dialog stack"); this.dialogStack.splice(index, 1); if (this.dialogStack.length > 0) { // Show the dialog which was previously open this.dialogStack[this.dialogStack.length - 1].show(); } document.body.classList.toggle("modalDialogActive", this.dialogStack.length > 0); } close() { for (let i = 0; i < this.dialogStack.length; ++i) { const dialog = this.dialogStack[i]; dialog.destroy(); } this.dialogStack = []; } cleanup() { super.cleanup(); for (let i = 0; i < this.dialogStack.length; ++i) { this.dialogStack[i].destroy(); } this.dialogStack = []; this.dialogParent = null; } } /***/ }), /***/ "./src/js/game/hud/parts/notifications.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/notifications.js ***! \************************************************/ /*! exports provided: enumNotificationType, HUDNotifications */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumNotificationType", function() { return enumNotificationType; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDNotifications", function() { return HUDNotifications; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /** @enum {string} */ const enumNotificationType = { saved: "saved", upgrade: "upgrade", success: "success", }; const notificationDuration = 3; class HUDNotifications extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_Notifications", [], ``); } initialize() { this.root.hud.signals.notification.add(this.onNotification, this); /** @type {Array<{ element: HTMLElement, expireAt: number}>} */ this.notificationElements = []; // Automatic notifications this.root.signals.gameSaved.add(() => this.onNotification(_translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.notifications.gameSaved, enumNotificationType.saved) ); } /** * @param {string} message * @param {enumNotificationType} type */ onNotification(message, type) { const element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["notification", "type-" + type], message); element.setAttribute("data-icon", "icons/notification_" + type + ".png"); this.notificationElements.push({ element, expireAt: this.root.time.realtimeNow() + notificationDuration, }); } update() { const now = this.root.time.realtimeNow(); for (let i = 0; i < this.notificationElements.length; ++i) { const handle = this.notificationElements[i]; if (handle.expireAt <= now) { handle.element.remove(); this.notificationElements.splice(i, 1); } } } } /***/ }), /***/ "./src/js/game/hud/parts/pinned_shapes.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/pinned_shapes.js ***! \************************************************/ /*! exports provided: HUDPinnedShapes */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDPinnedShapes", function() { return HUDPinnedShapes; }); /* harmony import */ var _core_click_detector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /** * Manages the pinned shapes on the left side of the screen */ class HUDPinnedShapes extends _base_hud_part__WEBPACK_IMPORTED_MODULE_3__["BaseHUDPart"] { constructor(root) { super(root); /** * Store a list of pinned shapes * @type {Array} */ this.pinnedShapes = []; /** * Store handles to the currently rendered elements, so we can update them more * convenient. Also allows for cleaning up handles. * @type {Array<{ * key: string, * amountLabel: HTMLElement, * lastRenderedValue: string, * element: HTMLElement, * detector?: ClickDetector, * infoDetector?: ClickDetector * }>} */ this.handles = []; } createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_PinnedShapes", []); } /** * Serializes the pinned shapes */ serialize() { return { shapes: this.pinnedShapes, }; } /** * Deserializes the pinned shapes * @param {{ shapes: Array}} data */ deserialize(data) { if (!data || !data.shapes || !Array.isArray(data.shapes)) { return "Invalid pinned shapes data"; } this.pinnedShapes = data.shapes; } /** * Initializes the hud component */ initialize() { // Connect to any relevant signals this.root.signals.storyGoalCompleted.add(this.rerenderFull, this); this.root.signals.upgradePurchased.add(this.updateShapesAfterUpgrade, this); this.root.signals.postLoadHook.add(this.rerenderFull, this); this.root.hud.signals.shapePinRequested.add(this.pinNewShape, this); this.root.hud.signals.shapeUnpinRequested.add(this.unpinShape, this); // Perform initial render this.updateShapesAfterUpgrade(); } /** * Updates all shapes after an upgrade has been purchased and removes the unused ones */ updateShapesAfterUpgrade() { for (let i = 0; i < this.pinnedShapes.length; ++i) { const key = this.pinnedShapes[i]; if (key === _upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"]) { // Ignore blueprint shapes continue; } let goal = this.findGoalValueForShape(key); if (!goal) { // Seems no longer relevant this.pinnedShapes.splice(i, 1); i -= 1; } } this.rerenderFull(); } /** * Finds the current goal for the given key. If the key is the story goal, returns * the story goal. If its the blueprint shape, no goal is returned. Otherwise * it's searched for upgrades. * @param {string} key */ findGoalValueForShape(key) { if (key === this.root.hubGoals.currentGoal.definition.getHash()) { return this.root.hubGoals.currentGoal.required; } if (key === _upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"]) { return null; } // Check if this shape is required for any upgrade for (const upgradeId in _upgrades__WEBPACK_IMPORTED_MODULE_4__["UPGRADES"]) { const { tiers } = _upgrades__WEBPACK_IMPORTED_MODULE_4__["UPGRADES"][upgradeId]; const currentTier = this.root.hubGoals.getUpgradeLevel(upgradeId); const tierHandle = tiers[currentTier]; if (!tierHandle) { // Max level continue; } for (let i = 0; i < tierHandle.required.length; ++i) { const { shape, amount } = tierHandle.required[i]; if (shape === key) { return amount; } } } return null; } /** * Returns whether a given shape is currently pinned * @param {string} key */ isShapePinned(key) { if (key === this.root.hubGoals.currentGoal.definition.getHash() || key === _upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"]) { // This is a "special" shape which is always pinned return true; } return this.pinnedShapes.indexOf(key) >= 0; } /** * Rerenders the whole component */ rerenderFull() { const currentGoal = this.root.hubGoals.currentGoal; const currentKey = currentGoal.definition.getHash(); // First, remove all old shapes for (let i = 0; i < this.handles.length; ++i) { this.handles[i].element.remove(); const detector = this.handles[i].detector; if (detector) { detector.cleanup(); } const infoDetector = this.handles[i].infoDetector; if (infoDetector) { infoDetector.cleanup(); } } this.handles = []; // Pin story goal this.internalPinShape(currentKey, false, "goal"); // Pin blueprint shape as well if (this.root.hubGoals.isRewardUnlocked(_tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["enumHubGoalRewards"].reward_blueprints)) { this.internalPinShape(_upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"], false, "blueprint"); if (this.root.hubGoals.getShapesStoredByKey(_upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"]) == 0) { this.root.hubGoals.putShapeByKey(_upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"], 50); } } // Pin manually pinned shapes for (let i = 0; i < this.pinnedShapes.length; ++i) { const key = this.pinnedShapes[i]; if (key !== currentKey) { this.internalPinShape(key); } } } /** * Pins a new shape * @param {string} key * @param {boolean} canUnpin * @param {string=} className */ internalPinShape(key, canUnpin = true, className = null) { const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey(key); const element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.element, null, ["shape"]); const canvas = definition.generateAsCanvas(120); element.appendChild(canvas); if (className) { element.classList.add(className); } let detector = null; if (canUnpin) { element.classList.add("unpinable"); detector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](element, { consumeEvents: true, preventDefault: true, targetOnly: true, }); detector.click.add(() => this.unpinShape(key)); } else { element.classList.add("marked"); } // Show small info icon const infoButton = document.createElement("button"); infoButton.classList.add("infoButton"); element.appendChild(infoButton); const infoDetector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](infoButton, { consumeEvents: true, preventDefault: true, targetOnly: true, }); infoDetector.click.add(() => this.root.hud.signals.viewShapeDetailsRequested.dispatch(definition)); const amountLabel = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(element, null, ["amountLabel"], ""); const goal = this.findGoalValueForShape(key); if (goal) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(element, null, ["goalLabel"], "/" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["formatBigNumber"])(goal)); } this.handles.push({ key, element, amountLabel, lastRenderedValue: "", detector, infoDetector, }); } /** * Updates all amount labels */ update() { for (let i = 0; i < this.handles.length; ++i) { const handle = this.handles[i]; const currentValue = this.root.hubGoals.getShapesStoredByKey(handle.key); const currentValueFormatted = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["formatBigNumber"])(currentValue); if (currentValueFormatted !== handle.lastRenderedValue) { handle.lastRenderedValue = currentValueFormatted; handle.amountLabel.innerText = currentValueFormatted; const goal = this.findGoalValueForShape(handle.key); handle.element.classList.toggle("completed", goal && currentValue > goal); } } } /** * Unpins a shape * @param {string} key */ unpinShape(key) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["arrayDeleteValue"])(this.pinnedShapes, key); this.rerenderFull(); } /** * Requests to pin a new shape * @param {ShapeDefinition} definition */ pinNewShape(definition) { const key = definition.getHash(); if (key === this.root.hubGoals.currentGoal.definition.getHash()) { // Can not pin current goal return; } if (key === _upgrades__WEBPACK_IMPORTED_MODULE_4__["blueprintShape"]) { // Can not pin the blueprint shape return; } // Check if its already pinned if (this.pinnedShapes.indexOf(key) >= 0) { return; } this.pinnedShapes.push(key); this.rerenderFull(); } } /***/ }), /***/ "./src/js/game/hud/parts/sandbox_controller.js": /*!*****************************************************!*\ !*** ./src/js/game/hud/parts/sandbox_controller.js ***! \*****************************************************/ /*! exports provided: HUDSandboxController */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDSandboxController", function() { return HUDSandboxController; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _notifications__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./notifications */ "./src/js/game/hud/parts/notifications.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../tutorial_goals */ "./src/js/game/tutorial_goals.js"); class HUDSandboxController extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])( parent, "ingame_HUD_SandboxController", [], ` Use F6 to toggle this overlay
` ); const bind = (selector, handler) => this.trackClicks(this.element.querySelector(selector), handler); bind(".giveBlueprints", this.giveBlueprints); bind(".maxOutAll", this.maxOutAll); bind(".levelToggle .minus", () => this.modifyLevel(-1)); bind(".levelToggle .plus", () => this.modifyLevel(1)); bind(".upgradesBelt .minus", () => this.modifyUpgrade("belt", -1)); bind(".upgradesBelt .plus", () => this.modifyUpgrade("belt", 1)); bind(".upgradesExtraction .minus", () => this.modifyUpgrade("miner", -1)); bind(".upgradesExtraction .plus", () => this.modifyUpgrade("miner", 1)); bind(".upgradesProcessing .minus", () => this.modifyUpgrade("processors", -1)); bind(".upgradesProcessing .plus", () => this.modifyUpgrade("processors", 1)); bind(".upgradesPainting .minus", () => this.modifyUpgrade("painting", -1)); bind(".upgradesPainting .plus", () => this.modifyUpgrade("painting", 1)); } giveBlueprints() { if (!this.root.hubGoals.storedShapes[_upgrades__WEBPACK_IMPORTED_MODULE_3__["blueprintShape"]]) { this.root.hubGoals.storedShapes[_upgrades__WEBPACK_IMPORTED_MODULE_3__["blueprintShape"]] = 0; } this.root.hubGoals.storedShapes[_upgrades__WEBPACK_IMPORTED_MODULE_3__["blueprintShape"]] += 1e9; } maxOutAll() { this.modifyUpgrade("belt", 100); this.modifyUpgrade("miner", 100); this.modifyUpgrade("processors", 100); this.modifyUpgrade("painting", 100); } modifyUpgrade(id, amount) { const handle = _upgrades__WEBPACK_IMPORTED_MODULE_3__["UPGRADES"][id]; const maxLevel = handle.tiers.length; this.root.hubGoals.upgradeLevels[id] = Math.max( 0, Math.min(maxLevel, (this.root.hubGoals.upgradeLevels[id] || 0) + amount) ); // Compute improvement let improvement = 1; for (let i = 0; i < this.root.hubGoals.upgradeLevels[id]; ++i) { improvement += handle.tiers[i].improvement; } this.root.hubGoals.upgradeImprovements[id] = improvement; this.root.signals.upgradePurchased.dispatch(id); this.root.hud.signals.notification.dispatch( "Upgrade '" + id + "' is now at tier " + (this.root.hubGoals.upgradeLevels[id] + 1), _notifications__WEBPACK_IMPORTED_MODULE_4__["enumNotificationType"].upgrade ); } modifyLevel(amount) { const hubGoals = this.root.hubGoals; hubGoals.level = Math.max(1, hubGoals.level + amount); hubGoals.createNextGoal(); // Clear all shapes of this level hubGoals.storedShapes[hubGoals.currentGoal.definition.getHash()] = 0; this.root.hud.parts.pinnedShapes.rerenderFull(); // Compute gained rewards hubGoals.gainedRewards = {}; for (let i = 0; i < hubGoals.level - 1; ++i) { if (i < _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"].length) { const reward = _tutorial_goals__WEBPACK_IMPORTED_MODULE_5__["tutorialGoals"][i].reward; hubGoals.gainedRewards[reward] = (hubGoals.gainedRewards[reward] || 0) + 1; } } this.root.hud.signals.notification.dispatch( "Changed level to " + hubGoals.level, _notifications__WEBPACK_IMPORTED_MODULE_4__["enumNotificationType"].upgrade ); } initialize() { // Allow toggling the controller overlay this.root.gameState.inputReciever.keydown.add(key => { if (key.keyCode === 117) { // F6 this.toggle(); } }); this.visible = !true; this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_2__["DynamicDomAttach"](this.root, this.element); } toggle() { this.visible = !this.visible; } update() { this.domAttach.update(this.visible); } } /***/ }), /***/ "./src/js/game/hud/parts/screenshot_exporter.js": /*!******************************************************!*\ !*** ./src/js/game/hud/parts/screenshot_exporter.js ***! \******************************************************/ /*! exports provided: HUDScreenshotExporter */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDScreenshotExporter", function() { return HUDScreenshotExporter; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _components_static_map_entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../components/static_map_entity */ "./src/js/game/components/static_map_entity.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../core/rectangle */ "./src/js/core/rectangle.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_4__["createLogger"])("screenshot_exporter"); class HUDScreenshotExporter extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements() {} initialize() { this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_1__["KEYMAPPINGS"].ingame.exportScreenshot).add(this.startExport, this); } startExport() { if (_core_config__WEBPACK_IMPORTED_MODULE_2__["IS_DEMO"]) { this.root.hud.parts.dialogs.showFeatureRestrictionInfo(_translations__WEBPACK_IMPORTED_MODULE_3__["T"].demo.features.exportingBase); return; } const { ok } = this.root.hud.parts.dialogs.showInfo( _translations__WEBPACK_IMPORTED_MODULE_3__["T"].dialogs.exportScreenshotWarning.title, _translations__WEBPACK_IMPORTED_MODULE_3__["T"].dialogs.exportScreenshotWarning.desc, ["cancel:good", "ok:bad"] ); ok.add(this.doExport, this); } doExport() { logger.log("Starting export ..."); // Find extends const staticEntities = this.root.entityMgr.getAllWithComponent(_components_static_map_entity__WEBPACK_IMPORTED_MODULE_5__["StaticMapEntityComponent"]); const minTile = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); const maxTile = new _core_vector__WEBPACK_IMPORTED_MODULE_6__["Vector"](0, 0); for (let i = 0; i < staticEntities.length; ++i) { const bounds = staticEntities[i].components.StaticMapEntity.getTileSpaceBounds(); minTile.x = Math.min(minTile.x, bounds.x); minTile.y = Math.min(minTile.y, bounds.y); maxTile.x = Math.max(maxTile.x, bounds.x + bounds.w); maxTile.y = Math.max(maxTile.y, bounds.y + bounds.h); } const minChunk = minTile.divideScalar(_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkSize).floor(); const maxChunk = maxTile.divideScalar(_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkSize).ceil(); const dimensions = maxChunk.sub(minChunk); logger.log("Dimensions:", dimensions); let chunkSizePixels = 128; const maxDimensions = Math.max(dimensions.x, dimensions.y); if (maxDimensions > 128) { chunkSizePixels = Math.max(1, Math.floor(128 * (128 / maxDimensions))); } logger.log("ChunkSizePixels:", chunkSizePixels); const chunkScale = chunkSizePixels / _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkWorldSize; logger.log("Scale:", chunkScale); logger.log("Allocating buffer, if the factory grew too big it will crash here"); const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_7__["makeOffscreenBuffer"])( dimensions.x * chunkSizePixels, dimensions.y * chunkSizePixels, { smooth: true, reusable: false, label: "export-buffer", } ); logger.log("Got buffer, rendering now ..."); const visibleRect = new _core_rectangle__WEBPACK_IMPORTED_MODULE_9__["Rectangle"]( minChunk.x * _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkWorldSize, minChunk.y * _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkWorldSize, dimensions.x * _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkWorldSize, dimensions.y * _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].mapChunkWorldSize ); const parameters = new _core_draw_parameters__WEBPACK_IMPORTED_MODULE_8__["DrawParameters"]({ context, visibleRect, desiredAtlasScale: "1", root: this.root, zoomLevel: chunkScale, }); context.scale(chunkScale, chunkScale); context.translate(-visibleRect.x, -visibleRect.y); // Render all relevant chunks this.root.map.drawBackground(parameters); this.root.map.drawForeground(parameters); // Offer export logger.log("Rendered buffer, exporting ..."); const image = canvas.toDataURL("image/png"); const link = document.createElement("a"); link.download = "base.png"; link.href = image; link.click(); logger.log("Done!"); } } /***/ }), /***/ "./src/js/game/hud/parts/settings_menu.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/settings_menu.js ***! \************************************************/ /*! exports provided: HUDSettingsMenu */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDSettingsMenu", function() { return HUDSettingsMenu; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _core_input_receiver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_static_map_entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../components/static_map_entity */ "./src/js/game/components/static_map_entity.js"); /* harmony import */ var _components_belt__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../components/belt */ "./src/js/game/components/belt.js"); class HUDSettingsMenu extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.background = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_SettingsMenu", ["ingameDialog"]); this.menuElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.background, null, ["menuElement"]); this.statsElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])( this.background, null, ["statsElement"], ` ${_translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.beltsPlaced} ${_translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.buildingsPlaced} ${_translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.playtime} ` ); this.buttonContainer = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.menuElement, null, ["buttons"]); const buttons = [ { title: _translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.buttons.continue, action: () => this.close(), }, { title: _translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.buttons.settings, action: () => this.goToSettings(), }, { title: _translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.buttons.menu, action: () => this.returnToMenu(), }, ]; for (let i = 0; i < buttons.length; ++i) { const { title, action } = buttons[i]; const element = document.createElement("button"); element.classList.add("styledButton"); element.innerText = title; this.buttonContainer.appendChild(element); this.trackClicks(element, action); } } returnToMenu() { this.root.gameState.goBackToMenu(); } goToSettings() { this.root.gameState.goToSettings(); } shouldPauseGame() { return this.visible; } shouldPauseRendering() { return this.visible; } initialize() { this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KEYMAPPINGS"].general.back).add(this.show, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_2__["DynamicDomAttach"](this.root, this.background, { attachClass: "visible", }); this.inputReciever = new _core_input_receiver__WEBPACK_IMPORTED_MODULE_3__["InputReceiver"]("settingsmenu"); this.keyActionMapper = new _key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KeyActionMapper"](this.root, this.inputReciever); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KEYMAPPINGS"].general.back).add(this.close, this); this.close(); } cleanup() { document.body.classList.remove("ingameDialogOpen"); } show() { this.visible = true; document.body.classList.add("ingameDialogOpen"); this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); const totalMinutesPlayed = Math.ceil(this.root.time.now() / 60); /** @type {HTMLElement} */ const playtimeElement = this.statsElement.querySelector(".playtime"); /** @type {HTMLElement} */ const buildingsPlacedElement = this.statsElement.querySelector(".buildingsPlaced"); /** @type {HTMLElement} */ const beltsPlacedElement = this.statsElement.querySelector(".beltsPlaced"); playtimeElement.innerText = _translations__WEBPACK_IMPORTED_MODULE_5__["T"].global.time.xMinutes.replace("", `${totalMinutesPlayed}`); buildingsPlacedElement.innerText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["formatBigNumberFull"])( this.root.entityMgr.getAllWithComponent(_components_static_map_entity__WEBPACK_IMPORTED_MODULE_6__["StaticMapEntityComponent"]).length - this.root.entityMgr.getAllWithComponent(_components_belt__WEBPACK_IMPORTED_MODULE_7__["BeltComponent"]).length ); beltsPlacedElement.innerText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["formatBigNumberFull"])( this.root.entityMgr.getAllWithComponent(_components_belt__WEBPACK_IMPORTED_MODULE_7__["BeltComponent"]).length ); } close() { this.visible = false; document.body.classList.remove("ingameDialogOpen"); this.root.app.inputMgr.makeSureDetached(this.inputReciever); this.update(); } update() { this.domAttach.update(this.visible); } } /***/ }), /***/ "./src/js/game/hud/parts/shape_viewer.js": /*!***********************************************!*\ !*** ./src/js/game/hud/parts/shape_viewer.js ***! \***********************************************/ /*! exports provided: HUDShapeViewer */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDShapeViewer", function() { return HUDShapeViewer; }); /* harmony import */ var _core_input_receiver__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); const copy = __webpack_require__(/*! clipboard-copy */ "./node_modules/clipboard-copy/index.js"); class HUDShapeViewer extends _base_hud_part__WEBPACK_IMPORTED_MODULE_5__["BaseHUDPart"] { createElements(parent) { this.background = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_ShapeViewer", ["ingameDialog"]); // DIALOG Inner / Wrapper this.dialogInner = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.background, null, ["dialogInner"]); this.title = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.dialogInner, null, ["title"], _translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.shapeViewer.title); this.closeButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.title, null, ["closeButton"]); this.trackClicks(this.closeButton, this.close); this.contentDiv = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.dialogInner, null, ["content"]); this.renderArea = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.contentDiv, null, ["renderArea"]); this.infoArea = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.contentDiv, null, ["infoArea"]); // Create button to copy the shape area this.copyButton = document.createElement("button"); this.copyButton.classList.add("styledButton", "copyKey"); this.copyButton.innerText = _translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.shapeViewer.copyKey; this.infoArea.appendChild(this.copyButton); } initialize() { this.root.hud.signals.viewShapeDetailsRequested.add(this.renderForShape, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_6__["DynamicDomAttach"](this.root, this.background, { attachClass: "visible", }); this.currentShapeKey = null; this.inputReciever = new _core_input_receiver__WEBPACK_IMPORTED_MODULE_0__["InputReceiver"]("shape_viewer"); this.keyActionMapper = new _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KeyActionMapper"](this.root, this.inputReciever); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].general.back).add(this.close, this); this.trackClicks(this.copyButton, this.onCopyKeyRequested); this.close(); } /** * Called when the copying of a key was requested */ onCopyKeyRequested() { if (this.currentShapeKey) { copy(this.currentShapeKey); this.close(); } } /** * Closes the dialog */ close() { this.visible = false; document.body.classList.remove("ingameDialogOpen"); this.root.app.inputMgr.makeSureDetached(this.inputReciever); this.update(); } /** * Shows the viewer for a given definition * @param {ShapeDefinition} definition */ renderForShape(definition) { this.visible = true; document.body.classList.add("ingameDialogOpen"); this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["removeAllChildren"])(this.renderArea); this.currentShapeKey = definition.getHash(); const layers = definition.layers; this.contentDiv.setAttribute("data-layers", layers.length); for (let i = 0; i < layers.length; ++i) { const layerElem = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.renderArea, null, ["layer", "layer-" + i]); let fakeLayers = []; for (let k = 0; k < i; ++k) { fakeLayers.push([null, null, null, null]); } fakeLayers.push(layers[i]); const thisLayerOnly = new _shape_definition__WEBPACK_IMPORTED_MODULE_4__["ShapeDefinition"]({ layers: fakeLayers }); const thisLayerCanvas = thisLayerOnly.generateAsCanvas(160); layerElem.appendChild(thisLayerCanvas); for (let quad = 0; quad < 4; ++quad) { const quadElem = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(layerElem, null, ["quad", "quad-" + quad]); const contents = layers[i][quad]; if (contents) { const colorLabelElem = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])( quadElem, null, ["colorLabel"], _translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.colors[contents.color] ); } else { const emptyLabelElem = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])( quadElem, null, ["emptyLabel"], _translations__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.shapeViewer.empty ); } } } } /** * Cleans up everything */ cleanup() { document.body.classList.remove("ingameDialogOpen"); } update() { this.domAttach.update(this.visible); } } /***/ }), /***/ "./src/js/game/hud/parts/shop.js": /*!***************************************!*\ !*** ./src/js/game/hud/parts/shop.js ***! \***************************************/ /*! exports provided: HUDShop */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDShop", function() { return HUDShop; }); /* harmony import */ var _core_click_detector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/click_detector */ "./src/js/core/click_detector.js"); /* harmony import */ var _core_input_receiver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); class HUDShop extends _base_hud_part__WEBPACK_IMPORTED_MODULE_6__["BaseHUDPart"] { createElements(parent) { this.background = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(parent, "ingame_HUD_Shop", ["ingameDialog"]); // DIALOG Inner / Wrapper this.dialogInner = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.background, null, ["dialogInner"]); this.title = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.dialogInner, null, ["title"], _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.shop.title); this.closeButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.title, null, ["closeButton"]); this.trackClicks(this.closeButton, this.close); this.contentDiv = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.dialogInner, null, ["content"]); this.upgradeToElements = {}; // Upgrades for (const upgradeId in _upgrades__WEBPACK_IMPORTED_MODULE_5__["UPGRADES"]) { const handle = {}; handle.requireIndexToElement = []; // Wrapper handle.elem = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.contentDiv, null, ["upgrade"]); handle.elem.setAttribute("data-upgrade-id", upgradeId); // Title const title = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(handle.elem, null, ["title"], _translations__WEBPACK_IMPORTED_MODULE_3__["T"].shopUpgrades[upgradeId].name); // Title > Tier handle.elemTierLabel = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(title, null, ["tier"]); // Icon handle.icon = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(handle.elem, null, ["icon"]); handle.icon.setAttribute("data-icon", "upgrades/" + upgradeId + ".png"); // Description handle.elemDescription = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(handle.elem, null, ["description"], "??"); handle.elemRequirements = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(handle.elem, null, ["requirements"]); // Buy button handle.buyButton = document.createElement("button"); handle.buyButton.classList.add("buy", "styledButton"); handle.buyButton.innerText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.shop.buttonUnlock; handle.elem.appendChild(handle.buyButton); this.trackClicks(handle.buyButton, () => this.tryUnlockNextTier(upgradeId)); // Assign handle this.upgradeToElements[upgradeId] = handle; } } rerenderFull() { for (const upgradeId in this.upgradeToElements) { const handle = this.upgradeToElements[upgradeId]; const { tiers } = _upgrades__WEBPACK_IMPORTED_MODULE_5__["UPGRADES"][upgradeId]; const currentTier = this.root.hubGoals.getUpgradeLevel(upgradeId); const currentTierMultiplier = this.root.hubGoals.upgradeImprovements[upgradeId]; const tierHandle = tiers[currentTier]; // Set tier handle.elemTierLabel.innerText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.shop.tier.replace( "", "" + _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.shop.tierLabels[currentTier] ); handle.elemTierLabel.setAttribute("data-tier", currentTier); // Cleanup detectors for (let i = 0; i < handle.requireIndexToElement.length; ++i) { const requiredHandle = handle.requireIndexToElement[i]; requiredHandle.container.remove(); requiredHandle.pinDetector.cleanup(); requiredHandle.infoDetector.cleanup(); } // Cleanup handle.requireIndexToElement = []; handle.elem.classList.toggle("maxLevel", !tierHandle); if (!tierHandle) { // Max level handle.elemDescription.innerText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.shop.maximumLevel.replace( "", currentTierMultiplier.toString() ); continue; } // Set description handle.elemDescription.innerText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].shopUpgrades[upgradeId].description .replace("", currentTierMultiplier.toString()) .replace("", (currentTierMultiplier + tierHandle.improvement).toString()) // Backwards compatibility .replace("", (tierHandle.improvement * 100.0).toString()); tierHandle.required.forEach(({ shape, amount }) => { const container = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(handle.elemRequirements, null, ["requirement"]); const shapeDef = this.root.shapeDefinitionMgr.getShapeFromShortKey(shape); const shapeCanvas = shapeDef.generateAsCanvas(120); shapeCanvas.classList.add(); container.appendChild(shapeCanvas); const progressContainer = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(container, null, ["amount"]); const progressBar = document.createElement("label"); progressBar.classList.add("progressBar"); progressContainer.appendChild(progressBar); const progressLabel = document.createElement("label"); progressContainer.appendChild(progressLabel); const pinButton = document.createElement("button"); pinButton.classList.add("pin"); container.appendChild(pinButton); const viewInfoButton = document.createElement("button"); viewInfoButton.classList.add("showInfo"); container.appendChild(viewInfoButton); const currentGoalShape = this.root.hubGoals.currentGoal.definition.getHash(); if (shape === currentGoalShape) { pinButton.classList.add("isGoal"); } else if (this.root.hud.parts.pinnedShapes.isShapePinned(shape)) { pinButton.classList.add("alreadyPinned"); } const pinDetector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](pinButton, { consumeEvents: true, preventDefault: true, }); pinDetector.click.add(() => { if (this.root.hud.parts.pinnedShapes.isShapePinned(shape)) { this.root.hud.signals.shapeUnpinRequested.dispatch(shape); pinButton.classList.add("unpinned"); pinButton.classList.remove("pinned", "alreadyPinned"); } else { this.root.hud.signals.shapePinRequested.dispatch(shapeDef); pinButton.classList.add("pinned"); pinButton.classList.remove("unpinned"); } }); const infoDetector = new _core_click_detector__WEBPACK_IMPORTED_MODULE_0__["ClickDetector"](viewInfoButton, { consumeEvents: true, preventDefault: true, }); infoDetector.click.add(() => this.root.hud.signals.viewShapeDetailsRequested.dispatch(shapeDef) ); handle.requireIndexToElement.push({ container, progressLabel, progressBar, definition: shapeDef, required: amount, pinDetector, infoDetector, }); }); } } renderCountsAndStatus() { for (const upgradeId in this.upgradeToElements) { const handle = this.upgradeToElements[upgradeId]; for (let i = 0; i < handle.requireIndexToElement.length; ++i) { const { progressLabel, progressBar, definition, required } = handle.requireIndexToElement[i]; const haveAmount = this.root.hubGoals.getShapesStored(definition); const progress = Math.min(haveAmount / required, 1.0); progressLabel.innerText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])(haveAmount) + " / " + Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])(required); progressBar.style.width = progress * 100.0 + "%"; progressBar.classList.toggle("complete", progress >= 1.0); } handle.buyButton.classList.toggle("buyable", this.root.hubGoals.canUnlockUpgrade(upgradeId)); } } initialize() { this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_7__["DynamicDomAttach"](this.root, this.background, { attachClass: "visible", }); this.inputReciever = new _core_input_receiver__WEBPACK_IMPORTED_MODULE_1__["InputReceiver"]("shop"); this.keyActionMapper = new _key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KeyActionMapper"](this.root, this.inputReciever); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KEYMAPPINGS"].general.back).add(this.close, this); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KEYMAPPINGS"].ingame.menuClose).add(this.close, this); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_4__["KEYMAPPINGS"].ingame.menuOpenShop).add(this.close, this); this.close(); this.rerenderFull(); this.root.signals.upgradePurchased.add(this.rerenderFull, this); } cleanup() { document.body.classList.remove("ingameDialogOpen"); // Cleanup detectors for (const upgradeId in this.upgradeToElements) { const handle = this.upgradeToElements[upgradeId]; for (let i = 0; i < handle.requireIndexToElement.length; ++i) { const requiredHandle = handle.requireIndexToElement[i]; requiredHandle.container.remove(); requiredHandle.pinDetector.cleanup(); requiredHandle.infoDetector.cleanup(); } handle.requireIndexToElement = []; } } show() { this.visible = true; document.body.classList.add("ingameDialogOpen"); // this.background.classList.add("visible"); this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); this.rerenderFull(); } close() { this.visible = false; document.body.classList.remove("ingameDialogOpen"); this.root.app.inputMgr.makeSureDetached(this.inputReciever); this.update(); } update() { this.domAttach.update(this.visible); if (this.visible) { this.renderCountsAndStatus(); } } tryUnlockNextTier(upgradeId) { // Nothing this.root.hubGoals.tryUnlockUpgrade(upgradeId); } } /***/ }), /***/ "./src/js/game/hud/parts/statistics.js": /*!*********************************************!*\ !*** ./src/js/game/hud/parts/statistics.js ***! \*********************************************/ /*! exports provided: HUDStatistics */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDStatistics", function() { return HUDStatistics; }); /* harmony import */ var _core_input_receiver__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _production_analytics__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../production_analytics */ "./src/js/game/production_analytics.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _statistics_handle__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./statistics_handle */ "./src/js/game/hud/parts/statistics_handle.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /** * Capitalizes the first letter * @param {string} str */ function capitalizeFirstLetter(str) { return str.substr(0, 1).toUpperCase() + str.substr(1).toLowerCase(); } class HUDStatistics extends _base_hud_part__WEBPACK_IMPORTED_MODULE_4__["BaseHUDPart"] { createElements(parent) { this.background = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_HUD_Statistics", ["ingameDialog"]); // DIALOG Inner / Wrapper this.dialogInner = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.background, null, ["dialogInner"]); this.title = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.dialogInner, null, ["title"], _translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.statistics.title); this.closeButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.title, null, ["closeButton"]); this.trackClicks(this.closeButton, this.close); this.filterHeader = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.dialogInner, null, ["filterHeader"]); this.sourceExplanation = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.dialogInner, null, ["sourceExplanation"]); this.filtersDataSource = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.filterHeader, null, ["filtersDataSource"]); this.filtersDisplayMode = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.filterHeader, null, ["filtersDisplayMode"]); const dataSources = [ _production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].produced, _production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].delivered, _production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].stored, ]; for (let i = 0; i < dataSources.length; ++i) { const dataSource = dataSources[i]; const button = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeButton"])( this.filtersDataSource, ["mode" + capitalizeFirstLetter(dataSource)], _translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.statistics.dataSources[dataSource].title ); this.trackClicks(button, () => this.setDataSource(dataSource)); } const buttonDisplayDetailed = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeButton"])(this.filtersDisplayMode, ["displayDetailed"]); const buttonDisplayIcons = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeButton"])(this.filtersDisplayMode, ["displayIcons"]); this.trackClicks(buttonDisplayIcons, () => this.setDisplayMode(_statistics_handle__WEBPACK_IMPORTED_MODULE_6__["enumDisplayMode"].icons)); this.trackClicks(buttonDisplayDetailed, () => this.setDisplayMode(_statistics_handle__WEBPACK_IMPORTED_MODULE_6__["enumDisplayMode"].detailed)); this.contentDiv = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(this.dialogInner, null, ["content"]); } /** * @param {enumAnalyticsDataSource} source */ setDataSource(source) { this.dataSource = source; this.dialogInner.setAttribute("data-datasource", source); this.sourceExplanation.innerText = _translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.statistics.dataSources[source].description; if (this.visible) { this.rerenderFull(); } } /** * @param {enumDisplayMode} mode */ setDisplayMode(mode) { this.displayMode = mode; this.dialogInner.setAttribute("data-displaymode", mode); if (this.visible) { this.rerenderFull(); } } initialize() { this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_5__["DynamicDomAttach"](this.root, this.background, { attachClass: "visible", }); this.inputReciever = new _core_input_receiver__WEBPACK_IMPORTED_MODULE_0__["InputReceiver"]("statistics"); this.keyActionMapper = new _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KeyActionMapper"](this.root, this.inputReciever); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYMAPPINGS"].general.back).add(this.close, this); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYMAPPINGS"].ingame.menuClose).add(this.close, this); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYMAPPINGS"].ingame.menuOpenStats).add(this.close, this); /** @type {Object.} */ this.activeHandles = {}; this.setDataSource(_production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].produced); this.setDisplayMode(_statistics_handle__WEBPACK_IMPORTED_MODULE_6__["enumDisplayMode"].detailed); this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { root: this.contentDiv, }); this.lastFullRerender = 0; this.close(); this.rerenderFull(); } intersectionCallback(entries) { for (let i = 0; i < entries.length; ++i) { const entry = entries[i]; const handle = this.activeHandles[entry.target.getAttribute("data-shape-key")]; if (handle) { handle.setVisible(entry.intersectionRatio > 0); } } } cleanup() { document.body.classList.remove("ingameDialogOpen"); } show() { this.visible = true; document.body.classList.add("ingameDialogOpen"); this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); this.rerenderFull(); this.update(); } close() { this.visible = false; document.body.classList.remove("ingameDialogOpen"); this.root.app.inputMgr.makeSureDetached(this.inputReciever); this.update(); } update() { this.domAttach.update(this.visible); if (this.visible) { if (this.root.time.now() - this.lastFullRerender > 1) { this.lastFullRerender = this.root.time.now(); this.lastPartialRerender = this.root.time.now(); this.rerenderFull(); } this.rerenderPartial(); } } /** * Performs a partial rerender, only updating graphs and counts */ rerenderPartial() { for (const key in this.activeHandles) { const handle = this.activeHandles[key]; handle.update(this.displayMode, this.dataSource); } } /** * Performs a full rerender, regenerating everything */ rerenderFull() { for (const key in this.activeHandles) { this.activeHandles[key].detach(); } Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["removeAllChildren"])(this.contentDiv); // Now, attach new ones let entries = null; switch (this.dataSource) { case _production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].stored: { entries = Object.entries(this.root.hubGoals.storedShapes); break; } case _production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].produced: case _production_analytics__WEBPACK_IMPORTED_MODULE_3__["enumAnalyticsDataSource"].delivered: { entries = Object.entries(this.root.productionAnalytics.getCurrentShapeRates(this.dataSource)); break; } } entries.sort((a, b) => b[1] - a[1]); let rendered = new Set(); for (let i = 0; i < Math.min(entries.length, 200); ++i) { const entry = entries[i]; const shapeKey = entry[0]; let handle = this.activeHandles[shapeKey]; // TODO TODO TODO TODO TODO TODO TODO TODO TODO if (!handle) { handle = this.activeHandles[shapeKey] = new _statistics_handle__WEBPACK_IMPORTED_MODULE_6__["HUDShapeStatisticsHandle"]( this.root, shapeKey, this.intersectionObserver ); } rendered.add(shapeKey); handle.attach(this.contentDiv); } for (const key in this.activeHandles) { if (!rendered.has(key)) { this.activeHandles[key].destroy(); delete this.activeHandles[key]; } } if (entries.length === 0) { this.contentDiv.innerHTML = ` ${_translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.statistics.noShapesProduced}`; } this.contentDiv.classList.toggle("hasEntries", entries.length > 0); } } /***/ }), /***/ "./src/js/game/hud/parts/statistics_handle.js": /*!****************************************************!*\ !*** ./src/js/game/hud/parts/statistics_handle.js ***! \****************************************************/ /*! exports provided: enumDisplayMode, HUDShapeStatisticsHandle */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumDisplayMode", function() { return enumDisplayMode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDShapeStatisticsHandle", function() { return HUDShapeStatisticsHandle; }); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _production_analytics__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../production_analytics */ "./src/js/game/production_analytics.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../root */ "./src/js/game/root.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../base_item */ "./src/js/game/base_item.js"); /** @enum {string} */ const enumDisplayMode = { icons: "icons", detailed: "detailed", }; /** * Simple wrapper for a shape definition within the shape statistics */ class HUDShapeStatisticsHandle { /** * @param {GameRoot} root * @param {string} shapeHash * @param {IntersectionObserver} intersectionObserver */ constructor(root, shapeHash, intersectionObserver) { this.shapeHash = shapeHash; this.root = root; this.intersectionObserver = intersectionObserver; this.visible = false; } initElement() { this.element = document.createElement("div"); this.element.setAttribute("data-shape-key", this.shapeHash); this.counter = document.createElement("span"); this.counter.classList.add("counter"); this.element.appendChild(this.counter); } /** * Sets whether the shape handle is visible currently * @param {boolean} visibility */ setVisible(visibility) { if (visibility === this.visible) { return; } this.visible = visibility; if (visibility) { if (!this.shapeCanvas) { // Create elements this.shapeCanvas = _base_item__WEBPACK_IMPORTED_MODULE_7__["BaseItem"].generateAsCanvas(this.shapeHash, 100); this.shapeCanvas.classList.add("icon"); this.element.appendChild(this.shapeCanvas); } } else { // Drop elements this.cleanupChildElements(); } } /** * * @param {enumDisplayMode} displayMode * @param {enumAnalyticsDataSource} dataSource * @param {boolean=} forced */ update(displayMode, dataSource, forced = false) { if (!this.element) { return; } if (!this.visible && !forced) { return; } switch (dataSource) { case _production_analytics__WEBPACK_IMPORTED_MODULE_4__["enumAnalyticsDataSource"].stored: { this.counter.innerText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])( this.root.hubGoals.storedShapes[this.shapeHash] || 0 ); break; } case _production_analytics__WEBPACK_IMPORTED_MODULE_4__["enumAnalyticsDataSource"].delivered: case _production_analytics__WEBPACK_IMPORTED_MODULE_4__["enumAnalyticsDataSource"].produced: { let rate = (this.root.productionAnalytics.getCurrentShapeRate(dataSource, this.shapeHash) / _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].analyticsSliceDurationSeconds) * 60; this.counter.innerText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].ingame.statistics.shapesPerMinute.replace( "", Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])(rate) ); if (_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].debug.detailedStatistics) { this.counter.innerText = "" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["round2Digits"])(rate / 60) + " /s"; } break; } } if (displayMode === enumDisplayMode.detailed) { const graphDpi = _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].statisticsGraphDpi; const w = 270; const h = 40; if (!this.graphCanvas) { const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(w * graphDpi, h * graphDpi, { smooth: true, reusable: false, label: "statgraph-" + this.shapeHash, }); context.scale(graphDpi, graphDpi); canvas.classList.add("graph"); this.graphCanvas = canvas; this.graphContext = context; this.element.appendChild(this.graphCanvas); } this.graphContext.clearRect(0, 0, w, h); this.graphContext.fillStyle = "#bee0db"; this.graphContext.strokeStyle = "#66ccbc"; this.graphContext.lineWidth = 1.5; const sliceWidth = w / (_core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].statisticsGraphSlices - 1); let values = []; let maxValue = 1; for (let i = 0; i < _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].statisticsGraphSlices - 2; ++i) { const value = this.root.productionAnalytics.getPastShapeRate( dataSource, this.shapeHash, _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].statisticsGraphSlices - i - 2 ); if (value > maxValue) { maxValue = value; } values.push(value); } this.graphContext.beginPath(); this.graphContext.moveTo(0.75, h + 5); for (let i = 0; i < values.length; ++i) { const yValue = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["clamp"])((1 - values[i] / maxValue) * h, 0.75, h - 0.75); const x = i * sliceWidth; if (i === 0) { this.graphContext.lineTo(0.75, yValue); } this.graphContext.lineTo(x, yValue); if (i === values.length - 1) { this.graphContext.lineTo(w + 100, yValue); this.graphContext.lineTo(w + 100, h + 5); } } this.graphContext.closePath(); this.graphContext.stroke(); this.graphContext.fill(); } else { if (this.graphCanvas) { this.graphCanvas.remove(); delete this.graphCanvas; delete this.graphContext; } } } /** * Attaches the handle * @param {HTMLElement} parent */ attach(parent) { if (!this.element) { this.initElement(); } if (this.element.parentElement !== parent) { parent.appendChild(this.element); this.intersectionObserver.observe(this.element); } } /** * Detaches the handle */ detach() { if (this.element && this.element.parentElement) { this.element.parentElement.removeChild(this.element); this.intersectionObserver.unobserve(this.element); } } /** * Cleans up all child elements */ cleanupChildElements() { if (this.shapeCanvas) { this.shapeCanvas.remove(); delete this.shapeCanvas; } if (this.graphCanvas) { this.graphCanvas.remove(); delete this.graphCanvas; delete this.graphContext; } } /** * Destroys the handle */ destroy() { this.cleanupChildElements(); if (this.element) { this.intersectionObserver.unobserve(this.element); this.element.remove(); delete this.element; // Remove handle delete this.counter; } } } /***/ }), /***/ "./src/js/game/hud/parts/tools_toolbar.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/tools_toolbar.js ***! \************************************************/ /*! exports provided: supportedBuildings, HUDToolsToolbar */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportedBuildings", function() { return supportedBuildings; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDToolsToolbar", function() { return HUDToolsToolbar; }); /* harmony import */ var _buildings_cutter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../buildings/cutter */ "./src/js/game/buildings/cutter.js"); /* harmony import */ var _base_toolbar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base_toolbar */ "./src/js/game/hud/parts/base_toolbar.js"); /* harmony import */ var _buildings_belt_base__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../buildings/belt_base */ "./src/js/game/buildings/belt_base.js"); /* harmony import */ var _buildings_splitter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../buildings/splitter */ "./src/js/game/buildings/splitter.js"); /* harmony import */ var _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../buildings/underground_belt */ "./src/js/game/buildings/underground_belt.js"); /* harmony import */ var _buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../buildings/toolbar_swapper */ "./src/js/game/buildings/toolbar_swapper.js"); const supportedBuildings = [ _buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_5__["MetaToolbarSwapperBuilding"], _buildings_belt_base__WEBPACK_IMPORTED_MODULE_2__["MetaBeltBaseBuilding"], _buildings_splitter__WEBPACK_IMPORTED_MODULE_3__["MetaSplitterBuilding"], _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_4__["MetaUndergroundBeltBuilding"], ]; class HUDToolsToolbar extends _base_toolbar__WEBPACK_IMPORTED_MODULE_1__["HUDBaseToolbar"] { constructor(root) { super(root, { supportedBuildings, visibilityCondition: () => !this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "regular" && this.root.currentToolbar === 1, htmlElementId: "ingame_HUD_buildings_toolbar", }); } } /***/ }), /***/ "./src/js/game/hud/parts/tutorial_hints.js": /*!*************************************************!*\ !*** ./src/js/game/hud/parts/tutorial_hints.js ***! \*************************************************/ /*! exports provided: HUDPartTutorialHints */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDPartTutorialHints", function() { return HUDPartTutorialHints; }); /* harmony import */ var _core_input_receiver__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/input_receiver */ "./src/js/core/input_receiver.js"); /* harmony import */ var _core_tracked_state__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/tracked_state */ "./src/js/core/tracked_state.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); const tutorialVideos = [2, 3, 4, 5, 6, 7, 9, 10, 11]; class HUDPartTutorialHints extends _base_hud_part__WEBPACK_IMPORTED_MODULE_4__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])( parent, "ingame_HUD_TutorialHints", [], `
${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].ingame.tutorialHints.title}
` ); this.videoElement = this.element.querySelector("video"); } shouldPauseGame() { return this.enlarged; } initialize() { this.trackClicks(this.element.querySelector(".toggleHint"), this.toggleHintEnlarged); this.videoAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_5__["DynamicDomAttach"](this.root, this.videoElement, { timeToKeepSeconds: 0.3, }); this.videoAttach.update(false); this.enlarged = false; this.inputReciever = new _core_input_receiver__WEBPACK_IMPORTED_MODULE_0__["InputReceiver"]("tutorial_hints"); this.keyActionMapper = new _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KeyActionMapper"](this.root, this.inputReciever); this.keyActionMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].general.back).add(this.close, this); this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_5__["DynamicDomAttach"](this.root, this.element); this.currentShownLevel = new _core_tracked_state__WEBPACK_IMPORTED_MODULE_1__["TrackedState"](this.updateVideoUrl, this); } updateVideoUrl(level) { if (tutorialVideos.indexOf(level) < 0) { this.videoElement.querySelector("source").setAttribute("src", ""); this.videoElement.pause(); } else { this.videoElement .querySelector("source") .setAttribute("src", "https://static.shapez.io/tutorial_videos/level_" + level + ".webm"); this.videoElement.currentTime = 0; this.videoElement.load(); } } close() { this.enlarged = false; document.body.classList.remove("ingameDialogOpen"); this.element.classList.remove("enlarged", "noBlur"); this.root.app.inputMgr.makeSureDetached(this.inputReciever); this.update(); } show() { this.root.app.analytics.trackUiClick("tutorial_hint_show"); this.root.app.analytics.trackUiClick("tutorial_hint_show_lvl_" + this.root.hubGoals.level); document.body.classList.add("ingameDialogOpen"); this.element.classList.add("enlarged", "noBlur"); this.enlarged = true; this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); this.update(); this.videoElement.currentTime = 0; this.videoElement.play(); } update() { this.videoAttach.update(this.enlarged); this.currentShownLevel.set(this.root.hubGoals.level); const tutorialVisible = tutorialVideos.indexOf(this.root.hubGoals.level) >= 0; this.domAttach.update(tutorialVisible); } toggleHintEnlarged() { if (this.enlarged) { this.close(); } else { this.show(); } } } /***/ }), /***/ "./src/js/game/hud/parts/unlock_notification.js": /*!******************************************************!*\ !*** ./src/js/game/hud/parts/unlock_notification.js ***! \******************************************************/ /*! exports provided: HUDUnlockNotification */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDUnlockNotification", function() { return HUDUnlockNotification; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _tutorial_goals_mappings__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../tutorial_goals_mappings */ "./src/js/game/tutorial_goals_mappings.js"); /* harmony import */ var _core_input_receiver__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../core/input_receiver */ "./src/js/core/input_receiver.js"); class HUDUnlockNotification extends _base_hud_part__WEBPACK_IMPORTED_MODULE_7__["BaseHUDPart"] { initialize() { this.visible = false; this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_8__["DynamicDomAttach"](this.root, this.element, { timeToKeepSeconds: 0, }); if (!_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.disableUnlockDialog) { this.root.signals.storyGoalCompleted.add(this.showForLevel, this); } this.buttonShowTimeout = null; } createElements(parent) { this.inputReciever = new _core_input_receiver__WEBPACK_IMPORTED_MODULE_10__["InputReceiver"]("unlock-notification"); this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(parent, "ingame_HUD_UnlockNotification", ["noBlur"]); const dialog = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(this.element, null, ["dialog"]); this.elemTitle = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(dialog, null, ["title"]); this.elemSubTitle = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(dialog, null, ["subTitle"], _translations__WEBPACK_IMPORTED_MODULE_4__["T"].ingame.levelCompleteNotification.completed); this.elemContents = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(dialog, null, ["contents"]); this.btnClose = document.createElement("button"); this.btnClose.classList.add("close", "styledButton"); this.btnClose.innerText = _translations__WEBPACK_IMPORTED_MODULE_4__["T"].ingame.levelCompleteNotification.buttonNextLevel; dialog.appendChild(this.btnClose); this.trackClicks(this.btnClose, this.requestClose); } /** * @param {number} level * @param {enumHubGoalRewards} reward */ showForLevel(level, reward) { this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); this.elemTitle.innerText = _translations__WEBPACK_IMPORTED_MODULE_4__["T"].ingame.levelCompleteNotification.levelTitle.replace( "", ("" + level).padStart(2, "0") ); const rewardName = _translations__WEBPACK_IMPORTED_MODULE_4__["T"].storyRewards[reward].title; let html = `
${_translations__WEBPACK_IMPORTED_MODULE_4__["T"].ingame.levelCompleteNotification.unlockText.replace("", rewardName)}
${_translations__WEBPACK_IMPORTED_MODULE_4__["T"].storyRewards[reward].desc}
`; html += "
"; const gained = _tutorial_goals_mappings__WEBPACK_IMPORTED_MODULE_9__["enumHubGoalRewardsToContentUnlocked"][reward]; if (gained) { gained.forEach(([metaBuildingClass, variant]) => { const metaBuilding = _core_global_registries__WEBPACK_IMPORTED_MODULE_1__["gMetaBuildingRegistry"].findByClass(metaBuildingClass); html += `
`; }); } html += "
"; this.elemContents.innerHTML = html; this.visible = true; this.root.soundProxy.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].levelComplete); if (this.buttonShowTimeout) { clearTimeout(this.buttonShowTimeout); } this.element.querySelector("button.close").classList.remove("unlocked"); if (this.root.app.settings.getAllSettings().offerHints) { this.buttonShowTimeout = setTimeout( () => this.element.querySelector("button.close").classList.add("unlocked"), true ? 100 : undefined ); } else { this.element.querySelector("button.close").classList.add("unlocked"); } } cleanup() { this.root.app.inputMgr.makeSureDetached(this.inputReciever); if (this.buttonShowTimeout) { clearTimeout(this.buttonShowTimeout); this.buttonShowTimeout = null; } } requestClose() { this.root.app.adProvider.showVideoAd().then(() => { this.close(); if (!this.root.app.settings.getAllSettings().offerHints) { return; } if (this.root.hubGoals.level === 3) { const { showUpgrades } = this.root.hud.parts.dialogs.showInfo( _translations__WEBPACK_IMPORTED_MODULE_4__["T"].dialogs.upgradesIntroduction.title, _translations__WEBPACK_IMPORTED_MODULE_4__["T"].dialogs.upgradesIntroduction.desc, ["showUpgrades:good:timeout"] ); showUpgrades.add(() => this.root.hud.parts.shop.show()); } if (this.root.hubGoals.level === 5) { const { showKeybindings } = this.root.hud.parts.dialogs.showInfo( _translations__WEBPACK_IMPORTED_MODULE_4__["T"].dialogs.keybindingsIntroduction.title, _translations__WEBPACK_IMPORTED_MODULE_4__["T"].dialogs.keybindingsIntroduction.desc, ["showKeybindings:misc", "ok:good:timeout"] ); showKeybindings.add(() => this.root.gameState.goToKeybindings()); } }); } close() { this.root.app.inputMgr.makeSureDetached(this.inputReciever); if (this.buttonShowTimeout) { clearTimeout(this.buttonShowTimeout); this.buttonShowTimeout = null; } this.visible = false; } update() { this.domAttach.update(this.visible); if (!this.visible && this.buttonShowTimeout) { clearTimeout(this.buttonShowTimeout); this.buttonShowTimeout = null; } } } /***/ }), /***/ "./src/js/game/hud/parts/vignette_overlay.js": /*!***************************************************!*\ !*** ./src/js/game/hud/parts/vignette_overlay.js ***! \***************************************************/ /*! exports provided: HUDVignetteOverlay */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDVignetteOverlay", function() { return HUDVignetteOverlay; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); class HUDVignetteOverlay extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["makeDiv"])(parent, "ingame_VignetteOverlay"); } initialize() {} } /***/ }), /***/ "./src/js/game/hud/parts/watermark.js": /*!********************************************!*\ !*** ./src/js/game/hud/parts/watermark.js ***! \********************************************/ /*! exports provided: HUDWatermark */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDWatermark", function() { return HUDWatermark; }); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); class HUDWatermark extends _base_hud_part__WEBPACK_IMPORTED_MODULE_0__["BaseHUDPart"] { createElements(parent) { this.element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["makeDiv"])(parent, "ingame_HUD_Watermark"); } initialize() { this.trackClicks(this.element, this.onWatermarkClick); } onWatermarkClick() { this.root.app.analytics.trackUiClick("watermark_click_2"); this.root.app.platformWrapper.openExternalLink(_core_config__WEBPACK_IMPORTED_MODULE_3__["THIRDPARTY_URLS"].standaloneStorePage); } /** * * @param {DrawParameters} parameters */ drawOverlays(parameters) { const w = this.root.gameWidth; const x = 280 * this.root.app.getEffectiveUiScale(); parameters.context.fillStyle = "#f77"; parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 17 + "px GameFont"; // parameters.context.textAlign = "center"; parameters.context.fillText( _translations__WEBPACK_IMPORTED_MODULE_4__["T"].demoBanners.title.toUpperCase(), x, this.root.app.getEffectiveUiScale() * 27 ); parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 12 + "px GameFont"; // parameters.context.textAlign = "center"; parameters.context.fillText(_translations__WEBPACK_IMPORTED_MODULE_4__["T"].demoBanners.intro, x, this.root.app.getEffectiveUiScale() * 45); // parameters.context.textAlign = "left"; } } /***/ }), /***/ "./src/js/game/hud/parts/waypoints.js": /*!********************************************!*\ !*** ./src/js/game/hud/parts/waypoints.js ***! \********************************************/ /*! exports provided: HUDWaypoints */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDWaypoints", function() { return HUDWaypoints; }); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../core/modal_dialog_elements */ "./src/js/core/modal_dialog_elements.js"); /* harmony import */ var _core_modal_dialog_forms__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/modal_dialog_forms */ "./src/js/core/modal_dialog_forms.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../translations */ "./src/js/translations.js"); /* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../camera */ "./src/js/game/camera.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../dynamic_dom_attach */ "./src/js/game/hud/dynamic_dom_attach.js"); /* harmony import */ var _notifications__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./notifications */ "./src/js/game/hud/parts/notifications.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../items/shape_item */ "./src/js/game/items/shape_item.js"); /** @typedef {{ * label: string | null, * center: { x: number, y: number }, * zoomLevel: number * }} Waypoint */ /** * Used when a shape icon is rendered instead */ const MAX_LABEL_LENGTH = 71; class HUDWaypoints extends _base_hud_part__WEBPACK_IMPORTED_MODULE_13__["BaseHUDPart"] { /** * Creates the overview of waypoints * @param {HTMLElement} parent */ createElements(parent) { // Create the helper box on the lower right when zooming out if (this.root.app.settings.getAllSettings().offerHints) { this.hintElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["makeDiv"])( parent, "ingame_HUD_Waypoints_Hint", [], ` ${_translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.waypoints} ${_translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.description.replace( "", `${this.root.keyMapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].navigation.createMarker) .getKeyCodeString()}` )} ` ); } // Create the waypoint list on the upper right this.waypointsListElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["makeDiv"])(parent, "ingame_HUD_Waypoints", [], "Waypoints"); } /** * Serializes the waypoints */ serialize() { return { waypoints: this.waypoints, }; } /** * Deserializes the waypoints * @param {{waypoints: Array}} data */ deserialize(data) { if (!data || !data.waypoints || !Array.isArray(data.waypoints)) { return "Invalid waypoints data"; } this.waypoints = data.waypoints; this.rerenderWaypointList(); } /** * Initializes everything */ initialize() { // Cache the sprite for the waypoints this.waypointSprite = _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/misc/waypoint.png"); this.directionIndicatorSprite = _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/misc/hub_direction_indicator.png"); /** @type {Array} */ this.waypoints = [ { label: null, center: { x: 0, y: 0 }, zoomLevel: 3, }, ]; // Create a buffer we can use to measure text this.dummyBuffer = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(1, 1, { reusable: false, label: "waypoints-measure-canvas", })[1]; // Dynamically attach/detach the lower right hint in the map overview if (this.hintElement) { this.domAttach = new _dynamic_dom_attach__WEBPACK_IMPORTED_MODULE_14__["DynamicDomAttach"](this.root, this.hintElement); } // Catch mouse and key events this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.keyMapper .getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].navigation.createMarker) .add(() => this.requestSaveMarker({})); /** * Stores at how much opacity the markers should be rendered on the map. * This is interpolated over multiple frames so we have some sort of fade effect */ this.currentMarkerOpacity = 1; this.currentCompassOpacity = 0; // Create buffer which is used to indicate the hub direction const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(48, 48, { smooth: true, reusable: false, label: "waypoints-compass", }); this.compassBuffer = { canvas, context }; /** * Stores a cache from a shape short key to its canvas representation */ this.cachedKeyToCanvas = {}; /** * Store cached text widths * @type {Object} */ this.cachedTextWidths = {}; // Initial render this.rerenderWaypointList(); } /** * Returns how long a text will be rendered * @param {string} text * @returns {number} */ getTextWidth(text) { if (this.cachedTextWidths[text]) { return this.cachedTextWidths[text]; } this.dummyBuffer.font = "bold " + this.getTextScale() + "px GameFont"; return (this.cachedTextWidths[text] = this.dummyBuffer.measureText(text).width); } /** * Returns how big the text should be rendered */ getTextScale() { return this.getWaypointUiScale() * 12; } /** * Returns the scale for rendering waypoints */ getWaypointUiScale() { return this.root.app.getEffectiveUiScale(); } /** * Re-renders the waypoint list to account for changes */ rerenderWaypointList() { Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["removeAllChildren"])(this.waypointsListElement); this.cleanupClickDetectors(); for (let i = 0; i < this.waypoints.length; ++i) { const waypoint = this.waypoints[i]; const label = this.getWaypointLabel(waypoint); const element = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["makeDiv"])(this.waypointsListElement, null, ["waypoint"]); if (_shape_definition__WEBPACK_IMPORTED_MODULE_16__["ShapeDefinition"].isValidShortKey(label)) { const canvas = this.getWaypointCanvas(waypoint); /** * Create a clone of the cached canvas, as calling appendElement when a canvas is * already in the document will move the existing canvas to the new position. */ const [newCanvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(48, 48, { smooth: true, label: label + "-waypoint-" + i, }); context.drawImage(canvas, 0, 0); element.appendChild(newCanvas); element.classList.add("shapeIcon"); } else { element.innerText = label; } if (this.isWaypointDeletable(waypoint)) { const editButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["makeDiv"])(element, null, ["editButton"]); this.trackClicks(editButton, () => this.requestSaveMarker({ waypoint })); } if (!waypoint.label) { // This must be the hub label element.classList.add("hub"); element.insertBefore(this.compassBuffer.canvas, element.childNodes[0]); } this.trackClicks(element, () => this.moveToWaypoint(waypoint), { targetOnly: true, }); } } /** * Moves the camera to a given waypoint * @param {Waypoint} waypoint */ moveToWaypoint(waypoint) { this.root.camera.setDesiredCenter(new _core_vector__WEBPACK_IMPORTED_MODULE_9__["Vector"](waypoint.center.x, waypoint.center.y)); this.root.camera.setDesiredZoom(waypoint.zoomLevel); } /** * Deletes a waypoint from the list * @param {Waypoint} waypoint */ deleteWaypoint(waypoint) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["arrayDeleteValue"])(this.waypoints, waypoint); this.rerenderWaypointList(); } /** * Gets the canvas for a given waypoint * @param {Waypoint} waypoint * @returns {HTMLCanvasElement} */ getWaypointCanvas(waypoint) { const key = waypoint.label; if (this.cachedKeyToCanvas[key]) { return this.cachedKeyToCanvas[key]; } window.assert(_shape_definition__WEBPACK_IMPORTED_MODULE_16__["ShapeDefinition"].isValidShortKey(key), "Invalid short key: " + key); const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey(key); const preRendered = definition.generateAsCanvas(48); return (this.cachedKeyToCanvas[key] = preRendered); } /** * Requests to save a marker at the current camera position. If worldPos is set, * uses that position instead. * @param {object} param0 * @param {Vector=} param0.worldPos Override the world pos, otherwise it is the camera position * @param {Waypoint=} param0.waypoint Waypoint to be edited. If omitted, create new */ requestSaveMarker({ worldPos = null, waypoint = null }) { // Construct dialog with input field const markerNameInput = new _core_modal_dialog_forms__WEBPACK_IMPORTED_MODULE_5__["FormElementInput"]({ id: "markerName", label: null, placeholder: "", defaultValue: waypoint ? waypoint.label : "", validator: val => val.length > 0 && (val.length < MAX_LABEL_LENGTH || _shape_definition__WEBPACK_IMPORTED_MODULE_16__["ShapeDefinition"].isValidShortKey(val)), }); const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_4__["DialogWithForm"]({ app: this.root.app, title: waypoint ? _translations__WEBPACK_IMPORTED_MODULE_10__["T"].dialogs.createMarker.titleEdit : _translations__WEBPACK_IMPORTED_MODULE_10__["T"].dialogs.createMarker.title, desc: _translations__WEBPACK_IMPORTED_MODULE_10__["T"].dialogs.createMarker.desc, formElements: [markerNameInput], buttons: waypoint ? ["delete:bad", "cancel", "ok:good"] : ["cancel", "ok:good"], }); this.root.hud.parts.dialogs.internalShowDialog(dialog); // Edit marker if (waypoint) { dialog.buttonSignals.ok.add(() => { // Actually rename the waypoint this.renameWaypoint(waypoint, markerNameInput.getValue()); }); dialog.buttonSignals.delete.add(() => { // Actually delete the waypoint this.deleteWaypoint(waypoint); }); } else { // Compute where to create the marker const center = worldPos || this.root.camera.center; dialog.buttonSignals.ok.add(() => { // Show info that you can have only N markers in the demo, // actually show this *after* entering the name so you want the // standalone even more (I'm evil :P) if (_core_config__WEBPACK_IMPORTED_MODULE_1__["IS_DEMO"] && this.waypoints.length > 2) { this.root.hud.parts.dialogs.showFeatureRestrictionInfo( "", _translations__WEBPACK_IMPORTED_MODULE_10__["T"].dialogs.markerDemoLimit.desc ); return; } // Actually create the waypoint this.addWaypoint(markerNameInput.getValue(), center); }); } } /** * Adds a new waypoint at the given location with the given label * @param {string} label * @param {Vector} position */ addWaypoint(label, position) { this.waypoints.push({ label, center: { x: position.x, y: position.y }, // Make sure the zoom is *just* a bit above the zoom level where the map overview // starts, so you always see all buildings zoomLevel: Math.max(this.root.camera.zoomLevel, _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].mapChunkOverviewMinZoom + 0.05), }); this.sortWaypoints(); // Show notification about creation this.root.hud.signals.notification.dispatch( _translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.creationSuccessNotification, _notifications__WEBPACK_IMPORTED_MODULE_15__["enumNotificationType"].success ); // Re-render the list and thus add it this.rerenderWaypointList(); } /** * Renames a waypoint with the given label * @param {Waypoint} waypoint * @param {string} label */ renameWaypoint(waypoint, label) { waypoint.label = label; this.sortWaypoints(); // Show notification about renamed this.root.hud.signals.notification.dispatch( _translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.creationSuccessNotification, _notifications__WEBPACK_IMPORTED_MODULE_15__["enumNotificationType"].success ); // Re-render the list and thus add it this.rerenderWaypointList(); } /** * Called every frame to update stuff */ update() { if (this.domAttach) { this.domAttach.update(this.root.camera.getIsMapOverlayActive()); } } /** * Sort waypoints by name */ sortWaypoints() { this.waypoints.sort((a, b) => { if (!a.label) { return -1; } if (!b.label) { return 1; } return this.getWaypointLabel(a) .padEnd(MAX_LABEL_LENGTH, "0") .localeCompare(this.getWaypointLabel(b).padEnd(MAX_LABEL_LENGTH, "0")); }); } /** * Returns the label for a given waypoint * @param {Waypoint} waypoint * @returns {string} */ getWaypointLabel(waypoint) { return waypoint.label || _translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.hub; } /** * Returns if a waypoint is deletable * @param {Waypoint} waypoint * @returns {boolean} */ isWaypointDeletable(waypoint) { return waypoint.label !== null; } /** * Returns the screen space bounds of the given waypoint or null * if it couldn't be determined. Also returns wheter its a shape or not * @param {Waypoint} waypoint * @return {{ * screenBounds: Rectangle * item: BaseItem|null, * text: string * }} */ getWaypointScreenParams(waypoint) { if (!this.root.camera.getIsMapOverlayActive()) { return null; } // Find parameters const scale = this.getWaypointUiScale(); const screenPos = this.root.camera.worldToScreen(new _core_vector__WEBPACK_IMPORTED_MODULE_9__["Vector"](waypoint.center.x, waypoint.center.y)); // Distinguish between text and item waypoints -> Figure out parameters const originalLabel = this.getWaypointLabel(waypoint); let text, item, textWidth; if (_shape_definition__WEBPACK_IMPORTED_MODULE_16__["ShapeDefinition"].isValidShortKey(originalLabel)) { // If the label is actually a key, render the shape icon item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey(originalLabel); textWidth = 40; } else { // Otherwise render a regular waypoint text = originalLabel; textWidth = this.getTextWidth(text); } return { screenBounds: new _core_rectangle__WEBPACK_IMPORTED_MODULE_6__["Rectangle"]( screenPos.x - 7 * scale, screenPos.y - 12 * scale, 15 * scale + textWidth, 15 * scale ), item, text, }; } /** * Finds the currently intersected waypoint on the map overview under * the cursor. * * @returns {Waypoint | null} */ findCurrentIntersectedWaypoint() { const mousePos = this.root.app.mousePosition; if (!mousePos) { return; } for (let i = 0; i < this.waypoints.length; ++i) { const waypoint = this.waypoints[i]; const params = this.getWaypointScreenParams(waypoint); if (params && params.screenBounds.containsPoint(mousePos.x, mousePos.y)) { return waypoint; } } } /** * Mouse-Down handler * @param {Vector} pos * @param {enumMouseButton} button */ onMouseDown(pos, button) { const waypoint = this.findCurrentIntersectedWaypoint(); if (waypoint) { if (button === _camera__WEBPACK_IMPORTED_MODULE_11__["enumMouseButton"].left) { this.root.soundProxy.playUiClick(); this.moveToWaypoint(waypoint); } else if (button === _camera__WEBPACK_IMPORTED_MODULE_11__["enumMouseButton"].right) { if (this.isWaypointDeletable(waypoint)) { this.root.soundProxy.playUiClick(); this.requestSaveMarker({ waypoint }); } else { this.root.soundProxy.playUiError(); } } return _core_signal__WEBPACK_IMPORTED_MODULE_7__["STOP_PROPAGATION"]; } else { // Allow right click to create a marker if (button === _camera__WEBPACK_IMPORTED_MODULE_11__["enumMouseButton"].right) { if (this.root.camera.getIsMapOverlayActive()) { const worldPos = this.root.camera.screenToWorld(pos); this.requestSaveMarker({ worldPos }); return _core_signal__WEBPACK_IMPORTED_MODULE_7__["STOP_PROPAGATION"]; } } } } /** * Rerenders the compass */ rerenderWaypointsCompass() { const dims = 48; const indicatorSize = 30; const cameraPos = this.root.camera.center; const context = this.compassBuffer.context; context.clearRect(0, 0, dims, dims); const distanceToHub = cameraPos.length(); const compassVisible = distanceToHub > (10 * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize) / this.root.camera.zoomLevel; const targetCompassAlpha = compassVisible ? 1 : 0; // Fade the compas in / out this.currentCompassOpacity = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["lerp"])(this.currentCompassOpacity, targetCompassAlpha, 0.08); // Render the compass if (this.currentCompassOpacity > 0.01) { context.globalAlpha = this.currentCompassOpacity; const angle = cameraPos.angle() + Math.radians(45) + Math.PI / 2; context.translate(dims / 2, dims / 2); context.rotate(angle); this.directionIndicatorSprite.drawCentered(context, 0, 0, indicatorSize); context.rotate(-angle); context.translate(-dims / 2, -dims / 2); context.globalAlpha = 1; } // Render the regualr icon const iconOpacity = 1 - this.currentCompassOpacity; if (iconOpacity > 0.01) { context.globalAlpha = iconOpacity; this.waypointSprite.drawCentered(context, dims / 2, dims / 2, dims * 0.7); context.globalAlpha = 1; } } /** * Draws the waypoints on the map * @param {DrawParameters} parameters */ drawOverlays(parameters) { const mousePos = this.root.app.mousePosition; const desiredOpacity = this.root.camera.getIsMapOverlayActive() ? 1 : 0; this.currentMarkerOpacity = Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["lerp"])(this.currentMarkerOpacity, desiredOpacity, 0.08); this.rerenderWaypointsCompass(); // Don't render with low opacity if (this.currentMarkerOpacity < 0.01) { return; } // Determine rendering scale const scale = this.getWaypointUiScale(); // Set the font size const textSize = this.getTextScale(); parameters.context.font = "bold " + textSize + "px GameFont"; parameters.context.textBaseline = "middle"; // Loop over all waypoints for (let i = 0; i < this.waypoints.length; ++i) { const waypoint = this.waypoints[i]; const waypointData = this.getWaypointScreenParams(waypoint); if (!waypointData) { // Not relevant continue; } if (!parameters.visibleRect.containsRect(waypointData.screenBounds)) { // Out of screen continue; } const bounds = waypointData.screenBounds; const contentPaddingX = 7 * scale; const isSelected = mousePos && bounds.containsPoint(mousePos.x, mousePos.y); // Render the background rectangle parameters.context.globalAlpha = this.currentMarkerOpacity * (isSelected ? 1 : 0.7); parameters.context.fillStyle = "rgba(255, 255, 255, 0.7)"; parameters.context.fillRect(bounds.x, bounds.y, bounds.w, bounds.h); // Render the text if (waypointData.item) { const canvas = this.getWaypointCanvas(waypoint); const itemSize = 14 * scale; parameters.context.drawImage( canvas, bounds.x + contentPaddingX + 6 * scale, bounds.y + bounds.h / 2 - itemSize / 2, itemSize, itemSize ); } else if (waypointData.text) { // Render the text parameters.context.fillStyle = "#000"; parameters.context.textBaseline = "middle"; parameters.context.fillText( waypointData.text, bounds.x + contentPaddingX + 6 * scale, bounds.y + bounds.h / 2 ); parameters.context.textBaseline = "alphabetic"; } else { window.assert(false, "Waypoint has no item and text"); } // Render the small icon on the left this.waypointSprite.drawCentered( parameters.context, bounds.x + contentPaddingX, bounds.y + bounds.h / 2, bounds.h * 0.7 ); } parameters.context.textBaseline = "alphabetic"; parameters.context.globalAlpha = 1; } } /***/ }), /***/ "./src/js/game/hud/parts/wire_info.js": /*!********************************************!*\ !*** ./src/js/game/hud/parts/wire_info.js ***! \********************************************/ /*! exports provided: HUDWireInfo */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDWireInfo", function() { return HUDWireInfo; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _systems_wire__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../systems/wire */ "./src/js/game/systems/wire.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../theme */ "./src/js/game/theme.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../core/loader */ "./src/js/core/loader.js"); class HUDWireInfo extends _base_hud_part__WEBPACK_IMPORTED_MODULE_4__["BaseHUDPart"] { initialize() { this.spriteEmpty = _core_loader__WEBPACK_IMPORTED_MODULE_5__["Loader"].getSprite("sprites/wires/network_empty.png"); this.spriteConflict = _core_loader__WEBPACK_IMPORTED_MODULE_5__["Loader"].getSprite("sprites/wires/network_conflict.png"); } /** * * @param {import("../../../core/draw_utils").DrawParameters} parameters */ drawOverlays(parameters) { if (this.root.currentLayer !== "wires") { // Not in the wires layer return; } const mousePos = this.root.app.mousePosition; if (!mousePos) { // No mouse return; } const worldPos = this.root.camera.screenToWorld(mousePos); const tile = worldPos.toTileSpace(); const entity = this.root.map.getLayerContentXY(tile.x, tile.y, "wires"); if (!entity) { // No entity return; } if ( !this.root.camera.getIsMapOverlayActive() && !this.root.logic.getIsEntityIntersectedWithMatrix(entity, worldPos) ) { // Detailed intersection check return; } const networks = this.root.logic.getEntityWireNetworks(entity, tile); if (networks === null) { // This entity will never be able to be connected return; } if (networks.length === 0) { // No network at all return; } for (let i = 0; i < networks.length; ++i) { const network = networks[i]; this.drawHighlightedNetwork(parameters, network); } if (networks.length === 1) { const network = networks[0]; if (network.valueConflict) { this.spriteConflict.draw(parameters.context, mousePos.x + 15, mousePos.y - 10, 60, 60); } else if (!network.currentValue) { this.spriteEmpty.draw(parameters.context, mousePos.x + 15, mousePos.y - 10, 60, 60); } else { network.currentValue.drawItemCenteredClipped( mousePos.x + 40, mousePos.y + 10, parameters, 60 ); } } } /** * * * @param {import("../../../core/draw_utils").DrawParameters} parameters * @param {WireNetwork} network */ drawHighlightedNetwork(parameters, network) { parameters.context.globalAlpha = 0.5; for (let i = 0; i < network.wires.length; ++i) { const wire = network.wires[i]; const staticComp = wire.components.StaticMapEntity; const screenTile = this.root.camera.worldToScreen(staticComp.origin.toWorldSpace()); _map_chunk_view__WEBPACK_IMPORTED_MODULE_1__["MapChunkView"].drawSingleWiresOverviewTile({ context: parameters.context, x: screenTile.x, y: screenTile.y, entity: wire, tileSizePixels: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize * this.root.camera.zoomLevel, overrideColor: _theme__WEBPACK_IMPORTED_MODULE_3__["THEME"].map.wires.highlightColor, }); } for (let i = 0; i < network.tunnels.length; ++i) { const tunnel = network.tunnels[i]; const staticComp = tunnel.components.StaticMapEntity; const screenTile = this.root.camera.worldToScreen(staticComp.origin.toWorldSpace()); _map_chunk_view__WEBPACK_IMPORTED_MODULE_1__["MapChunkView"].drawSingleWiresOverviewTile({ context: parameters.context, x: screenTile.x, y: screenTile.y, entity: tunnel, tileSizePixels: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize * this.root.camera.zoomLevel, overrideColor: _theme__WEBPACK_IMPORTED_MODULE_3__["THEME"].map.wires.highlightColor, }); } parameters.context.globalAlpha = 1; } } /***/ }), /***/ "./src/js/game/hud/parts/wires_overlay.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/wires_overlay.js ***! \************************************************/ /*! exports provided: HUDWiresOverlay */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDWiresOverlay", function() { return HUDWiresOverlay; }); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _key_action_mapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../theme */ "./src/js/game/theme.js"); /* harmony import */ var _base_hud_part__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../base_hud_part */ "./src/js/game/hud/base_hud_part.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../core/utils */ "./src/js/core/utils.js"); const wiresBackgroundDpi = 4; class HUDWiresOverlay extends _base_hud_part__WEBPACK_IMPORTED_MODULE_5__["BaseHUDPart"] { createElements(parent) {} initialize() { // Probably not the best location, but the one which makes most sense this.root.keyMapper.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"].ingame.switchLayers).add(this.switchLayers, this); this.generateTilePattern(); this.currentAlpha = 0.0; } /** * Switches between layers */ switchLayers() { if (this.root.currentLayer === "regular") { this.root.currentLayer = "wires"; } else { this.root.currentLayer = "regular"; } this.root.signals.editModeChanged.dispatch(this.root.currentLayer); } /** * Generates the background pattern for the wires overlay */ generateTilePattern() { const overlayTile = _core_loader__WEBPACK_IMPORTED_MODULE_6__["Loader"].getSprite("sprites/wires/overlay_tile.png"); const dims = _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize * wiresBackgroundDpi; const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_0__["makeOffscreenBuffer"])(dims, dims, { smooth: false, reusable: false, label: "wires-tile-pattern", }); context.clearRect(0, 0, dims, dims); overlayTile.draw(context, 0, 0, dims, dims); this.tilePatternCanvas = canvas; } update() { const desiredAlpha = this.root.currentLayer === "wires" ? 1.0 : 0.0; this.currentAlpha = Object(_core_utils__WEBPACK_IMPORTED_MODULE_7__["lerp"])(this.currentAlpha, desiredAlpha, 0.12); } /** * * @param {DrawParameters} parameters */ draw(parameters) { if (this.currentAlpha < 0.02) { return; } if (this.root.camera.getIsMapOverlayActive()) { return; } if (!this.cachedPatternBackground) { this.cachedPatternBackground = parameters.context.createPattern(this.tilePatternCanvas, "repeat"); } const bounds = parameters.visibleRect; parameters.context.globalAlpha = this.currentAlpha; const scaleFactor = 1 / wiresBackgroundDpi; parameters.context.globalCompositeOperation = "overlay"; parameters.context.fillStyle = "rgba(50, 200, 150, 1)"; parameters.context.fillRect(bounds.x, bounds.y, bounds.w, bounds.h); parameters.context.globalCompositeOperation = "source-over"; parameters.context.scale(scaleFactor, scaleFactor); parameters.context.fillStyle = this.cachedPatternBackground; parameters.context.fillRect( bounds.x / scaleFactor, bounds.y / scaleFactor, bounds.w / scaleFactor, bounds.h / scaleFactor ); parameters.context.scale(1 / scaleFactor, 1 / scaleFactor); parameters.context.globalAlpha = 1; } } /***/ }), /***/ "./src/js/game/hud/parts/wires_toolbar.js": /*!************************************************!*\ !*** ./src/js/game/hud/parts/wires_toolbar.js ***! \************************************************/ /*! exports provided: HUDWiresToolbar */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HUDWiresToolbar", function() { return HUDWiresToolbar; }); /* harmony import */ var _base_toolbar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_toolbar */ "./src/js/game/hud/parts/base_toolbar.js"); /* harmony import */ var _buildings_wire__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../buildings/wire */ "./src/js/game/buildings/wire.js"); /* harmony import */ var _buildings_constant_signal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../buildings/constant_signal */ "./src/js/game/buildings/constant_signal.js"); /* harmony import */ var _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../buildings/logic_gate */ "./src/js/game/buildings/logic_gate.js"); /* harmony import */ var _buildings_lever__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../buildings/lever */ "./src/js/game/buildings/lever.js"); /* harmony import */ var _buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../buildings/wire_tunnel */ "./src/js/game/buildings/wire_tunnel.js"); /* harmony import */ var _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../buildings/virtual_processor */ "./src/js/game/buildings/virtual_processor.js"); const supportedBuildings = [ _buildings_wire__WEBPACK_IMPORTED_MODULE_1__["MetaWireBuilding"], _buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_5__["MetaWireTunnelBuilding"], _buildings_constant_signal__WEBPACK_IMPORTED_MODULE_2__["MetaConstantSignalBuilding"], _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_3__["MetaLogicGateBuilding"], _buildings_lever__WEBPACK_IMPORTED_MODULE_4__["MetaLeverBuilding"], _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_6__["MetaVirtualProcessorBuilding"], ]; class HUDWiresToolbar extends _base_toolbar__WEBPACK_IMPORTED_MODULE_0__["HUDBaseToolbar"] { constructor(root) { super(root, { supportedBuildings, visibilityCondition: () => !this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "wires", htmlElementId: "ingame_HUD_wires_toolbar", }); } } /***/ }), /***/ "./src/js/game/hud/trailer_maker.js": /*!******************************************!*\ !*** ./src/js/game/hud/trailer_maker.js ***! \******************************************/ /*! exports provided: TrailerMaker */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrailerMaker", function() { return TrailerMaker; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../root */ "./src/js/game/root.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _trailer_points__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./trailer_points */ "./src/js/game/hud/trailer_points.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _buildings_belt_base__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../buildings/belt_base */ "./src/js/game/buildings/belt_base.js"); /* harmony import */ var _components_miner__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/miner */ "./src/js/game/components/miner.js"); /* dev:start */ const tickrate = 1 / 165; class TrailerMaker { /** * * @param {GameRoot} root */ constructor(root) { this.root = root; this.markers = []; this.playbackMarkers = null; this.currentPlaybackOrigin = new _core_vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](); this.currentPlaybackZoom = 3; window.addEventListener("keydown", ev => { if (ev.key === "j") { console.log("Record"); this.markers.push({ pos: this.root.camera.center.copy(), zoom: this.root.camera.zoomLevel, time: 1, wait: 0, }); } else if (ev.key === "k") { console.log("Export"); const json = JSON.stringify(this.markers); const handle = window.open("about:blank"); handle.document.write(json); } else if (ev.key === "u") { if (this.playbackMarkers && this.playbackMarkers.length > 0) { this.playbackMarkers = []; return; } console.log("Playback"); this.playbackMarkers = _trailer_points__WEBPACK_IMPORTED_MODULE_4__["default"].map(p => Object.assign({}, p)); this.playbackMarkers.unshift(this.playbackMarkers[0]); this.currentPlaybackOrigin = _core_vector__WEBPACK_IMPORTED_MODULE_2__["Vector"].fromSerializedObject(this.playbackMarkers[0].pos); this.currentPlaybackZoom = this.playbackMarkers[0].zoom; this.root.camera.center = this.currentPlaybackOrigin.copy(); this.root.camera.zoomLevel = this.currentPlaybackZoom; console.log("STart at", this.currentPlaybackOrigin); // this.root.entityMgr.getAllWithComponent(MinerComponent).forEach(miner => { // miner.components.Miner.itemChainBuffer = []; // miner.components.Miner.lastMiningTime = this.root.time.now() + 5; // miner.components.ItemEjector.slots.forEach(slot => (slot.item = null)); // }); // this.root.logic.tryPlaceBuilding({ // origin: new Vector(-428, -15), // building: gMetaBuildingRegistry.findByClass(MetaBeltBaseBuilding), // originalRotation: 0, // rotation: 0, // variant: "default", // rotationVariant: 0, // }); // this.root.logic.tryPlaceBuilding({ // origin: new Vector(-427, -15), // building: gMetaBuildingRegistry.findByClass(MetaBeltBaseBuilding), // originalRotation: 0, // rotation: 0, // variant: "default", // rotationVariant: 0, // }); } }); } update() { if (this.playbackMarkers && this.playbackMarkers.length > 0) { const nextMarker = this.playbackMarkers[0]; if (!nextMarker.startTime) { console.log("Starting to approach", nextMarker.pos); nextMarker.startTime = performance.now() / 1000.0; } const speed = _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].tileSize * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].beltSpeedItemsPerSecond * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].itemSpacingOnBelts; // let time = // this.currentPlaybackOrigin.distance(Vector.fromSerializedObject(nextMarker.pos)) / speed; const time = nextMarker.time; const progress = (performance.now() / 1000.0 - nextMarker.startTime) / time; if (progress > 1.0) { if (nextMarker.wait > 0) { nextMarker.wait -= tickrate; } else { console.log("Approached"); this.currentPlaybackOrigin = this.root.camera.center.copy(); this.currentPlaybackZoom = this.root.camera.zoomLevel; this.playbackMarkers.shift(); } return; } const targetPos = _core_vector__WEBPACK_IMPORTED_MODULE_2__["Vector"].fromSerializedObject(nextMarker.pos); const targetZoom = nextMarker.zoom; const pos = Object(_core_vector__WEBPACK_IMPORTED_MODULE_2__["mixVector"])(this.currentPlaybackOrigin, targetPos, progress); const zoom = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["lerp"])(this.currentPlaybackZoom, targetZoom, progress); this.root.camera.zoomLevel = zoom; this.root.camera.center = pos; } } } /* dev:end */ /***/ }), /***/ "./src/js/game/hud/trailer_points.js": /*!*******************************************!*\ !*** ./src/js/game/hud/trailer_points.js ***! \*******************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = ([ // // initial // { pos: { x: -13665, y: -434 }, zoom: 6, time: 1, wait: 8 }, // // Go up to first curve // { pos: { x: -13665, y: -580 }, zoom: 6, time: 1, wait: 0 }, // // To balancers // { pos: { x: -13450, y: -580 }, zoom: 6, time: 1, wait: 0 }, // // To cutters // { pos: { x: -13350, y: -580 }, zoom: 3, time: 1, wait: 2 }, // // To initial cutters // { pos: { x: -12713, y: -580 }, zoom: 3, time: 1, wait: 2.5 }, // // To rotaters 3,2,1,0 // { pos: { x: -12402, y: -580 }, zoom: 3, time: 1, wait: 0 }, // // Zoom in further to stackers // { pos: { x: -12045, y: -580 }, zoom: 6, time: 1, wait: 4 }, // // Focus on painter // { pos: { x: -11700, y: -660 }, zoom: 6, time: 1, wait: 3.5 }, // // Zoom in to mixers // { pos: { x: -11463, y: -520 }, zoom: 6, time: 1, wait: 3.8 }, // // Focus to second painter // { pos: { x: -11290, y: -610 }, zoom: 6, time: 1, wait: 1 }, // // Second stacker // { pos: { x: -11022, y: -610 }, zoom: 6, time: 1, wait: 0 }, // // Go right until first curve // { pos: { x: -10859, y: -650 }, zoom: 6, time: 1, wait: 0 }, // // Go up to stacker // { pos: { x: -10859, y: -1120 }, zoom: 6, time: 1, wait: 0 }, // // Go further up // { pos: { x: -10859, y: -1260 }, zoom: 6, time: 1, wait: 0 }, // // Go left // { pos: { x: -11235, y: -1260 }, zoom: 6, time: 1, wait: 1 }, // OWO Savegames // { pos: { x: -4939.356940622392, y: 71.76431237675517 }, zoom: 5.06640625, time: 1, wait: 1 }, // { pos: { x: -4275.441641063683, y: 26.3603982512193 }, zoom: 0.45, time: 32, wait: 0 }, // Eve // { pos: { x: -277.22574043554704, y: 2151.1873666983033 }, zoom: 3.1, time: 0, wait: 2 }, // { pos: { x: -43.64015426578788, y: 1577.5520572108883 }, zoom: 1.4, time: 16, wait: 0 }, // { pos: { x: 133.22735227708466, y: 957.2211413984563 }, zoom: 1.4, time: 8, wait: 0 }, // { pos: { x: 480.20365842184424, y: -313.5485044644265 }, zoom: 1.4, time: 8, wait: 0 }, // { // pos: { x: 452.56528647804333, y: -1341.6422407571154 }, // zoom: 1.4, // time: 8, // wait: 0, // }, // D { pos: { x: -7506.562977380196, y: 1777.6671860680613 }, zoom: 2.3764616075569833, time: 0, wait: 1 }, { pos: { x: -7506.562977380196, y: 1777.6671860680613 }, zoom: 2.3764616075569833, time: 1, wait: 0 }, { pos: { x: -6592.471896026158, y: 1841.974816890533 }, zoom: 1.4594444847409322, time: 24, wait: 0 }, { pos: { x: -7274.384090342281, y: 729.3783696229457 }, zoom: 1.4594444847409322, time: 24, wait: 0 }, { pos: { x: -6048.006011617565, y: 764.6297752493597 }, zoom: 1.1853320776932916, time: 24, wait: 0 }, { pos: { x: -3674.7204249483366, y: 658.6366426023269 }, zoom: 0.25332031250000003, time: 24, wait: 0, }, { pos: { x: -1213.9916574596728, y: -1387.1496772071198 }, zoom: 0.443058809814453, time: 24, wait: 0, }, { pos: { x: 1722.5210292405573, y: -2457.2072755163636 }, zoom: 0.6313986260996299, time: 24, wait: 0, }, { pos: { x: 3533.263459106946, y: -1806.6756300805193 }, zoom: 1.551908182277415, time: 24, wait: 0 }, ]); /***/ }), /***/ "./src/js/game/item_registry.js": /*!**************************************!*\ !*** ./src/js/game/item_registry.js ***! \**************************************/ /*! exports provided: initItemRegistry */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initItemRegistry", function() { return initItemRegistry; }); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./items/shape_item */ "./src/js/game/items/shape_item.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./items/boolean_item */ "./src/js/game/items/boolean_item.js"); function initItemRegistry() { _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gItemRegistry"].register(_items_shape_item__WEBPACK_IMPORTED_MODULE_1__["ShapeItem"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gItemRegistry"].register(_items_color_item__WEBPACK_IMPORTED_MODULE_2__["ColorItem"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gItemRegistry"].register(_items_boolean_item__WEBPACK_IMPORTED_MODULE_3__["BooleanItem"]); } /***/ }), /***/ "./src/js/game/item_resolver.js": /*!**************************************!*\ !*** ./src/js/game/item_resolver.js ***! \**************************************/ /*! exports provided: itemResolverSingleton, typeItemSingleton */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "itemResolverSingleton", function() { return itemResolverSingleton; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "typeItemSingleton", function() { return typeItemSingleton; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./items/shape_item */ "./src/js/game/items/shape_item.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./items/color_item */ "./src/js/game/items/color_item.js"); /** * Resolves items so we share instances * @param {import("../savegame/savegame_serializer").GameRoot} root * @param {{$: string, data: any }} data */ function itemResolverSingleton(root, data) { const itemType = data.$; const itemData = data.data; switch (itemType) { case _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__["BooleanItem"].getId(): { return itemData ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__["BOOL_FALSE_SINGLETON"]; } case _items_shape_item__WEBPACK_IMPORTED_MODULE_3__["ShapeItem"].getId(): { return root.shapeDefinitionMgr.getShapeItemFromShortKey(itemData); } case _items_color_item__WEBPACK_IMPORTED_MODULE_4__["ColorItem"].getId(): { return _items_color_item__WEBPACK_IMPORTED_MODULE_4__["COLOR_ITEM_SINGLETONS"][itemData]; } default: { window.assert(false, "Unknown item type: " + itemType); } } } const typeItemSingleton = _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].obj(_core_global_registries__WEBPACK_IMPORTED_MODULE_1__["gItemRegistry"], itemResolverSingleton); /***/ }), /***/ "./src/js/game/items/boolean_item.js": /*!*******************************************!*\ !*** ./src/js/game/items/boolean_item.js ***! \*******************************************/ /*! exports provided: BooleanItem, BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BooleanItem", function() { return BooleanItem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BOOL_FALSE_SINGLETON", function() { return BOOL_FALSE_SINGLETON; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BOOL_TRUE_SINGLETON", function() { return BOOL_TRUE_SINGLETON; }); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); class BooleanItem extends _base_item__WEBPACK_IMPORTED_MODULE_3__["BaseItem"] { static getId() { return "boolean_item"; } static getSchema() { return _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].uint; } serialize() { return this.value; } deserialize(data) { this.value = data; } /** @returns {"boolean"} **/ getItemType() { return "boolean"; } /** * @param {number} value */ constructor(value) { super(); this.value = value ? 1 : 0; } /** * @param {BaseItem} other */ equalsImpl(other) { return this.value === /** @type {BooleanItem} */ (other).value; } /** * @param {number} x * @param {number} y * @param {number} diameter * @param {DrawParameters} parameters */ drawItemCenteredImpl(x, y, parameters, diameter = _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].defaultItemDiameter) { let sprite; if (this.value) { sprite = _core_loader__WEBPACK_IMPORTED_MODULE_1__["Loader"].getSprite("sprites/wires/boolean_true.png"); } else { sprite = _core_loader__WEBPACK_IMPORTED_MODULE_1__["Loader"].getSprite("sprites/wires/boolean_false.png"); } sprite.drawCachedCentered(parameters, x, y, diameter); } } const BOOL_FALSE_SINGLETON = new BooleanItem(0); const BOOL_TRUE_SINGLETON = new BooleanItem(1); /***/ }), /***/ "./src/js/game/items/color_item.js": /*!*****************************************!*\ !*** ./src/js/game/items/color_item.js ***! \*****************************************/ /*! exports provided: ColorItem, COLOR_ITEM_SINGLETONS */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorItem", function() { return ColorItem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "COLOR_ITEM_SINGLETONS", function() { return COLOR_ITEM_SINGLETONS; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_dpi_manager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/dpi_manager */ "./src/js/core/dpi_manager.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../colors */ "./src/js/game/colors.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../theme */ "./src/js/game/theme.js"); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/draw_utils */ "./src/js/core/draw_utils.js"); class ColorItem extends _base_item__WEBPACK_IMPORTED_MODULE_4__["BaseItem"] { static getId() { return "color"; } static getSchema() { return _savegame_serialization__WEBPACK_IMPORTED_MODULE_3__["types"].enum(_colors__WEBPACK_IMPORTED_MODULE_5__["enumColors"]); } serialize() { return this.color; } deserialize(data) { this.color = data; } getHash() { return _colors__WEBPACK_IMPORTED_MODULE_5__["enumColorToShortcode"][this.color]; } /** @returns {ColorItem} */ static createFromHash(hash) { return new ColorItem(_colors__WEBPACK_IMPORTED_MODULE_5__["enumShortcodeToColor"][hash]); } /** @returns {"color"} **/ getItemType() { return "color"; } /** * @param {BaseItem} other */ equalsImpl(other) { return this.color === /** @type {ColorItem} */ (other).color; } /** * @param {enumColors} color */ constructor(color) { super(); this.color = color; this.bufferGenerator = null; } getBackgroundColorAsResource() { return _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].map.resources[this.color] || _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].map.resources.shape; } /** * @param {number} x * @param {number} y * @param {number} diameter * @param {DrawParameters} parameters */ drawItemCenteredImpl(x, y, parameters, diameter = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter) { if (!this.bufferGenerator) { this.bufferGenerator = this.internalGenerateColorBuffer.bind(this); } const realDiameter = diameter * 0.6; const dpi = Object(_core_dpi_manager__WEBPACK_IMPORTED_MODULE_1__["smoothenDpi"])(_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].shapesSharpness * parameters.zoomLevel); const key = realDiameter + "/" + dpi + "/" + this.color; const canvas = parameters.root.buffers.getForKey({ key: "coloritem", subKey: key, w: realDiameter, h: realDiameter, dpi, redrawMethod: this.bufferGenerator, }); Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_8__["drawSpriteClipped"])({ parameters, sprite: canvas, x: x - realDiameter / 2, y: y - realDiameter / 2, w: realDiameter, h: realDiameter, originalW: realDiameter * dpi, originalH: realDiameter * dpi, }); } /** * * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h * @param {number} dpi */ internalGenerateColorBuffer(canvas, context, w, h, dpi) { context.translate((w * dpi) / 2, (h * dpi) / 2); context.scale((dpi * w) / 12, (dpi * h) / 12); context.fillStyle = _colors__WEBPACK_IMPORTED_MODULE_5__["enumColorsToHexCode"][this.color]; context.strokeStyle = _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].items.outline; context.lineWidth = 2 * _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].items.outlineWidth; context.beginCircle(2, -1, 3); context.stroke(); context.fill(); context.beginCircle(-2, -1, 3); context.stroke(); context.fill(); context.beginCircle(0, 2, 3); context.closePath(); context.stroke(); context.fill(); } /** * Generates this shape as a canvas * @param {number} size */ generateAsCanvas(size = 120) { const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_7__["makeOffscreenBuffer"])(size, size, { smooth: true, label: "definition-canvas-cache-" + this.getHash(), reusable: false, }); this.internalGenerateColorBuffer(canvas, context, size, size, 1); return canvas; } } /** * Singleton instances * @type {Object} */ const COLOR_ITEM_SINGLETONS = {}; for (const color in _colors__WEBPACK_IMPORTED_MODULE_5__["enumColors"]) { COLOR_ITEM_SINGLETONS[color] = new ColorItem(color); } _base_item__WEBPACK_IMPORTED_MODULE_4__["BaseItem"].ColorItem = ColorItem; /***/ }), /***/ "./src/js/game/items/shape_item.js": /*!*****************************************!*\ !*** ./src/js/game/items/shape_item.js ***! \*****************************************/ /*! exports provided: ShapeItem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeItem", function() { return ShapeItem; }); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../theme */ "./src/js/game/theme.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); class ShapeItem extends _base_item__WEBPACK_IMPORTED_MODULE_2__["BaseItem"] { static getId() { return "shape"; } static getSchema() { return _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["types"].string; } serialize() { return this.definition.getHash(); } deserialize(data) { this.definition = _shape_definition__WEBPACK_IMPORTED_MODULE_3__["ShapeDefinition"].fromShortKey(data); } getHash() { return this.definition.getHash(); } /** @returns {ShapeItem} */ static createFromHash(hash) { return new ShapeItem(_shape_definition__WEBPACK_IMPORTED_MODULE_3__["ShapeDefinition"].fromShortKey(hash)); } /** @returns {"shape"} **/ getItemType() { return "shape"; } /** * @param {BaseItem} other */ equalsImpl(other) { return this.definition.getHash() === /** @type {ShapeItem} */ (other).definition.getHash(); } /** * @param {ShapeDefinition} definition */ constructor(definition) { super(); /** * This property must not be modified on runtime, you have to clone the class in order to change the definition */ this.definition = definition; } getBackgroundColorAsResource() { return _theme__WEBPACK_IMPORTED_MODULE_4__["THEME"].map.resources.shape; } /** * @param {number} x * @param {number} y * @param {DrawParameters} parameters * @param {number=} diameter */ drawItemCenteredImpl(x, y, parameters, diameter = _core_config__WEBPACK_IMPORTED_MODULE_5__["globalConfig"].defaultItemDiameter) { this.definition.drawCentered(x, y, parameters, diameter); } } /***/ }), /***/ "./src/js/game/key_action_mapper.js": /*!******************************************!*\ !*** ./src/js/game/key_action_mapper.js ***! \******************************************/ /*! exports provided: keyCodeOf, KEYMAPPINGS, KEYCODE_LMB, KEYCODE_MMB, KEYCODE_RMB, getStringForKeyCode, Keybinding, KeyActionMapper */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "keyCodeOf", function() { return keyCodeOf; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KEYMAPPINGS", function() { return KEYMAPPINGS; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KEYCODE_LMB", function() { return KEYCODE_LMB; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KEYCODE_MMB", function() { return KEYCODE_MMB; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KEYCODE_RMB", function() { return KEYCODE_RMB; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getStringForKeyCode", function() { return getStringForKeyCode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Keybinding", function() { return Keybinding; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyActionMapper", function() { return KeyActionMapper; }); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); function key(str) { return str.toUpperCase().charCodeAt(0); } function keyCodeOf(key) { if (typeof key == "number") { return key; } if (key.match(/F\d+/)) { return 111 + +key.slice(1); } return key.toUpperCase().charCodeAt(0); } const KEYMAPPINGS = { general: { confirm: { keyCode: 13 }, // enter back: { keyCode: 27, builtin: true }, // escape }, ingame: { menuOpenShop: { keyCode: key("F") }, menuOpenStats: { keyCode: key("G") }, menuClose: { keyCode: key("Q") }, toggleHud: { keyCode: 113 }, // F2 exportScreenshot: { keyCode: 114 }, // F3PS toggleFPSInfo: { keyCode: 115 }, // F4 switchLayers: { keyCode: key("Y") }, switchToolbar: { keyCode: key("Z") }, }, navigation: { mapMoveUp: { keyCode: key("W") }, mapMoveRight: { keyCode: key("D") }, mapMoveDown: { keyCode: key("S") }, mapMoveLeft: { keyCode: key("A") }, mapMoveFaster: { keyCode: 16 }, //shift centerMap: { keyCode: 32 }, // SPACE mapZoomIn: { keyCode: 187, repeated: true }, // "+" mapZoomOut: { keyCode: 189, repeated: true }, // "-" createMarker: { keyCode: key("M") }, }, buildings: { belt: { keyCode: key("1") }, splitter: { keyCode: key("2") }, underground_belt: { keyCode: key("3") }, miner: { keyCode: key("4") }, cutter: { keyCode: key("5") }, rotater: { keyCode: key("6") }, stacker: { keyCode: key("7") }, mixer: { keyCode: key("8") }, painter: { keyCode: key("9") }, trash: { keyCode: key("0") }, lever: { keyCode: key("L") }, filter: { keyCode: key("B") }, display: { keyCode: key("N") }, wire: { keyCode: key("1") }, wire_tunnel: { keyCode: key("2") }, constant_signal: { keyCode: key("3") }, logic_gate: { keyCode: key("4") }, virtual_processor: { keyCode: key("5") }, }, placement: { pipette: { keyCode: key("Q") }, rotateWhilePlacing: { keyCode: key("R") }, rotateInverseModifier: { keyCode: 16 }, // SHIFT cycleBuildingVariants: { keyCode: key("T") }, cycleBuildings: { keyCode: 9 }, // TAB switchDirectionLockSide: { keyCode: key("R") }, }, massSelect: { massSelectStart: { keyCode: 17 }, // CTRL massSelectSelectMultiple: { keyCode: 16 }, // SHIFT massSelectCopy: { keyCode: key("C") }, massSelectCut: { keyCode: key("X") }, confirmMassDelete: { keyCode: 46 }, // DEL pasteLastBlueprint: { keyCode: key("V") }, }, placementModifiers: { lockBeltDirection: { keyCode: 16 }, // SHIFT placementDisableAutoOrientation: { keyCode: 17 }, // CTRL placeMultiple: { keyCode: 16 }, // SHIFT placeInverse: { keyCode: 18 }, // ALT }, }; // Assign ids for (const categoryId in KEYMAPPINGS) { for (const mappingId in KEYMAPPINGS[categoryId]) { KEYMAPPINGS[categoryId][mappingId].id = mappingId; } } const KEYCODE_LMB = 1; const KEYCODE_MMB = 2; const KEYCODE_RMB = 3; /** * Returns a keycode -> string * @param {number} code * @returns {string} */ function getStringForKeyCode(code) { switch (code) { case KEYCODE_LMB: return "LMB"; case KEYCODE_MMB: return "MMB"; case KEYCODE_RMB: return "RMB"; case 4: return "MB4"; case 5: return "MB5"; case 8: return "⌫"; case 9: return _translations__WEBPACK_IMPORTED_MODULE_2__["T"].global.keys.tab; case 13: return "⏎"; case 16: return "⇪"; case 17: return _translations__WEBPACK_IMPORTED_MODULE_2__["T"].global.keys.control; case 18: return _translations__WEBPACK_IMPORTED_MODULE_2__["T"].global.keys.alt; case 19: return "PAUSE"; case 20: return "CAPS"; case 27: return _translations__WEBPACK_IMPORTED_MODULE_2__["T"].global.keys.escape; case 32: return _translations__WEBPACK_IMPORTED_MODULE_2__["T"].global.keys.space; case 33: return "PGUP"; case 34: return "PGDOWN"; case 35: return "END"; case 36: return "HOME"; case 37: return "⬅"; case 38: return "⬆"; case 39: return "➡"; case 40: return "⬇"; case 44: return "PRNT"; case 45: return "INS"; case 46: return "DEL"; case 93: return "SEL"; case 96: return "NUM 0"; case 97: return "NUM 1"; case 98: return "NUM 2"; case 99: return "NUM 3"; case 100: return "NUM 4"; case 101: return "NUM 5"; case 102: return "NUM 6"; case 103: return "NUM 7"; case 104: return "NUM 8"; case 105: return "NUM 9"; case 106: return "*"; case 107: return "+"; case 109: return "-"; case 110: return "."; case 111: return "/"; case 112: return "F1"; case 113: return "F2"; case 114: return "F3"; case 115: return "F4"; case 116: return "F4"; case 117: return "F5"; case 118: return "F6"; case 119: return "F7"; case 120: return "F8"; case 121: return "F9"; case 122: return "F10"; case 123: return "F11"; case 124: return "F12"; case 144: return "NUMLOCK"; case 145: return "SCRLOCK"; case 182: return "COMP"; case 183: return "CALC"; case 186: return ";"; case 187: return "+"; case 188: return ","; case 189: return "-"; case 191: return "/"; case 219: return "["; case 220: return "\\"; case 221: return "]"; case 222: return "'"; } return String.fromCharCode(code); } class Keybinding { /** * * @param {KeyActionMapper} keyMapper * @param {Application} app * @param {object} param0 * @param {number} param0.keyCode * @param {boolean=} param0.builtin * @param {boolean=} param0.repeated */ constructor(keyMapper, app, { keyCode, builtin = false, repeated = false }) { window.assert(keyCode && Number.isInteger(keyCode), "Invalid key code: " + keyCode); this.keyMapper = keyMapper; this.app = app; this.keyCode = keyCode; this.builtin = builtin; this.repeated = repeated; this.signal = new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); this.toggled = new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](); } /** * Returns whether this binding is currently pressed * @returns {boolean} */ get pressed() { // Check if the key is down if (this.app.inputMgr.keysDown.has(this.keyCode)) { // Check if it is the top reciever const reciever = this.keyMapper.inputReceiver; return this.app.inputMgr.getTopReciever() === reciever; } return false; } /** * Adds an event listener * @param {function() : void} receiver * @param {object=} scope */ add(receiver, scope = null) { this.signal.add(receiver, scope); } /** * @param {Element} elem * @returns {HTMLElement} the created element, or null if the keybindings are not shown * */ appendLabelToElement(elem) { if (_core_config__WEBPACK_IMPORTED_MODULE_1__["IS_MOBILE"]) { return null; } const spacer = document.createElement("code"); spacer.classList.add("keybinding"); spacer.innerHTML = getStringForKeyCode(this.keyCode); elem.appendChild(spacer); return spacer; } /** * Returns the key code as a nice string */ getKeyCodeString() { return getStringForKeyCode(this.keyCode); } /** * Remvoes all signal receivers */ clearSignalReceivers() { this.signal.removeAll(); } } class KeyActionMapper { /** * * @param {GameRoot} root * @param {InputReceiver} inputReciever */ constructor(root, inputReciever) { this.root = root; this.inputReceiver = inputReciever; inputReciever.keydown.add(this.handleKeydown, this); inputReciever.keyup.add(this.handleKeyup, this); /** @type {Object.} */ this.keybindings = {}; const overrides = root.app.settings.getKeybindingOverrides(); for (const category in KEYMAPPINGS) { for (const key in KEYMAPPINGS[category]) { let payload = Object.assign({}, KEYMAPPINGS[category][key]); if (overrides[key]) { payload.keyCode = overrides[key]; } this.keybindings[key] = new Keybinding(this, this.root.app, payload); } } inputReciever.pageBlur.add(this.onPageBlur, this); inputReciever.destroyed.add(this.cleanup, this); } /** * Returns all keybindings starting with the given id * @param {string} pattern * @returns {Array} */ getKeybindingsStartingWith(pattern) { let result = []; for (const key in this.keybindings) { if (key.startsWith(pattern)) { result.push(this.keybindings[key]); } } return result; } /** * Forwards the given events to the other mapper (used in tooltips) * @param {KeyActionMapper} receiver * @param {Array} bindings */ forward(receiver, bindings) { for (let i = 0; i < bindings.length; ++i) { const key = bindings[i]; this.keybindings[key].signal.add((...args) => receiver.keybindings[key].signal.dispatch(...args)); } } cleanup() { for (const key in this.keybindings) { this.keybindings[key].signal.removeAll(); } } onPageBlur() { // Reset all down states // Find mapping for (const key in this.keybindings) { /** @type {Keybinding} */ const binding = this.keybindings[key]; } } /** * Internal keydown handler * @param {object} param0 * @param {number} param0.keyCode * @param {boolean} param0.shift * @param {boolean} param0.alt * @param {boolean=} param0.initial */ handleKeydown({ keyCode, shift, alt, initial }) { let stop = false; // Find mapping for (const key in this.keybindings) { /** @type {Keybinding} */ const binding = this.keybindings[key]; if (binding.keyCode === keyCode && (initial || binding.repeated)) { /** @type {Signal} */ const signal = this.keybindings[key].signal; if (signal.dispatch() === _core_signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]) { return; } } } if (stop) { return _core_signal__WEBPACK_IMPORTED_MODULE_0__["STOP_PROPAGATION"]; } } /** * Internal keyup handler * @param {object} param0 * @param {number} param0.keyCode * @param {boolean} param0.shift * @param {boolean} param0.alt */ handleKeyup({ keyCode, shift, alt }) { // Empty } /** * Returns a given keybinding * @param {{ keyCode: number }} binding * @returns {Keybinding} */ getBinding(binding) { // @ts-ignore const id = binding.id; window.assert(id, "Not a valid keybinding: " + JSON.stringify(binding)); window.assert(this.keybindings[id], "Keybinding " + id + " not known!"); return this.keybindings[id]; } } /***/ }), /***/ "./src/js/game/logic.js": /*!******************************!*\ !*** ./src/js/game/logic.js ***! \******************************/ /*! exports provided: enumWireEdgeFlag, GameLogic */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumWireEdgeFlag", function() { return enumWireEdgeFlag; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameLogic", function() { return GameLogic; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _systems_wire__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./systems/wire */ "./src/js/game/systems/wire.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./map_chunk_view */ "./src/js/game/map_chunk_view.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("ingame/logic"); /** @enum {number} */ const enumWireEdgeFlag = { empty: 0, connected: 2, }; /** * Typing helper * @typedef {Array<{ * entity: Entity, * slot: import("./components/item_ejector").ItemEjectorSlot, * fromTile: Vector, * toDirection: enumDirection * }>} EjectorsAffectingTile */ /** * Typing helper * @typedef {Array<{ * entity: Entity, * slot: import("./components/item_acceptor").ItemAcceptorSlot, * toTile: Vector, * fromDirection: enumDirection * }>} AcceptorsAffectingTile */ /** * @typedef {{ * acceptors: AcceptorsAffectingTile, * ejectors: EjectorsAffectingTile * }} AcceptorsAndEjectorsAffectingTile */ class GameLogic { /** * * @param {GameRoot} root */ constructor(root) { this.root = root; } /** * Checks if the given entity can be placed * @param {Entity} entity * @param {Vector=} offset Optional, move the entity by the given offset first * @returns {boolean} true if the entity could be placed there */ checkCanPlaceEntity(entity, offset = null) { // Compute area of the building const rect = entity.components.StaticMapEntity.getTileSpaceBounds(); if (offset) { rect.x += offset.x; rect.y += offset.y; } // Check the whole area of the building for (let x = rect.x; x < rect.x + rect.w; ++x) { for (let y = rect.y; y < rect.y + rect.h; ++y) { // Check if there is any direct collision const otherEntity = this.root.map.getLayerContentXY(x, y, entity.layer); if (otherEntity) { const metaClass = otherEntity.components.StaticMapEntity.getMetaBuilding(); if (!metaClass.getIsReplaceable()) { // This one is a direct blocker return false; } } } } // Perform additional placement checks if (this.root.signals.prePlacementCheck.dispatch(entity, offset) === _core_signal__WEBPACK_IMPORTED_MODULE_1__["STOP_PROPAGATION"]) { return false; } return true; } /** * Attempts to place the given building * @param {object} param0 * @param {Vector} param0.origin * @param {number} param0.rotation * @param {number} param0.originalRotation * @param {number} param0.rotationVariant * @param {string} param0.variant * @param {MetaBuilding} param0.building * @returns {Entity} */ tryPlaceBuilding({ origin, rotation, rotationVariant, originalRotation, variant, building }) { const entity = building.createEntity({ root: this.root, origin, rotation, originalRotation, rotationVariant, variant, }); if (this.checkCanPlaceEntity(entity)) { this.freeEntityAreaBeforeBuild(entity); this.root.map.placeStaticEntity(entity); this.root.entityMgr.registerEntity(entity); return entity; } return null; } /** * Removes all entities with a RemovableMapEntityComponent which need to get * removed before placing this entity * @param {Entity} entity */ freeEntityAreaBeforeBuild(entity) { const staticComp = entity.components.StaticMapEntity; const rect = staticComp.getTileSpaceBounds(); // Remove any removeable colliding entities on the same layer for (let x = rect.x; x < rect.x + rect.w; ++x) { for (let y = rect.y; y < rect.y + rect.h; ++y) { const contents = this.root.map.getLayerContentXY(x, y, entity.layer); if (contents) { window.assert( contents.components.StaticMapEntity.getMetaBuilding().getIsReplaceable(), "Tried to replace non-repleaceable entity" ); if (!this.tryDeleteBuilding(contents)) { window.assert(false, "Tried to replace non-repleaceable entity #2"); } } } } // Perform other callbacks this.root.signals.freeEntityAreaBeforeBuild.dispatch(entity); } /** * Performs a bulk operation, not updating caches in the meantime * @param {function} operation */ performBulkOperation(operation) { logger.warn("Running bulk operation ..."); window.assert(!this.root.bulkOperationRunning, "Can not run two bulk operations twice"); this.root.bulkOperationRunning = true; const now = performance.now(); const returnValue = operation(); const duration = performance.now() - now; logger.log("Done in", Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["round2Digits"])(duration), "ms"); window.assert(this.root.bulkOperationRunning, "Bulk operation = false while bulk operation was running"); this.root.bulkOperationRunning = false; this.root.signals.bulkOperationFinished.dispatch(); return returnValue; } /** * Returns whether the given building can get removed * @param {Entity} building */ canDeleteBuilding(building) { const staticComp = building.components.StaticMapEntity; return staticComp.getMetaBuilding().getIsRemovable(); } /** * Tries to delete the given building * @param {Entity} building */ tryDeleteBuilding(building) { if (!this.canDeleteBuilding(building)) { return false; } this.root.map.removeStaticEntity(building); this.root.entityMgr.destroyEntity(building); this.root.entityMgr.processDestroyList(); return true; } /** * * Computes the flag for a given tile * @param {object} param0 * @param {Vector} param0.tile The tile to check at * @param {enumDirection} param0.edge The edge to check for * @param {number} param0.rotation The local tiles base rotation */ computeWireEdgeStatus({ tile, edge, rotation }) { const offset = _core_vector__WEBPACK_IMPORTED_MODULE_3__["enumDirectionToVector"][edge]; const refTile = tile.add(offset); // const angle = enumDirectionToAngle[edge]; // // First, check if this edge can be connected from locally // const canConnectLocally = rotation === angle || (rotation + 180) % 360 === angle; const neighbourStatus = this.getWireEdgeFlag(refTile, edge); if (neighbourStatus === enumWireEdgeFlag.empty) { // It's empty, no point in connecting return false; } if (neighbourStatus === enumWireEdgeFlag.connected) { return true; } } /** * Returns all wire networks this entity participates in on the given tile * @param {Entity} entity * @param {Vector} tile * @returns {Array|null} Null if the entity is never able to be connected at the given tile */ getEntityWireNetworks(entity, tile) { let canConnectAtAll = false; /** @type {Set} */ const networks = new Set(); const staticComp = entity.components.StaticMapEntity; const wireComp = entity.components.Wire; if (wireComp) { canConnectAtAll = true; if (wireComp.linkedNetwork) { networks.add(wireComp.linkedNetwork); } } const tunnelComp = entity.components.WireTunnel; if (tunnelComp) { canConnectAtAll = true; for (let i = 0; i < tunnelComp.linkedNetworks.length; ++i) { networks.add(tunnelComp.linkedNetworks[i]); } } const pinsComp = entity.components.WiredPins; if (pinsComp) { const slots = pinsComp.slots; for (let i = 0; i < slots.length; ++i) { const slot = slots[i]; const slotLocalPos = staticComp.localTileToWorld(slot.pos); if (slotLocalPos.equals(tile)) { canConnectAtAll = true; if (slot.linkedNetwork) { networks.add(slot.linkedNetwork); } } } } if (!canConnectAtAll) { return null; } return Array.from(networks); } /** * Returns if the entities tile *and* his overlay matrix is intersected * @param {Entity} entity * @param {Vector} worldPos */ getIsEntityIntersectedWithMatrix(entity, worldPos) { const staticComp = entity.components.StaticMapEntity; const tile = worldPos.toTileSpace(); if (!staticComp.getTileSpaceBounds().containsPoint(tile.x, tile.y)) { // No intersection at all return; } const data = Object(_building_codes__WEBPACK_IMPORTED_MODULE_4__["getBuildingDataFromCode"])(staticComp.code); const overlayMatrix = data.metaInstance.getSpecialOverlayRenderMatrix( staticComp.rotation, data.rotationVariant, data.variant, entity ); // Always the same if (!overlayMatrix) { return true; } const localPosition = worldPos .divideScalar(_core_config__WEBPACK_IMPORTED_MODULE_9__["globalConfig"].tileSize) .modScalar(1) .multiplyScalar(_map_chunk_view__WEBPACK_IMPORTED_MODULE_10__["CHUNK_OVERLAY_RES"]) .floor(); return !!overlayMatrix[localPosition.x + localPosition.y * 3]; } /** * Gets the flag at the given tile * @param {Vector} tile * @param {enumDirection} edge * @returns {enumWireEdgeFlag} */ getWireEdgeFlag(tile, edge) { // Search for relevant pins const pinEntities = this.root.map.getLayersContentsMultipleXY(tile.x, tile.y); // Go over all entities which could have a pin for (let i = 0; i < pinEntities.length; ++i) { const pinEntity = pinEntities[i]; const pinComp = pinEntity.components.WiredPins; const staticComp = pinEntity.components.StaticMapEntity; // Skip those who don't have pins if (!pinComp) { continue; } // Go over all pins const pins = pinComp.slots; for (let k = 0; k < pinComp.slots.length; ++k) { const pinSlot = pins[k]; const pinLocation = staticComp.localTileToWorld(pinSlot.pos); const pinDirection = staticComp.localDirectionToWorld(pinSlot.direction); // Check if the pin has the right location if (!pinLocation.equals(tile)) { continue; } // Check if the pin has the right direction if (pinDirection !== _core_vector__WEBPACK_IMPORTED_MODULE_3__["enumInvertedDirections"][edge]) { continue; } // Found a pin! return enumWireEdgeFlag.connected; } } // Now check if there's a connectable wire const targetEntity = this.root.map.getTileContent(tile, "wires"); if (!targetEntity) { return enumWireEdgeFlag.empty; } const targetStaticComp = targetEntity.components.StaticMapEntity; // Check if its a crossing const wireTunnelComp = targetEntity.components.WireTunnel; if (wireTunnelComp) { // Check if the crossing is connected if (wireTunnelComp.multipleDirections) { return enumWireEdgeFlag.connected; } else { // Its a coating, check if it matches the direction const referenceDirection = targetStaticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_3__["enumDirection"].top); return referenceDirection === edge || _core_vector__WEBPACK_IMPORTED_MODULE_3__["enumInvertedDirections"][referenceDirection] === edge ? enumWireEdgeFlag.connected : enumWireEdgeFlag.empty; } } // Check if its a wire const wiresComp = targetEntity.components.Wire; if (!wiresComp) { return enumWireEdgeFlag.empty; } // const refAngle = enumDirectionToAngle[edge]; // const refRotation = targetEntity.components.StaticMapEntity.originalRotation; // const canConnectRemotely = refRotation === refAngle || (refRotation + 180) % 360 === refAngle; // Actually connected return enumWireEdgeFlag.connected; } /** * Returns the acceptors and ejectors which affect the current tile * @param {Vector} tile * @returns {AcceptorsAndEjectorsAffectingTile} */ getEjectorsAndAcceptorsAtTile(tile) { /** @type {EjectorsAffectingTile} */ let ejectors = []; /** @type {AcceptorsAffectingTile} */ let acceptors = []; // Well .. please ignore this code! :D for (let dx = -1; dx <= 1; ++dx) { for (let dy = -1; dy <= 1; ++dy) { if (Math.abs(dx) + Math.abs(dy) !== 1) { continue; } const entity = this.root.map.getLayerContentXY(tile.x + dx, tile.y + dy, "regular"); if (entity) { let ejectorSlots = []; let acceptorSlots = []; const staticComp = entity.components.StaticMapEntity; const itemEjector = entity.components.ItemEjector; const itemAcceptor = entity.components.ItemAcceptor; const beltComp = entity.components.Belt; if (itemEjector) { ejectorSlots = itemEjector.slots.slice(); } if (itemAcceptor) { acceptorSlots = itemAcceptor.slots.slice(); } if (beltComp) { const fakeEjectorSlot = beltComp.getFakeEjectorSlot(); const fakeAcceptorSlot = beltComp.getFakeAcceptorSlot(); ejectorSlots.push(fakeEjectorSlot); acceptorSlots.push(fakeAcceptorSlot); } for (let ejectorSlot = 0; ejectorSlot < ejectorSlots.length; ++ejectorSlot) { const slot = ejectorSlots[ejectorSlot]; const wsTile = staticComp.localTileToWorld(slot.pos); const wsDirection = staticComp.localDirectionToWorld(slot.direction); const targetTile = wsTile.add(_core_vector__WEBPACK_IMPORTED_MODULE_3__["enumDirectionToVector"][wsDirection]); if (targetTile.equals(tile)) { ejectors.push({ entity, slot, fromTile: wsTile, toDirection: wsDirection, }); } } for (let acceptorSlot = 0; acceptorSlot < acceptorSlots.length; ++acceptorSlot) { const slot = acceptorSlots[acceptorSlot]; const wsTile = staticComp.localTileToWorld(slot.pos); for (let k = 0; k < slot.directions.length; ++k) { const direction = slot.directions[k]; const wsDirection = staticComp.localDirectionToWorld(direction); const sourceTile = wsTile.add(_core_vector__WEBPACK_IMPORTED_MODULE_3__["enumDirectionToVector"][wsDirection]); if (sourceTile.equals(tile)) { acceptors.push({ entity, slot, toTile: wsTile, fromDirection: wsDirection, }); } } } } } } return { ejectors, acceptors }; } } /***/ }), /***/ "./src/js/game/map.js": /*!****************************!*\ !*** ./src/js/game/map.js ***! \****************************/ /*! exports provided: BaseMap */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseMap", function() { return BaseMap; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); class BaseMap extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["BasicSerializableObject"] { static getId() { return "Map"; } static getSchema() { return { seed: _savegame_serialization__WEBPACK_IMPORTED_MODULE_2__["types"].uint, }; } /** * * @param {GameRoot} root */ constructor(root) { super(); this.root = root; this.seed = 0; /** * Mapping of 'X|Y' to chunk * @type {Map} */ this.chunksById = new Map(); } /** * Returns the given chunk by index * @param {number} chunkX * @param {number} chunkY */ getChunk(chunkX, chunkY, createIfNotExistent = false) { const chunkIdentifier = chunkX + "|" + chunkY; let storedChunk; if ((storedChunk = this.chunksById.get(chunkIdentifier))) { return storedChunk; } if (createIfNotExistent) { const instance = new _map_chunk_view__WEBPACK_IMPORTED_MODULE_5__["MapChunkView"](this.root, chunkX, chunkY); this.chunksById.set(chunkIdentifier, instance); return instance; } return null; } /** * Gets or creates a new chunk if not existent for the given tile * @param {number} tileX * @param {number} tileY * @returns {MapChunkView} */ getOrCreateChunkAtTile(tileX, tileY) { const chunkX = Math.floor(tileX / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkY = Math.floor(tileY / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); return this.getChunk(chunkX, chunkY, true); } /** * Gets a chunk if not existent for the given tile * @param {number} tileX * @param {number} tileY * @returns {MapChunkView?} */ getChunkAtTileOrNull(tileX, tileY) { const chunkX = Math.floor(tileX / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkY = Math.floor(tileY / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); return this.getChunk(chunkX, chunkY, false); } /** * Checks if a given tile is within the map bounds * @param {Vector} tile * @returns {boolean} */ isValidTile(tile) { if (true) { window.assert(tile instanceof _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"], "tile is not a vector"); } return Number.isInteger(tile.x) && Number.isInteger(tile.y); } /** * Returns the tile content of a given tile * @param {Vector} tile * @param {Layer} layer * @returns {Entity} Entity or null */ getTileContent(tile, layer) { if (true) { this.internalCheckTile(tile); } const chunk = this.getChunkAtTileOrNull(tile.x, tile.y); return chunk && chunk.getLayerContentFromWorldCoords(tile.x, tile.y, layer); } /** * Returns the lower layers content of the given tile * @param {number} x * @param {number} y * @returns {BaseItem=} */ getLowerLayerContentXY(x, y) { return this.getOrCreateChunkAtTile(x, y).getLowerLayerFromWorldCoords(x, y); } /** * Returns the tile content of a given tile * @param {number} x * @param {number} y * @param {Layer} layer * @returns {Entity} Entity or null */ getLayerContentXY(x, y, layer) { const chunk = this.getChunkAtTileOrNull(x, y); return chunk && chunk.getLayerContentFromWorldCoords(x, y, layer); } /** * Returns the tile contents of a given tile * @param {number} x * @param {number} y * @returns {Array} Entity or null */ getLayersContentsMultipleXY(x, y) { const chunk = this.getChunkAtTileOrNull(x, y); if (!chunk) { return []; } return chunk.getLayersContentsMultipleFromWorldCoords(x, y); } /** * Checks if the tile is used * @param {Vector} tile * @param {Layer} layer * @returns {boolean} */ isTileUsed(tile, layer) { if (true) { this.internalCheckTile(tile); } const chunk = this.getChunkAtTileOrNull(tile.x, tile.y); return chunk && chunk.getLayerContentFromWorldCoords(tile.x, tile.y, layer) != null; } /** * Checks if the tile is used * @param {number} x * @param {number} y * @param {Layer} layer * @returns {boolean} */ isTileUsedXY(x, y, layer) { const chunk = this.getChunkAtTileOrNull(x, y); return chunk && chunk.getLayerContentFromWorldCoords(x, y, layer) != null; } /** * Sets the tiles content * @param {Vector} tile * @param {Entity} entity */ setTileContent(tile, entity) { if (true) { this.internalCheckTile(tile); } this.getOrCreateChunkAtTile(tile.x, tile.y).setLayerContentFromWorldCords( tile.x, tile.y, entity, entity.layer ); const staticComponent = entity.components.StaticMapEntity; window.assert(staticComponent, "Can only place static map entities in tiles"); } /** * Places an entity with the StaticMapEntity component * @param {Entity} entity */ placeStaticEntity(entity) { window.assert(entity.components.StaticMapEntity, "Entity is not static"); const staticComp = entity.components.StaticMapEntity; const rect = staticComp.getTileSpaceBounds(); for (let dx = 0; dx < rect.w; ++dx) { for (let dy = 0; dy < rect.h; ++dy) { const x = rect.x + dx; const y = rect.y + dy; this.getOrCreateChunkAtTile(x, y).setLayerContentFromWorldCords(x, y, entity, entity.layer); } } } /** * Removes an entity with the StaticMapEntity component * @param {Entity} entity */ removeStaticEntity(entity) { window.assert(entity.components.StaticMapEntity, "Entity is not static"); const staticComp = entity.components.StaticMapEntity; const rect = staticComp.getTileSpaceBounds(); for (let dx = 0; dx < rect.w; ++dx) { for (let dy = 0; dy < rect.h; ++dy) { const x = rect.x + dx; const y = rect.y + dy; this.getOrCreateChunkAtTile(x, y).setLayerContentFromWorldCords(x, y, null, entity.layer); } } } // Internal /** * Checks a given tile for validty * @param {Vector} tile */ internalCheckTile(tile) { window.assert(tile instanceof _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"], "tile is not a vector: " + tile); window.assert(tile.x % 1 === 0, "Tile X is not a valid integer: " + tile.x); window.assert(tile.y % 1 === 0, "Tile Y is not a valid integer: " + tile.y); } } /***/ }), /***/ "./src/js/game/map_chunk.js": /*!**********************************!*\ !*** ./src/js/game/map_chunk.js ***! \**********************************/ /*! exports provided: MapChunk */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapChunk", function() { return MapChunk; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rng__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/rng */ "./src/js/core/rng.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./colors */ "./src/js/game/colors.js"); /* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./shapes */ "./src/js/game/shapes.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../core/rectangle */ "./src/js/core/rectangle.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("map_chunk"); class MapChunk { /** * * @param {GameRoot} root * @param {number} x * @param {number} y */ constructor(root, x, y) { this.root = root; this.x = x; this.y = y; this.tileX = x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; this.tileY = y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; /** * Stores the contents of the lower (= map resources) layer * @type {Array>} */ this.lowerLayer = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["make2DUndefinedArray"])(_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); /** * Stores the contents of the regular layer * @type {Array>} */ this.contents = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["make2DUndefinedArray"])(_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); /** * Stores the contents of the wires layer * @type {Array>} */ this.wireContents = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["make2DUndefinedArray"])(_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); /** @type {Array} */ this.containedEntities = []; /** * World space rectangle, can be used for culling */ this.worldSpaceRectangle = new _core_rectangle__WEBPACK_IMPORTED_MODULE_12__["Rectangle"]( this.tileX * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, this.tileY * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize ); /** * Tile space rectangle, can be used for culling */ this.tileSpaceRectangle = new _core_rectangle__WEBPACK_IMPORTED_MODULE_12__["Rectangle"]( this.tileX, this.tileY, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize ); /** * Which entities this chunk contains, sorted by layer * @type {Record>} */ this.containedEntitiesByLayer = { regular: [], wires: [], }; /** * Store which patches we have so we can render them in the overview * @type {Array<{pos: Vector, item: BaseItem, size: number }>} */ this.patches = []; this.generateLowerLayer(); } /** * Generates a patch filled with the given item * @param {RandomNumberGenerator} rng * @param {number} patchSize * @param {BaseItem} item * @param {number=} overrideX Override the X position of the patch * @param {number=} overrideY Override the Y position of the patch */ internalGeneratePatch(rng, patchSize, item, overrideX = null, overrideY = null) { const border = Math.ceil(patchSize / 2 + 3); // Find a position within the chunk which is not blocked let patchX = rng.nextIntRange(border, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize - border - 1); let patchY = rng.nextIntRange(border, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize - border - 1); if (overrideX !== null) { patchX = overrideX; } if (overrideY !== null) { patchY = overrideY; } const avgPos = new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](0, 0); let patchesDrawn = 0; // Each patch consists of multiple circles const numCircles = patchSize; for (let i = 0; i <= numCircles; ++i) { // Determine circle parameters const circleRadius = Math.min(1 + i, patchSize); const circleRadiusSquare = circleRadius * circleRadius; const circleOffsetRadius = (numCircles - i) / 2 + 2; // We draw an elipsis actually const circleScaleX = rng.nextRange(0.9, 1.1); const circleScaleY = rng.nextRange(0.9, 1.1); const circleX = patchX + rng.nextIntRange(-circleOffsetRadius, circleOffsetRadius); const circleY = patchY + rng.nextIntRange(-circleOffsetRadius, circleOffsetRadius); for (let dx = -circleRadius * circleScaleX - 2; dx <= circleRadius * circleScaleX + 2; ++dx) { for (let dy = -circleRadius * circleScaleY - 2; dy <= circleRadius * circleScaleY + 2; ++dy) { const x = Math.round(circleX + dx); const y = Math.round(circleY + dy); if (x >= 0 && x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize && y >= 0 && y <= _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize) { const originalDx = dx / circleScaleX; const originalDy = dy / circleScaleY; if (originalDx * originalDx + originalDy * originalDy <= circleRadiusSquare) { if (!this.lowerLayer[x][y]) { this.lowerLayer[x][y] = item; ++patchesDrawn; avgPos.x += x; avgPos.y += y; } } } else { // logger.warn("Tried to spawn resource out of chunk"); } } } } this.patches.push({ pos: avgPos.divideScalar(patchesDrawn), item, size: patchSize, }); } /** * Generates a color patch * @param {RandomNumberGenerator} rng * @param {number} colorPatchSize * @param {number} distanceToOriginInChunks */ internalGenerateColorPatch(rng, colorPatchSize, distanceToOriginInChunks) { // First, determine available colors let availableColors = []; for (let c in _colors__WEBPACK_IMPORTED_MODULE_6__["enumColors"]) { c = _colors__WEBPACK_IMPORTED_MODULE_6__["enumColors"][c]; if ( _colors__WEBPACK_IMPORTED_MODULE_6__["allColorData"][c] && _colors__WEBPACK_IMPORTED_MODULE_6__["allColorData"][c].spawnable && _colors__WEBPACK_IMPORTED_MODULE_6__["allColorData"][c].minDistance <= distanceToOriginInChunks ) { availableColors.push(c); } } this.internalGeneratePatch(rng, colorPatchSize, _items_color_item__WEBPACK_IMPORTED_MODULE_9__["COLOR_ITEM_SINGLETONS"][rng.choice(availableColors)]); } /** * Generates a shape patch * @param {RandomNumberGenerator} rng * @param {number} shapePatchSize * @param {number} distanceToOriginInChunks */ internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks) { /** @type {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} */ let quads = null; let weights = {}; for (let s in _shapes__WEBPACK_IMPORTED_MODULE_7__["allShapeData"]) { const data = _shapes__WEBPACK_IMPORTED_MODULE_7__["allShapeData"][s]; if (data.disabled || !data.spawnable || distanceToOriginInChunks < data.minDistance) { continue; } const chance = Math.round( Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["clamp"])( data.minChance + (distanceToOriginInChunks - data.minDistance) * data.distChance, 0, data.maxChance ) ); if (chance) { weights[data.id] = chance; } } quads = [ this.internalGenerateRandomSubShape(rng, weights), this.internalGenerateRandomSubShape(rng, weights), this.internalGenerateRandomSubShape(rng, weights), this.internalGenerateRandomSubShape(rng, weights), ]; if (distanceToOriginInChunks < 10) { // Initial chunk patches always have the same shape quads = [quads[0], quads[0], quads[0], quads[0]]; } else if (distanceToOriginInChunks < 15) { // Later patches can also have mixed ones quads = [quads[0], quads[0], quads[1], quads[1]]; } else { // if (quads[0] == quads[2] && quads[0] != quads[3] && quads[0] != quads[1]) { // quads = [quads[0], quads[2], quads[1], quads[3]]; // } // if (quads[1] == quads[3] && quads[1] != quads[0] && quads[1] != quads[2]) { // quads = [quads[0], quads[2], quads[1], quads[3]]; // } } if ( quads.filter(q => q == quads[0]).length > _shapes__WEBPACK_IMPORTED_MODULE_7__["allShapeData"][quads[0]].maxQuarters || quads.filter(q => q == quads[1]).length > _shapes__WEBPACK_IMPORTED_MODULE_7__["allShapeData"][quads[1]].maxQuarters || quads.filter(q => q == quads[2]).length > _shapes__WEBPACK_IMPORTED_MODULE_7__["allShapeData"][quads[2]].maxQuarters ) { return this.internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks); } let colors = quads.map(q => _shapes__WEBPACK_IMPORTED_MODULE_7__["allShapeData"][q].spawnColor); const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapesAndColors(quads, colors); this.internalGeneratePatch( rng, shapePatchSize, this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition) ); } /** * Chooses a random shape with the given weights * @param {RandomNumberGenerator} rng * @param {Object.} weights * @returns {enumSubShape} */ internalGenerateRandomSubShape(rng, weights) { // @ts-ignore const sum = Object.values(weights).reduce((a, b) => a + b, 0); const chosenNumber = rng.nextIntRange(0, sum - 1); let accumulated = 0; for (const key in weights) { const weight = weights[key]; if (accumulated + weight > chosenNumber) { return key; } accumulated += weight; } logger.error("Failed to find matching shape in chunk generation"); return _shape_definition__WEBPACK_IMPORTED_MODULE_11__["enumSubShape"].circle; } /** * Generates the lower layer "terrain" */ generateLowerLayer() { const rng = new _core_rng__WEBPACK_IMPORTED_MODULE_2__["RandomNumberGenerator"](this.x + "|" + this.y + "|" + this.root.map.seed); const rng1 = new _core_rng__WEBPACK_IMPORTED_MODULE_2__["RandomNumberGenerator"]("patch1" + this.x + "|" + this.y + "|" + this.root.map.seed); const rng2 = new _core_rng__WEBPACK_IMPORTED_MODULE_2__["RandomNumberGenerator"]("patch2" + this.x + "|" + this.y + "|" + this.root.map.seed); if (this.generatePredefined(rng)) { return; } const chunkCenter = new _core_vector__WEBPACK_IMPORTED_MODULE_4__["Vector"](this.x, this.y).addScalar(0.5); const distanceToOriginInChunks = Math.round(chunkCenter.length()); // Determine how likely it is that there is a color patch const colorPatchChance = 0.9 - Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["clamp"])(distanceToOriginInChunks / 25, 0, 1) * 0.5; if (rng.next() < colorPatchChance / 4) { const colorPatchSize = Math.max(2, Math.round(1 + Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["clamp"])(distanceToOriginInChunks / 8, 0, 4))); this.internalGenerateColorPatch(rng, colorPatchSize, distanceToOriginInChunks); } // Determine how likely it is that there is a shape patch const shapePatchChance = 0.9 - Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["clamp"])(distanceToOriginInChunks / 25, 0, 1) * 0.5; if (rng.next() < shapePatchChance / 4) { const shapePatchSize = Math.max(2, Math.round(1 + Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["clamp"])(distanceToOriginInChunks / 8, 0, 4))); this.internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks); } } /** * Checks if this chunk has predefined contents, and if so returns true and generates the * predefined contents * @param {RandomNumberGenerator} rng * @returns {boolean} */ generatePredefined(rng) { if (this.x === 0 && this.y === 0) { this.internalGeneratePatch(rng, 2, _items_color_item__WEBPACK_IMPORTED_MODULE_9__["COLOR_ITEM_SINGLETONS"][_colors__WEBPACK_IMPORTED_MODULE_6__["enumColors"].red], 7, 7); return true; } if (this.x === -1 && this.y === 0) { const item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey("CuCuCuCu"); this.internalGeneratePatch(rng, 2, item, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize - 9, 7); return true; } if (this.x === 0 && this.y === -1) { const item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey("RuRuRuRu"); this.internalGeneratePatch(rng, 2, item, 5, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize - 7); return true; } if (this.x === -1 && this.y === -1) { this.internalGeneratePatch(rng, 2, _items_color_item__WEBPACK_IMPORTED_MODULE_9__["COLOR_ITEM_SINGLETONS"][_colors__WEBPACK_IMPORTED_MODULE_6__["enumColors"].green]); return true; } if (this.x === 5 && this.y === -2) { const item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey("SuSuSuSu"); this.internalGeneratePatch(rng, 2, item, 5, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize - 7); return true; } return false; } /** * * @param {number} worldX * @param {number} worldY * @returns {BaseItem=} */ getLowerLayerFromWorldCoords(worldX, worldY) { const localX = worldX - this.tileX; const localY = worldY - this.tileY; window.assert(localX >= 0, "Local X is < 0"); window.assert(localY >= 0, "Local Y is < 0"); window.assert(localX < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local X is >= chunk size"); window.assert(localY < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local Y is >= chunk size"); return this.lowerLayer[localX][localY] || null; } /** * Returns the contents of this chunk from the given world space coordinates * @param {number} worldX * @param {number} worldY * @returns {Entity=} */ getTileContentFromWorldCoords(worldX, worldY) { const localX = worldX - this.tileX; const localY = worldY - this.tileY; window.assert(localX >= 0, "Local X is < 0"); window.assert(localY >= 0, "Local Y is < 0"); window.assert(localX < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local X is >= chunk size"); window.assert(localY < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local Y is >= chunk size"); return this.contents[localX][localY] || null; } /** * Returns the contents of this chunk from the given world space coordinates * @param {number} worldX * @param {number} worldY * @param {Layer} layer * @returns {Entity=} */ getLayerContentFromWorldCoords(worldX, worldY, layer) { const localX = worldX - this.tileX; const localY = worldY - this.tileY; window.assert(localX >= 0, "Local X is < 0"); window.assert(localY >= 0, "Local Y is < 0"); window.assert(localX < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local X is >= chunk size"); window.assert(localY < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local Y is >= chunk size"); if (layer === "regular") { return this.contents[localX][localY] || null; } else { return this.wireContents[localX][localY] || null; } } /** * Returns the contents of this chunk from the given world space coordinates * @param {number} worldX * @param {number} worldY * @returns {Array} */ getLayersContentsMultipleFromWorldCoords(worldX, worldY) { const localX = worldX - this.tileX; const localY = worldY - this.tileY; window.assert(localX >= 0, "Local X is < 0"); window.assert(localY >= 0, "Local Y is < 0"); window.assert(localX < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local X is >= chunk size"); window.assert(localY < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local Y is >= chunk size"); const regularContent = this.contents[localX][localY]; const wireContent = this.wireContents[localX][localY]; const result = []; if (regularContent) { result.push(regularContent); } if (wireContent) { result.push(wireContent); } return result; } /** * Returns the chunks contents from the given local coordinates * @param {number} localX * @param {number} localY * @returns {Entity=} */ getTileContentFromLocalCoords(localX, localY) { window.assert(localX >= 0, "Local X is < 0"); window.assert(localY >= 0, "Local Y is < 0"); window.assert(localX < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local X is >= chunk size"); window.assert(localY < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local Y is >= chunk size"); return this.contents[localX][localY] || null; } /** * Sets the chunks contents * @param {number} tileX * @param {number} tileY * @param {Entity=} contents * @param {Layer} layer */ setLayerContentFromWorldCords(tileX, tileY, contents, layer) { const localX = tileX - this.tileX; const localY = tileY - this.tileY; window.assert(localX >= 0, "Local X is < 0"); window.assert(localY >= 0, "Local Y is < 0"); window.assert(localX < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local X is >= chunk size"); window.assert(localY < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, "Local Y is >= chunk size"); let oldContents; if (layer === "regular") { oldContents = this.contents[localX][localY]; } else { oldContents = this.wireContents[localX][localY]; } window.assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY); if (oldContents) { // Remove from list (the old contents must be reigstered) Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["fastArrayDeleteValueIfContained"])(this.containedEntities, oldContents); Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["fastArrayDeleteValueIfContained"])(this.containedEntitiesByLayer[layer], oldContents); } if (layer === "regular") { this.contents[localX][localY] = contents; } else { this.wireContents[localX][localY] = contents; } if (contents) { if (this.containedEntities.indexOf(contents) < 0) { this.containedEntities.push(contents); } if (this.containedEntitiesByLayer[layer].indexOf(contents) < 0) { this.containedEntitiesByLayer[layer].push(contents); } } } } /***/ }), /***/ "./src/js/game/map_chunk_view.js": /*!***************************************!*\ !*** ./src/js/game/map_chunk_view.js ***! \***************************************/ /*! exports provided: CHUNK_OVERLAY_RES, MapChunkView */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CHUNK_OVERLAY_RES", function() { return CHUNK_OVERLAY_RES; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapChunkView", function() { return MapChunkView; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _map_chunk__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./map_chunk */ "./src/js/game/map_chunk.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./theme */ "./src/js/game/theme.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); const CHUNK_OVERLAY_RES = 3; class MapChunkView extends _map_chunk__WEBPACK_IMPORTED_MODULE_4__["MapChunk"] { /** * * @param {GameRoot} root * @param {number} x * @param {number} y */ constructor(root, x, y) { super(root, x, y); /** * Whenever something changes, we increase this number - so we know we need to redraw */ this.renderIteration = 0; this.markDirty(); } /** * Marks this chunk as dirty, rerendering all caches */ markDirty() { ++this.renderIteration; this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration; } /** * Draws the background layer * @param {DrawParameters} parameters */ drawBackgroundLayer(parameters) { const systems = this.root.systemMgr.systems; systems.mapResources.drawChunk(parameters, this); systems.beltUnderlays.drawChunk(parameters, this); systems.belt.drawChunk(parameters, this); } /** * Draws the foreground layer * @param {DrawParameters} parameters */ drawForegroundLayer(parameters) { const systems = this.root.systemMgr.systems; systems.itemEjector.drawChunk(parameters, this); systems.itemAcceptor.drawChunk(parameters, this); systems.miner.drawChunk(parameters, this); systems.staticMapEntities.drawChunk(parameters, this); systems.lever.drawChunk(parameters, this); systems.display.drawChunk(parameters, this); systems.storage.drawChunk(parameters, this); for (let custom of _custom_modBuildings__WEBPACK_IMPORTED_MODULE_8__["allCustomBuildingData"]) { if (custom.system) { systems[custom.id].drawChunk(parameters, this); } } } /** * Overlay * @param {DrawParameters} parameters */ drawOverlay(parameters) { const overlaySize = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize * CHUNK_OVERLAY_RES; const sprite = this.root.buffers.getForKey({ key: "chunk@" + this.root.currentLayer, subKey: this.renderKey, w: overlaySize, h: overlaySize, dpi: 1, redrawMethod: this.generateOverlayBuffer.bind(this), }); const dims = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize; // Draw chunk "pixel" art parameters.context.imageSmoothingEnabled = false; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_7__["drawSpriteClipped"])({ parameters, sprite, x: this.x * dims, y: this.y * dims, w: dims, h: dims, originalW: overlaySize, originalH: overlaySize, }); parameters.context.imageSmoothingEnabled = true; // Draw patch items if (this.root.currentLayer === "regular") { for (let i = 0; i < this.patches.length; ++i) { const patch = this.patches[i]; const destX = this.x * dims + patch.pos.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const destY = this.y * dims + patch.pos.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const diameter = Math.min(80, 30 / parameters.zoomLevel); patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter); } } } /** * * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h * @param {number} dpi */ generateOverlayBuffer(canvas, context, w, h, dpi) { context.fillStyle = this.containedEntities.length > 0 ? _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].map.chunkOverview.filled : _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].map.chunkOverview.empty; context.fillRect(0, 0, w, h); for (let x = 0; x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++x) { const lowerArray = this.lowerLayer[x]; const upperArray = this.contents[x]; for (let y = 0; y < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++y) { const upperContent = upperArray[y]; if (upperContent) { const staticComp = upperContent.components.StaticMapEntity; const data = Object(_building_codes__WEBPACK_IMPORTED_MODULE_2__["getBuildingDataFromCode"])(staticComp.code); const metaBuilding = data.metaInstance; const overlayMatrix = metaBuilding.getSpecialOverlayRenderMatrix( staticComp.rotation, data.rotationVariant, data.variant, upperContent ); if (overlayMatrix) { // Draw lower content first since it "shines" through const lowerContent = lowerArray[y]; if (lowerContent) { context.fillStyle = lowerContent.getBackgroundColorAsResource(); context.fillRect( x * CHUNK_OVERLAY_RES, y * CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES ); } context.fillStyle = metaBuilding.getSilhouetteColor(); for (let dx = 0; dx < 3; ++dx) { for (let dy = 0; dy < 3; ++dy) { const isFilled = overlayMatrix[dx + dy * 3]; if (isFilled) { context.fillRect( x * CHUNK_OVERLAY_RES + dx, y * CHUNK_OVERLAY_RES + dy, 1, 1 ); } } } continue; } else { context.fillStyle = metaBuilding.getSilhouetteColor(); context.fillRect( x * CHUNK_OVERLAY_RES, y * CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES ); continue; } } const lowerContent = lowerArray[y]; if (lowerContent) { context.fillStyle = lowerContent.getBackgroundColorAsResource(); context.fillRect( x * CHUNK_OVERLAY_RES, y * CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES ); } } } if (this.root.currentLayer === "wires") { // Draw wires overlay context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_6__["THEME"].map.wires.overlayColor; context.fillRect(0, 0, w, h); for (let x = 0; x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++x) { const wiresArray = this.wireContents[x]; for (let y = 0; y < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++y) { const content = wiresArray[y]; if (!content) { continue; } MapChunkView.drawSingleWiresOverviewTile({ context, x: x * CHUNK_OVERLAY_RES, y: y * CHUNK_OVERLAY_RES, entity: content, tileSizePixels: CHUNK_OVERLAY_RES, }); } } } } /** * @param {object} param0 * @param {CanvasRenderingContext2D} param0.context * @param {number} param0.x * @param {number} param0.y * @param {Entity} param0.entity * @param {number} param0.tileSizePixels * @param {string=} param0.overrideColor Optionally override the color to be rendered */ static drawSingleWiresOverviewTile({ context, x, y, entity, tileSizePixels, overrideColor = null }) { const staticComp = entity.components.StaticMapEntity; const data = Object(_building_codes__WEBPACK_IMPORTED_MODULE_2__["getBuildingDataFromCode"])(staticComp.code); const metaBuilding = data.metaInstance; const overlayMatrix = metaBuilding.getSpecialOverlayRenderMatrix( staticComp.rotation, data.rotationVariant, data.variant, entity ); context.fillStyle = overrideColor || metaBuilding.getSilhouetteColor(); if (overlayMatrix) { for (let dx = 0; dx < 3; ++dx) { for (let dy = 0; dy < 3; ++dy) { const isFilled = overlayMatrix[dx + dy * 3]; if (isFilled) { context.fillRect( x + (dx * tileSizePixels) / CHUNK_OVERLAY_RES, y + (dy * tileSizePixels) / CHUNK_OVERLAY_RES, tileSizePixels / CHUNK_OVERLAY_RES, tileSizePixels / CHUNK_OVERLAY_RES ); } } } } else { context.fillRect(x, y, tileSizePixels, tileSizePixels); } } /** * Draws the wires layer * @param {DrawParameters} parameters */ drawWiresForegroundLayer(parameters) { const systems = this.root.systemMgr.systems; systems.wire.drawChunk(parameters, this); systems.staticMapEntities.drawWiresChunk(parameters, this); systems.wiredPins.drawChunk(parameters, this); } } /***/ }), /***/ "./src/js/game/map_view.js": /*!*********************************!*\ !*** ./src/js/game/map_view.js ***! \*********************************/ /*! exports provided: MapView */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapView", function() { return MapView; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./map */ "./src/js/game/map.js"); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./theme */ "./src/js/game/theme.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./map_chunk_view */ "./src/js/game/map_chunk_view.js"); /** * This is the view of the map, it extends the map which is the raw model and allows * to draw it */ class MapView extends _map__WEBPACK_IMPORTED_MODULE_2__["BaseMap"] { constructor(root) { super(root); /** * DPI of the background cache images, required in some places */ this.backgroundCacheDPI = 2; /** * The cached background sprite, containing the flat background * @type {HTMLCanvasElement} */ this.cachedBackgroundCanvas = null; /** @type {CanvasRenderingContext2D} */ this.cachedBackgroundContext = null; /** * Cached pattern of the stripes background * @type {CanvasPattern} */ this.cachedBackgroundPattern = null; this.internalInitializeCachedBackgroundCanvases(); this.root.signals.aboutToDestruct.add(this.cleanup, this); this.root.signals.entityAdded.add(this.onEntityChanged, this); this.root.signals.entityDestroyed.add(this.onEntityChanged, this); this.root.signals.entityChanged.add(this.onEntityChanged, this); } cleanup() { Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_3__["freeCanvas"])(this.cachedBackgroundCanvas); this.cachedBackgroundCanvas = null; this.cachedBackgroundPattern = null; } /** * Called when an entity was added, removed or changed * @param {Entity} entity */ onEntityChanged(entity) { const staticComp = entity.components.StaticMapEntity; if (staticComp) { const rect = staticComp.getTileSpaceBounds(); for (let x = rect.x; x <= rect.right(); ++x) { for (let y = rect.y; y <= rect.bottom(); ++y) { this.root.map.getOrCreateChunkAtTile(x, y).markDirty(); } } } } /** * Draws all static entities like buildings etc. * @param {DrawParameters} drawParameters */ drawStaticEntityDebugOverlays(drawParameters) { const cullRange = drawParameters.visibleRect.toTileCullRectangle(); const top = cullRange.top(); const right = cullRange.right(); const bottom = cullRange.bottom(); const left = cullRange.left(); const border = 1; const minY = top - border; const maxY = bottom + border; const minX = left - border; const maxX = right + border - 1; // Render y from top down for proper blending for (let y = minY; y <= maxY; ++y) { for (let x = minX; x <= maxX; ++x) { // const content = this.tiles[x][y]; const chunk = this.getChunkAtTileOrNull(x, y); if (!chunk) { continue; } const content = chunk.getTileContentFromWorldCoords(x, y); if (content) { let isBorder = x <= left - 1 || x >= right + 1 || y <= top - 1 || y >= bottom + 1; if (!isBorder) { content.drawDebugOverlays(drawParameters); } } } } } /** * Initializes all canvases used for background rendering */ internalInitializeCachedBackgroundCanvases() { // Background canvas const dims = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const dpi = this.backgroundCacheDPI; const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_3__["makeOffscreenBuffer"])(dims * dpi, dims * dpi, { smooth: false, label: "map-cached-bg", }); context.scale(dpi, dpi); context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_5__["THEME"].map.background; context.fillRect(0, 0, dims, dims); const borderWidth = _theme__WEBPACK_IMPORTED_MODULE_5__["THEME"].map.gridLineWidth; context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_5__["THEME"].map.grid; context.fillRect(0, 0, dims, borderWidth); context.fillRect(0, borderWidth, borderWidth, dims); context.fillRect(dims - borderWidth, borderWidth, borderWidth, dims - 2 * borderWidth); context.fillRect(borderWidth, dims - borderWidth, dims, borderWidth); this.cachedBackgroundCanvas = canvas; this.cachedBackgroundContext = context; } /** * Draws the maps foreground * @param {DrawParameters} parameters */ drawForeground(parameters) { this.drawVisibleChunks(parameters, _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__["MapChunkView"].prototype.drawForegroundLayer); } /** * Calls a given method on all given chunks * @param {DrawParameters} parameters * @param {function} method */ drawVisibleChunks(parameters, method) { const cullRange = parameters.visibleRect.allScaled(1 / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize); const top = cullRange.top(); const right = cullRange.right(); const bottom = cullRange.bottom(); const left = cullRange.left(); const border = 0; const minY = top - border; const maxY = bottom + border; const minX = left - border; const maxX = right + border; const chunkStartX = Math.floor(minX / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkStartY = Math.floor(minY / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkEndX = Math.floor(maxX / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkEndY = Math.floor(maxY / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); // Render y from top down for proper blending for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) { for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { const chunk = this.root.map.getChunk(chunkX, chunkY, true); method.call(chunk, parameters); } } } /** * Draws the wires foreground * @param {DrawParameters} parameters */ drawWiresForegroundLayer(parameters) { this.drawVisibleChunks(parameters, _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__["MapChunkView"].prototype.drawWiresForegroundLayer); } /** * Draws the map overlay * @param {DrawParameters} parameters */ drawOverlay(parameters) { this.drawVisibleChunks(parameters, _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__["MapChunkView"].prototype.drawOverlay); } /** * Draws the map background * @param {DrawParameters} parameters */ drawBackground(parameters) { if (!this.cachedBackgroundPattern) { this.cachedBackgroundPattern = parameters.context.createPattern( this.cachedBackgroundCanvas, "repeat" ); } if (!this.root.app.settings.getAllSettings().disableTileGrid) { const dpi = this.backgroundCacheDPI; parameters.context.scale(1 / dpi, 1 / dpi); parameters.context.fillStyle = this.cachedBackgroundPattern; parameters.context.fillRect( parameters.visibleRect.x * dpi, parameters.visibleRect.y * dpi, parameters.visibleRect.w * dpi, parameters.visibleRect.h * dpi ); parameters.context.scale(dpi, dpi); } this.drawVisibleChunks(parameters, _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__["MapChunkView"].prototype.drawBackgroundLayer); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.showChunkBorders) { const cullRange = parameters.visibleRect.toTileCullRectangle(); const top = cullRange.top(); const right = cullRange.right(); const bottom = cullRange.bottom(); const left = cullRange.left(); const border = 1; const minY = top - border; const maxY = bottom + border; const minX = left - border; const maxX = right + border - 1; const chunkStartX = Math.floor(minX / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkStartY = Math.floor(minY / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkEndX = Math.ceil(maxX / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); const chunkEndY = Math.ceil(maxY / _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize); for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) { for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { parameters.context.fillStyle = "#ffaaaa"; parameters.context.fillRect( chunkX * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, chunkY * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, 3 ); parameters.context.fillRect( chunkX * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, chunkY * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, 3, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize ); } } } } } /***/ }), /***/ "./src/js/game/meta_building.js": /*!**************************************!*\ !*** ./src/js/game/meta_building.js ***! \**************************************/ /*! exports provided: defaultBuildingVariant, MetaBuilding */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultBuildingVariant", function() { return defaultBuildingVariant; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MetaBuilding", function() { return MetaBuilding; }); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_sprites__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/sprites */ "./src/js/core/sprites.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _components_static_map_entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/static_map_entity */ "./src/js/game/components/static_map_entity.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./entity */ "./src/js/game/entity.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./building_codes */ "./src/js/game/building_codes.js"); const defaultBuildingVariant = "default"; class MetaBuilding { /** * * @param {string} id Building id */ constructor(id) { this.id = id; } /** * Returns the id of this building */ getId() { return this.id; } /** * Returns the edit layer of the building * @returns {Layer} */ getLayer() { return "regular"; } /** * Should return the dimensions of the building */ getDimensions(variant = defaultBuildingVariant) { return new _core_vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](1, 1); } /** * Returns whether the building has the direction lock switch available */ getHasDirectionLockAvailable() { return false; } /** * Whether to stay in placement mode after having placed a building */ getStayInPlacementMode() { return false; } /** * Can return a special interlaved 9 elements overlay matrix for rendering * @param {number} rotation * @param {number} rotationVariant * @param {string} variant * @param {Entity} entity * @returns {Array|null} */ getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { return null; } /** * Should return additional statistics about this building * @param {GameRoot} root * @param {string} variant * @returns {Array<[string, string]>} */ getAdditionalStatistics(root, variant) { return []; } /** * Returns whether this building can get replaced */ getIsReplaceable() { return false; } /** * Whether to flip the orientation after a building has been placed - useful * for tunnels. */ getFlipOrientationAfterPlacement() { return false; } /** * Whether to show a preview of the wires layer when placing the building */ getShowWiresLayerPreview() { return false; } /** * Whether to rotate automatically in the dragging direction while placing * @param {string} variant */ getRotateAutomaticallyWhilePlacing(variant) { return false; } /** * Returns whether this building is removable * @returns {boolean} */ getIsRemovable() { return true; } /** * Returns the placement sound * @returns {string} */ getPlacementSound() { return _platform_sound__WEBPACK_IMPORTED_MODULE_3__["SOUNDS"].placeBuilding; } /** * @param {GameRoot} root */ getAvailableVariants(root) { return [defaultBuildingVariant]; } /** * Returns a preview sprite * @returns {AtlasSprite} */ getPreviewSprite(rotationVariant = 0, variant = defaultBuildingVariant) { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite( "sprites/buildings/" + this.id + (variant === defaultBuildingVariant ? "" : "-" + variant) + ".png" ); } /** * Returns a sprite for blueprints * @returns {AtlasSprite} */ getBlueprintSprite(rotationVariant = 0, variant = defaultBuildingVariant) { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite( "sprites/blueprints/" + this.id + (variant === defaultBuildingVariant ? "" : "-" + variant) + ".png" ); } /** * Returns whether this building is rotateable * @param {string} variant * @returns {boolean} */ getIsRotateable(variant) { return true; } /** * Returns whether this building is unlocked for the given game * @param {GameRoot} root */ getIsUnlocked(root) { return true; } /** * Should return a silhouette color for the map overview or null if not set */ getSilhouetteColor() { return null; } /** * Should return false if the pins are already included in the sprite of the building * @returns {boolean} */ getRenderPins() { return true; } /** * Creates the entity without placing it * @param {object} param0 * @param {GameRoot} param0.root * @param {Vector} param0.origin Origin tile * @param {number=} param0.rotation Rotation * @param {number} param0.originalRotation Original Rotation * @param {number} param0.rotationVariant Rotation variant * @param {string} param0.variant */ createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) { const entity = new _entity__WEBPACK_IMPORTED_MODULE_5__["Entity"](root); entity.layer = this.getLayer(); entity.addComponent( new _components_static_map_entity__WEBPACK_IMPORTED_MODULE_4__["StaticMapEntityComponent"]({ origin: new _core_vector__WEBPACK_IMPORTED_MODULE_2__["Vector"](origin.x, origin.y), rotation, originalRotation, tileSize: this.getDimensions(variant).copy(), code: Object(_building_codes__WEBPACK_IMPORTED_MODULE_7__["getCodeFromBuildingData"])(this, variant, rotationVariant), }) ); this.setupEntityComponents(entity, root); this.updateVariants(entity, rotationVariant, variant); return entity; } /** * Returns the sprite for a given variant * @param {number} rotationVariant * @param {string} variant * @returns {AtlasSprite} */ getSprite(rotationVariant, variant) { return _core_loader__WEBPACK_IMPORTED_MODULE_0__["Loader"].getSprite( "sprites/buildings/" + this.id + (variant === defaultBuildingVariant ? "" : "-" + variant) + ".png" ); } /** * Should compute the optimal rotation variant on the given tile * @param {object} param0 * @param {GameRoot} param0.root * @param {Vector} param0.tile * @param {number} param0.rotation * @param {string} param0.variant * @param {Layer} param0.layer * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }} */ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { if (!this.getIsRotateable(variant)) { return { rotation: 0, rotationVariant: 0, }; } return { rotation, rotationVariant: 0, }; } /** * Should update the entity to match the given variants * @param {Entity} entity * @param {number} rotationVariant * @param {string} variant */ updateVariants(entity, rotationVariant, variant) {} // PRIVATE INTERFACE /** * Should setup the entity components * @param {Entity} entity * @param {GameRoot} root */ setupEntityComponents(entity, root) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } } /***/ }), /***/ "./src/js/game/meta_building_registry.js": /*!***********************************************!*\ !*** ./src/js/game/meta_building_registry.js ***! \***********************************************/ /*! exports provided: initMetaBuildingRegistry, initBuildingCodesAfterResourcesLoaded */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initMetaBuildingRegistry", function() { return initMetaBuildingRegistry; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initBuildingCodesAfterResourcesLoaded", function() { return initBuildingCodesAfterResourcesLoaded; }); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./buildings/toolbar_swapper */ "./src/js/game/buildings/toolbar_swapper.js"); /* harmony import */ var _buildings_belt__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./buildings/belt */ "./src/js/game/buildings/belt.js"); /* harmony import */ var _buildings_belt_base__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./buildings/belt_base */ "./src/js/game/buildings/belt_base.js"); /* harmony import */ var _buildings_cutter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./buildings/cutter */ "./src/js/game/buildings/cutter.js"); /* harmony import */ var _buildings_hub__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./buildings/hub */ "./src/js/game/buildings/hub.js"); /* harmony import */ var _buildings_miner__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./buildings/miner */ "./src/js/game/buildings/miner.js"); /* harmony import */ var _buildings_mixer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./buildings/mixer */ "./src/js/game/buildings/mixer.js"); /* harmony import */ var _buildings_painter__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./buildings/painter */ "./src/js/game/buildings/painter.js"); /* harmony import */ var _buildings_rotater__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./buildings/rotater */ "./src/js/game/buildings/rotater.js"); /* harmony import */ var _buildings_splitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./buildings/splitter */ "./src/js/game/buildings/splitter.js"); /* harmony import */ var _buildings_stacker__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./buildings/stacker */ "./src/js/game/buildings/stacker.js"); /* harmony import */ var _buildings_trash__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./buildings/trash */ "./src/js/game/buildings/trash.js"); /* harmony import */ var _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./buildings/underground_belt */ "./src/js/game/buildings/underground_belt.js"); /* harmony import */ var _buildings_wire__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./buildings/wire */ "./src/js/game/buildings/wire.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); /* harmony import */ var _buildings_constant_signal__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./buildings/constant_signal */ "./src/js/game/buildings/constant_signal.js"); /* harmony import */ var _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./buildings/logic_gate */ "./src/js/game/buildings/logic_gate.js"); /* harmony import */ var _buildings_lever__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./buildings/lever */ "./src/js/game/buildings/lever.js"); /* harmony import */ var _buildings_filter__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./buildings/filter */ "./src/js/game/buildings/filter.js"); /* harmony import */ var _buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./buildings/wire_tunnel */ "./src/js/game/buildings/wire_tunnel.js"); /* harmony import */ var _buildings_display__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./buildings/display */ "./src/js/game/buildings/display.js"); /* harmony import */ var _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./buildings/virtual_processor */ "./src/js/game/buildings/virtual_processor.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("building_registry"); function initMetaBuildingRegistry() { _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_toolbar_swapper__WEBPACK_IMPORTED_MODULE_2__["MetaToolbarSwapperBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_splitter__WEBPACK_IMPORTED_MODULE_11__["MetaSplitterBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_miner__WEBPACK_IMPORTED_MODULE_7__["MetaMinerBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_cutter__WEBPACK_IMPORTED_MODULE_5__["MetaCutterBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_rotater__WEBPACK_IMPORTED_MODULE_10__["MetaRotaterBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_stacker__WEBPACK_IMPORTED_MODULE_12__["MetaStackerBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_mixer__WEBPACK_IMPORTED_MODULE_8__["MetaMixerBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_painter__WEBPACK_IMPORTED_MODULE_9__["MetaPainterBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_trash__WEBPACK_IMPORTED_MODULE_13__["MetaTrashBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_belt__WEBPACK_IMPORTED_MODULE_3__["MetaBeltBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["MetaUndergroundBeltBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_hub__WEBPACK_IMPORTED_MODULE_6__["MetaHubBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_wire__WEBPACK_IMPORTED_MODULE_15__["MetaWireBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_constant_signal__WEBPACK_IMPORTED_MODULE_19__["MetaConstantSignalBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["MetaLogicGateBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_lever__WEBPACK_IMPORTED_MODULE_21__["MetaLeverBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_filter__WEBPACK_IMPORTED_MODULE_22__["MetaFilterBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_23__["MetaWireTunnelBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_display__WEBPACK_IMPORTED_MODULE_24__["MetaDisplayBuilding"]); _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(_buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"]); for (let custom of _custom_modBuildings__WEBPACK_IMPORTED_MODULE_18__["allCustomBuildingData"]) { if (custom.meta && !custom.meta._registered) { _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].register(custom.meta); custom.meta._registered = true; } } // Belt Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(1, _buildings_belt_base__WEBPACK_IMPORTED_MODULE_4__["MetaBeltBaseBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 0); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(2, _buildings_belt_base__WEBPACK_IMPORTED_MODULE_4__["MetaBeltBaseBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 1); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(3, _buildings_belt_base__WEBPACK_IMPORTED_MODULE_4__["MetaBeltBaseBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 2); // Splitter Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(4, _buildings_splitter__WEBPACK_IMPORTED_MODULE_11__["MetaSplitterBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(5, _buildings_splitter__WEBPACK_IMPORTED_MODULE_11__["MetaSplitterBuilding"], _buildings_splitter__WEBPACK_IMPORTED_MODULE_11__["enumSplitterVariants"].compact); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(6, _buildings_splitter__WEBPACK_IMPORTED_MODULE_11__["MetaSplitterBuilding"], _buildings_splitter__WEBPACK_IMPORTED_MODULE_11__["enumSplitterVariants"].compactInverse); // Miner Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(7, _buildings_miner__WEBPACK_IMPORTED_MODULE_7__["MetaMinerBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(8, _buildings_miner__WEBPACK_IMPORTED_MODULE_7__["MetaMinerBuilding"], _buildings_miner__WEBPACK_IMPORTED_MODULE_7__["enumMinerVariants"].chainable); // Cutter Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(9, _buildings_cutter__WEBPACK_IMPORTED_MODULE_5__["MetaCutterBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(10, _buildings_cutter__WEBPACK_IMPORTED_MODULE_5__["MetaCutterBuilding"], _buildings_cutter__WEBPACK_IMPORTED_MODULE_5__["enumCutterVariants"].quad); // Rotater Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(11, _buildings_rotater__WEBPACK_IMPORTED_MODULE_10__["MetaRotaterBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(12, _buildings_rotater__WEBPACK_IMPORTED_MODULE_10__["MetaRotaterBuilding"], _buildings_rotater__WEBPACK_IMPORTED_MODULE_10__["enumRotaterVariants"].ccw); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(13, _buildings_rotater__WEBPACK_IMPORTED_MODULE_10__["MetaRotaterBuilding"], _buildings_rotater__WEBPACK_IMPORTED_MODULE_10__["enumRotaterVariants"].fl); // Stacker Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(14, _buildings_stacker__WEBPACK_IMPORTED_MODULE_12__["MetaStackerBuilding"]); // Mixer Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(15, _buildings_mixer__WEBPACK_IMPORTED_MODULE_8__["MetaMixerBuilding"]); // Painter Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(16, _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["MetaPainterBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(17, _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["MetaPainterBuilding"], _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["enumPainterVariants"].mirrored); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(18, _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["MetaPainterBuilding"], _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["enumPainterVariants"].double); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(19, _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["MetaPainterBuilding"], _buildings_painter__WEBPACK_IMPORTED_MODULE_9__["enumPainterVariants"].quad); // Trash Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(20, _buildings_trash__WEBPACK_IMPORTED_MODULE_13__["MetaTrashBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(21, _buildings_trash__WEBPACK_IMPORTED_MODULE_13__["MetaTrashBuilding"], _buildings_trash__WEBPACK_IMPORTED_MODULE_13__["enumTrashVariants"].storage); // Underground belt Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(22, _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["MetaUndergroundBeltBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 0); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(23, _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["MetaUndergroundBeltBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 1); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(24, _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["MetaUndergroundBeltBuilding"], _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["enumUndergroundBeltVariants"].tier2, 0); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(25, _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["MetaUndergroundBeltBuilding"], _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_14__["enumUndergroundBeltVariants"].tier2, 1); // Hub Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(26, _buildings_hub__WEBPACK_IMPORTED_MODULE_6__["MetaHubBuilding"]); // Wire Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(27, _buildings_wire__WEBPACK_IMPORTED_MODULE_15__["MetaWireBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 0); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(28, _buildings_wire__WEBPACK_IMPORTED_MODULE_15__["MetaWireBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 1); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(29, _buildings_wire__WEBPACK_IMPORTED_MODULE_15__["MetaWireBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 2); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(30, _buildings_wire__WEBPACK_IMPORTED_MODULE_15__["MetaWireBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], 3); // Constant signal Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(31, _buildings_constant_signal__WEBPACK_IMPORTED_MODULE_19__["MetaConstantSignalBuilding"]); // Logic gate Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(32, _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["MetaLogicGateBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(34, _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["MetaLogicGateBuilding"], _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["enumLogicGateVariants"].not); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(35, _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["MetaLogicGateBuilding"], _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["enumLogicGateVariants"].xor); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(36, _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["MetaLogicGateBuilding"], _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["enumLogicGateVariants"].or); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(38, _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["MetaLogicGateBuilding"], _buildings_logic_gate__WEBPACK_IMPORTED_MODULE_20__["enumLogicGateVariants"].transistor); // Lever Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(33, _buildings_lever__WEBPACK_IMPORTED_MODULE_21__["MetaLeverBuilding"]); // Filter Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(37, _buildings_filter__WEBPACK_IMPORTED_MODULE_22__["MetaFilterBuilding"]); // Wire tunnel Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(39, _buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_23__["MetaWireTunnelBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(41, _buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_23__["MetaWireTunnelBuilding"], _buildings_wire_tunnel__WEBPACK_IMPORTED_MODULE_23__["enumWireTunnelVariants"].coating); // Display Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(40, _buildings_display__WEBPACK_IMPORTED_MODULE_24__["MetaDisplayBuilding"]); // Virtual Processor Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(42, _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"]); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(43, _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"], _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["enumVirtualProcessorVariants"].analyzer); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(44, _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"], _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["enumVirtualProcessorVariants"].rotater); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(45, _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"], _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["enumVirtualProcessorVariants"].unstacker); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(46, _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"], _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["enumVirtualProcessorVariants"].shapecompare); Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])(147, _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["MetaVirtualProcessorBuilding"], _buildings_virtual_processor__WEBPACK_IMPORTED_MODULE_25__["enumVirtualProcessorVariants"].adder); for (let custom of _custom_modBuildings__WEBPACK_IMPORTED_MODULE_18__["allCustomBuildingData"]) { if (custom.meta && custom.variantId) { Object(_building_codes__WEBPACK_IMPORTED_MODULE_16__["registerBuildingVariant"])( custom.variantId, custom.meta, custom.variant || _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"], custom.rotationVariant || 0 ); } } // Propagate instances for (const key in _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"]) { _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"][key].metaInstance = _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].findByClass( _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"][key].metaClass ); } for (const key in _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"]) { const variant = _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"][key]; window.assert(variant.metaClass, "Variant has no meta: " + key); if (typeof variant.rotationVariant === "undefined") { variant.rotationVariant = 0; } if (typeof variant.variant === "undefined") { variant.variant = _meta_building__WEBPACK_IMPORTED_MODULE_17__["defaultBuildingVariant"]; } } logger.log("Registered", _core_global_registries__WEBPACK_IMPORTED_MODULE_0__["gMetaBuildingRegistry"].getNumEntries(), "buildings"); logger.log("Registered", Object.keys(_building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"]).length, "building codes"); } /** * Once all sprites are loaded, propagates the cache */ function initBuildingCodesAfterResourcesLoaded() { logger.log("Propagating sprite cache"); for (const key in _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"]) { const variant = _building_codes__WEBPACK_IMPORTED_MODULE_16__["gBuildingVariants"][key]; variant.sprite = variant.metaInstance.getSprite(variant.rotationVariant, variant.variant); variant.blueprintSprite = variant.metaInstance.getBlueprintSprite( variant.rotationVariant, variant.variant ); variant.silhouetteColor = variant.metaInstance.getSilhouetteColor(); } } /***/ }), /***/ "./src/js/game/production_analytics.js": /*!*********************************************!*\ !*** ./src/js/game/production_analytics.js ***! \*********************************************/ /*! exports provided: enumAnalyticsDataSource, ProductionAnalytics */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumAnalyticsDataSource", function() { return enumAnalyticsDataSource; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProductionAnalytics", function() { return ProductionAnalytics; }); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./items/shape_item */ "./src/js/game/items/shape_item.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /** @enum {string} */ const enumAnalyticsDataSource = { produced: "produced", stored: "stored", delivered: "delivered", }; class ProductionAnalytics extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_5__["BasicSerializableObject"] { static getId() { return "ProductionAnalytics"; } /** * @param {GameRoot} root */ constructor(root) { super(); this.root = root; this.history = { [enumAnalyticsDataSource.produced]: [], [enumAnalyticsDataSource.stored]: [], [enumAnalyticsDataSource.delivered]: [], }; for (let i = 0; i < _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].statisticsGraphSlices; ++i) { this.startNewSlice(); } this.root.signals.shapeDelivered.add(this.onShapeDelivered, this); this.root.signals.itemProduced.add(this.onItemProduced, this); this.lastAnalyticsSlice = 0; } /** * @param {string} key */ onShapeDelivered(key) { const entry = this.history[enumAnalyticsDataSource.delivered]; entry[entry.length - 1][key] = (entry[entry.length - 1][key] || 0) + 1; } /** * @param {BaseItem} item */ onItemProduced(item) { // if (item.getItemType() === "shape") { // const definition = /** @type {ShapeItem} */ (item).definition; // const key = definition.getHash(); // const entry = this.history[enumAnalyticsDataSource.produced]; // entry[entry.length - 1][key] = (entry[entry.length - 1][key] || 0) + 1; // } const key = item.getHash(); const entry = this.history[enumAnalyticsDataSource.produced]; entry[entry.length - 1][key] = (entry[entry.length - 1][key] || 0) + 1; } /** * Starts a new time slice */ startNewSlice() { for (const key in this.history) { if (key === enumAnalyticsDataSource.stored) { // Copy stored data this.history[key].push(Object.assign({}, this.root.hubGoals.storedShapes)); } else { this.history[key].push({}); } while (this.history[key].length > _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].statisticsGraphSlices) { this.history[key].shift(); } } } /** * Returns the current rate of a given shape * @param {enumAnalyticsDataSource} dataSource * @param {string} shapeHash */ getCurrentShapeRate(dataSource, shapeHash) { const slices = this.history[dataSource]; return slices[slices.length - 2][shapeHash] || 0; } /** * Returns the rate of a given shape, frames ago * @param {enumAnalyticsDataSource} dataSource * @param {string} shapeHash * @param {number} historyOffset */ getPastShapeRate(dataSource, shapeHash, historyOffset) { window.assert( historyOffset >= 0 && historyOffset < _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].statisticsGraphSlices - 1, "Invalid slice offset: " + historyOffset ); const slices = this.history[dataSource]; return slices[slices.length - 2 - historyOffset][shapeHash] || 0; } /** * Returns the rates of all shapes * @param {enumAnalyticsDataSource} dataSource */ getCurrentShapeRates(dataSource) { const slices = this.history[dataSource]; // First, copy current slice const baseValues = Object.assign({}, slices[slices.length - 2]); // Add past values for (let i = 0; i < 10; ++i) { const pastValues = slices[slices.length - i - 3]; for (const key in pastValues) { baseValues[key] = (baseValues[key] || 0) + pastValues[key]; } } return baseValues; } update() { if (this.root.time.now() - this.lastAnalyticsSlice > _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].analyticsSliceDurationSeconds) { this.lastAnalyticsSlice = this.root.time.now(); this.startNewSlice(); } } } /***/ }), /***/ "./src/js/game/root.js": /*!*****************************!*\ !*** ./src/js/game/root.js ***! \*****************************/ /*! exports provided: layers, GameRoot */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "layers", function() { return layers; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameRoot", function() { return GameRoot; }); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_rng__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/rng */ "./src/js/core/rng.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* eslint-disable no-unused-vars */ // Type hints const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("game/root"); /** @type {Array} */ const layers = ["regular", "wires"]; /** * The game root is basically the whole game state at a given point, * combining all important classes. We don't have globals, but this * class is passed to almost all game classes. */ class GameRoot { /** * Constructs a new game root * @param {Application} app */ constructor(app) { this.app = app; /** @type {Savegame} */ this.savegame = null; /** @type {InGameState} */ this.gameState = null; /** @type {KeyActionMapper} */ this.keyMapper = null; // Store game dimensions this.gameWidth = 500; this.gameHeight = 500; // Stores whether the current session is a fresh game (true), or was continued (false) /** @type {boolean} */ this.gameIsFresh = true; // Stores whether the logic is already initialized /** @type {boolean} */ this.logicInitialized = false; // Stores whether the game is already initialized, that is, all systems etc have been created /** @type {boolean} */ this.gameInitialized = false; /** * Whether a bulk operation is running */ this.bulkOperationRunning = false; //////// Other properties /////// /** @type {Camera} */ this.camera = null; /** @type {HTMLCanvasElement} */ this.canvas = null; /** @type {CanvasRenderingContext2D} */ this.context = null; /** @type {MapView} */ this.map = null; /** @type {GameLogic} */ this.logic = null; /** @type {EntityManager} */ this.entityMgr = null; /** @type {GameHUD} */ this.hud = null; /** @type {GameSystemManager} */ this.systemMgr = null; /** @type {GameTime} */ this.time = null; /** @type {HubGoals} */ this.hubGoals = null; /** @type {BufferMaintainer} */ this.buffers = null; /** @type {AutomaticSave} */ this.automaticSave = null; /** @type {SoundProxy} */ this.soundProxy = null; /** @type {ShapeDefinitionManager} */ this.shapeDefinitionMgr = null; /** @type {ProductionAnalytics} */ this.productionAnalytics = null; /** @type {DynamicTickrate} */ this.dynamicTickrate = null; /** @type {Layer} */ this.currentLayer = "regular"; this.currentToolbar = 0; this.signals = { // Entities entityManuallyPlaced: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), entityAdded: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), entityChanged: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), entityGotNewComponent: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), entityComponentRemoved: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), entityQueuedForDestroy: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), entityDestroyed: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // Global resized: /** @type {TypedSignal<[number, number]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), readyToRender: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), aboutToDestruct: /** @type {TypedSignal<[]>} */ new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"](), // Game Hooks gameSaved: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // Game got saved gameRestored: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // Game got restored gameFrameStarted: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // New frame storyGoalCompleted: /** @type {TypedSignal<[number, string]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), upgradePurchased: /** @type {TypedSignal<[string]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // Called right after game is initialized postLoadHook: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), shapeDelivered: /** @type {TypedSignal<[string]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), bulkOperationFinished: /** @type {TypedSignal<[]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), editModeChanged: /** @type {TypedSignal<[Layer]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // Called to check if an entity can be placed, second parameter is an additional offset. // Use to introduce additional placement checks prePlacementCheck: /** @type {TypedSignal<[Entity, Vector]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), // Called before actually placing an entity, use to perform additional logic // for freeing space before actually placing. freeEntityAreaBeforeBuild: /** @type {TypedSignal<[Entity]>} */ (new _core_signal__WEBPACK_IMPORTED_MODULE_0__["Signal"]()), }; // RNG's /** @type {Object.>} */ this.rngs = {}; // Work queue this.queue = { requireRedraw: false, }; } /** * Destructs the game root */ destruct() { logger.log("destructing root"); this.signals.aboutToDestruct.dispatch(); this.reset(); } /** * Resets the whole root and removes all properties */ reset() { if (this.signals) { // Destruct all signals for (let i = 0; i < this.signals.length; ++i) { this.signals[i].removeAll(); } } if (this.hud) { this.hud.cleanup(); } if (this.camera) { this.camera.cleanup(); } // Finally free all properties for (let prop in this) { if (this.hasOwnProperty(prop)) { delete this[prop]; } } } } /***/ }), /***/ "./src/js/game/shape_definition.js": /*!*****************************************!*\ !*** ./src/js/game/shape_definition.js ***! \*****************************************/ /*! exports provided: enumSubShape, enumSubShapeToShortcode, enumShortcodeToSubShape, createSimpleShape, ShapeDefinition */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createSimpleShape", function() { return createSimpleShape; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeDefinition", function() { return ShapeDefinition; }); /* harmony import */ var _shapes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shapes.js */ "./src/js/game/shapes.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "enumSubShape", function() { return _shapes_js__WEBPACK_IMPORTED_MODULE_0__["enumSubShape"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "enumSubShapeToShortcode", function() { return _shapes_js__WEBPACK_IMPORTED_MODULE_0__["enumSubShapeToShortcode"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "enumShortcodeToSubShape", function() { return _shapes_js__WEBPACK_IMPORTED_MODULE_0__["enumShortcodeToSubShape"]; }); /* harmony import */ var _core_buffer_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/buffer_utils */ "./src/js/core/buffer_utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_dpi_manager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/dpi_manager */ "./src/js/core/dpi_manager.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./colors */ "./src/js/game/colors.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./theme */ "./src/js/game/theme.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./base_item */ "./src/js/game/base_item.js"); /** * @typedef {{ * subShape: enumSubShape, * color: enumColors, * }} ShapeLayerItem */ /** * Order is Q1 (tr), Q2(br), Q3(bl), Q4(tl) * @typedef {[ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?]} ShapeLayer */ const arrayQuadrantIndexToOffset = [ new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](1, -1), // tr new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](1, 1), // br new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](-1, 1), // bl new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](-1, -1), // tl ]; /** * Converts the given parameters to a valid shape definition * @param {*} layers * @returns {Array} */ function createSimpleShape(layers) { layers.forEach(layer => { layer.forEach(item => { if (item) { item.color = item.color || _colors__WEBPACK_IMPORTED_MODULE_7__["enumColors"].uncolored; } }); }); return layers; } /** * Cache which shapes are valid short keys and which not * @type {Map} */ const SHORT_KEY_CACHE = new Map(); /** * Cache of definitions * @type {Map} */ const ShapeDefinitionCache = new Map(); class ShapeDefinition extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_6__["BasicSerializableObject"] { static getId() { return "ShapeDefinition"; } static getSchema() { return {}; } deserialize(data) { const errorCode = super.deserialize(data); if (errorCode) { return errorCode; } const definition = ShapeDefinition.fromShortKey(data); this.layers = /** @type {Array} */ (definition.layers); } serialize() { return this.getHash(); } /** @returns {ShapeDefinition} */ static createFromHash(hash) { return ShapeDefinition.fromShortKey(hash); } /** * * @param {object} param0 * @param {Array=} param0.layers */ constructor({ layers = [] }) { super(); /** * The layers from bottom to top * @type {Array} */ this.layers = layers; /** @type {string} */ this.cachedHash = null; // Set on demand this.bufferGenerator = null; } /** * Generates the definition from the given short key * @param {string} key * @returns {ShapeDefinition} */ static fromShortKey(key) { let v = ShapeDefinitionCache.get(key); if (v) return v; const sourceLayers = key.split(":"); let layers = []; for (let i = 0; i < sourceLayers.length; ++i) { const text = sourceLayers[i]; window.assert(text.length === 8, "Invalid shape short key: " + key); /** @type {ShapeLayer} */ const quads = [null, null, null, null]; for (let quad = 0; quad < 4; ++quad) { const shapeText = text[quad * 2 + 0]; const subShape = _shapes_js__WEBPACK_IMPORTED_MODULE_0__["enumShortcodeToSubShape"][shapeText]; const color = _colors__WEBPACK_IMPORTED_MODULE_7__["enumShortcodeToColor"][text[quad * 2 + 1]]; if (subShape) { window.assert(color, "Invalid shape short key:", key); quads[quad] = { subShape, color, }; } else if (shapeText !== "-") { window.assert(false, "Invalid shape key: " + shapeText); } } layers.push(quads); } const definition = new ShapeDefinition({ layers }); // We know the hash so save some work definition.cachedHash = key; ShapeDefinitionCache.set(key, definition); return definition; } /** * Checks if a given string is a valid short key * @param {string} key * @returns {boolean} */ static isValidShortKey(key) { if (SHORT_KEY_CACHE.has(key)) { return SHORT_KEY_CACHE.get(key); } const result = ShapeDefinition.isValidShortKeyInternal(key); SHORT_KEY_CACHE.set(key, result); return result; } /** * INTERNAL * Checks if a given string is a valid short key * @param {string} key * @returns {boolean} */ static isValidShortKeyInternal(key) { const sourceLayers = key.split(":"); let layers = []; for (let i = 0; i < sourceLayers.length; ++i) { const text = sourceLayers[i]; if (text.length !== 8) { return false; } /** @type {ShapeLayer} */ const quads = [null, null, null, null]; let anyFilled = false; for (let quad = 0; quad < 4; ++quad) { const shapeText = text[quad * 2 + 0]; const colorText = text[quad * 2 + 1]; const subShape = _shapes_js__WEBPACK_IMPORTED_MODULE_0__["enumShortcodeToSubShape"][shapeText]; const color = _colors__WEBPACK_IMPORTED_MODULE_7__["enumShortcodeToColor"][colorText]; // Valid shape if (subShape) { if (!color) { // Invalid color return false; } quads[quad] = { subShape, color, }; anyFilled = true; } else if (shapeText === "-") { // Make sure color is empty then, too if (colorText !== "-") { return false; } } else { // Invalid shape key return false; } } if (!anyFilled) { // Empty layer return false; } layers.push(quads); } if (layers.length === 0 || layers.length > 4) { return false; } return true; } /** * Internal method to clone the shape definition * @returns {Array} */ internalCloneLayers() { return JSON.parse(JSON.stringify(this.layers)); } /** * Returns if the definition is entirely empty^ * @returns {boolean} */ isEntirelyEmpty() { return this.layers.length === 0; } /** * Returns a unique id for this shape * @returns {string} */ getHash() { if (this.cachedHash) { return this.cachedHash; } let id = ""; for (let layerIndex = 0; layerIndex < this.layers.length; ++layerIndex) { const layer = this.layers[layerIndex]; for (let quadrant = 0; quadrant < layer.length; ++quadrant) { const item = layer[quadrant]; if (item) { id += _shapes_js__WEBPACK_IMPORTED_MODULE_0__["enumSubShapeToShortcode"][item.subShape] + _colors__WEBPACK_IMPORTED_MODULE_7__["enumColorToShortcode"][item.color]; } else { id += "--"; } } if (layerIndex < this.layers.length - 1) { id += ":"; } } this.cachedHash = id; return id; } /** * Draws the shape definition * @param {number} x * @param {number} y * @param {DrawParameters} parameters * @param {number=} diameter */ drawCentered(x, y, parameters, diameter = 20) { const dpi = Object(_core_dpi_manager__WEBPACK_IMPORTED_MODULE_3__["smoothenDpi"])(_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].shapesSharpness * parameters.zoomLevel); if (!this.bufferGenerator) { this.bufferGenerator = this.internalGenerateShapeBuffer.bind(this); } const key = diameter + "/" + dpi + "/" + this.cachedHash; const canvas = parameters.root.buffers.getForKey({ key: "shapedef", subKey: key, w: diameter, h: diameter, dpi, redrawMethod: this.bufferGenerator, }); parameters.context.drawImage(canvas, x - diameter / 2, y - diameter / 2, diameter, diameter); } /** * Generates this shape as a canvas * @param {number} size */ generateAsCanvas(size = 120) { const [canvas, context] = Object(_core_buffer_utils__WEBPACK_IMPORTED_MODULE_1__["makeOffscreenBuffer"])(size, size, { smooth: true, label: "definition-canvas-cache-" + this.getHash(), reusable: false, }); this.internalGenerateShapeBuffer(canvas, context, size, size, 1); return canvas; } /** * * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h * @param {number} dpi */ internalGenerateShapeBuffer(canvas, context, w, h, dpi) { context.translate((w * dpi) / 2, (h * dpi) / 2); context.scale((dpi * w) / 23, (dpi * h) / 23); context.fillStyle = "#e9ecf7"; const quadrantSize = 10; const quadrantHalfSize = quadrantSize / 2; context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_8__["THEME"].items.circleBackground; context.beginCircle(0, 0, quadrantSize * 1.15); context.fill(); for (let layerIndex = 0; layerIndex < this.layers.length; ++layerIndex) { const quadrants = this.layers[layerIndex]; let quads = quadrants .map((e, i) => ({ e, i })) .filter(e => e.e) .map(e => ({ ...e.e, quadrantIndex: e.i })) .sort( (a, b) => (_shapes_js__WEBPACK_IMPORTED_MODULE_0__["allShapeData"][a.subShape] || noSuchShape(a.subShape)).layer - (_shapes_js__WEBPACK_IMPORTED_MODULE_0__["allShapeData"][b.subShape] || noSuchShape(b.subShape)).layer ); const layerScale = Math.max(0.1, 0.9 - layerIndex * 0.22); for (let quad of quads) { if (!quad) { continue; } const { subShape, color, quadrantIndex } = quad; if (subShape == "-") { continue; } const quadrantPos = arrayQuadrantIndexToOffset[quadrantIndex]; const centerQuadrantX = quadrantPos.x * quadrantHalfSize; const centerQuadrantY = quadrantPos.y * quadrantHalfSize; const rotation = Math.radians(quadrantIndex * 90); context.save(); context.translate(centerQuadrantX, centerQuadrantY); context.rotate(rotation); context.fillStyle = _colors__WEBPACK_IMPORTED_MODULE_7__["enumColorsToHexCode"][color]; context.strokeStyle = _theme__WEBPACK_IMPORTED_MODULE_8__["THEME"].items.outline; const lineWidth = _theme__WEBPACK_IMPORTED_MODULE_8__["THEME"].items.outlineWidth * Math.pow(0.8, layerIndex); context.lineWidth = lineWidth; const insetPadding = 0.0; const dims = quadrantSize * layerScale; const innerDims = insetPadding - quadrantHalfSize; let began = null; // eslint-disable-next-line no-inner-declarations function begin(args) { context.save(); context.translate(innerDims, -innerDims); context.scale(dims, -dims); context.lineWidth = lineWidth / dims / (args.size || 1); if (args.size) { context.scale(args.size, args.size); } if (args.path) { context.beginPath(); } if (args.zero) { context.moveTo(0, 0); } began = args; } // eslint-disable-next-line no-inner-declarations function end() { if (!began) { return; } if (began.path) { context.closePath(); } context.restore(); } let shape = _shapes_js__WEBPACK_IMPORTED_MODULE_0__["allShapeData"][subShape]; window.assert(shape.draw, "stape should be drawable!"); if (typeof shape.draw == "string") { let draw = shape.draw; let scale = parseFloat(draw); if (scale) { draw = draw.replace(scale, ""); scale = 1 / scale; } else { scale = 1; } begin({ size: scale }); let p = new Path2D(draw); context.fill(p); context.stroke(p); end(); } else { shape.draw({ dims, innerDims, layer: layerIndex, quad: quadrantIndex, context, color, begin, }); end(); context.fill(); context.stroke(); } context.restore(); } } } /** * Returns a definition with only the given quadrants * @param {Array} includeQuadrants * @returns {ShapeDefinition} */ cloneFilteredByQuadrants(includeQuadrants) { const newLayers = this.internalCloneLayers(); for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { const quadrants = newLayers[layerIndex]; let anyContents = false; for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { if (includeQuadrants.indexOf(quadrantIndex) < 0) { quadrants[quadrantIndex] = null; } else if (quadrants[quadrantIndex]) { anyContents = true; } } // Check if the layer is entirely empty if (!anyContents) { newLayers.splice(layerIndex, 1); layerIndex -= 1; } } return new ShapeDefinition({ layers: newLayers }); } /** * Returns a definition which was rotated clockwise * @returns {ShapeDefinition} */ cloneRotateCW() { const newLayers = this.internalCloneLayers(); for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { const quadrants = newLayers[layerIndex]; quadrants.unshift(quadrants[3]); quadrants.pop(); } return new ShapeDefinition({ layers: newLayers }); } /** * Returns a definition which was rotated counter clockwise * @returns {ShapeDefinition} */ cloneRotateCCW() { const newLayers = this.internalCloneLayers(); for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { const quadrants = newLayers[layerIndex]; quadrants.push(quadrants[0]); quadrants.shift(); } return new ShapeDefinition({ layers: newLayers }); } /** * Returns a definition which was rotated 180 degrees (flipped) * @returns {ShapeDefinition} */ cloneRotateFL() { const newLayers = this.internalCloneLayers(); for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { const quadrants = newLayers[layerIndex]; quadrants.push(quadrants.shift(), quadrants.shift()); } return new ShapeDefinition({ layers: newLayers }); } /** * Stacks the given shape definition on top. * @param {ShapeDefinition} definition */ cloneAndStackWith(definition) { if (this.isEntirelyEmpty() || definition.isEntirelyEmpty()) { window.assert(false, "Can not stack entirely empty definition"); } const bottomShapeLayers = this.layers; const bottomShapeHighestLayerByQuad = [-1, -1, -1, -1]; for (let layer = bottomShapeLayers.length - 1; layer >= 0; --layer) { const shapeLayer = bottomShapeLayers[layer]; for (let quad = 0; quad < 4; ++quad) { const shapeQuad = shapeLayer[quad]; if (shapeQuad !== null && bottomShapeHighestLayerByQuad[quad] < layer) { bottomShapeHighestLayerByQuad[quad] = layer; } } } const topShapeLayers = definition.layers; const topShapeLowestLayerByQuad = [4, 4, 4, 4]; for (let layer = 0; layer < topShapeLayers.length; ++layer) { const shapeLayer = topShapeLayers[layer]; for (let quad = 0; quad < 4; ++quad) { const shapeQuad = shapeLayer[quad]; if (shapeQuad !== null && topShapeLowestLayerByQuad[quad] > layer) { topShapeLowestLayerByQuad[quad] = layer; } } } /** * We want to find the number `layerToMergeAt` such that when the top shape is placed at that * layer, the smallest gap between shapes is only 1. Instead of doing a guess-and-check method to * find the appropriate layer, we just calculate all the gaps assuming a merge at layer 0, even * though they go negative, and calculating the number to add to it so the minimum gap is 1 (ends * up being 1 - minimum). */ const gapsBetweenShapes = []; for (let quad = 0; quad < 4; ++quad) { gapsBetweenShapes.push(topShapeLowestLayerByQuad[quad] - bottomShapeHighestLayerByQuad[quad]); } const smallestGapBetweenShapes = Math.min(...gapsBetweenShapes); // Can't merge at a layer lower than 0 const layerToMergeAt = Math.max(1 - smallestGapBetweenShapes, 0); const mergedLayers = this.internalCloneLayers(); for (let layer = mergedLayers.length; layer < layerToMergeAt + topShapeLayers.length; ++layer) { mergedLayers.push([null, null, null, null]); } for (let layer = 0; layer < topShapeLayers.length; ++layer) { const layerMergingAt = layerToMergeAt + layer; const bottomShapeLayer = mergedLayers[layerMergingAt]; const topShapeLayer = topShapeLayers[layer]; for (let quad = 0; quad < 4; quad++) { window.assert(!(bottomShapeLayer[quad] && topShapeLayer[quad]), "Shape merge: Sub shape got lost"); bottomShapeLayer[quad] = bottomShapeLayer[quad] || topShapeLayer[quad]; } } // Limit to 4 layers at max mergedLayers.splice(4); return new ShapeDefinition({ layers: mergedLayers }); } /** * Clones the shape and colors everything in the given color * @param {enumColors} color */ cloneAndPaintWith(color) { const newLayers = this.internalCloneLayers(); for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { const quadrants = newLayers[layerIndex]; for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { const item = quadrants[quadrantIndex]; if (item) { item.color = color; } } } return new ShapeDefinition({ layers: newLayers }); } /** * Clones the shape and colors everything in the given colors * @param {[enumColors, enumColors, enumColors, enumColors]} colors */ cloneAndPaintWith4Colors(colors) { const newLayers = this.internalCloneLayers(); for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { const quadrants = newLayers[layerIndex]; for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { const item = quadrants[quadrantIndex]; if (item) { item.color = colors[quadrantIndex]; } } } return new ShapeDefinition({ layers: newLayers }); } } _base_item__WEBPACK_IMPORTED_MODULE_9__["BaseItem"].ShapeDefinition = ShapeDefinition; /***/ }), /***/ "./src/js/game/shape_definition_manager.js": /*!*************************************************!*\ !*** ./src/js/game/shape_definition_manager.js ***! \*************************************************/ /*! exports provided: ShapeDefinitionManager */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeDefinitionManager", function() { return ShapeDefinitionManager; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./colors */ "./src/js/game/colors.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./items/shape_item */ "./src/js/game/items/shape_item.js"); /* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./root */ "./src/js/game/root.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./shape_definition */ "./src/js/game/shape_definition.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("shape_definition_manager"); class ShapeDefinitionManager extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_1__["BasicSerializableObject"] { static getId() { return "ShapeDefinitionManager"; } /** * * @param {GameRoot} root */ constructor(root) { super(); this.root = root; /** * Store a cache from key -> definition * @type {Object} */ this.shapeKeyToDefinition = {}; /** * Store a cache from key -> item */ this.shapeKeyToItem = {}; // Caches operations in the form of 'operation:def1[:def2]' /** @type {Object.|ShapeDefinition>} */ this.operationCache = {}; } /** * Returns a shape instance from a given short key * @param {string} hash * @returns {ShapeDefinition} */ getShapeFromShortKey(hash) { const cached = this.shapeKeyToDefinition[hash]; if (cached) { return cached; } return (this.shapeKeyToDefinition[hash] = _shape_definition__WEBPACK_IMPORTED_MODULE_5__["ShapeDefinition"].fromShortKey(hash)); } /** * Returns a item instance from a given short key * @param {string} hash * @returns {ShapeItem} */ getShapeItemFromShortKey(hash) { const cached = this.shapeKeyToItem[hash]; if (cached) { return cached; } const definition = this.getShapeFromShortKey(hash); return (this.shapeKeyToItem[hash] = new _items_shape_item__WEBPACK_IMPORTED_MODULE_3__["ShapeItem"](definition)); } /** * Returns a shape item for a given definition * @param {ShapeDefinition} definition * @returns {ShapeItem} */ getShapeItemFromDefinition(definition) { return this.getShapeItemFromShortKey(definition.getHash()); } /** * Registers a new shape definition * @param {ShapeDefinition} definition */ registerShapeDefinition(definition) { const id = definition.getHash(); window.assert(!this.shapeKeyToDefinition[id], "Shape Definition " + id + " already exists"); this.shapeKeyToDefinition[id] = definition; // logger.log("Registered shape with key", id); } /** * Generates a definition for splitting a shape definition in two halfs * @param {ShapeDefinition} definition * @returns {[ShapeDefinition, ShapeDefinition]} */ shapeActionCutHalf(definition) { const key = "cut:" + definition.getHash(); if (this.operationCache[key]) { return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key]); } const rightSide = definition.cloneFilteredByQuadrants([2, 3]); const leftSide = definition.cloneFilteredByQuadrants([0, 1]); return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key] = [ this.registerOrReturnHandle(rightSide), this.registerOrReturnHandle(leftSide), ]); } /** * Generates a definition for splitting a shape definition in four quads * @param {ShapeDefinition} definition * @returns {[ShapeDefinition, ShapeDefinition, ShapeDefinition, ShapeDefinition]} */ shapeActionCutQuad(definition) { const key = "cut-quad:" + definition.getHash(); if (this.operationCache[key]) { return /** @type {[ShapeDefinition, ShapeDefinition, ShapeDefinition, ShapeDefinition]} */ (this .operationCache[key]); } return /** @type {[ShapeDefinition, ShapeDefinition, ShapeDefinition, ShapeDefinition]} */ (this.operationCache[ key ] = [ this.registerOrReturnHandle(definition.cloneFilteredByQuadrants([0])), this.registerOrReturnHandle(definition.cloneFilteredByQuadrants([1])), this.registerOrReturnHandle(definition.cloneFilteredByQuadrants([2])), this.registerOrReturnHandle(definition.cloneFilteredByQuadrants([3])), ]); } /** * Generates a definition for rotating a shape clockwise * @param {ShapeDefinition} definition * @returns {ShapeDefinition} */ shapeActionRotateCW(definition) { const key = "rotate-cw:" + definition.getHash(); if (this.operationCache[key]) { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } const rotated = definition.cloneRotateCW(); return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( rotated )); } /** * Generates a definition for rotating a shape counter clockwise * @param {ShapeDefinition} definition * @returns {ShapeDefinition} */ shapeActionRotateCCW(definition) { const key = "rotate-ccw:" + definition.getHash(); if (this.operationCache[key]) { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } const rotated = definition.cloneRotateCCW(); return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( rotated )); } /** * Generates a definition for rotating a shape counter clockwise * @param {ShapeDefinition} definition * @returns {ShapeDefinition} */ shapeActionRotateFL(definition) { const key = "rotate-fl:" + definition.getHash(); if (this.operationCache[key]) { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } const rotated = definition.cloneRotateFL(); return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( rotated )); } /** * Generates a definition for stacking the upper definition onto the lower one * @param {ShapeDefinition} lowerDefinition * @param {ShapeDefinition} upperDefinition * @returns {ShapeDefinition} */ shapeActionStack(lowerDefinition, upperDefinition) { const key = "stack:" + lowerDefinition.getHash() + ":" + upperDefinition.getHash(); if (this.operationCache[key]) { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } const stacked = lowerDefinition.cloneAndStackWith(upperDefinition); return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( stacked )); } /** * Generates a definition for painting it with the given color * @param {ShapeDefinition} definition * @param {enumColors} color * @returns {ShapeDefinition} */ shapeActionPaintWith(definition, color) { const key = "paint:" + definition.getHash() + ":" + color; if (this.operationCache[key]) { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } const colorized = definition.cloneAndPaintWith(color); return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( colorized )); } /** * Generates a definition for painting it with the 4 colors * @param {ShapeDefinition} definition * @param {[enumColors, enumColors, enumColors, enumColors]} colors * @returns {ShapeDefinition} */ shapeActionPaintWith4Colors(definition, colors) { const key = "paint4:" + definition.getHash() + ":" + colors.join(","); if (this.operationCache[key]) { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } const colorized = definition.cloneAndPaintWith4Colors(colors); return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( colorized )); } /** * Checks if we already have cached this definition, and if so throws it away and returns the already * cached variant * @param {ShapeDefinition} definition */ registerOrReturnHandle(definition) { const id = definition.getHash(); if (this.shapeKeyToDefinition[id]) { return this.shapeKeyToDefinition[id]; } this.shapeKeyToDefinition[id] = definition; // logger.log("Registered shape with key (2)", id); return definition; } /** * * @param {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} subShapes * @returns {ShapeDefinition} */ getDefinitionFromSimpleShapes(subShapes, color = _colors__WEBPACK_IMPORTED_MODULE_2__["enumColors"].uncolored) { const shapeLayer = /** @type {import("./shape_definition").ShapeLayer} */ (subShapes.map( subShape => ({ subShape, color }) )); return this.registerOrReturnHandle(new _shape_definition__WEBPACK_IMPORTED_MODULE_5__["ShapeDefinition"]({ layers: [shapeLayer] })); } getDefinitionFromSimpleShapesAndColors(subShapes, colors) { const shapeLayer = /** @type {import("./shape_definition").ShapeLayer} */ (subShapes.map( (subShape, i) => ({ subShape, color: colors[i] }) )); return this.registerOrReturnHandle(new _shape_definition__WEBPACK_IMPORTED_MODULE_5__["ShapeDefinition"]({ layers: [shapeLayer] })); } } /***/ }), /***/ "./src/js/game/shapes.js": /*!*******************************!*\ !*** ./src/js/game/shapes.js ***! \*******************************/ /*! exports provided: enumSubShape, enumSubShapeToShortcode, enumShortcodeToSubShape, allShapeData, initShapes */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumSubShape", function() { return enumSubShape; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumSubShapeToShortcode", function() { return enumSubShapeToShortcode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumShortcodeToSubShape", function() { return enumShortcodeToSubShape; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allShapeData", function() { return allShapeData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initShapes", function() { return initShapes; }); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./colors */ "./src/js/game/colors.js"); /* harmony import */ var _custom_shapes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./custom/shapes */ "./src/js/game/custom/shapes.js"); /** @enum {string} */ const enumSubShape = { rect: "rect", circle: "circle", star: "star", windmill: "windmill", }; /** @enum {string} */ const enumSubShapeToShortcode = { [enumSubShape.rect]: "R", [enumSubShape.circle]: "C", [enumSubShape.star]: "S", [enumSubShape.windmill]: "W", }; /** @enum {enumSubShape} */ const enumShortcodeToSubShape = {}; for (const key in enumSubShapeToShortcode) { enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key; } /** * @callback DrawShape * @param {Object} args */ /** * @typedef {Object} ShapeData * @property {string} id * @property {string} code * @property {boolean} [spawnable] * @property {string} [spawnColor] * @property {number} [maxQuarters] * @property {number} [minDistance] * @property {number} [minChance] * @property {number} [distChance] * @property {number} [maxChance] * @property {DrawShape | string} draw * @property {number} tier */ /** @enum {ShapeData} */ const allShapeData = { rect: { id: "rect", code: "R", spawnable: true, spawnColor: "uncolored", maxQuarters: 4, minDistance: 0, minChance: 100, distChance: 0, maxChance: 100, draw: "M 0 0 v 1 h 1 v -1 z", tier: 0, }, circle: { id: "circle", code: "C", spawnable: true, spawnColor: "uncolored", maxQuarters: 4, minDistance: 0, minChance: 50, distChance: 15, maxChance: 100, draw: "M 0 0 l 1 0 a 1 1 0 0 1 -1 1 z ", tier: 0, }, star: { id: "star", code: "S", spawnable: true, spawnColor: "uncolored", maxQuarters: 4, minDistance: 5, minChance: 20, distChance: 10, maxChance: 100, draw: "M 0 0 L 0 0.6 1 1 0.6 0 z", tier: 0.5, }, windmill: { id: "windmill", code: "W", spawnable: true, spawnColor: "uncolored", maxQuarters: 3, minDistance: 7, minChance: 20, distChance: 5, maxChance: 100, draw: "M 0 0 L 0 0.6 1 1 1 0 z", tier: 1, }, }; for (let data of _custom_shapes__WEBPACK_IMPORTED_MODULE_1__["customShapes"]) { allShapeData[data.id] = data; } initShapes(); function initShapes() { for (let k in enumSubShape) { delete enumSubShape[k]; } for (let k in enumSubShapeToShortcode) { delete enumSubShapeToShortcode[k]; } for (let k in enumShortcodeToSubShape) { delete enumShortcodeToSubShape[k]; } for (let s in allShapeData) { let data = allShapeData[s]; window.assert(data.id == s); window.assert(data.code.toUpperCase() == data.code); enumSubShape[data.id] = data.id; enumSubShapeToShortcode[data.id] = data.code; enumShortcodeToSubShape[data.code] = data.id; if (data.spawnable) { data.spawnColor = data.spawnColor || "uncolored"; window.assert(_colors__WEBPACK_IMPORTED_MODULE_0__["enumColors"][data.spawnColor], "should have known initial color"); data.maxQuarters = data.maxQuarters || 4; data.minDistance = data.minDistance || 0; window.assert(data.minChance > 0 || data.distChance > 0, "should have chance to spawn"); data.minChance = data.minChance || 0; data.distChance = data.distChance || 0; data.maxChance = data.maxChance || 999999; } } } /***/ }), /***/ "./src/js/game/sound_proxy.js": /*!************************************!*\ !*** ./src/js/game/sound_proxy.js ***! \************************************/ /*! exports provided: SoundProxy */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SoundProxy", function() { return SoundProxy; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); const avgSoundDurationSeconds = 0.1; const maxOngoingSounds = 2; const maxOngoingUiSounds = 5; // Proxy to the application sound instance class SoundProxy { /** * @param {GameRoot} root */ constructor(root) { this.root = root; // Store a list of sounds and when we started them this.playing3DSounds = []; this.playingUiSounds = []; } /** * Plays a new ui sound * @param {string} id Sound ID */ playUi(id) { window.assert(typeof id === "string", "Not a valid sound id: " + id); this.internalUpdateOngoingSounds(); if (this.playingUiSounds.length > maxOngoingUiSounds) { // Too many ongoing sounds return false; } this.root.app.sound.playUiSound(id); this.playingUiSounds.push(this.root.time.realtimeNow()); } /** * Plays the ui click sound */ playUiClick() { this.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_1__["SOUNDS"].uiClick); } /** * Plays the ui error sound */ playUiError() { this.playUi(_platform_sound__WEBPACK_IMPORTED_MODULE_1__["SOUNDS"].uiError); } /** * Plays a 3D sound whose volume is scaled based on where it was emitted * @param {string} id Sound ID * @param {Vector} pos World space position */ play3D(id, pos) { window.assert(typeof id === "string", "Not a valid sound id: " + id); window.assert(pos instanceof _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"], "Invalid sound position"); this.internalUpdateOngoingSounds(); if (this.playing3DSounds.length > maxOngoingSounds) { // Too many ongoing sounds return false; } this.root.app.sound.play3DSound(id, pos, this.root); this.playing3DSounds.push(this.root.time.realtimeNow()); return true; } /** * Updates the list of ongoing sounds */ internalUpdateOngoingSounds() { const now = this.root.time.realtimeNow(); for (let i = 0; i < this.playing3DSounds.length; ++i) { if (now - this.playing3DSounds[i] > avgSoundDurationSeconds) { this.playing3DSounds.splice(i, 1); i -= 1; } } for (let i = 0; i < this.playingUiSounds.length; ++i) { if (now - this.playingUiSounds[i] > avgSoundDurationSeconds) { this.playingUiSounds.splice(i, 1); i -= 1; } } } } /***/ }), /***/ "./src/js/game/systems/belt.js": /*!*************************************!*\ !*** ./src/js/game/systems/belt.js ***! \*************************************/ /*! exports provided: BELT_ANIM_COUNT, BeltSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BELT_ANIM_COUNT", function() { return BELT_ANIM_COUNT; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BeltSystem", function() { return BeltSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_sprites__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/sprites */ "./src/js/core/sprites.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _belt_path__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../belt_path */ "./src/js/game/belt_path.js"); /* harmony import */ var _buildings_belt_base__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../buildings/belt_base */ "./src/js/game/buildings/belt_base.js"); /* harmony import */ var _components_belt__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../components/belt */ "./src/js/game/components/belt.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../building_codes */ "./src/js/game/building_codes.js"); const BELT_ANIM_COUNT = 14; const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_4__["createLogger"])("belt"); /** * Manages all belts */ class BeltSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_12__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_belt__WEBPACK_IMPORTED_MODULE_10__["BeltComponent"]]); /** * @type {Object.>} */ this.beltSprites = { [_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].top]: _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/belt/built/forward_0.png"), [_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].left]: _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/belt/built/left_0.png"), [_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].right]: _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/belt/built/right_0.png"), }; /** * @type {Object.>} */ this.beltAnimations = { [_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].top]: [], [_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].left]: [], [_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].right]: [], }; for (let i = 0; i < BELT_ANIM_COUNT; ++i) { this.beltAnimations[_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].top].push( _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/belt/built/forward_" + i + ".png") ); this.beltAnimations[_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].left].push( _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/belt/built/left_" + i + ".png") ); this.beltAnimations[_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].right].push( _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/belt/built/right_" + i + ".png") ); } this.root.signals.entityDestroyed.add(this.onEntityDestroyed, this); this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this); // Notice: These must come *after* the entity destroyed signals this.root.signals.entityAdded.add(this.onEntityAdded, this); this.root.signals.entityAdded.add(this.updateSurroundingBeltPlacement, this); /** @type {Array} */ this.beltPaths = []; } /** * Serializes all belt paths * @returns {Array} */ serializePaths() { let data = []; for (let i = 0; i < this.beltPaths.length; ++i) { data.push(this.beltPaths[i].serialize()); } return data; } /** * Deserializes all belt paths * @param {Array} data */ deserializePaths(data) { if (!Array.isArray(data)) { return "Belt paths are not an array: " + typeof data; } for (let i = 0; i < data.length; ++i) { const path = _belt_path__WEBPACK_IMPORTED_MODULE_8__["BeltPath"].fromSerialized(this.root, data[i]); // If path is a string, that means its an error if (!(path instanceof _belt_path__WEBPACK_IMPORTED_MODULE_8__["BeltPath"])) { return "Failed to create path from belt data: " + path; } this.beltPaths.push(path); } if (this.beltPaths.length === 0) { // Old savegames might not have paths yet logger.warn("Recomputing belt paths (most likely the savegame is old or empty)"); this.recomputeAllBeltPaths(); } else { logger.warn("Restored", this.beltPaths.length, "belt paths"); } if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } } /** * Updates the belt placement after an entity has been added / deleted * @param {Entity} entity */ updateSurroundingBeltPlacement(entity) { if (!this.root.gameInitialized) { return; } const staticComp = entity.components.StaticMapEntity; if (!staticComp) { return; } const metaBelt = _core_global_registries__WEBPACK_IMPORTED_MODULE_2__["gMetaBuildingRegistry"].findByClass(_buildings_belt_base__WEBPACK_IMPORTED_MODULE_9__["MetaBeltBaseBuilding"]); // Compute affected area const originalRect = staticComp.getTileSpaceBounds(); const affectedArea = originalRect.expandedInAllDirections(1); /** @type {Set} */ const changedPaths = new Set(); for (let x = affectedArea.x; x < affectedArea.right(); ++x) { for (let y = affectedArea.y; y < affectedArea.bottom(); ++y) { if (originalRect.containsPoint(x, y)) { // Make sure we don't update the original entity continue; } const targetEntities = this.root.map.getLayersContentsMultipleXY(x, y); for (let i = 0; i < targetEntities.length; ++i) { const targetEntity = targetEntities[i]; const targetBeltComp = targetEntity.components.Belt; const targetStaticComp = targetEntity.components.StaticMapEntity; if (!targetBeltComp) { // Not a belt continue; } const { rotation, rotationVariant, } = metaBelt.computeOptimalDirectionAndRotationVariantAtTile({ root: this.root, tile: new _core_vector__WEBPACK_IMPORTED_MODULE_7__["Vector"](x, y), rotation: targetStaticComp.originalRotation, variant: _meta_building__WEBPACK_IMPORTED_MODULE_14__["defaultBuildingVariant"], layer: targetEntity.layer, }); // Compute delta to see if anything changed const newDirection = _buildings_belt_base__WEBPACK_IMPORTED_MODULE_9__["arrayBeltVariantToRotation"][rotationVariant]; if (targetStaticComp.rotation !== rotation || newDirection !== targetBeltComp.direction) { // Ok, first remove it from its current path this.deleteEntityFromPath(targetBeltComp.assignedPath, targetEntity); // Change stuff targetStaticComp.rotation = rotation; metaBelt.updateVariants(targetEntity, rotationVariant, _meta_building__WEBPACK_IMPORTED_MODULE_14__["defaultBuildingVariant"]); // Update code as well targetStaticComp.code = Object(_building_codes__WEBPACK_IMPORTED_MODULE_15__["getCodeFromBuildingData"])( metaBelt, _meta_building__WEBPACK_IMPORTED_MODULE_14__["defaultBuildingVariant"], rotationVariant ); // Now add it again this.addEntityToPaths(targetEntity); // Sanity if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } // Make sure the chunks know about the update this.root.signals.entityChanged.dispatch(targetEntity); } if (targetBeltComp.assignedPath) { changedPaths.add(targetBeltComp.assignedPath); } } } } // notify all paths *afterwards* to avoid multi-updates changedPaths.forEach(path => path.onSurroundingsChanged()); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } } /** * Called when an entity got destroyed * @param {Entity} entity */ onEntityDestroyed(entity) { if (!this.root.gameInitialized) { return; } if (!entity.components.Belt) { return; } const assignedPath = entity.components.Belt.assignedPath; window.assert(assignedPath, "Entity has no belt path assigned"); this.deleteEntityFromPath(assignedPath, entity); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } } /** * Attempts to delete the belt from its current path * @param {BeltPath} path * @param {Entity} entity */ deleteEntityFromPath(path, entity) { if (path.entityPath.length === 1) { // This is a single entity path, easy to do, simply erase whole path Object(_core_utils__WEBPACK_IMPORTED_MODULE_6__["fastArrayDeleteValue"])(this.beltPaths, path); return; } // Notice: Since there might be circular references, it is important to check // which role the entity has if (path.isStartEntity(entity)) { // We tried to delete the start path.deleteEntityOnStart(entity); } else if (path.isEndEntity(entity)) { // We tried to delete the end path.deleteEntityOnEnd(entity); } else { // We tried to delete something inbetween const newPath = path.deleteEntityOnPathSplitIntoTwo(entity); this.beltPaths.push(newPath); } // Sanity entity.components.Belt.assignedPath = null; } /** * Adds the given entity to the appropriate paths * @param {Entity} entity */ addEntityToPaths(entity) { const fromEntity = this.findSupplyingEntity(entity); const toEntity = this.findFollowUpEntity(entity); // Check if we can add the entity to the previous path if (fromEntity) { const fromPath = fromEntity.components.Belt.assignedPath; fromPath.extendOnEnd(entity); // Check if we now can extend the current path by the next path if (toEntity) { const toPath = toEntity.components.Belt.assignedPath; if (fromPath === toPath) { // This is a circular dependency -> Ignore } else { fromPath.extendByPath(toPath); // Delete now obsolete path Object(_core_utils__WEBPACK_IMPORTED_MODULE_6__["fastArrayDeleteValue"])(this.beltPaths, toPath); } } } else { if (toEntity) { // Prepend it to the other path const toPath = toEntity.components.Belt.assignedPath; toPath.extendOnBeginning(entity); } else { // This is an empty belt path const path = new _belt_path__WEBPACK_IMPORTED_MODULE_8__["BeltPath"](this.root, [entity]); this.beltPaths.push(path); } } } /** * Called when an entity got added * @param {Entity} entity */ onEntityAdded(entity) { if (!this.root.gameInitialized) { return; } if (!entity.components.Belt) { return; } this.addEntityToPaths(entity); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } } /** * Draws all belt paths * @param {DrawParameters} parameters */ drawBeltItems(parameters) { for (let i = 0; i < this.beltPaths.length; ++i) { this.beltPaths[i].draw(parameters); } } /** * Verifies all belt paths */ debug_verifyBeltPaths() { for (let i = 0; i < this.beltPaths.length; ++i) { this.beltPaths[i].debug_checkIntegrity("general-verify"); } const belts = this.root.entityMgr.getAllWithComponent(_components_belt__WEBPACK_IMPORTED_MODULE_10__["BeltComponent"]); for (let i = 0; i < belts.length; ++i) { const path = belts[i].components.Belt.assignedPath; if (!path) { throw new Error("Belt has no path: " + belts[i].uid); } if (this.beltPaths.indexOf(path) < 0) { throw new Error("Path of entity not contained: " + belts[i].uid); } } } /** * Finds the follow up entity for a given belt. Used for building the dependencies * @param {Entity} entity * @returns {Entity|null} */ findFollowUpEntity(entity) { const staticComp = entity.components.StaticMapEntity; const beltComp = entity.components.Belt; const followUpDirection = staticComp.localDirectionToWorld(beltComp.direction); const followUpVector = _core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirectionToVector"][followUpDirection]; const followUpTile = staticComp.origin.add(followUpVector); const followUpEntity = this.root.map.getLayerContentXY(followUpTile.x, followUpTile.y, entity.layer); // Check if theres a belt at the tile we point to if (followUpEntity) { const followUpBeltComp = followUpEntity.components.Belt; if (followUpBeltComp) { const followUpStatic = followUpEntity.components.StaticMapEntity; const acceptedDirection = followUpStatic.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].top); if (acceptedDirection === followUpDirection) { return followUpEntity; } } } return null; } /** * Finds the supplying belt for a given belt. Used for building the dependencies * @param {Entity} entity * @returns {Entity|null} */ findSupplyingEntity(entity) { const staticComp = entity.components.StaticMapEntity; const supplyDirection = staticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].bottom); const supplyVector = _core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirectionToVector"][supplyDirection]; const supplyTile = staticComp.origin.add(supplyVector); const supplyEntity = this.root.map.getLayerContentXY(supplyTile.x, supplyTile.y, entity.layer); // Check if theres a belt at the tile we point to if (supplyEntity) { const supplyBeltComp = supplyEntity.components.Belt; if (supplyBeltComp) { const supplyStatic = supplyEntity.components.StaticMapEntity; const otherDirection = supplyStatic.localDirectionToWorld( _core_vector__WEBPACK_IMPORTED_MODULE_7__["enumInvertedDirections"][supplyBeltComp.direction] ); if (otherDirection === supplyDirection) { return supplyEntity; } } } return null; } /** * Recomputes the belt path network. Only required for old savegames */ recomputeAllBeltPaths() { logger.warn("Recomputing all belt paths"); const visitedUids = new Set(); const result = []; for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; if (visitedUids.has(entity.uid)) { continue; } // Mark entity as visited visitedUids.add(entity.uid); // Compute path, start with entity and find precedors / successors const path = [entity]; // Prevent infinite loops let maxIter = 99999; // Find precedors let prevEntity = this.findSupplyingEntity(entity); while (prevEntity && --maxIter > 0) { if (visitedUids.has(prevEntity.uid)) { break; } path.unshift(prevEntity); visitedUids.add(prevEntity.uid); prevEntity = this.findSupplyingEntity(prevEntity); } // Find succedors let nextEntity = this.findFollowUpEntity(entity); while (nextEntity && --maxIter > 0) { if (visitedUids.has(nextEntity.uid)) { break; } path.push(nextEntity); visitedUids.add(nextEntity.uid); nextEntity = this.findFollowUpEntity(nextEntity); } window.assert(maxIter > 1, "Ran out of iterations"); result.push(new _belt_path__WEBPACK_IMPORTED_MODULE_8__["BeltPath"](this.root, path)); } logger.log("Found", this.beltPaths.length, "belt paths"); this.beltPaths = result; } /** * Updates all belts */ update() { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } for (let i = 0; i < this.beltPaths.length; ++i) { this.beltPaths[i].update(); } if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.checkBeltPaths) { this.debug_verifyBeltPaths(); } } /** * Draws a given chunk * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { // Limit speed to avoid belts going backwards const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10); // SYNC with systems/item_acceptor.js:drawEntityUnderlays! // 126 / 42 is the exact animation speed of the png animation const animationIndex = Math.floor( ((this.root.time.realtimeNow() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts ); const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; if (entity.components.Belt) { const direction = entity.components.Belt.direction; const sprite = this.beltAnimations[direction][animationIndex % BELT_ANIM_COUNT]; // Culling happens within the static map entity component entity.components.StaticMapEntity.drawSpriteOnBoundsClipped(parameters, sprite, 0); } } } /** * Draws the belt path debug overlays * @param {DrawParameters} parameters */ drawBeltPathDebug(parameters) { for (let i = 0; i < this.beltPaths.length; ++i) { this.beltPaths[i].drawDebug(parameters); } } } /***/ }), /***/ "./src/js/game/systems/belt_underlays.js": /*!***********************************************!*\ !*** ./src/js/game/systems/belt_underlays.js ***! \***********************************************/ /*! exports provided: BeltUnderlaysSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BeltUnderlaysSystem", function() { return BeltUnderlaysSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_belt_underlays__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/belt_underlays */ "./src/js/game/components/belt_underlays.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _belt__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./belt */ "./src/js/game/systems/belt.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); class BeltUnderlaysSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_belt_underlays__WEBPACK_IMPORTED_MODULE_4__["BeltUnderlaysComponent"]]); this.underlayBeltSprites = []; for (let i = 0; i < _belt__WEBPACK_IMPORTED_MODULE_6__["BELT_ANIM_COUNT"]; ++i) { this.underlayBeltSprites.push(_core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/belt/built/forward_" + i + ".png")); } } /** * Draws a given chunk * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { // Limit speed to avoid belts going backwards const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10); const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const underlayComp = entity.components.BeltUnderlays; if (!underlayComp) { continue; } const staticComp = entity.components.StaticMapEntity; const underlays = underlayComp.underlays; for (let i = 0; i < underlays.length; ++i) { const { pos, direction } = underlays[i]; const transformedPos = staticComp.localTileToWorld(pos); // Culling if (!chunk.tileSpaceRectangle.containsPoint(transformedPos.x, transformedPos.y)) { continue; } const destX = transformedPos.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const destY = transformedPos.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; // Culling, #2 if ( !parameters.visibleRect.containsRect4Params( destX, destY, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize ) ) { continue; } const angle = _core_vector__WEBPACK_IMPORTED_MODULE_3__["enumDirectionToAngle"][staticComp.localDirectionToWorld(direction)]; // SYNC with systems/belt.js:drawSingleEntity! const animationIndex = Math.floor( ((this.root.time.realtimeNow() * speedMultiplier * _belt__WEBPACK_IMPORTED_MODULE_6__["BELT_ANIM_COUNT"] * 126) / 42) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts ); Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_1__["drawRotatedSprite"])({ parameters, sprite: this.underlayBeltSprites[animationIndex % this.underlayBeltSprites.length], x: destX + _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize, y: destY + _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize, angle: Math.radians(angle), size: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, }); } } } } /***/ }), /***/ "./src/js/game/systems/constant_signal.js": /*!************************************************!*\ !*** ./src/js/game/systems/constant_signal.js ***! \************************************************/ /*! exports provided: ConstantSignalSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConstantSignalSystem", function() { return ConstantSignalSystem; }); /* harmony import */ var trim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! trim */ "./node_modules/trim/index.js"); /* harmony import */ var trim__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(trim__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/modal_dialog_elements */ "./src/js/core/modal_dialog_elements.js"); /* harmony import */ var _core_modal_dialog_forms__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/modal_dialog_forms */ "./src/js/core/modal_dialog_forms.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../colors */ "./src/js/game/colors.js"); /* harmony import */ var _components_constant_signal__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/constant_signal */ "./src/js/game/components/constant_signal.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../shape_definition */ "./src/js/game/shape_definition.js"); class ConstantSignalSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_7__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_constant_signal__WEBPACK_IMPORTED_MODULE_5__["ConstantSignalComponent"]]); this.root.signals.entityManuallyPlaced.add(this.querySigalValue, this); } update() { // Set signals for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const pinsComp = entity.components.WiredPins; const signalComp = entity.components.ConstantSignal; pinsComp.slots[0].value = signalComp.signal; } } /** * Asks the entity to enter a valid signal code * @param {Entity} entity */ querySigalValue(entity) { if (!entity.components.ConstantSignal) { return; } // Ok, query, but also save the uid because it could get stale const uid = entity.uid; const signalValueInput = new _core_modal_dialog_forms__WEBPACK_IMPORTED_MODULE_2__["FormElementInput"]({ id: "signalValue", label: null, placeholder: "", defaultValue: "", validator: val => this.parseSignalCode(val), }); const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_1__["DialogWithForm"]({ app: this.root.app, title: "Set Signal", desc: "Enter a shape code, color or '0' or '1'", formElements: [signalValueInput], buttons: ["cancel:bad:escape", "ok:good:enter"], }); this.root.hud.parts.dialogs.internalShowDialog(dialog); // When confirmed, set the signal dialog.buttonSignals.ok.add(() => { if (!this.root || !this.root.entityMgr) { // Game got stopped return; } const entityRef = this.root.entityMgr.findByUid(uid, false); if (!entityRef) { // outdated return; } const constantComp = entityRef.components.ConstantSignal; if (!constantComp) { // no longer interesting return; } constantComp.signal = this.parseSignalCode(signalValueInput.getValue()); }); // When cancelled, destroy the entity again dialog.buttonSignals.cancel.add(() => { if (!this.root || !this.root.entityMgr) { // Game got stopped return; } const entityRef = this.root.entityMgr.findByUid(uid, false); if (!entityRef) { // outdated return; } const constantComp = entityRef.components.ConstantSignal; if (!constantComp) { // no longer interesting return; } this.root.logic.tryDeleteBuilding(entityRef); }); } /** * Tries to parse a signal code * @param {string} code * @returns {BaseItem} */ parseSignalCode(code) { code = trim__WEBPACK_IMPORTED_MODULE_0___default()(code); const codeLower = code.toLowerCase(); if (_colors__WEBPACK_IMPORTED_MODULE_4__["enumColors"][codeLower]) { return _items_color_item__WEBPACK_IMPORTED_MODULE_9__["COLOR_ITEM_SINGLETONS"][codeLower]; } if (code === "1" || codeLower === "true") { return _items_boolean_item__WEBPACK_IMPORTED_MODULE_8__["BOOL_TRUE_SINGLETON"]; } if (code === "0" || codeLower === "false") { return _items_boolean_item__WEBPACK_IMPORTED_MODULE_8__["BOOL_FALSE_SINGLETON"]; } if (_shape_definition__WEBPACK_IMPORTED_MODULE_10__["ShapeDefinition"].isValidShortKey(code)) { return this.root.shapeDefinitionMgr.getShapeItemFromShortKey(code); } return null; } } /***/ }), /***/ "./src/js/game/systems/display.js": /*!****************************************!*\ !*** ./src/js/game/systems/display.js ***! \****************************************/ /*! exports provided: DisplaySystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DisplaySystem", function() { return DisplaySystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../colors */ "./src/js/game/colors.js"); /* harmony import */ var _components_display__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/display */ "./src/js/game/components/display.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); class DisplaySystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_display__WEBPACK_IMPORTED_MODULE_4__["DisplayComponent"]]); /** @type {Object} */ this.displaySprites = {}; for (const colorId in _colors__WEBPACK_IMPORTED_MODULE_3__["enumColors"]) { if (colorId === _colors__WEBPACK_IMPORTED_MODULE_3__["enumColors"].uncolored) { continue; } this.displaySprites[colorId] = _core_loader__WEBPACK_IMPORTED_MODULE_1__["Loader"].getSprite("sprites/wires/display/" + colorId + ".png"); } } /** * Returns the color / value a display should show * @param {BaseItem} value * @returns {BaseItem} */ getDisplayItem(value) { if (!value) { return null; } switch (value.getItemType()) { case "boolean": { return /** @type {BooleanItem} */ (value).value ? _items_color_item__WEBPACK_IMPORTED_MODULE_6__["COLOR_ITEM_SINGLETONS"][_colors__WEBPACK_IMPORTED_MODULE_3__["enumColors"].white] : null; } case "color": { const item = /**@type {ColorItem} */ (value); return item.color === _colors__WEBPACK_IMPORTED_MODULE_3__["enumColors"].uncolored ? null : item; } case "shape": { return value; } default: window.assert(false, "Unknown item type: " + value.getItemType()); } } /** * Draws a given chunk * @param {import("../../core/draw_utils").DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; if (entity && entity.components.Display) { const pinsComp = entity.components.WiredPins; const network = pinsComp.slots[0].linkedNetwork; if (!network || !network.currentValue) { continue; } const value = this.getDisplayItem(network.currentValue); if (!value) { continue; } const origin = entity.components.StaticMapEntity.origin; if (value.getItemType() === "color") { this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( parameters, (origin.x + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, (origin.y + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize ); } else if (value.getItemType() === "shape") { value.drawItemCenteredClipped( (origin.x + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, (origin.y + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, parameters, 30 ); } } } } } /***/ }), /***/ "./src/js/game/systems/hub.js": /*!************************************!*\ !*** ./src/js/game/systems/hub.js ***! \************************************/ /*! exports provided: HubSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HubSystem", function() { return HubSystem; }); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../translations */ "./src/js/translations.js"); /* harmony import */ var _components_hub__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/hub */ "./src/js/game/components/hub.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_dpi_manager__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/dpi_manager */ "./src/js/core/dpi_manager.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_sprites__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../core/sprites */ "./src/js/core/sprites.js"); const HUB_SIZE_TILES = 4; const HUB_SIZE_PIXELS = HUB_SIZE_TILES * _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize; class HubSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_6__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_hub__WEBPACK_IMPORTED_MODULE_4__["HubComponent"]]); this.hubSprite = _core_loader__WEBPACK_IMPORTED_MODULE_1__["Loader"].getSprite("sprites/buildings/hub.png"); } /** * @param {DrawParameters} parameters */ draw(parameters) { for (let i = 0; i < this.allEntities.length; ++i) { this.drawEntity(parameters, this.allEntities[i]); } } update() { for (let i = 0; i < this.allEntities.length; ++i) { // Set hub goal const entity = this.allEntities[i]; const pinsComp = entity.components.WiredPins; pinsComp.slots[0].value = this.root.shapeDefinitionMgr.getShapeItemFromDefinition( this.root.hubGoals.currentGoal.definition ); } } /** * * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h * @param {number} dpi */ redrawHubBaseTexture(canvas, context, w, h, dpi) { // This method is quite ugly, please ignore it! context.scale(dpi, dpi); const parameters = new _core_draw_parameters__WEBPACK_IMPORTED_MODULE_0__["DrawParameters"]({ context, visibleRect: new _core_rectangle__WEBPACK_IMPORTED_MODULE_10__["Rectangle"](0, 0, w, h), desiredAtlasScale: _core_sprites__WEBPACK_IMPORTED_MODULE_11__["ORIGINAL_SPRITE_SCALE"], zoomLevel: dpi * 0.75, root: this.root, }); context.clearRect(0, 0, w, h); this.hubSprite.draw(context, 0, 0, w, h); const definition = this.root.hubGoals.currentGoal.definition; definition.drawCentered(45, 58, parameters, 36); const goals = this.root.hubGoals.currentGoal; const textOffsetX = 70; const textOffsetY = 61; // Deliver count const delivered = this.root.hubGoals.getCurrentGoalDelivered(); const deliveredText = "" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])(delivered); if (delivered > 9999) { context.font = "bold 16px GameFont"; } else if (delivered > 999) { context.font = "bold 20px GameFont"; } else { context.font = "bold 25px GameFont"; } context.fillStyle = "#64666e"; context.textAlign = "left"; context.fillText(deliveredText, textOffsetX, textOffsetY); // Required context.font = "13px GameFont"; context.fillStyle = "#a4a6b0"; context.fillText("/ " + Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])(goals.required), textOffsetX, textOffsetY + 13); // Reward const rewardText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].storyRewards[goals.reward].title.toUpperCase(); if (rewardText.length > 12) { context.font = "bold 8px GameFont"; } else { context.font = "bold 10px GameFont"; } context.fillStyle = "#fd0752"; context.textAlign = "center"; context.fillText(rewardText, HUB_SIZE_PIXELS / 2, 105); // Level "8" context.font = "bold 10px GameFont"; context.fillStyle = "#fff"; context.fillText("" + this.root.hubGoals.level, 27, 32); // "LVL" context.textAlign = "center"; context.fillStyle = "#fff"; context.font = "bold 6px GameFont"; context.fillText(_translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings.hub.levelShortcut, 27, 22); // "Deliver" context.fillStyle = "#64666e"; context.font = "bold 10px GameFont"; context.fillText(_translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings.hub.deliver.toUpperCase(), HUB_SIZE_PIXELS / 2, 30); // "To unlock" const unlockText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings.hub.toUnlock.toUpperCase(); if (unlockText.length > 15) { context.font = "bold 8px GameFont"; } else { context.font = "bold 10px GameFont"; } context.fillText(_translations__WEBPACK_IMPORTED_MODULE_3__["T"].buildings.hub.toUnlock.toUpperCase(), HUB_SIZE_PIXELS / 2, 92); context.textAlign = "left"; } /** * @param {DrawParameters} parameters * @param {Entity} entity */ drawEntity(parameters, entity) { const staticComp = entity.components.StaticMapEntity; if (!staticComp.shouldBeDrawn(parameters)) { return; } // Deliver count const delivered = this.root.hubGoals.getCurrentGoalDelivered(); const deliveredText = "" + Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["formatBigNumber"])(delivered); const dpi = Object(_core_dpi_manager__WEBPACK_IMPORTED_MODULE_8__["smoothenDpi"])(_core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].shapesSharpness * parameters.zoomLevel); const canvas = parameters.root.buffers.getForKey({ key: "hub", subKey: dpi + "/" + this.root.hubGoals.level + "/" + deliveredText, w: _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize * 4, h: _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize * 4, dpi, redrawMethod: this.redrawHubBaseTexture.bind(this), }); const extrude = 8; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_9__["drawSpriteClipped"])({ parameters, sprite: canvas, x: staticComp.origin.x * _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize - extrude, y: staticComp.origin.y * _core_config__WEBPACK_IMPORTED_MODULE_7__["globalConfig"].tileSize - extrude, w: HUB_SIZE_PIXELS + 2 * extrude, h: HUB_SIZE_PIXELS + 2 * extrude, originalW: HUB_SIZE_PIXELS * dpi, originalH: HUB_SIZE_PIXELS * dpi, }); } } /***/ }), /***/ "./src/js/game/systems/item_acceptor.js": /*!**********************************************!*\ !*** ./src/js/game/systems/item_acceptor.js ***! \**********************************************/ /*! exports provided: ItemAcceptorSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemAcceptorSystem", function() { return ItemAcceptorSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_item_acceptor__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/item_acceptor */ "./src/js/game/components/item_acceptor.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); class ItemAcceptorSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_item_acceptor__WEBPACK_IMPORTED_MODULE_4__["ItemAcceptorComponent"]]); } update() { const progress = this.root.dynamicTickrate.deltaSeconds * 2; // * 2 because its only a half tile for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const aceptorComp = entity.components.ItemAcceptor; const animations = aceptorComp.itemConsumptionAnimations; // Process item consumption animations to avoid items popping from the belts for (let animIndex = 0; animIndex < animations.length; ++animIndex) { const anim = animations[animIndex]; anim.animProgress += progress * this.root.hubGoals.getBeltBaseSpeed() * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts; if (anim.animProgress > 1) { // Original // animations.splice(animIndex, 1); // Faster variant Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["fastArrayDelete"])(animations, animIndex); animIndex -= 1; } } } } /** * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const acceptorComp = entity.components.ItemAcceptor; if (!acceptorComp) { continue; } const staticComp = entity.components.StaticMapEntity; for (let animIndex = 0; animIndex < acceptorComp.itemConsumptionAnimations.length; ++animIndex) { const { item, slotIndex, animProgress, direction } = acceptorComp.itemConsumptionAnimations[ animIndex ]; const slotData = acceptorComp.slots[slotIndex]; const realSlotPos = staticComp.localTileToWorld(slotData.pos); if (!chunk.tileSpaceRectangle.containsPoint(realSlotPos.x, realSlotPos.y)) { // Not within this chunk continue; } const fadeOutDirection = _core_vector__WEBPACK_IMPORTED_MODULE_3__["enumDirectionToVector"][staticComp.localDirectionToWorld(direction)]; const finalTile = realSlotPos.subScalars( fadeOutDirection.x * (animProgress / 2 - 0.5), fadeOutDirection.y * (animProgress / 2 - 0.5) ); item.drawItemCenteredClipped( (finalTile.x + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, (finalTile.y + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, parameters, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter ); } } } } /***/ }), /***/ "./src/js/game/systems/item_ejector.js": /*!*********************************************!*\ !*** ./src/js/game/systems/item_ejector.js ***! \*********************************************/ /*! exports provided: ItemEjectorSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemEjectorSystem", function() { return ItemEjectorSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _components_item_ejector__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/item_ejector */ "./src/js/game/components/item_ejector.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("systems/ejector"); class ItemEjectorSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_8__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_item_ejector__WEBPACK_IMPORTED_MODULE_6__["ItemEjectorComponent"]]); this.root.signals.entityAdded.add(this.checkForCacheInvalidation, this); this.root.signals.entityDestroyed.add(this.checkForCacheInvalidation, this); this.root.signals.postLoadHook.add(this.recomputeCache, this); /** * @type {Rectangle} */ this.areaToRecompute = null; } /** * * @param {Entity} entity */ checkForCacheInvalidation(entity) { if (!this.root.gameInitialized) { return; } if (!entity.components.StaticMapEntity) { return; } // Optimize for the common case: adding or removing one building at a time. Clicking // and dragging can cause up to 4 add/remove signals. const staticComp = entity.components.StaticMapEntity; const bounds = staticComp.getTileSpaceBounds(); const expandedBounds = bounds.expandedInAllDirections(2); if (this.areaToRecompute) { this.areaToRecompute = this.areaToRecompute.getUnion(expandedBounds); } else { this.areaToRecompute = expandedBounds; } } /** * Precomputes the cache, which makes up for a huge performance improvement */ recomputeCache() { if (this.areaToRecompute) { logger.log("Recomputing cache using rectangle"); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderChanges) { this.root.hud.parts.changesDebugger.renderChange( "ejector-area", this.areaToRecompute, "#fe50a6" ); } this.recomputeAreaCache(); this.areaToRecompute = null; } else { logger.log("Full cache recompute"); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderChanges) { this.root.hud.parts.changesDebugger.renderChange( "ejector-full", new _core_rectangle__WEBPACK_IMPORTED_MODULE_3__["Rectangle"](-1000, -1000, 2000, 2000), "#fe50a6" ); } // Try to find acceptors for every ejector for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; this.recomputeSingleEntityCache(entity); } } } /** * Recomputes the cache in the given area */ recomputeAreaCache() { const area = this.areaToRecompute; let entryCount = 0; logger.log("Recomputing area:", area.x, area.y, "/", area.w, area.h); // Store the entities we already recomputed, so we don't do work twice const recomputedEntities = new Set(); for (let x = area.x; x < area.right(); ++x) { for (let y = area.y; y < area.bottom(); ++y) { const entities = this.root.map.getLayersContentsMultipleXY(x, y); for (let i = 0; i < entities.length; ++i) { const entity = entities[i]; // Recompute the entity in case its relevant for this system and it // hasn't already been computed if (!recomputedEntities.has(entity.uid) && entity.components.ItemEjector) { recomputedEntities.add(entity.uid); this.recomputeSingleEntityCache(entity); } } } } return entryCount; } /** * @param {Entity} entity */ recomputeSingleEntityCache(entity) { const ejectorComp = entity.components.ItemEjector; const staticComp = entity.components.StaticMapEntity; for (let slotIndex = 0; slotIndex < ejectorComp.slots.length; ++slotIndex) { const ejectorSlot = ejectorComp.slots[slotIndex]; // Clear the old cache. ejectorSlot.cachedDestSlot = null; ejectorSlot.cachedTargetEntity = null; ejectorSlot.cachedBeltPath = null; // Figure out where and into which direction we eject items const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos); const ejectSlotWsDirection = staticComp.localDirectionToWorld(ejectorSlot.direction); const ejectSlotWsDirectionVector = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirectionToVector"][ejectSlotWsDirection]; const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector); // Try to find the given acceptor component to take the item // Since there can be cross layer dependencies, check on all layers const targetEntities = this.root.map.getLayersContentsMultipleXY( ejectSlotTargetWsTile.x, ejectSlotTargetWsTile.y ); for (let i = 0; i < targetEntities.length; ++i) { const targetEntity = targetEntities[i]; const targetStaticComp = targetEntity.components.StaticMapEntity; const targetBeltComp = targetEntity.components.Belt; // Check for belts (special case) if (targetBeltComp) { const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirection"].top); if (ejectSlotWsDirection === beltAcceptingDirection) { ejectorSlot.cachedTargetEntity = targetEntity; ejectorSlot.cachedBeltPath = targetBeltComp.assignedPath; break; } } // Check for item acceptors const targetAcceptorComp = targetEntity.components.ItemAcceptor; if (!targetAcceptorComp) { // Entity doesn't accept items continue; } const matchingSlot = targetAcceptorComp.findMatchingSlot( targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile), targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection) ); if (!matchingSlot) { // No matching slot found continue; } // A slot can always be connected to one other slot only ejectorSlot.cachedTargetEntity = targetEntity; ejectorSlot.cachedDestSlot = matchingSlot; break; } } } update() { if (this.areaToRecompute) { this.recomputeCache(); } // Precompute effective belt speed let progressGrowth = 2 * this.root.dynamicTickrate.deltaSeconds; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.instantBelts) { progressGrowth = 1; } // Go over all cache entries for (let i = 0; i < this.allEntities.length; ++i) { const sourceEntity = this.allEntities[i]; const sourceEjectorComp = sourceEntity.components.ItemEjector; if (!sourceEjectorComp.enabled) { continue; } const slots = sourceEjectorComp.slots; for (let j = 0; j < slots.length; ++j) { const sourceSlot = slots[j]; const item = sourceSlot.item; if (!item) { // No item available to be ejected continue; } const targetEntity = sourceSlot.cachedTargetEntity; // Advance items on the slot sourceSlot.progress = Math.min( 1, sourceSlot.progress + progressGrowth * this.root.hubGoals.getBeltBaseSpeed() * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].itemSpacingOnBelts ); // Check if we are still in the process of ejecting, can't proceed then if (sourceSlot.progress < 1.0) { continue; } // Check if we are ejecting to a belt path const destPath = sourceSlot.cachedBeltPath; if (destPath) { // Try passing the item over if (destPath.tryAcceptItem(item)) { sourceSlot.item = null; } // Always stop here, since there can *either* be a belt path *or* // a slot continue; } // Check if the target acceptor can actually accept this item const destSlot = sourceSlot.cachedDestSlot; if (destSlot) { const targetAcceptorComp = targetEntity.components.ItemAcceptor; if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) { continue; } // Try to hand over the item if (this.tryPassOverItem(item, targetEntity, destSlot.index)) { // Handover successful, clear slot targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item); sourceSlot.item = null; continue; } } } } } /** * * @param {BaseItem} item * @param {Entity} receiver * @param {number} slotIndex */ tryPassOverItem(item, receiver, slotIndex) { // Try figuring out how what to do with the item // TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell. // Also its just a few cases (hope it stays like this .. :x). const beltComp = receiver.components.Belt; if (beltComp) { const path = beltComp.assignedPath; window.assert(path, "belt has no path"); if (path.tryAcceptItem(item)) { return true; } // Belt can have nothing else return false; } const itemProcessorComp = receiver.components.ItemProcessor; if (itemProcessorComp) { // @todo HACK // Check if there are pins, and if so if they are connected if (itemProcessorComp.type === _components_item_processor__WEBPACK_IMPORTED_MODULE_9__["enumItemProcessorTypes"].filter) { const pinsComp = receiver.components.WiredPins; if (pinsComp && pinsComp.slots.length === 1) { const network = pinsComp.slots[0].linkedNetwork; if (!network || !network.currentValue) { return false; } } } // Its an item processor .. if (itemProcessorComp.tryTakeItem(item, slotIndex)) { return true; } // Item processor can have nothing else return false; } const undergroundBeltComp = receiver.components.UndergroundBelt; if (undergroundBeltComp) { // Its an underground belt. yay. if ( undergroundBeltComp.tryAcceptExternalItem( item, this.root.hubGoals.getUndergroundBeltBaseSpeed() ) ) { return true; } // Underground belt can have nothing else return false; } const storageComp = receiver.components.Storage; if (storageComp) { // It's a storage if (storageComp.canAcceptItem(item)) { storageComp.takeItem(item); return true; } // Storage can't have anything else return false; } return false; } /** * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const ejectorComp = entity.components.ItemEjector; if (!ejectorComp) { continue; } const staticComp = entity.components.StaticMapEntity; for (let i = 0; i < ejectorComp.slots.length; ++i) { const slot = ejectorComp.slots[i]; const ejectedItem = slot.item; if (!ejectedItem) { // No item continue; } const realPosition = staticComp.localTileToWorld(slot.pos); if (!chunk.tileSpaceRectangle.containsPoint(realPosition.x, realPosition.y)) { // Not within this chunk continue; } const realDirection = staticComp.localDirectionToWorld(slot.direction); const realDirectionVector = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirectionToVector"][realDirection]; const tileX = realPosition.x + 0.5 + realDirectionVector.x * 0.5 * slot.progress; const tileY = realPosition.y + 0.5 + realDirectionVector.y * 0.5 * slot.progress; const worldX = tileX * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const worldY = tileY * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; ejectedItem.drawItemCenteredClipped( worldX, worldY, parameters, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter ); } } } } /***/ }), /***/ "./src/js/game/systems/item_processor.js": /*!***********************************************!*\ !*** ./src/js/game/systems/item_processor.js ***! \***********************************************/ /*! exports provided: ItemProcessorSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ItemProcessorSystem", function() { return ItemProcessorSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../colors */ "./src/js/game/colors.js"); /* harmony import */ var _components_item_processor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/item_processor */ "./src/js/game/components/item_processor.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../items/shape_item */ "./src/js/game/items/shape_item.js"); /* harmony import */ var _custom_modBuildings__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../custom/modBuildings */ "./src/js/game/custom/modBuildings.js"); class ItemProcessorSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_5__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_item_processor__WEBPACK_IMPORTED_MODULE_3__["ItemProcessorComponent"]]); } update() { for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const processorComp = entity.components.ItemProcessor; const ejectorComp = entity.components.ItemEjector; // First of all, process the current recipe if (processorComp.secondsUntilEject > 0) { processorComp.secondsUntilEject -= this.root.dynamicTickrate.deltaSeconds; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.instantProcessors) { processorComp.secondsUntilEject = 0; } } else if (processorComp.itemsToEject.length == 0) { processorComp.secondsUntilEject = 0; } // Check if we have any finished items we can eject if ( processorComp.secondsUntilEject <= 0 && // it was processed in time processorComp.itemsToEject.length > 0 // we have some items left to eject ) { for (let itemIndex = 0; itemIndex < processorComp.itemsToEject.length; ++itemIndex) { const { item, requiredSlot, preferredSlot } = processorComp.itemsToEject[itemIndex]; let slot = null; if (requiredSlot !== null && requiredSlot !== undefined) { // We have a slot override, check if that is free if (ejectorComp.canEjectOnSlot(requiredSlot)) { slot = requiredSlot; } } else if (preferredSlot !== null && preferredSlot !== undefined) { // We have a slot preference, try using it but otherwise use a free slot if (ejectorComp.canEjectOnSlot(preferredSlot)) { slot = preferredSlot; } else { slot = ejectorComp.getFirstFreeSlot(); } } else { // We can eject on any slot slot = ejectorComp.getFirstFreeSlot(); } if (slot !== null) { // Alright, we can actually eject if (!ejectorComp.tryEject(slot, item)) { window.assert(false, "Failed to eject"); } else { processorComp.itemsToEject.splice(itemIndex, 1); itemIndex -= 1; } } } } // Check if we have an empty queue and can start a new charge if (processorComp.itemsToEject.length === 0) { if (processorComp.inputSlots.length >= processorComp.inputsPerCharge) { this.startNewCharge(entity); } } } } /** * Starts a new charge for the entity * @param {Entity} entity */ startNewCharge(entity) { const processorComp = entity.components.ItemProcessor; // First, take items const items = processorComp.inputSlots; processorComp.inputSlots = []; /** @type {Array.<{ item: BaseItem, sourceSlot: number }>} */ const itemsBySlot = []; for (let i = 0; i < items.length; ++i) { itemsBySlot[items[i].sourceSlot] = items[i]; } const baseSpeed = this.root.hubGoals.getProcessorBaseSpeed(processorComp.type); processorComp.secondsUntilEject += 1 / baseSpeed; /** @type {Array<{item: BaseItem, requiredSlot?: number, preferredSlot?: number}>} */ const outItems = []; // Whether to track the production towards the analytics let trackProduction = true; // DO SOME MAGIC if (_custom_modBuildings__WEBPACK_IMPORTED_MODULE_9__["customBuildingData"][processorComp.type]) { let custom = _custom_modBuildings__WEBPACK_IMPORTED_MODULE_9__["customBuildingData"][processorComp.type]; trackProduction = custom.process({ items: itemsBySlot.map(e => e.item), itemsBySlot, itemsRaw: items, trackProduction, entity, outItems, system: this, }); } else switch (processorComp.type) { // SPLITTER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].splitterWires: case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].splitter: { trackProduction = false; const availableSlots = entity.components.ItemEjector.slots.length; let nextSlot = processorComp.nextOutputSlot++ % availableSlots; for (let i = 0; i < items.length; ++i) { outItems.push({ item: items[i].item, preferredSlot: (nextSlot + i) % availableSlots, }); } break; } // CUTTER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].cutter: { const inputItem = /** @type {ShapeItem} */ (items[0].item); window.assert(inputItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for cut is not a shape"); const inputDefinition = inputItem.definition; const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition); for (let i = 0; i < cutDefinitions.length; ++i) { const definition = cutDefinitions[i]; if (!definition.isEntirelyEmpty()) { outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), requiredSlot: i, }); } } break; } // CUTTER (Quad) case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].cutterQuad: { const inputItem = /** @type {ShapeItem} */ (items[0].item); window.assert(inputItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for cut is not a shape"); const inputDefinition = inputItem.definition; const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition); for (let i = 0; i < cutDefinitions.length; ++i) { const definition = cutDefinitions[i]; if (!definition.isEntirelyEmpty()) { outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), requiredSlot: i, }); } } break; } // ROTATER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].rotater: { const inputItem = /** @type {ShapeItem} */ (items[0].item); window.assert(inputItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW( inputDefinition ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), }); break; } // ROTATER (CCW) case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].rotaterCCW: { const inputItem = /** @type {ShapeItem} */ (items[0].item); window.assert(inputItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW( inputDefinition ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), }); break; } // ROTATER (FL) case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].rotaterFL: { const inputItem = /** @type {ShapeItem} */ (items[0].item); window.assert(inputItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateFL( inputDefinition ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), }); break; } // STACKER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].stacker: { const lowerItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); const upperItem = /** @type {ShapeItem} */ (itemsBySlot[1].item); window.assert(lowerItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for lower stack is not a shape"); window.assert(upperItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for upper stack is not a shape"); const stackedDefinition = this.root.shapeDefinitionMgr.shapeActionStack( lowerItem.definition, upperItem.definition ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition), }); break; } // TRASH case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].trash: { // Well this one is easy .. simply do nothing with the item break; } // MIXER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].mixer: { // Find both colors and combine them const item1 = /** @type {ColorItem} */ (items[0].item); const item2 = /** @type {ColorItem} */ (items[1].item); window.assert(item1 instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for color mixer is not a color"); window.assert(item2 instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for color mixer is not a color"); const color1 = item1.color; const color2 = item2.color; // Try finding mixer color, and if we can't mix it we simply return the same color const mixedColor = _colors__WEBPACK_IMPORTED_MODULE_2__["enumColorMixingResults"][color1][color2]; let resultColor = color1; if (mixedColor) { resultColor = mixedColor; } outItems.push({ item: _items_color_item__WEBPACK_IMPORTED_MODULE_7__["COLOR_ITEM_SINGLETONS"][resultColor], }); break; } // PAINTER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].painter: { const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); const colorItem = /** @type {ColorItem} */ (itemsBySlot[1].item); const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem.definition, colorItem.color ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition), }); break; } // PAINTER (DOUBLE) case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].painterDouble: { const shapeItem1 = /** @type {ShapeItem} */ (itemsBySlot[0].item); const shapeItem2 = /** @type {ShapeItem} */ (itemsBySlot[1].item); const colorItem = /** @type {ColorItem} */ (itemsBySlot[2].item); window.assert(shapeItem1 instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for painter is not a shape"); window.assert(shapeItem2 instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for painter is not a shape"); window.assert(colorItem instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for painter is not a color"); const colorizedDefinition1 = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem1.definition, colorItem.color ); const colorizedDefinition2 = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem2.definition, colorItem.color ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1), }); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2), }); break; } // PAINTER (QUAD) case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].painterQuad: { const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); const colorItem1 = /** @type {ColorItem} */ (itemsBySlot[1].item); const colorItem2 = /** @type {ColorItem} */ (itemsBySlot[2].item); const colorItem3 = /** @type {ColorItem} */ (itemsBySlot[3].item); const colorItem4 = /** @type {ColorItem} */ (itemsBySlot[4].item); window.assert(shapeItem instanceof _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"], "Input for painter is not a shape"); window.assert(colorItem1 instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for painter is not a color"); window.assert(colorItem2 instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for painter is not a color"); window.assert(colorItem3 instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for painter is not a color"); window.assert(colorItem4 instanceof _items_color_item__WEBPACK_IMPORTED_MODULE_7__["ColorItem"], "Input for painter is not a color"); const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith4Colors( shapeItem.definition, [colorItem2.color, colorItem3.color, colorItem4.color, colorItem1.color] ); outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition), }); break; } // FILTER case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].filter: { // TODO trackProduction = false; const item = itemsBySlot[0].item; const network = entity.components.WiredPins.slots[0].linkedNetwork; if (!network || !network.currentValue) { outItems.push({ item, requiredSlot: 1, }); break; } const value = network.currentValue; if (value.equals(_items_boolean_item__WEBPACK_IMPORTED_MODULE_6__["BOOL_TRUE_SINGLETON"]) || value.equals(item)) { outItems.push({ item, requiredSlot: 0, }); } else { outItems.push({ item, requiredSlot: 1, }); } break; } // HUB case _components_item_processor__WEBPACK_IMPORTED_MODULE_3__["enumItemProcessorTypes"].hub: { trackProduction = false; const hubComponent = entity.components.Hub; window.assert(hubComponent, "Hub item processor has no hub component"); for (let i = 0; i < items.length; ++i) { const item = /** @type {BaseItem} */ (items[i].item); this.root.hubGoals.handleDeliveredByHash(item.getHash()); } break; } default: window.assert(false, "Unkown item processor type: " + processorComp.type); } // Track produced items if (trackProduction) { for (let i = 0; i < outItems.length; ++i) { this.root.signals.itemProduced.dispatch(outItems[i].item); } } if (outItems.length > 1) { const baseBeltSpeed = this.root.hubGoals.getBeltBaseSpeed(); processorComp.secondsUntilEject -= (outItems.length - 1) / baseBeltSpeed; } processorComp.itemsToEject = outItems; } } /***/ }), /***/ "./src/js/game/systems/lever.js": /*!**************************************!*\ !*** ./src/js/game/systems/lever.js ***! \**************************************/ /*! exports provided: LeverSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LeverSystem", function() { return LeverSystem; }); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _components_lever__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/lever */ "./src/js/game/components/lever.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); class LeverSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_0__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_lever__WEBPACK_IMPORTED_MODULE_1__["LeverComponent"]]); this.spriteOn = _core_loader__WEBPACK_IMPORTED_MODULE_5__["Loader"].getSprite("sprites/wires/lever_on.png"); this.spriteOff = _core_loader__WEBPACK_IMPORTED_MODULE_5__["Loader"].getSprite("sprites/buildings/lever.png"); } update() { for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const leverComp = entity.components.Lever; const pinsComp = entity.components.WiredPins; // Simply sync the status to the first slot pinsComp.slots[0].value = leverComp.toggled ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_2__["BOOL_FALSE_SINGLETON"]; } } /** * Draws a given chunk * @param {import("../../core/draw_utils").DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const leverComp = entity.components.Lever; if (leverComp) { const sprite = leverComp.toggled ? this.spriteOn : this.spriteOff; const origin = entity.components.StaticMapEntity.origin; sprite.drawCached( parameters, origin.x * _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].tileSize, origin.y * _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].tileSize ); } } } } /***/ }), /***/ "./src/js/game/systems/logic_gate.js": /*!*******************************************!*\ !*** ./src/js/game/systems/logic_gate.js ***! \*******************************************/ /*! exports provided: LogicGateSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LogicGateSystem", function() { return LogicGateSystem; }); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../colors */ "./src/js/game/colors.js"); /* harmony import */ var _components_logic_gate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/logic_gate */ "./src/js/game/components/logic_gate.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _items_color_item__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../items/color_item */ "./src/js/game/items/color_item.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _items_shape_item__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../items/shape_item */ "./src/js/game/items/shape_item.js"); class LogicGateSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_4__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["LogicGateComponent"]]); this.boundOperations = { [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].and]: this.compute_AND.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].not]: this.compute_NOT.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].xor]: this.compute_XOR.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].or]: this.compute_OR.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].transistor]: this.compute_IF.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].rotater]: this.compute_ROTATE.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].analyzer]: this.compute_ANALYZE.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].cutter]: this.compute_CUT.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].unstacker]: this.compute_UNSTACK.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].shapecompare]: this.compute_SHAPECOMPARE.bind(this), [_components_logic_gate__WEBPACK_IMPORTED_MODULE_2__["enumLogicGateType"].adder]: this.compute_ADD.bind(this), }; } update() { for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const logicComp = entity.components.LogicGate; const slotComp = entity.components.WiredPins; const slotValues = []; for (let i = 0; i < slotComp.slots.length; ++i) { const slot = slotComp.slots[i]; if (slot.type !== _components_wired_pins__WEBPACK_IMPORTED_MODULE_3__["enumPinSlotType"].logicalAcceptor) { continue; } if (slot.linkedNetwork) { slotValues.push(slot.linkedNetwork.currentValue); } else { slotValues.push(null); } } const result = this.boundOperations[logicComp.type](slotValues); if (Array.isArray(result)) { let resultIndex = 0; for (let i = 0; i < slotComp.slots.length; ++i) { const slot = slotComp.slots[i]; if (slot.type !== _components_wired_pins__WEBPACK_IMPORTED_MODULE_3__["enumPinSlotType"].logicalEjector) { continue; } slot.value = result[resultIndex++]; } } else { // @TODO: For now we hardcode the value to always be slot 0 window.assert( slotValues.length === slotComp.slots.length - 1, "Bad slot config, should have N acceptor slots and 1 ejector" ); window.assert(slotComp.slots[0].type === _components_wired_pins__WEBPACK_IMPORTED_MODULE_3__["enumPinSlotType"].logicalEjector, "Slot 0 should be ejector"); slotComp.slots[0].value = result; } } } /** * @param {Array} parameters * @returns {BaseItem} */ compute_AND(parameters) { window.assert(parameters.length === 2, "bad parameter count for AND"); const param1 = parameters[0]; const param2 = parameters[1]; if (!param1 || !param2) { // Not enough params return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } const itemType = param1.getItemType(); if (itemType !== param2.getItemType()) { // Differing type return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } if (itemType === "boolean") { return /** @type {BooleanItem} */ (param1).value && /** @type {BooleanItem} */ (param2).value ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_NOT(parameters) { const item = parameters[0]; if (!item) { return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"]; } if (item.getItemType() !== "boolean") { // Not a boolean actually return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } const value = /** @type {BooleanItem} */ (item).value; return value ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"]; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_XOR(parameters) { window.assert(parameters.length === 2, "bad parameter count for XOR"); const param1 = parameters[0]; const param2 = parameters[1]; if (!param1 && !param2) { // Not enough params return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } // Check for the right types if (param1 && param1.getItemType() !== "boolean") { return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } if (param2 && param2.getItemType() !== "boolean") { return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } const valueParam1 = param1 ? /** @type {BooleanItem} */ (param1).value : 0; const valueParam2 = param2 ? /** @type {BooleanItem} */ (param2).value : 0; return valueParam1 ^ valueParam2 ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_OR(parameters) { window.assert(parameters.length === 2, "bad parameter count for OR"); const param1 = parameters[0]; const param2 = parameters[1]; if (!param1 && !param2) { // Not enough params return _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } const valueParam1 = param1 && param1.getItemType() === "boolean" ? /** @type {BooleanItem} */ (param1).value : 0; const valueParam2 = param2 && param2.getItemType() === "boolean" ? /** @type {BooleanItem} */ (param2).value : 0; return valueParam1 || valueParam2 ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_IF(parameters) { window.assert(parameters.length === 2, "bad parameter count for IF"); const flag = parameters[0]; const value = parameters[1]; if (!flag || !value) { // Not enough params return null; } if (flag.getItemType() !== "boolean") { // Flag is not a boolean return null; } // pass through item if (/** @type {BooleanItem} */ (flag).value) { return value; } return null; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_ROTATE(parameters) { const item = parameters[0]; if (!item || item.getItemType() !== "shape") { // Not a shape return null; } const definition = /** @type {ShapeItem} */ (item).definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(definition); return this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition); } /** * @param {Array} parameters * @returns {[BaseItem, BaseItem]} */ compute_ANALYZE(parameters) { const item = parameters[0]; if (!item || item.getItemType() !== "shape") { // Not a shape return [null, null]; } const definition = /** @type {ShapeItem} */ (item).definition; const lowerLayer = /** @type {import("../shape_definition").ShapeLayer} */ (definition.layers[0]); if (!lowerLayer) { return [null, null]; } const topRightContent = lowerLayer[0]; if (!topRightContent || topRightContent.subShape === null) { return [null, null]; } const newDefinition = new _shape_definition__WEBPACK_IMPORTED_MODULE_7__["ShapeDefinition"]({ layers: [ [ { subShape: topRightContent.subShape, color: _colors__WEBPACK_IMPORTED_MODULE_1__["enumColors"].uncolored }, { subShape: topRightContent.subShape, color: _colors__WEBPACK_IMPORTED_MODULE_1__["enumColors"].uncolored }, { subShape: topRightContent.subShape, color: _colors__WEBPACK_IMPORTED_MODULE_1__["enumColors"].uncolored }, { subShape: topRightContent.subShape, color: _colors__WEBPACK_IMPORTED_MODULE_1__["enumColors"].uncolored }, ], ], }); return [ _items_color_item__WEBPACK_IMPORTED_MODULE_6__["COLOR_ITEM_SINGLETONS"][topRightContent.color], this.root.shapeDefinitionMgr.getShapeItemFromDefinition(newDefinition), ]; } /** * @param {Array} parameters * @returns {[BaseItem, BaseItem]} */ compute_CUT(parameters) { const item = parameters[0]; if (!item || item.getItemType() !== "shape") { // Not a shape return [null, null]; } const definition = /** @type {ShapeItem} */ (item).definition; const result = this.root.shapeDefinitionMgr.shapeActionCutHalf(definition); return [ result[0].isEntirelyEmpty() ? null : this.root.shapeDefinitionMgr.getShapeItemFromDefinition(result[0]), result[1].isEntirelyEmpty() ? null : this.root.shapeDefinitionMgr.getShapeItemFromDefinition(result[1]), ]; } /** * @param {Array} parameters * @returns {[BaseItem, BaseItem]} */ compute_UNSTACK(parameters) { const item = parameters[0]; if (!item || item.getItemType() !== "shape") { // Not a shape return [null, null]; } const definition = /** @type {ShapeItem} */ (item).definition; const layers = /** @type {Array} */ (definition.layers); const upperLayerDefinition = new _shape_definition__WEBPACK_IMPORTED_MODULE_7__["ShapeDefinition"]({ layers: [layers[layers.length - 1]], }); const lowerLayers = layers.slice(0, layers.length - 1); const lowerLayerDefinition = lowerLayers.length > 0 ? new _shape_definition__WEBPACK_IMPORTED_MODULE_7__["ShapeDefinition"]({ layers: lowerLayers }) : null; return [ lowerLayerDefinition ? this.root.shapeDefinitionMgr.getShapeItemFromDefinition(lowerLayerDefinition) : null, this.root.shapeDefinitionMgr.getShapeItemFromDefinition(upperLayerDefinition), ]; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_SHAPECOMPARE(parameters) { const itemA = parameters[0]; const itemB = parameters[1]; return itemA && itemB && itemA.getItemType() === "shape" && itemB.getItemType() === "shape" && /** @type {ShapeItem} */ (itemA).definition.getHash() === /** @type {ShapeItem} */ (itemB).definition.getHash() ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } /** * @param {Array} parameters * @returns {BaseItem} */ compute_ADD(parameters) { const itemA = parameters[0]; const itemB = parameters[1]; if (itemA && itemB && itemA.getItemType() == "shape" && itemB.getItemType() == "shape") { let defA = /** @type {ShapeItem} */ (itemA).definition; let defB = /** @type {ShapeItem} */ (itemB).definition; let defR = defA.cloneAndStackWith(defB); return _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"].createFromHash(defR.getHash()); } if (itemA && itemB && itemA.getItemType() == "shape" && itemB.getItemType() == "color") { let defA = /** @type {ShapeItem} */ (itemA).definition; let colorB = /** @type {ColorItem} */ (itemB).color; let defR = defA.cloneAndPaintWith(colorB); return _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"].createFromHash(defR.getHash()); } if (itemA && itemB && itemA.getItemType() == "color" && itemB.getItemType() == "shape") { let defA = /** @type {ShapeItem} */ (itemB).definition; let colorB = /** @type {ColorItem} */ (itemA).color; let defR = defA.cloneAndPaintWith(colorB); return _items_shape_item__WEBPACK_IMPORTED_MODULE_8__["ShapeItem"].createFromHash(defR.getHash()); } if (itemA && itemB && itemA.getItemType() == "color" && itemB.getItemType() == "color") { let colorA = /** @type {ColorItem} */ (itemA).color; let colorB = /** @type {ColorItem} */ (itemB).color; let colorR = _colors__WEBPACK_IMPORTED_MODULE_1__["enumColorMixingResults"][colorA][colorB]; return _items_color_item__WEBPACK_IMPORTED_MODULE_6__["COLOR_ITEM_SINGLETONS"][colorR]; } return null; } } /***/ }), /***/ "./src/js/game/systems/map_resources.js": /*!**********************************************!*\ !*** ./src/js/game/systems/map_resources.js ***! \**********************************************/ /*! exports provided: MapResourcesSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapResourcesSystem", function() { return MapResourcesSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _game_system__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../game_system */ "./src/js/game/game_system.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _theme__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../theme */ "./src/js/game/theme.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/draw_utils */ "./src/js/core/draw_utils.js"); class MapResourcesSystem extends _game_system__WEBPACK_IMPORTED_MODULE_2__["GameSystem"] { /** * Draws the map resources * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const basicChunkBackground = this.root.buffers.getForKey({ key: "mapresourcebg", subKey: chunk.renderKey, w: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, h: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, dpi: 1, redrawMethod: this.generateChunkBackground.bind(this, chunk), }); parameters.context.imageSmoothingEnabled = false; Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_5__["drawSpriteClipped"])({ parameters, sprite: basicChunkBackground, x: chunk.tileX * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, y: chunk.tileY * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, w: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, h: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize, originalW: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, originalH: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize, }); parameters.context.imageSmoothingEnabled = true; parameters.context.globalAlpha = 0.5; if (this.root.app.settings.getAllSettings().lowQualityMapResources) { // LOW QUALITY: Draw patch items only for (let i = 0; i < chunk.patches.length; ++i) { const patch = chunk.patches[i]; const destX = chunk.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize + patch.pos.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const destY = chunk.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkWorldSize + patch.pos.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const diameter = Math.min(80, 40 / parameters.zoomLevel); patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter); } } else { // HIGH QUALITY: Draw all items const layer = chunk.lowerLayer; for (let x = 0; x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++x) { const row = layer[x]; const worldX = (chunk.tileX + x) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; for (let y = 0; y < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++y) { const lowerItem = row[y]; if (lowerItem) { const worldY = (chunk.tileY + y) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize; const destX = worldX + _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize; const destY = worldY + _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize; lowerItem.drawItemCenteredClipped( destX, destY, parameters, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter ); } } } } parameters.context.globalAlpha = 1; } /** * * @param {MapChunkView} chunk * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h * @param {number} dpi */ generateChunkBackground(chunk, canvas, context, w, h, dpi) { if (this.root.app.settings.getAllSettings().disableTileGrid) { // The map doesn't draw a background, so we have to context.fillStyle = _theme__WEBPACK_IMPORTED_MODULE_4__["THEME"].map.background; context.fillRect(0, 0, w, h); } else { context.clearRect(0, 0, w, h); } context.globalAlpha = 0.5; const layer = chunk.lowerLayer; for (let x = 0; x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++x) { const row = layer[x]; for (let y = 0; y < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++y) { const item = row[y]; if (item) { context.fillStyle = item.getBackgroundColorAsResource(); context.fillRect(x, y, 1, 1); } } } } } /***/ }), /***/ "./src/js/game/systems/miner.js": /*!**************************************!*\ !*** ./src/js/game/systems/miner.js ***! \**************************************/ /*! exports provided: MinerSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MinerSystem", function() { return MinerSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _components_miner__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/miner */ "./src/js/game/components/miner.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); class MinerSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_6__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_miner__WEBPACK_IMPORTED_MODULE_4__["MinerComponent"]]); } update() { let miningSpeed = this.root.hubGoals.getMinerBaseSpeed(); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.instantMiners) { miningSpeed *= 100; } for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; // Check if miner is above an actual tile const minerComp = entity.components.Miner; if (!minerComp.cachedMinedItem) { const staticComp = entity.components.StaticMapEntity; const tileBelow = this.root.map.getLowerLayerContentXY( staticComp.origin.x, staticComp.origin.y ); if (!tileBelow) { continue; } minerComp.cachedMinedItem = tileBelow; } // First, try to get rid of chained items if (minerComp.itemChainBuffer.length > 0) { if (this.tryPerformMinerEject(entity, minerComp.itemChainBuffer[0])) { minerComp.itemChainBuffer.shift(); continue; } } let now = this.root.time.now(); if (minerComp.lastMiningTime < now) { if (this.tryPerformMinerEject(entity, minerComp.cachedMinedItem)) { // Analytics hook this.root.signals.itemProduced.dispatch(minerComp.cachedMinedItem); // Actually mine minerComp.lastMiningTime = Math.max(now, minerComp.lastMiningTime + 1 / miningSpeed); } } } } /** * * @param {Entity} entity * @param {BaseItem} item */ tryPerformMinerEject(entity, item) { const minerComp = entity.components.Miner; const ejectComp = entity.components.ItemEjector; const staticComp = entity.components.StaticMapEntity; // Check if we are a chained miner if (minerComp.chainable) { const ejectingSlot = ejectComp.slots[0]; const ejectingPos = staticComp.localTileToWorld(ejectingSlot.pos); const ejectingDirection = staticComp.localDirectionToWorld(ejectingSlot.direction); const targetTile = ejectingPos.add(_core_vector__WEBPACK_IMPORTED_MODULE_2__["enumDirectionToVector"][ejectingDirection]); const targetContents = this.root.map.getTileContent(targetTile, "regular"); // Check if we are connected to another miner and thus do not eject directly if (targetContents) { const targetMinerComp = targetContents.components.Miner; if (targetMinerComp) { if (targetMinerComp.tryAcceptChainedItem(item)) { return true; } else { return false; } } } } // Seems we are a regular miner or at the end of a row, try actually ejecting if (ejectComp.tryEject(0, item)) { return true; } return false; } /** * * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const minerComp = entity.components.Miner; if (!minerComp) { continue; } const staticComp = entity.components.StaticMapEntity; if (!minerComp.cachedMinedItem) { continue; } // Draw the item background - this is to hide the ejected item animation from // the item ejecto const padding = 3; const destX = staticComp.origin.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + padding; const destY = staticComp.origin.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + padding; const dimensions = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize - 2 * padding; if (parameters.visibleRect.containsRect4Params(destX, destY, dimensions, dimensions)) { parameters.context.fillStyle = minerComp.cachedMinedItem.getBackgroundColorAsResource(); parameters.context.fillRect(destX, destY, dimensions, dimensions); } minerComp.cachedMinedItem.drawItemCenteredClipped( (0.5 + staticComp.origin.x) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, (0.5 + staticComp.origin.y) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, parameters, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].defaultItemDiameter ); } } } /***/ }), /***/ "./src/js/game/systems/static_map_entity.js": /*!**************************************************!*\ !*** ./src/js/game/systems/static_map_entity.js ***! \**************************************************/ /*! exports provided: StaticMapEntitySystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StaticMapEntitySystem", function() { return StaticMapEntitySystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _game_system__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../game_system */ "./src/js/game/game_system.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); class StaticMapEntitySystem extends _game_system__WEBPACK_IMPORTED_MODULE_2__["GameSystem"] { constructor(root) { super(root); /** @type {Set} */ this.drawnUids = new Set(); this.root.signals.gameFrameStarted.add(this.clearUidList, this); } /** * Clears the uid list when a new frame started */ clearUidList() { this.drawnUids.clear(); } /** * Draws the static entities * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.doNotRenderStatics) { return; } const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const staticComp = entity.components.StaticMapEntity; const sprite = staticComp.getSprite(); if (sprite) { // Avoid drawing an entity twice which has been drawn for // another chunk already if (this.drawnUids.has(entity.uid)) { continue; } this.drawnUids.add(entity.uid); staticComp.drawSpriteOnBoundsClipped(parameters, sprite, 2); } } } /** * Draws the static wire entities * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawWiresChunk(parameters, chunk) { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.doNotRenderStatics) { return; } const drawnUids = new Set(); const contents = chunk.wireContents; for (let y = 0; y < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++y) { for (let x = 0; x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++x) { const entity = contents[x][y]; if (entity) { if (drawnUids.has(entity.uid)) { continue; } drawnUids.add(entity.uid); const staticComp = entity.components.StaticMapEntity; const sprite = staticComp.getSprite(); if (sprite) { staticComp.drawSpriteOnBoundsClipped(parameters, sprite, 2); } } } } } } /***/ }), /***/ "./src/js/game/systems/storage.js": /*!****************************************!*\ !*** ./src/js/game/systems/storage.js ***! \****************************************/ /*! exports provided: StorageSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StorageSystem", function() { return StorageSystem; }); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _components_storage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/storage */ "./src/js/game/components/storage.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); class StorageSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_0__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_storage__WEBPACK_IMPORTED_MODULE_1__["StorageComponent"]]); this.storageOverlaySprite = _core_loader__WEBPACK_IMPORTED_MODULE_4__["Loader"].getSprite("sprites/misc/storage_overlay.png"); /** * Stores which uids were already drawn to avoid drawing entities twice * @type {Set} */ this.drawnUids = new Set(); this.root.signals.gameFrameStarted.add(this.clearDrawnUids, this); } clearDrawnUids() { this.drawnUids.clear(); } update() { for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const storageComp = entity.components.Storage; const pinsComp = entity.components.WiredPins; // Eject from storage if (storageComp.storedItem && storageComp.storedCount > 0) { const ejectorComp = entity.components.ItemEjector; const nextSlot = ejectorComp.getFirstFreeSlot(); if (nextSlot !== null) { if (ejectorComp.tryEject(nextSlot, storageComp.storedItem)) { storageComp.storedCount--; if (storageComp.storedCount === 0) { storageComp.storedItem = null; } } } } let targetAlpha = storageComp.storedCount > 0 ? 1 : 0; storageComp.overlayOpacity = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["lerp"])(storageComp.overlayOpacity, targetAlpha, 0.05); pinsComp.slots[0].value = storageComp.storedItem; pinsComp.slots[1].value = storageComp.getIsFull() ? _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_TRUE_SINGLETON"] : _items_boolean_item__WEBPACK_IMPORTED_MODULE_5__["BOOL_FALSE_SINGLETON"]; } } /** * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const storageComp = entity.components.Storage; if (!storageComp) { continue; } const storedItem = storageComp.storedItem; if (!storedItem) { continue; } if (this.drawnUids.has(entity.uid)) { continue; } this.drawnUids.add(entity.uid); const staticComp = entity.components.StaticMapEntity; const context = parameters.context; context.globalAlpha = storageComp.overlayOpacity; const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); storedItem.drawItemCenteredClipped(center.x, center.y, parameters, 30); this.storageOverlaySprite.drawCached(parameters, center.x - 15, center.y + 15, 30, 15); if (parameters.visibleRect.containsCircle(center.x, center.y + 25, 20)) { context.font = "bold 10px GameFont"; context.textAlign = "center"; context.fillStyle = "#64666e"; context.fillText(Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["formatBigNumber"])(storageComp.storedCount), center.x, center.y + 25.5); context.textAlign = "left"; } context.globalAlpha = 1; } } } /***/ }), /***/ "./src/js/game/systems/underground_belt.js": /*!*************************************************!*\ !*** ./src/js/game/systems/underground_belt.js ***! \*************************************************/ /*! exports provided: UndergroundBeltSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UndergroundBeltSystem", function() { return UndergroundBeltSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/underground_belt */ "./src/js/game/components/underground_belt.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("tunnels"); class UndergroundBeltSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_7__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["UndergroundBeltComponent"]]); this.beltSprites = { [_components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].sender]: _core_loader__WEBPACK_IMPORTED_MODULE_1__["Loader"].getSprite( "sprites/buildings/underground_belt_entry.png" ), [_components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].receiver]: _core_loader__WEBPACK_IMPORTED_MODULE_1__["Loader"].getSprite( "sprites/buildings/underground_belt_exit.png" ), }; this.root.signals.entityManuallyPlaced.add(this.onEntityManuallyPlaced, this); /** * @type {Rectangle} */ this.areaToRecompute = null; this.root.signals.entityAdded.add(this.onEntityChanged, this); this.root.signals.entityDestroyed.add(this.onEntityChanged, this); } /** * Called when an entity got added or removed * @param {Entity} entity */ onEntityChanged(entity) { if (!this.root.gameInitialized) { return; } const undergroundComp = entity.components.UndergroundBelt; if (!undergroundComp) { return; } const affectedArea = entity.components.StaticMapEntity.getTileSpaceBounds().expandedInAllDirections( _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].undergroundBeltMaxTilesByTier[ _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].undergroundBeltMaxTilesByTier.length - 1 ] + 1 ); if (this.areaToRecompute) { this.areaToRecompute = this.areaToRecompute.getUnion(affectedArea); } else { this.areaToRecompute = affectedArea; } } /** * Callback when an entity got placed, used to remove belts between underground belts * @param {Entity} entity */ onEntityManuallyPlaced(entity) { if (!this.root.app.settings.getAllSettings().enableTunnelSmartplace) { // Smart-place disabled return; } const undergroundComp = entity.components.UndergroundBelt; if (undergroundComp && undergroundComp.mode === _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].receiver) { const staticComp = entity.components.StaticMapEntity; const tile = staticComp.origin; const direction = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumAngleToDirection"][staticComp.rotation]; const inverseDirection = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumInvertedDirections"][direction]; const offset = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirectionToVector"][inverseDirection]; let currentPos = tile.copy(); const tier = undergroundComp.tier; const range = _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].undergroundBeltMaxTilesByTier[tier]; // FIND ENTRANCE // Search for the entrance which is furthes apart (this is why we can't reuse logic here) let matchingEntrance = null; for (let i = 0; i < range; ++i) { currentPos.addInplace(offset); const contents = this.root.map.getTileContent(currentPos, entity.layer); if (!contents) { continue; } const contentsUndergroundComp = contents.components.UndergroundBelt; const contentsStaticComp = contents.components.StaticMapEntity; if ( contentsUndergroundComp && contentsUndergroundComp.tier === undergroundComp.tier && contentsUndergroundComp.mode === _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].sender && _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumAngleToDirection"][contentsStaticComp.rotation] === direction ) { matchingEntrance = { entity: contents, range: i, }; } } if (!matchingEntrance) { // Nothing found return; } // DETECT OBSOLETE BELTS BETWEEN // Remove any belts between entrance and exit which have the same direction, // but only if they *all* have the right direction currentPos = tile.copy(); let allBeltsMatch = true; for (let i = 0; i < matchingEntrance.range; ++i) { currentPos.addInplace(offset); const contents = this.root.map.getTileContent(currentPos, entity.layer); if (!contents) { allBeltsMatch = false; break; } const contentsStaticComp = contents.components.StaticMapEntity; const contentsBeltComp = contents.components.Belt; if (!contentsBeltComp) { allBeltsMatch = false; break; } // It's a belt if ( contentsBeltComp.direction !== _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirection"].top || _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumAngleToDirection"][contentsStaticComp.rotation] !== direction ) { allBeltsMatch = false; break; } } currentPos = tile.copy(); if (allBeltsMatch) { // All belts between this are obsolete, so drop them for (let i = 0; i < matchingEntrance.range; ++i) { currentPos.addInplace(offset); const contents = this.root.map.getTileContent(currentPos, entity.layer); window.assert(contents, "Invalid smart underground belt logic"); this.root.logic.tryDeleteBuilding(contents); } } // REMOVE OBSOLETE TUNNELS // Remove any double tunnels, by checking the tile plus the tile above currentPos = tile.copy().add(offset); for (let i = 0; i < matchingEntrance.range - 1; ++i) { const posBefore = currentPos.copy(); currentPos.addInplace(offset); const entityBefore = this.root.map.getTileContent(posBefore, entity.layer); const entityAfter = this.root.map.getTileContent(currentPos, entity.layer); if (!entityBefore || !entityAfter) { continue; } const undergroundBefore = entityBefore.components.UndergroundBelt; const undergroundAfter = entityAfter.components.UndergroundBelt; if (!undergroundBefore || !undergroundAfter) { // Not an underground belt continue; } if ( // Both same tier undergroundBefore.tier !== undergroundAfter.tier || // And same tier as our original entity undergroundBefore.tier !== undergroundComp.tier ) { // Mismatching tier continue; } if ( undergroundBefore.mode !== _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].sender || undergroundAfter.mode !== _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].receiver ) { // Not the right mode continue; } // Check rotations const staticBefore = entityBefore.components.StaticMapEntity; const staticAfter = entityAfter.components.StaticMapEntity; if ( _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumAngleToDirection"][staticBefore.rotation] !== direction || _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumAngleToDirection"][staticAfter.rotation] !== direction ) { // Wrong rotation continue; } // All good, can remove this.root.logic.tryDeleteBuilding(entityBefore); this.root.logic.tryDeleteBuilding(entityAfter); } } } /** * Recomputes the cache in the given area, invalidating all entries there */ recomputeArea() { const area = this.areaToRecompute; logger.log("Recomputing area:", area.x, area.y, "/", area.w, area.h); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderChanges) { this.root.hud.parts.changesDebugger.renderChange("tunnels", this.areaToRecompute, "#fc03be"); } for (let x = area.x; x < area.right(); ++x) { for (let y = area.y; y < area.bottom(); ++y) { const entities = this.root.map.getLayersContentsMultipleXY(x, y); for (let i = 0; i < entities.length; ++i) { const entity = entities[i]; const undergroundComp = entity.components.UndergroundBelt; if (!undergroundComp) { continue; } undergroundComp.cachedLinkedEntity = null; } } } } update() { if (this.areaToRecompute) { this.recomputeArea(); this.areaToRecompute = null; } const delta = this.root.dynamicTickrate.deltaSeconds; for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const undergroundComp = entity.components.UndergroundBelt; const pendingItems = undergroundComp.pendingItems; // Decrease remaining time of all items in belt for (let k = 0; k < pendingItems.length; ++k) { const item = pendingItems[k]; item[1] = Math.max(0, item[1] - delta); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.instantBelts) { item[1] = 0; } } if (undergroundComp.mode === _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].sender) { this.handleSender(entity); } else { this.handleReceiver(entity); } } } /** * Finds the receiver for a given sender * @param {Entity} entity * @returns {import("../components/underground_belt").LinkedUndergroundBelt} */ findRecieverForSender(entity) { const staticComp = entity.components.StaticMapEntity; const undergroundComp = entity.components.UndergroundBelt; const searchDirection = staticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirection"].top); const searchVector = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirectionToVector"][searchDirection]; const targetRotation = _core_vector__WEBPACK_IMPORTED_MODULE_4__["enumDirectionToAngle"][searchDirection]; let currentTile = staticComp.origin; // Search in the direction of the tunnel for ( let searchOffset = 0; searchOffset < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].undergroundBeltMaxTilesByTier[undergroundComp.tier]; ++searchOffset ) { currentTile = currentTile.add(searchVector); const potentialReceiver = this.root.map.getTileContent(currentTile, "regular"); if (!potentialReceiver) { // Empty tile continue; } const receiverUndergroundComp = potentialReceiver.components.UndergroundBelt; if (!receiverUndergroundComp || receiverUndergroundComp.tier !== undergroundComp.tier) { // Not a tunnel, or not on the same tier continue; } if (receiverUndergroundComp.mode !== _components_underground_belt__WEBPACK_IMPORTED_MODULE_5__["enumUndergroundBeltMode"].receiver) { // Not a receiver continue; } const receiverStaticComp = potentialReceiver.components.StaticMapEntity; if (receiverStaticComp.rotation !== targetRotation) { // Wrong rotation continue; } return { entity: potentialReceiver, distance: searchOffset }; } // None found return { entity: null, distance: 0 }; } /** * * @param {Entity} entity */ handleSender(entity) { const undergroundComp = entity.components.UndergroundBelt; // Find the current receiver let receiver = undergroundComp.cachedLinkedEntity; if (!receiver) { // We don't have a receiver, compute it receiver = undergroundComp.cachedLinkedEntity = this.findRecieverForSender(entity); if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderChanges) { this.root.hud.parts.changesDebugger.renderChange( "sender", entity.components.StaticMapEntity.getTileSpaceBounds(), "#fc03be" ); } } if (!receiver.entity) { // If there is no connection to a receiver, ignore this one return; } // Check if we have any item if (undergroundComp.pendingItems.length > 0) { window.assert(undergroundComp.pendingItems.length === 1, "more than 1 pending"); const nextItemAndDuration = undergroundComp.pendingItems[0]; const remainingTime = nextItemAndDuration[1]; const nextItem = nextItemAndDuration[0]; // Check if the item is ready to be emitted if (remainingTime === 0) { // Check if the receiver can accept it if ( receiver.entity.components.UndergroundBelt.tryAcceptTunneledItem( nextItem, receiver.distance, this.root.hubGoals.getUndergroundBeltBaseSpeed() ) ) { // Drop this item Object(_core_utils__WEBPACK_IMPORTED_MODULE_8__["fastArrayDelete"])(undergroundComp.pendingItems, 0); } } } } /** * * @param {Entity} entity */ handleReceiver(entity) { const undergroundComp = entity.components.UndergroundBelt; // Try to eject items, we only check the first one because it is sorted by remaining time const items = undergroundComp.pendingItems; if (items.length > 0) { const nextItemAndDuration = undergroundComp.pendingItems[0]; const remainingTime = nextItemAndDuration[1]; const nextItem = nextItemAndDuration[0]; if (remainingTime <= 0) { const ejectorComp = entity.components.ItemEjector; const nextSlotIndex = ejectorComp.getFirstFreeSlot(); if (nextSlotIndex !== null) { if (ejectorComp.tryEject(nextSlotIndex, nextItem)) { items.shift(); } } } } } } /***/ }), /***/ "./src/js/game/systems/wire.js": /*!*************************************!*\ !*** ./src/js/game/systems/wire.js ***! \*************************************/ /*! exports provided: WireNetwork, WireSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WireNetwork", function() { return WireNetwork; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WireSystem", function() { return WireSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_rectangle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/rectangle */ "./src/js/core/rectangle.js"); /* harmony import */ var _core_stale_area_detector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/stale_area_detector */ "./src/js/core/stale_area_detector.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _base_item__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../base_item */ "./src/js/game/base_item.js"); /* harmony import */ var _items_boolean_item__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../items/boolean_item */ "./src/js/game/items/boolean_item.js"); /* harmony import */ var _buildings_wire__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../buildings/wire */ "./src/js/game/buildings/wire.js"); /* harmony import */ var _building_codes__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _components_wire__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../components/wire */ "./src/js/game/components/wire.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _components_wire_tunnel__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../components/wire_tunnel */ "./src/js/game/components/wire_tunnel.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../meta_building */ "./src/js/game/meta_building.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_3__["createLogger"])("wires"); let networkUidCounter = 0; const VERBOSE_WIRES = true && false; class WireNetwork { constructor() { /** * Who contributes to this network * @type {Array<{ entity: Entity, slot: import("../components/wired_pins").WirePinSlot }>} */ this.providers = []; /** * Who takes values from this network * @type {Array<{ entity: Entity, slot: import("../components/wired_pins").WirePinSlot }>} */ this.receivers = []; /** * All connected slots * @type {Array<{ entity: Entity, slot: import("../components/wired_pins").WirePinSlot }>} */ this.allSlots = []; /** * All connected tunnels * @type {Array} */ this.tunnels = []; /** * Which wires are in this network * @type {Array} */ this.wires = []; /** * The current value of this network * @type {BaseItem} */ this.currentValue = null; /** * Whether this network has a value conflict, that is, more than one * sender has sent a value * @type {boolean} */ this.valueConflict = false; /** * Unique network identifier * @type {number} */ this.uid = ++networkUidCounter; } } class WireSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_16__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_wire__WEBPACK_IMPORTED_MODULE_12__["WireComponent"]]); this.wireSprites = { regular: { [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].regular]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/regular_forward.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].turn]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/regular_turn.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].split]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/regular_split.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].cross]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/regular_cross.png"), }, conflict: { [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].regular]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/conflict_forward.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].turn]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/conflict_turn.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].split]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/conflict_split.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].cross]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/conflict_cross.png"), }, shape: { [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].regular]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/shape_forward.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].turn]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/shape_turn.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].split]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/shape_split.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].cross]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/shape_cross.png"), }, color: { [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].regular]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/color_forward.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].turn]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/color_turn.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].split]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/color_split.png"), [_components_wire__WEBPACK_IMPORTED_MODULE_12__["enumWireType"].cross]: _core_loader__WEBPACK_IMPORTED_MODULE_2__["Loader"].getSprite("sprites/wires/sets/color_cross.png"), }, }; this.root.signals.entityDestroyed.add(this.queuePlacementUpdate, this); this.root.signals.entityAdded.add(this.queuePlacementUpdate, this); this.root.signals.entityDestroyed.add(this.queueRecomputeIfWire, this); this.root.signals.entityChanged.add(this.queueRecomputeIfWire, this); this.root.signals.entityAdded.add(this.queueRecomputeIfWire, this); this.needsRecompute = true; this.staleArea = new _core_stale_area_detector__WEBPACK_IMPORTED_MODULE_5__["StaleAreaDetector"]({ root: this.root, name: "wires", recomputeMethod: this.updateSurroundingWirePlacement.bind(this), }); /** * @type {Array} */ this.networks = []; } /** * Invalidates the wires network if the given entity is relevant for it * @param {Entity} entity */ queueRecomputeIfWire(entity) { if (!this.root.gameInitialized) { return; } if (this.isEntityRelevantForWires(entity)) { this.needsRecompute = true; this.networks = []; } } /** * Recomputes the whole wires network */ recomputeWiresNetwork() { this.needsRecompute = false; logger.log("Recomputing wires network"); this.networks = []; // Clear all network references const wireEntities = this.root.entityMgr.getAllWithComponent(_components_wire__WEBPACK_IMPORTED_MODULE_12__["WireComponent"]); for (let i = 0; i < wireEntities.length; ++i) { wireEntities[i].components.Wire.linkedNetwork = null; } const tunnelEntities = this.root.entityMgr.getAllWithComponent(_components_wire_tunnel__WEBPACK_IMPORTED_MODULE_14__["WireTunnelComponent"]); for (let i = 0; i < tunnelEntities.length; ++i) { tunnelEntities[i].components.WireTunnel.linkedNetworks = []; } const pinEntities = this.root.entityMgr.getAllWithComponent(_components_wired_pins__WEBPACK_IMPORTED_MODULE_13__["WiredPinsComponent"]); for (let i = 0; i < pinEntities.length; ++i) { const slots = pinEntities[i].components.WiredPins.slots; for (let k = 0; k < slots.length; ++k) { slots[k].linkedNetwork = null; } } VERBOSE_WIRES && logger.log("Recomputing slots"); // Iterate over all ejector slots for (let i = 0; i < pinEntities.length; ++i) { const entity = pinEntities[i]; const slots = entity.components.WiredPins.slots; for (let k = 0; k < slots.length; ++k) { const slot = slots[k]; // Ejectors are computed directly, acceptors are just set if (slot.type === _components_wired_pins__WEBPACK_IMPORTED_MODULE_13__["enumPinSlotType"].logicalEjector && !slot.linkedNetwork) { this.findNetworkForEjector(entity, slot); } } } } /** * Finds the network for the given slot * @param {Entity} initialEntity * @param {import("../components/wired_pins").WirePinSlot} slot */ findNetworkForEjector(initialEntity, slot) { let currentNetwork = new WireNetwork(); VERBOSE_WIRES && logger.log( "Finding network for entity", initialEntity.uid, initialEntity.components.StaticMapEntity.origin.toString(), "(nw-id:", currentNetwork.uid, ")" ); const entitiesToVisit = [ { entity: initialEntity, slot, }, ]; while (entitiesToVisit.length > 0) { const nextData = entitiesToVisit.pop(); const nextEntity = nextData.entity; const wireComp = nextEntity.components.Wire; const staticComp = nextEntity.components.StaticMapEntity; VERBOSE_WIRES && logger.log("Visiting", staticComp.origin.toString(), "(", nextEntity.uid, ")"); // Where to search for neighbours let newSearchDirections = []; let newSearchTile = null; //// WIRE if (wireComp) { // Sanity check window.assert( !wireComp.linkedNetwork || wireComp.linkedNetwork === currentNetwork, "Mismatching wire network on wire entity " + (wireComp.linkedNetwork ? wireComp.linkedNetwork.uid : "") + " vs " + currentNetwork.uid + " @ " + staticComp.origin.toString() ); if (!wireComp.linkedNetwork) { // This one is new! :D VERBOSE_WIRES && logger.log(" Visited new wire:", staticComp.origin.toString()); wireComp.linkedNetwork = currentNetwork; currentNetwork.wires.push(nextEntity); newSearchDirections = _core_vector__WEBPACK_IMPORTED_MODULE_7__["arrayAllDirections"]; newSearchTile = nextEntity.components.StaticMapEntity.origin; } } //// PINS const pinsComp = nextEntity.components.WiredPins; if (pinsComp) { const slot = nextData.slot; window.assert(slot, "No slot set for next entity"); if (slot.type === _components_wired_pins__WEBPACK_IMPORTED_MODULE_13__["enumPinSlotType"].logicalEjector) { VERBOSE_WIRES && logger.log(" Visiting ejector slot", staticComp.origin.toString(), "->", slot.type); } else if (slot.type === _components_wired_pins__WEBPACK_IMPORTED_MODULE_13__["enumPinSlotType"].logicalAcceptor) { VERBOSE_WIRES && logger.log(" Visiting acceptor slot", staticComp.origin.toString(), "->", slot.type); } else { window.assert(false, "Bad slot type: " + slot.type); } // Sanity check window.assert( !slot.linkedNetwork || slot.linkedNetwork === currentNetwork, "Mismatching wire network on pin slot entity " + (slot.linkedNetwork ? slot.linkedNetwork.uid : "") + " vs " + currentNetwork.uid ); if (!slot.linkedNetwork) { // This one is new VERBOSE_WIRES && logger.log(" Visited new slot:", staticComp.origin.toString()); // Add to the right list if (slot.type === _components_wired_pins__WEBPACK_IMPORTED_MODULE_13__["enumPinSlotType"].logicalEjector) { currentNetwork.providers.push({ entity: nextEntity, slot }); } else if (slot.type === _components_wired_pins__WEBPACK_IMPORTED_MODULE_13__["enumPinSlotType"].logicalAcceptor) { currentNetwork.receivers.push({ entity: nextEntity, slot }); } else { window.assert(false, "unknown slot type:" + slot.type); } // Register on the network currentNetwork.allSlots.push({ entity: nextEntity, slot }); slot.linkedNetwork = currentNetwork; // Specify where to search next newSearchDirections = [staticComp.localDirectionToWorld(slot.direction)]; newSearchTile = staticComp.localTileToWorld(slot.pos); } } if (newSearchTile) { // Find new surrounding wire targets const newTargets = this.findSurroundingWireTargets( newSearchTile, newSearchDirections, currentNetwork ); VERBOSE_WIRES && logger.log(" Found", newTargets, "new targets to visit!"); for (let i = 0; i < newTargets.length; ++i) { entitiesToVisit.push(newTargets[i]); } } } if ( currentNetwork.providers.length > 0 && (currentNetwork.wires.length > 0 || currentNetwork.receivers.length > 0 || currentNetwork.tunnels.length > 0) ) { this.networks.push(currentNetwork); VERBOSE_WIRES && logger.log("Attached new network with uid", currentNetwork); } else { // Unregister network again for (let i = 0; i < currentNetwork.wires.length; ++i) { currentNetwork.wires[i].components.Wire.linkedNetwork = null; } for (let i = 0; i < currentNetwork.tunnels.length; ++i) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_6__["fastArrayDeleteValueIfContained"])( currentNetwork.tunnels[i].components.WireTunnel.linkedNetworks, currentNetwork ); } for (let i = 0; i < currentNetwork.allSlots.length; ++i) { currentNetwork.allSlots[i].slot.linkedNetwork = null; } } } /** * Finds surrounding entities which are not yet assigned to a network * @param {Vector} initialTile * @param {Array} directions * @param {WireNetwork} network * @returns {Array} */ findSurroundingWireTargets(initialTile, directions, network) { let result = []; VERBOSE_WIRES && logger.log(" Searching for new targets at", initialTile.toString(), "and d=", directions); // Go over all directions we should search for for (let i = 0; i < directions.length; ++i) { const direction = directions[i]; const offset = _core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirectionToVector"][direction]; const initialSearchTile = initialTile.add(offset); // Store which tunnels we already visited to avoid infinite loops const visitedTunnels = new Set(); // First, find the initial connected entities const initialContents = this.root.map.getLayersContentsMultipleXY( initialSearchTile.x, initialSearchTile.y ); // Link the initial tile to the initial entities, since it may change /** @type {Array<{entity: Entity, tile: Vector}>} */ const contents = []; for (let j = 0; j < initialContents.length; ++j) { contents.push({ entity: initialContents[j], tile: initialSearchTile, }); } for (let k = 0; k < contents.length; ++k) { const { entity, tile } = contents[k]; const wireComp = entity.components.Wire; // Check for wire if (wireComp && !wireComp.linkedNetwork) { // Wires accept connections from everywhere result.push({ entity, }); } // Check for connected slots const pinComp = entity.components.WiredPins; if (pinComp) { const staticComp = entity.components.StaticMapEntity; // Go over all slots and see if they are connected const pinSlots = pinComp.slots; for (let j = 0; j < pinSlots.length; ++j) { const slot = pinSlots[j]; // Check if the position matches const pinPos = staticComp.localTileToWorld(slot.pos); if (!pinPos.equals(tile)) { continue; } // Check if the direction (inverted) matches const pinDirection = staticComp.localDirectionToWorld(slot.direction); if (pinDirection !== _core_vector__WEBPACK_IMPORTED_MODULE_7__["enumInvertedDirections"][direction]) { continue; } if (!slot.linkedNetwork) { result.push({ entity, slot, }); } } // Pin slots mean it can be nothing else continue; } // Check if its a tunnel, if so, go to the forwarded item const tunnelComp = entity.components.WireTunnel; if (tunnelComp) { if (visitedTunnels.has(entity.uid)) { continue; } const staticComp = entity.components.StaticMapEntity; if ( !tunnelComp.multipleDirections && !( direction === staticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].top) || direction === staticComp.localDirectionToWorld(_core_vector__WEBPACK_IMPORTED_MODULE_7__["enumDirection"].bottom) ) ) { // It's a coating, and it doesn't connect here continue; } // Compute where this tunnel connects to const forwardedTile = staticComp.origin.add(offset); VERBOSE_WIRES && logger.log( " Found tunnel", entity.uid, "at", tile, "-> forwarding to", forwardedTile ); // Figure out which entities are connected const connectedContents = this.root.map.getLayersContentsMultipleXY( forwardedTile.x, forwardedTile.y ); // Attach the entities and the tile we search at, because it may change for (let h = 0; h < connectedContents.length; ++h) { contents.push({ entity: connectedContents[h], tile: forwardedTile, }); } // Add the tunnel to the network if (tunnelComp.linkedNetworks.indexOf(network) < 0) { tunnelComp.linkedNetworks.push(network); } if (network.tunnels.indexOf(entity) < 0) { network.tunnels.push(entity); } // Remember this tunnel visitedTunnels.add(entity.uid); } } } VERBOSE_WIRES && logger.log(" -> Found", result.length); return result; } /** * Updates the wires network */ update() { this.staleArea.update(); if (this.needsRecompute) { this.recomputeWiresNetwork(); } // Re-compute values of all networks for (let i = 0; i < this.networks.length; ++i) { const network = this.networks[i]; // Reset conflicts network.valueConflict = false; // Aggregate values of all senders const senders = network.providers; let value = null; for (let k = 0; k < senders.length; ++k) { const senderSlot = senders[k]; const slotValue = senderSlot.slot.value; // The first sender can just put in his value if (!value) { value = slotValue; continue; } // If the slot is empty itself, just skip it if (!slotValue) { continue; } // If there is already an value, compare if it matches -> // otherwise there is a conflict if (value.equals(slotValue)) { // All good continue; } // There is a conflict, this means the value will be null anyways network.valueConflict = true; break; } // Assign value if (network.valueConflict) { network.currentValue = null; } else { network.currentValue = value; } } } /** * Returns the given tileset and opacity * @param {WireComponent} wireComp * @returns {{ spriteSet: Object, opacity: number}} */ getSpriteSetAndOpacityForWire(wireComp) { if (!wireComp.linkedNetwork) { // There is no network, it's empty return { spriteSet: this.wireSprites.regular, opacity: 0.3, }; } const network = wireComp.linkedNetwork; if (network.valueConflict) { // There is a conflict return { spriteSet: this.wireSprites.conflict, opacity: 1, }; } const value = network.currentValue; if (!value) { // There is no value stored return { spriteSet: this.wireSprites.regular, opacity: 0.3, }; } const valueType = value.getItemType(); if (valueType === "shape") { return { spriteSet: this.wireSprites.shape, opacity: 1, }; } else if (valueType === "color") { return { spriteSet: this.wireSprites.color, opacity: 1, }; } else if (valueType === "boolean") { return { spriteSet: this.wireSprites.regular, opacity: /** @type {BooleanItem} */ (value).value ? 1 : 0.5, }; } else { window.assert(false, "Unknown item type: " + valueType); } return { spriteSet: this.wireSprites.regular, opacity: 1, }; } /** * Draws a given chunk * @param {import("../../core/draw_utils").DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.wireContents; for (let y = 0; y < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++y) { for (let x = 0; x < _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].mapChunkSize; ++x) { const entity = contents[x][y]; if (entity && entity.components.Wire) { const wireComp = entity.components.Wire; const wireType = wireComp.type; const { opacity, spriteSet } = this.getSpriteSetAndOpacityForWire(wireComp); const sprite = spriteSet[wireType]; window.assert(sprite, "Unknown wire type: " + wireType); const staticComp = entity.components.StaticMapEntity; parameters.context.globalAlpha = opacity; staticComp.drawSpriteOnBoundsClipped(parameters, sprite, 0); parameters.context.globalAlpha = 1; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderWireRotations) { parameters.context.fillStyle = "red"; parameters.context.font = "5px Tahoma"; parameters.context.fillText( "" + staticComp.originalRotation, staticComp.origin.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, staticComp.origin.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + 5 ); parameters.context.fillStyle = "rgba(255, 0, 0, 0.2)"; if (staticComp.originalRotation % 180 === 0) { parameters.context.fillRect( (staticComp.origin.x + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, staticComp.origin.y * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, 3, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize ); } else { parameters.context.fillRect( staticComp.origin.x * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, (staticComp.origin.y + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, 3 ); } } } // DEBUG Rendering if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderWireNetworkInfos) { if (entity) { const staticComp = entity.components.StaticMapEntity; const wireComp = entity.components.Wire; // Draw network info for wires if (wireComp && wireComp.linkedNetwork) { parameters.context.fillStyle = "red"; parameters.context.font = "5px Tahoma"; parameters.context.fillText( "W" + wireComp.linkedNetwork.uid, (staticComp.origin.x + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize, (staticComp.origin.y + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize ); } } } } } } /** * Returns whether this entity is relevant for the wires network * @param {Entity} entity */ isEntityRelevantForWires(entity) { return entity.components.Wire || entity.components.WiredPins || entity.components.WireTunnel; } /** * * @param {Entity} entity */ queuePlacementUpdate(entity) { if (!this.root.gameInitialized) { return; } if (!this.isEntityRelevantForWires(entity)) { return; } const staticComp = entity.components.StaticMapEntity; if (!staticComp) { return; } // Invalidate affected area const originalRect = staticComp.getTileSpaceBounds(); const affectedArea = originalRect.expandedInAllDirections(1); this.staleArea.invalidate(affectedArea); } /** * Updates the wire placement after an entity has been added / deleted * @param {Rectangle} affectedArea */ updateSurroundingWirePlacement(affectedArea) { const metaWire = _core_global_registries__WEBPACK_IMPORTED_MODULE_1__["gMetaBuildingRegistry"].findByClass(_buildings_wire__WEBPACK_IMPORTED_MODULE_10__["MetaWireBuilding"]); for (let x = affectedArea.x; x < affectedArea.right(); ++x) { for (let y = affectedArea.y; y < affectedArea.bottom(); ++y) { const targetEntities = this.root.map.getLayersContentsMultipleXY(x, y); for (let i = 0; i < targetEntities.length; ++i) { const targetEntity = targetEntities[i]; const targetWireComp = targetEntity.components.Wire; const targetStaticComp = targetEntity.components.StaticMapEntity; if (!targetWireComp) { // Not a wire continue; } const { rotation, rotationVariant, } = metaWire.computeOptimalDirectionAndRotationVariantAtTile({ root: this.root, tile: new _core_vector__WEBPACK_IMPORTED_MODULE_7__["Vector"](x, y), rotation: targetStaticComp.originalRotation, variant: _meta_building__WEBPACK_IMPORTED_MODULE_18__["defaultBuildingVariant"], layer: targetEntity.layer, }); // Compute delta to see if anything changed const newType = _buildings_wire__WEBPACK_IMPORTED_MODULE_10__["arrayWireRotationVariantToType"][rotationVariant]; if (targetStaticComp.rotation !== rotation || newType !== targetWireComp.type) { // Change stuff targetStaticComp.rotation = rotation; metaWire.updateVariants(targetEntity, rotationVariant, _meta_building__WEBPACK_IMPORTED_MODULE_18__["defaultBuildingVariant"]); // Update code as well targetStaticComp.code = Object(_building_codes__WEBPACK_IMPORTED_MODULE_11__["getCodeFromBuildingData"])( metaWire, _meta_building__WEBPACK_IMPORTED_MODULE_18__["defaultBuildingVariant"], rotationVariant ); // Make sure the chunks know about the update this.root.signals.entityChanged.dispatch(targetEntity); } } } } } } /***/ }), /***/ "./src/js/game/systems/wired_pins.js": /*!*******************************************!*\ !*** ./src/js/game/systems/wired_pins.js ***! \*******************************************/ /*! exports provided: WiredPinsSystem */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WiredPinsSystem", function() { return WiredPinsSystem; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_draw_parameters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/draw_parameters */ "./src/js/core/draw_parameters.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _core_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/loader */ "./src/js/core/loader.js"); /* harmony import */ var _core_signal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../core/signal */ "./src/js/core/signal.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _components_wired_pins__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/wired_pins */ "./src/js/game/components/wired_pins.js"); /* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_system_with_filter__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../game_system_with_filter */ "./src/js/game/game_system_with_filter.js"); /* harmony import */ var _map_chunk_view__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../map_chunk_view */ "./src/js/game/map_chunk_view.js"); class WiredPinsSystem extends _game_system_with_filter__WEBPACK_IMPORTED_MODULE_8__["GameSystemWithFilter"] { constructor(root) { super(root, [_components_wired_pins__WEBPACK_IMPORTED_MODULE_6__["WiredPinsComponent"]]); this.pinSprites = { [_components_wired_pins__WEBPACK_IMPORTED_MODULE_6__["enumPinSlotType"].logicalEjector]: _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/wires/logical_ejector.png"), [_components_wired_pins__WEBPACK_IMPORTED_MODULE_6__["enumPinSlotType"].logicalAcceptor]: _core_loader__WEBPACK_IMPORTED_MODULE_3__["Loader"].getSprite("sprites/wires/logical_acceptor.png"), }; this.root.signals.prePlacementCheck.add(this.prePlacementCheck, this); this.root.signals.freeEntityAreaBeforeBuild.add(this.freeEntityAreaBeforeBuild, this); } /** * Performs pre-placement checks * @param {Entity} entity * @param {Vector} offset */ prePlacementCheck(entity, offset) { // Compute area of the building const rect = entity.components.StaticMapEntity.getTileSpaceBounds(); if (offset) { rect.x += offset.x; rect.y += offset.y; } // If this entity is placed on the wires layer, make sure we don't // place it above a pin if (entity.layer === "wires") { for (let x = rect.x; x < rect.x + rect.w; ++x) { for (let y = rect.y; y < rect.y + rect.h; ++y) { // Find which entities are in same tiles of both layers const entities = this.root.map.getLayersContentsMultipleXY(x, y); for (let i = 0; i < entities.length; ++i) { const otherEntity = entities[i]; // Check if entity has a wired component const pinComponent = otherEntity.components.WiredPins; const staticComp = otherEntity.components.StaticMapEntity; if (!pinComponent) { continue; } if (staticComp.getMetaBuilding().getIsReplaceable()) { // Don't mind here, even if there would be a collision we // could replace it continue; } // Go over all pins and check if they are blocking const pins = pinComponent.slots; for (let pinSlot = 0; pinSlot < pins.length; ++pinSlot) { const pos = staticComp.localTileToWorld(pins[pinSlot].pos); // Occupied by a pin if (pos.x === x && pos.y === y) { return _core_signal__WEBPACK_IMPORTED_MODULE_4__["STOP_PROPAGATION"]; } } } } } } // Check for collisions on the wires layer if (this.checkEntityPinsCollide(entity, offset)) { return _core_signal__WEBPACK_IMPORTED_MODULE_4__["STOP_PROPAGATION"]; } } /** * Checks if the pins of the given entity collide on the wires layer * @param {Entity} entity * @param {Vector=} offset Optional, move the entity by the given offset first * @returns {boolean} True if the pins collide */ checkEntityPinsCollide(entity, offset) { const pinsComp = entity.components.WiredPins; if (!pinsComp) { return false; } // Go over all slots for (let slotIndex = 0; slotIndex < pinsComp.slots.length; ++slotIndex) { const slot = pinsComp.slots[slotIndex]; // Figure out which tile this slot is on const worldPos = entity.components.StaticMapEntity.localTileToWorld(slot.pos); if (offset) { worldPos.x += offset.x; worldPos.y += offset.y; } // Check if there is any entity on that tile (Wired pins are always on the wires layer) const collidingEntity = this.root.map.getLayerContentXY(worldPos.x, worldPos.y, "wires"); // If there's an entity, and it can't get removed -> That's a collision if (collidingEntity) { if (!collidingEntity.components.StaticMapEntity.getMetaBuilding().getIsReplaceable()) { return true; } } } return false; } /** * Called to free space for the given entity * @param {Entity} entity */ freeEntityAreaBeforeBuild(entity) { const pinsComp = entity.components.WiredPins; if (!pinsComp) { // Entity has no pins return; } // Remove any stuff which collides with the pins for (let i = 0; i < pinsComp.slots.length; ++i) { const slot = pinsComp.slots[i]; const worldPos = entity.components.StaticMapEntity.localTileToWorld(slot.pos); const collidingEntity = this.root.map.getLayerContentXY(worldPos.x, worldPos.y, "wires"); if (collidingEntity) { window.assert( collidingEntity.components.StaticMapEntity.getMetaBuilding().getIsReplaceable(), "Tried to replace non-repleaceable entity for pins" ); if (!this.root.logic.tryDeleteBuilding(collidingEntity)) { window.assert(false, "Tried to replace non-repleaceable entity for pins #2"); } } } } update() { // TODO } /** * Draws a given entity * @param {DrawParameters} parameters * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { const contents = chunk.containedEntities; for (let i = 0; i < contents.length; ++i) { const entity = contents[i]; const pinsComp = entity.components.WiredPins; if (!pinsComp) { continue; } const staticComp = entity.components.StaticMapEntity; const slots = pinsComp.slots; for (let j = 0; j < slots.length; ++j) { const slot = slots[j]; const tile = staticComp.localTileToWorld(slot.pos); if (!chunk.tileSpaceRectangle.containsPoint(tile.x, tile.y)) { // Doesn't belong to this chunk continue; } const worldPos = tile.toWorldSpaceCenterOfTile(); // Culling if ( !parameters.visibleRect.containsCircle(worldPos.x, worldPos.y, _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].halfTileSize) ) { continue; } const effectiveRotation = Math.radians( staticComp.rotation + _core_vector__WEBPACK_IMPORTED_MODULE_5__["enumDirectionToAngle"][slot.direction] ); if (staticComp.getMetaBuilding().getRenderPins()) { Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_2__["drawRotatedSprite"])({ parameters, sprite: this.pinSprites[slot.type], x: worldPos.x, y: worldPos.y, angle: effectiveRotation, size: _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + 2, offsetX: 0, offsetY: 0, }); } // Draw contained item to visualize whats emitted const value = slot.value; if (value) { const offset = new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](0, -9).rotated(effectiveRotation); value.drawItemCenteredClipped( worldPos.x + offset.x, worldPos.y + offset.y, parameters, 9 ); } // Debug view if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.renderWireNetworkInfos) { const offset = new _core_vector__WEBPACK_IMPORTED_MODULE_5__["Vector"](0, -10).rotated(effectiveRotation); const network = slot.linkedNetwork; parameters.context.fillStyle = "blue"; parameters.context.font = "5px Tahoma"; parameters.context.textAlign = "center"; parameters.context.fillText( network ? "S" + network.uid : "???", (tile.x + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + offset.x, (tile.y + 0.5) * _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].tileSize + offset.y ); parameters.context.textAlign = "left"; } } } } } /***/ }), /***/ "./src/js/game/theme.js": /*!******************************!*\ !*** ./src/js/game/theme.js ***! \******************************/ /*! exports provided: THEMES, THEME, applyGameTheme */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "THEMES", function() { return THEMES; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "THEME", function() { return THEME; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyGameTheme", function() { return applyGameTheme; }); const THEMES = { dark: __webpack_require__(/*! ./themes/dark.json */ "./src/js/game/themes/dark.json"), light: __webpack_require__(/*! ./themes/light.json */ "./src/js/game/themes/light.json"), }; let THEME = THEMES.light; function applyGameTheme(id) { THEME = THEMES[id]; } /***/ }), /***/ "./src/js/game/themes/dark.json": /*!**************************************!*\ !*** ./src/js/game/themes/dark.json ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQK4EsDKAXAngGwKYwFywBMBDAJwGsYAacaWAWyIAc8JRJboYAjIgYzIDmJAPZwAdgRYwAxACYssgGYBmAOxUaHKDCEJJ+GCQE8AFLICs5yhAtWbl6wAYAdI9kBKDey06SegDIIYlgA6nooABYsLlbgmj4AzljYvCgIwmIA8gBuWCQYRGhSRqaqACzWAIwAbMrWsrJ1EC6qntTeHDBJKWkZmXAoGEE4BiVEJuVVtfWNTs7mbfGd3Vip6WIAQnyCIuL6sGMTFRA1TQ1NLh5eS7QwBAgkq71i-sL8LGxaPo8CcAUkHxuX1uvGEGGEANGxiO9TUVWUZUWHWBtx4-CEogkxWM40mNjhJwRcyuQK0AF92ijOAB3B5YBKA5FU2Cg8GQg7Q2SOACcVUcqnqjmUSOZnTRO0x+0MOLMPL5ApsQuJnlJHDJqopcSZ2lZEI2QwkAAUEPw8gAVBDYbGmWz1Bz2OwxJGqwz00QkXj0xmiroRJgjWDSZQEZSKMpELw+x5S6Th4OhyPM3xYLBiKRBrBxySUpNcDBwAMyZTmZQADnDMA1OZ8vAi4jIOTy2QQWGp3qTWDojHQ6bKfdL5mqiapMEUluwMeqZWqXFUkirWuBMFpjwZ+E+SeEuXyhQAwmCIdbxtyFTVKlVzLI5qoFsOUTBGI9m6392zrSYT1NzydL3Nb9X7wiBABAiIYQJQV9DyhUxHCcO1HXmFVtQgdUOk1MAlhgBAUE7NdWBdURBmGdNKlIspKlLO9bkIg1QnCKJ8BaWJkJgXgHl4bAtnRXYsWg8YuWsZRYIgMphJcYVKzQ8BUKAA")); })() /***/ }), /***/ "./src/js/game/themes/light.json": /*!***************************************!*\ !*** ./src/js/game/themes/light.json ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQK4EsDKAXAngGwKYwFywwQHMALFGAGnGlgFsBDABzwlEhuhgCN6BjAayIAnAPZwAdgBMWMAMQAzRZWocoMYQmn458+rt3L2q9UM0AZBOKwB1TShIsAjFTArjAZyzZeKBCPEA8gBuWEIY9GgyQkQ8ABQA7AAsFBCOAGwAzCkATNlZEAAMAHTxAJSGqmqe3r7+AXAohFZRMfQJyamZOXkpxQCs5S6VsNVYPn7iAEJ8gqISWrDRcUkp6fm5+cXZg+BuHDCSCEJjteJmIgIsbMM0MMdEcOFCV3s3nLwiGCLP2kvtORl4qsMokdkY3pweAJhGIpC1lh08kDUiDekVtjBXpUAL5DCEwADuRyw7he4IhsA+Xx+ixisWyBQAnKsCsiGRkwRTblDZrCFndWvSmSy2QVNujyljVNipRBcbtye9Pt9Jk1JAAFBACUIAFQQ2HhbT6BRSxtNJsKRVBhlldxJYiEvBJZIpMHcJCYOG0siw9CwXDGFXxx35CnkXHkvEcQbeJiwWHEMlkvAjkcSMZu3AwcC9sFkEckenkmMVUHlrlLlJIEn4wVCQQQWAJLvxWFojHQSfoaT0XC4GeGMHk+uwod4fV4vEkaRLw3LtqJx1J+Gu+JEITCEQAwsqaQK4ozkelnKk+tk0fEBgPKjBGMcG02d9T4bFD6s0ifHGe0da8bGSMQJCEKQKBPt8hoJOeKJsn0fRogAHJKlYyuC87gjACAoG2y6sLaYiNJYuZyLBfSXvQ15qPhTQ2HYDj4MUl5-vsvBHLw2DTNCcxwr8gqJBaZoQGkcGWo4SE0ChKFAA")); })() /***/ }), /***/ "./src/js/game/time/base_game_speed.js": /*!*********************************************!*\ !*** ./src/js/game/time/base_game_speed.js ***! \*********************************************/ /*! exports provided: BaseGameSpeed */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseGameSpeed", function() { return BaseGameSpeed; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); class BaseGameSpeed extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["BasicSerializableObject"] { /** * @param {GameRoot} root */ constructor(root) { super(); this.root = root; this.initializeAfterDeserialize(root); } /** @returns {string} */ static getId() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return "unknown-speed"; } getId() { // @ts-ignore return this.constructor.getId(); } static getSchema() { return {}; } initializeAfterDeserialize(root) { this.root = root; } /** * Returns the time multiplier */ getTimeMultiplier() { return 1; } /** * Returns how many logic steps there may be queued */ getMaxLogicStepsInQueue() { return 3; } // Internals /** @returns {BaseGameSpeed} */ newSpeed(instance) { return new instance(this.root); } } /***/ }), /***/ "./src/js/game/time/fast_forward_game_speed.js": /*!*****************************************************!*\ !*** ./src/js/game/time/fast_forward_game_speed.js ***! \*****************************************************/ /*! exports provided: FastForwardGameSpeed */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FastForwardGameSpeed", function() { return FastForwardGameSpeed; }); /* harmony import */ var _base_game_speed__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_game_speed */ "./src/js/game/time/base_game_speed.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); class FastForwardGameSpeed extends _base_game_speed__WEBPACK_IMPORTED_MODULE_0__["BaseGameSpeed"] { static getId() { return "fast-forward"; } getTimeMultiplier() { return _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].fastForwardSpeed; } getMaxLogicStepsInQueue() { return 3 * _core_config__WEBPACK_IMPORTED_MODULE_1__["globalConfig"].fastForwardSpeed; } } /***/ }), /***/ "./src/js/game/time/game_time.js": /*!***************************************!*\ !*** ./src/js/game/time/game_time.js ***! \***************************************/ /*! exports provided: GameTime */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameTime", function() { return GameTime; }); /* harmony import */ var _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../savegame/serialization */ "./src/js/savegame/serialization.js"); /* harmony import */ var _regular_game_speed__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./regular_game_speed */ "./src/js/game/time/regular_game_speed.js"); /* harmony import */ var _base_game_speed__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base_game_speed */ "./src/js/game/time/base_game_speed.js"); /* harmony import */ var _paused_game_speed__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./paused_game_speed */ "./src/js/game/time/paused_game_speed.js"); /* harmony import */ var _fast_forward_game_speed__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./fast_forward_game_speed */ "./src/js/game/time/fast_forward_game_speed.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_8__["createLogger"])("game_time"); class GameTime extends _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["BasicSerializableObject"] { /** * @param {GameRoot} root */ constructor(root) { super(); this.root = root; // Current ingame time seconds, not incremented while paused this.timeSeconds = 0; // Current "realtime", a timer which always is incremented no matter whether the game is paused or no this.realtimeSeconds = 0; // The adjustment, used when loading savegames so we can continue where we were this.realtimeAdjust = 0; /** @type {BaseGameSpeed} */ this.speed = new _regular_game_speed__WEBPACK_IMPORTED_MODULE_1__["RegularGameSpeed"](this.root); // Store how much time we have in bucket this.logicTimeBudget = 0; } static getId() { return "GameTime"; } static getSchema() { return { timeSeconds: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].float, speed: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].obj(_core_global_registries__WEBPACK_IMPORTED_MODULE_5__["gGameSpeedRegistry"]), realtimeSeconds: _savegame_serialization__WEBPACK_IMPORTED_MODULE_0__["types"].float, }; } /** * Fetches the new "real" time, called from the core once per frame, since performance now() is kinda slow */ updateRealtimeNow() { this.realtimeSeconds = performance.now() / 1000.0 + this.realtimeAdjust; } /** * Returns the ingame time in milliseconds */ getTimeMs() { return this.timeSeconds * 1000.0; } /** * Safe check to check if a timer is expired. quantizes numbers * @param {number} lastTick Last tick of the timer * @param {number} tickRateSeconds Interval of the timer in seconds */ isIngameTimerExpired(lastTick, tickRateSeconds) { return Object(_core_utils__WEBPACK_IMPORTED_MODULE_7__["checkTimerExpired"])(this.timeSeconds, lastTick, tickRateSeconds); } /** * Returns how many seconds we are in the grace period * @returns {number} */ getRemainingGracePeriodSeconds() { return 0; } /** * Returns if we are currently in the grace period * @returns {boolean} */ getIsWithinGracePeriod() { return this.getRemainingGracePeriodSeconds() > 0; } /** * Internal method to generate new logic time budget * @param {number} deltaMs */ internalAddDeltaToBudget(deltaMs) { // Only update if game is supposed to update if (this.root.hud.shouldPauseGame()) { this.logicTimeBudget = 0; } else { const multiplier = this.getSpeed().getTimeMultiplier(); this.logicTimeBudget += deltaMs * multiplier; } // Check for too big pile of updates -> reduce it to 1 let maxLogicSteps = Math.max( 3, (this.speed.getMaxLogicStepsInQueue() * this.root.dynamicTickrate.currentTickRate) / 60 ); if (_core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].debug.framePausesBetweenTicks) { maxLogicSteps *= 1 + _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].debug.framePausesBetweenTicks; } if (this.logicTimeBudget > this.root.dynamicTickrate.deltaMs * maxLogicSteps) { this.logicTimeBudget = this.root.dynamicTickrate.deltaMs * maxLogicSteps; } } /** * Performs update ticks based on the queued logic budget * @param {number} deltaMs * @param {function():boolean} updateMethod */ performTicks(deltaMs, updateMethod) { this.internalAddDeltaToBudget(deltaMs); const speedAtStart = this.root.time.getSpeed(); let effectiveDelta = this.root.dynamicTickrate.deltaMs; if (_core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].debug.framePausesBetweenTicks) { effectiveDelta += _core_config__WEBPACK_IMPORTED_MODULE_6__["globalConfig"].debug.framePausesBetweenTicks * this.root.dynamicTickrate.deltaMs; } // Update physics & logic while (this.logicTimeBudget >= effectiveDelta) { this.logicTimeBudget -= effectiveDelta; if (!updateMethod()) { // Gameover happened or so, do not update anymore return; } // Step game time this.timeSeconds = Object(_core_utils__WEBPACK_IMPORTED_MODULE_7__["quantizeFloat"])(this.timeSeconds + this.root.dynamicTickrate.deltaSeconds); // Game time speed changed, need to abort since our logic steps are no longer valid if (speedAtStart.getId() !== this.speed.getId()) { logger.warn( "Skipping update because speed changed from", speedAtStart.getId(), "to", this.speed.getId() ); break; } } } /** * Returns ingame time in seconds * @returns {number} seconds */ now() { return this.timeSeconds; } /** * Returns "real" time in seconds * @returns {number} seconds */ realtimeNow() { return this.realtimeSeconds; } /** * Returns "real" time in seconds * @returns {number} seconds */ systemNow() { return (this.realtimeSeconds - this.realtimeAdjust) * 1000.0; } getIsPaused() { return this.speed.getId() === _paused_game_speed__WEBPACK_IMPORTED_MODULE_3__["PausedGameSpeed"].getId(); } getSpeed() { return this.speed; } setSpeed(speed) { window.assert(speed instanceof _base_game_speed__WEBPACK_IMPORTED_MODULE_2__["BaseGameSpeed"], "Not a valid game speed"); if (this.speed.getId() === speed.getId()) { logger.warn("Same speed set than current one:", speed.constructor.getId()); } this.speed = speed; } deserialize(data) { const errorCode = super.deserialize(data); if (errorCode) { return errorCode; } // Adjust realtime now difference so they match this.realtimeAdjust = this.realtimeSeconds - performance.now() / 1000.0; this.updateRealtimeNow(); // Make sure we have a quantizied time this.timeSeconds = Object(_core_utils__WEBPACK_IMPORTED_MODULE_7__["quantizeFloat"])(this.timeSeconds); this.speed.initializeAfterDeserialize(this.root); } } /***/ }), /***/ "./src/js/game/time/paused_game_speed.js": /*!***********************************************!*\ !*** ./src/js/game/time/paused_game_speed.js ***! \***********************************************/ /*! exports provided: PausedGameSpeed */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PausedGameSpeed", function() { return PausedGameSpeed; }); /* harmony import */ var _base_game_speed__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_game_speed */ "./src/js/game/time/base_game_speed.js"); class PausedGameSpeed extends _base_game_speed__WEBPACK_IMPORTED_MODULE_0__["BaseGameSpeed"] { static getId() { return "paused"; } getTimeMultiplier() { return 0; } getMaxLogicStepsInQueue() { return 0; } } /***/ }), /***/ "./src/js/game/time/regular_game_speed.js": /*!************************************************!*\ !*** ./src/js/game/time/regular_game_speed.js ***! \************************************************/ /*! exports provided: RegularGameSpeed */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RegularGameSpeed", function() { return RegularGameSpeed; }); /* harmony import */ var _base_game_speed__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_game_speed */ "./src/js/game/time/base_game_speed.js"); class RegularGameSpeed extends _base_game_speed__WEBPACK_IMPORTED_MODULE_0__["BaseGameSpeed"] { static getId() { return "regular"; } getTimeMultiplier() { return 1; } } /***/ }), /***/ "./src/js/game/tutorial_goals.js": /*!***************************************!*\ !*** ./src/js/game/tutorial_goals.js ***! \***************************************/ /*! exports provided: enumHubGoalRewards, tutorialGoals, fixedGoals */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumHubGoalRewards", function() { return enumHubGoalRewards; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tutorialGoals", function() { return tutorialGoals; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fixedGoals", function() { return fixedGoals; }); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shape_definition */ "./src/js/game/shape_definition.js"); /* harmony import */ var _upgrades__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./upgrades */ "./src/js/game/upgrades.js"); /** * Don't forget to also update tutorial_goals_mappings.js as well as the translations! * @enum {string} */ const enumHubGoalRewards = { reward_cutter_and_trash: "reward_cutter_and_trash", reward_rotater: "reward_rotater", reward_painter: "reward_painter", reward_mixer: "reward_mixer", reward_stacker: "reward_stacker", reward_splitter: "reward_splitter", reward_tunnel: "reward_tunnel", reward_rotater_ccw: "reward_rotater_ccw", reward_rotater_fl: "reward_rotater_fl", reward_miner_chainable: "reward_miner_chainable", reward_underground_belt_tier_2: "reward_underground_belt_tier_2", reward_splitter_compact: "reward_splitter_compact", reward_cutter_quad: "reward_cutter_quad", reward_painter_double: "reward_painter_double", reward_painter_quad: "reward_painter_quad", reward_storage: "reward_storage", reward_blueprints: "reward_blueprints", reward_freeplay: "reward_freeplay", no_reward: "no_reward", no_reward_freeplay: "no_reward_freeplay", }; const tutorialGoals = [ // 1 // Circle { shape: "CuCuCuCu", // belts t1 required: 40, reward: enumHubGoalRewards.reward_cutter_and_trash, }, // 2 // Cutter { shape: "----CuCu", // required: 40, reward: enumHubGoalRewards.no_reward, }, // 3 // Rectangle { shape: "RuRuRuRu", // miners t1 required: 100, reward: enumHubGoalRewards.reward_splitter, }, // 4 { shape: "RuRu----", // processors t2 required: 120, reward: enumHubGoalRewards.reward_rotater, }, // 5 // Rotater { shape: "Cu----Cu", // belts t2 required: 200, reward: enumHubGoalRewards.reward_tunnel, }, // 6 { shape: "Cu------", // miners t2 required: 400, reward: enumHubGoalRewards.reward_painter, }, // 6.5 // Blueprints { shape: "CbCbCbCb", required: 600, reward: enumHubGoalRewards.reward_blueprints, }, // 7 // Painter { shape: "CrCrCrCr", // unused required: 800, reward: enumHubGoalRewards.reward_rotater_ccw, }, // 8 { shape: "RbRb----", // painter t2 required: 1000, reward: enumHubGoalRewards.reward_mixer, }, // 9 // Mixing (purple) { shape: "CmCmCmCm", // belts t3 required: 1400, reward: enumHubGoalRewards.reward_splitter_compact, }, // 10 // Star shape + cyan { shape: "ScScScSc", // miners t3 required: 1600, reward: enumHubGoalRewards.reward_stacker, }, // 11 // Stacker { shape: "CgScScCg", // processors t3 required: 1800, reward: enumHubGoalRewards.reward_miner_chainable, }, // 12 // Blueprints { shape: "CbCbCbRb:CwCwCwCw", required: 2000, reward: enumHubGoalRewards.reward_blueprints, }, // 13 { shape: "RmRmRmRm:CwCwCwCw", // painting t3 required: 3000, reward: enumHubGoalRewards.reward_underground_belt_tier_2, }, // 14 { shape: "SrSrSrSr:CyCyCyCy", // unused required: 4000, reward: enumHubGoalRewards.reward_storage, }, // 15 { shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants) required: 5000, reward: enumHubGoalRewards.reward_cutter_quad, }, // 16 { shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants) required: 10000, reward: enumHubGoalRewards.reward_painter_double, }, // 17 { shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two variants) required: 15000, reward: enumHubGoalRewards.reward_painter_quad, }, // // 18 // { // shape: finalGameShape, // required: 250000, // reward: enumHubGoalRewards.reward_freeplay, // }, ]; const fixedGoals = []; if (true) { tutorialGoals.forEach(({ shape }) => { try { _shape_definition__WEBPACK_IMPORTED_MODULE_0__["ShapeDefinition"].fromShortKey(shape); } catch (ex) { throw new Error("Invalid tutorial goal: '" + ex + "' for shape" + shape); } }); } /***/ }), /***/ "./src/js/game/tutorial_goals_mappings.js": /*!************************************************!*\ !*** ./src/js/game/tutorial_goals_mappings.js ***! \************************************************/ /*! exports provided: enumHubGoalRewardsToContentUnlocked */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumHubGoalRewardsToContentUnlocked", function() { return enumHubGoalRewardsToContentUnlocked; }); /* harmony import */ var _meta_building__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./meta_building */ "./src/js/game/meta_building.js"); /* harmony import */ var _buildings_cutter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./buildings/cutter */ "./src/js/game/buildings/cutter.js"); /* harmony import */ var _buildings_rotater__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./buildings/rotater */ "./src/js/game/buildings/rotater.js"); /* harmony import */ var _buildings_painter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./buildings/painter */ "./src/js/game/buildings/painter.js"); /* harmony import */ var _buildings_mixer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./buildings/mixer */ "./src/js/game/buildings/mixer.js"); /* harmony import */ var _buildings_stacker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./buildings/stacker */ "./src/js/game/buildings/stacker.js"); /* harmony import */ var _buildings_splitter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./buildings/splitter */ "./src/js/game/buildings/splitter.js"); /* harmony import */ var _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./buildings/underground_belt */ "./src/js/game/buildings/underground_belt.js"); /* harmony import */ var _buildings_miner__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./buildings/miner */ "./src/js/game/buildings/miner.js"); /* harmony import */ var _buildings_trash__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./buildings/trash */ "./src/js/game/buildings/trash.js"); /* harmony import */ var _tutorial_goals__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./tutorial_goals */ "./src/js/game/tutorial_goals.js"); /** @typedef {Array<[typeof MetaBuilding, string]>} TutorialGoalReward */ /** * Helper method for proper types * @returns {TutorialGoalReward} */ const typed = x => x; /** * Stores which reward unlocks what * @enum {TutorialGoalReward?} */ const enumHubGoalRewardsToContentUnlocked = { [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_cutter_and_trash]: typed([[_buildings_cutter__WEBPACK_IMPORTED_MODULE_1__["MetaCutterBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_rotater]: typed([[_buildings_rotater__WEBPACK_IMPORTED_MODULE_2__["MetaRotaterBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_painter]: typed([[_buildings_painter__WEBPACK_IMPORTED_MODULE_3__["MetaPainterBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_mixer]: typed([[_buildings_mixer__WEBPACK_IMPORTED_MODULE_4__["MetaMixerBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_stacker]: typed([[_buildings_stacker__WEBPACK_IMPORTED_MODULE_5__["MetaStackerBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_splitter]: typed([[_buildings_splitter__WEBPACK_IMPORTED_MODULE_6__["MetaSplitterBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_tunnel]: typed([[_buildings_underground_belt__WEBPACK_IMPORTED_MODULE_7__["MetaUndergroundBeltBuilding"], _meta_building__WEBPACK_IMPORTED_MODULE_0__["defaultBuildingVariant"]]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_rotater_ccw]: typed([[_buildings_rotater__WEBPACK_IMPORTED_MODULE_2__["MetaRotaterBuilding"], _buildings_rotater__WEBPACK_IMPORTED_MODULE_2__["enumRotaterVariants"].ccw]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_rotater_fl]: typed([[_buildings_rotater__WEBPACK_IMPORTED_MODULE_2__["MetaRotaterBuilding"], _buildings_rotater__WEBPACK_IMPORTED_MODULE_2__["enumRotaterVariants"].fl]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_miner_chainable]: typed([[_buildings_miner__WEBPACK_IMPORTED_MODULE_8__["MetaMinerBuilding"], _buildings_miner__WEBPACK_IMPORTED_MODULE_8__["enumMinerVariants"].chainable]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_underground_belt_tier_2]: typed([ [_buildings_underground_belt__WEBPACK_IMPORTED_MODULE_7__["MetaUndergroundBeltBuilding"], _buildings_underground_belt__WEBPACK_IMPORTED_MODULE_7__["enumUndergroundBeltVariants"].tier2], ]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_splitter_compact]: typed([ [_buildings_splitter__WEBPACK_IMPORTED_MODULE_6__["MetaSplitterBuilding"], _buildings_splitter__WEBPACK_IMPORTED_MODULE_6__["enumSplitterVariants"].compact], ]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_cutter_quad]: typed([[_buildings_cutter__WEBPACK_IMPORTED_MODULE_1__["MetaCutterBuilding"], _buildings_cutter__WEBPACK_IMPORTED_MODULE_1__["enumCutterVariants"].quad]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_painter_double]: typed([[_buildings_painter__WEBPACK_IMPORTED_MODULE_3__["MetaPainterBuilding"], _buildings_painter__WEBPACK_IMPORTED_MODULE_3__["enumPainterVariants"].double]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_painter_quad]: typed([[_buildings_painter__WEBPACK_IMPORTED_MODULE_3__["MetaPainterBuilding"], _buildings_painter__WEBPACK_IMPORTED_MODULE_3__["enumPainterVariants"].quad]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_storage]: typed([[_buildings_trash__WEBPACK_IMPORTED_MODULE_9__["MetaTrashBuilding"], _buildings_trash__WEBPACK_IMPORTED_MODULE_9__["enumTrashVariants"].storage]]), [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].reward_freeplay]: null, [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].no_reward]: null, [_tutorial_goals__WEBPACK_IMPORTED_MODULE_10__["enumHubGoalRewards"].no_reward_freeplay]: null, }; /***/ }), /***/ "./src/js/game/upgrades.js": /*!*********************************!*\ !*** ./src/js/game/upgrades.js ***! \*********************************/ /*! exports provided: finalGameShape, blueprintShape, UPGRADES */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "finalGameShape", function() { return finalGameShape; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "blueprintShape", function() { return blueprintShape; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UPGRADES", function() { return UPGRADES; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _shape_definition__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shape_definition */ "./src/js/game/shape_definition.js"); const finalGameShape = "RuCw--Cw:----Ru--"; const blueprintShape = "CbCbCbRb:CwCwCwCw"; const UPGRADES = { belt: { tiers: [ { required: [{ shape: "CuCuCuCu", amount: 150 }], improvement: 1, }, { required: [{ shape: "--CuCu--", amount: 1200 }], improvement: 2, }, { required: [{ shape: "CmCmCmCm", amount: 5000 }], improvement: 2, }, { required: [{ shape: "SrSrSrSr:CyCyCyCy", amount: 10000 }], improvement: 2, }, { required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 10000 }], improvement: 2, }, { required: [{ shape: finalGameShape, amount: 50000 }], improvement: 5, excludePrevious: true, }, ], }, miner: { tiers: [ { required: [{ shape: "RuRuRuRu", amount: 400 }], improvement: 1, }, { required: [{ shape: "Cu------", amount: 4000 }], improvement: 2, }, { required: [{ shape: "ScScScSc", amount: 6000 }], improvement: 2, }, { required: [{ shape: "CwCwCwCw:WbWbWbWb", amount: 10000 }], improvement: 2, }, { required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 10000 }], improvement: 2, }, { required: [{ shape: finalGameShape, amount: 50000 }], improvement: 5, excludePrevious: true, }, ], }, processors: { tiers: [ { required: [{ shape: "SuSuSuSu", amount: 1000 }], improvement: 1, }, { required: [{ shape: "RuRu----", amount: 2000 }], improvement: 2, }, { required: [{ shape: "CgScScCg", amount: 7000 }], improvement: 2, }, { required: [{ shape: "CwCrCwCr:SgSgSgSg", amount: 10000 }], improvement: 2, }, { required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 10000 }], improvement: 2, }, { required: [{ shape: finalGameShape, amount: 50000 }], improvement: 5, excludePrevious: true, }, ], }, painting: { tiers: [ { required: [{ shape: "RbRb----", amount: 1500 }], improvement: 2, }, { required: [{ shape: "WrWrWrWr", amount: 4000 }], improvement: 1, }, { required: [{ shape: "RmRmRmRm:CwCwCwCw", amount: 8000 }], improvement: 2, }, { required: [{ shape: "WmWmWmWm:CwCwCwCw:WmWmWmWm", amount: 10000 }], improvement: 2, }, { required: [{ shape: "WmWmWmWm:CwCwCwCw:WmWmWmWm:CwCwCwCw", amount: 10000 }], improvement: 2, }, { required: [{ shape: finalGameShape, amount: 50000 }], improvement: 5, excludePrevious: true, }, ], }, }; // Tiers need % of the previous tier as requirement too const tierGrowth = 2.5; // Automatically generate tier levels for (const upgradeId in UPGRADES) { const upgrade = UPGRADES[upgradeId]; let currentTierRequirements = []; for (let i = 0; i < upgrade.tiers.length; ++i) { const tierHandle = upgrade.tiers[i]; const originalRequired = tierHandle.required.slice(); for (let k = currentTierRequirements.length - 1; k >= 0; --k) { const oldTierRequirement = currentTierRequirements[k]; if (!tierHandle.excludePrevious) { tierHandle.required.unshift({ shape: oldTierRequirement.shape, amount: oldTierRequirement.amount, }); } } currentTierRequirements.push( ...originalRequired.map(req => ({ amount: req.amount, shape: req.shape, })) ); currentTierRequirements.forEach(tier => { tier.amount = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["findNiceIntegerValue"])(tier.amount * tierGrowth); }); } } if (true) { for (const upgradeId in UPGRADES) { const upgrade = UPGRADES[upgradeId]; upgrade.tiers.forEach(tier => { tier.required.forEach(({ shape }) => { try { _shape_definition__WEBPACK_IMPORTED_MODULE_1__["ShapeDefinition"].fromShortKey(shape); } catch (ex) { throw new Error("Invalid upgrade goal: '" + ex + "' for shape" + shape); } }); }); } } /***/ }), /***/ "./src/js/languages.js": /*!*****************************!*\ !*** ./src/js/languages.js ***! \*****************************/ /*! exports provided: LANGUAGES */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LANGUAGES", function() { return LANGUAGES; }); /** * @type {Object} */ const LANGUAGES = { "en": { name: "English", data: null, code: "en", region: "", }, "de": { name: "Deutsch", data: __webpack_require__(/*! ./built-temp/base-de.json */ "./src/js/built-temp/base-de.json"), code: "de", region: "", }, "fr": { name: "Français", data: __webpack_require__(/*! ./built-temp/base-fr.json */ "./src/js/built-temp/base-fr.json"), code: "fr", region: "", }, "ja": { name: "日本語", data: __webpack_require__(/*! ./built-temp/base-ja.json */ "./src/js/built-temp/base-ja.json"), code: "ja", region: "", }, "pt-PT": { name: "Português (Portugal)", data: __webpack_require__(/*! ./built-temp/base-pt-PT.json */ "./src/js/built-temp/base-pt-PT.json"), code: "pt", region: "PT", }, "pt-BR": { name: "Português (Brasil)", data: __webpack_require__(/*! ./built-temp/base-pt-BR.json */ "./src/js/built-temp/base-pt-BR.json"), code: "pt", region: "BR", }, "ru": { name: "Русский", data: __webpack_require__(/*! ./built-temp/base-ru.json */ "./src/js/built-temp/base-ru.json"), code: "ru", region: "", }, "cs": { name: "Čeština", data: __webpack_require__(/*! ./built-temp/base-cz.json */ "./src/js/built-temp/base-cz.json"), code: "cs", region: "", }, "es-419": { name: "Español", data: __webpack_require__(/*! ./built-temp/base-es.json */ "./src/js/built-temp/base-es.json"), code: "es", region: "", }, "pl": { name: "Polski", data: __webpack_require__(/*! ./built-temp/base-pl.json */ "./src/js/built-temp/base-pl.json"), code: "pl", region: "", }, "kor": { name: "한국어", data: __webpack_require__(/*! ./built-temp/base-kor.json */ "./src/js/built-temp/base-kor.json"), code: "kor", region: "", }, "nl": { name: "Nederlands", data: __webpack_require__(/*! ./built-temp/base-nl.json */ "./src/js/built-temp/base-nl.json"), code: "nl", region: "", }, "no": { name: "Norsk", data: __webpack_require__(/*! ./built-temp/base-no.json */ "./src/js/built-temp/base-no.json"), code: "no", region: "", }, "tr": { name: "Türkçe", data: __webpack_require__(/*! ./built-temp/base-tr.json */ "./src/js/built-temp/base-tr.json"), code: "tr", region: "", }, "zh-CN": { // simplified name: "中文简体", data: __webpack_require__(/*! ./built-temp/base-zh-CN.json */ "./src/js/built-temp/base-zh-CN.json"), code: "zh", region: "CN", }, "zh-TW": { // traditional name: "中文繁體", data: __webpack_require__(/*! ./built-temp/base-zh-TW.json */ "./src/js/built-temp/base-zh-TW.json"), code: "zh", region: "TW", }, "sv": { name: "Svenska", data: __webpack_require__(/*! ./built-temp/base-sv.json */ "./src/js/built-temp/base-sv.json"), code: "sv", region: "", }, }; /***/ }), /***/ "./src/js/main.js": /*!************************!*\ !*** ./src/js/main.js ***! \************************/ /*! no exports provided */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _core_polyfills__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./core/polyfills */ "./src/js/core/polyfills.js"); /* harmony import */ var _core_assert__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./core/assert */ "./src/js/core/assert.js"); /* harmony import */ var _core_error_handler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./core/error_handler */ "./src/js/core/error_handler.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _application__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./application */ "./src/js/application.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./core/config */ "./src/js/core/config.js"); /* harmony import */ var _game_component_registry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./game/component_registry */ "./src/js/game/component_registry.js"); /* harmony import */ var _core_draw_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./core/draw_utils */ "./src/js/core/draw_utils.js"); /* harmony import */ var _game_item_registry__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./game/item_registry */ "./src/js/game/item_registry.js"); /* harmony import */ var _game_meta_building_registry__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./game/meta_building_registry */ "./src/js/game/meta_building_registry.js"); /* harmony import */ var _game_game_speed_registry__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./game/game_speed_registry */ "./src/js/game/game_speed_registry.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_3__["createLogger"])("main"); if (window.coreThreadLoadedCb) { logger.log("Javascript parsed, calling html thread"); window.coreThreadLoadedCb(); } // Logrocket // if (!G_IS_DEV && !G_IS_STANDALONE) { // const monthlyUsers = 300; // thousand // const logrocketLimit = 10; // thousand // const percentageOfUsers = logrocketLimit / monthlyUsers; // if (Math.random() <= percentageOfUsers) { // logger.log("Analyzing this session with logrocket"); // const logrocket = require("logrocket"); // logrocket.init("p1x9zh/shapezio"); // try { // logrocket.getSessionURL(function (sessionURL) { // logger.log("Connected lockrocket to GA"); // // @ts-ignore // try { // window.ga("send", { // hitType: "event", // eventCategory: "LogRocket", // eventAction: sessionURL, // }); // } catch (ex) { // logger.warn("Logrocket connection to analytics failed:", ex); // } // }); // } catch (ex) { // logger.warn("Logrocket connection to analytics failed:", ex); // } // } // } console.log( `%cshapez.io ️%c\n© 2020 Tobias Springer IT Solutions\nCommit %c${"4bbf0823"}%c on %c${new Date( 1603628670741 ).toLocaleString()}\n`, "font-size: 35px; font-family: Arial;font-weight: bold; padding: 10px 0;", "color: #aaa", "color: #7f7", "color: #aaa", "color: #7f7" ); console.log("Environment: %c" + "dev", "color: #fff"); if ( true && _core_config__WEBPACK_IMPORTED_MODULE_5__["IS_DEBUG"]) { console.log("\n%c🛑 DEBUG ENVIRONMENT 🛑\n", "color: #f77"); } /* dev:start */ console.log("%cDEVCODE BUILT IN", "color: #f77"); /* dev:end */ Object(_core_logging__WEBPACK_IMPORTED_MODULE_3__["logSection"])("Boot Process", "#f9a825"); Object(_core_draw_utils__WEBPACK_IMPORTED_MODULE_7__["initDrawUtils"])(); Object(_game_component_registry__WEBPACK_IMPORTED_MODULE_6__["initComponentRegistry"])(); Object(_game_item_registry__WEBPACK_IMPORTED_MODULE_8__["initItemRegistry"])(); Object(_game_meta_building_registry__WEBPACK_IMPORTED_MODULE_9__["initMetaBuildingRegistry"])(); Object(_game_game_speed_registry__WEBPACK_IMPORTED_MODULE_10__["initGameSpeedRegistry"])(); let app = null; function bootApp() { logger.log("Page Loaded"); app = new _application__WEBPACK_IMPORTED_MODULE_4__["Application"](); app.boot(); } window.addEventListener("load", bootApp); /***/ }), /***/ "./src/js/platform/ad_provider.js": /*!****************************************!*\ !*** ./src/js/platform/ad_provider.js ***! \****************************************/ /*! exports provided: AdProviderInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdProviderInterface", function() { return AdProviderInterface; }); class AdProviderInterface { /** @param {Application} app */ constructor(app) { this.app = app; } /** * Initializes the storage * @returns {Promise} */ initialize() { return Promise.resolve(); } /** * Returns if this provider serves ads at all * @returns {boolean} */ getHasAds() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } /** * Returns if it would be possible to show a video ad *now*. This can be false if for * example the last video ad is * @returns {boolean} */ getCanShowVideoAd() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } /** * Shows an video ad * @returns {Promise} */ showVideoAd() { return Promise.resolve(); } } /***/ }), /***/ "./src/js/platform/ad_providers/gamedistribution.js": /*!**********************************************************!*\ !*** ./src/js/platform/ad_providers/gamedistribution.js ***! \**********************************************************/ /*! exports provided: GamedistributionAdProvider */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GamedistributionAdProvider", function() { return GamedistributionAdProvider; }); /* harmony import */ var _ad_provider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../ad_provider */ "./src/js/platform/ad_provider.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); const minimumTimeBetweenVideoAdsMs = true ? 1 : undefined; const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("gamedistribution"); class GamedistributionAdProvider extends _ad_provider__WEBPACK_IMPORTED_MODULE_0__["AdProviderInterface"] { /** * * @param {Application} app */ constructor(app) { super(app); /** * The resolve function to finish the current video ad. Null if none is currently running * @type {Function} */ this.videoAdResolveFunction = null; /** * The current timer which will timeout the resolve */ this.videoAdResolveTimer = null; /** * When we showed the last video ad */ this.lastVideoAdShowTime = -1e20; console.error("X"); } getHasAds() { return true; } getCanShowVideoAd() { return ( this.getHasAds() && !this.videoAdResolveFunction && performance.now() - this.lastVideoAdShowTime > minimumTimeBetweenVideoAdsMs ); } initialize() { // No point to initialize everything if ads are not supported if (!this.getHasAds()) { return Promise.resolve(); } logger.log("🎬 Initializing gamedistribution ads"); try { parent.postMessage("shapezio://gd.game_loaded", "*"); } catch (ex) { return Promise.reject("Frame communication not allowed"); } window.addEventListener( "message", event => { if (event.data === "shapezio://gd.ad_started") { console.log("🎬 Got ad started callback"); } else if (event.data === "shapezio://gd.ad_finished") { console.log("🎬 Got ad finished callback"); if (this.videoAdResolveFunction) { this.videoAdResolveFunction(); } } }, false ); return Promise.resolve(); } showVideoAd() { window.assert(this.getHasAds(), "Called showVideoAd but ads are not supported!"); window.assert(!this.videoAdResolveFunction, "Video ad still running, can not show again!"); this.lastVideoAdShowTime = performance.now(); console.log("🎬 Gamedistribution: Start ad"); try { parent.postMessage("shapezio://gd.show_ad", "*"); } catch (ex) { logger.warn("🎬 Failed to send message for gd ad:", ex); return Promise.resolve(); } document.body.classList.add("externalAdOpen"); return new Promise(resolve => { // So, wait for the remove call but also remove after N seconds this.videoAdResolveFunction = () => { this.videoAdResolveFunction = null; clearTimeout(this.videoAdResolveTimer); this.videoAdResolveTimer = null; // When the ad closed, also set the time this.lastVideoAdShowTime = performance.now(); resolve(); }; this.videoAdResolveTimer = setTimeout(() => { logger.warn("Automatically closing ad after not receiving callback"); if (this.videoAdResolveFunction) { this.videoAdResolveFunction(); } }, 35000); }) .catch(err => { logger.error(this, "Error while resolving video ad:", err); }) .then(() => { document.body.classList.remove("externalAdOpen"); }); } } /***/ }), /***/ "./src/js/platform/ad_providers/no_ad_provider.js": /*!********************************************************!*\ !*** ./src/js/platform/ad_providers/no_ad_provider.js ***! \********************************************************/ /*! exports provided: NoAdProvider */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NoAdProvider", function() { return NoAdProvider; }); /* harmony import */ var _ad_provider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../ad_provider */ "./src/js/platform/ad_provider.js"); class NoAdProvider extends _ad_provider__WEBPACK_IMPORTED_MODULE_0__["AdProviderInterface"] { getHasAds() { return false; } getCanShowVideoAd() { return false; } } /***/ }), /***/ "./src/js/platform/analytics.js": /*!**************************************!*\ !*** ./src/js/platform/analytics.js ***! \**************************************/ /*! exports provided: AnalyticsInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnalyticsInterface", function() { return AnalyticsInterface; }); class AnalyticsInterface { constructor(app) { /** @type {Application} */ this.app = app; } /** * Initializes the analytics * @returns {Promise} */ initialize() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.reject(); } /** * Sets the player name for analytics * @param {string} userName */ setUserContext(userName) {} /** * Tracks a click no an ui element * @param {string} elementName */ trackUiClick(elementName) {} /** * Tracks when a new state is entered * @param {string} stateId */ trackStateEnter(stateId) {} /** * Tracks a new user decision * @param {string} name */ trackDecision(name) {} } /***/ }), /***/ "./src/js/platform/browser/game_analytics.js": /*!***************************************************!*\ !*** ./src/js/platform/browser/game_analytics.js ***! \***************************************************/ /*! exports provided: ShapezGameAnalytics */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapezGameAnalytics", function() { return ShapezGameAnalytics; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _game_root__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../game/root */ "./src/js/game/root.js"); /* harmony import */ var _states_ingame__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../states/ingame */ "./src/js/states/ingame.js"); /* harmony import */ var _game_analytics__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../game_analytics */ "./src/js/platform/game_analytics.js"); /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../storage */ "./src/js/platform/storage.js"); /* harmony import */ var _game_upgrades__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../game/upgrades */ "./src/js/game/upgrades.js"); /* harmony import */ var _game_tutorial_goals__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../game/tutorial_goals */ "./src/js/game/tutorial_goals.js"); /* harmony import */ var _game_components_belt__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../game/components/belt */ "./src/js/game/components/belt.js"); /* harmony import */ var _game_components_static_map_entity__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../game/components/static_map_entity */ "./src/js/game/components/static_map_entity.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("game_analytics"); const analyticsUrl = true ? "http://localhost:8001" : undefined; // Be sure to increment the ID whenever it changes to make sure all // users are tracked const analyticsLocalFile = "shapez_token_123.bin"; class ShapezGameAnalytics extends _game_analytics__WEBPACK_IMPORTED_MODULE_4__["GameAnalyticsInterface"] { get environment() { if (true) { return "dev"; } if (false) {} if (false) {} return "beta"; } /** * @returns {Promise} */ initialize() { this.syncKey = null; setInterval(() => this.sendTimePoints(), 60 * 1000); // Retrieve sync key from player return this.app.storage.readFileAsync(analyticsLocalFile).then( syncKey => { this.syncKey = syncKey; logger.log("Player sync key read:", this.syncKey); }, error => { // File was not found, retrieve new key if (error === _storage__WEBPACK_IMPORTED_MODULE_5__["FILE_NOT_FOUND"]) { logger.log("Retrieving new player key"); // Perform call to get a new key from the API this.sendToApi("/v1/register", { environment: this.environment, }) .then(res => { // Try to read and parse the key from the api if (res.key && typeof res.key === "string" && res.key.length === 40) { this.syncKey = res.key; logger.log("Key retrieved:", this.syncKey); this.app.storage.writeFileAsync(analyticsLocalFile, res.key); } else { throw new Error("Bad response from analytics server: " + res); } }) .catch(err => { logger.error("Failed to register on analytics api:", err); }); } else { logger.error("Failed to read ga key:", error); } return; } ); } /** * Sends a request to the api * @param {string} endpoint Endpoint without base url * @param {object} data payload * @returns {Promise} */ sendToApi(endpoint, data) { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.noApiCalls) { return Promise.resolve("Api calls are disabled!"); } return new Promise((resolve, reject) => { const timeout = setTimeout(() => reject("Request to " + endpoint + " timed out"), 20000); fetch(analyticsUrl + endpoint, { method: "POST", mode: "cors", cache: "no-cache", referrer: "no-referrer", credentials: "omit", headers: { "Content-Type": "application/json", "Accept": "application/json", "x-api-key": _core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].info.analyticsApiKey, }, body: JSON.stringify(data), }) .then(res => { clearTimeout(timeout); if (!res.ok || res.status !== 200) { reject("Fetch error: Bad status " + res.status); } else { return res.json(); } }) .then(resolve) .catch(reason => { clearTimeout(timeout); reject(reason); }); }); } /** * Sends a game event to the analytics * @param {string} category * @param {string} value */ sendGameEvent(category, value) { if (!this.syncKey) { logger.warn("Can not send event due to missing sync key"); return; } const gameState = this.app.stateMgr.currentState; if (!(gameState instanceof _states_ingame__WEBPACK_IMPORTED_MODULE_3__["InGameState"])) { logger.warn("Trying to send analytics event outside of ingame state"); return; } const savegame = gameState.savegame; if (!savegame) { logger.warn("Ingame state has empty savegame"); return; } const savegameId = savegame.internalId; if (!gameState.core) { logger.warn("Game state has no core"); return; } const root = gameState.core.root; if (!root) { logger.warn("Root is not initialized"); return; } logger.log("Sending event", category, value); this.sendToApi("/v1/game-event", { playerKey: this.syncKey, gameKey: savegameId, ingameTime: root.time.now(), environment: this.environment, category, value, version: "modZ 1.0.3", level: root.hubGoals.level, gameDump: this.generateGameDump(root), }); } sendTimePoints() { const gameState = this.app.stateMgr.currentState; if (gameState instanceof _states_ingame__WEBPACK_IMPORTED_MODULE_3__["InGameState"]) { logger.log("Syncing analytics"); this.sendGameEvent("sync", ""); } } /** * Returns true if the shape is interesting * @param {string} key */ isInterestingShape(key) { if (key === _game_upgrades__WEBPACK_IMPORTED_MODULE_6__["blueprintShape"]) { return true; } // Check if its a story goal for (let i = 0; i < _game_tutorial_goals__WEBPACK_IMPORTED_MODULE_7__["tutorialGoals"].length; ++i) { if (key === _game_tutorial_goals__WEBPACK_IMPORTED_MODULE_7__["tutorialGoals"][i].shape) { return true; } } // Check if its required to unlock an upgrade for (const upgradeKey in _game_upgrades__WEBPACK_IMPORTED_MODULE_6__["UPGRADES"]) { const handle = _game_upgrades__WEBPACK_IMPORTED_MODULE_6__["UPGRADES"][upgradeKey]; const tiers = handle.tiers; for (let i = 0; i < tiers.length; ++i) { const tier = tiers[i]; const required = tier.required; for (let k = 0; k < required.length; ++k) { if (required[k].shape === key) { return true; } } } } return false; } /** * Generates a game dump * @param {GameRoot} root */ generateGameDump(root) { const shapeIds = Object.keys(root.hubGoals.storedShapes).filter(this.isInterestingShape.bind(this)); let shapes = {}; for (let i = 0; i < shapeIds.length; ++i) { shapes[shapeIds[i]] = root.hubGoals.storedShapes[shapeIds[i]]; } return { shapes, upgrades: root.hubGoals.upgradeLevels, belts: root.entityMgr.getAllWithComponent(_game_components_belt__WEBPACK_IMPORTED_MODULE_8__["BeltComponent"]).length, buildings: root.entityMgr.getAllWithComponent(_game_components_static_map_entity__WEBPACK_IMPORTED_MODULE_9__["StaticMapEntityComponent"]).length - root.entityMgr.getAllWithComponent(_game_components_belt__WEBPACK_IMPORTED_MODULE_8__["BeltComponent"]).length, }; } /** */ handleGameStarted() { this.sendGameEvent("game_start", ""); } /** */ handleGameResumed() { this.sendTimePoints(); } /** * Handles the given level completed * @param {number} level */ handleLevelCompleted(level) { logger.log("Complete level", level); this.sendGameEvent("level_complete", "" + level); } /** * Handles the given upgrade completed * @param {string} id * @param {number} level */ handleUpgradeUnlocked(id, level) { logger.log("Unlock upgrade", id, level); this.sendGameEvent("upgrade_unlock", id + "@" + level); } } /***/ }), /***/ "./src/js/platform/browser/google_analytics.js": /*!*****************************************************!*\ !*** ./src/js/platform/browser/google_analytics.js ***! \*****************************************************/ /*! exports provided: GoogleAnalyticsImpl */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GoogleAnalyticsImpl", function() { return GoogleAnalyticsImpl; }); /* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../analytics */ "./src/js/platform/analytics.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("ga"); class GoogleAnalyticsImpl extends _analytics__WEBPACK_IMPORTED_MODULE_0__["AnalyticsInterface"] { initialize() { this.lastUiClickTracked = -1000; setInterval(() => this.internalTrackAfkEvent(), 120 * 1000); // Analytics is already loaded in the html return Promise.resolve(); } setUserContext(userName) { try { if (window.gtag) { logger.log("📊 Setting user context:", userName); window.gtag("set", { player: userName, }); } } catch (ex) { logger.warn("📊 Failed to set user context:", ex); } } trackStateEnter(stateId) { const nonInteractionStates = [ "LoginState", "MainMenuState", "PreloadState", "RegisterState", "WatchAdState", ]; try { if (window.gtag) { logger.log("📊 Tracking state enter:", stateId); window.gtag("event", "enter_state", { event_category: "ui", event_label: stateId, non_interaction: nonInteractionStates.indexOf(stateId) >= 0, }); } } catch (ex) { logger.warn("📊 Failed to track state analytcis:", ex); } } trackDecision(decisionName) { try { if (window.gtag) { logger.log("📊 Tracking decision:", decisionName); window.gtag("event", "decision", { event_category: "ui", event_label: decisionName, non_interaction: true, }); } } catch (ex) { logger.warn("📊 Failed to track state analytcis:", ex); } } trackUiClick(elementName) { const stateKey = this.app.stateMgr.getCurrentState().key; const fullSelector = stateKey + ">" + elementName; try { if (window.gtag) { logger.log("📊 Tracking click on:", fullSelector); window.gtag("event", "click", { event_category: "ui", event_label: fullSelector, }); } } catch (ex) { logger.warn("📊 Failed to track ui click:", ex); } } /** * Tracks an event so GA keeps track of the user */ internalTrackAfkEvent() { if (window.gtag) { window.gtag("event", "afk", { event_category: "ping", event_label: "timed", }); } } } /***/ }), /***/ "./src/js/platform/browser/sound.js": /*!******************************************!*\ !*** ./src/js/platform/browser/sound.js ***! \******************************************/ /*! exports provided: SoundImplBrowser */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SoundImplBrowser", function() { return SoundImplBrowser; }); /* harmony import */ var _sound__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../sound */ "./src/js/platform/sound.js"); /* harmony import */ var _core_cachebust__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/cachebust */ "./src/js/core/cachebust.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); const { Howl, Howler } = __webpack_require__(/*! howler */ "./node_modules/howler/dist/howler.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("sound/browser"); // @ts-ignore const sprites = __webpack_require__(/*! ../../built-temp/sfx.json */ "./src/js/built-temp/sfx.json"); class SoundSpritesContainer { constructor() { this.howl = null; this.loadingPromise = null; } load() { if (this.loadingPromise) { return this.loadingPromise; } return (this.loadingPromise = Promise.race([ new Promise((resolve, reject) => { setTimeout(reject, 5000); }), new Promise(resolve => { this.howl = new Howl({ src: Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_1__["cachebust"])("res/sounds/sfx.mp3"), sprite: sprites.sprite, autoplay: false, loop: false, volume: 0, preload: true, pool: 20, onload: () => { resolve(); }, onloaderror: (id, err) => { logger.warn("SFX failed to load:", id, err); this.howl = null; resolve(); }, onplayerror: (id, err) => { logger.warn("SFX failed to play:", id, err); }, }); }), ])); } play(volume, key) { if (this.howl) { const instance = this.howl.play(key); this.howl.volume(volume, instance); } } deinitialize() { if (this.howl) { this.howl.unload(); this.howl = null; } } } class WrappedSoundInstance extends _sound__WEBPACK_IMPORTED_MODULE_0__["SoundInstanceInterface"] { /** * * @param {SoundSpritesContainer} spriteContainer * @param {string} key */ constructor(spriteContainer, key) { super(key, "sfx.mp3"); this.spriteContainer = spriteContainer; } /** @returns {Promise} */ load() { return this.spriteContainer.load(); } play(volume) { this.spriteContainer.play(volume, this.key); } deinitialize() { return this.spriteContainer.deinitialize(); } } class MusicInstance extends _sound__WEBPACK_IMPORTED_MODULE_0__["MusicInstanceInterface"] { constructor(key, url) { super(key, url); this.howl = null; this.instance = null; this.playing = false; } load() { return Promise.race([ new Promise((resolve, reject) => { setTimeout(reject, 5000); }), new Promise((resolve, reject) => { this.howl = new Howl({ src: Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_1__["cachebust"])("res/sounds/music/" + this.url + ".mp3"), autoplay: false, loop: true, html5: true, volume: 1, preload: true, pool: 2, onunlock: () => { if (this.playing) { logger.log("Playing music after manual unlock"); this.play(); } }, onload: () => { resolve(); }, onloaderror: (id, err) => { logger.warn(this, "Music", this.url, "failed to load:", id, err); this.howl = null; resolve(); }, onplayerror: (id, err) => { logger.warn(this, "Music", this.url, "failed to play:", id, err); }, }); }), ]); } stop() { if (this.howl && this.instance) { this.playing = false; this.howl.pause(this.instance); } } isPlaying() { return this.playing; } play() { if (this.howl) { this.playing = true; if (this.instance) { this.howl.play(this.instance); } else { this.instance = this.howl.play(); } } } deinitialize() { if (this.howl) { this.howl.unload(); this.howl = null; this.instance = null; } } } class SoundImplBrowser extends _sound__WEBPACK_IMPORTED_MODULE_0__["SoundInterface"] { constructor(app) { Howler.mobileAutoEnable = true; Howler.autoUnlock = true; Howler.autoSuspend = false; Howler.html5PoolSize = 20; Howler.pos(0, 0, 0); super(app, WrappedSoundInstance, MusicInstance); } initialize() { this.sfxHandle = new SoundSpritesContainer(); // @ts-ignore const keys = Object.values(_sound__WEBPACK_IMPORTED_MODULE_0__["SOUNDS"]); keys.forEach(key => { this.sounds[key] = new WrappedSoundInstance(this.sfxHandle, key); }); for (const musicKey in _sound__WEBPACK_IMPORTED_MODULE_0__["MUSIC"]) { const musicPath = _sound__WEBPACK_IMPORTED_MODULE_0__["MUSIC"][musicKey]; const music = new this.musicClass(musicKey, musicPath); this.music[musicPath] = music; } this.musicMuted = this.app.settings.getAllSettings().musicMuted; this.soundsMuted = this.app.settings.getAllSettings().soundsMuted; if (_core_config__WEBPACK_IMPORTED_MODULE_3__["globalConfig"].debug.disableMusic) { this.musicMuted = true; } return Promise.resolve(); } deinitialize() { return super.deinitialize().then(() => Howler.unload()); } } /***/ }), /***/ "./src/js/platform/browser/storage.js": /*!********************************************!*\ !*** ./src/js/platform/browser/storage.js ***! \********************************************/ /*! exports provided: StorageImplBrowser */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StorageImplBrowser", function() { return StorageImplBrowser; }); /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../storage */ "./src/js/platform/storage.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("storage/browser"); const LOCAL_STORAGE_UNAVAILABLE = "local-storage-unavailable"; const LOCAL_STORAGE_NO_WRITE_PERMISSION = "local-storage-no-write-permission"; let randomDelay = () => 0; if (true) { // Random delay for testing // randomDelay = () => 500; } class StorageImplBrowser extends _storage__WEBPACK_IMPORTED_MODULE_0__["StorageInterface"] { constructor(app) { super(app); this.currentBusyFilename = false; } initialize() { logger.error("Using localStorage, please update to a newer browser"); return new Promise((resolve, reject) => { // Check for local storage availability in general if (!window.localStorage) { alert("Local storage is not available! Please upgrade to a newer browser!"); reject(LOCAL_STORAGE_UNAVAILABLE); } // Check if we can set and remove items try { window.localStorage.setItem("storage_availability_test", "1"); window.localStorage.removeItem("storage_availability_test"); } catch (e) { alert( "It seems we don't have permission to write to local storage! Please update your browsers settings or use a different browser!" ); reject(LOCAL_STORAGE_NO_WRITE_PERMISSION); return; } setTimeout(resolve, 0); }); } writeFileAsync(filename, contents) { if (this.currentBusyFilename === filename) { logger.warn("Attempt to write", filename, "while write process is not finished!"); } this.currentBusyFilename = filename; window.localStorage.setItem(filename, contents); return new Promise((resolve, reject) => { setTimeout(() => { this.currentBusyFilename = false; resolve(); }, 0); }); } writeFileSyncIfSupported(filename, contents) { window.localStorage.setItem(filename, contents); return true; } readFileAsync(filename) { if (this.currentBusyFilename === filename) { logger.warn("Attempt to read", filename, "while write progress on it is ongoing!"); } return new Promise((resolve, reject) => { const contents = window.localStorage.getItem(filename); if (!contents) { // File not found setTimeout(() => reject(_storage__WEBPACK_IMPORTED_MODULE_0__["FILE_NOT_FOUND"]), randomDelay()); return; } // File read, simulate delay setTimeout(() => resolve(contents), 0); }); } deleteFileAsync(filename) { if (this.currentBusyFilename === filename) { logger.warn("Attempt to delete", filename, "while write progres on it is ongoing!"); } this.currentBusyFilename = filename; return new Promise((resolve, reject) => { window.localStorage.removeItem(filename); setTimeout(() => { this.currentBusyFilename = false; resolve(); }, 0); }); } } /***/ }), /***/ "./src/js/platform/browser/storage_indexed_db.js": /*!*******************************************************!*\ !*** ./src/js/platform/browser/storage_indexed_db.js ***! \*******************************************************/ /*! exports provided: StorageImplBrowserIndexedDB */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StorageImplBrowserIndexedDB", function() { return StorageImplBrowserIndexedDB; }); /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../storage */ "./src/js/platform/storage.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("storage/browserIDB"); const LOCAL_STORAGE_UNAVAILABLE = "local-storage-unavailable"; const LOCAL_STORAGE_NO_WRITE_PERMISSION = "local-storage-no-write-permission"; let randomDelay = () => 0; if (true) { // Random delay for testing // randomDelay = () => 500; } class StorageImplBrowserIndexedDB extends _storage__WEBPACK_IMPORTED_MODULE_0__["StorageInterface"] { constructor(app) { super(app); this.currentBusyFilename = false; /** @type {IDBDatabase} */ this.database = null; } initialize() { logger.log("Using indexed DB storage"); return new Promise((resolve, reject) => { const request = window.indexedDB.open("app_storage", 10); request.onerror = event => { logger.error("IDB error:", event); alert( "Sorry, it seems your browser has blocked the access to the storage system. This might be the case if you are browsing in private mode for example. I recommend to use google chrome or disable private browsing." ); reject("Indexed DB access error"); }; // @ts-ignore request.onsuccess = event => resolve(event.target.result); request.onupgradeneeded = /** @type {IDBVersionChangeEvent} */ event => { /** @type {IDBDatabase} */ // @ts-ignore const database = event.target.result; const objectStore = database.createObjectStore("files", { keyPath: "filename", }); objectStore.createIndex("filename", "filename", { unique: true }); objectStore.transaction.onerror = event => { logger.error("IDB transaction error:", event); reject("Indexed DB transaction error during migration, check console output."); }; objectStore.transaction.oncomplete = event => { logger.log("Object store completely initialized"); resolve(database); }; }; }).then(database => { this.database = database; }); } writeFileAsync(filename, contents) { if (this.currentBusyFilename === filename) { logger.warn("Attempt to write", filename, "while write process is not finished!"); } if (!this.database) { return Promise.reject("Storage not ready"); } this.currentBusyFilename = filename; const transaction = this.database.transaction(["files"], "readwrite"); return new Promise((resolve, reject) => { transaction.oncomplete = () => { this.currentBusyFilename = null; resolve(); }; transaction.onerror = error => { this.currentBusyFilename = null; logger.error("Error while writing", filename, ":", error); reject(error); }; const store = transaction.objectStore("files"); store.put({ filename, contents, }); }); } writeFileSyncIfSupported(filename, contents) { // Not supported this.writeFileAsync(filename, contents); return true; } readFileAsync(filename) { if (!this.database) { return Promise.reject("Storage not ready"); } this.currentBusyFilename = filename; const transaction = this.database.transaction(["files"], "readonly"); return new Promise((resolve, reject) => { const store = transaction.objectStore("files"); const request = store.get(filename); request.onsuccess = event => { this.currentBusyFilename = null; if (!request.result) { reject(_storage__WEBPACK_IMPORTED_MODULE_0__["FILE_NOT_FOUND"]); return; } resolve(request.result.contents); }; request.onerror = error => { this.currentBusyFilename = null; logger.error("Error while reading", filename, ":", error); reject(error); }; }); } deleteFileAsync(filename) { if (this.currentBusyFilename === filename) { logger.warn("Attempt to delete", filename, "while write progres on it is ongoing!"); } if (!this.database) { return Promise.reject("Storage not ready"); } this.currentBusyFilename = filename; const transaction = this.database.transaction(["files"], "readwrite"); return new Promise((resolve, reject) => { transaction.oncomplete = () => { this.currentBusyFilename = null; resolve(); }; transaction.onerror = error => { this.currentBusyFilename = null; logger.error("Error while deleting", filename, ":", error); reject(error); }; const store = transaction.objectStore("files"); store.delete(filename); }); } } /***/ }), /***/ "./src/js/platform/browser/wrapper.js": /*!********************************************!*\ !*** ./src/js/platform/browser/wrapper.js ***! \********************************************/ /*! exports provided: PlatformWrapperImplBrowser */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlatformWrapperImplBrowser", function() { return PlatformWrapperImplBrowser; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_query_parameters__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/query_parameters */ "./src/js/core/query_parameters.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _ad_providers_gamedistribution__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../ad_providers/gamedistribution */ "./src/js/platform/ad_providers/gamedistribution.js"); /* harmony import */ var _ad_providers_no_ad_provider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../ad_providers/no_ad_provider */ "./src/js/platform/ad_providers/no_ad_provider.js"); /* harmony import */ var _wrapper__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../wrapper */ "./src/js/platform/wrapper.js"); /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./storage */ "./src/js/platform/browser/storage.js"); /* harmony import */ var _storage_indexed_db__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./storage_indexed_db */ "./src/js/platform/browser/storage_indexed_db.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("platform/browser"); class PlatformWrapperImplBrowser extends _wrapper__WEBPACK_IMPORTED_MODULE_6__["PlatformWrapperInterface"] { initialize() { this.recaptchaTokenCallback = null; this.embedProvider = { id: "shapezio-website", adProvider: _ad_providers_no_ad_provider__WEBPACK_IMPORTED_MODULE_5__["NoAdProvider"], iframed: false, externalLinks: true, iogLink: true, unlimitedSavegames: _core_config__WEBPACK_IMPORTED_MODULE_0__["IS_DEMO"] ? false : true, showDemoBadge: _core_config__WEBPACK_IMPORTED_MODULE_0__["IS_DEMO"], }; if ( true && _core_query_parameters__WEBPACK_IMPORTED_MODULE_2__["queryParamOptions"].embedProvider) { const providerId = _core_query_parameters__WEBPACK_IMPORTED_MODULE_2__["queryParamOptions"].embedProvider; this.embedProvider.iframed = true; this.embedProvider.iogLink = false; switch (providerId) { case "armorgames": { this.embedProvider.id = "armorgames"; break; } case "iogames.space": { this.embedProvider.id = "iogames.space"; this.embedProvider.iogLink = true; this.embedProvider.unlimitedSavegames = true; this.embedProvider.showDemoBadge = false; break; } case "miniclip": { this.embedProvider.id = "miniclip"; break; } case "gamedistribution": { this.embedProvider.id = "gamedistribution"; this.embedProvider.externalLinks = false; this.embedProvider.adProvider = _ad_providers_gamedistribution__WEBPACK_IMPORTED_MODULE_4__["GamedistributionAdProvider"]; break; } case "kongregate": { this.embedProvider.id = "kongregate"; break; } case "crazygames": { this.embedProvider.id = "crazygames"; break; } default: { logger.error("Got unsupported embed provider:", providerId); } } } logger.log("Embed provider:", this.embedProvider.id); return this.detectStorageImplementation() .then(() => this.initializeAdProvider()) .then(() => super.initialize()); } detectStorageImplementation() { return new Promise(resolve => { logger.log("Detecting storage"); if (!window.indexedDB) { logger.log("Indexed DB not supported"); this.app.storage = new _storage__WEBPACK_IMPORTED_MODULE_7__["StorageImplBrowser"](this.app); resolve(); return; } // Try accessing the indexedb let request; try { request = window.indexedDB.open("indexeddb_feature_detection", 1); } catch (ex) { logger.warn("Error while opening indexed db:", ex); this.app.storage = new _storage__WEBPACK_IMPORTED_MODULE_7__["StorageImplBrowser"](this.app); resolve(); return; } request.onerror = err => { logger.log("Indexed DB can *not* be accessed: ", err); logger.log("Using fallback to local storage"); this.app.storage = new _storage__WEBPACK_IMPORTED_MODULE_7__["StorageImplBrowser"](this.app); resolve(); }; request.onsuccess = () => { logger.log("Indexed DB *can* be accessed"); this.app.storage = new _storage_indexed_db__WEBPACK_IMPORTED_MODULE_8__["StorageImplBrowserIndexedDB"](this.app); resolve(); }; }); } getHasUnlimitedSavegames() { return this.embedProvider.unlimitedSavegames; } getShowDemoBadges() { return this.embedProvider.showDemoBadge; } getId() { return "browser@" + this.embedProvider.id; } getUiScale() { if (_core_config__WEBPACK_IMPORTED_MODULE_0__["IS_MOBILE"]) { return 1; } const avgDims = Math.min(this.app.screenWidth, this.app.screenHeight); return Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["clamp"])((avgDims / 1000.0) * 1.9, 0.1, 10); } getSupportsRestart() { return true; } getTouchPanStrength() { return _core_config__WEBPACK_IMPORTED_MODULE_0__["IS_MOBILE"] ? 1 : 0.5; } openExternalLink(url, force = false) { logger.log("Opening external:", url); if (force || this.embedProvider.externalLinks) { window.open(url); } else { // Do nothing alert( "This platform does not allow opening external links. You can play on https://shapez.io directly to open them.\n\nClicked Link: " + url ); } } performRestart() { logger.log("Performing restart"); window.location.reload(true); } /** * Detects if there is an adblocker installed * @returns {Promise} */ detectAdblock() { return Promise.race([ new Promise(resolve => { // If the request wasn't blocked within a very short period of time, this means // the adblocker is not active and the request was actually made -> ignore it then setTimeout(() => resolve(false), 30); }), new Promise(resolve => { fetch("https://googleads.g.doubleclick.net/pagead/id", { method: "HEAD", mode: "no-cors", }) .then(res => { resolve(false); }) .catch(err => { resolve(true); }); }), ]); } initializeAdProvider() { if (!_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.testAds) { logger.log("Ads disabled in local environment"); return Promise.resolve(); } // First, detect adblocker return this.detectAdblock().then(hasAdblocker => { if (hasAdblocker) { logger.log("Adblock detected"); return; } const adProvider = this.embedProvider.adProvider; this.app.adProvider = new adProvider(this.app); return this.app.adProvider.initialize().catch(err => { logger.error("Failed to initialize ad provider, disabling ads:", err); this.app.adProvider = new _ad_providers_no_ad_provider__WEBPACK_IMPORTED_MODULE_5__["NoAdProvider"](this.app); }); }); } exitApp() { // Can not exit app } } /***/ }), /***/ "./src/js/platform/electron/storage.js": /*!*********************************************!*\ !*** ./src/js/platform/electron/storage.js ***! \*********************************************/ /*! exports provided: StorageImplElectron */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StorageImplElectron", function() { return StorageImplElectron; }); /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../storage */ "./src/js/platform/storage.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("electron-storage"); class StorageImplElectron extends _storage__WEBPACK_IMPORTED_MODULE_0__["StorageInterface"] { constructor(app) { super(app); /** @type {Object.} */ this.jobs = {}; this.jobId = 0; Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().on("fs-response", (event, arg) => { const id = arg.id; if (!this.jobs[id]) { logger.warn("Got unhandled FS response, job not known:", id); return; } const { resolve, reject } = this.jobs[id]; if (arg.result.success) { resolve(arg.result.data); } else { reject(arg.result.error); } }); } initialize() { return Promise.resolve(); } writeFileAsync(filename, contents) { return new Promise((resolve, reject) => { // ipcMain const jobId = ++this.jobId; this.jobs[jobId] = { resolve, reject }; Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().send("fs-job", { type: "write", filename, contents, id: jobId, }); }); } writeFileSyncIfSupported(filename, contents) { return Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().sendSync("fs-sync-job", { type: "write", filename, contents, }); } readFileAsync(filename) { return new Promise((resolve, reject) => { // ipcMain const jobId = ++this.jobId; this.jobs[jobId] = { resolve, reject }; Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().send("fs-job", { type: "read", filename, id: jobId, }); }); } deleteFileAsync(filename) { return new Promise((resolve, reject) => { // ipcMain const jobId = ++this.jobId; this.jobs[jobId] = { resolve, reject }; Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().send("fs-job", { type: "delete", filename, id: jobId, }); }); } } /***/ }), /***/ "./src/js/platform/electron/wrapper.js": /*!*********************************************!*\ !*** ./src/js/platform/electron/wrapper.js ***! \*********************************************/ /*! exports provided: PlatformWrapperImplElectron */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlatformWrapperImplElectron", function() { return PlatformWrapperImplElectron; }); /* harmony import */ var _browser_wrapper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../browser/wrapper */ "./src/js/platform/browser/wrapper.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./storage */ "./src/js/platform/electron/storage.js"); /* harmony import */ var _wrapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../wrapper */ "./src/js/platform/wrapper.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("electron-wrapper"); class PlatformWrapperImplElectron extends _browser_wrapper__WEBPACK_IMPORTED_MODULE_0__["PlatformWrapperImplBrowser"] { initialize() { this.app.storage = new _storage__WEBPACK_IMPORTED_MODULE_3__["StorageImplElectron"](this); return _wrapper__WEBPACK_IMPORTED_MODULE_4__["PlatformWrapperInterface"].prototype.initialize.call(this); } getId() { return "electron"; } getSupportsRestart() { return true; } openExternalLink(url) { logger.log(this, "Opening external:", url); window.open(url, "about:blank"); } getSupportsAds() { return false; } getHasUnlimitedSavegames() { return true; } getShowDemoBadges() { return false; } performRestart() { logger.log(this, "Performing restart"); window.location.reload(true); } initializeAdProvider() { return Promise.resolve(); } getSupportsFullscreen() { return true; } setFullscreen(flag) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().send("set-fullscreen", flag); } getSupportsAppExit() { return true; } exitApp() { logger.log(this, "Sending app exit signal"); Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["getIPCRenderer"])().send("exit-app"); } } /***/ }), /***/ "./src/js/platform/game_analytics.js": /*!*******************************************!*\ !*** ./src/js/platform/game_analytics.js ***! \*******************************************/ /*! exports provided: GameAnalyticsInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameAnalyticsInterface", function() { return GameAnalyticsInterface; }); /** * @typedef {import("../application").Application} Application */ class GameAnalyticsInterface { constructor(app) { /** @type {Application} */ this.app = app; } /** * Initializes the analytics * @returns {Promise} */ initialize() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.reject(); } /** * Handles a new game which was started */ handleGameStarted() {} /** * Handles a resumed game */ handleGameResumed() {} /** * Handles the given level completed * @param {number} level */ handleLevelCompleted(level) {} /** * Handles the given upgrade completed * @param {string} id * @param {number} level */ handleUpgradeUnlocked(id, level) {} } /***/ }), /***/ "./src/js/platform/sound.js": /*!**********************************!*\ !*** ./src/js/platform/sound.js ***! \**********************************/ /*! exports provided: SOUNDS, MUSIC, SoundInstanceInterface, MusicInstanceInterface, SoundInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SOUNDS", function() { return SOUNDS; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MUSIC", function() { return MUSIC; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SoundInstanceInterface", function() { return SoundInstanceInterface; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MusicInstanceInterface", function() { return MusicInstanceInterface; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SoundInterface", function() { return SoundInterface; }); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("sound"); const SOUNDS = { // Menu and such uiClick: "ui_click", uiError: "ui_error", dialogError: "dialog_error", dialogOk: "dialog_ok", swishHide: "ui_swish_hide", swishShow: "ui_swish_show", badgeNotification: "badge_notification", levelComplete: "level_complete", destroyBuilding: "destroy_building", placeBuilding: "place_building", placeBelt: "place_belt", }; const MUSIC = { theme: false ? undefined : "theme-short", menu: "menu", }; class SoundInstanceInterface { constructor(key, url) { this.key = key; this.url = url; } /** @returns {Promise} */ load() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.resolve(); } play(volume) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } deinitialize() {} } class MusicInstanceInterface { constructor(key, url) { this.key = key; this.url = url; } stop() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } play() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** @returns {Promise} */ load() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.resolve(); } /** @returns {boolean} */ isPlaying() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } deinitialize() {} } class SoundInterface { constructor(app, soundClass, musicClass) { /** @type {Application} */ this.app = app; this.soundClass = soundClass; this.musicClass = musicClass; /** @type {Object} */ this.sounds = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["newEmptyMap"])(); /** @type {Object} */ this.music = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["newEmptyMap"])(); /** @type {MusicInstanceInterface} */ this.currentMusic = null; this.pageIsVisible = true; this.musicMuted = false; this.soundsMuted = false; } /** * Initializes the sound * @returns {Promise} */ initialize() { for (const soundKey in SOUNDS) { const soundPath = SOUNDS[soundKey]; const sound = new this.soundClass(soundKey, soundPath); this.sounds[soundPath] = sound; } for (const musicKey in MUSIC) { const musicPath = MUSIC[musicKey]; const music = new this.musicClass(musicKey, musicPath); this.music[musicPath] = music; } this.musicMuted = this.app.settings.getAllSettings().musicMuted; this.soundsMuted = this.app.settings.getAllSettings().soundsMuted; if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.disableMusic) { this.musicMuted = true; } return Promise.resolve(); } /** * Pre-Loads the given sounds * @param {string} key * @returns {Promise} */ loadSound(key) { if (this.sounds[key]) { return this.sounds[key].load(); } else if (this.music[key]) { return this.music[key].load(); } else { logger.error("Sound/Music by key not found:", key); return Promise.resolve(); } } /** Deinits the sound * @returns {Promise} */ deinitialize() { const promises = []; for (const key in this.sounds) { promises.push(this.sounds[key].deinitialize()); } for (const key in this.music) { promises.push(this.music[key].deinitialize()); } // @ts-ignore return Promise.all(...promises); } /** * Returns if the music is muted * @returns {boolean} */ getMusicMuted() { return this.musicMuted; } /** * Returns if sounds are muted * @returns {boolean} */ getSoundsMuted() { return this.soundsMuted; } /** * Sets if the music is muted * @param {boolean} muted */ setMusicMuted(muted) { this.musicMuted = muted; if (this.musicMuted) { if (this.currentMusic) { this.currentMusic.stop(); } } else { if (this.currentMusic) { this.currentMusic.play(); } } } /** * Sets if the sounds are muted * @param {boolean} muted */ setSoundsMuted(muted) { this.soundsMuted = muted; } /** * Focus change handler, called by the pap * @param {boolean} pageIsVisible */ onPageRenderableStateChanged(pageIsVisible) { this.pageIsVisible = pageIsVisible; if (this.currentMusic) { if (pageIsVisible) { if (!this.currentMusic.isPlaying() && !this.musicMuted) { this.currentMusic.play(); } } else { this.currentMusic.stop(); } } } /** * @param {string} key */ playUiSound(key) { if (this.soundsMuted) { return; } if (!this.sounds[key]) { logger.warn("Sound", key, "not found, probably not loaded yet"); return; } this.sounds[key].play(1.0); } /** * * @param {string} key * @param {Vector} worldPosition * @param {GameRoot} root */ play3DSound(key, worldPosition, root) { if (!this.sounds[key]) { logger.warn("Music", key, "not found, probably not loaded yet"); return; } if (!this.pageIsVisible || this.soundsMuted) { return; } // hack, but works if (root.time.getIsPaused()) { return; } let volume = 1.0; if (!root.camera.isWorldPointOnScreen(worldPosition)) { volume = 0.2; } volume *= Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["clamp"])(root.camera.zoomLevel / 3); this.sounds[key].play(Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["clamp"])(volume)); } /** * @param {string} key */ playThemeMusic(key) { const music = this.music[key]; if (key !== null && !music) { logger.warn("Music", key, "not found"); } if (this.currentMusic !== music) { if (this.currentMusic) { logger.log("Stopping", this.currentMusic.key); this.currentMusic.stop(); } this.currentMusic = music; if (music && this.pageIsVisible && !this.musicMuted) { logger.log("Starting", this.currentMusic.key); music.play(); } } } } /***/ }), /***/ "./src/js/platform/storage.js": /*!************************************!*\ !*** ./src/js/platform/storage.js ***! \************************************/ /*! exports provided: FILE_NOT_FOUND, StorageInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FILE_NOT_FOUND", function() { return FILE_NOT_FOUND; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StorageInterface", function() { return StorageInterface; }); const FILE_NOT_FOUND = "file_not_found"; class StorageInterface { constructor(app) { /** @type {Application} */ this.app = app; } /** * Initializes the storage * @returns {Promise} */ initialize() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.reject(); } /** * Writes a string to a file asynchronously * @param {string} filename * @param {string} contents * @returns {Promise} */ writeFileAsync(filename, contents) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.reject(); } /** * Tries to write a file synchronously, used in unload handler * @param {string} filename * @param {string} contents */ writeFileSyncIfSupported(filename, contents) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } /** * Reads a string asynchronously. Returns Promise if file was not found. * @param {string} filename * @returns {Promise} */ readFileAsync(filename) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return Promise.reject(); } /** * Tries to delete a file * @param {string} filename * @returns {Promise} */ deleteFileAsync(filename) { // Default implementation does not allow deleting files return Promise.reject(); } } /***/ }), /***/ "./src/js/platform/wrapper.js": /*!************************************!*\ !*** ./src/js/platform/wrapper.js ***! \************************************/ /*! exports provided: PlatformWrapperInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlatformWrapperInterface", function() { return PlatformWrapperInterface; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); class PlatformWrapperInterface { constructor(app) { /** @type {Application} */ this.app = app; } /** @returns {string} */ getId() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return "unknown-platform"; } /** * Returns the UI scale, called on every resize * @returns {number} */ getUiScale() { return 1; } /** @returns {boolean} */ getSupportsRestart() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } /** * Whether the user has unlimited savegames */ getHasUnlimitedSavegames() { return true; } getShowDemoBadges() { return false; } /** * Returns the strength of touch pans with the mouse */ getTouchPanStrength() { return 1; } /** @returns {Promise} */ initialize() { document.documentElement.classList.add("p-" + this.getId()); return Promise.resolve(); } /** * Should initialize the apps ad provider in case supported * @returns {Promise} */ initializeAdProvider() { return Promise.resolve(); } /** * Should return the minimum supported zoom level * @returns {number} */ getMinimumZoom() { return 0.1 * this.getScreenScale(); } /** * Should return the maximum supported zoom level * @returns {number} */ getMaximumZoom() { return 3.5 * this.getScreenScale(); } getScreenScale() { return Math.min(window.innerWidth, window.innerHeight) / 1024.0; } /** * Should return if this platform supports ads at all */ getSupportsAds() { return false; } /** * Attempt to open an external url * @param {string} url * @param {boolean=} force Whether to always open the url even if not allowed */ openExternalLink(url, force = false) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Attempt to restart the app */ performRestart() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Returns whether this platform supports a toggleable fullscreen */ getSupportsFullscreen() { return false; } /** * Should set the apps fullscreen state to the desired state * @param {boolean} flag */ setFullscreen(flag) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Returns whether this platform supports quitting the app */ getSupportsAppExit() { return false; } /** * Attempts to quit the app */ exitApp() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Whether this platform supports a keyboard */ getSupportsKeyboard() { return !_core_config__WEBPACK_IMPORTED_MODULE_0__["IS_MOBILE"]; } } /***/ }), /***/ "./src/js/profile/application_settings.js": /*!************************************************!*\ !*** ./src/js/profile/application_settings.js ***! \************************************************/ /*! exports provided: enumCategories, uiScales, scrollWheelSensitivities, movementSpeeds, autosaveIntervals, allApplicationSettings, getApplicationSettingById, ApplicationSettings */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumCategories", function() { return enumCategories; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "uiScales", function() { return uiScales; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scrollWheelSensitivities", function() { return scrollWheelSensitivities; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "movementSpeeds", function() { return movementSpeeds; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "autosaveIntervals", function() { return autosaveIntervals; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allApplicationSettings", function() { return allApplicationSettings; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getApplicationSettingById", function() { return getApplicationSettingById; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ApplicationSettings", function() { return ApplicationSettings; }); /* harmony import */ var _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/read_write_proxy */ "./src/js/core/read_write_proxy.js"); /* harmony import */ var _setting_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./setting_types */ "./src/js/profile/setting_types.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_explained_result__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/explained_result */ "./src/js/core/explained_result.js"); /* harmony import */ var _game_theme__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../game/theme */ "./src/js/game/theme.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /* harmony import */ var _languages__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../languages */ "./src/js/languages.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("application_settings"); /** * @enum {string} */ const enumCategories = { general: "general", userInterface: "userInterface", performance: "performance", advanced: "advanced", debug: "debug", keybindings: "keybindings", }; const uiScales = [ { id: "super_small", size: 0.6, }, { id: "small", size: 0.8, }, { id: "regular", size: 1, }, { id: "large", size: 1.05, }, { id: "huge", size: 1.1, }, ]; const scrollWheelSensitivities = [ { id: "super_slow", scale: 0.25, }, { id: "slow", scale: 0.5, }, { id: "regular", scale: 1, }, { id: "fast", scale: 2, }, { id: "super_fast", scale: 4, }, ]; const movementSpeeds = [ { id: "super_slow", multiplier: 0.25, }, { id: "slow", multiplier: 0.5, }, { id: "regular", multiplier: 1, }, { id: "fast", multiplier: 2, }, { id: "super_fast", multiplier: 4, }, { id: "extremely_fast", multiplier: 8, }, ]; const autosaveIntervals = [ { id: "one_minute", seconds: 60, }, { id: "two_minutes", seconds: 120, }, { id: "five_minutes", seconds: 5 * 60, }, { id: "ten_minutes", seconds: 10 * 60, }, { id: "twenty_minutes", seconds: 20 * 60, }, { id: "disabled", seconds: null, }, ]; /** @type {Array} */ const allApplicationSettings = [ new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("language", { options: Object.keys(_languages__WEBPACK_IMPORTED_MODULE_7__["LANGUAGES"]), valueGetter: key => key, textGetter: key => _languages__WEBPACK_IMPORTED_MODULE_7__["LANGUAGES"][key].name, category: enumCategories.general, restartRequired: true, changeCb: (app, id) => null, magicValue: "auto-detect", }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("uiScale", { options: uiScales.sort((a, b) => a.size - b.size), valueGetter: scale => scale.id, textGetter: scale => _translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels.uiScale.scales[scale.id], category: enumCategories.userInterface, restartRequired: false, changeCb: /** * @param {Application} app */ (app, id) => app.updateAfterUiScaleChanged(), }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]( "soundsMuted", enumCategories.general, /** * @param {Application} app */ (app, value) => app.sound.setSoundsMuted(value) ), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]( "musicMuted", enumCategories.general, /** * @param {Application} app */ (app, value) => app.sound.setMusicMuted(value) ), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]( "fullscreen", enumCategories.general, /** * @param {Application} app */ (app, value) => { if (app.platformWrapper.getSupportsFullscreen()) { app.platformWrapper.setFullscreen(value); } }, !_core_config__WEBPACK_IMPORTED_MODULE_5__["IS_DEMO"] ), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]( "enableColorBlindHelper", enumCategories.general, /** * @param {Application} app */ (app, value) => null ), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("offerHints", enumCategories.userInterface, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("theme", { options: Object.keys(_game_theme__WEBPACK_IMPORTED_MODULE_4__["THEMES"]), valueGetter: theme => theme, textGetter: theme => _translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels.theme.themes[theme], category: enumCategories.userInterface, restartRequired: false, changeCb: /** * @param {Application} app */ (app, id) => { Object(_game_theme__WEBPACK_IMPORTED_MODULE_4__["applyGameTheme"])(id); document.documentElement.setAttribute("data-theme", id); }, enabled: !_core_config__WEBPACK_IMPORTED_MODULE_5__["IS_DEMO"], }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("autosaveInterval", { options: autosaveIntervals, valueGetter: interval => interval.id, textGetter: interval => _translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels.autosaveInterval.intervals[interval.id], category: enumCategories.advanced, restartRequired: false, changeCb: /** * @param {Application} app */ (app, id) => null, }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("scrollWheelSensitivity", { options: scrollWheelSensitivities.sort((a, b) => a.scale - b.scale), valueGetter: scale => scale.id, textGetter: scale => _translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels.scrollWheelSensitivity.sensitivity[scale.id], category: enumCategories.advanced, restartRequired: false, changeCb: /** * @param {Application} app */ (app, id) => app.updateAfterUiScaleChanged(), }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("movementSpeed", { options: movementSpeeds.sort((a, b) => a.multiplier - b.multiplier), valueGetter: multiplier => multiplier.id, textGetter: multiplier => _translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels.movementSpeed.speeds[multiplier.id], category: enumCategories.advanced, restartRequired: false, changeCb: (app, id) => {}, }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("alwaysMultiplace", enumCategories.advanced, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("enableTunnelSmartplace", enumCategories.advanced, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("vignette", enumCategories.userInterface, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("compactBuildingInfo", enumCategories.userInterface, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("disableCutDeleteWarnings", enumCategories.advanced, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("rotationByBuilding", enumCategories.advanced, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["EnumSetting"]("refreshRate", { options: ["60", "75", "100", "120", "144", "165", "250", "500"], valueGetter: rate => rate, textGetter: rate => rate + " Hz", category: enumCategories.performance, restartRequired: false, changeCb: (app, id) => {}, enabled: !_core_config__WEBPACK_IMPORTED_MODULE_5__["IS_DEMO"], }), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("lowQualityMapResources", enumCategories.performance, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("disableTileGrid", enumCategories.performance, (app, value) => {}), new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"]("lowQualityTextures", enumCategories.performance, (app, value) => {}), ]; if (_core_config__WEBPACK_IMPORTED_MODULE_5__["IS_DEBUG"]) { for (let k in _core_config__WEBPACK_IMPORTED_MODULE_5__["globalConfig"].debug) { if (k.startsWith("_")) continue; const setting = new _setting_types__WEBPACK_IMPORTED_MODULE_1__["BoolSetting"](`debug_${k}`, enumCategories.debug, (app, value) => { _core_config__WEBPACK_IMPORTED_MODULE_5__["globalConfig"].debug[k] = value; }); setting.validate = () => true; _translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels[`debug_${k}`] = { title: k.replace(/(?!^)([A-Z])/g, " $1"), description: _core_config__WEBPACK_IMPORTED_MODULE_5__["globalConfig"].debug[`_${k}`], }; allApplicationSettings.push(setting); } } function getApplicationSettingById(id) { return allApplicationSettings.find(setting => setting.id === id); } class SettingsStorage { constructor() { this.uiScale = "regular"; this.fullscreen = false; this.soundsMuted = false; this.musicMuted = false; this.theme = "light"; this.refreshRate = "60"; this.scrollWheelSensitivity = "regular"; this.movementSpeed = "regular"; this.language = "auto-detect"; this.autosaveInterval = "two_minutes"; this.alwaysMultiplace = false; this.offerHints = true; this.enableTunnelSmartplace = true; this.vignette = true; this.compactBuildingInfo = false; this.disableCutDeleteWarnings = false; this.rotationByBuilding = true; this.enableColorBlindHelper = false; this.lowQualityMapResources = false; this.disableTileGrid = false; this.lowQualityTextures = false; /** * @type {Object.} */ this.keybindingOverrides = {}; } } class ApplicationSettings extends _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_0__["ReadWriteProxy"] { constructor(app) { super(app, "app_settings.bin"); } initialize() { // Read and directly write latest data back return this.readAsync() .then(() => { // Apply default setting callbacks const settings = this.getAllSettings(); for (let i = 0; i < allApplicationSettings.length; ++i) { const handle = allApplicationSettings[i]; handle.apply(this.app, settings[handle.id]); } }) .then(() => this.writeAsync()); } save() { return this.writeAsync(); } // Getters /** * @returns {SettingsStorage} */ getAllSettings() { return this.getCurrentData().settings; } /** * @param {string} key */ getSetting(key) { if (!key.startsWith("debug_")) { window.assert(this.getAllSettings().hasOwnProperty(key), "Setting not known: " + key); } return this.getAllSettings()[key]; } getInterfaceScaleId() { if (!this.currentData) { // Not initialized yet return "regular"; } return this.getAllSettings().uiScale; } getDesiredFps() { return parseInt(this.getAllSettings().refreshRate); } getInterfaceScaleValue() { const id = this.getInterfaceScaleId(); for (let i = 0; i < uiScales.length; ++i) { if (uiScales[i].id === id) { return uiScales[i].size; } } logger.error("Unknown ui scale id:", id); return 1; } getScrollWheelSensitivity() { const id = this.getAllSettings().scrollWheelSensitivity; for (let i = 0; i < scrollWheelSensitivities.length; ++i) { if (scrollWheelSensitivities[i].id === id) { return scrollWheelSensitivities[i].scale; } } logger.error("Unknown scroll wheel sensitivity id:", id); return 1; } getMovementSpeed() { const id = this.getAllSettings().movementSpeed; for (let i = 0; i < movementSpeeds.length; ++i) { if (movementSpeeds[i].id === id) { return movementSpeeds[i].multiplier; } } logger.error("Unknown movement speed id:", id); return 1; } getAutosaveIntervalSeconds() { const id = this.getAllSettings().autosaveInterval; for (let i = 0; i < autosaveIntervals.length; ++i) { if (autosaveIntervals[i].id === id) { return autosaveIntervals[i].seconds; } } logger.error("Unknown autosave interval id:", id); return 120; } getIsFullScreen() { return this.getAllSettings().fullscreen; } getKeybindingOverrides() { return this.getAllSettings().keybindingOverrides; } getLanguage() { return this.getAllSettings().language; } // Setters updateLanguage(id) { window.assert(_languages__WEBPACK_IMPORTED_MODULE_7__["LANGUAGES"][id], "Language not known: " + id); return this.updateSetting("language", id); } /** * @param {string} key * @param {string|boolean} value */ updateSetting(key, value) { for (let i = 0; i < allApplicationSettings.length; ++i) { const setting = allApplicationSettings[i]; if (setting.id === key) { if (!setting.validate(value)) { window.assert(false, "Bad setting value: " + key); } this.getAllSettings()[key] = value; if (setting.changeCb) { setting.changeCb(this.app, value); } return this.writeAsync(); } } window.assert(false, "Unknown setting: " + key); } /** * Sets a new keybinding override * @param {string} keybindingId * @param {number} keyCode */ updateKeybindingOverride(keybindingId, keyCode) { window.assert(Number.isInteger(keyCode), "Not a valid key code: " + keyCode); this.getAllSettings().keybindingOverrides[keybindingId] = keyCode; return this.writeAsync(); } /** * Resets a given keybinding override * @param {string} id */ resetKeybindingOverride(id) { delete this.getAllSettings().keybindingOverrides[id]; return this.writeAsync(); } /** * Resets all keybinding overrides */ resetKeybindingOverrides() { this.getAllSettings().keybindingOverrides = {}; return this.writeAsync(); } // RW Proxy impl verify(data) { if (!data.settings) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_3__["ExplainedResult"].bad("missing key 'settings'"); } if (typeof data.settings !== "object") { return _core_explained_result__WEBPACK_IMPORTED_MODULE_3__["ExplainedResult"].bad("Bad settings object"); } const settings = data.settings; for (let i = 0; i < allApplicationSettings.length; ++i) { const setting = allApplicationSettings[i]; const storedValue = settings[setting.id]; if (!setting.validate(storedValue)) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_3__["ExplainedResult"].bad("Bad setting value for " + setting.id + ": " + storedValue); } } return _core_explained_result__WEBPACK_IMPORTED_MODULE_3__["ExplainedResult"].good(); } getDefaultData() { return { version: this.getCurrentVersion(), settings: new SettingsStorage(), }; } getCurrentVersion() { return 21; } /** @param {{settings: SettingsStorage, version: number}} data */ migrate(data) { // Simply reset before if (data.version < 5) { data.settings = new SettingsStorage(); data.version = this.getCurrentVersion(); return _core_explained_result__WEBPACK_IMPORTED_MODULE_3__["ExplainedResult"].good(); } if (data.version < 6) { data.settings.alwaysMultiplace = false; data.version = 6; } if (data.version < 7) { data.settings.offerHints = true; data.version = 7; } if (data.version < 8) { data.settings.scrollWheelSensitivity = "regular"; data.version = 8; } if (data.version < 9) { data.settings.language = "auto-detect"; data.version = 9; } if (data.version < 10) { data.settings.movementSpeed = "regular"; data.version = 10; } if (data.version < 11) { data.settings.enableTunnelSmartplace = true; data.version = 11; } if (data.version < 12) { data.settings.vignette = true; data.version = 12; } if (data.version < 13) { data.settings.compactBuildingInfo = false; data.version = 13; } if (data.version < 14) { data.settings.disableCutDeleteWarnings = false; data.version = 14; } if (data.version < 15) { data.settings.autosaveInterval = "two_minutes"; data.version = 15; } if (data.version < 16) { // RE-ENABLE this setting, it already existed data.settings.enableTunnelSmartplace = true; data.version = 16; } if (data.version < 17) { data.settings.enableColorBlindHelper = false; data.version = 17; } if (data.version < 18) { data.settings.rotationByBuilding = true; data.version = 18; } if (data.version < 19) { data.settings.lowQualityMapResources = false; data.version = 19; } if (data.version < 20) { data.settings.disableTileGrid = false; data.version = 20; } if (data.version < 21) { data.settings.lowQualityTextures = false; data.version = 21; } return _core_explained_result__WEBPACK_IMPORTED_MODULE_3__["ExplainedResult"].good(); } } /***/ }), /***/ "./src/js/profile/setting_types.js": /*!*****************************************!*\ !*** ./src/js/profile/setting_types.js ***! \*****************************************/ /*! exports provided: BaseSetting, EnumSetting, BoolSetting */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSetting", function() { return BaseSetting; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EnumSetting", function() { return EnumSetting; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoolSetting", function() { return BoolSetting; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("setting_types"); class BaseSetting { /** * * @param {string} id * @param {string} categoryId * @param {function(Application, any):void} changeCb * @param {boolean} enabled */ constructor(id, categoryId, changeCb, enabled) { this.id = id; this.categoryId = categoryId; this.changeCb = changeCb; this.enabled = enabled; /** @type {Application} */ this.app = null; this.element = null; this.dialogs = null; } /** * @param {Application} app * @param {any} value */ apply(app, value) { if (this.changeCb) { this.changeCb(app, value); } } /** * @param {Application} app * @param {HTMLElement} element * @param {any} dialogs */ bind(app, element, dialogs) { this.app = app; this.element = element; this.dialogs = dialogs; } getHtml() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return ""; } syncValueToElement() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } modify() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } showRestartRequiredDialog() { const { restart } = this.dialogs.showInfo( _translations__WEBPACK_IMPORTED_MODULE_1__["T"].dialogs.restartRequired.title, _translations__WEBPACK_IMPORTED_MODULE_1__["T"].dialogs.restartRequired.text, this.app.platformWrapper.getSupportsRestart() ? ["later:grey", "restart:misc"] : ["ok:good"] ); if (restart) { restart.add(() => this.app.platformWrapper.performRestart()); } } /** * @param {any} value * @returns {boolean} */ validate(value) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return false; } } class EnumSetting extends BaseSetting { constructor( id, { options, valueGetter, textGetter, descGetter = null, category, restartRequired = true, iconPrefix = null, changeCb = null, magicValue = null, enabled = true, } ) { super(id, category, changeCb, enabled); this.options = options; this.valueGetter = valueGetter; this.textGetter = textGetter; this.descGetter = descGetter || (() => null); this.restartRequired = restartRequired; this.iconPrefix = iconPrefix; this.magicValue = magicValue; } getHtml() { return `
${this.enabled ? "" : `${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].demo.settingNotAvailable}`}
${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].description}
`; } validate(value) { if (value === this.magicValue) { return true; } const availableValues = this.options.map(option => this.valueGetter(option)); if (availableValues.indexOf(value) < 0) { logger.error( "Value '" + value + "' is not contained in available values:", availableValues, "of", this.id ); return false; } return true; } syncValueToElement() { const value = this.app.settings.getSetting(this.id); let displayText = "???"; const matchedInstance = this.options.find(data => this.valueGetter(data) === value); if (matchedInstance) { displayText = this.textGetter(matchedInstance); } else { logger.warn("Setting value", value, "not found for", this.id, "!"); } this.element.innerText = displayText; } modify() { const { optionSelected } = this.dialogs.showOptionChooser(_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].title, { active: this.app.settings.getSetting(this.id), options: this.options.map(option => ({ value: this.valueGetter(option), text: this.textGetter(option), desc: this.descGetter(option), iconPrefix: this.iconPrefix, })), }); optionSelected.add(value => { this.app.settings.updateSetting(this.id, value); this.syncValueToElement(); if (this.restartRequired) { this.showRestartRequiredDialog(); } if (this.changeCb) { this.changeCb(this.app, value); } }, this); } } class BoolSetting extends BaseSetting { constructor(id, category, changeCb = null, enabled = true) { super(id, category, changeCb, enabled); } getHtml() { if (!_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].description) { let a = _translations__WEBPACK_IMPORTED_MODULE_1__["T"]; let b = a; } return `
${this.enabled ? "" : `${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].demo.settingNotAvailable}`}
${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].description}
`; } syncValueToElement() { const value = this.app.settings.getSetting(this.id); this.element.classList.toggle("checked", value); } modify() { const newValue = !this.app.settings.getSetting(this.id); this.app.settings.updateSetting(this.id, newValue); this.syncValueToElement(); if (this.changeCb) { this.changeCb(this.app, newValue); } } validate(value) { return typeof value === "boolean"; } } /***/ }), /***/ "./src/js/savegame/savegame.js": /*!*************************************!*\ !*** ./src/js/savegame/savegame.js ***! \*************************************/ /*! exports provided: Savegame */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Savegame", function() { return Savegame; }); /* harmony import */ var _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/read_write_proxy */ "./src/js/core/read_write_proxy.js"); /* harmony import */ var _core_explained_result__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/explained_result */ "./src/js/core/explained_result.js"); /* harmony import */ var _savegame_serializer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./savegame_serializer */ "./src/js/savegame/savegame_serializer.js"); /* harmony import */ var _savegame_interface__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./savegame_interface */ "./src/js/savegame/savegame_interface.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _savegame_interface_registry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./savegame_interface_registry */ "./src/js/savegame/savegame_interface_registry.js"); /* harmony import */ var _schemas_1001__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./schemas/1001 */ "./src/js/savegame/schemas/1001.js"); /* harmony import */ var _schemas_1002__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./schemas/1002 */ "./src/js/savegame/schemas/1002.js"); /* harmony import */ var _schemas_1003__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./schemas/1003 */ "./src/js/savegame/schemas/1003.js"); /* harmony import */ var _schemas_1004__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./schemas/1004 */ "./src/js/savegame/schemas/1004.js"); /* harmony import */ var _schemas_1005__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./schemas/1005 */ "./src/js/savegame/schemas/1005.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_4__["createLogger"])("savegame"); /** * @typedef {import("../application").Application} Application * @typedef {import("../game/root").GameRoot} GameRoot * @typedef {import("./savegame_typedefs").SavegameData} SavegameData * @typedef {import("./savegame_typedefs").SavegameMetadata} SavegameMetadata * @typedef {import("./savegame_typedefs").SavegameStats} SavegameStats * @typedef {import("./savegame_typedefs").SerializedGame} SerializedGame */ class Savegame extends _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_0__["ReadWriteProxy"] { /** * * @param {Application} app * @param {object} param0 * @param {string} param0.internalId * @param {SavegameMetadata} param0.metaDataRef Handle to the meta data */ constructor(app, { internalId, metaDataRef }) { super(app, "savegame-" + internalId + ".bin"); this.internalId = internalId; this.metaDataRef = metaDataRef; /** @type {SavegameData} */ this.currentData = this.getDefaultData(); window.assert( _savegame_interface_registry__WEBPACK_IMPORTED_MODULE_6__["savegameInterfaces"][Savegame.getCurrentVersion()], "Savegame interface not defined: " + Savegame.getCurrentVersion() ); } //////// RW Proxy Impl ////////// /** * @returns {number} */ static getCurrentVersion() { return 1005; } /** * @returns {typeof BaseSavegameInterface} */ static getReaderClass() { return _savegame_interface_registry__WEBPACK_IMPORTED_MODULE_6__["savegameInterfaces"][Savegame.getCurrentVersion()]; } /** * @returns {number} */ getCurrentVersion() { return /** @type {typeof Savegame} */ (this.constructor).getCurrentVersion(); } /** * Returns the savegames default data * @returns {SavegameData} */ getDefaultData() { return { version: this.getCurrentVersion(), dump: null, stats: {}, lastUpdate: Date.now(), }; } /** * Migrates the savegames data * @param {SavegameData} data */ migrate(data) { if (data.version < 1000) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_1__["ExplainedResult"].bad("Can not migrate savegame, too old"); } if (data.version === 1000) { _schemas_1001__WEBPACK_IMPORTED_MODULE_7__["SavegameInterface_V1001"].migrate1000to1001(data); data.version = 1001; } if (data.version === 1001) { _schemas_1002__WEBPACK_IMPORTED_MODULE_8__["SavegameInterface_V1002"].migrate1001to1002(data); data.version = 1002; } if (data.version === 1002) { _schemas_1003__WEBPACK_IMPORTED_MODULE_9__["SavegameInterface_V1003"].migrate1002to1003(data); data.version = 1003; } if (data.version === 1003) { _schemas_1004__WEBPACK_IMPORTED_MODULE_10__["SavegameInterface_V1004"].migrate1003to1004(data); data.version = 1004; } if (data.version === 1004) { _schemas_1005__WEBPACK_IMPORTED_MODULE_11__["SavegameInterface_V1005"].migrate1004to1005(data); data.version = 1005; } if (data.version === 1005) { _schemas_1005__WEBPACK_IMPORTED_MODULE_11__["SavegameInterface_V1005"].migrate1005(data); data.version = 1005; } return _core_explained_result__WEBPACK_IMPORTED_MODULE_1__["ExplainedResult"].good(); } migrateBeforeGameEnter(data) { _schemas_1005__WEBPACK_IMPORTED_MODULE_11__["SavegameInterface_V1005"].migrate1005BeforeGameEnter(data); } migrateAfterGameEnter(data, root) { _schemas_1005__WEBPACK_IMPORTED_MODULE_11__["SavegameInterface_V1005"].migrate1005AfterGameEnter(data, root); } /** * Verifies the savegames data * @param {SavegameData} data */ verify(data) { if (!data.dump) { // Well, guess that works return _core_explained_result__WEBPACK_IMPORTED_MODULE_1__["ExplainedResult"].good(); } if (!this.getDumpReaderForExternalData(data).validate()) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_1__["ExplainedResult"].bad("dump-reader-failed-validation"); } return _core_explained_result__WEBPACK_IMPORTED_MODULE_1__["ExplainedResult"].good(); } //////// Subclasses interface //////// /** * Returns if this game can be saved on disc * @returns {boolean} */ isSaveable() { return true; } /** * Returns the statistics of the savegame * @returns {SavegameStats} */ getStatistics() { return this.currentData.stats; } /** * Returns the *real* last update of the savegame, not the one of the metadata * which could also be the servers one */ getRealLastUpdate() { return this.currentData.lastUpdate; } /** * Returns if this game has a serialized game dump */ hasGameDump() { return !!this.currentData.dump && this.currentData.dump.entities.length > 0; } /** * Returns the current game dump * @returns {SerializedGame} */ getCurrentDump() { return this.currentData.dump; } /** * Returns a reader to access the data * @returns {BaseSavegameInterface} */ getDumpReader() { if (!this.currentData.dump) { logger.warn("Getting reader on null-savegame dump"); } const cls = /** @type {typeof Savegame} */ (this.constructor).getReaderClass(); return new cls(this.currentData); } /** * Returns a reader to access external data * @returns {BaseSavegameInterface} */ getDumpReaderForExternalData(data) { window.assert(data.version, "External data contains no version"); return Object(_savegame_interface_registry__WEBPACK_IMPORTED_MODULE_6__["getSavegameInterface"])(data); } ///////// Public Interface /////////// /** * Updates the last update field so we can send the savegame to the server, * WITHOUT Saving! */ setLastUpdate(time) { this.currentData.lastUpdate = time; } /** * * @param {GameRoot} root */ updateData(root) { // Construct a new serializer const serializer = new _savegame_serializer__WEBPACK_IMPORTED_MODULE_2__["SavegameSerializer"](); // let timer = performance.now(); const dump = serializer.generateDumpFromGameRoot(root); if (!dump) { return false; } const shadowData = Object.assign({}, this.currentData); shadowData.dump = dump; shadowData.lastUpdate = new Date().getTime(); shadowData.version = this.getCurrentVersion(); shadowData.lastVersion = "modZ 1.0.3"; const reader = this.getDumpReaderForExternalData(shadowData); // Validate (not in prod though) if (true) { const validationResult = reader.validate(); if (!validationResult) { return false; } } // Save data this.currentData = shadowData; } /** * Writes the savegame as well as its metadata */ writeSavegameAndMetadata() { return this.writeAsync().then(() => this.saveMetadata()); } /** * Updates the savegames metadata */ saveMetadata() { this.metaDataRef.lastUpdate = new Date().getTime(); this.metaDataRef.version = this.getCurrentVersion(); this.metaDataRef.lastVersion = "modZ 1.0.3"; if (!this.hasGameDump()) { this.metaDataRef.level = 0; } else { this.metaDataRef.level = this.currentData.dump.hubGoals.level; } return this.app.savegameMgr.writeAsync(); } /** * @see ReadWriteProxy.writeAsync * @returns {Promise} */ writeAsync() { if (_core_config__WEBPACK_IMPORTED_MODULE_5__["globalConfig"].debug.disableSavegameWrite) { return Promise.resolve(); } return super.writeAsync(); } } /***/ }), /***/ "./src/js/savegame/savegame_compressor.js": /*!************************************************!*\ !*** ./src/js/savegame/savegame_compressor.js ***! \************************************************/ /*! exports provided: compressObject, decompressObject */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compressObject", function() { return compressObject; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decompressObject", function() { return decompressObject; }); const charmap = "!#%&'()*+,-./:;<=>?@[]^_`{|}~¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿABCDEFGHIJKLMNOPQRSTUVWXYZ"; let compressionCache = {}; let decompressionCache = {}; /** * Compresses an integer into a tight string representation * @param {number} i * @returns {string} */ function compressInt(i) { // Zero value breaks i += 1; if (compressionCache[i]) { return compressionCache[i]; } let result = ""; do { result += charmap[i % charmap.length]; i = Math.floor(i / charmap.length); } while (i > 0); return (compressionCache[i] = result); } /** * Decompresses an integer from its tight string representation * @param {string} s * @returns {number} */ function decompressInt(s) { if (decompressionCache[s]) { return decompressionCache[s]; } s = "" + s; let result = 0; for (let i = s.length - 1; i >= 0; --i) { result = result * charmap.length + charmap.indexOf(s.charAt(i)); } // Fixes zero value break fix from above result -= 1; return (decompressionCache[s] = result); } // Sanity if (true) { for (let i = 0; i < 10000; ++i) { if (decompressInt(compressInt(i)) !== i) { throw new Error( "Bad compression for: " + i + " compressed: " + compressInt(i) + " decompressed: " + decompressInt(compressInt(i)) ); } } } function compressObjectInternal(obj, keys = [], values = []) { if (Array.isArray(obj)) { let result = []; for (let i = 0; i < obj.length; ++i) { result.push(compressObjectInternal(obj[i], keys, values)); } return result; } else if (typeof obj === "object" && obj !== null) { let result = {}; for (const key in obj) { let index = keys.indexOf(key); if (index < 0) { keys.push(key); index = keys.length - 1; } const value = obj[key]; result[compressInt(index)] = compressObjectInternal(value, keys, values); } return result; } else if (typeof obj === "string") { let index = values.indexOf(obj); if (index < 0) { values.push(obj); index = values.length - 1; } return compressInt(index); } return obj; } function compressObject(obj) { const keys = []; const values = []; const data = compressObjectInternal(obj, keys, values); return { keys, values, data, }; } function decompressObjectInternal(obj, keys = [], values = []) { if (Array.isArray(obj)) { let result = []; for (let i = 0; i < obj.length; ++i) { result.push(decompressObjectInternal(obj[i], keys, values)); } return result; } else if (typeof obj === "object" && obj !== null) { let result = {}; for (const key in obj) { const realIndex = decompressInt(key); const value = obj[key]; result[keys[realIndex]] = decompressObjectInternal(value, keys, values); } return result; } else if (typeof obj === "string") { const realIndex = decompressInt(obj); return values[realIndex]; } return obj; } function decompressObject(obj) { if (obj.keys && obj.values && obj.data) { const keys = obj.keys; const values = obj.values; const result = decompressObjectInternal(obj.data, keys, values); return result; } return obj; } /***/ }), /***/ "./src/js/savegame/savegame_interface.js": /*!***********************************************!*\ !*** ./src/js/savegame/savegame_interface.js ***! \***********************************************/ /*! exports provided: BaseSavegameInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSavegameInterface", function() { return BaseSavegameInterface; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); const Ajv = __webpack_require__(/*! ajv */ "./node_modules/ajv/lib/ajv.js"); const ajv = new Ajv({ allErrors: false, uniqueItems: false, unicode: false, nullable: false, }); const validators = {}; const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("savegame_interface"); class BaseSavegameInterface { /** * Returns the interfaces version */ getVersion() { throw new Error("Implement get version"); } /** * Returns the uncached json schema * @returns {object} */ getSchemaUncached() { throw new Error("Implement get schema"); } getValidator() { const version = this.getVersion(); if (validators[version]) { return validators[version]; } logger.log("Compiling schema for savegame version", version); const schema = this.getSchemaUncached(); try { validators[version] = ajv.compile(schema); } catch (ex) { logger.error("SCHEMA FOR", this.getVersion(), "IS INVALID!"); logger.error(ex); throw new Error("Invalid schema for version " + version); } return validators[version]; } /** * Constructs an new interface for the given savegame * @param {any} data */ constructor(data) { this.data = data; } /** * Validates the data * @returns {boolean} */ validate() { const validator = this.getValidator(); if (!validator(this.data)) { logger.error( "Savegame failed validation! ErrorText:", ajv.errorsText(validator.errors), "RawErrors:", validator.errors ); return false; } return true; } ///// INTERFACE (Override when the schema changes) ///// /** * Returns the time of last update * @returns {number} */ readLastUpdate() { return this.data.lastUpdate; } /** * Returns the ingame time in seconds * @returns {number} */ readIngameTimeSeconds() { return this.data.dump.time.timeSeconds; } } /***/ }), /***/ "./src/js/savegame/savegame_interface_registry.js": /*!********************************************************!*\ !*** ./src/js/savegame/savegame_interface_registry.js ***! \********************************************************/ /*! exports provided: savegameInterfaces, getSavegameInterface */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "savegameInterfaces", function() { return savegameInterfaces; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSavegameInterface", function() { return getSavegameInterface; }); /* harmony import */ var _savegame_interface__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./savegame_interface */ "./src/js/savegame/savegame_interface.js"); /* harmony import */ var _schemas_1000__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./schemas/1000 */ "./src/js/savegame/schemas/1000.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _schemas_1001__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./schemas/1001 */ "./src/js/savegame/schemas/1001.js"); /* harmony import */ var _schemas_1002__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./schemas/1002 */ "./src/js/savegame/schemas/1002.js"); /* harmony import */ var _schemas_1003__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./schemas/1003 */ "./src/js/savegame/schemas/1003.js"); /* harmony import */ var _schemas_1004__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./schemas/1004 */ "./src/js/savegame/schemas/1004.js"); /* harmony import */ var _schemas_1005__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./schemas/1005 */ "./src/js/savegame/schemas/1005.js"); /** @type {Object.} */ const savegameInterfaces = { 1000: _schemas_1000__WEBPACK_IMPORTED_MODULE_1__["SavegameInterface_V1000"], 1001: _schemas_1001__WEBPACK_IMPORTED_MODULE_3__["SavegameInterface_V1001"], 1002: _schemas_1002__WEBPACK_IMPORTED_MODULE_4__["SavegameInterface_V1002"], 1003: _schemas_1003__WEBPACK_IMPORTED_MODULE_5__["SavegameInterface_V1003"], 1004: _schemas_1004__WEBPACK_IMPORTED_MODULE_6__["SavegameInterface_V1004"], 1005: _schemas_1005__WEBPACK_IMPORTED_MODULE_7__["SavegameInterface_V1005"], }; const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("savegame_interface_registry"); /** * Returns if the given savegame has any supported interface * @param {any} savegame * @returns {BaseSavegameInterface|null} */ function getSavegameInterface(savegame) { if (!savegame || !savegame.version) { logger.warn("Savegame does not contain a valid version (undefined)"); return null; } const version = savegame.version; if (!Number.isInteger(version)) { logger.warn("Savegame does not contain a valid version (non-integer):", version); return null; } const interfaceClass = savegameInterfaces[version]; if (!interfaceClass) { logger.warn("Version", version, "has no implemented interface!"); return null; } return new interfaceClass(savegame); } /***/ }), /***/ "./src/js/savegame/savegame_manager.js": /*!*********************************************!*\ !*** ./src/js/savegame/savegame_manager.js ***! \*********************************************/ /*! exports provided: enumLocalSavegameStatus, SavegameManager */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enumLocalSavegameStatus", function() { return enumLocalSavegameStatus; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameManager", function() { return SavegameManager; }); /* harmony import */ var _core_explained_result__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/explained_result */ "./src/js/core/explained_result.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/read_write_proxy */ "./src/js/core/read_write_proxy.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _savegame__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./savegame */ "./src/js/savegame/savegame.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("savegame_manager"); const Rusha = __webpack_require__(/*! rusha */ "./node_modules/rusha/dist/rusha.js"); /** * @typedef {import("./savegame_typedefs").SavegamesData} SavegamesData * @typedef {import("./savegame_typedefs").SavegameMetadata} SavegameMetadata */ /** @enum {string} */ const enumLocalSavegameStatus = { offline: "offline", synced: "synced", }; class SavegameManager extends _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_2__["ReadWriteProxy"] { constructor(app) { super(app, "savegames.bin"); this.currentData = this.getDefaultData(); } // RW Proxy Impl /** * @returns {SavegamesData} */ getDefaultData() { return { version: this.getCurrentVersion(), savegames: [], }; } getCurrentVersion() { return 1001; } /** * @returns {SavegamesData} */ getCurrentData() { return super.getCurrentData(); } verify(data) { // TODO / FIXME!!!! return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].good(); } /** * * @param {SavegamesData} data */ migrate(data) { if (data.version < 1001) { data.savegames.forEach(savegame => { savegame.level = 0; }); data.version = 1001; } return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].good(); } // End rw proxy /** * @returns {Array} */ getSavegamesMetaData() { return this.currentData.savegames; } /** * * @param {string} internalId * @returns {Savegame} */ getSavegameById(internalId) { const metadata = this.getGameMetaDataByInternalId(internalId); if (!metadata) { return null; } return new _savegame__WEBPACK_IMPORTED_MODULE_4__["Savegame"](this.app, { internalId, metaDataRef: metadata }); } /** * Deletes a savegame * @param {SavegameMetadata} game */ deleteSavegame(game) { const handle = new _savegame__WEBPACK_IMPORTED_MODULE_4__["Savegame"](this.app, { internalId: game.internalId, metaDataRef: game, }); return handle.deleteAsync().then(() => { for (let i = 0; i < this.currentData.savegames.length; ++i) { const potentialGame = this.currentData.savegames[i]; if (potentialGame.internalId === handle.internalId) { this.currentData.savegames.splice(i, 1); break; } } return this.writeAsync(); }); } /** * Returns a given games metadata by id * @param {string} id * @returns {SavegameMetadata} */ getGameMetaDataByInternalId(id) { for (let i = 0; i < this.currentData.savegames.length; ++i) { const data = this.currentData.savegames[i]; if (data.internalId === id) { return data; } } logger.error("Savegame internal id not found:", id); return null; } /** * Creates a new savegame * @returns {Savegame} */ createNewSavegame() { const id = this.generateInternalId(); const metaData = /** @type {SavegameMetadata} */ ({ lastUpdate: Date.now(), version: _savegame__WEBPACK_IMPORTED_MODULE_4__["Savegame"].getCurrentVersion(), internalId: id, }); this.currentData.savegames.push(metaData); this.sortSavegames(); return new _savegame__WEBPACK_IMPORTED_MODULE_4__["Savegame"](this.app, { internalId: id, metaDataRef: metaData, }); } importSavegame(data) { const savegame = this.createNewSavegame(); const migrationResult = savegame.migrate(data); if (migrationResult.isBad()) { return Promise.reject("Failed to migrate: " + migrationResult.reason); } savegame.currentData = data; const verification = savegame.verify(data); if (verification.isBad()) { return Promise.reject("Verification failed: " + verification.result); } return savegame.writeSavegameAndMetadata().then(() => this.sortSavegames()); } /** * Sorts all savegames by their creation time descending * @returns {Promise} */ sortSavegames() { this.currentData.savegames.sort((a, b) => b.lastUpdate - a.lastUpdate); let promiseChain = Promise.resolve(); while (this.currentData.savegames.length > 30) { const toRemove = this.currentData.savegames.pop(); // Try to remove the savegame since its no longer available const game = new _savegame__WEBPACK_IMPORTED_MODULE_4__["Savegame"](this.app, { internalId: toRemove.internalId, metaDataRef: toRemove, }); promiseChain = promiseChain .then(() => game.deleteAsync()) .then( () => {}, err => { logger.error(this, "Failed to remove old savegame:", toRemove, ":", err); } ); } return promiseChain; } /** * Helper method to generate a new internal savegame id */ generateInternalId() { return Rusha.createHash() .update(Date.now() + "/" + Math.random()) .digest("hex"); } // End initialize() { // First read, then directly write to ensure we have the latest data // @ts-ignore return this.readAsync().then(() => { if (_core_config__WEBPACK_IMPORTED_MODULE_3__["globalConfig"].debug.disableSavegameWrite) { return Promise.resolve(); } return this.sortSavegames().then(() => this.writeAsync()); }); } } /***/ }), /***/ "./src/js/savegame/savegame_serializer.js": /*!************************************************!*\ !*** ./src/js/savegame/savegame_serializer.js ***! \************************************************/ /*! exports provided: SavegameSerializer */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameSerializer", function() { return SavegameSerializer; }); /* harmony import */ var _core_explained_result__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/explained_result */ "./src/js/core/explained_result.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _serializer_internal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./serializer_internal */ "./src/js/savegame/serializer_internal.js"); /** * @typedef {import("../game/component").Component} Component * @typedef {import("../game/component").StaticComponent} StaticComponent * @typedef {import("../game/entity").Entity} Entity * @typedef {import("../game/root").GameRoot} GameRoot * @typedef {import("../savegame/savegame_typedefs").SerializedGame} SerializedGame */ const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("savegame_serializer"); /** * Serializes a savegame */ class SavegameSerializer { constructor() { this.internal = new _serializer_internal__WEBPACK_IMPORTED_MODULE_3__["SerializerInternal"](); } /** * Serializes the game root into a dump * @param {GameRoot} root * @param {boolean=} sanityChecks Whether to check for validity * @returns {object} */ generateDumpFromGameRoot(root, sanityChecks = true) { /** @type {SerializedGame} */ const data = { camera: root.camera.serialize(), time: root.time.serialize(), map: root.map.serialize(), entityMgr: root.entityMgr.serialize(), hubGoals: root.hubGoals.serialize(), pinnedShapes: root.hud.parts.pinnedShapes.serialize(), waypoints: root.hud.parts.waypoints.serialize(), entities: this.internal.serializeEntityArray(root.entityMgr.entities), beltPaths: root.systemMgr.systems.belt.serializePaths(), }; if (true) { if (sanityChecks) { // Sanity check const sanity = this.verifyLogicalErrors(data); if (!sanity.result) { logger.error("Created invalid savegame:", sanity.reason, "savegame:", data); return null; } } } return data; } /** * Verifies if there are logical errors in the savegame * @param {SerializedGame} savegame * @returns {ExplainedResult} */ verifyLogicalErrors(savegame) { if (!savegame.entities) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad("Savegame has no entities"); } const seenUids = []; // Check for duplicate UIDS for (let i = 0; i < savegame.entities.length; ++i) { /** @type {Entity} */ const entity = savegame.entities[i]; const uid = entity.uid; if (!Number.isInteger(uid)) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad("Entity has invalid uid: " + uid); } if (seenUids.indexOf(uid) >= 0) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad("Duplicate uid " + uid); } seenUids.push(uid); // Verify components if (!entity.components) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad("Entity is missing key 'components': " + JSON.stringify(entity)); } const components = entity.components; for (const componentId in components) { const componentClass = _core_global_registries__WEBPACK_IMPORTED_MODULE_2__["gComponentRegistry"].findById(componentId); // Check component id is known if (!componentClass) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad("Unknown component id: " + componentId); } // Verify component data const componentData = components[componentId]; const componentVerifyError = /** @type {StaticComponent} */ (componentClass).verify( componentData ); // Check component data is ok if (componentVerifyError) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad( "Component " + componentId + " has invalid data: " + componentVerifyError ); } } } return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].good(); } /** * Tries to load the savegame from a given dump * @param {SerializedGame} savegame * @param {GameRoot} root * @returns {ExplainedResult} */ deserialize(savegame, root) { // Sanity const verifyResult = this.verifyLogicalErrors(savegame); if (!verifyResult.result) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad(verifyResult.reason); } let errorReason = null; errorReason = errorReason || root.entityMgr.deserialize(savegame.entityMgr); errorReason = errorReason || root.time.deserialize(savegame.time); errorReason = errorReason || root.camera.deserialize(savegame.camera); errorReason = errorReason || root.map.deserialize(savegame.map); errorReason = errorReason || root.hubGoals.deserialize(savegame.hubGoals); errorReason = errorReason || root.hud.parts.pinnedShapes.deserialize(savegame.pinnedShapes); errorReason = errorReason || root.hud.parts.waypoints.deserialize(savegame.waypoints); errorReason = errorReason || this.internal.deserializeEntityArray(root, savegame.entities); errorReason = errorReason || root.systemMgr.systems.belt.deserializePaths(savegame.beltPaths); // Check for errors if (errorReason) { return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].bad(errorReason); } return _core_explained_result__WEBPACK_IMPORTED_MODULE_0__["ExplainedResult"].good(); } } /***/ }), /***/ "./src/js/savegame/schemas/1000.js": /*!*****************************************!*\ !*** ./src/js/savegame/schemas/1000.js ***! \*****************************************/ /*! exports provided: SavegameInterface_V1000 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameInterface_V1000", function() { return SavegameInterface_V1000; }); /* harmony import */ var _savegame_interface_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../savegame_interface.js */ "./src/js/savegame/savegame_interface.js"); const schema = __webpack_require__(/*! ./1000.json */ "./src/js/savegame/schemas/1000.json"); class SavegameInterface_V1000 extends _savegame_interface_js__WEBPACK_IMPORTED_MODULE_0__["BaseSavegameInterface"] { getVersion() { return 1000; } getSchemaUncached() { return schema; } } /***/ }), /***/ "./src/js/savegame/schemas/1000.json": /*!*******************************************!*\ !*** ./src/js/savegame/schemas/1000.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQC4E8AOBTGAuWB7ARgKxQGM4YAacaWAJxQEcBXASxoBMMIBtAXXMmhgCGLFoziMsAOwEAbAApUsqKmJQBndnCr0U4AL7ggA")); })() /***/ }), /***/ "./src/js/savegame/schemas/1001.js": /*!*****************************************!*\ !*** ./src/js/savegame/schemas/1001.js ***! \*****************************************/ /*! exports provided: SavegameInterface_V1001 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameInterface_V1001", function() { return SavegameInterface_V1001; }); /* harmony import */ var _1000_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./1000.js */ "./src/js/savegame/schemas/1000.js"); /* harmony import */ var _core_logging_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../core/logging.js */ "./src/js/core/logging.js"); /* harmony import */ var _translations_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../translations.js */ "./src/js/translations.js"); /* harmony import */ var _serialization_data_types_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../serialization_data_types.js */ "./src/js/savegame/serialization_data_types.js"); const schema = __webpack_require__(/*! ./1001.json */ "./src/js/savegame/schemas/1001.json"); const logger = Object(_core_logging_js__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("savegame_interface/1001"); class SavegameInterface_V1001 extends _1000_js__WEBPACK_IMPORTED_MODULE_0__["SavegameInterface_V1000"] { getVersion() { return 1001; } getSchemaUncached() { return schema; } /** * @param {import("../savegame_typedefs.js").SavegameData} data */ static migrate1000to1001(data) { logger.log("Migrating 1000 to 1001"); const dump = data.dump; if (!dump) { return true; } dump.pinnedShapes = { shapes: [], }; dump.waypoints = { waypoints: [ { label: _translations_js__WEBPACK_IMPORTED_MODULE_2__["T"].ingame.waypoints.hub, center: { x: 0, y: 0 }, zoomLevel: 3, deletable: false, }, ], }; const entities = dump.entities; for (let i = 0; i < entities.length; ++i) { const entity = entities[i]; /** * @typedef {{ * origin: TypeVector, * tileSize: TypeVector, * rotation: TypeNumber, * originalRotation: TypeNumber, * spriteKey?: string, * blueprintSpriteKey: string, * silhouetteColor: string * }} OldStaticMapEntity */ // Here we mock the old type of the StaticMapEntity before the change to using // a building ID based system (see building_codes.js) to stop the linter from // complaining that the type doesn't have the properties. // The ignored error is the error that the types do not overlap. In the case // of a v1000 save though, the data will match the mocked type above. /** @type OldStaticMapEntity **/ // @ts-ignore const staticComp = entity.components.StaticMapEntity; const beltComp = entity.components.Belt; if (staticComp) { if (staticComp.spriteKey) { staticComp.blueprintSpriteKey = staticComp.spriteKey.replace( "sprites/buildings", "sprites/blueprints" ); } else { if (entity.components.Hub) { staticComp.blueprintSpriteKey = ""; } else if (beltComp) { const direction = beltComp.direction; staticComp.blueprintSpriteKey = "sprites/blueprints/belt_" + direction + ".png"; } else { window.assert(false, "Could not deduct entity type for migrating 1000 -> 1001"); } } } } } } /***/ }), /***/ "./src/js/savegame/schemas/1001.json": /*!*******************************************!*\ !*** ./src/js/savegame/schemas/1001.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQC4E8AOBTGAuWB7ARgKxQGM4YAacaWAJxQEcBXASxoBMMIBtAXXMmhgCGLFoziMsAOwEAbAApUsqKmJQBndnCr0U4AL7ggA")); })() /***/ }), /***/ "./src/js/savegame/schemas/1002.js": /*!*****************************************!*\ !*** ./src/js/savegame/schemas/1002.js ***! \*****************************************/ /*! exports provided: SavegameInterface_V1002 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameInterface_V1002", function() { return SavegameInterface_V1002; }); /* harmony import */ var _core_logging_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/logging.js */ "./src/js/core/logging.js"); /* harmony import */ var _translations_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../translations.js */ "./src/js/translations.js"); /* harmony import */ var _1001_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./1001.js */ "./src/js/savegame/schemas/1001.js"); const schema = __webpack_require__(/*! ./1002.json */ "./src/js/savegame/schemas/1002.json"); const logger = Object(_core_logging_js__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("savegame_interface/1002"); class SavegameInterface_V1002 extends _1001_js__WEBPACK_IMPORTED_MODULE_2__["SavegameInterface_V1001"] { getVersion() { return 1002; } getSchemaUncached() { return schema; } /** * @param {import("../savegame_typedefs.js").SavegameData} data */ static migrate1001to1002(data) { logger.log("Migrating 1001 to 1002"); const dump = data.dump; if (!dump) { return true; } const entities = dump.entities; for (let i = 0; i < entities.length; ++i) { const entity = entities[i]; const beltComp = entity.components.Belt; const ejectorComp = entity.components.ItemEjector; if (beltComp && ejectorComp) { // @ts-ignore ejectorComp.instantEject = true; } } } } /***/ }), /***/ "./src/js/savegame/schemas/1002.json": /*!*******************************************!*\ !*** ./src/js/savegame/schemas/1002.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQC4E8AOBTGAuWB7ARgKxQGM4YAacaWAJxQEcBXASxoBMMIBtAXXMmhgCGLFoziMsAOwEAbAApUsqKmJQBndnCr0U4AL7ggA")); })() /***/ }), /***/ "./src/js/savegame/schemas/1003.js": /*!*****************************************!*\ !*** ./src/js/savegame/schemas/1003.js ***! \*****************************************/ /*! exports provided: SavegameInterface_V1003 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameInterface_V1003", function() { return SavegameInterface_V1003; }); /* harmony import */ var _core_logging_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/logging.js */ "./src/js/core/logging.js"); /* harmony import */ var _1002_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./1002.js */ "./src/js/savegame/schemas/1002.js"); const schema = __webpack_require__(/*! ./1003.json */ "./src/js/savegame/schemas/1003.json"); const logger = Object(_core_logging_js__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("savegame_interface/1003"); class SavegameInterface_V1003 extends _1002_js__WEBPACK_IMPORTED_MODULE_1__["SavegameInterface_V1002"] { getVersion() { return 1003; } getSchemaUncached() { return schema; } /** * @param {import("../savegame_typedefs.js").SavegameData} data */ static migrate1002to1003(data) { logger.log("Migrating 1002 to 1003"); const dump = data.dump; if (!dump) { return true; } dump.pinnedShapes = { shapes: [] }; } } /***/ }), /***/ "./src/js/savegame/schemas/1003.json": /*!*******************************************!*\ !*** ./src/js/savegame/schemas/1003.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQC4E8AOBTGAuWB7ARgKxQGM4YAacaWAJxQEcBXASxoBMMIBtAXXMmhgCGLFoziMsAOwEAbAApUsqKmJQBndnCr0U4AL7ggA")); })() /***/ }), /***/ "./src/js/savegame/schemas/1004.js": /*!*****************************************!*\ !*** ./src/js/savegame/schemas/1004.js ***! \*****************************************/ /*! exports provided: SavegameInterface_V1004 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameInterface_V1004", function() { return SavegameInterface_V1004; }); /* harmony import */ var _core_logging_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/logging.js */ "./src/js/core/logging.js"); /* harmony import */ var _1003_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./1003.js */ "./src/js/savegame/schemas/1003.js"); const schema = __webpack_require__(/*! ./1004.json */ "./src/js/savegame/schemas/1004.json"); const logger = Object(_core_logging_js__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("savegame_interface/1004"); class SavegameInterface_V1004 extends _1003_js__WEBPACK_IMPORTED_MODULE_1__["SavegameInterface_V1003"] { getVersion() { return 1004; } getSchemaUncached() { return schema; } /** * @param {import("../savegame_typedefs.js").SavegameData} data */ static migrate1003to1004(data) { logger.log("Migrating 1003 to 1004"); const dump = data.dump; if (!dump) { return true; } // The hub simply has an empty label const waypointData = dump.waypoints.waypoints; for (let i = 0; i < waypointData.length; ++i) { const waypoint = waypointData[i]; if (!waypoint.deletable) { waypoint.label = null; } delete waypoint.deletable; } } } /***/ }), /***/ "./src/js/savegame/schemas/1004.json": /*!*******************************************!*\ !*** ./src/js/savegame/schemas/1004.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQC4E8AOBTGAuWB7ARgKxQGM4YAacaWAJxQEcBXASxoBMMIBtAXXMmhgCGLFoziMsAOwEAbAApUsqKmJQBndnCr0U4AL7ggA")); })() /***/ }), /***/ "./src/js/savegame/schemas/1005.js": /*!*****************************************!*\ !*** ./src/js/savegame/schemas/1005.js ***! \*****************************************/ /*! exports provided: SavegameInterface_V1005 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SavegameInterface_V1005", function() { return SavegameInterface_V1005; }); /* harmony import */ var _core_logging_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../core/logging.js */ "./src/js/core/logging.js"); /* harmony import */ var _1004_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./1004.js */ "./src/js/savegame/schemas/1004.js"); /* harmony import */ var _core_global_registries__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../core/global_registries */ "./src/js/core/global_registries.js"); /* harmony import */ var _game_building_codes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../game/building_codes */ "./src/js/game/building_codes.js"); const schema = __webpack_require__(/*! ./1005.json */ "./src/js/savegame/schemas/1005.json"); const logger = Object(_core_logging_js__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("savegame_interface/1005"); class SavegameInterface_V1005 extends _1004_js__WEBPACK_IMPORTED_MODULE_1__["SavegameInterface_V1004"] { getVersion() { return 1005; } getSchemaUncached() { return schema; } /** * @param {import("../savegame_typedefs.js").SavegameData} data */ static migrate1004to1005(data) { logger.log("Migrating 1004 to 1005"); const dump = data.dump; if (!dump) { return true; } // just reset belt paths for now dump.beltPaths = []; const entities = dump.entities; // clear ejector slots for (let i = 0; i < entities.length; ++i) { const entity = entities[i]; const itemEjector = entity.components.ItemEjector; if (itemEjector) { const slots = itemEjector.slots; for (let k = 0; k < slots.length; ++k) { const slot = slots[k]; slot.item = null; slot.progress = 0; } } } } static migrate1005(data) { let es = data.dump.entities; data.dump.beltPaths = []; let shapes = []; let dig = function dig(o) { if (typeof o == "object" && o) { if (o.$) { shapes.push(o); } for (let k in o) { dig(o[k]); } } }; dig(data.dump.entities); shapes; for (let o of shapes) { if (o.$ == "shape") { o.data = o.data.replace(/p/g, "m"); } if (o.$ == "color") { if (o.data == "purple") { o.data = "magenta"; } } } } static migrate1005BeforeGameEnter(data) { if (!data.dump.entities.find(e => e.components.Unremovable)) { return; } // data.dump.entities.filter(e=>e.components.Unremovable) // .map(e => delete e.components.Unremovable) // data.dump.entities.filter(e=>e.components.ReplaceableMapEntity) // .map(e => delete e.components.ReplaceableMapEntity) globalThis.dump = data.dump; data.dump._entities = data.dump.entities; data.dump.entities = []; data.dump.beltPaths = []; // data.dump.entities.filter(e=>e.components.EnergyConsumer) // .map(e => delete e.components.EnergyConsumer) // data.dump.entities.filter(e=>e.components.EnergyGenerator) // .map(e => delete e.components.EnergyGenerator) // debugger; } static migrate1005AfterGameEnter(data, root) { if (!data.dump._entities) return; // Energy generator // registerBuildingVariant(27, MetaEnergyGenerator); // // Wire // registerBuildingVariant(28, MetaWireBaseBuilding, defaultBuildingVariant, 0); // registerBuildingVariant(29, MetaWireBaseBuilding, defaultBuildingVariant, 1); // registerBuildingVariant(30, MetaWireBaseBuilding, defaultBuildingVariant, 2); // // Advanced processor // registerBuildingVariant(31, MetaAdvancedProcessorBuilding); // // Wire crossing // registerBuildingVariant(32, MetaWireCrossingsBuilding); // registerBuildingVariant(33, MetaWireCrossingsBuilding, enumWireCrossingVariants.merger); let removedCodes = [27, 28, 29, 30, 32, 33]; let movedCodes = { 31: 310 }; let serialized = ["Storage", "checker", "repeater"]; let es = []; for (let e of data.dump._entities) { let code = e.components.StaticMapEntity.code; if (!code) { console.warn("no code", e); } if (removedCodes.includes(code)) { continue; } if (movedCodes[code]) { code = movedCodes[code]; } let vrt = _game_building_codes__WEBPACK_IMPORTED_MODULE_3__["gBuildingVariants"][code]; if (!vrt) { throw "not found"; } const entity = root.logic.tryPlaceBuilding({ origin: e.components.StaticMapEntity.origin, rotation: e.components.StaticMapEntity.rotation, rotationVariant: vrt.rotationVariant, originalRotation: e.components.StaticMapEntity.originalRotation, building: vrt.metaInstance, variant: vrt.variant, }); es.push({ e, entity }); for (let c of serialized) { if (e.components[c]) { entity.components[c].deserialize(e.components[c]); } } } globalThis.es = es; } } /***/ }), /***/ "./src/js/savegame/schemas/1005.json": /*!*******************************************!*\ !*** ./src/js/savegame/schemas/1005.json ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = (function() { return JSON.parse(__webpack_require__(/*! global-compression */ "./src/js/core/lzstring.js").decompressX64("N4WAUABFEEQC4E8AOBTGAuWB7ARgKxQGM4YAacaWAJxQEcBXASxoBMMIBtAXXMmhgCGLFoziMsAOwEAbAApUsqKmJQBndnCr0U4AL7ggA")); })() /***/ }), /***/ "./src/js/savegame/serialization.js": /*!******************************************!*\ !*** ./src/js/savegame/serialization.js ***! \******************************************/ /*! exports provided: types, BasicSerializableObject, serializeSchema, deserializeSchema, verifySchema, extendSchema */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "types", function() { return types; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BasicSerializableObject", function() { return BasicSerializableObject; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeSchema", function() { return serializeSchema; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deserializeSchema", function() { return deserializeSchema; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "verifySchema", function() { return verifySchema; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "extendSchema", function() { return extendSchema; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./serialization_data_types */ "./src/js/savegame/serialization_data_types.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("serialization"); // Schema declarations const types = { int: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeInteger"](), uint: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypePositiveInteger"](), float: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeNumber"](), ufloat: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypePositiveNumber"](), string: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeString"](), entity: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeEntity"](), weakEntityRef: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeEntityWeakref"](), vector: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeVector"](), tileVector: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeVector"](), bool: new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeBoolean"](), /** * @param {BaseDataType} wrapped */ nullable(wrapped) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeNullable"](wrapped); }, /** * @param {FactoryTemplate<*>|SingletonFactoryTemplate<*>} registry */ classId(registry) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeClassId"](registry); }, /** * @param {BaseDataType} valueType * @param {boolean=} includeEmptyValues */ keyValueMap(valueType, includeEmptyValues = true) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeKeyValueMap"](valueType, includeEmptyValues); }, /** * @param {Object} values */ enum(values) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeEnum"](values); }, /** * @param {FactoryTemplate<*>} registry * @param {(GameRoot, any) => object=} resolver */ obj(registry, resolver = null) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeClass"](registry, resolver); }, /** * @param {FactoryTemplate<*>} registry */ objData(registry) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeClassData"](registry); }, /** * @param {typeof BasicSerializableObject} cls */ knownType(cls) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeFixedClass"](cls); }, /** * @param {BaseDataType} innerType */ array(innerType) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeArray"](innerType); }, /** * @param {SingletonFactoryTemplate<*>} innerType */ classRef(registry) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeMetaClass"](registry); }, /** * @param {Object.} descriptor */ structured(descriptor) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeStructuredObject"](descriptor); }, /** * @param {BaseDataType} a * @param {BaseDataType} b */ pair(a, b) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypePair"](a, b); }, /** * @param {typeof BasicSerializableObject} classHandle * @param {SingletonFactoryTemplate<*>} registry */ classWithMetaclass(classHandle, registry) { return new _serialization_data_types__WEBPACK_IMPORTED_MODULE_1__["TypeClassFromMetaclass"](classHandle, registry); }, }; /** * A full schema declaration * @typedef {Object.} Schema */ const globalSchemaCache = {}; /* dev:start */ const classnamesCache = {}; /* dev:end*/ class BasicSerializableObject { /* dev:start */ /** * Fixes typeof DerivedComponent is not assignable to typeof Component, compiled out * in non-dev builds */ constructor(...args) {} /* dev:end */ static getId() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Should return the serialization schema * @returns {Schema} */ static getSchema() { return {}; } // Implementation /** @returns {Schema} */ static getCachedSchema() { const id = this.getId(); /* dev:start */ window.assert( classnamesCache[id] === this || classnamesCache[id] === undefined, "Class name taken twice: " + id + " (from " + this.name + ")" ); classnamesCache[id] = this; /* dev:end */ const entry = globalSchemaCache[id]; if (entry) { return entry; } const schema = this.getSchema(); globalSchemaCache[id] = schema; return schema; } /** @returns {object} */ serialize() { return serializeSchema( this, /** @type {typeof BasicSerializableObject} */ (this.constructor).getCachedSchema() ); } /** * @param {any} data * @param {import("./savegame_serializer").GameRoot} root * @returns {string|void} */ deserialize(data, root = null) { return deserializeSchema( this, /** @type {typeof BasicSerializableObject} */ (this.constructor).getCachedSchema(), data, null, root ); } /** @returns {string|void} */ static verify(data) { return verifySchema(this.getCachedSchema(), data); } } /** * Serializes an object using the given schema, mergin with the given properties * @param {object} obj The object to serialize * @param {Schema} schema The schema to use * @param {object=} mergeWith Any additional properties to merge with the schema, useful for super calls * @returns {object} Serialized data object */ function serializeSchema(obj, schema, mergeWith = {}) { for (const key in schema) { if (!obj.hasOwnProperty(key)) { logger.error("Invalid schema, property", key, "does not exist on", obj, "(schema=", schema, ")"); window.assert( obj.hasOwnProperty(key), "serialization: invalid schema, property does not exist on object: " + key ); } if (!schema[key]) { window.assert(false, "Invalid schema (bad key '" + key + "'): " + JSON.stringify(schema)); } if (true) { try { mergeWith[key] = schema[key].serialize(obj[key]); } catch (ex) { logger.error( "Serialization of", obj, "failed on key '" + key + "' ->", ex, "(schema was", schema, ")" ); throw ex; } } else {} } return mergeWith; } /** * Deserializes data into an object * @param {object} obj The object to store the deserialized data into * @param {Schema} schema The schema to use * @param {object} data The serialized data * @param {string|void|null=} baseclassErrorResult Convenience, if this is a string error code, do nothing and return it * @param {import("../game/root").GameRoot=} root Optional game root reference * @returns {string|void} String error code or nothing on success */ function deserializeSchema(obj, schema, data, baseclassErrorResult = null, root) { if (baseclassErrorResult) { return baseclassErrorResult; } if (!data) { logger.error("Got 'NULL' data for", obj, "and schema", schema, "!"); return "Got null data"; } for (const key in schema) { if (!data.hasOwnProperty(key)) { logger.error("Data", data, "does not contain", key, "(schema:", schema, ")"); return "Missing key in schema: " + key + " of class " + obj.constructor.name; } if (!schema[key].allowNull() && (data[key] === null || data[key] === undefined)) { logger.error("Data", data, "has null value for", key, "(schema:", schema, ")"); return "Non-nullable entry is null: " + key + " of class " + obj.constructor.name; } const errorStatus = schema[key].deserializeWithVerify(data[key], obj, key, obj.root || root); if (errorStatus) { logger.error( "Deserialization failed with error '" + errorStatus + "' on object", obj, "and key", key, "(root? =", obj.root ? "y" : "n", ")" ); return errorStatus; } } } /** * Verifies stored data using the given schema * @param {Schema} schema The schema to use * @param {object} data The data to verify * @returns {string|void} String error code or nothing on success */ function verifySchema(schema, data) { for (const key in schema) { if (!data.hasOwnProperty(key)) { logger.error("Data", data, "does not contain", key, "(schema:", schema, ")"); return "verify: missing key required by schema in stored data: " + key; } if (!schema[key].allowNull() && (data[key] === null || data[key] === undefined)) { logger.error("Data", data, "has null value for", key, "(schema:", schema, ")"); return "verify: non-nullable entry is null: " + key; } const errorStatus = schema[key].verifySerializedValue(data[key]); if (errorStatus) { logger.error(errorStatus); return "verify: " + errorStatus; } } } /** * Extends a schema by adding the properties from the new schema to the existing base schema * @param {Schema} base * @param {Schema} newOne * @returns {Schema} */ function extendSchema(base, newOne) { /** @type {Schema} */ const result = Object.assign({}, base); for (const key in newOne) { if (result.hasOwnProperty(key)) { logger.error("Extend schema got duplicate key:", key); continue; } result[key] = newOne[key]; } return result; } /***/ }), /***/ "./src/js/savegame/serialization_data_types.js": /*!*****************************************************!*\ !*** ./src/js/savegame/serialization_data_types.js ***! \*****************************************************/ /*! exports provided: globalJsonSchemaDefs, schemaToJsonSchema, BaseDataType, TypeInteger, TypePositiveInteger, TypeBoolean, TypeString, TypeVector, TypeTileVector, TypeNumber, TypePositiveNumber, TypeEnum, TypeEntity, TypeEntityWeakref, TypeClass, TypeClassData, TypeClassFromMetaclass, TypeMetaClass, TypeArray, TypeFixedClass, TypeKeyValueMap, TypeClassId, TypePair, TypeNullable, TypeStructuredObject */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "globalJsonSchemaDefs", function() { return globalJsonSchemaDefs; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "schemaToJsonSchema", function() { return schemaToJsonSchema; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseDataType", function() { return BaseDataType; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeInteger", function() { return TypeInteger; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypePositiveInteger", function() { return TypePositiveInteger; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeBoolean", function() { return TypeBoolean; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeString", function() { return TypeString; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeVector", function() { return TypeVector; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeTileVector", function() { return TypeTileVector; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeNumber", function() { return TypeNumber; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypePositiveNumber", function() { return TypePositiveNumber; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeEnum", function() { return TypeEnum; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeEntity", function() { return TypeEntity; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeEntityWeakref", function() { return TypeEntityWeakref; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeClass", function() { return TypeClass; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeClassData", function() { return TypeClassData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeClassFromMetaclass", function() { return TypeClassFromMetaclass; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeMetaClass", function() { return TypeMetaClass; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeArray", function() { return TypeArray; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeFixedClass", function() { return TypeFixedClass; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeKeyValueMap", function() { return TypeKeyValueMap; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeClassId", function() { return TypeClassId; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypePair", function() { return TypePair; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeNullable", function() { return TypeNullable; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypeStructuredObject", function() { return TypeStructuredObject; }); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); const globalJsonSchemaDefs = {}; /** * * @param {import("./serialization").Schema} schema */ function schemaToJsonSchema(schema) { const jsonSchema = { type: "object", additionalProperties: false, required: [], properties: {}, }; for (const key in schema) { const subSchema = schema[key].getAsJsonSchema(); jsonSchema.required.push(key); jsonSchema.properties[key] = subSchema; } return jsonSchema; } /** * Helper function to create a json schema object * @param {any} properties */ function schemaObject(properties) { return { type: "object", required: Object.keys(properties).slice(), additionalProperties: false, properties, }; } /** * Base serialization data type */ class BaseDataType { /** * Serializes a given raw value * @param {any} value */ serialize(value) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return {}; } /** * Verifies a given serialized value * @param {any} value * @returns {string|void} String error code or null on success */ verifySerializedValue(value) {} /** * Deserializes a serialized value into the target object under the given key * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Returns the json schema */ getAsJsonSchema() { const key = this.getCacheKey(); const schema = this.getAsJsonSchemaUncached(); if (!globalJsonSchemaDefs[key]) { // schema.$id = key; globalJsonSchemaDefs[key] = schema; } return { $ref: "#/definitions/" + key, }; } /** * INTERNAL Should return the json schema representation */ getAsJsonSchemaUncached() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; } /** * Returns whether null values are okay * @returns {boolean} */ allowNull() { return false; } // Helper methods /** * Deserializes a serialized value, but performs integrity checks before * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserializeWithVerify(value, targetObject, targetKey, root) { const errorCode = this.verifySerializedValue(value); if (errorCode) { return ( "serialization verify failed: " + errorCode + " [value " + JSON.stringify(value).substr(0, 100) + "]" ); } return this.deserialize(value, targetObject, targetKey, root); } /** * Should return a cacheable key */ getCacheKey() { window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));; return ""; } } class TypeInteger extends BaseDataType { serialize(value) { window.assert(Number.isInteger(value), "Type integer got non integer for serialize: " + value); return value; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "integer", }; } verifySerializedValue(value) { if (!Number.isInteger(value)) { return "Not a valid number"; } } getCacheKey() { return "int"; } } class TypePositiveInteger extends BaseDataType { serialize(value) { window.assert(Number.isInteger(value), "Type integer got non integer for serialize: " + value); window.assert(value >= 0, "value < 0: " + value); return value; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "integer", minimum: 0, }; } verifySerializedValue(value) { if (!Number.isInteger(value)) { return "Not a valid number"; } if (value < 0) { return "Negative value for positive integer"; } } getCacheKey() { return "uint"; } } class TypeBoolean extends BaseDataType { serialize(value) { window.assert(value === true || value === false, "Type bool got non bool for serialize: " + value); return value; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "boolean", }; } verifySerializedValue(value) { if (value !== true && value !== false) { return "Not a boolean"; } } getCacheKey() { return "bool"; } } class TypeString extends BaseDataType { serialize(value) { window.assert(typeof value === "string", "Type string got non string for serialize: " + value); return value; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "string", }; } verifySerializedValue(value) { if (typeof value !== "string") { return "Not a valid string"; } } getCacheKey() { return "string"; } } class TypeVector extends BaseDataType { serialize(value) { window.assert(value instanceof _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"], "Type vector got non vector for serialize: " + value); return { x: Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["round4Digits"])(value.x), y: Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["round4Digits"])(value.y), }; } getAsJsonSchemaUncached() { return schemaObject({ x: { type: "number", }, y: { type: "number", }, }); } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](value.x, value.y); } verifySerializedValue(value) { if (!Number.isFinite(value.x) || !Number.isFinite(value.y)) { return "Not a valid vector, missing x/y or bad data type"; } } getCacheKey() { return "vector"; } } class TypeTileVector extends BaseDataType { serialize(value) { window.assert(value instanceof _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"], "Type vector got non vector for serialize: " + value); window.assert(Number.isInteger(value.x) && value.x > 0, "Invalid tile x:" + value.x); window.assert(Number.isInteger(value.y) && value.y > 0, "Invalid tile x:" + value.y); return { x: value.x, y: value.y }; } getAsJsonSchemaUncached() { return schemaObject({ x: { type: "integer", minimum: 0, maximum: 256, }, y: { type: "integer", minimum: 0, maximum: 256, }, }); } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = new _core_vector__WEBPACK_IMPORTED_MODULE_0__["Vector"](value.x, value.y); } verifySerializedValue(value) { if (!Number.isInteger(value.x) || !Number.isInteger(value.y)) { return "Not a valid tile vector, missing x/y or bad data type"; } if (value.x < 0 || value.y < 0) { return "Invalid tile vector, x or y < 0"; } } getCacheKey() { return "tilevector"; } } class TypeNumber extends BaseDataType { serialize(value) { window.assert(Number.isFinite(value), "Type number got non number for serialize: " + value); window.assert(!Number.isNaN(value), "Value is nan: " + value); return Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["round4Digits"])(value); } getAsJsonSchemaUncached() { return { type: "number", }; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } verifySerializedValue(value) { if (!Number.isFinite(value)) { return "Not a valid number: " + value; } } getCacheKey() { return "float"; } } class TypePositiveNumber extends BaseDataType { serialize(value) { window.assert(Number.isFinite(value), "Type number got non number for serialize: " + value); window.assert(value >= 0, "Postitive number got negative value: " + value); return Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["round4Digits"])(value); } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "number", minimum: 0, }; } verifySerializedValue(value) { if (!Number.isFinite(value)) { return "Not a valid number: " + value; } if (value < 0) { return "Positive number got negative value: " + value; } } getCacheKey() { return "ufloat"; } } class TypeEnum extends BaseDataType { /** * @param {Object.} enumeration */ constructor(enumeration = {}) { super(); this.availableValues = Object.values(enumeration); } serialize(value) { window.assert(this.availableValues.indexOf(value) >= 0, "Unknown value: " + value); return value; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "string", enum: this.availableValues, }; } verifySerializedValue(value) { if (this.availableValues.indexOf(value) < 0) { return "Unknown enum value: " + value; } } getCacheKey() { return "enum." + this.availableValues.join(","); } } class TypeEntity extends BaseDataType { serialize(value) { // assert(value instanceof Entity, "Not a valid entity ref: " + value); window.assert(value.uid, "Entity has no uid yet"); window.assert(!value.destroyed, "Entity already destroyed"); window.assert(!value.queuedForDestroy, "Entity queued for destroy"); return value.uid; } getAsJsonSchemaUncached() { return { type: "integer", minimum: 0, }; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { const entity = root.entityMgr.findByUid(value); if (!entity) { return "Entity not found by uid: " + value; } targetObject[targetKey] = entity; } verifySerializedValue(value) { if (!Number.isFinite(value)) { return "Not a valid uuid: " + value; } } getCacheKey() { return "entity"; } } class TypeEntityWeakref extends BaseDataType { serialize(value) { if (value === null) { return null; } // assert(value instanceof Entity, "Not a valid entity ref (weak): " + value); window.assert(value.uid, "Entity has no uid yet"); if (value.destroyed || value.queuedForDestroy) { return null; } return value.uid; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { if (value === null) { targetObject[targetKey] = null; return; } const entity = root.entityMgr.findByUid(value, false); targetObject[targetKey] = entity; } getAsJsonSchemaUncached() { return { type: ["null", "integer"], minimum: 0, }; } allowNull() { return true; } verifySerializedValue(value) { if (value !== null && !Number.isFinite(value)) { return "Not a valid uuid: " + value; } } getCacheKey() { return "entity-weakref"; } } class TypeClass extends BaseDataType { /** * * @param {FactoryTemplate<*>} registry * @param {(GameRoot, object) => object} customResolver */ constructor(registry, customResolver = null) { super(); this.registry = registry; this.customResolver = customResolver; } serialize(value) { window.assert(typeof value === "object", "Not a class instance: " + value); return { $: value.constructor.getId(), data: value.serialize(), }; } getAsJsonSchemaUncached() { const options = []; const entries = this.registry.getEntries(); for (let i = 0; i < entries.length; ++i) { const entry = entries[i]; options.push( schemaObject({ $: { type: "string", // @ts-ignore enum: [entry.getId()], }, // @ts-ignore data: schemaToJsonSchema(entry.getCachedSchema()), }) ); } return { oneOf: options }; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { let instance; if (this.customResolver) { instance = this.customResolver(root, value); if (!instance) { return "Failed to call custom resolver"; } } else { const instanceClass = this.registry.findById(value.$); if (!instanceClass || !instanceClass.prototype) { return "Invalid class id (runtime-err): " + value.$ + "->" + instanceClass; } instance = Object.create(instanceClass.prototype); const errorState = instance.deserialize(value.data); if (errorState) { return errorState; } } targetObject[targetKey] = instance; } verifySerializedValue(value) { if (!value) { return "Got null data"; } if (!this.registry.hasId(value.$)) { return "Invalid class id: " + value.$ + " (factory is " + this.registry.getId() + ")"; } } getCacheKey() { return "class." + this.registry.getId(); } } class TypeClassData extends BaseDataType { /** * * @param {FactoryTemplate<*>} registry */ constructor(registry) { super(); this.registry = registry; } serialize(value) { window.assert(typeof value === "object", "Not a class instance: " + value); return value.serialize(); } getAsJsonSchemaUncached() { const options = []; const entries = this.registry.getEntries(); for (let i = 0; i < entries.length; ++i) { const entry = entries[i]; options.push( schemaToJsonSchema(/** @type {typeof BasicSerializableObject} */ (entry).getCachedSchema()) ); } return { oneOf: options }; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { window.assert(false, "can not deserialize class data of type " + this.registry.getId()); } verifySerializedValue(value) { if (!value) { return "Got null data"; } } getCacheKey() { return "class." + this.registry.getId(); } } class TypeClassFromMetaclass extends BaseDataType { /** * * @param {typeof BasicSerializableObject} classHandle * @param {SingletonFactoryTemplate<*>} registry */ constructor(classHandle, registry) { super(); this.registry = registry; this.classHandle = classHandle; } serialize(value) { window.assert(typeof value === "object", "Not a class instance: " + value); return { $: value.getMetaclass().getId(), data: value.serialize(), }; } getAsJsonSchemaUncached() { // const options = []; const ids = this.registry.getAllIds(); return { $: { type: "string", enum: ids, }, data: schemaToJsonSchema(this.classHandle.getCachedSchema()), }; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { const metaClassInstance = this.registry.findById(value.$); if (!metaClassInstance || !metaClassInstance.prototype) { return "Invalid meta class id (runtime-err): " + value.$ + "->" + metaClassInstance; } const instanceClass = metaClassInstance.getInstanceClass(); const instance = Object.create(instanceClass.prototype); const errorState = instance.deserialize(value.data); if (errorState) { return errorState; } targetObject[targetKey] = instance; } verifySerializedValue(value) { if (!value) { return "Got null data"; } if (!this.registry.hasId(value.$)) { return "Invalid class id: " + value.$ + " (factory is " + this.registry.getId() + ")"; } } getCacheKey() { return "classofmetaclass." + this.registry.getId(); } } class TypeMetaClass extends BaseDataType { /** * * @param {SingletonFactoryTemplate<*>} registry */ constructor(registry) { super(); this.registry = registry; } serialize(value) { return value.getId(); } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { const instanceClass = this.registry.findById(value); if (!instanceClass) { return "Invalid class id (runtime-err): " + value; } targetObject[targetKey] = instanceClass; } getAsJsonSchemaUncached() { return { type: "string", enum: this.registry.getAllIds(), }; } verifySerializedValue(value) { if (!value) { return "Got null data"; } if (typeof value !== "string") { return "Got non string data"; } if (!this.registry.hasId(value)) { return "Invalid class id: " + value + " (factory is " + this.registry.getId() + ")"; } } getCacheKey() { return "metaclass." + this.registry.getId(); } } class TypeArray extends BaseDataType { /** * @param {BaseDataType} innerType */ constructor(innerType) { super(); this.innerType = innerType; } serialize(value) { window.assert(Array.isArray(value), "Not an array"); const result = new Array(value.length); for (let i = 0; i < value.length; ++i) { result[i] = this.innerType.serialize(value[i]); } return result; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { let destination = targetObject[targetKey]; if (!destination) { targetObject[targetKey] = destination = new Array(value.length); } for (let i = 0; i < value.length; ++i) { const errorStatus = this.innerType.deserializeWithVerify(value[i], destination, i, root); if (errorStatus) { return errorStatus; } } } getAsJsonSchemaUncached() { return { type: "array", items: this.innerType.getAsJsonSchema(), }; } verifySerializedValue(value) { if (!Array.isArray(value)) { return "Not an array: " + value; } } getCacheKey() { return "array." + this.innerType.getCacheKey(); } } class TypeFixedClass extends BaseDataType { /** * * @param {typeof BasicSerializableObject} baseclass */ constructor(baseclass) { super(); this.baseclass = baseclass; } serialize(value) { window.assert(value instanceof this.baseclass, "Not a valid class instance"); return value.serialize(); } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { const instance = Object.create(this.baseclass.prototype); const errorState = instance.deserialize(value); if (errorState) { return "Failed to deserialize class: " + errorState; } targetObject[targetKey] = instance; } getAsJsonSchemaUncached() { this.baseclass.getSchema(); this.baseclass.getCachedSchema(); return schemaToJsonSchema(this.baseclass.getCachedSchema()); } verifySerializedValue(value) { if (!value) { return "Got null data"; } } getCacheKey() { return "fixedclass." + this.baseclass.getId(); } } class TypeKeyValueMap extends BaseDataType { /** * @param {BaseDataType} valueType * @param {boolean=} includeEmptyValues */ constructor(valueType, includeEmptyValues = true) { super(); this.valueType = valueType; this.includeEmptyValues = includeEmptyValues; } serialize(value) { window.assert(typeof value === "object", "not an object"); let result = {}; for (const key in value) { const serialized = this.valueType.serialize(value[key]); if (!this.includeEmptyValues && typeof serialized === "object") { if ( serialized.$ && typeof serialized.data === "object" && Object.keys(serialized.data).length === 0 ) { continue; } else if (Object.keys(serialized).length === 0) { continue; } } result[key] = serialized; } return result; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { let result = {}; for (const key in value) { const errorCode = this.valueType.deserializeWithVerify(value[key], result, key, root); if (errorCode) { return errorCode; } } targetObject[targetKey] = result; } getAsJsonSchemaUncached() { return { type: "object", additionalProperties: this.valueType.getAsJsonSchema(), }; } verifySerializedValue(value) { if (typeof value !== "object") { return "KV map is not an object"; } } getCacheKey() { return "kvmap." + this.valueType.getCacheKey(); } } class TypeClassId extends BaseDataType { /** * @param {FactoryTemplate<*>|SingletonFactoryTemplate<*>} registry */ constructor(registry) { super(); this.registry = registry; } serialize(value) { window.assert(typeof value === "string", "Not a valid string"); window.assert(this.registry.hasId(value), "Id " + value + " not found in registry"); return value; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { targetObject[targetKey] = value; } getAsJsonSchemaUncached() { return { type: "string", enum: this.registry.getAllIds(), }; } verifySerializedValue(value) { if (typeof value !== "string") { return "Not a valid registry id key: " + value; } if (!this.registry.hasId(value)) { return "Id " + value + " not known to registry"; } } getCacheKey() { return "classid." + this.registry.getId(); } } class TypePair extends BaseDataType { /** * @param {BaseDataType} type1 * @param {BaseDataType} type2 */ constructor(type1, type2) { super(); window.assert(type1 && type1 instanceof BaseDataType, "bad first type given for pair"); window.assert(type2 && type2 instanceof BaseDataType, "bad second type given for pair"); this.type1 = type1; this.type2 = type2; } serialize(value) { window.assert(Array.isArray(value), "pair: not an array"); window.assert(value.length === 2, "pair: length != 2"); return [this.type1.serialize(value[0]), this.type2.serialize(value[1])]; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { const result = [undefined, undefined]; let errorCode = this.type1.deserialize(value[0], result, 0, root); if (errorCode) { return errorCode; } errorCode = this.type2.deserialize(value[1], result, 1, root); if (errorCode) { return errorCode; } targetObject[targetKey] = result; } getAsJsonSchemaUncached() { return { type: "array", minLength: 2, maxLength: 2, items: [this.type1.getAsJsonSchema(), this.type2.getAsJsonSchema()], }; } verifySerializedValue(value) { if (!Array.isArray(value)) { return "Pair is not an array"; } if (value.length !== 2) { return "Pair length != 2"; } let errorCode = this.type1.verifySerializedValue(value[0]); if (errorCode) { return errorCode; } errorCode = this.type2.verifySerializedValue(value[1]); if (errorCode) { return errorCode; } } getCacheKey() { return "pair.(" + this.type1.getCacheKey() + "," + this.type2.getCacheKey + ")"; } } class TypeNullable extends BaseDataType { /** * @param {BaseDataType} wrapped */ constructor(wrapped) { super(); this.wrapped = wrapped; } serialize(value) { if (value === null || value === undefined) { return null; } return this.wrapped.serialize(value); } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { if (value === null || value === undefined) { targetObject[targetKey] = null; return; } return this.wrapped.deserialize(value, targetObject, targetKey, root); } verifySerializedValue(value) { if (value === null) { return; } return this.wrapped.verifySerializedValue(value); } getAsJsonSchemaUncached() { return { oneOf: [ { type: "null", }, this.wrapped.getAsJsonSchema(), ], }; } allowNull() { return true; } getCacheKey() { return "nullable." + this.wrapped.getCacheKey(); } } class TypeStructuredObject extends BaseDataType { /** * @param {Object.} descriptor */ constructor(descriptor) { super(); this.descriptor = descriptor; } serialize(value) { window.assert(typeof value === "object", "not an object"); let result = {}; for (const key in this.descriptor) { // assert(value.hasOwnProperty(key), "Serialization: Object does not have", key, "property!"); result[key] = this.descriptor[key].serialize(value[key]); } return result; } /** * @see BaseDataType.deserialize * @param {any} value * @param {GameRoot} root * @param {object} targetObject * @param {string|number} targetKey * @returns {string|void} String error code or null on success */ deserialize(value, targetObject, targetKey, root) { let target = targetObject[targetKey]; if (!target) { targetObject[targetKey] = target = {}; } for (const key in value) { const valueType = this.descriptor[key]; const errorCode = valueType.deserializeWithVerify(value[key], target, key, root); if (errorCode) { return errorCode; } } } getAsJsonSchemaUncached() { let properties = {}; for (const key in this.descriptor) { properties[key] = this.descriptor[key].getAsJsonSchema(); } return { type: "object", required: Object.keys(this.descriptor), properties, }; } verifySerializedValue(value) { if (typeof value !== "object") { return "structured object is not an object"; } for (const key in this.descriptor) { if (!value.hasOwnProperty(key)) { return "structured object is missing key " + key; } const subError = this.descriptor[key].verifySerializedValue(value[key]); if (subError) { return "structured object::" + subError; } } } getCacheKey() { let props = []; for (const key in this.descriptor) { props.push(key + "=" + this.descriptor[key].getCacheKey()); } return "structured[" + props.join(",") + "]"; } } /***/ }), /***/ "./src/js/savegame/serializer_internal.js": /*!************************************************!*\ !*** ./src/js/savegame/serializer_internal.js ***! \************************************************/ /*! exports provided: SerializerInternal */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SerializerInternal", function() { return SerializerInternal; }); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/vector */ "./src/js/core/vector.js"); /* harmony import */ var _game_building_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../game/building_codes */ "./src/js/game/building_codes.js"); /* harmony import */ var _game_entity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../game/entity */ "./src/js/game/entity.js"); /* harmony import */ var _game_root__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../game/root */ "./src/js/game/root.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_0__["createLogger"])("serializer_internal"); // Internal serializer methods class SerializerInternal { /** * Serializes an array of entities * @param {Array} array */ serializeEntityArray(array) { const serialized = []; for (let i = 0; i < array.length; ++i) { const entity = array[i]; if (!entity.queuedForDestroy && !entity.destroyed) { serialized.push(entity.serialize()); } } return serialized; } /** * * @param {GameRoot} root * @param {Array} array * @returns {string|void} */ deserializeEntityArray(root, array) { for (let i = 0; i < array.length; ++i) { this.deserializeEntity(root, array[i]); } } /** * * @param {GameRoot} root * @param {Entity} payload */ deserializeEntity(root, payload) { const staticData = payload.components.StaticMapEntity; window.assert(staticData, "entity has no static data"); const code = staticData.code; const data = Object(_game_building_codes__WEBPACK_IMPORTED_MODULE_2__["getBuildingDataFromCode"])(code); const metaBuilding = data.metaInstance; const entity = metaBuilding.createEntity({ root, origin: _core_vector__WEBPACK_IMPORTED_MODULE_1__["Vector"].fromSerializedObject(staticData.origin), rotation: staticData.rotation, originalRotation: staticData.originalRotation, rotationVariant: data.rotationVariant, variant: data.variant, }); entity.uid = payload.uid; this.deserializeComponents(root, entity, payload.components); root.entityMgr.registerEntity(entity, payload.uid); root.map.placeStaticEntity(entity); } /////// COMPONENTS //// /** * Deserializes components of an entity * @param {GameRoot} root * @param {Entity} entity * @param {Object.} data * @returns {string|void} */ deserializeComponents(root, entity, data) { for (const componentId in data) { if (!entity.components[componentId]) { logger.warn("Entity no longer has component:", componentId); continue; } const errorStatus = entity.components[componentId].deserialize(data[componentId], root); if (errorStatus) { return errorStatus; } } } } /***/ }), /***/ "./src/js/states/about.js": /*!********************************!*\ !*** ./src/js/states/about.js ***! \********************************/ /*! exports provided: AboutState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AboutState", function() { return AboutState; }); /* harmony import */ var _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/textual_game_state */ "./src/js/core/textual_game_state.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_cachebust__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/cachebust */ "./src/js/core/cachebust.js"); class AboutState extends _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__["TextualGameState"] { constructor() { super("AboutState"); } getStateHeaderTitle() { return _translations__WEBPACK_IMPORTED_MODULE_1__["T"].about.title; } getMainContentHTML() { return `
shapez.io Logo
${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].about.body .replace("", _core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].github) .replace("", _core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].discord)}
`; } onEnter() { const links = this.htmlElement.querySelectorAll("a[href]"); links.forEach(link => { this.trackClicks( link, () => this.app.platformWrapper.openExternalLink(link.getAttribute("href")), { preventClick: true } ); }); } getDefaultPreviousState() { return "SettingsState"; } } /***/ }), /***/ "./src/js/states/changelog.js": /*!************************************!*\ !*** ./src/js/states/changelog.js ***! \************************************/ /*! exports provided: ChangelogState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ChangelogState", function() { return ChangelogState; }); /* harmony import */ var _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/textual_game_state */ "./src/js/core/textual_game_state.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /* harmony import */ var _changelog__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../changelog */ "./src/js/changelog.js"); class ChangelogState extends _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__["TextualGameState"] { constructor() { super("ChangelogState"); } getStateHeaderTitle() { return _translations__WEBPACK_IMPORTED_MODULE_1__["T"].changelog.title; } getMainContentHTML() { const entries = _changelog__WEBPACK_IMPORTED_MODULE_2__["CHANGELOG"]; let html = ""; for (let i = 0; i < entries.length; ++i) { const entry = entries[i]; html += `
${entry.version} ${entry.date}
    ${entry.entries.map(text => `
  • ${text}
  • `).join("")}
`; } return html; } onEnter() { const links = this.htmlElement.querySelectorAll("a[href]"); links.forEach(link => { this.trackClicks( link, () => this.app.platformWrapper.openExternalLink(link.getAttribute("href")), { preventClick: true } ); }); } } /***/ }), /***/ "./src/js/states/ingame.js": /*!*********************************!*\ !*** ./src/js/states/ingame.js ***! \*********************************/ /*! exports provided: gameCreationAction, GameCreationPayload, InGameState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gameCreationAction", function() { return gameCreationAction; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GameCreationPayload", function() { return GameCreationPayload; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InGameState", function() { return InGameState; }); /* harmony import */ var _core_error_handler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/error_handler */ "./src/js/core/error_handler.js"); /* harmony import */ var _core_game_state__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _game_game_loading_overlay__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game/game_loading_overlay */ "./src/js/game/game_loading_overlay.js"); /* harmony import */ var _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../game/key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _savegame_savegame__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../savegame/savegame */ "./src/js/savegame/savegame.js"); /* harmony import */ var _game_core__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../game/core */ "./src/js/game/core.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["createLogger"])("state/ingame"); // Different sub-states const stages = { s3_createCore: "🌈 3: Create core", s4_A_initEmptyGame: "🌈 4/A: Init empty game", s4_B_resumeGame: "🌈 4/B: Resume game", s5_firstUpdate: "🌈 5: First game update", s6_postLoadHook: "🌈 6: Post load hook", s7_warmup: "🌈 7: Warmup", s10_gameRunning: "🌈 10: Game finally running", leaving: "🌈 Saving, then leaving the game", destroyed: "🌈 DESTROYED: Core is empty and waits for state leave", initFailed: "🌈 ERROR: Initialization failed!", }; const gameCreationAction = { new: "new-game", resume: "resume-game", }; // Typehints class GameCreationPayload { constructor() { /** @type {boolean|undefined} */ this.fastEnter; /** @type {Savegame} */ this.savegame; } } class InGameState extends _core_game_state__WEBPACK_IMPORTED_MODULE_1__["GameState"] { constructor() { super("InGameState"); /** @type {GameCreationPayload} */ this.creationPayload = null; // Stores current stage this.stage = ""; /** @type {GameCore} */ this.core = null; /** @type {KeyActionMapper} */ this.keyActionMapper = null; /** @type {GameLoadingOverlay} */ this.loadingOverlay = null; /** @type {Savegame} */ this.savegame; this.boundInputFilter = this.filterInput.bind(this); } /** * Switches the game into another sub-state * @param {string} stage */ switchStage(stage) { window.assert(stage, "Got empty stage"); if (stage !== this.stage) { this.stage = stage; logger.log(this.stage); return true; } else { // log(this, "Re entering", stage); return false; } } // GameState implementation getInnerHTML() { return ""; } getThemeMusic() { return _platform_sound__WEBPACK_IMPORTED_MODULE_9__["MUSIC"].theme; } onBeforeExit() { // logger.log("Saving before quitting"); // return this.doSave().then(() => { // logger.log(this, "Successfully saved"); // // this.stageDestroyed(); // }); } onAppPause() { // if (this.stage === stages.s10_gameRunning) { // logger.log("Saving because app got paused"); // this.doSave(); // } } getHasFadeIn() { return false; } getPauseOnFocusLost() { return false; } getHasUnloadConfirmation() { return true; } onLeave() { if (this.core) { this.stageDestroyed(); } this.app.inputMgr.dismountFilter(this.boundInputFilter); } onResized(w, h) { super.onResized(w, h); if (this.stage === stages.s10_gameRunning) { this.core.resize(w, h); } } // ---- End of GameState implementation /** * Goes back to the menu state */ goBackToMenu() { this.saveThenGoToState("MainMenuState"); } /** * Goes back to the settings state */ goToSettings() { this.saveThenGoToState("SettingsState", { backToStateId: this.key, backToStatePayload: this.creationPayload, }); } /** * Goes back to the settings state */ goToKeybindings() { this.saveThenGoToState("KeybindingsState", { backToStateId: this.key, backToStatePayload: this.creationPayload, }); } /** * Moves to a state outside of the game * @param {string} stateId * @param {any=} payload */ saveThenGoToState(stateId, payload) { if (this.stage === stages.leaving || this.stage === stages.destroyed) { logger.warn( "Tried to leave game twice or during destroy:", this.stage, "(attempted to move to", stateId, ")" ); return; } this.stageLeavingGame(); this.doSave().then(() => { this.stageDestroyed(); this.moveToState(stateId, payload); }); } onBackButton() { // do nothing } /** * Called when the game somehow failed to initialize. Resets everything to basic state and * then goes to the main menu, showing the error * @param {string} err */ onInitializationFailure(err) { if (this.switchStage(stages.initFailed)) { logger.error("Init failure:", err); this.stageDestroyed(); this.moveToState("MainMenuState", { loadError: err }); } } // STAGES /** * Creates the game core instance, and thus the root */ stage3CreateCore() { if (this.switchStage(stages.s3_createCore)) { logger.log("Creating new game core"); this.core = new _game_core__WEBPACK_IMPORTED_MODULE_8__["GameCore"](this.app); this.core.initializeRoot(this, this.savegame); if (this.savegame.hasGameDump()) { this.stage4bResumeGame(); } else { this.app.gameAnalytics.handleGameStarted(); this.stage4aInitEmptyGame(); } } } /** * Initializes a new empty game */ stage4aInitEmptyGame() { if (this.switchStage(stages.s4_A_initEmptyGame)) { this.core.initNewGame(); this.stage5FirstUpdate(); } } /** * Resumes an existing game */ stage4bResumeGame() { if (this.switchStage(stages.s4_B_resumeGame)) { if (!this.core.initExistingGame()) { this.onInitializationFailure("Savegame is corrupt and can not be restored."); return; } this.app.gameAnalytics.handleGameResumed(); this.stage5FirstUpdate(); } } /** * Performs the first game update on the game which initializes most caches */ stage5FirstUpdate() { if (this.switchStage(stages.s5_firstUpdate)) { this.core.root.logicInitialized = true; this.core.updateLogic(); this.stage6PostLoadHook(); } } /** * Call the post load hook, this means that we have loaded the game, and all systems * can operate and start to work now. */ stage6PostLoadHook() { if (this.switchStage(stages.s6_postLoadHook)) { logger.log("Post load hook"); this.core.postLoadHook(); this.stage7Warmup(); } } /** * This makes the game idle and draw for a while, because we run most code this way * the V8 engine can already start to optimize it. Also this makes sure the resources * are in the VRAM and we have a smooth experience once we start. */ stage7Warmup() { if (this.switchStage(stages.s7_warmup)) { if (_core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].debug.noArtificialDelays) { this.warmupTimeSeconds = 0.05; } else { if (this.creationPayload.fastEnter) { this.warmupTimeSeconds = _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].warmupTimeSecondsFast; } else { this.warmupTimeSeconds = _core_config__WEBPACK_IMPORTED_MODULE_4__["globalConfig"].warmupTimeSecondsRegular; } } } } /** * The final stage where this game is running and updating regulary. */ stage10GameRunning() { if (this.switchStage(stages.s10_gameRunning)) { this.core.root.signals.readyToRender.dispatch(); Object(_core_logging__WEBPACK_IMPORTED_MODULE_2__["logSection"])("GAME STARTED", "#26a69a"); // Initial resize, might have changed during loading (this is possible) this.core.resize(this.app.screenWidth, this.app.screenHeight); } } /** * This stage destroys the whole game, used to cleanup */ stageDestroyed() { if (this.switchStage(stages.destroyed)) { // Cleanup all api calls this.cancelAllAsyncOperations(); if (this.syncer) { this.syncer.cancelSync(); this.syncer = null; } // Cleanup core if (this.core) { this.core.destruct(); this.core = null; } } } /** * When leaving the game */ stageLeavingGame() { if (this.switchStage(stages.leaving)) { // ... } } // END STAGES /** * Filters the input (keybindings) */ filterInput() { return this.stage === stages.s10_gameRunning; } /** * @param {GameCreationPayload} payload */ onEnter(payload) { this.app.inputMgr.installFilter(this.boundInputFilter); this.creationPayload = payload; this.savegame = payload.savegame; this.loadingOverlay = new _game_game_loading_overlay__WEBPACK_IMPORTED_MODULE_5__["GameLoadingOverlay"](this.app, this.getDivElement()); this.loadingOverlay.showBasic(); // Remove unneded default element document.body.querySelector(".modalDialogParent").remove(); this.asyncChannel.watch(Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["waitNextFrame"])()).then(() => this.stage3CreateCore()); } /** * Render callback * @param {number} dt */ onRender(dt) { if (_core_error_handler__WEBPACK_IMPORTED_MODULE_0__["APPLICATION_ERROR_OCCURED"]) { // Application somehow crashed, do not do anything return; } if (this.stage === stages.s7_warmup) { this.core.draw(); this.warmupTimeSeconds -= dt / 1000.0; if (this.warmupTimeSeconds < 0) { logger.log("Warmup completed"); this.stage10GameRunning(); } } if (this.stage === stages.s10_gameRunning) { this.core.tick(dt); } // If the stage is still active (This might not be the case if tick() moved us to game over) if (this.stage === stages.s10_gameRunning) { // Only draw if page visible if (this.app.pageVisible) { this.core.draw(); } this.loadingOverlay.removeIfAttached(); } else { if (!this.loadingOverlay.isAttached()) { this.loadingOverlay.showBasic(); } } } onBackgroundTick(dt) { this.onRender(dt); } /** * Saves the game */ doSave() { if (!this.savegame || !this.savegame.isSaveable()) { return Promise.resolve(); } if (_core_error_handler__WEBPACK_IMPORTED_MODULE_0__["APPLICATION_ERROR_OCCURED"]) { logger.warn("skipping save because application crashed"); return Promise.resolve(); } if ( this.stage !== stages.s10_gameRunning && this.stage !== stages.s7_warmup && this.stage !== stages.leaving ) { logger.warn("Skipping save because game is not ready"); return Promise.resolve(); } // First update the game data logger.log("Starting to save game ..."); this.core.root.signals.gameSaved.dispatch(); this.savegame.updateData(this.core.root); return this.savegame.writeSavegameAndMetadata().catch(err => { logger.warn("Failed to save:", err); }); } } /***/ }), /***/ "./src/js/states/keybindings.js": /*!**************************************!*\ !*** ./src/js/states/keybindings.js ***! \**************************************/ /*! exports provided: KeybindingsState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeybindingsState", function() { return KeybindingsState; }); /* harmony import */ var _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/textual_game_state */ "./src/js/core/textual_game_state.js"); /* harmony import */ var _platform_sound__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../platform/sound */ "./src/js/platform/sound.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /* harmony import */ var _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../game/key_action_mapper */ "./src/js/game/key_action_mapper.js"); /* harmony import */ var _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/modal_dialog_elements */ "./src/js/core/modal_dialog_elements.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _settings__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./settings */ "./src/js/states/settings.js"); class KeybindingsState extends _settings__WEBPACK_IMPORTED_MODULE_6__["SettingsState"] { // constructor() { // super(); // super("KeybindingsState"); // this.settingsState = settingsState; // } // getStateHeaderTitle() { // return T.keybindings.title; // } getMainContentHTML() { return `
${_translations__WEBPACK_IMPORTED_MODULE_2__["T"].keybindings.hint}
${this.getSettingsHtml()}
`; } onEnter() { this.onEnterCommon(); const keybindingsElem = this.htmlElement.querySelector(".keybindings"); this.trackClicks(this.htmlElement.querySelector(".resetBindings"), this.resetBindings); for (const category in _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"]) { const categoryDiv = document.createElement("div"); categoryDiv.classList.add("keyCategory"); keybindingsElem.appendChild(categoryDiv); const labelDiv = document.createElement("strong"); labelDiv.innerText = _translations__WEBPACK_IMPORTED_MODULE_2__["T"].keybindings.categoryLabels[category]; labelDiv.classList.add("categoryLabel"); categoryDiv.appendChild(labelDiv); for (const keybindingId in _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"][category]) { const mapped = _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"][category][keybindingId]; const elem = document.createElement("div"); elem.classList.add("entry"); elem.setAttribute("data-keybinding", keybindingId); categoryDiv.appendChild(elem); const title = document.createElement("span"); title.classList.add("title"); title.innerText = _translations__WEBPACK_IMPORTED_MODULE_2__["T"].keybindings.mappings[keybindingId]; elem.appendChild(title); const mappingDiv = document.createElement("span"); mappingDiv.classList.add("mapping"); elem.appendChild(mappingDiv); const editBtn = document.createElement("button"); editBtn.classList.add("styledButton", "editKeybinding"); const resetBtn = document.createElement("button"); resetBtn.classList.add("styledButton", "resetKeybinding"); if (mapped.builtin) { editBtn.classList.add("disabled"); resetBtn.classList.add("disabled"); } else { this.trackClicks(editBtn, () => this.editKeybinding(keybindingId)); this.trackClicks(resetBtn, () => this.resetKeybinding(keybindingId)); } elem.appendChild(editBtn); elem.appendChild(resetBtn); } } this.updateKeybindings(); } editKeybinding(id) { // if (IS_DEMO) { // this.dialogs.showFeatureRestrictionInfo(T.demo.features.customizeKeybindings); // return; // } const dialog = new _core_modal_dialog_elements__WEBPACK_IMPORTED_MODULE_4__["Dialog"]({ app: this.app, title: _translations__WEBPACK_IMPORTED_MODULE_2__["T"].dialogs.editKeybinding.title, contentHTML: _translations__WEBPACK_IMPORTED_MODULE_2__["T"].dialogs.editKeybinding.desc, buttons: ["cancel:good"], type: "info", }); dialog.inputReciever.keydown.add(({ keyCode, shift, alt, event }) => { if (keyCode === 27) { this.dialogs.closeDialog(dialog); return; } if (event) { event.preventDefault(); } if (event.target && event.target.tagName === "BUTTON" && keyCode === 1) { return; } if ( // Enter keyCode === 13 ) { // Ignore builtins return; } this.app.settings.updateKeybindingOverride(id, keyCode); this.dialogs.closeDialog(dialog); this.updateKeybindings(); }); dialog.inputReciever.backButton.add(() => {}); this.dialogs.internalShowDialog(dialog); this.app.sound.playUiSound(_platform_sound__WEBPACK_IMPORTED_MODULE_1__["SOUNDS"].dialogOk); } updateKeybindings() { const overrides = this.app.settings.getKeybindingOverrides(); for (const category in _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"]) { for (const keybindingId in _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"][category]) { const mapped = _game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["KEYMAPPINGS"][category][keybindingId]; const container = this.htmlElement.querySelector("[data-keybinding='" + keybindingId + "']"); window.assert(container, "Container for keybinding not found: " + keybindingId); let keyCode = mapped.keyCode; if (overrides[keybindingId]) { keyCode = overrides[keybindingId]; } const mappingDiv = container.querySelector(".mapping"); mappingDiv.innerHTML = Object(_game_key_action_mapper__WEBPACK_IMPORTED_MODULE_3__["getStringForKeyCode"])(keyCode); mappingDiv.classList.toggle("changed", !!overrides[keybindingId]); const resetBtn = container.querySelector("button.resetKeybinding"); resetBtn.classList.toggle("disabled", mapped.builtin || !overrides[keybindingId]); } } } resetKeybinding(id) { this.app.settings.resetKeybindingOverride(id); this.updateKeybindings(); } resetBindings() { const { reset } = this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_2__["T"].dialogs.resetKeybindingsConfirmation.title, _translations__WEBPACK_IMPORTED_MODULE_2__["T"].dialogs.resetKeybindingsConfirmation.desc, ["cancel:good", "reset:bad"] ); reset.add(() => { this.app.settings.resetKeybindingOverrides(); this.updateKeybindings(); this.dialogs.showInfo(_translations__WEBPACK_IMPORTED_MODULE_2__["T"].dialogs.keybindingsResetOk.title, _translations__WEBPACK_IMPORTED_MODULE_2__["T"].dialogs.keybindingsResetOk.desc); }); } // getDefaultPreviousState() { // return "SettingsState"; // } } /***/ }), /***/ "./src/js/states/main_menu.js": /*!************************************!*\ !*** ./src/js/states/main_menu.js ***! \************************************/ /*! exports provided: MainMenuState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MainMenuState", function() { return MainMenuState; }); /* harmony import */ var _core_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _core_cachebust__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/cachebust */ "./src/js/core/cachebust.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/read_write_proxy */ "./src/js/core/read_write_proxy.js"); /* harmony import */ var _game_hud_parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../game/hud/parts/modal_dialogs */ "./src/js/game/hud/parts/modal_dialogs.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /* harmony import */ var _profile_application_settings__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../profile/application_settings */ "./src/js/profile/application_settings.js"); /** * @typedef {import("../savegame/savegame_typedefs").SavegameMetadata} SavegameMetadata * @typedef {import("../profile/setting_types").EnumSetting} EnumSetting */ /** * Generates a file download * @param {string} filename * @param {string} text */ function generateFileDownload(filename, text) { var element = document.createElement("a"); element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text)); element.setAttribute("download", filename); element.style.display = "none"; document.body.appendChild(element); element.click(); document.body.removeChild(element); } let noFastGameEnter = false; class MainMenuState extends _core_game_state__WEBPACK_IMPORTED_MODULE_0__["GameState"] { constructor() { super("MainMenuState"); } getInnerHTML() { const bannerHtml = `

${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].demoBanners.title}

${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].demoBanners.intro}

Get the shapez.io standalone! `; return `
${ true ? ` ` : undefined }
${_core_config__WEBPACK_IMPORTED_MODULE_2__["IS_DEMO"] ? `
${bannerHtml}
` : ""}
${ Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["isSupportedBrowser"])() ? "" : `
${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.browserWarning}
` }
`; } requestImportSavegame() { if ( _core_config__WEBPACK_IMPORTED_MODULE_2__["IS_DEMO"] && this.app.savegameMgr.getSavegamesMetaData().length > 0 && !this.app.platformWrapper.getHasUnlimitedSavegames() ) { this.app.analytics.trackUiClick("importgame_slot_limit_show"); this.dialogs.showWarning(_translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.oneSavegameLimit.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.oneSavegameLimit.desc); return; } var input = document.createElement("input"); input.type = "file"; input.accept = ".bin"; input.onchange = e => { const file = input.files[0]; if (file) { Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["waitNextFrame"])().then(() => { this.app.analytics.trackUiClick("import_savegame"); const closeLoader = this.dialogs.showLoadingDialog(); const reader = new FileReader(); reader.addEventListener("load", event => { const contents = event.target.result; let realContent; try { realContent = _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_4__["ReadWriteProxy"].deserializeObject(contents); } catch (err) { closeLoader(); this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameError.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameError.text + "

" + err ); return; } this.app.savegameMgr.importSavegame(realContent).then( () => { closeLoader(); this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameSuccess.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameSuccess.text ); this.renderMainMenu(); this.renderSavegames(); }, err => { closeLoader(); this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameError.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameError.text + ":

" + err ); } ); }); reader.addEventListener("error", error => { this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameError.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.importSavegameError.text + ":

" + error ); }); reader.readAsText(file, "utf-8"); }); } }; input.click(); } onBackButton() { this.app.platformWrapper.exitApp(); } onEnter(payload) { this.dialogs = new _game_hud_parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_5__["HUDModalDialogs"](null, this.app); const dialogsElement = document.body.querySelector(".modalDialogParent"); this.dialogs.initializeToElement(dialogsElement); if (payload.loadError) { this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.gameLoadFailure.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.gameLoadFailure.text + "

" + payload.loadError ); } const qs = this.htmlElement.querySelector.bind(this.htmlElement); if (_core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.fastGameEnter && !noFastGameEnter) { noFastGameEnter = true; const games = this.app.savegameMgr.getSavegamesMetaData(); if (games.length > 0 && _core_config__WEBPACK_IMPORTED_MODULE_2__["globalConfig"].debug.resumeGameOnFastEnter) { this.resumeGame(games[0]); } else { this.onPlayButtonClicked(); } } // Initialize video this.videoElement = this.htmlElement.querySelector("video"); this.videoElement.playbackRate = 0.9; this.videoElement.addEventListener("canplay", () => { if (this.videoElement) { this.videoElement.classList.add("loaded"); } }); this.trackClicks(qs(".settingsButton"), this.onSettingsButtonClicked); this.trackClicks(qs(".changelog"), this.onChangelogClicked); this.trackClicks(qs(".redditLink"), this.onRedditClicked); this.trackClicks(qs(".languageChoose"), this.onLanguageChooseClicked); this.trackClicks(qs(".helpTranslate"), this.onTranslationHelpLinkClicked); if (false) {} this.renderMainMenu(); this.renderSavegames(); const steamLink = this.htmlElement.querySelector(".steamLink"); if (steamLink) { this.trackClicks(steamLink, () => this.onSteamLinkClicked(), { preventClick: true }); } const discordLink = this.htmlElement.querySelector(".discordLink"); this.trackClicks( discordLink, () => this.app.platformWrapper.openExternalLink(_core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].discord), { preventClick: true } ); const githubLink = this.htmlElement.querySelector(".githubLink"); this.trackClicks( githubLink, () => this.app.platformWrapper.openExternalLink(_core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].github), { preventClick: true } ); const producerLink = this.htmlElement.querySelector(".producerLink"); this.trackClicks( producerLink, () => this.app.platformWrapper.openExternalLink("https://tobspr.com"), { preventClick: true } ); } renderMainMenu() { const buttonContainer = this.htmlElement.querySelector(".mainContainer .buttons"); Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["removeAllChildren"])(buttonContainer); // Import button const importButtonElement = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeButtonElement"])( ["importButton", "styledButton"], _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.importSavegame ); this.trackClicks(importButtonElement, this.requestImportSavegame); if (this.savedGames.length > 0) { // Continue game const continueButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeButton"])( buttonContainer, ["continueButton", "styledButton"], _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.continue ); this.trackClicks(continueButton, this.onContinueButtonClicked); const outerDiv = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(buttonContainer, null, ["outer"], null); outerDiv.appendChild(importButtonElement); const newGameButton = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeButton"])( this.htmlElement.querySelector(".mainContainer .outer"), ["newGameButton", "styledButton"], _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.newGame ); this.trackClicks(newGameButton, this.onPlayButtonClicked); } else { // New game const playBtn = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeButton"])(buttonContainer, ["playButton", "styledButton"], _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.play); this.trackClicks(playBtn, this.onPlayButtonClicked); buttonContainer.appendChild(importButtonElement); } } onSteamLinkClicked() { this.app.analytics.trackUiClick("main_menu_steam_link_2"); this.app.platformWrapper.openExternalLink(_core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].standaloneStorePage); return false; } onExitAppButtonClicked() { this.app.platformWrapper.exitApp(); } onChangelogClicked() { this.moveToState("ChangelogState"); } onRedditClicked() { this.app.analytics.trackUiClick("main_menu_reddit_link"); this.app.platformWrapper.openExternalLink(_core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].reddit); } onLanguageChooseClicked() { this.app.analytics.trackUiClick("choose_language"); const setting = /** @type {EnumSetting} */ (Object(_profile_application_settings__WEBPACK_IMPORTED_MODULE_7__["getApplicationSettingById"])("language")); const { optionSelected } = this.dialogs.showOptionChooser(_translations__WEBPACK_IMPORTED_MODULE_6__["T"].settings.labels.language.title, { active: this.app.settings.getLanguage(), options: setting.options.map(option => ({ value: setting.valueGetter(option), text: setting.textGetter(option), desc: setting.descGetter(option), iconPrefix: setting.iconPrefix, })), }); optionSelected.add(value => { this.app.settings.updateLanguage(value); if (setting.restartRequired) { if (this.app.platformWrapper.getSupportsRestart()) { this.app.platformWrapper.performRestart(); } else { this.dialogs.showInfo(_translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.restartRequired.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.restartRequired.text, [ "ok:good", ]); } } if (setting.changeCb) { setting.changeCb(this.app, value); } // Update current icon this.htmlElement.querySelector("button.languageChoose").setAttribute("data-languageIcon", value); }, this); } get savedGames() { return this.app.savegameMgr.getSavegamesMetaData(); } renderSavegames() { const oldContainer = this.htmlElement.querySelector(".mainContainer .savegames"); if (oldContainer) { oldContainer.remove(); } const games = this.savedGames; if (games.length > 0) { const parent = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(this.htmlElement.querySelector(".mainContainer"), null, ["savegames"]); for (let i = 0; i < games.length; ++i) { const elem = Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(parent, null, ["savegame"]); Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])( elem, null, ["playtime"], Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["formatSecondsToTimeAgo"])((new Date().getTime() - games[i].lastUpdate) / 1000.0) ); Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])( elem, null, ["level"], games[i].level ? _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.savegameLevel.replace("", "" + games[i].level) : _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.savegameLevelUnknown ); let TlastVersion = "@"; Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(elem, null, ["version"], TlastVersion.replace("", "" + games[i].lastVersion)); const deleteButton = document.createElement("button"); deleteButton.classList.add("styledButton", "deleteGame"); elem.appendChild(deleteButton); const downloadButton = document.createElement("button"); downloadButton.classList.add("styledButton", "downloadGame"); elem.appendChild(downloadButton); const resumeButton = document.createElement("button"); resumeButton.classList.add("styledButton", "resumeGame"); elem.appendChild(resumeButton); this.trackClicks(deleteButton, () => this.deleteGame(games[i])); this.trackClicks(downloadButton, () => this.downloadGame(games[i])); this.trackClicks(resumeButton, () => this.resumeGame(games[i])); } } } /** * @param {SavegameMetadata} game */ resumeGame(game) { this.app.analytics.trackUiClick("resume_game"); this.app.adProvider.showVideoAd().then(() => { this.app.analytics.trackUiClick("resume_game_adcomplete"); const savegame = this.app.savegameMgr.getSavegameById(game.internalId); savegame .readAsync() .then(() => { this.moveToState("InGameState", { savegame, }); }) .catch(err => { this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.gameLoadFailure.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.gameLoadFailure.text + "

" + err ); }); }); } /** * @param {SavegameMetadata} game */ deleteGame(game) { this.app.analytics.trackUiClick("delete_game"); const signals = this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.confirmSavegameDelete.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.confirmSavegameDelete.text, ["delete:bad", "cancel:good"] ); signals.delete.add(() => { this.app.savegameMgr.deleteSavegame(game).then( () => { this.renderSavegames(); if (this.savedGames.length <= 0) this.renderMainMenu(); }, err => { this.dialogs.showWarning( _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.savegameDeletionError.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.savegameDeletionError.text + "

" + err ); } ); }); } /** * @param {SavegameMetadata} game */ downloadGame(game) { this.app.analytics.trackUiClick("download_game"); const savegame = this.app.savegameMgr.getSavegameById(game.internalId); savegame.readAsync().then(() => { const data = _core_read_write_proxy__WEBPACK_IMPORTED_MODULE_4__["ReadWriteProxy"].serializeObject(savegame.currentData); generateFileDownload(savegame.filename, data); }); } onSettingsButtonClicked() { this.moveToState("SettingsState"); } onTranslationHelpLinkClicked() { this.app.analytics.trackUiClick("translation_help_link"); this.app.platformWrapper.openExternalLink( "https://github.com/tobspr/shapez.io/blob/master/translations" ); } onPlayButtonClicked() { if ( _core_config__WEBPACK_IMPORTED_MODULE_2__["IS_DEMO"] && this.app.savegameMgr.getSavegamesMetaData().length > 0 && !this.app.platformWrapper.getHasUnlimitedSavegames() ) { this.app.analytics.trackUiClick("startgame_slot_limit_show"); this.dialogs.showWarning(_translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.oneSavegameLimit.title, _translations__WEBPACK_IMPORTED_MODULE_6__["T"].dialogs.oneSavegameLimit.desc); return; } this.app.analytics.trackUiClick("startgame"); this.app.adProvider.showVideoAd().then(() => { const savegame = this.app.savegameMgr.createNewSavegame(); this.moveToState("InGameState", { savegame, }); this.app.analytics.trackUiClick("startgame_adcomplete"); }); } onContinueButtonClicked() { let latestLastUpdate = 0; let latestInternalId; this.app.savegameMgr.currentData.savegames.forEach(saveGame => { if (saveGame.lastUpdate > latestLastUpdate) { latestLastUpdate = saveGame.lastUpdate; latestInternalId = saveGame.internalId; } }); const savegame = this.app.savegameMgr.getSavegameById(latestInternalId); savegame.readAsync().then(() => { this.moveToState("InGameState", { savegame, }); }); } onLeave() { this.dialogs.cleanup(); } } /***/ }), /***/ "./src/js/states/mobile_warning.js": /*!*****************************************!*\ !*** ./src/js/states/mobile_warning.js ***! \*****************************************/ /*! exports provided: MobileWarningState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MobileWarningState", function() { return MobileWarningState; }); /* harmony import */ var _core_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _core_cachebust__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/cachebust */ "./src/js/core/cachebust.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); class MobileWarningState extends _core_game_state__WEBPACK_IMPORTED_MODULE_0__["GameState"] { constructor() { super("MobileWarningState"); } getInnerHTML() { return `

I'm sorry, but shapez.io is not available on mobile devices yet! There is also no estimate when this will change, but feel to make a contribution! It's  open source!

If you want to play on your computer, you can also get the standalone on steam:

Get the shapez.io standalone! `; } getThemeMusic() { return null; } getHasFadeIn() { return false; } onEnter() { try { if (window.gtag) { window.gtag("event", "click", { event_category: "ui", event_label: "mobile_warning", }); } } catch (ex) { console.warn("Failed to track mobile click:", ex); } } onLeave() { // this.dialogs.cleanup(); } } /***/ }), /***/ "./src/js/states/preload.js": /*!**********************************!*\ !*** ./src/js/states/preload.js ***! \**********************************/ /*! exports provided: PreloadState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PreloadState", function() { return PreloadState; }); /* harmony import */ var _core_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/game_state */ "./src/js/core/game_state.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _core_cachebust__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core/cachebust */ "./src/js/core/cachebust.js"); /* harmony import */ var _platform_browser_wrapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../platform/browser/wrapper */ "./src/js/platform/browser/wrapper.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); /* harmony import */ var _game_hud_parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../game/hud/parts/modal_dialogs */ "./src/js/game/hud/parts/modal_dialogs.js"); /* harmony import */ var _changelog__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../changelog */ "./src/js/changelog.js"); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../core/config */ "./src/js/core/config.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("state/preload"); class PreloadState extends _core_game_state__WEBPACK_IMPORTED_MODULE_0__["GameState"] { constructor() { super("PreloadState"); } getInnerHTML() { return `
Booting 0%
`; } getThemeMusic() { return null; } getHasFadeIn() { return false; } onEnter() { this.htmlElement.classList.add("prefab_LoadingState"); const elementsToRemove = ["#loadingPreload", "#fontPreload"]; for (let i = 0; i < elementsToRemove.length; ++i) { const elem = document.querySelector(elementsToRemove[i]); if (elem) { elem.remove(); } } this.dialogs = new _game_hud_parts_modal_dialogs__WEBPACK_IMPORTED_MODULE_6__["HUDModalDialogs"](null, this.app); const dialogsElement = document.body.querySelector(".modalDialogParent"); this.dialogs.initializeToElement(dialogsElement); /** @type {HTMLElement} */ this.statusText = this.htmlElement.querySelector(".loadingStatus > .desc"); /** @type {HTMLElement} */ this.statusBar = this.htmlElement.querySelector(".loadingStatus > .bar > .inner"); /** @type {HTMLElement} */ this.statusBarText = this.htmlElement.querySelector(".loadingStatus > .bar > .status"); this.currentStatus = "booting"; this.currentIndex = 0; this.startLoading(); } onLeave() { // this.dialogs.cleanup(); } startLoading() { this.setStatus("Booting") .then(() => this.setStatus("Creating platform wrapper")) .then(() => this.app.platformWrapper.initialize()) .then(() => this.setStatus("Initializing local storage")) .then(() => { const wrapper = this.app.platformWrapper; if (wrapper instanceof _platform_browser_wrapper__WEBPACK_IMPORTED_MODULE_4__["PlatformWrapperImplBrowser"]) { try { window.localStorage.setItem("local_storage_test", "1"); window.localStorage.removeItem("local_storage_test"); } catch (ex) { logger.error("Failed to read/write local storage:", ex); return new Promise(() => { alert(`Your brower does not support thirdparty cookies or you have disabled it in your security settings.\n\n In Chrome this setting is called "Block third-party cookies and site data".\n\n Please allow third party cookies and then reload the page.`); // Never return }); } } }) .then(() => this.setStatus("Creating storage")) .then(() => { return this.app.storage.initialize(); }) .then(() => this.setStatus("Initializing libraries")) .then(() => this.app.analytics.initialize()) .then(() => this.app.gameAnalytics.initialize()) .then(() => this.setStatus("Initializing settings")) .then(() => { return this.app.settings.initialize(); }) .then(() => { // Initialize fullscreen if (this.app.platformWrapper.getSupportsFullscreen()) { this.app.platformWrapper.setFullscreen(this.app.settings.getIsFullScreen()); } }) .then(() => this.setStatus("Initializing language")) .then(() => { if (this.app.settings.getLanguage() === "auto-detect") { const language = Object(_translations__WEBPACK_IMPORTED_MODULE_5__["autoDetectLanguageId"])(); logger.log("Setting language to", language); return this.app.settings.updateLanguage(language); } }) .then(() => { const language = this.app.settings.getLanguage(); Object(_translations__WEBPACK_IMPORTED_MODULE_5__["updateApplicationLanguage"])(language); }) .then(() => this.setStatus("Initializing sounds")) .then(() => { // Notice: We don't await the sounds loading itself return this.app.sound.initialize(); }) .then(() => { this.app.backgroundResourceLoader.startLoading(); }) .then(() => this.setStatus("Initializing savegame")) .then(() => { return this.app.savegameMgr.initialize().catch(err => { logger.error("Failed to initialize savegames:", err); alert( "Your savegames failed to load, it seems your data files got corrupted. I'm so sorry!\n\n(This can happen if your pc crashed while a game was saved).\n\nYou can try re-importing your savegames." ); return this.app.savegameMgr.writeAsync(); }); }) .then(() => this.setStatus("Downloading resources")) .then(() => { return this.app.backgroundResourceLoader.getPromiseForBareGame(); }) .then(() => this.setStatus("Checking changelog")) .then(() => { if (_core_config__WEBPACK_IMPORTED_MODULE_8__["globalConfig"].debug.disableUpgradeNotification) { return; } return this.app.storage .readFileAsync("lastversion.bin") .catch(err => { logger.warn("Failed to read lastversion:", err); return "modZ 1.0.3"; }) .then(version => { logger.log("Last version:", version, "App version:", "modZ 1.0.3"); this.app.storage.writeFileAsync("lastversion.bin", "modZ 1.0.3"); return version; }) .then(version => { let changelogEntries = []; logger.log("Last seen version:", version); for (let i = 0; i < _changelog__WEBPACK_IMPORTED_MODULE_7__["CHANGELOG"].length; ++i) { if (_changelog__WEBPACK_IMPORTED_MODULE_7__["CHANGELOG"][i].version === version) { break; } changelogEntries.push(_changelog__WEBPACK_IMPORTED_MODULE_7__["CHANGELOG"][i]); } if (changelogEntries.length === 0) { return; } let dialogHtml = _translations__WEBPACK_IMPORTED_MODULE_5__["T"].dialogs.updateSummary.desc; for (let i = 0; i < changelogEntries.length; ++i) { const entry = changelogEntries[i]; dialogHtml += `
${entry.version} ${entry.date}
    ${entry.entries.map(text => `
  • ${text}
  • `).join("")}
`; } return new Promise(resolve => { this.dialogs.showInfo(_translations__WEBPACK_IMPORTED_MODULE_5__["T"].dialogs.updateSummary.title, dialogHtml).ok.add(resolve); }); }); }) .then(() => this.setStatus("Launching")) .then( () => { this.moveToState("MainMenuState"); }, err => { this.showFailMessage(err); } ); } setStatus(text) { logger.log("✅ " + text); this.currentIndex += 1; this.currentStatus = text; this.statusText.innerText = text; const numSteps = 10; // FIXME const percentage = (this.currentIndex / numSteps) * 100.0; this.statusBar.style.width = percentage + "%"; this.statusBarText.innerText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_2__["findNiceValue"])(percentage) + "%"; return Promise.resolve(); } showFailMessage(text) { logger.error("App init failed:", text); const email = "bugs@shapez.io"; const subElement = document.createElement("div"); subElement.classList.add("failureBox"); subElement.innerHTML = `
Failed to initialize application!
${this.currentStatus} failed:
${text}
Please send me an email with steps to reproduce and what you did before this happened:
Build ${"modZ 1.0.3"} @ ${"4bbf0823"}
`; this.htmlElement.classList.add("failure"); this.htmlElement.appendChild(subElement); const resetBtn = subElement.querySelector("button.resetApp"); this.trackClicks(resetBtn, this.showResetConfirm); } showResetConfirm() { if (confirm("Are you sure you want to reset the app? This will delete all your savegames")) { this.resetApp(); } } resetApp() { this.app.settings .resetEverythingAsync() .then(() => { this.app.savegameMgr.resetEverythingAsync(); }) .then(() => { this.app.settings.resetEverythingAsync(); }) .then(() => { window.location.reload(); }); } } /***/ }), /***/ "./src/js/states/settings.js": /*!***********************************!*\ !*** ./src/js/states/settings.js ***! \***********************************/ /*! exports provided: SettingsState */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SettingsState", function() { return SettingsState; }); /* harmony import */ var _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/textual_game_state */ "./src/js/core/textual_game_state.js"); /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/utils */ "./src/js/core/utils.js"); /* harmony import */ var _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../profile/application_settings */ "./src/js/profile/application_settings.js"); /* harmony import */ var _translations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../translations */ "./src/js/translations.js"); class SettingsState extends _core_textual_game_state__WEBPACK_IMPORTED_MODULE_0__["TextualGameState"] { constructor(key = "SettingsState") { super(key); } getStateHeaderTitle() { return _translations__WEBPACK_IMPORTED_MODULE_3__["T"].settings.title; } getMainContentHTML() { return `
${this.getSettingsHtml()}
`; } getCategoryButtonsHtml() { return Object.keys(_profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"]) .map(key => _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"][key]) .map( category => ` ` ) .join(""); } getSettingsHtml() { const categoriesHTML = {}; Object.keys(_profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"]).forEach(key => { const catName = _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"][key]; categoriesHTML[catName] = `
`; }); for (let i = 0; i < _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["allApplicationSettings"].length; ++i) { const setting = _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["allApplicationSettings"][i]; categoriesHTML[setting.categoryId] += setting.getHtml(); } return Object.keys(categoriesHTML) .map(k => categoriesHTML[k] + "
") .join(""); } renderBuildText() { const labelVersion = this.htmlElement.querySelector(".buildVersion"); const lastBuildMs = new Date().getTime() - 1603628670741; const lastBuildText = Object(_core_utils__WEBPACK_IMPORTED_MODULE_1__["formatSecondsToTimeAgo"])(lastBuildMs / 1000.0); const version = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].settings.versionBadges["dev"]; labelVersion.innerHTML = ` ${"modZ 1.0.3"} @ ${version} @ ${"4bbf0823"} ${_translations__WEBPACK_IMPORTED_MODULE_3__["T"].settings.buildDate.replace("", lastBuildText)}
`; } onEnterCommon() { this.renderBuildText(); this.trackClicks(this.htmlElement.querySelector(".about"), this.onAboutClicked, { preventDefault: false, }); const keybindingsButton = this.htmlElement.querySelector(".editKeybindings"); if (keybindingsButton) { this.trackClicks(keybindingsButton, this.onKeybindingsClicked, { preventDefault: false }); } this.initSettings(); this.initCategoryButtons(); this.htmlElement.querySelector(".category").classList.add("active"); this.htmlElement.querySelector(".categoryButton").classList.add("active"); this.setActiveCategory(_profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"].general); } onEnter(payload) { this.onEnterCommon(); } setActiveCategory(category) { const previousCategory = this.htmlElement.querySelector(".category.active"); const previousCategoryButton = this.htmlElement.querySelector(".categoryButton.active"); if (previousCategory.getAttribute("data-category") == category) { return; } previousCategory.classList.remove("active"); previousCategoryButton.classList.remove("active"); const newCategory = this.htmlElement.querySelector("[data-category='" + category + "']"); const newCategoryButton = this.htmlElement.querySelector("[data-category-btn='" + category + "']"); newCategory.classList.add("active"); newCategoryButton.classList.add("active"); } initSettings() { _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["allApplicationSettings"].forEach(setting => { /** @type {HTMLElement} */ const element = this.htmlElement.querySelector("[data-setting='" + setting.id + "']"); setting.bind(this.app, element, this.dialogs); setting.syncValueToElement(); this.trackClicks( element, () => { setting.modify(); }, { preventDefault: false } ); }); } initCategoryButtons() { Object.keys(_profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"]).forEach(key => { const category = _profile_application_settings__WEBPACK_IMPORTED_MODULE_2__["enumCategories"][key]; const button = this.htmlElement.querySelector("[data-category-btn='" + category + "']"); this.trackClicks( button, () => { this.setActiveCategory(category); }, { preventDefault: false } ); }); } onAboutClicked() { this.moveToStateAddGoBack("AboutState"); } onKeybindingsClicked() { this.switchToState("KeybindingsState"); } } /***/ }), /***/ "./src/js/translations.js": /*!********************************!*\ !*** ./src/js/translations.js ***! \********************************/ /*! exports provided: T, applyLanguage, autoDetectLanguageId, updateApplicationLanguage */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "T", function() { return T; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyLanguage", function() { return applyLanguage; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "autoDetectLanguageId", function() { return autoDetectLanguageId; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateApplicationLanguage", function() { return updateApplicationLanguage; }); /* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./core/config */ "./src/js/core/config.js"); /* harmony import */ var _core_logging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./core/logging */ "./src/js/core/logging.js"); /* harmony import */ var _languages__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./languages */ "./src/js/languages.js"); const logger = Object(_core_logging__WEBPACK_IMPORTED_MODULE_1__["createLogger"])("translations"); // @ts-ignore const baseTranslations = __webpack_require__(/*! ./built-temp/base-en.json */ "./src/js/built-temp/base-en.json"); let T = baseTranslations; if (_core_config__WEBPACK_IMPORTED_MODULE_0__["globalConfig"].debug.testTranslations) { // Replaces all translations by fake translations to see whats translated and what not const mapTranslations = obj => { for (const key in obj) { const value = obj[key]; if (typeof value === "string") { obj[key] = value.replace(/[a-z]/gi, "x"); } else { mapTranslations(value); } } }; mapTranslations(T); } function applyLanguage(languageCode) { logger.log("Applying language:", languageCode); const data = _languages__WEBPACK_IMPORTED_MODULE_2__["LANGUAGES"][languageCode]; if (!data) { logger.error("Language not found:", languageCode); return false; } } // Language key is something like de-DE or en or en-US function mapLanguageCodeToId(languageKey) { const key = languageKey.toLowerCase(); const shortKey = key.split("-")[0]; // Try to match by key or short key for (const id in _languages__WEBPACK_IMPORTED_MODULE_2__["LANGUAGES"]) { const data = _languages__WEBPACK_IMPORTED_MODULE_2__["LANGUAGES"][id]; const code = data.code.toLowerCase(); if (code === key) { console.log("-> Match", languageKey, "->", id); return id; } if (code === shortKey) { console.log("-> Match by short key", languageKey, "->", id); return id; } } // If none found, try to find a better alternative by using the base language at least for (const id in _languages__WEBPACK_IMPORTED_MODULE_2__["LANGUAGES"]) { const data = _languages__WEBPACK_IMPORTED_MODULE_2__["LANGUAGES"][id]; const code = data.code.toLowerCase(); const shortCode = code.split("-")[0]; if (shortCode === key) { console.log("-> Desperate Match", languageKey, "->", id); return id; } if (shortCode === shortKey) { console.log("-> Desperate Match by short key", languageKey, "->", id); return id; } } return null; } /** * Tries to auto-detect a language * @returns {string} */ function autoDetectLanguageId() { let languages = []; if (navigator.languages) { languages = navigator.languages.slice(); } else if (navigator.language) { languages = [navigator.language]; } else { logger.warn("Navigator has no languages prop"); } for (let i = 0; i < languages.length; ++i) { logger.log("Trying to find language target for", languages[i]); const trans = mapLanguageCodeToId(languages[i]); if (trans) { return trans; } } // Fallback return "en"; } function matchDataRecursive(dest, src) { if (typeof dest !== "object" || typeof src !== "object") { return; } for (const key in dest) { if (src[key]) { // console.log("copy", key); const data = dest[key]; if (typeof data === "object") { matchDataRecursive(dest[key], src[key]); } else if (typeof data === "string" || typeof data === "number") { // console.log("match string", key); dest[key] = src[key]; } else { logger.log("Unknown type:", typeof data, "in key", key); } } } } function updateApplicationLanguage(id) { logger.log("Setting application language:", id); const data = _languages__WEBPACK_IMPORTED_MODULE_2__["LANGUAGES"][id]; if (!data) { logger.error("Unknown language:", id); return; } if (data.data) { logger.log("Applying translations ..."); matchDataRecursive(T, data.data); } } /***/ }), /***/ "./src/js/webworkers/background_animation_frame_emittter.worker.js": /*!*************************************************************************!*\ !*** ./src/js/webworkers/background_animation_frame_emittter.worker.js ***! \*************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = function() { return __webpack_require__(/*! !./node_modules/worker-loader/dist/workers/InlineWorker.js */ "./node_modules/worker-loader/dist/workers/InlineWorker.js")("/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = \"./node_modules/webpack-strip-block/index.js?!./src/js/webworkers/background_animation_frame_emittter.worker.js\");\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./node_modules/webpack-strip-block/index.js?!./src/js/webworkers/background_animation_frame_emittter.worker.js\":\n/*!**********************************************************************************************************************!*\\\n !*** ./node_modules/webpack-strip-block??ref--7-0!./src/js/webworkers/background_animation_frame_emittter.worker.js ***!\n \\**********************************************************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// We clamp high deltas so 30 fps is fairly ok\r\nconst bgFps = 30;\r\nconst desiredMsDelay = 1000 / bgFps;\r\n\r\nlet lastTick = performance.now();\r\n\r\nfunction tick() {\r\n const now = performance.now();\r\n const delta = now - lastTick;\r\n lastTick = now;\r\n\r\n // @ts-ignore\r\n self.postMessage({ delta });\r\n}\r\n\r\nsetInterval(tick, desiredMsDelay);\r\n\n\n/***/ })\n\n/******/ });\n//# sourceMappingURL=71a6a9408a2d0b49ba56.worker.js.map", null); }; /***/ }), /***/ "./src/js/webworkers/compression.worker.js": /*!*************************************************!*\ !*** ./src/js/webworkers/compression.worker.js ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = function() { return __webpack_require__(/*! !./node_modules/worker-loader/dist/workers/InlineWorker.js */ "./node_modules/worker-loader/dist/workers/InlineWorker.js")("/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = \"./node_modules/webpack-strip-block/index.js?!./src/js/webworkers/compression.worker.js\");\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./gulp/node_modules/base64-js/index.js\":\n/*!**********************************************!*\\\n !*** ./gulp/node_modules/base64-js/index.js ***!\n \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(\n uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n ))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n\n\n/***/ }),\n\n/***/ \"./gulp/node_modules/ieee754/index.js\":\n/*!********************************************!*\\\n !*** ./gulp/node_modules/ieee754/index.js ***!\n \\********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n\n\n/***/ }),\n\n/***/ \"./gulp/node_modules/isarray/index.js\":\n/*!********************************************!*\\\n !*** ./gulp/node_modules/isarray/index.js ***!\n \\********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n\n\n/***/ }),\n\n/***/ \"./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js\":\n/*!**************************************************************************!*\\\n !*** ./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js ***!\n \\**************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"./gulp/node_modules/base64-js/index.js\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"./gulp/node_modules/ieee754/index.js\")\nvar isArray = __webpack_require__(/*! isarray */ \"./gulp/node_modules/isarray/index.js\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"./gulp/node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./gulp/node_modules/webpack/buildin/global.js\":\n/*!***********************************!*\\\n !*** (webpack)/buildin/global.js ***!\n \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n/***/ }),\n\n/***/ \"./node_modules/crc/crc32.js\":\n/*!***********************************!*\\\n !*** ./node_modules/crc/crc32.js ***!\n \\***********************************/\n/*! exports provided: default */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! buffer */ \"./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js\");\n/* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _create_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./create_buffer */ \"./node_modules/crc/create_buffer.js\");\n/* harmony import */ var _define_crc__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./define_crc */ \"./node_modules/crc/define_crc.js\");\n\n\n\n\n// Generated by `./pycrc.py --algorithm=table-driven --model=crc-32 --generate=c`\n// prettier-ignore\nlet TABLE = [\n 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,\n 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\n 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,\n 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\n 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,\n 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,\n 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,\n 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,\n 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\n 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,\n 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\n 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,\n 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,\n 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\n 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,\n 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\n 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,\n 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,\n 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,\n 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,\n 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\n 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,\n 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\n 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,\n 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,\n 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\n 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d\n];\n\nif (typeof Int32Array !== 'undefined') TABLE = new Int32Array(TABLE);\n\nconst crc32 = Object(_define_crc__WEBPACK_IMPORTED_MODULE_2__[\"default\"])('crc-32', function(buf, previous) {\n if (!buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"].isBuffer(buf)) buf = Object(_create_buffer__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(buf);\n\n let crc = previous === 0 ? 0 : ~~previous ^ -1;\n\n for (let index = 0; index < buf.length; index++) {\n const byte = buf[index];\n crc = TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n\n return crc ^ -1;\n});\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (crc32);\n\n\n/***/ }),\n\n/***/ \"./node_modules/crc/create_buffer.js\":\n/*!*******************************************!*\\\n !*** ./node_modules/crc/create_buffer.js ***!\n \\*******************************************/\n/*! exports provided: default */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! buffer */ \"./gulp/node_modules/node-libs-browser/node_modules/buffer/index.js\");\n/* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer__WEBPACK_IMPORTED_MODULE_0__);\n\n\nconst createBuffer =\n buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"].from && buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"].alloc && buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"].allocUnsafe && buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"].allocUnsafeSlow\n ? buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"].from\n : // support for Node < 5.10\n val => new buffer__WEBPACK_IMPORTED_MODULE_0__[\"Buffer\"](val);\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (createBuffer);\n\n\n/***/ }),\n\n/***/ \"./node_modules/crc/define_crc.js\":\n/*!****************************************!*\\\n !*** ./node_modules/crc/define_crc.js ***!\n \\****************************************/\n/*! exports provided: default */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(model, calc) {\n const fn = (buf, previous) => calc(buf, previous) >>> 0;\n fn.signed = calc;\n fn.unsigned = fn;\n fn.model = model;\n\n return fn;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/decode-uri-component/index.js\":\n/*!****************************************************!*\\\n !*** ./node_modules/decode-uri-component/index.js ***!\n \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar token = '%[a-f0-9]{2}';\nvar singleMatcher = new RegExp(token, 'gi');\nvar multiMatcher = new RegExp('(' + token + ')+', 'gi');\n\nfunction decodeComponents(components, split) {\n\ttry {\n\t\t// Try to decode the entire string first\n\t\treturn decodeURIComponent(components.join(''));\n\t} catch (err) {\n\t\t// Do nothing\n\t}\n\n\tif (components.length === 1) {\n\t\treturn components;\n\t}\n\n\tsplit = split || 1;\n\n\t// Split the array in 2 parts\n\tvar left = components.slice(0, split);\n\tvar right = components.slice(split);\n\n\treturn Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));\n}\n\nfunction decode(input) {\n\ttry {\n\t\treturn decodeURIComponent(input);\n\t} catch (err) {\n\t\tvar tokens = input.match(singleMatcher);\n\n\t\tfor (var i = 1; i < tokens.length; i++) {\n\t\t\tinput = decodeComponents(tokens, i).join('');\n\n\t\t\ttokens = input.match(singleMatcher);\n\t\t}\n\n\t\treturn input;\n\t}\n}\n\nfunction customDecodeURIComponent(input) {\n\t// Keep track of all the replacements and prefill the map with the `BOM`\n\tvar replaceMap = {\n\t\t'%FE%FF': '\\uFFFD\\uFFFD',\n\t\t'%FF%FE': '\\uFFFD\\uFFFD'\n\t};\n\n\tvar match = multiMatcher.exec(input);\n\twhile (match) {\n\t\ttry {\n\t\t\t// Decode as big chunks as possible\n\t\t\treplaceMap[match[0]] = decodeURIComponent(match[0]);\n\t\t} catch (err) {\n\t\t\tvar result = decode(match[0]);\n\n\t\t\tif (result !== match[0]) {\n\t\t\t\treplaceMap[match[0]] = result;\n\t\t\t}\n\t\t}\n\n\t\tmatch = multiMatcher.exec(input);\n\t}\n\n\t// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else\n\treplaceMap['%C2'] = '\\uFFFD';\n\n\tvar entries = Object.keys(replaceMap);\n\n\tfor (var i = 0; i < entries.length; i++) {\n\t\t// Replace all decoded components\n\t\tvar key = entries[i];\n\t\tinput = input.replace(new RegExp(key, 'g'), replaceMap[key]);\n\t}\n\n\treturn input;\n}\n\nmodule.exports = function (encodedURI) {\n\tif (typeof encodedURI !== 'string') {\n\t\tthrow new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');\n\t}\n\n\ttry {\n\t\tencodedURI = encodedURI.replace(/\\+/g, ' ');\n\n\t\t// Try the built in decoder first\n\t\treturn decodeURIComponent(encodedURI);\n\t} catch (err) {\n\t\t// Fallback to a more advanced decoder\n\t\treturn customDecodeURIComponent(encodedURI);\n\t}\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/query-string/index.js\":\n/*!********************************************!*\\\n !*** ./node_modules/query-string/index.js ***!\n \\********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nconst strictUriEncode = __webpack_require__(/*! strict-uri-encode */ \"./node_modules/strict-uri-encode/index.js\");\nconst decodeComponent = __webpack_require__(/*! decode-uri-component */ \"./node_modules/decode-uri-component/index.js\");\nconst splitOnFirst = __webpack_require__(/*! split-on-first */ \"./node_modules/split-on-first/index.js\");\n\nconst isNullOrUndefined = value => value === null || value === undefined;\n\nfunction encoderForArrayFormat(options) {\n\tswitch (options.arrayFormat) {\n\t\tcase 'index':\n\t\t\treturn key => (result, value) => {\n\t\t\t\tconst index = result.length;\n\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined ||\n\t\t\t\t\t(options.skipNull && value === null) ||\n\t\t\t\t\t(options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [...result, [encode(key, options), '[', index, ']'].join('')];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[', encode(index, options), ']=', encode(value, options)].join('')\n\t\t\t\t];\n\t\t\t};\n\n\t\tcase 'bracket':\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined ||\n\t\t\t\t\t(options.skipNull && value === null) ||\n\t\t\t\t\t(options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [...result, [encode(key, options), '[]'].join('')];\n\t\t\t\t}\n\n\t\t\t\treturn [...result, [encode(key, options), '[]=', encode(value, options)].join('')];\n\t\t\t};\n\n\t\tcase 'comma':\n\t\tcase 'separator':\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (value === null || value === undefined || value.length === 0) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (result.length === 0) {\n\t\t\t\t\treturn [[encode(key, options), '=', encode(value, options)].join('')];\n\t\t\t\t}\n\n\t\t\t\treturn [[result, encode(value, options)].join(options.arrayFormatSeparator)];\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined ||\n\t\t\t\t\t(options.skipNull && value === null) ||\n\t\t\t\t\t(options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [...result, encode(key, options)];\n\t\t\t\t}\n\n\t\t\t\treturn [...result, [encode(key, options), '=', encode(value, options)].join('')];\n\t\t\t};\n\t}\n}\n\nfunction parserForArrayFormat(options) {\n\tlet result;\n\n\tswitch (options.arrayFormat) {\n\t\tcase 'index':\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /\\[(\\d*)\\]$/.exec(key);\n\n\t\t\t\tkey = key.replace(/\\[\\d*\\]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = {};\n\t\t\t\t}\n\n\t\t\t\taccumulator[key][result[1]] = value;\n\t\t\t};\n\n\t\tcase 'bracket':\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(\\[\\])$/.exec(key);\n\t\t\t\tkey = key.replace(/\\[\\]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [].concat(accumulator[key], value);\n\t\t\t};\n\n\t\tcase 'comma':\n\t\tcase 'separator':\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = typeof value === 'string' && value.split('').indexOf(options.arrayFormatSeparator) > -1;\n\t\t\t\tconst newValue = isArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : value === null ? value : decode(value, options);\n\t\t\t\taccumulator[key] = newValue;\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [].concat(accumulator[key], value);\n\t\t\t};\n\t}\n}\n\nfunction validateArrayFormatSeparator(value) {\n\tif (typeof value !== 'string' || value.length !== 1) {\n\t\tthrow new TypeError('arrayFormatSeparator must be single character string');\n\t}\n}\n\nfunction encode(value, options) {\n\tif (options.encode) {\n\t\treturn options.strict ? strictUriEncode(value) : encodeURIComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction decode(value, options) {\n\tif (options.decode) {\n\t\treturn decodeComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction keysSorter(input) {\n\tif (Array.isArray(input)) {\n\t\treturn input.sort();\n\t}\n\n\tif (typeof input === 'object') {\n\t\treturn keysSorter(Object.keys(input))\n\t\t\t.sort((a, b) => Number(a) - Number(b))\n\t\t\t.map(key => input[key]);\n\t}\n\n\treturn input;\n}\n\nfunction removeHash(input) {\n\tconst hashStart = input.indexOf('#');\n\tif (hashStart !== -1) {\n\t\tinput = input.slice(0, hashStart);\n\t}\n\n\treturn input;\n}\n\nfunction getHash(url) {\n\tlet hash = '';\n\tconst hashStart = url.indexOf('#');\n\tif (hashStart !== -1) {\n\t\thash = url.slice(hashStart);\n\t}\n\n\treturn hash;\n}\n\nfunction extract(input) {\n\tinput = removeHash(input);\n\tconst queryStart = input.indexOf('?');\n\tif (queryStart === -1) {\n\t\treturn '';\n\t}\n\n\treturn input.slice(queryStart + 1);\n}\n\nfunction parseValue(value, options) {\n\tif (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {\n\t\tvalue = Number(value);\n\t} else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {\n\t\tvalue = value.toLowerCase() === 'true';\n\t}\n\n\treturn value;\n}\n\nfunction parse(input, options) {\n\toptions = Object.assign({\n\t\tdecode: true,\n\t\tsort: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',',\n\t\tparseNumbers: false,\n\t\tparseBooleans: false\n\t}, options);\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst formatter = parserForArrayFormat(options);\n\n\t// Create an object with no prototype\n\tconst ret = Object.create(null);\n\n\tif (typeof input !== 'string') {\n\t\treturn ret;\n\t}\n\n\tinput = input.trim().replace(/^[?#&]/, '');\n\n\tif (!input) {\n\t\treturn ret;\n\t}\n\n\tfor (const param of input.split('&')) {\n\t\tlet [key, value] = splitOnFirst(options.decode ? param.replace(/\\+/g, ' ') : param, '=');\n\n\t\t// Missing `=` should be `null`:\n\t\t// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters\n\t\tvalue = value === undefined ? null : ['comma', 'separator'].includes(options.arrayFormat) ? value : decode(value, options);\n\t\tformatter(decode(key, options), value, ret);\n\t}\n\n\tfor (const key of Object.keys(ret)) {\n\t\tconst value = ret[key];\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tfor (const k of Object.keys(value)) {\n\t\t\t\tvalue[k] = parseValue(value[k], options);\n\t\t\t}\n\t\t} else {\n\t\t\tret[key] = parseValue(value, options);\n\t\t}\n\t}\n\n\tif (options.sort === false) {\n\t\treturn ret;\n\t}\n\n\treturn (options.sort === true ? Object.keys(ret).sort() : Object.keys(ret).sort(options.sort)).reduce((result, key) => {\n\t\tconst value = ret[key];\n\t\tif (Boolean(value) && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// Sort object keys, not values\n\t\t\tresult[key] = keysSorter(value);\n\t\t} else {\n\t\t\tresult[key] = value;\n\t\t}\n\n\t\treturn result;\n\t}, Object.create(null));\n}\n\nexports.extract = extract;\nexports.parse = parse;\n\nexports.stringify = (object, options) => {\n\tif (!object) {\n\t\treturn '';\n\t}\n\n\toptions = Object.assign({\n\t\tencode: true,\n\t\tstrict: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ','\n\t}, options);\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst shouldFilter = key => (\n\t\t(options.skipNull && isNullOrUndefined(object[key])) ||\n\t\t(options.skipEmptyString && object[key] === '')\n\t);\n\n\tconst formatter = encoderForArrayFormat(options);\n\n\tconst objectCopy = {};\n\n\tfor (const key of Object.keys(object)) {\n\t\tif (!shouldFilter(key)) {\n\t\t\tobjectCopy[key] = object[key];\n\t\t}\n\t}\n\n\tconst keys = Object.keys(objectCopy);\n\n\tif (options.sort !== false) {\n\t\tkeys.sort(options.sort);\n\t}\n\n\treturn keys.map(key => {\n\t\tconst value = object[key];\n\n\t\tif (value === undefined) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (value === null) {\n\t\t\treturn encode(key, options);\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\treturn value\n\t\t\t\t.reduce(formatter(key), [])\n\t\t\t\t.join('&');\n\t\t}\n\n\t\treturn encode(key, options) + '=' + encode(value, options);\n\t}).filter(x => x.length > 0).join('&');\n};\n\nexports.parseUrl = (input, options) => {\n\treturn {\n\t\turl: removeHash(input).split('?')[0] || '',\n\t\tquery: parse(extract(input), options)\n\t};\n};\n\nexports.stringifyUrl = (input, options) => {\n\tconst url = removeHash(input.url).split('?')[0] || '';\n\tconst queryFromUrl = exports.extract(input.url);\n\tconst parsedQueryFromUrl = exports.parse(queryFromUrl);\n\tconst hash = getHash(input.url);\n\tconst query = Object.assign(parsedQueryFromUrl, input.query);\n\tlet queryString = exports.stringify(query, options);\n\tif (queryString) {\n\t\tqueryString = `?${queryString}`;\n\t}\n\n\treturn `${url}${queryString}${hash}`;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/rusha/dist/rusha.js\":\n/*!******************************************!*\\\n !*** ./node_modules/rusha/dist/rusha.js ***!\n \\******************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(true)\n\t\tmodule.exports = factory();\n\telse {}\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 3);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/* eslint-env commonjs, browser */\n\nvar RushaCore = __webpack_require__(5);\n\nvar _require = __webpack_require__(1),\n toHex = _require.toHex,\n ceilHeapSize = _require.ceilHeapSize;\n\nvar conv = __webpack_require__(6);\n\n// Calculate the length of buffer that the sha1 routine uses\n// including the padding.\nvar padlen = function (len) {\n for (len += 9; len % 64 > 0; len += 1) {}\n return len;\n};\n\nvar padZeroes = function (bin, len) {\n var h8 = new Uint8Array(bin.buffer);\n var om = len % 4,\n align = len - om;\n switch (om) {\n case 0:\n h8[align + 3] = 0;\n case 1:\n h8[align + 2] = 0;\n case 2:\n h8[align + 1] = 0;\n case 3:\n h8[align + 0] = 0;\n }\n for (var i = (len >> 2) + 1; i < bin.length; i++) {\n bin[i] = 0;\n }\n};\n\nvar padData = function (bin, chunkLen, msgLen) {\n bin[chunkLen >> 2] |= 0x80 << 24 - (chunkLen % 4 << 3);\n // To support msgLen >= 2 GiB, use a float division when computing the\n // high 32-bits of the big-endian message length in bits.\n bin[((chunkLen >> 2) + 2 & ~0x0f) + 14] = msgLen / (1 << 29) | 0;\n bin[((chunkLen >> 2) + 2 & ~0x0f) + 15] = msgLen << 3;\n};\n\nvar getRawDigest = function (heap, padMaxChunkLen) {\n var io = new Int32Array(heap, padMaxChunkLen + 320, 5);\n var out = new Int32Array(5);\n var arr = new DataView(out.buffer);\n arr.setInt32(0, io[0], false);\n arr.setInt32(4, io[1], false);\n arr.setInt32(8, io[2], false);\n arr.setInt32(12, io[3], false);\n arr.setInt32(16, io[4], false);\n return out;\n};\n\nvar Rusha = function () {\n function Rusha(chunkSize) {\n _classCallCheck(this, Rusha);\n\n chunkSize = chunkSize || 64 * 1024;\n if (chunkSize % 64 > 0) {\n throw new Error('Chunk size must be a multiple of 128 bit');\n }\n this._offset = 0;\n this._maxChunkLen = chunkSize;\n this._padMaxChunkLen = padlen(chunkSize);\n // The size of the heap is the sum of:\n // 1. The padded input message size\n // 2. The extended space the algorithm needs (320 byte)\n // 3. The 160 bit state the algoritm uses\n this._heap = new ArrayBuffer(ceilHeapSize(this._padMaxChunkLen + 320 + 20));\n this._h32 = new Int32Array(this._heap);\n this._h8 = new Int8Array(this._heap);\n this._core = new RushaCore({ Int32Array: Int32Array }, {}, this._heap);\n }\n\n Rusha.prototype._initState = function _initState(heap, padMsgLen) {\n this._offset = 0;\n var io = new Int32Array(heap, padMsgLen + 320, 5);\n io[0] = 1732584193;\n io[1] = -271733879;\n io[2] = -1732584194;\n io[3] = 271733878;\n io[4] = -1009589776;\n };\n\n Rusha.prototype._padChunk = function _padChunk(chunkLen, msgLen) {\n var padChunkLen = padlen(chunkLen);\n var view = new Int32Array(this._heap, 0, padChunkLen >> 2);\n padZeroes(view, chunkLen);\n padData(view, chunkLen, msgLen);\n return padChunkLen;\n };\n\n Rusha.prototype._write = function _write(data, chunkOffset, chunkLen, off) {\n conv(data, this._h8, this._h32, chunkOffset, chunkLen, off || 0);\n };\n\n Rusha.prototype._coreCall = function _coreCall(data, chunkOffset, chunkLen, msgLen, finalize) {\n var padChunkLen = chunkLen;\n this._write(data, chunkOffset, chunkLen);\n if (finalize) {\n padChunkLen = this._padChunk(chunkLen, msgLen);\n }\n this._core.hash(padChunkLen, this._padMaxChunkLen);\n };\n\n Rusha.prototype.rawDigest = function rawDigest(str) {\n var msgLen = str.byteLength || str.length || str.size || 0;\n this._initState(this._heap, this._padMaxChunkLen);\n var chunkOffset = 0,\n chunkLen = this._maxChunkLen;\n for (chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen) {\n this._coreCall(str, chunkOffset, chunkLen, msgLen, false);\n }\n this._coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true);\n return getRawDigest(this._heap, this._padMaxChunkLen);\n };\n\n Rusha.prototype.digest = function digest(str) {\n return toHex(this.rawDigest(str).buffer);\n };\n\n Rusha.prototype.digestFromString = function digestFromString(str) {\n return this.digest(str);\n };\n\n Rusha.prototype.digestFromBuffer = function digestFromBuffer(str) {\n return this.digest(str);\n };\n\n Rusha.prototype.digestFromArrayBuffer = function digestFromArrayBuffer(str) {\n return this.digest(str);\n };\n\n Rusha.prototype.resetState = function resetState() {\n this._initState(this._heap, this._padMaxChunkLen);\n return this;\n };\n\n Rusha.prototype.append = function append(chunk) {\n var chunkOffset = 0;\n var chunkLen = chunk.byteLength || chunk.length || chunk.size || 0;\n var turnOffset = this._offset % this._maxChunkLen;\n var inputLen = void 0;\n\n this._offset += chunkLen;\n while (chunkOffset < chunkLen) {\n inputLen = Math.min(chunkLen - chunkOffset, this._maxChunkLen - turnOffset);\n this._write(chunk, chunkOffset, inputLen, turnOffset);\n turnOffset += inputLen;\n chunkOffset += inputLen;\n if (turnOffset === this._maxChunkLen) {\n this._core.hash(this._maxChunkLen, this._padMaxChunkLen);\n turnOffset = 0;\n }\n }\n return this;\n };\n\n Rusha.prototype.getState = function getState() {\n var turnOffset = this._offset % this._maxChunkLen;\n var heap = void 0;\n if (!turnOffset) {\n var io = new Int32Array(this._heap, this._padMaxChunkLen + 320, 5);\n heap = io.buffer.slice(io.byteOffset, io.byteOffset + io.byteLength);\n } else {\n heap = this._heap.slice(0);\n }\n return {\n offset: this._offset,\n heap: heap\n };\n };\n\n Rusha.prototype.setState = function setState(state) {\n this._offset = state.offset;\n if (state.heap.byteLength === 20) {\n var io = new Int32Array(this._heap, this._padMaxChunkLen + 320, 5);\n io.set(new Int32Array(state.heap));\n } else {\n this._h32.set(new Int32Array(state.heap));\n }\n return this;\n };\n\n Rusha.prototype.rawEnd = function rawEnd() {\n var msgLen = this._offset;\n var chunkLen = msgLen % this._maxChunkLen;\n var padChunkLen = this._padChunk(chunkLen, msgLen);\n this._core.hash(padChunkLen, this._padMaxChunkLen);\n var result = getRawDigest(this._heap, this._padMaxChunkLen);\n this._initState(this._heap, this._padMaxChunkLen);\n return result;\n };\n\n Rusha.prototype.end = function end() {\n return toHex(this.rawEnd().buffer);\n };\n\n return Rusha;\n}();\n\nmodule.exports = Rusha;\nmodule.exports._core = RushaCore;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n/* eslint-env commonjs, browser */\n\n//\n// toHex\n//\n\nvar precomputedHex = new Array(256);\nfor (var i = 0; i < 256; i++) {\n precomputedHex[i] = (i < 0x10 ? '0' : '') + i.toString(16);\n}\n\nmodule.exports.toHex = function (arrayBuffer) {\n var binarray = new Uint8Array(arrayBuffer);\n var res = new Array(arrayBuffer.byteLength);\n for (var _i = 0; _i < res.length; _i++) {\n res[_i] = precomputedHex[binarray[_i]];\n }\n return res.join('');\n};\n\n//\n// ceilHeapSize\n//\n\nmodule.exports.ceilHeapSize = function (v) {\n // The asm.js spec says:\n // The heap object's byteLength must be either\n // 2^n for n in [12, 24) or 2^24 * n for n ≥ 1.\n // Also, byteLengths smaller than 2^16 are deprecated.\n var p = 0;\n // If v is smaller than 2^16, the smallest possible solution\n // is 2^16.\n if (v <= 65536) return 65536;\n // If v < 2^24, we round up to 2^n,\n // otherwise we round up to 2^24 * n.\n if (v < 16777216) {\n for (p = 1; p < v; p = p << 1) {}\n } else {\n for (p = 16777216; p < v; p += 16777216) {}\n }\n return p;\n};\n\n//\n// isDedicatedWorkerScope\n//\n\nmodule.exports.isDedicatedWorkerScope = function (self) {\n var isRunningInWorker = 'WorkerGlobalScope' in self && self instanceof self.WorkerGlobalScope;\n var isRunningInSharedWorker = 'SharedWorkerGlobalScope' in self && self instanceof self.SharedWorkerGlobalScope;\n var isRunningInServiceWorker = 'ServiceWorkerGlobalScope' in self && self instanceof self.ServiceWorkerGlobalScope;\n\n // Detects whether we run inside a dedicated worker or not.\n //\n // We can't just check for `DedicatedWorkerGlobalScope`, since IE11\n // has a bug where it only supports `WorkerGlobalScope`.\n //\n // Therefore, we consider us as running inside a dedicated worker\n // when we are running inside a worker, but not in a shared or service worker.\n //\n // When new types of workers are introduced, we will need to adjust this code.\n return isRunningInWorker && !isRunningInSharedWorker && !isRunningInServiceWorker;\n};\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* eslint-env commonjs, worker */\n\nmodule.exports = function () {\n var Rusha = __webpack_require__(0);\n\n var hashData = function (hasher, data, cb) {\n try {\n return cb(null, hasher.digest(data));\n } catch (e) {\n return cb(e);\n }\n };\n\n var hashFile = function (hasher, readTotal, blockSize, file, cb) {\n var reader = new self.FileReader();\n reader.onloadend = function onloadend() {\n if (reader.error) {\n return cb(reader.error);\n }\n var buffer = reader.result;\n readTotal += reader.result.byteLength;\n try {\n hasher.append(buffer);\n } catch (e) {\n cb(e);\n return;\n }\n if (readTotal < file.size) {\n hashFile(hasher, readTotal, blockSize, file, cb);\n } else {\n cb(null, hasher.end());\n }\n };\n reader.readAsArrayBuffer(file.slice(readTotal, readTotal + blockSize));\n };\n\n var workerBehaviourEnabled = true;\n\n self.onmessage = function (event) {\n if (!workerBehaviourEnabled) {\n return;\n }\n\n var data = event.data.data,\n file = event.data.file,\n id = event.data.id;\n if (typeof id === 'undefined') return;\n if (!file && !data) return;\n var blockSize = event.data.blockSize || 4 * 1024 * 1024;\n var hasher = new Rusha(blockSize);\n hasher.resetState();\n var done = function (err, hash) {\n if (!err) {\n self.postMessage({ id: id, hash: hash });\n } else {\n self.postMessage({ id: id, error: err.name });\n }\n };\n if (data) hashData(hasher, data, done);\n if (file) hashFile(hasher, 0, blockSize, file, done);\n };\n\n return function () {\n workerBehaviourEnabled = false;\n };\n};\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* eslint-env commonjs, browser */\n\nvar work = __webpack_require__(4);\nvar Rusha = __webpack_require__(0);\nvar createHash = __webpack_require__(7);\nvar runWorker = __webpack_require__(2);\n\nvar _require = __webpack_require__(1),\n isDedicatedWorkerScope = _require.isDedicatedWorkerScope;\n\nvar isRunningInDedicatedWorker = typeof self !== 'undefined' && isDedicatedWorkerScope(self);\n\nRusha.disableWorkerBehaviour = isRunningInDedicatedWorker ? runWorker() : function () {};\n\nRusha.createWorker = function () {\n var worker = work(/*require.resolve*/(2));\n var terminate = worker.terminate;\n worker.terminate = function () {\n URL.revokeObjectURL(worker.objectURL);\n terminate.call(worker);\n };\n return worker;\n};\n\nRusha.createHash = createHash;\n\nmodule.exports = Rusha;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\nfunction webpackBootstrapFunc (modules) {\n/******/ // The module cache\n/******/ var installedModules = {};\n\n/******/ // The require function\n/******/ function __webpack_require__(moduleId) {\n\n/******/ // Check if module is in cache\n/******/ if(installedModules[moduleId])\n/******/ return installedModules[moduleId].exports;\n\n/******/ // Create a new module (and put it into the cache)\n/******/ var module = installedModules[moduleId] = {\n/******/ i: moduleId,\n/******/ l: false,\n/******/ exports: {}\n/******/ };\n\n/******/ // Execute the module function\n/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n/******/ // Flag the module as loaded\n/******/ module.l = true;\n\n/******/ // Return the exports of the module\n/******/ return module.exports;\n/******/ }\n\n/******/ // expose the modules object (__webpack_modules__)\n/******/ __webpack_require__.m = modules;\n\n/******/ // expose the module cache\n/******/ __webpack_require__.c = installedModules;\n\n/******/ // identity function for calling harmony imports with the correct context\n/******/ __webpack_require__.i = function(value) { return value; };\n\n/******/ // define getter function for harmony exports\n/******/ __webpack_require__.d = function(exports, name, getter) {\n/******/ if(!__webpack_require__.o(exports, name)) {\n/******/ Object.defineProperty(exports, name, {\n/******/ configurable: false,\n/******/ enumerable: true,\n/******/ get: getter\n/******/ });\n/******/ }\n/******/ };\n\n/******/ // define __esModule on exports\n/******/ __webpack_require__.r = function(exports) {\n/******/ Object.defineProperty(exports, '__esModule', { value: true });\n/******/ };\n\n/******/ // getDefaultExport function for compatibility with non-harmony modules\n/******/ __webpack_require__.n = function(module) {\n/******/ var getter = module && module.__esModule ?\n/******/ function getDefault() { return module['default']; } :\n/******/ function getModuleExports() { return module; };\n/******/ __webpack_require__.d(getter, 'a', getter);\n/******/ return getter;\n/******/ };\n\n/******/ // Object.prototype.hasOwnProperty.call\n/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n/******/ // __webpack_public_path__\n/******/ __webpack_require__.p = \"/\";\n\n/******/ // on error function for async loading\n/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n var f = __webpack_require__(__webpack_require__.s = ENTRY_MODULE)\n return f.default || f // try to call default if defined to also support babel esmodule exports\n}\n\nvar moduleNameReqExp = '[\\\\.|\\\\-|\\\\+|\\\\w|\\/|@]+'\nvar dependencyRegExp = '\\\\((\\/\\\\*.*?\\\\*\\/)?\\s?.*?(' + moduleNameReqExp + ').*?\\\\)' // additional chars when output.pathinfo is true\n\n// http://stackoverflow.com/a/2593661/130442\nfunction quoteRegExp (str) {\n return (str + '').replace(/[.?*+^$[\\]\\\\(){}|-]/g, '\\\\$&')\n}\n\nfunction getModuleDependencies (sources, module, queueName) {\n var retval = {}\n retval[queueName] = []\n\n var fnString = module.toString()\n var wrapperSignature = fnString.match(/^function\\s?\\(\\w+,\\s*\\w+,\\s*(\\w+)\\)/)\n if (!wrapperSignature) return retval\n var webpackRequireName = wrapperSignature[1]\n\n // main bundle deps\n var re = new RegExp('(\\\\\\\\n|\\\\W)' + quoteRegExp(webpackRequireName) + dependencyRegExp, 'g')\n var match\n while ((match = re.exec(fnString))) {\n if (match[3] === 'dll-reference') continue\n retval[queueName].push(match[3])\n }\n\n // dll deps\n re = new RegExp('\\\\(' + quoteRegExp(webpackRequireName) + '\\\\(\"(dll-reference\\\\s(' + moduleNameReqExp + '))\"\\\\)\\\\)' + dependencyRegExp, 'g')\n while ((match = re.exec(fnString))) {\n if (!sources[match[2]]) {\n retval[queueName].push(match[1])\n sources[match[2]] = __webpack_require__(match[1]).m\n }\n retval[match[2]] = retval[match[2]] || []\n retval[match[2]].push(match[4])\n }\n\n return retval\n}\n\nfunction hasValuesInQueues (queues) {\n var keys = Object.keys(queues)\n return keys.reduce(function (hasValues, key) {\n return hasValues || queues[key].length > 0\n }, false)\n}\n\nfunction getRequiredModules (sources, moduleId) {\n var modulesQueue = {\n main: [moduleId]\n }\n var requiredModules = {\n main: []\n }\n var seenModules = {\n main: {}\n }\n\n while (hasValuesInQueues(modulesQueue)) {\n var queues = Object.keys(modulesQueue)\n for (var i = 0; i < queues.length; i++) {\n var queueName = queues[i]\n var queue = modulesQueue[queueName]\n var moduleToCheck = queue.pop()\n seenModules[queueName] = seenModules[queueName] || {}\n if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue\n seenModules[queueName][moduleToCheck] = true\n requiredModules[queueName] = requiredModules[queueName] || []\n requiredModules[queueName].push(moduleToCheck)\n var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName)\n var newModulesKeys = Object.keys(newModules)\n for (var j = 0; j < newModulesKeys.length; j++) {\n modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || []\n modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]])\n }\n }\n }\n\n return requiredModules\n}\n\nmodule.exports = function (moduleId, options) {\n options = options || {}\n var sources = {\n main: __webpack_require__.m\n }\n\n var requiredModules = options.all ? { main: Object.keys(sources) } : getRequiredModules(sources, moduleId)\n\n var src = ''\n\n Object.keys(requiredModules).filter(function (m) { return m !== 'main' }).forEach(function (module) {\n var entryModule = 0\n while (requiredModules[module][entryModule]) {\n entryModule++\n }\n requiredModules[module].push(entryModule)\n sources[module][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })'\n src = src + 'var ' + module + ' = (' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(entryModule)) + ')({' + requiredModules[module].map(function (id) { return '' + JSON.stringify(id) + ': ' + sources[module][id].toString() }).join(',') + '});\\n'\n })\n\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);'\n\n var blob = new window.Blob([src], { type: 'text/javascript' })\n if (options.bare) { return blob }\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL\n\n var workerUrl = URL.createObjectURL(blob)\n var worker = new window.Worker(workerUrl)\n worker.objectURL = workerUrl\n\n return worker\n}\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n// The low-level RushCore module provides the heart of Rusha,\n// a high-speed sha1 implementation working on an Int32Array heap.\n// At first glance, the implementation seems complicated, however\n// with the SHA1 spec at hand, it is obvious this almost a textbook\n// implementation that has a few functions hand-inlined and a few loops\n// hand-unrolled.\nmodule.exports = function RushaCore(stdlib$846, foreign$847, heap$848) {\n 'use asm';\n var H$849 = new stdlib$846.Int32Array(heap$848);\n function hash$850(k$851, x$852) {\n // k in bytes\n k$851 = k$851 | 0;\n x$852 = x$852 | 0;\n var i$853 = 0, j$854 = 0, y0$855 = 0, z0$856 = 0, y1$857 = 0, z1$858 = 0, y2$859 = 0, z2$860 = 0, y3$861 = 0, z3$862 = 0, y4$863 = 0, z4$864 = 0, t0$865 = 0, t1$866 = 0;\n y0$855 = H$849[x$852 + 320 >> 2] | 0;\n y1$857 = H$849[x$852 + 324 >> 2] | 0;\n y2$859 = H$849[x$852 + 328 >> 2] | 0;\n y3$861 = H$849[x$852 + 332 >> 2] | 0;\n y4$863 = H$849[x$852 + 336 >> 2] | 0;\n for (i$853 = 0; (i$853 | 0) < (k$851 | 0); i$853 = i$853 + 64 | 0) {\n z0$856 = y0$855;\n z1$858 = y1$857;\n z2$860 = y2$859;\n z3$862 = y3$861;\n z4$864 = y4$863;\n for (j$854 = 0; (j$854 | 0) < 64; j$854 = j$854 + 4 | 0) {\n t1$866 = H$849[i$853 + j$854 >> 2] | 0;\n t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | ~y1$857 & y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1518500249 | 0) | 0;\n y4$863 = y3$861;\n y3$861 = y2$859;\n y2$859 = y1$857 << 30 | y1$857 >>> 2;\n y1$857 = y0$855;\n y0$855 = t0$865;\n H$849[k$851 + j$854 >> 2] = t1$866;\n }\n for (j$854 = k$851 + 64 | 0; (j$854 | 0) < (k$851 + 80 | 0); j$854 = j$854 + 4 | 0) {\n t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31;\n t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | ~y1$857 & y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1518500249 | 0) | 0;\n y4$863 = y3$861;\n y3$861 = y2$859;\n y2$859 = y1$857 << 30 | y1$857 >>> 2;\n y1$857 = y0$855;\n y0$855 = t0$865;\n H$849[j$854 >> 2] = t1$866;\n }\n for (j$854 = k$851 + 80 | 0; (j$854 | 0) < (k$851 + 160 | 0); j$854 = j$854 + 4 | 0) {\n t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31;\n t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 ^ y2$859 ^ y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1859775393 | 0) | 0;\n y4$863 = y3$861;\n y3$861 = y2$859;\n y2$859 = y1$857 << 30 | y1$857 >>> 2;\n y1$857 = y0$855;\n y0$855 = t0$865;\n H$849[j$854 >> 2] = t1$866;\n }\n for (j$854 = k$851 + 160 | 0; (j$854 | 0) < (k$851 + 240 | 0); j$854 = j$854 + 4 | 0) {\n t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31;\n t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | y1$857 & y3$861 | y2$859 & y3$861) | 0) + ((t1$866 + y4$863 | 0) - 1894007588 | 0) | 0;\n y4$863 = y3$861;\n y3$861 = y2$859;\n y2$859 = y1$857 << 30 | y1$857 >>> 2;\n y1$857 = y0$855;\n y0$855 = t0$865;\n H$849[j$854 >> 2] = t1$866;\n }\n for (j$854 = k$851 + 240 | 0; (j$854 | 0) < (k$851 + 320 | 0); j$854 = j$854 + 4 | 0) {\n t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31;\n t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 ^ y2$859 ^ y3$861) | 0) + ((t1$866 + y4$863 | 0) - 899497514 | 0) | 0;\n y4$863 = y3$861;\n y3$861 = y2$859;\n y2$859 = y1$857 << 30 | y1$857 >>> 2;\n y1$857 = y0$855;\n y0$855 = t0$865;\n H$849[j$854 >> 2] = t1$866;\n }\n y0$855 = y0$855 + z0$856 | 0;\n y1$857 = y1$857 + z1$858 | 0;\n y2$859 = y2$859 + z2$860 | 0;\n y3$861 = y3$861 + z3$862 | 0;\n y4$863 = y4$863 + z4$864 | 0;\n }\n H$849[x$852 + 320 >> 2] = y0$855;\n H$849[x$852 + 324 >> 2] = y1$857;\n H$849[x$852 + 328 >> 2] = y2$859;\n H$849[x$852 + 332 >> 2] = y3$861;\n H$849[x$852 + 336 >> 2] = y4$863;\n }\n return { hash: hash$850 };\n};\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\nvar _this = this;\n\n/* eslint-env commonjs, browser */\n\nvar reader = void 0;\nif (typeof self !== 'undefined' && typeof self.FileReaderSync !== 'undefined') {\n reader = new self.FileReaderSync();\n}\n\n// Convert a binary string and write it to the heap.\n// A binary string is expected to only contain char codes < 256.\nvar convStr = function (str, H8, H32, start, len, off) {\n var i = void 0,\n om = off % 4,\n lm = (len + om) % 4,\n j = len - lm;\n switch (om) {\n case 0:\n H8[off] = str.charCodeAt(start + 3);\n case 1:\n H8[off + 1 - (om << 1) | 0] = str.charCodeAt(start + 2);\n case 2:\n H8[off + 2 - (om << 1) | 0] = str.charCodeAt(start + 1);\n case 3:\n H8[off + 3 - (om << 1) | 0] = str.charCodeAt(start);\n }\n if (len < lm + (4 - om)) {\n return;\n }\n for (i = 4 - om; i < j; i = i + 4 | 0) {\n 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);\n }\n switch (lm) {\n case 3:\n H8[off + j + 1 | 0] = str.charCodeAt(start + j + 2);\n case 2:\n H8[off + j + 2 | 0] = str.charCodeAt(start + j + 1);\n case 1:\n H8[off + j + 3 | 0] = str.charCodeAt(start + j);\n }\n};\n\n// Convert a buffer or array and write it to the heap.\n// The buffer or array is expected to only contain elements < 256.\nvar convBuf = function (buf, H8, H32, start, len, off) {\n var i = void 0,\n om = off % 4,\n lm = (len + om) % 4,\n j = len - lm;\n switch (om) {\n case 0:\n H8[off] = buf[start + 3];\n case 1:\n H8[off + 1 - (om << 1) | 0] = buf[start + 2];\n case 2:\n H8[off + 2 - (om << 1) | 0] = buf[start + 1];\n case 3:\n H8[off + 3 - (om << 1) | 0] = buf[start];\n }\n if (len < lm + (4 - om)) {\n return;\n }\n for (i = 4 - om; i < j; i = i + 4 | 0) {\n H32[off + i >> 2 | 0] = buf[start + i] << 24 | buf[start + i + 1] << 16 | buf[start + i + 2] << 8 | buf[start + i + 3];\n }\n switch (lm) {\n case 3:\n H8[off + j + 1 | 0] = buf[start + j + 2];\n case 2:\n H8[off + j + 2 | 0] = buf[start + j + 1];\n case 1:\n H8[off + j + 3 | 0] = buf[start + j];\n }\n};\n\nvar convBlob = function (blob, H8, H32, start, len, off) {\n var i = void 0,\n om = off % 4,\n lm = (len + om) % 4,\n j = len - lm;\n var buf = new Uint8Array(reader.readAsArrayBuffer(blob.slice(start, start + len)));\n switch (om) {\n case 0:\n H8[off] = buf[3];\n case 1:\n H8[off + 1 - (om << 1) | 0] = buf[2];\n case 2:\n H8[off + 2 - (om << 1) | 0] = buf[1];\n case 3:\n H8[off + 3 - (om << 1) | 0] = buf[0];\n }\n if (len < lm + (4 - om)) {\n return;\n }\n for (i = 4 - om; i < j; i = i + 4 | 0) {\n H32[off + i >> 2 | 0] = buf[i] << 24 | buf[i + 1] << 16 | buf[i + 2] << 8 | buf[i + 3];\n }\n switch (lm) {\n case 3:\n H8[off + j + 1 | 0] = buf[j + 2];\n case 2:\n H8[off + j + 2 | 0] = buf[j + 1];\n case 1:\n H8[off + j + 3 | 0] = buf[j];\n }\n};\n\nmodule.exports = function (data, H8, H32, start, len, off) {\n if (typeof data === 'string') {\n return convStr(data, H8, H32, start, len, off);\n }\n if (data instanceof Array) {\n return convBuf(data, H8, H32, start, len, off);\n }\n // Safely doing a Buffer check using \"this\" to avoid Buffer polyfill to be included in the dist\n if (_this && _this.Buffer && _this.Buffer.isBuffer(data)) {\n return convBuf(data, H8, H32, start, len, off);\n }\n if (data instanceof ArrayBuffer) {\n return convBuf(new Uint8Array(data), H8, H32, start, len, off);\n }\n if (data.buffer instanceof ArrayBuffer) {\n return convBuf(new Uint8Array(data.buffer, data.byteOffset, data.byteLength), H8, H32, start, len, off);\n }\n if (data instanceof Blob) {\n return convBlob(data, H8, H32, start, len, off);\n }\n throw new Error('Unsupported data type.');\n};\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/* eslint-env commonjs, browser */\n\nvar Rusha = __webpack_require__(0);\n\nvar _require = __webpack_require__(1),\n toHex = _require.toHex;\n\nvar Hash = function () {\n function Hash() {\n _classCallCheck(this, Hash);\n\n this._rusha = new Rusha();\n this._rusha.resetState();\n }\n\n Hash.prototype.update = function update(data) {\n this._rusha.append(data);\n return this;\n };\n\n Hash.prototype.digest = function digest(encoding) {\n var digest = this._rusha.rawEnd().buffer;\n if (!encoding) {\n return digest;\n }\n if (encoding === 'hex') {\n return toHex(digest);\n }\n throw new Error('unsupported digest encoding');\n };\n\n return Hash;\n}();\n\nmodule.exports = function () {\n return new Hash();\n};\n\n/***/ })\n/******/ ]);\n});\n\n/***/ }),\n\n/***/ \"./node_modules/split-on-first/index.js\":\n/*!**********************************************!*\\\n !*** ./node_modules/split-on-first/index.js ***!\n \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = (string, separator) => {\n\tif (!(typeof string === 'string' && typeof separator === 'string')) {\n\t\tthrow new TypeError('Expected the arguments to be of type `string`');\n\t}\n\n\tif (separator === '') {\n\t\treturn [string];\n\t}\n\n\tconst separatorIndex = string.indexOf(separator);\n\n\tif (separatorIndex === -1) {\n\t\treturn [string];\n\t}\n\n\treturn [\n\t\tstring.slice(0, separatorIndex),\n\t\tstring.slice(separatorIndex + separator.length)\n\t];\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/strict-uri-encode/index.js\":\n/*!*************************************************!*\\\n !*** ./node_modules/strict-uri-encode/index.js ***!\n \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nmodule.exports = str => encodeURIComponent(str).replace(/[!'()*]/g, x => `%${x.charCodeAt(0).toString(16).toUpperCase()}`);\n\n\n/***/ }),\n\n/***/ \"./node_modules/webpack-strip-block/index.js?!./src/js/webworkers/compression.worker.js\":\n/*!**********************************************************************************************!*\\\n !*** ./node_modules/webpack-strip-block??ref--7-0!./src/js/webworkers/compression.worker.js ***!\n \\**********************************************************************************************/\n/*! no exports provided */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _core_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core/config */ \"./src/js/core/config.js\");\n/* harmony import */ var _core_lzstring__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/lzstring */ \"./src/js/core/lzstring.js\");\n/* harmony import */ var _core_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core/sensitive_utils.encrypt */ \"./src/js/core/sensitive_utils.encrypt.js\");\n/* harmony import */ var _savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../savegame/savegame_compressor */ \"./src/js/savegame/savegame_compressor.js\");\n\r\n\r\n\r\n\r\n\r\nfunction accessNestedPropertyReverse(obj, keys) {\r\n let result = obj;\r\n for (let i = keys.length - 1; i >= 0; --i) {\r\n result = result[keys[i]];\r\n }\r\n return result;\r\n}\r\n\r\nconst salt = accessNestedPropertyReverse(_core_config__WEBPACK_IMPORTED_MODULE_0__[\"globalConfig\"], [\"file\", \"info\"]);\r\n\r\nself.addEventListener(\"message\", event => {\r\n // @ts-ignore\r\n const { jobId, job, data } = event.data;\r\n const result = performJob(job, data);\r\n\r\n // @ts-ignore\r\n self.postMessage({ jobId, result });\r\n});\r\n\r\nfunction performJob(job, data) {\r\n switch (job) {\r\n case \"compressX64\": {\r\n return Object(_core_lzstring__WEBPACK_IMPORTED_MODULE_1__[\"compressX64\"])(data);\r\n }\r\n\r\n case \"compressObject\": {\r\n const optimized = Object(_savegame_savegame_compressor__WEBPACK_IMPORTED_MODULE_3__[\"compressObject\"])(data.obj);\r\n const stringified = JSON.stringify(optimized);\r\n\r\n const checksum = Object(_core_sensitive_utils_encrypt__WEBPACK_IMPORTED_MODULE_2__[\"computeCrc\"])(stringified + salt);\r\n return data.compressionPrefix + Object(_core_lzstring__WEBPACK_IMPORTED_MODULE_1__[\"compressX64\"])(checksum + stringified);\r\n }\r\n default:\r\n throw new Error(\"Webworker: Unknown job: \" + job);\r\n }\r\n}\r\n\n\n/***/ }),\n\n/***/ \"./src/js/core/config.js\":\n/*!*******************************!*\\\n !*** ./src/js/core/config.js ***!\n \\*******************************/\n/*! exports provided: IS_DEBUG, IS_DEMO, SUPPORT_TOUCH, THIRDPARTY_URLS, globalConfig, IS_MOBILE */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"IS_DEBUG\", function() { return IS_DEBUG; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"IS_DEMO\", function() { return IS_DEMO; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"SUPPORT_TOUCH\", function() { return SUPPORT_TOUCH; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"THIRDPARTY_URLS\", function() { return THIRDPARTY_URLS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"globalConfig\", function() { return globalConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"IS_MOBILE\", function() { return IS_MOBILE; });\n/* harmony import */ var _query_parameters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./query_parameters */ \"./src/js/core/query_parameters.js\");\n\r\n\r\nconst IS_DEBUG =\r\n true ||\r\n (false);\r\n\r\nconst IS_DEMO =\r\n true\r\n ? false\r\n : undefined;\r\n\r\nconst SUPPORT_TOUCH = false;\r\n\r\nconst smoothCanvas = true;\r\n\r\nconst THIRDPARTY_URLS = {\r\n discord: \"https://discord.gg/HN7EVzV\",\r\n github: \"https://github.com/tobspr/shapez.io\",\r\n reddit: \"https://www.reddit.com/r/shapezio\",\r\n\r\n standaloneStorePage: \"https://store.steampowered.com/app/1318690/shapezio/\",\r\n};\r\n\r\nconst globalConfig = {\r\n // Size of a single tile in Pixels.\r\n // NOTICE: Update webpack.production.config too!\r\n tileSize: 32,\r\n halfTileSize: 16,\r\n\r\n // Which dpi the assets have\r\n assetsDpi: 192 / 32,\r\n assetsSharpness: 1.5,\r\n shapesSharpness: 1.4,\r\n\r\n // Production analytics\r\n statisticsGraphDpi: 2.5,\r\n statisticsGraphSlices: 100,\r\n analyticsSliceDurationSeconds: true ? 1 : undefined,\r\n\r\n minimumTickRate: 25,\r\n maximumTickRate: 500,\r\n\r\n // Map\r\n mapChunkSize: 16,\r\n mapChunkOverviewMinZoom: 0.9,\r\n mapChunkWorldSize: null, // COMPUTED\r\n\r\n // Belt speeds\r\n // NOTICE: Update webpack.production.config too!\r\n beltSpeedItemsPerSecond: 2,\r\n minerSpeedItemsPerSecond: 0, // COMPUTED\r\n\r\n defaultItemDiameter: 20,\r\n\r\n itemSpacingOnBelts: 0.63,\r\n\r\n wiresSpeedItemsPerSecond: 6,\r\n\r\n undergroundBeltMaxTilesByTier: [5, 8],\r\n\r\n buildingSpeeds: {\r\n cutter: 1 / 4,\r\n cutterQuad: 1 / 4,\r\n rotater: 1 / 1,\r\n rotaterCCW: 1 / 1,\r\n rotaterFL: 1 / 1,\r\n painter: 1 / 6,\r\n painterDouble: 1 / 8,\r\n painterQuad: 1 / 8,\r\n mixer: 1 / 5,\r\n stacker: 1 / 6,\r\n advancedProcessor: 1 / 3,\r\n filter: 1,\r\n },\r\n\r\n // Zooming\r\n initialZoom: 1.9,\r\n minZoomLevel: 0.1,\r\n maxZoomLevel: 3,\r\n\r\n // Global game speed\r\n gameSpeed: 1,\r\n\r\n warmupTimeSecondsFast: 0.1,\r\n warmupTimeSecondsRegular: 1,\r\n\r\n smoothing: {\r\n smoothMainCanvas: smoothCanvas && true,\r\n quality: \"low\", // Low is CRUCIAL for mobile performance!\r\n },\r\n\r\n rendering: {},\r\n debug: IS_DEBUG ? __webpack_require__(/*! ./config.local */ \"./src/js/core/config.local.js\").default : {},\r\n\r\n // Secret vars\r\n info: {\r\n // Binary file salt\r\n file: \"Ec'])@^+*9zMevK3uMV4432x9%iK'=\",\r\n\r\n // Savegame salt\r\n sgSalt: \"}95Q3%8/.837Lqym_BJx%q7)pAHJbF\",\r\n\r\n // Analytics key\r\n analyticsApiKey: \"baf6a50f0cc7dfdec5a0e21c88a1c69a4b34bc4a\",\r\n },\r\n};\r\n\r\nconst IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\r\n\r\n// Automatic calculations\r\nglobalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;\r\n\r\nglobalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;\r\n\r\n// Dynamic calculations\r\nif (globalConfig.debug.disableMapOverview) {\r\n globalConfig.mapChunkOverviewMinZoom = 0;\r\n}\r\n\r\n// Stuff for making the trailer\r\nif (globalConfig.debug.renderForTrailer) {\r\n globalConfig.debug.framePausesBetweenTicks = 32;\r\n // globalConfig.mapChunkOverviewMinZoom = 0.0;\r\n // globalConfig.debug.instantBelts = true;\r\n // globalConfig.debug.instantProcessors = true;\r\n // globalConfig.debug.instantMiners = true;\r\n globalConfig.debug.disableSavegameWrite = true;\r\n // globalConfig.beltSpeedItemsPerSecond *= 2;\r\n}\r\n\r\nif (globalConfig.debug.fastGameEnter) {\r\n globalConfig.debug.noArtificalDelays = true;\r\n}\r\n\n\n/***/ }),\n\n/***/ \"./src/js/core/config.local.js\":\n/*!*************************************!*\\\n !*** ./src/js/core/config.local.js ***!\n \\*************************************/\n/*! exports provided: default */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\r\n // You can set any debug options here!\r\n /* ---dev:start */\r\n // -----------------------------------------------------------------------------------\r\n _fastGameEnter: \"Quickly enters the game and skips the main menu - good for fast iterating\",\r\n fastGameEnter: false,\r\n // -----------------------------------------------------------------------------------\r\n _noArtificialDelays: \"Skips any delays like transitions between states and such\",\r\n noArtificialDelays: false,\r\n // -----------------------------------------------------------------------------------\r\n _disableSavegameWrite:\r\n \"Disables writing of savegames, useful for testing the same savegame over and over\",\r\n disableSavegameWrite: false,\r\n // -----------------------------------------------------------------------------------\r\n _showEntityBounds: \"Shows bounds of all entities\",\r\n showEntityBounds: false,\r\n // -----------------------------------------------------------------------------------\r\n _showAcceptorEjectors: \"Shows arrows for every ejector / acceptor\",\r\n showAcceptorEjectors: false,\r\n // -----------------------------------------------------------------------------------\r\n _disableMusic: \"Disables the music (Overrides any setting, can cause weird behaviour)\",\r\n disableMusic: false,\r\n // -----------------------------------------------------------------------------------\r\n _doNotRenderStatics: \"Do not render static map entities (=most buildings)\",\r\n doNotRenderStatics: false,\r\n // -----------------------------------------------------------------------------------\r\n _disableZoomLimits: \"Allow to zoom freely without limits\",\r\n disableZoomLimits: false,\r\n // -----------------------------------------------------------------------------------\r\n _showChunkBorders: \"Shows a border arround every chunk\",\r\n showChunkBorders: false,\r\n // -----------------------------------------------------------------------------------\r\n _rewardsInstant: \"All rewards can be unlocked by passing just 1 of any shape\",\r\n rewardsInstant: false,\r\n // -----------------------------------------------------------------------------------\r\n _allBuildingsUnlocked: \"Unlocks all buildings\",\r\n allBuildingsUnlocked: false,\r\n // -----------------------------------------------------------------------------------\r\n _blueprintsNoCost: \"Disables cost of blueprints\",\r\n blueprintsNoCost: false,\r\n // -----------------------------------------------------------------------------------\r\n _upgradesNoCost: \"Disables cost of upgrades\",\r\n upgradesNoCost: false,\r\n // -----------------------------------------------------------------------------------\r\n _disableUnlockDialog: \"Disables the dialog when completing a level\",\r\n disableUnlockDialog: false,\r\n // -----------------------------------------------------------------------------------\r\n _disableLogicTicks: \"Disables the simulation - This effectively pauses the game.\",\r\n disableLogicTicks: false,\r\n // -----------------------------------------------------------------------------------\r\n _testClipping: \"Test the rendering if everything is clipped out properly\",\r\n testClipping: false,\r\n // -----------------------------------------------------------------------------------\r\n // Allows to render slower, useful for recording at half speed to avoid stuttering\r\n // framePausesBetweenTicks: 1,\r\n // -----------------------------------------------------------------------------------\r\n _testTranslations: \"Replace all translations with emojis to see which texts are translateable\",\r\n testTranslations: false,\r\n // -----------------------------------------------------------------------------------\r\n _enableEntityInspector: \"Enables an inspector which shows information about the entity below the curosr\",\r\n enableEntityInspector: false,\r\n // -----------------------------------------------------------------------------------\r\n _testAds: \"Enables ads in the local build (normally they are deactivated there)\",\r\n testAds: false,\r\n // -----------------------------------------------------------------------------------\r\n _noApiCalls: \"Disables API calls\",\r\n noApiCalls: true,\r\n // -----------------------------------------------------------------------------------\r\n _disableMapOverview: \"Disables the automatic switch to an overview when zooming out\",\r\n disableMapOverview: false,\r\n // -----------------------------------------------------------------------------------\r\n _disableUpgradeNotification:\r\n \"Disables the notification when there are new entries in the changelog since last played\",\r\n disableUpgradeNotification: false,\r\n // -----------------------------------------------------------------------------------\r\n _instantBelts: \"Makes belts almost infinitely fast\",\r\n instantBelts: false,\r\n // -----------------------------------------------------------------------------------\r\n _instantProcessors: \"Makes item processors almost infinitely fast\",\r\n instantProcessors: false,\r\n // -----------------------------------------------------------------------------------\r\n _instantMiners: \"Makes miners almost infinitely fast\",\r\n instantMiners: false,\r\n // -----------------------------------------------------------------------------------\r\n _resumeGameOnFastEnter:\r\n \"When using fastGameEnter, controls whether a new game is started or the last one is resumed\",\r\n resumeGameOnFastEnter: false,\r\n // -----------------------------------------------------------------------------------\r\n _renderForTrailer: \"Special option used to render the trailer\",\r\n renderForTrailer: false,\r\n // -----------------------------------------------------------------------------------\r\n _renderChanges: \"Whether to render changes\",\r\n renderChanges: false,\r\n // -----------------------------------------------------------------------------------\r\n _renderBeltPaths: \"Whether to render belt paths\",\r\n renderBeltPaths: false,\r\n // -----------------------------------------------------------------------------------\r\n _checkBeltPaths: \"Whether to check belt paths\",\r\n checkBeltPaths: false,\r\n // -----------------------------------------------------------------------------------\r\n _showAtlasInfo: \"Shows detailed information about which atlas is used\",\r\n showAtlasInfo: false,\r\n // -----------------------------------------------------------------------------------\r\n _renderWireRotations: \"Renders the rotation of all wires\",\r\n renderWireRotations: false,\r\n // -----------------------------------------------------------------------------------\r\n _renderWireNetworkInfos: \"Renders information about wire networks\",\r\n renderWireNetworkInfos: false,\r\n // -----------------------------------------------------------------------------------\r\n /* ---dev:end */\r\n});\r\n\n\n/***/ }),\n\n/***/ \"./src/js/core/lzstring.js\":\n/*!*********************************!*\\\n !*** ./src/js/core/lzstring.js ***!\n \\*********************************/\n/*! exports provided: compressU8, compressU8WHeader, decompressU8WHeader, compressX64, decompressX64 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"compressU8\", function() { return compressU8; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"compressU8WHeader\", function() { return compressU8WHeader; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"decompressU8WHeader\", function() { return decompressU8WHeader; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"compressX64\", function() { return compressX64; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"decompressX64\", function() { return decompressX64; });\n// Copyright (c) 2013 Pieroxy \r\n// This work is free. You can redistribute it and/or modify it\r\n// under the terms of the WTFPL, Version 2\r\n// For more information see LICENSE.txt or http://www.wtfpl.net/\r\n//\r\n// For more information, the home page:\r\n// http://pieroxy.net/blog/pages/lz-string/testing.html\r\n//\r\n// LZ-based compression algorithm, version 1.4.4\r\n\r\nconst fromCharCode = String.fromCharCode;\r\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\r\n\r\nconst keyStrUriSafe = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$\";\r\nconst baseReverseDic = {};\r\n\r\nfunction getBaseValue(alphabet, character) {\r\n if (!baseReverseDic[alphabet]) {\r\n baseReverseDic[alphabet] = {};\r\n for (let i = 0; i < alphabet.length; i++) {\r\n baseReverseDic[alphabet][alphabet.charAt(i)] = i;\r\n }\r\n }\r\n return baseReverseDic[alphabet][character];\r\n}\r\n\r\n//compress into uint8array (UCS-2 big endian format)\r\nfunction compressU8(uncompressed) {\r\n let compressed = compress(uncompressed);\r\n let buf = new Uint8Array(compressed.length * 2); // 2 bytes per character\r\n\r\n for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) {\r\n let current_value = compressed.charCodeAt(i);\r\n buf[i * 2] = current_value >>> 8;\r\n buf[i * 2 + 1] = current_value % 256;\r\n }\r\n return buf;\r\n}\r\n\r\n// Compreses with header\r\n/**\r\n * @param {string} uncompressed\r\n * @param {number} header\r\n */\r\nfunction compressU8WHeader(uncompressed, header) {\r\n let compressed = compress(uncompressed);\r\n let buf = new Uint8Array(2 + compressed.length * 2); // 2 bytes per character\r\n\r\n buf[0] = header >>> 8;\r\n buf[1] = header % 256;\r\n for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) {\r\n let current_value = compressed.charCodeAt(i);\r\n buf[2 + i * 2] = current_value >>> 8;\r\n buf[2 + i * 2 + 1] = current_value % 256;\r\n }\r\n return buf;\r\n}\r\n\r\n//decompress from uint8array (UCS-2 big endian format)\r\n/**\r\n *\r\n * @param {Uint8Array} compressed\r\n */\r\nfunction decompressU8WHeader(compressed) {\r\n // let buf = new Array(compressed.length / 2); // 2 bytes per character\r\n // for (let i = 0, TotalLen = buf.length; i < TotalLen; i++) {\r\n // buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];\r\n // }\r\n\r\n // let result = [];\r\n // buf.forEach(function (c) {\r\n // result.push(fromCharCode(c));\r\n // });\r\n let result = [];\r\n for (let i = 2, n = compressed.length; i < n; i += 2) {\r\n const code = compressed[i] * 256 + compressed[i + 1];\r\n result.push(fromCharCode(code));\r\n }\r\n return decompress(result.join(\"\"));\r\n}\r\n\r\n//compress into a string that is already URI encoded\r\nfunction compressX64(input) {\r\n if (input == null) return \"\";\r\n return _compress(input, 6, function (a) {\r\n return keyStrUriSafe.charAt(a);\r\n });\r\n}\r\n\r\n//decompress from an output of compressToEncodedURIComponent\r\nfunction decompressX64(input) {\r\n if (input == null) return \"\";\r\n if (input == \"\") return null;\r\n input = input.replace(/ /g, \"+\");\r\n return _decompress(input.length, 32, function (index) {\r\n return getBaseValue(keyStrUriSafe, input.charAt(index));\r\n });\r\n}\r\n\r\nfunction compress(uncompressed) {\r\n return _compress(uncompressed, 16, function (a) {\r\n return fromCharCode(a);\r\n });\r\n}\r\n\r\nfunction _compress(uncompressed, bitsPerChar, getCharFromInt) {\r\n if (uncompressed == null) return \"\";\r\n let i,\r\n value,\r\n context_dictionary = {},\r\n context_dictionaryToCreate = {},\r\n context_c = \"\",\r\n context_wc = \"\",\r\n context_w = \"\",\r\n context_enlargeIn = 2, // Compensate for the first entry which should not count\r\n context_dictSize = 3,\r\n context_numBits = 2,\r\n context_data = [],\r\n context_data_val = 0,\r\n context_data_position = 0,\r\n ii;\r\n\r\n for (ii = 0; ii < uncompressed.length; ii += 1) {\r\n context_c = uncompressed.charAt(ii);\r\n if (!hasOwnProperty.call(context_dictionary, context_c)) {\r\n context_dictionary[context_c] = context_dictSize++;\r\n context_dictionaryToCreate[context_c] = true;\r\n }\r\n\r\n context_wc = context_w + context_c;\r\n if (hasOwnProperty.call(context_dictionary, context_wc)) {\r\n context_w = context_wc;\r\n } else {\r\n if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) {\r\n if (context_w.charCodeAt(0) < 256) {\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = context_data_val << 1;\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n }\r\n value = context_w.charCodeAt(0);\r\n for (i = 0; i < 8; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n } else {\r\n value = 1;\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = (context_data_val << 1) | value;\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = 0;\r\n }\r\n value = context_w.charCodeAt(0);\r\n for (i = 0; i < 16; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n }\r\n context_enlargeIn--;\r\n if (context_enlargeIn == 0) {\r\n context_enlargeIn = Math.pow(2, context_numBits);\r\n context_numBits++;\r\n }\r\n delete context_dictionaryToCreate[context_w];\r\n } else {\r\n value = context_dictionary[context_w];\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n }\r\n context_enlargeIn--;\r\n if (context_enlargeIn == 0) {\r\n context_enlargeIn = Math.pow(2, context_numBits);\r\n context_numBits++;\r\n }\r\n // Add wc to the dictionary.\r\n context_dictionary[context_wc] = context_dictSize++;\r\n context_w = String(context_c);\r\n }\r\n }\r\n\r\n // Output the code for w.\r\n if (context_w !== \"\") {\r\n if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) {\r\n if (context_w.charCodeAt(0) < 256) {\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = context_data_val << 1;\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n }\r\n value = context_w.charCodeAt(0);\r\n for (i = 0; i < 8; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n } else {\r\n value = 1;\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = (context_data_val << 1) | value;\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = 0;\r\n }\r\n value = context_w.charCodeAt(0);\r\n for (i = 0; i < 16; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n }\r\n context_enlargeIn--;\r\n if (context_enlargeIn == 0) {\r\n context_enlargeIn = Math.pow(2, context_numBits);\r\n context_numBits++;\r\n }\r\n delete context_dictionaryToCreate[context_w];\r\n } else {\r\n value = context_dictionary[context_w];\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n }\r\n context_enlargeIn--;\r\n if (context_enlargeIn == 0) {\r\n context_enlargeIn = Math.pow(2, context_numBits);\r\n context_numBits++;\r\n }\r\n }\r\n\r\n // Mark the end of the stream\r\n value = 2;\r\n for (i = 0; i < context_numBits; i++) {\r\n context_data_val = (context_data_val << 1) | (value & 1);\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data_position = 0;\r\n context_data.push(getCharFromInt(context_data_val));\r\n context_data_val = 0;\r\n } else {\r\n context_data_position++;\r\n }\r\n value = value >> 1;\r\n }\r\n\r\n // Flush the last char\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n context_data_val = context_data_val << 1;\r\n if (context_data_position == bitsPerChar - 1) {\r\n context_data.push(getCharFromInt(context_data_val));\r\n break;\r\n } else context_data_position++;\r\n }\r\n return context_data.join(\"\");\r\n}\r\n\r\nfunction decompress(compressed) {\r\n if (compressed == null) return \"\";\r\n if (compressed == \"\") return null;\r\n return _decompress(compressed.length, 32768, function (index) {\r\n return compressed.charCodeAt(index);\r\n });\r\n}\r\n\r\nfunction _decompress(length, resetValue, getNextValue) {\r\n let dictionary = [],\r\n next,\r\n enlargeIn = 4,\r\n dictSize = 4,\r\n numBits = 3,\r\n entry = \"\",\r\n result = [],\r\n i,\r\n w,\r\n bits,\r\n resb,\r\n maxpower,\r\n power,\r\n c,\r\n data = { val: getNextValue(0), position: resetValue, index: 1 };\r\n\r\n for (i = 0; i < 3; i += 1) {\r\n dictionary[i] = i;\r\n }\r\n\r\n bits = 0;\r\n maxpower = Math.pow(2, 2);\r\n power = 1;\r\n while (power != maxpower) {\r\n resb = data.val & data.position;\r\n data.position >>= 1;\r\n if (data.position == 0) {\r\n data.position = resetValue;\r\n data.val = getNextValue(data.index++);\r\n }\r\n bits |= (resb > 0 ? 1 : 0) * power;\r\n power <<= 1;\r\n }\r\n\r\n switch ((next = bits)) {\r\n case 0:\r\n bits = 0;\r\n maxpower = Math.pow(2, 8);\r\n power = 1;\r\n while (power != maxpower) {\r\n resb = data.val & data.position;\r\n data.position >>= 1;\r\n if (data.position == 0) {\r\n data.position = resetValue;\r\n data.val = getNextValue(data.index++);\r\n }\r\n bits |= (resb > 0 ? 1 : 0) * power;\r\n power <<= 1;\r\n }\r\n c = fromCharCode(bits);\r\n break;\r\n case 1:\r\n bits = 0;\r\n maxpower = Math.pow(2, 16);\r\n power = 1;\r\n while (power != maxpower) {\r\n resb = data.val & data.position;\r\n data.position >>= 1;\r\n if (data.position == 0) {\r\n data.position = resetValue;\r\n data.val = getNextValue(data.index++);\r\n }\r\n bits |= (resb > 0 ? 1 : 0) * power;\r\n power <<= 1;\r\n }\r\n c = fromCharCode(bits);\r\n break;\r\n case 2:\r\n return \"\";\r\n }\r\n dictionary[3] = c;\r\n w = c;\r\n result.push(c);\r\n\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n if (data.index > length) {\r\n return \"\";\r\n }\r\n\r\n bits = 0;\r\n maxpower = Math.pow(2, numBits);\r\n power = 1;\r\n while (power != maxpower) {\r\n resb = data.val & data.position;\r\n data.position >>= 1;\r\n if (data.position == 0) {\r\n data.position = resetValue;\r\n data.val = getNextValue(data.index++);\r\n }\r\n bits |= (resb > 0 ? 1 : 0) * power;\r\n power <<= 1;\r\n }\r\n\r\n switch ((c = bits)) {\r\n case 0:\r\n bits = 0;\r\n maxpower = Math.pow(2, 8);\r\n power = 1;\r\n while (power != maxpower) {\r\n resb = data.val & data.position;\r\n data.position >>= 1;\r\n if (data.position == 0) {\r\n data.position = resetValue;\r\n data.val = getNextValue(data.index++);\r\n }\r\n bits |= (resb > 0 ? 1 : 0) * power;\r\n power <<= 1;\r\n }\r\n\r\n dictionary[dictSize++] = fromCharCode(bits);\r\n c = dictSize - 1;\r\n enlargeIn--;\r\n break;\r\n case 1:\r\n bits = 0;\r\n maxpower = Math.pow(2, 16);\r\n power = 1;\r\n while (power != maxpower) {\r\n resb = data.val & data.position;\r\n data.position >>= 1;\r\n if (data.position == 0) {\r\n data.position = resetValue;\r\n data.val = getNextValue(data.index++);\r\n }\r\n bits |= (resb > 0 ? 1 : 0) * power;\r\n power <<= 1;\r\n }\r\n dictionary[dictSize++] = fromCharCode(bits);\r\n c = dictSize - 1;\r\n enlargeIn--;\r\n break;\r\n case 2:\r\n return result.join(\"\");\r\n }\r\n\r\n if (enlargeIn == 0) {\r\n enlargeIn = Math.pow(2, numBits);\r\n numBits++;\r\n }\r\n\r\n if (dictionary[c]) {\r\n // @ts-ignore\r\n entry = dictionary[c];\r\n } else {\r\n if (c === dictSize) {\r\n entry = w + w.charAt(0);\r\n } else {\r\n return null;\r\n }\r\n }\r\n result.push(entry);\r\n\r\n // Add w+entry[0] to the dictionary.\r\n dictionary[dictSize++] = w + entry.charAt(0);\r\n enlargeIn--;\r\n\r\n w = entry;\r\n\r\n if (enlargeIn == 0) {\r\n enlargeIn = Math.pow(2, numBits);\r\n numBits++;\r\n }\r\n }\r\n}\r\n\n\n/***/ }),\n\n/***/ \"./src/js/core/query_parameters.js\":\n/*!*****************************************!*\\\n !*** ./src/js/core/query_parameters.js ***!\n \\*****************************************/\n/*! exports provided: queryParamOptions */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"queryParamOptions\", function() { return queryParamOptions; });\nconst queryString = __webpack_require__(/*! query-string */ \"./node_modules/query-string/index.js\");\r\nconst options = queryString.parse(location.search);\r\n\r\nlet queryParamOptions = {\r\n embedProvider: null,\r\n fullVersion: false,\r\n sandboxMode: false,\r\n};\r\n\r\nif (options.embed) {\r\n queryParamOptions.embedProvider = options.embed;\r\n}\r\n\r\n// Allow testing full version outside of standalone\r\nif (options.fullVersion && !false) {\r\n queryParamOptions.fullVersion = true;\r\n}\r\n\r\n// Allow testing full version outside of standalone\r\nif (options.sandboxMode && !false) {\r\n queryParamOptions.sandboxMode = true;\r\n}\r\n\n\n/***/ }),\n\n/***/ \"./src/js/core/sensitive_utils.encrypt.js\":\n/*!************************************************!*\\\n !*** ./src/js/core/sensitive_utils.encrypt.js ***!\n \\************************************************/\n/*! exports provided: sha1, getNameOfProvider, CRC_PREFIX, computeCrc */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"sha1\", function() { return sha1; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getNameOfProvider\", function() { return getNameOfProvider; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"CRC_PREFIX\", function() { return CRC_PREFIX; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"computeCrc\", function() { return computeCrc; });\n/* harmony import */ var rusha__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rusha */ \"./node_modules/rusha/dist/rusha.js\");\n/* harmony import */ var rusha__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(rusha__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var crc_crc32__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! crc/crc32 */ \"./node_modules/crc/crc32.js\");\n/* harmony import */ var _lzstring__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lzstring */ \"./src/js/core/lzstring.js\");\n\r\n\r\n\r\n\r\nfunction sha1(str) {\r\n return Object(rusha__WEBPACK_IMPORTED_MODULE_0__[\"createHash\"])().update(str).digest(\"hex\");\r\n}\r\n\r\n// Window.location.host\r\nfunction getNameOfProvider() {\r\n return window[Object(_lzstring__WEBPACK_IMPORTED_MODULE_2__[\"decompressX64\"])(\"DYewxghgLgliB2Q\")][Object(_lzstring__WEBPACK_IMPORTED_MODULE_2__[\"decompressX64\"])(\"BYewzgLgdghgtgUyA\")];\r\n}\r\n\r\n// Distinguish legacy crc prefixes\r\nconst CRC_PREFIX = \"crc32\".padEnd(32, \"-\");\r\n\r\n/**\r\n * Computes the crc for a given string\r\n * @param {string} str\r\n */\r\nfunction computeCrc(str) {\r\n return CRC_PREFIX + Object(crc_crc32__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(str).toString(16).padStart(8, \"0\");\r\n}\r\n\n\n/***/ }),\n\n/***/ \"./src/js/savegame/savegame_compressor.js\":\n/*!************************************************!*\\\n !*** ./src/js/savegame/savegame_compressor.js ***!\n \\************************************************/\n/*! exports provided: compressObject, decompressObject */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"compressObject\", function() { return compressObject; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"decompressObject\", function() { return decompressObject; });\nconst charmap =\r\n \"!#%&'()*+,-./:;<=>?@[]^_`{|}~¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿABCDEFGHIJKLMNOPQRSTUVWXYZ\";\r\n\r\nlet compressionCache = {};\r\nlet decompressionCache = {};\r\n\r\n/**\r\n * Compresses an integer into a tight string representation\r\n * @param {number} i\r\n * @returns {string}\r\n */\r\nfunction compressInt(i) {\r\n // Zero value breaks\r\n i += 1;\r\n\r\n if (compressionCache[i]) {\r\n return compressionCache[i];\r\n }\r\n let result = \"\";\r\n do {\r\n result += charmap[i % charmap.length];\r\n i = Math.floor(i / charmap.length);\r\n } while (i > 0);\r\n return (compressionCache[i] = result);\r\n}\r\n\r\n/**\r\n * Decompresses an integer from its tight string representation\r\n * @param {string} s\r\n * @returns {number}\r\n */\r\nfunction decompressInt(s) {\r\n if (decompressionCache[s]) {\r\n return decompressionCache[s];\r\n }\r\n s = \"\" + s;\r\n let result = 0;\r\n for (let i = s.length - 1; i >= 0; --i) {\r\n result = result * charmap.length + charmap.indexOf(s.charAt(i));\r\n }\r\n // Fixes zero value break fix from above\r\n result -= 1;\r\n return (decompressionCache[s] = result);\r\n}\r\n\r\n// Sanity\r\nif (true) {\r\n for (let i = 0; i < 10000; ++i) {\r\n if (decompressInt(compressInt(i)) !== i) {\r\n throw new Error(\r\n \"Bad compression for: \" +\r\n i +\r\n \" compressed: \" +\r\n compressInt(i) +\r\n \" decompressed: \" +\r\n decompressInt(compressInt(i))\r\n );\r\n }\r\n }\r\n}\r\n\r\nfunction compressObjectInternal(obj, keys = [], values = []) {\r\n if (Array.isArray(obj)) {\r\n let result = [];\r\n for (let i = 0; i < obj.length; ++i) {\r\n result.push(compressObjectInternal(obj[i], keys, values));\r\n }\r\n return result;\r\n } else if (typeof obj === \"object\" && obj !== null) {\r\n let result = {};\r\n for (const key in obj) {\r\n let index = keys.indexOf(key);\r\n if (index < 0) {\r\n keys.push(key);\r\n index = keys.length - 1;\r\n }\r\n const value = obj[key];\r\n result[compressInt(index)] = compressObjectInternal(value, keys, values);\r\n }\r\n return result;\r\n } else if (typeof obj === \"string\") {\r\n let index = values.indexOf(obj);\r\n if (index < 0) {\r\n values.push(obj);\r\n index = values.length - 1;\r\n }\r\n return compressInt(index);\r\n }\r\n return obj;\r\n}\r\n\r\nfunction compressObject(obj) {\r\n const keys = [];\r\n const values = [];\r\n const data = compressObjectInternal(obj, keys, values);\r\n return {\r\n keys,\r\n values,\r\n data,\r\n };\r\n}\r\n\r\nfunction decompressObjectInternal(obj, keys = [], values = []) {\r\n if (Array.isArray(obj)) {\r\n let result = [];\r\n for (let i = 0; i < obj.length; ++i) {\r\n result.push(decompressObjectInternal(obj[i], keys, values));\r\n }\r\n return result;\r\n } else if (typeof obj === \"object\" && obj !== null) {\r\n let result = {};\r\n for (const key in obj) {\r\n const realIndex = decompressInt(key);\r\n const value = obj[key];\r\n result[keys[realIndex]] = decompressObjectInternal(value, keys, values);\r\n }\r\n return result;\r\n } else if (typeof obj === \"string\") {\r\n const realIndex = decompressInt(obj);\r\n return values[realIndex];\r\n }\r\n return obj;\r\n}\r\n\r\nfunction decompressObject(obj) {\r\n if (obj.keys && obj.values && obj.data) {\r\n const keys = obj.keys;\r\n const values = obj.values;\r\n const result = decompressObjectInternal(obj.data, keys, values);\r\n return result;\r\n }\r\n return obj;\r\n}\r\n\n\n/***/ })\n\n/******/ });\n//# sourceMappingURL=63bd5e6c8b0c401058d0.worker.js.map", null); }; /***/ }), /***/ 0: /*!******************************!*\ !*** multi ./src/js/main.js ***! \******************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(/*! D:\Users\dimava\Desktop\projects\shapez.io\src\js\main.js */"./src/js/main.js"); /***/ }) /******/ }); //# sourceMappingURL=bundle.js.map