1
0
forked from sent/waves
waves-fork/public/assets/g/shapez/bundle.js
2025-04-09 17:11:14 -05:00

69413 lines
2.9 MiB
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******/ (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 <feross@feross.org> <http://feross.org>
* @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 ' + str + '>'
}
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<schema.length; i++) this.addSchema(schema[i], undefined, _skipValidation, _meta);
return this;
}
var id = this._getId(schema);
if (id !== undefined && typeof id != 'string')
throw new Error('schema id must be string');
key = resolve.normalizeId(key || id);
checkUnique(this, key);
this._schemas[key] = this._addSchema(schema, _skipValidation, _meta, true);
return this;
}
/**
* Add schema that will be used to validate other schemas
* options in META_IGNORE_OPTIONS are alway set to false
* @this Ajv
* @param {Object} schema schema object
* @param {String} key optional schema key
* @param {Boolean} skipValidation true to skip schema validation, can be used to override validateSchema option for meta-schema
* @return {Ajv} this for method chaining
*/
function addMetaSchema(schema, key, skipValidation) {
this.addSchema(schema, key, skipValidation, true);
return this;
}
/**
* Validate schema
* @this Ajv
* @param {Object} schema schema to validate
* @param {Boolean} throwOrLogError pass true to throw (or log) an error if invalid
* @return {Boolean} true if schema is valid
*/
function validateSchema(schema, throwOrLogError) {
var $schema = schema.$schema;
if ($schema !== undefined && typeof $schema != 'string')
throw new Error('$schema must be a string');
$schema = $schema || this._opts.defaultMeta || defaultMeta(this);
if (!$schema) {
this.logger.warn('meta-schema not available');
this.errors = null;
return true;
}
var valid = this.validate($schema, schema);
if (!valid && throwOrLogError) {
var message = 'schema is invalid: ' + this.errorsText();
if (this._opts.validateSchema == 'log') this.logger.error(message);
else throw new Error(message);
}
return valid;
}
function defaultMeta(self) {
var meta = self._opts.meta;
self._opts.defaultMeta = typeof meta == 'object'
? self._getId(meta) || meta
: self.getSchema(META_SCHEMA_ID)
? META_SCHEMA_ID
: undefined;
return self._opts.defaultMeta;
}
/**
* Get compiled schema from the instance by `key` or `ref`.
* @this Ajv
* @param {String} keyRef `key` that was passed to `addSchema` or full schema reference (`schema.id` or resolved id).
* @return {Function} schema validating function (with property `schema`).
*/
function getSchema(keyRef) {
var schemaObj = _getSchemaObj(this, keyRef);
switch (typeof schemaObj) {
case 'object': return schemaObj.validate || this._compile(schemaObj);
case 'string': return this.getSchema(schemaObj);
case 'undefined': return _getSchemaFragment(this, keyRef);
}
}
function _getSchemaFragment(self, ref) {
var res = resolve.schema.call(self, { schema: {} }, ref);
if (res) {
var schema = res.schema
, root = res.root
, baseId = res.baseId;
var v = compileSchema.call(self, schema, root, undefined, baseId);
self._fragments[ref] = new SchemaObject({
ref: ref,
fragment: true,
schema: schema,
root: root,
baseId: baseId,
validate: v
});
return v;
}
}
function _getSchemaObj(self, keyRef) {
keyRef = resolve.normalizeId(keyRef);
return self._schemas[keyRef] || self._refs[keyRef] || self._fragments[keyRef];
}
/**
* Remove cached schema(s).
* If no parameter is passed all schemas but meta-schemas are removed.
* If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
* Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
* @this Ajv
* @param {String|Object|RegExp} schemaKeyRef key, ref, pattern to match key/ref or schema object
* @return {Ajv} this for method chaining
*/
function removeSchema(schemaKeyRef) {
if (schemaKeyRef instanceof RegExp) {
_removeAllSchemas(this, this._schemas, schemaKeyRef);
_removeAllSchemas(this, this._refs, schemaKeyRef);
return this;
}
switch (typeof schemaKeyRef) {
case 'undefined':
_removeAllSchemas(this, this._schemas);
_removeAllSchemas(this, this._refs);
this._cache.clear();
return this;
case 'string':
var schemaObj = _getSchemaObj(this, schemaKeyRef);
if (schemaObj) this._cache.del(schemaObj.cacheKey);
delete this._schemas[schemaKeyRef];
delete this._refs[schemaKeyRef];
return this;
case 'object':
var serialize = this._opts.serialize;
var cacheKey = serialize ? serialize(schemaKeyRef) : schemaKeyRef;
this._cache.del(cacheKey);
var id = this._getId(schemaKeyRef);
if (id) {
id = resolve.normalizeId(id);
delete this._schemas[id];
delete this._refs[id];
}
}
return this;
}
function _removeAllSchemas(self, schemas, regex) {
for (var keyRef in schemas) {
var schemaObj = schemas[keyRef];
if (!schemaObj.meta && (!regex || regex.test(keyRef))) {
self._cache.del(schemaObj.cacheKey);
delete schemas[keyRef];
}
}
}
/* @this Ajv */
function _addSchema(schema, skipValidation, meta, shouldAddSchema) {
if (typeof schema != 'object' && typeof schema != 'boolean')
throw new Error('schema should be object or boolean');
var serialize = this._opts.serialize;
var cacheKey = serialize ? serialize(schema) : schema;
var cached = this._cache.get(cacheKey);
if (cached) return cached;
shouldAddSchema = shouldAddSchema || this._opts.addUsedSchema !== false;
var id = resolve.normalizeId(this._getId(schema));
if (id && shouldAddSchema) checkUnique(this, id);
var willValidate = this._opts.validateSchema !== false && !skipValidation;
var recursiveMeta;
if (willValidate && !(recursiveMeta = id && id == resolve.normalizeId(schema.$schema)))
this.validateSchema(schema, true);
var localRefs = resolve.ids.call(this, schema);
var schemaObj = new SchemaObject({
id: id,
schema: schema,
localRefs: localRefs,
cacheKey: cacheKey,
meta: meta
});
if (id[0] != '#' && shouldAddSchema) this._refs[id] = schemaObj;
this._cache.put(cacheKey, schemaObj);
if (willValidate && recursiveMeta) this.validateSchema(schema, true);
return schemaObj;
}
/* @this Ajv */
function _compile(schemaObj, root) {
if (schemaObj.compiling) {
schemaObj.validate = callValidate;
callValidate.schema = schemaObj.schema;
callValidate.errors = null;
callValidate.root = root ? root : callValidate;
if (schemaObj.schema.$async === true)
callValidate.$async = true;
return callValidate;
}
schemaObj.compiling = true;
var currentOpts;
if (schemaObj.meta) {
currentOpts = this._opts;
this._opts = this._metaOpts;
}
var v;
try { v = compileSchema.call(this, schemaObj.schema, root, schemaObj.localRefs); }
catch(e) {
delete schemaObj.validate;
throw e;
}
finally {
schemaObj.compiling = false;
if (schemaObj.meta) this._opts = currentOpts;
}
schemaObj.validate = v;
schemaObj.refs = v.refs;
schemaObj.refVal = v.refVal;
schemaObj.root = v.root;
return v;
/* @this {*} - custom context, see passContext option */
function callValidate() {
/* jshint validthis: true */
var _validate = schemaObj.validate;
var result = _validate.apply(this, arguments);
callValidate.errors = _validate.errors;
return result;
}
}
function chooseGetId(opts) {
switch (opts.schemaId) {
case 'auto': return _get$IdOrId;
case 'id': return _getId;
default: return _get$Id;
}
}
/* @this Ajv */
function _getId(schema) {
if (schema.$id) this.logger.warn('schema $id ignored', schema.$id);
return schema.id;
}
/* @this Ajv */
function _get$Id(schema) {
if (schema.id) this.logger.warn('schema id ignored', schema.id);
return schema.$id;
}
function _get$IdOrId(schema) {
if (schema.$id && schema.id && schema.$id != schema.id)
throw new Error('schema $id is different from id');
return schema.$id || schema.id;
}
/**
* Convert array of error message objects to string
* @this Ajv
* @param {Array<Object>} 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<errors.length; i++) {
var e = errors[i];
if (e) text += dataVar + e.dataPath + ' ' + e.message + separator;
}
return text.slice(0, -separator.length);
}
/**
* Add custom format
* @this Ajv
* @param {String} name format name
* @param {String|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
* @return {Ajv} this for method chaining
*/
function addFormat(name, format) {
if (typeof format == 'string') format = new RegExp(format);
this._formats[name] = format;
return this;
}
function addDefaultMetaSchema(self) {
var $dataSchema;
if (self._opts.$data) {
$dataSchema = __webpack_require__(/*! ./refs/data.json */ "./node_modules/ajv/lib/refs/data.json");
self.addMetaSchema($dataSchema, $dataSchema.$id, true);
}
if (self._opts.meta === false) return;
var metaSchema = __webpack_require__(/*! ./refs/json-schema-draft-07.json */ "./node_modules/ajv/lib/refs/json-schema-draft-07.json");
if (self._opts.$data) metaSchema = $dataMetaSchema(metaSchema, META_SUPPORT_DATA);
self.addMetaSchema(metaSchema, META_SCHEMA_ID, true);
self._refs['http://json-schema.org/schema'] = META_SCHEMA_ID;
}
function addInitialSchemas(self) {
var optsSchemas = self._opts.schemas;
if (!optsSchemas) return;
if (Array.isArray(optsSchemas)) self.addSchema(optsSchemas);
else for (var key in optsSchemas) self.addSchema(optsSchemas[key], key);
}
function addInitialFormats(self) {
for (var name in self._opts.formats) {
var format = self._opts.formats[name];
self.addFormat(name, format);
}
}
function addInitialKeywords(self) {
for (var name in self._opts.keywords) {
var keyword = self._opts.keywords[name];
self.addKeyword(name, keyword);
}
}
function checkUnique(self, id) {
if (self._schemas[id] || self._refs[id])
throw new Error('schema with key or id "' + id + '" already exists');
}
function getMetaSchemaOptions(self) {
var metaOpts = util.copy(self._opts);
for (var i=0; i<META_IGNORE_OPTIONS.length; i++)
delete metaOpts[META_IGNORE_OPTIONS[i]];
return metaOpts;
}
function setLogger(self) {
var logger = self._opts.logger;
if (logger === false) {
self.logger = {log: noop, warn: noop, error: noop};
} else {
if (logger === undefined) logger = console;
if (!(typeof logger == 'object' && logger.log && logger.warn && logger.error))
throw new Error('logger must implement log, warn and error methods');
self.logger = logger;
}
}
function noop() {}
/***/ }),
/***/ "./node_modules/ajv/lib/cache.js":
/*!***************************************!*\
!*** ./node_modules/ajv/lib/cache.js ***!
\***************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var Cache = module.exports = function Cache() {
this._cache = {};
};
Cache.prototype.put = function Cache_put(key, value) {
this._cache[key] = value;
};
Cache.prototype.get = function Cache_get(key) {
return this._cache[key];
};
Cache.prototype.del = function Cache_del(key) {
delete this._cache[key];
};
Cache.prototype.clear = function Cache_clear() {
this._cache = {};
};
/***/ }),
/***/ "./node_modules/ajv/lib/compile/async.js":
/*!***********************************************!*\
!*** ./node_modules/ajv/lib/compile/async.js ***!
\***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var MissingRefError = __webpack_require__(/*! ./error_classes */ "./node_modules/ajv/lib/compile/error_classes.js").MissingRef;
module.exports = compileAsync;
/**
* Creates validating function for passed schema with asynchronous loading of missing schemas.
* `loadSchema` option should be a function that accepts schema uri and returns promise that resolves with the schema.
* @this Ajv
* @param {Object} schema schema object
* @param {Boolean} meta optional true to compile meta-schema; this parameter can be skipped
* @param {Function} callback an optional node-style callback, it is called with 2 parameters: error (or null) and validating function.
* @return {Promise} promise that resolves with a validating function.
*/
function compileAsync(schema, meta, callback) {
/* eslint no-shadow: 0 */
/* global Promise */
/* jshint validthis: true */
var self = this;
if (typeof this._opts.loadSchema != 'function')
throw new Error('options.loadSchema should be a function');
if (typeof meta == 'function') {
callback = meta;
meta = undefined;
}
var p = loadMetaSchemaOf(schema).then(function () {
var schemaObj = self._addSchema(schema, undefined, meta);
return schemaObj.validate || _compileAsync(schemaObj);
});
if (callback) {
p.then(
function(v) { callback(null, v); },
callback
);
}
return p;
function loadMetaSchemaOf(sch) {
var $schema = sch.$schema;
return $schema && !self.getSchema($schema)
? compileAsync.call(self, { $ref: $schema }, true)
: Promise.resolve();
}
function _compileAsync(schemaObj) {
try { return self._compile(schemaObj); }
catch(e) {
if (e instanceof MissingRefError) return loadMissingSchema(e);
throw e;
}
function loadMissingSchema(e) {
var ref = e.missingSchema;
if (added(ref)) throw new Error('Schema ' + ref + ' is loaded but ' + e.missingRef + ' cannot be resolved');
var schemaPromise = self._loadingSchemas[ref];
if (!schemaPromise) {
schemaPromise = self._loadingSchemas[ref] = self._opts.loadSchema(ref);
schemaPromise.then(removePromise, removePromise);
}
return schemaPromise.then(function (sch) {
if (!added(ref)) {
return loadMetaSchemaOf(sch).then(function () {
if (!added(ref)) self.addSchema(sch, ref, undefined, meta);
});
}
}).then(function() {
return _compileAsync(schemaObj);
});
function removePromise() {
delete self._loadingSchemas[ref];
}
function added(ref) {
return self._refs[ref] || self._schemas[ref];
}
}
}
}
/***/ }),
/***/ "./node_modules/ajv/lib/compile/error_classes.js":
/*!*******************************************************!*\
!*** ./node_modules/ajv/lib/compile/error_classes.js ***!
\*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var resolve = __webpack_require__(/*! ./resolve */ "./node_modules/ajv/lib/compile/resolve.js");
module.exports = {
Validation: errorSubclass(ValidationError),
MissingRef: errorSubclass(MissingRefError)
};
function ValidationError(errors) {
this.message = 'validation failed';
this.errors = errors;
this.ajv = this.validation = true;
}
MissingRefError.message = function (baseId, ref) {
return 'can\'t resolve reference ' + ref + ' from id ' + baseId;
};
function MissingRefError(baseId, ref, message) {
this.message = message || MissingRefError.message(baseId, ref);
this.missingRef = resolve.url(baseId, ref);
this.missingSchema = resolve.normalizeId(resolve.fullPath(this.missingRef));
}
function errorSubclass(Subclass) {
Subclass.prototype = Object.create(Error.prototype);
Subclass.prototype.constructor = Subclass;
return Subclass;
}
/***/ }),
/***/ "./node_modules/ajv/lib/compile/formats.js":
/*!*************************************************!*\
!*** ./node_modules/ajv/lib/compile/formats.js ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var util = __webpack_require__(/*! ./util */ "./node_modules/ajv/lib/compile/util.js");
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
var DAYS = [0,31,28,31,30,31,30,31,31,30,31,30,31];
var TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i;
var HOSTNAME = /^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i;
var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
var URIREF = /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
// uri-template: https://tools.ietf.org/html/rfc6570
var URITEMPLATE = /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[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<this._compilations.length; i++) {
var c = this._compilations[i];
if (c.schema == schema && c.root == root && c.baseId == baseId) return i;
}
return -1;
}
function patternCode(i, patterns) {
return 'var pattern' + i + ' = new RegExp(' + util.toQuotedString(patterns[i]) + ');';
}
function defaultCode(i) {
return 'var default' + i + ' = defaults[' + i + '];';
}
function refValCode(i, refVal) {
return refVal[i] === undefined ? '' : 'var refVal' + i + ' = refVal[' + i + '];';
}
function customRuleCode(i) {
return 'var customRule' + i + ' = customRules[' + i + '];';
}
function vars(arr, statement) {
if (!arr.length) return '';
var code = '';
for (var i=0; i<arr.length; i++)
code += statement(i, arr);
return code;
}
/***/ }),
/***/ "./node_modules/ajv/lib/compile/resolve.js":
/*!*************************************************!*\
!*** ./node_modules/ajv/lib/compile/resolve.js ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var URI = __webpack_require__(/*! uri-js */ "./node_modules/uri-js/dist/es5/uri.all.js")
, equal = __webpack_require__(/*! fast-deep-equal */ "./node_modules/fast-deep-equal/index.js")
, util = __webpack_require__(/*! ./util */ "./node_modules/ajv/lib/compile/util.js")
, SchemaObject = __webpack_require__(/*! ./schema_obj */ "./node_modules/ajv/lib/compile/schema_obj.js")
, traverse = __webpack_require__(/*! json-schema-traverse */ "./node_modules/json-schema-traverse/index.js");
module.exports = resolve;
resolve.normalizeId = normalizeId;
resolve.fullPath = getFullPath;
resolve.url = resolveUrl;
resolve.ids = resolveIds;
resolve.inlineRef = inlineRef;
resolve.schema = resolveSchema;
/**
* [resolve and compile the references ($ref)]
* @this Ajv
* @param {Function} compile reference to schema compilation funciton (localCompile)
* @param {Object} root object with information about the root schema for the current schema
* @param {String} ref reference to resolve
* @return {Object|Function} schema object (if the schema can be inlined) or validation function
*/
function resolve(compile, root, ref) {
/* jshint validthis: true */
var refVal = this._refs[ref];
if (typeof refVal == 'string') {
if (this._refs[refVal]) refVal = this._refs[refVal];
else return resolve.call(this, compile, root, refVal);
}
refVal = refVal || this._schemas[ref];
if (refVal instanceof SchemaObject) {
return inlineRef(refVal.schema, this._opts.inlineRefs)
? refVal.schema
: refVal.validate || this._compile(refVal);
}
var res = resolveSchema.call(this, root, ref);
var schema, v, baseId;
if (res) {
schema = res.schema;
root = res.root;
baseId = res.baseId;
}
if (schema instanceof SchemaObject) {
v = schema.validate || compile.call(this, schema.schema, root, undefined, baseId);
} else if (schema !== undefined) {
v = inlineRef(schema, this._opts.inlineRefs)
? schema
: compile.call(this, schema, root, undefined, baseId);
}
return v;
}
/**
* Resolve schema, its root and baseId
* @this Ajv
* @param {Object} root root object with properties schema, refVal, refs
* @param {String} ref reference to resolve
* @return {Object} object with properties schema, root, baseId
*/
function resolveSchema(root, ref) {
/* jshint validthis: true */
var p = URI.parse(ref)
, refPath = _getFullPath(p)
, baseId = getFullPath(this._getId(root.schema));
if (Object.keys(root.schema).length === 0 || refPath !== baseId) {
var id = normalizeId(refPath);
var refVal = this._refs[id];
if (typeof refVal == 'string') {
return resolveRecursive.call(this, root, refVal, p);
} else if (refVal instanceof SchemaObject) {
if (!refVal.validate) this._compile(refVal);
root = refVal;
} else {
refVal = this._schemas[id];
if (refVal instanceof SchemaObject) {
if (!refVal.validate) this._compile(refVal);
if (id == normalizeId(ref))
return { schema: refVal, root: root, baseId: baseId };
root = refVal;
} else {
return;
}
}
if (!root.schema) return;
baseId = getFullPath(this._getId(root.schema));
}
return getJsonPointer.call(this, p, baseId, root.schema, root);
}
/* @this Ajv */
function resolveRecursive(root, ref, parsedRef) {
/* jshint validthis: true */
var res = resolveSchema.call(this, root, ref);
if (res) {
var schema = res.schema;
var baseId = res.baseId;
root = res.root;
var id = this._getId(schema);
if (id) baseId = resolveUrl(baseId, id);
return getJsonPointer.call(this, parsedRef, baseId, schema, root);
}
}
var PREVENT_SCOPE_CHANGE = util.toHash(['properties', 'patternProperties', 'enum', 'dependencies', 'definitions']);
/* @this Ajv */
function getJsonPointer(parsedRef, baseId, schema, root) {
/* jshint validthis: true */
parsedRef.fragment = parsedRef.fragment || '';
if (parsedRef.fragment.slice(0,1) != '/') return;
var parts = parsedRef.fragment.split('/');
for (var i = 1; i < parts.length; i++) {
var part = parts[i];
if (part) {
part = util.unescapeFragment(part);
schema = schema[part];
if (schema === undefined) break;
var id;
if (!PREVENT_SCOPE_CHANGE[part]) {
id = this._getId(schema);
if (id) baseId = resolveUrl(baseId, id);
if (schema.$ref) {
var $ref = resolveUrl(baseId, schema.$ref);
var res = resolveSchema.call(this, root, $ref);
if (res) {
schema = res.schema;
root = res.root;
baseId = res.baseId;
}
}
}
}
}
if (schema !== undefined && schema !== root.schema)
return { schema: schema, root: root, baseId: baseId };
}
var SIMPLE_INLINED = util.toHash([
'type', 'format', 'pattern',
'maxLength', 'minLength',
'maxProperties', 'minProperties',
'maxItems', 'minItems',
'maximum', 'minimum',
'uniqueItems', 'multipleOf',
'required', 'enum'
]);
function inlineRef(schema, limit) {
if (limit === false) return false;
if (limit === undefined || limit === true) return checkNoRef(schema);
else if (limit) return countKeys(schema) <= limit;
}
function checkNoRef(schema) {
var item;
if (Array.isArray(schema)) {
for (var i=0; i<schema.length; i++) {
item = schema[i];
if (typeof item == 'object' && !checkNoRef(item)) return false;
}
} else {
for (var key in schema) {
if (key == '$ref') return false;
item = schema[key];
if (typeof item == 'object' && !checkNoRef(item)) return false;
}
}
return true;
}
function countKeys(schema) {
var count = 0, item;
if (Array.isArray(schema)) {
for (var i=0; i<schema.length; i++) {
item = schema[i];
if (typeof item == 'object') count += countKeys(item);
if (count == Infinity) return Infinity;
}
} else {
for (var key in schema) {
if (key == '$ref') return Infinity;
if (SIMPLE_INLINED[key]) {
count++;
} else {
item = schema[key];
if (typeof item == 'object') count += countKeys(item) + 1;
if (count == Infinity) return Infinity;
}
}
}
return count;
}
function getFullPath(id, normalize) {
if (normalize !== false) id = normalizeId(id);
var p = URI.parse(id);
return _getFullPath(p);
}
function _getFullPath(p) {
return URI.serialize(p).split('#')[0] + '#';
}
var TRAILING_SLASH_HASH = /#\/?$/;
function normalizeId(id) {
return id ? id.replace(TRAILING_SLASH_HASH, '') : '';
}
function resolveUrl(baseId, id) {
id = normalizeId(id);
return URI.resolve(baseId, id);
}
/* @this Ajv */
function resolveIds(schema) {
var schemaId = normalizeId(this._getId(schema));
var baseIds = {'': schemaId};
var fullPaths = {'': getFullPath(schemaId, false)};
var localRefs = {};
var self = this;
traverse(schema, {allKeys: true}, function(sch, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
if (jsonPtr === '') return;
var id = self._getId(sch);
var baseId = baseIds[parentJsonPtr];
var fullPath = fullPaths[parentJsonPtr] + '/' + parentKeyword;
if (keyIndex !== undefined)
fullPath += '/' + (typeof keyIndex == 'number' ? keyIndex : util.escapeFragment(keyIndex));
if (typeof id == 'string') {
id = baseId = normalizeId(baseId ? URI.resolve(baseId, id) : id);
var refVal = self._refs[id];
if (typeof refVal == 'string') refVal = self._refs[refVal];
if (refVal && refVal.schema) {
if (!equal(sch, refVal.schema))
throw new Error('id "' + id + '" resolves to more than one schema');
} else if (id != normalizeId(fullPath)) {
if (id[0] == '#') {
if (localRefs[id] && !equal(sch, localRefs[id]))
throw new Error('id "' + id + '" resolves to more than one schema');
localRefs[id] = sch;
} else {
self._refs[id] = fullPath;
}
}
}
baseIds[jsonPtr] = baseId;
fullPaths[jsonPtr] = fullPath;
});
return localRefs;
}
/***/ }),
/***/ "./node_modules/ajv/lib/compile/rules.js":
/*!***********************************************!*\
!*** ./node_modules/ajv/lib/compile/rules.js ***!
\***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var ruleModules = __webpack_require__(/*! ../dotjs */ "./node_modules/ajv/lib/dotjs/index.js")
, toHash = __webpack_require__(/*! ./util */ "./node_modules/ajv/lib/compile/util.js").toHash;
module.exports = function rules() {
var RULES = [
{ type: 'number',
rules: [ { 'maximum': ['exclusiveMaximum'] },
{ 'minimum': ['exclusiveMinimum'] }, 'multipleOf', 'format'] },
{ type: 'string',
rules: [ 'maxLength', 'minLength', 'pattern', 'format' ] },
{ type: 'array',
rules: [ 'maxItems', 'minItems', 'items', 'contains', 'uniqueItems' ] },
{ type: 'object',
rules: [ 'maxProperties', 'minProperties', 'required', 'dependencies', 'propertyNames',
{ 'properties': ['additionalProperties', 'patternProperties'] } ] },
{ rules: [ '$ref', 'const', 'enum', 'not', 'anyOf', 'oneOf', 'allOf', 'if' ] }
];
var ALL = [ 'type', '$comment' ];
var KEYWORDS = [
'$schema', '$id', 'id', '$data', '$async', 'title',
'description', 'default', 'definitions',
'examples', 'readOnly', 'writeOnly',
'contentMediaType', 'contentEncoding',
'additionalItems', 'then', 'else'
];
var TYPES = [ 'number', 'integer', 'string', 'array', 'object', 'boolean', 'null' ];
RULES.all = toHash(ALL);
RULES.types = toHash(TYPES);
RULES.forEach(function (group) {
group.rules = group.rules.map(function (keyword) {
var implKeywords;
if (typeof keyword == 'object') {
var key = Object.keys(keyword)[0];
implKeywords = keyword[key];
keyword = key;
implKeywords.forEach(function (k) {
ALL.push(k);
RULES.all[k] = true;
});
}
ALL.push(keyword);
var rule = RULES.all[keyword] = {
keyword: keyword,
code: ruleModules[keyword],
implements: implKeywords
};
return rule;
});
RULES.all.$comment = {
keyword: '$comment',
code: ruleModules.$comment
};
if (group.type) RULES.types[group.type] = group;
});
RULES.keywords = toHash(ALL.concat(KEYWORDS));
RULES.custom = {};
return RULES;
};
/***/ }),
/***/ "./node_modules/ajv/lib/compile/schema_obj.js":
/*!****************************************************!*\
!*** ./node_modules/ajv/lib/compile/schema_obj.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var util = __webpack_require__(/*! ./util */ "./node_modules/ajv/lib/compile/util.js");
module.exports = SchemaObject;
function SchemaObject(obj) {
util.copy(obj, this);
}
/***/ }),
/***/ "./node_modules/ajv/lib/compile/ucs2length.js":
/*!****************************************************!*\
!*** ./node_modules/ajv/lib/compile/ucs2length.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// https://mathiasbynens.be/notes/javascript-encoding
// https://github.com/bestiejs/punycode.js - punycode.ucs2.decode
module.exports = function ucs2length(str) {
var length = 0
, len = str.length
, pos = 0
, value;
while (pos < len) {
length++;
value = str.charCodeAt(pos++);
if (value >= 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<dataTypes.length; i++) {
var t = dataTypes[i];
if (COERCE_TO_TYPES[t]) types[types.length] = t;
else if (optionCoerceTypes === 'array' && t === 'array') types[types.length] = t;
}
if (types.length) return types;
} else if (COERCE_TO_TYPES[dataTypes]) {
return [dataTypes];
} else if (optionCoerceTypes === 'array' && dataTypes === 'array') {
return ['array'];
}
}
function toHash(arr) {
var hash = {};
for (var i=0; i<arr.length; i++) hash[arr[i]] = true;
return hash;
}
var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
var SINGLE_QUOTE = /'|\\/g;
function getProperty(key) {
return typeof key == 'number'
? '[' + key + ']'
: IDENTIFIER.test(key)
? '.' + key
: "['" + escapeQuotes(key) + "']";
}
function escapeQuotes(str) {
return str.replace(SINGLE_QUOTE, '\\$&')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\f/g, '\\f')
.replace(/\t/g, '\\t');
}
function varOccurences(str, dataVar) {
dataVar += '[^0-9]';
var matches = str.match(new RegExp(dataVar, 'g'));
return matches ? matches.length : 0;
}
function varReplace(str, dataVar, expr) {
dataVar += '([^0-9])';
expr = expr.replace(/\$/g, '$$$$');
return str.replace(new RegExp(dataVar, 'g'), expr + '$1');
}
var EMPTY_ELSE = /else\s*{\s*}/g
, EMPTY_IF_NO_ELSE = /if\s*\([^)]+\)\s*\{\s*\}(?!\s*else)/g
, EMPTY_IF_WITH_ELSE = /if\s*\(([^)]+)\)\s*\{\s*\}\s*else(?!\s*if)/g;
function cleanUpCode(out) {
return out.replace(EMPTY_ELSE, '')
.replace(EMPTY_IF_NO_ELSE, '')
.replace(EMPTY_IF_WITH_ELSE, 'if (!($1))');
}
var ERRORS_REGEXP = /[^v.]errors/g
, REMOVE_ERRORS = /var errors = 0;|var vErrors = null;|validate.errors = vErrors;/g
, REMOVE_ERRORS_ASYNC = /var errors = 0;|var vErrors = null;/g
, RETURN_VALID = 'return errors === 0;'
, RETURN_TRUE = 'validate.errors = null; return true;'
, RETURN_ASYNC = /if \(errors === 0\) return data;\s*else throw new ValidationError\(vErrors\);/
, RETURN_DATA_ASYNC = 'return data;'
, ROOTDATA_REGEXP = /[^A-Za-z_$]rootData[^A-Za-z0-9_$]/g
, REMOVE_ROOTDATA = /if \(rootData === undefined\) rootData = data;/;
function finalCleanUpCode(out, async) {
var matches = out.match(ERRORS_REGEXP);
if (matches && matches.length == 2) {
out = async
? out.replace(REMOVE_ERRORS_ASYNC, '')
.replace(RETURN_ASYNC, RETURN_DATA_ASYNC)
: out.replace(REMOVE_ERRORS, '')
.replace(RETURN_VALID, RETURN_TRUE);
}
matches = out.match(ROOTDATA_REGEXP);
if (!matches || matches.length !== 3) return out;
return out.replace(REMOVE_ROOTDATA, '');
}
function schemaHasRules(schema, rules) {
if (typeof schema == 'boolean') return !schema;
for (var key in schema) if (rules[key]) return true;
}
function schemaHasRulesExcept(schema, rules, exceptKeyword) {
if (typeof schema == 'boolean') return !schema && exceptKeyword != 'not';
for (var key in schema) if (key != exceptKeyword && rules[key]) return true;
}
function schemaUnknownRules(schema, rules) {
if (typeof schema == 'boolean') return;
for (var key in schema) if (!rules[key]) return key;
}
function toQuotedString(str) {
return '\'' + escapeQuotes(str) + '\'';
}
function getPathExpr(currentPath, expr, jsonPointers, isNumber) {
var path = jsonPointers // false by default
? '\'/\' + ' + expr + (isNumber ? '' : '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\')')
: (isNumber ? '\'[\' + ' + expr + ' + \']\'' : '\'[\\\'\' + ' + expr + ' + \'\\\']\'');
return joinPaths(currentPath, path);
}
function getPath(currentPath, prop, jsonPointers) {
var path = jsonPointers // false by default
? toQuotedString('/' + escapeJsonPointer(prop))
: toQuotedString(getProperty(prop));
return joinPaths(currentPath, path);
}
var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
function getData($data, lvl, paths) {
var up, jsonPointer, data, matches;
if ($data === '') return 'rootData';
if ($data[0] == '/') {
if (!JSON_POINTER.test($data)) throw new Error('Invalid JSON-pointer: ' + $data);
jsonPointer = $data;
data = 'rootData';
} else {
matches = $data.match(RELATIVE_JSON_POINTER);
if (!matches) throw new Error('Invalid JSON-pointer: ' + $data);
up = +matches[1];
jsonPointer = matches[2];
if (jsonPointer == '#') {
if (up >= 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<segments.length; i++) {
var segment = segments[i];
if (segment) {
data += getProperty(unescapeJsonPointer(segment));
expr += ' && ' + data;
}
}
return expr;
}
function joinPaths (a, b) {
if (a == '""') return b;
return (a + ' + ' + b).replace(/' \+ '/g, '');
}
function unescapeFragment(str) {
return unescapeJsonPointer(decodeURIComponent(str));
}
function escapeFragment(str) {
return encodeURIComponent(escapeJsonPointer(str));
}
function escapeJsonPointer(str) {
return str.replace(/~/g, '~0').replace(/\//g, '~1');
}
function unescapeJsonPointer(str) {
return str.replace(/~1/g, '/').replace(/~0/g, '~');
}
/***/ }),
/***/ "./node_modules/ajv/lib/data.js":
/*!**************************************!*\
!*** ./node_modules/ajv/lib/data.js ***!
\**************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var KEYWORDS = [
'multipleOf',
'maximum',
'exclusiveMaximum',
'minimum',
'exclusiveMinimum',
'maxLength',
'minLength',
'pattern',
'additionalItems',
'maxItems',
'minItems',
'uniqueItems',
'maxProperties',
'minProperties',
'required',
'additionalProperties',
'enum',
'format',
'const'
];
module.exports = function (metaSchema, keywordsJsonPointers) {
for (var i=0; i<keywordsJsonPointers.length; i++) {
metaSchema = JSON.parse(JSON.stringify(metaSchema));
var segments = keywordsJsonPointers[i].split('/');
var keywords = metaSchema;
var j;
for (j=1; j<segments.length; j++)
keywords = keywords[segments[j]];
for (j=0; j<KEYWORDS.length; j++) {
var key = KEYWORDS[j];
var schema = keywords[key];
if (schema) {
keywords[key] = {
anyOf: [
schema,
{ $ref: 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/data.json#' }
]
};
}
}
}
return metaSchema;
};
/***/ }),
/***/ "./node_modules/ajv/lib/definition_schema.js":
/*!***************************************************!*\
!*** ./node_modules/ajv/lib/definition_schema.js ***!
\***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var metaSchema = __webpack_require__(/*! ./refs/json-schema-draft-07.json */ "./node_modules/ajv/lib/refs/json-schema-draft-07.json");
module.exports = {
$id: 'https://github.com/epoberezkin/ajv/blob/master/lib/definition_schema.js',
definitions: {
simpleTypes: metaSchema.definitions.simpleTypes
},
type: 'object',
dependencies: {
schema: ['validate'],
$data: ['validate'],
statements: ['inline'],
valid: {not: {required: ['macro']}}
},
properties: {
type: metaSchema.properties.type,
schema: {type: 'boolean'},
statements: {type: 'boolean'},
dependencies: {
type: 'array',
items: {type: 'string'}
},
metaSchema: {type: 'object'},
modifying: {type: 'boolean'},
valid: {type: 'boolean'},
$data: {type: 'boolean'},
async: {type: 'boolean'},
errors: {
anyOf: [
{type: 'boolean'},
{const: 'full'}
]
}
}
};
/***/ }),
/***/ "./node_modules/ajv/lib/dotjs/_limit.js":
/*!**********************************************!*\
!*** ./node_modules/ajv/lib/dotjs/_limit.js ***!
\**********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function generate__limit(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 $isMax = $keyword == 'maximum',
$exclusiveKeyword = $isMax ? 'exclusiveMaximum' : 'exclusiveMinimum',
$schemaExcl = it.schema[$exclusiveKeyword],
$isDataExcl = it.opts.$data && $schemaExcl && $schemaExcl.$data,
$op = $isMax ? '<' : '>',
$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) + '<errors; ' + ($i) + '++) { var ' + ($ruleErr) + ' = vErrors[' + ($i) + ']; if (' + ($ruleErr) + '.dataPath === undefined) ' + ($ruleErr) + '.dataPath = (dataPath || \'\') + ' + (it.errorPath) + '; if (' + ($ruleErr) + '.schemaPath === undefined) { ' + ($ruleErr) + '.schemaPath = "' + ($errSchemaPath) + '"; } ';
if (it.opts.verbose) {
out += ' ' + ($ruleErr) + '.schema = ' + ($schemaValue) + '; ' + ($ruleErr) + '.data = ' + ($data) + '; ';
}
out += ' } ';
}
} else {
if ($rDef.errors === false) {
out += ' ' + (def_customError) + ' ';
} else {
out += ' if (' + ($errs) + ' == errors) { ' + (def_customError) + ' } else { for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + '<errors; ' + ($i) + '++) { var ' + ($ruleErr) + ' = vErrors[' + ($i) + ']; if (' + ($ruleErr) + '.dataPath === undefined) ' + ($ruleErr) + '.dataPath = (dataPath || \'\') + ' + (it.errorPath) + '; if (' + ($ruleErr) + '.schemaPath === undefined) { ' + ($ruleErr) + '.schemaPath = "' + ($errSchemaPath) + '"; } ';
if (it.opts.verbose) {
out += ' ' + ($ruleErr) + '.schema = ' + ($schemaValue) + '; ' + ($ruleErr) + '.data = ' + ($data) + '; ';
}
out += ' } } ';
}
}
} else if ($macro) {
out += ' var err = '; /* 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 += ' {} ';
}
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; ';
}
}
} else {
if ($rDef.errors === false) {
out += ' ' + (def_customError) + ' ';
} else {
out += ' if (Array.isArray(' + ($ruleErrs) + ')) { if (vErrors === null) vErrors = ' + ($ruleErrs) + '; else vErrors = vErrors.concat(' + ($ruleErrs) + '); errors = vErrors.length; for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + '<errors; ' + ($i) + '++) { var ' + ($ruleErr) + ' = vErrors[' + ($i) + ']; if (' + ($ruleErr) + '.dataPath === undefined) ' + ($ruleErr) + '.dataPath = (dataPath || \'\') + ' + (it.errorPath) + '; ' + ($ruleErr) + '.schemaPath = "' + ($errSchemaPath) + '"; ';
if (it.opts.verbose) {
out += ' ' + ($ruleErr) + '.schema = ' + ($schemaValue) + '; ' + ($ruleErr) + '.data = ' + ($data) + '; ';
}
out += ' } } else { ' + (def_customError) + ' } ';
}
}
out += ' } ';
if ($breakOnError) {
out += ' else { ';
}
}
return out;
}
/***/ }),
/***/ "./node_modules/ajv/lib/dotjs/dependencies.js":
/*!****************************************************!*\
!*** ./node_modules/ajv/lib/dotjs/dependencies.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function generate_dependencies(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 $schemaDeps = {},
$propertyDeps = {},
$ownProperties = it.opts.ownProperties;
for ($property in $schema) {
var $sch = $schema[$property];
var $deps = Array.isArray($sch) ? $propertyDeps : $schemaDeps;
$deps[$property] = $sch;
}
out += 'var ' + ($errs) + ' = errors;';
var $currentErrorPath = it.errorPath;
out += 'var missing' + ($lvl) + ';';
for (var $property in $propertyDeps) {
$deps = $propertyDeps[$property];
if ($deps.length) {
out += ' if ( ' + ($data) + (it.util.getProperty($property)) + ' !== undefined ';
if ($ownProperties) {
out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($property)) + '\') ';
}
if ($breakOnError) {
out += ' && ( ';
var arr1 = $deps;
if (arr1) {
var $propertyKey, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$propertyKey = arr1[$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: \'' + ('dependencies') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { property: \'' + (it.util.escapeQuotes($property)) + '\', missingProperty: \'' + ($missingProperty) + '\', depsCount: ' + ($deps.length) + ', deps: \'' + (it.util.escapeQuotes($deps.length == 1 ? $deps[0] : $deps.join(", "))) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'should have ';
if ($deps.length == 1) {
out += 'property ' + (it.util.escapeQuotes($deps[0]));
} else {
out += 'properties ' + (it.util.escapeQuotes($deps.join(", ")));
}
out += ' when property ' + (it.util.escapeQuotes($property)) + ' is present\' ';
}
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++; ';
}
} else {
out += ' ) { ';
var arr2 = $deps;
if (arr2) {
var $propertyKey, i2 = -1,
l2 = arr2.length - 1;
while (i2 < l2) {
$propertyKey = arr2[i2 += 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: \'' + ('dependencies') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { property: \'' + (it.util.escapeQuotes($property)) + '\', missingProperty: \'' + ($missingProperty) + '\', depsCount: ' + ($deps.length) + ', deps: \'' + (it.util.escapeQuotes($deps.length == 1 ? $deps[0] : $deps.join(", "))) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'should have ';
if ($deps.length == 1) {
out += 'property ' + (it.util.escapeQuotes($deps[0]));
} else {
out += 'properties ' + (it.util.escapeQuotes($deps.join(", ")));
}
out += ' when property ' + (it.util.escapeQuotes($property)) + ' is present\' ';
}
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++; } ';
}
}
}
out += ' } ';
if ($breakOnError) {
$closingBraces += '}';
out += ' else { ';
}
}
}
it.errorPath = $currentErrorPath;
var $currentBaseId = $it.baseId;
for (var $property in $schemaDeps) {
var $sch = $schemaDeps[$property];
if ((it.opts.strictKeywords ? typeof $sch == 'object' && Object.keys($sch).length > 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) + '<errors; ' + ($i) + '++) { vErrors[' + ($i) + '].propertyName = ' + ($key) + '; } var err = '; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('propertyNames') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { propertyName: \'' + ($invalidName) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'property name \\\'' + ($invalidName) + '\\\' is invalid\' ';
}
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; ';
}
}
if ($breakOnError) {
out += ' break; ';
}
out += ' } }';
}
if ($breakOnError) {
out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {';
}
out = it.util.cleanUpCode(out);
return out;
}
/***/ }),
/***/ "./node_modules/ajv/lib/dotjs/ref.js":
/*!*******************************************!*\
!*** ./node_modules/ajv/lib/dotjs/ref.js ***!
\*******************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function generate_ref(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || '');
var $valid = 'valid' + $lvl;
var $async, $refCode;
if ($schema == '#' || $schema == '#/') {
if (it.isRoot) {
$async = it.async;
$refCode = 'validate';
} else {
$async = it.root.schema.$async === true;
$refCode = 'root.refVal[0]';
}
} else {
var $refVal = it.resolveRef(it.baseId, $schema, it.isRoot);
if ($refVal === undefined) {
var $message = it.MissingRefError.message(it.baseId, $schema);
if (it.opts.missingRefs == 'fail') {
it.logger.error($message);
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('$ref') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { ref: \'' + (it.util.escapeQuotes($schema)) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'can\\\'t resolve reference ' + (it.util.escapeQuotes($schema)) + '\' ';
}
if (it.opts.verbose) {
out += ' , schema: ' + (it.util.toQuotedString($schema)) + ' , 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++; ';
}
if ($breakOnError) {
out += ' if (false) { ';
}
} else if (it.opts.missingRefs == 'ignore') {
it.logger.warn($message);
if ($breakOnError) {
out += ' if (true) { ';
}
} else {
throw new it.MissingRefError(it.baseId, $schema, $message);
}
} else if ($refVal.inline) {
var $it = it.util.copy(it);
$it.level++;
var $nextValid = 'valid' + $it.level;
$it.schema = $refVal.schema;
$it.schemaPath = '';
$it.errSchemaPath = $schema;
var $code = it.validate($it).replace(/validate\.schema/g, $refVal.code);
out += ' ' + ($code) + ' ';
if ($breakOnError) {
out += ' if (' + ($nextValid) + ') { ';
}
} else {
$async = $refVal.$async === true || (it.async && $refVal.$async !== false);
$refCode = $refVal.code;
}
}
if ($refCode) {
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = '';
if (it.opts.passContext) {
out += ' ' + ($refCode) + '.call(this, ';
} else {
out += ' ' + ($refCode) + '( ';
}
out += ' ' + ($data) + ', (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 __callValidate = out;
out = $$outStack.pop();
if ($async) {
if (!it.async) throw new Error('async schema referenced by sync schema');
if ($breakOnError) {
out += ' var ' + ($valid) + '; ';
}
out += ' try { await ' + (__callValidate) + '; ';
if ($breakOnError) {
out += ' ' + ($valid) + ' = true; ';
}
out += ' } catch (e) { if (!(e instanceof ValidationError)) throw e; if (vErrors === null) vErrors = e.errors; else vErrors = vErrors.concat(e.errors); errors = vErrors.length; ';
if ($breakOnError) {
out += ' ' + ($valid) + ' = false; ';
}
out += ' } ';
if ($breakOnError) {
out += ' if (' + ($valid) + ') { ';
}
} else {
out += ' if (!' + (__callValidate) + ') { if (vErrors === null) vErrors = ' + ($refCode) + '.errors; else vErrors = vErrors.concat(' + ($refCode) + '.errors); errors = vErrors.length; } ';
if ($breakOnError) {
out += ' else { ';
}
}
}
return out;
}
/***/ }),
/***/ "./node_modules/ajv/lib/dotjs/required.js":
/*!************************************************!*\
!*** ./node_modules/ajv/lib/dotjs/required.js ***!
\************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function generate_required(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 $vSchema = 'schema' + $lvl;
if (!$isData) {
if ($schema.length < it.opts.loopRequired && it.schema.properties && Object.keys(it.schema.properties).length) {
var $required = [];
var arr1 = $schema;
if (arr1) {
var $property, i1 = -1,
l1 = arr1.length - 1;
while (i1 < l1) {
$property = arr1[i1 += 1];
var $propertySch = it.schema.properties[$property];
if (!($propertySch && (it.opts.strictKeywords ? typeof $propertySch == 'object' && Object.keys($propertySch).length > 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<dataType.length; i++)
_addRule(keyword, dataType[i], definition);
} else {
_addRule(keyword, dataType, definition);
}
var metaSchema = definition.metaSchema;
if (metaSchema) {
if (definition.$data && this._opts.$data) {
metaSchema = {
anyOf: [
metaSchema,
{ '$ref': 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/data.json#' }
]
};
}
definition.validateSchema = this.compile(metaSchema, true);
}
}
RULES.keywords[keyword] = RULES.all[keyword] = true;
function _addRule(keyword, dataType, definition) {
var ruleGroup;
for (var i=0; i<RULES.length; i++) {
var rg = RULES[i];
if (rg.type == dataType) {
ruleGroup = rg;
break;
}
}
if (!ruleGroup) {
ruleGroup = { type: dataType, rules: [] };
RULES.push(ruleGroup);
}
var rule = {
keyword: keyword,
definition: definition,
custom: true,
code: customRuleCode,
implements: definition.implements
};
ruleGroup.rules.push(rule);
RULES.custom[keyword] = rule;
}
return this;
}
/**
* Get keyword
* @this Ajv
* @param {String} keyword pre-defined or custom keyword.
* @return {Object|Boolean} custom keyword definition, `true` if it is a predefined keyword, `false` otherwise.
*/
function getKeyword(keyword) {
/* jshint validthis: true */
var rule = this.RULES.custom[keyword];
return rule ? rule.definition : this.RULES.keywords[keyword] || false;
}
/**
* Remove keyword
* @this Ajv
* @param {String} keyword pre-defined or custom keyword.
* @return {Ajv} this for method chaining
*/
function removeKeyword(keyword) {
/* jshint validthis: true */
var RULES = this.RULES;
delete RULES.keywords[keyword];
delete RULES.all[keyword];
delete RULES.custom[keyword];
for (var i=0; i<RULES.length; i++) {
var rules = RULES[i].rules;
for (var j=0; j<rules.length; j++) {
if (rules[j].keyword == keyword) {
rules.splice(j, 1);
break;
}
}
}
return this;
}
/**
* Validate keyword definition
* @this Ajv
* @param {Object} definition keyword definition object.
* @param {Boolean} throwError true to throw exception if definition is invalid
* @return {boolean} validation result
*/
function validateKeyword(definition, throwError) {
validateKeyword.errors = null;
var v = this._validateKeyword = this._validateKeyword
|| this.compile(definitionSchema, true);
if (v(definition)) return true;
validateKeyword.errors = v.errors;
if (throwError)
throw new Error('custom keyword definition is invalid: ' + this.errorsText(v.errors));
else
return false;
}
/***/ }),
/***/ "./node_modules/ajv/lib/refs/data.json":
/*!*********************************************!*\
!*** ./node_modules/ajv/lib/refs/data.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("N4KABBYEQCQM4GMAWBTAtgQygLmkgLvgA7YD0pAVnAPYB2AtIqpgHTUBOA5qQCbsYAzfPQAMAdlJN0GAMRQANOEiwAljxx5CROGVL8A7i04r8SAK4AjM3BTsEdfClr4W9tKRRFqF2ygBeANYqtKQYFABupJhwjuykADYqFnooAnC8GPgYLFR0coqQ0DwoiOwqRPgqdBpQALIoWYzI0mACHGAwPJkYYOypvrQIKGAAFABSAMoA8gByYBPNmGAoAB6OtHBVtGBE7NRecBjxAJQKShBQ+ACeRCg13hQoCPhnhVB9AI5mKn3quADa0E63SgYAAugVlLt9rZKiUNKBCm9gVkEeckW9rrcajEyrROK8MUioBhaFcpgINP90USkcBoG12JgXrh3ih4pkVOEUPRcgwvMFYqCAL7yMA02mQelQRnMmp8+gC5y2EUSjFgtVgYXo0Xokk8HgmLZHAAKe1u7DhcA0AiONhA2qAA"));
})()
/***/ }),
/***/ "./node_modules/ajv/lib/refs/json-schema-draft-07.json":
/*!*************************************************************!*\
!*** ./node_modules/ajv/lib/refs/json-schema-draft-07.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("N4KABBYEQCQM4GMAWBTAtgQygLmkgLvgA7YD0pAVnAPYB2AtIqpgHTUBOA5qQCbsYAzfPQAMAdlJN0GAMRQANOEiwAljxx5CJclTqNk0tl178hoiVMxzFkaPhX4ANig1QAwhxRhLGMGhT4GPrMWDbKPCgCKrQOKnRwGqC2tlA+AILs-ACeiUrJyVD4WUQuuFAYmRg5YfkpaNEAkvjoCbgAjDW1EFAOLYnQMOyRrnJgAL55yWOdKbR0AHIonBj2AG4oDbTNnCjsuV0pRSWu0du7CpNdUPUxaACuaBoil5DTL91ztIvLaxtbS7sACKRDB3Rz4ET7A7dDCORwAeQEGgA2u8DsABkMkWUZLxItFYvFSJ9visVOtNmc9uMZtCwBioBEBKDwU9xmjbABdNFvK5wFRoIjOAAqxRQrXpHOUKFoDxRUvy5Uq1QVBQARtRqM4MLQLnSCqcAXtadCoLK4Xr9cpZWg1ecTQcoNQ1RQUAh8JardA4Ph2NFOFBVdyurzaqlff6MtkoaajqVoBVow6Ur00BKGXHXD6-bQAzTVVA7jEAI53DbNNMaX1l5PhEFgj24ZHB2oTWyh7qZptOl1uj3yaAarUoHVQTmdKBEdjUErsezimMFGBqRdXLveiO5z2OgQcTCN6B3P30LG7GUIFw8h2wHyrsPr8M5gO17q79j71xHlSBkPXwbDXAkjpQoxSzTdnwLN8PzKL8T0iM9aAvH9Wz-BBqDQfwtjvRUH2zf1kPyDsCnsJx4yA2NQLKPCtyvNFGXFBA-SIew6Gw4jKI3J8CKma8mRZA9qxQa8hgwHh4VoRwckAgsHyHbVdRfaA+IbDRmUcOAUFoq4UAADwwQVnHTGSOKVJMC1TCVBK0sN7nBFQhRQRE2MOEybTtY0C10hBHDufl1gAWQJe5HlwZ5fzozAdIFOVpP1EDjjKNzzmsxUvJ8vyUH8jAouC5zlAfJK9hSgobmikLJTigqHnc7j22vNLfPJTKgpiirgKq21kvCq5IoAGRlTh8CQfpYCxEY8SiGIWNoOBiQWJYyQpf4dmpIi6mifrcyGkb-2xaBcSZAlptmkkFt+SkjWBZkG0hfMriIFZmnYXVYvakzqIguKoJWVwhh2HTatea9RJ4QlaFhJo+kAzEAP2qA7rDCy8phWgsicptVVsBldpGeG1rpbGxpxCajriGbJAMTAoyqPGg0U+jrtZXArO6mzsshytodG2GoAO-EprJk75p+JqLpWvHrxuDn0xhvbeZJgWiVOkWlqpK7+Nu-HuiLFRS3LKG2oohLB01eTtyuZSmbANSNOKlI0K2DBohl7m5dGLXoEigAFadZ3nF2ceJw7FfJ5XFr+KkJYi6IfZnXZ-Z2on9oVsGha+M7ReWoF63BTXhJQUsVCGdQucD5Pg9TyRwOpnIEcVEGwdhWO-ZUBdS6T3mo4t-nU+RuwTOdV13XNsMG+mpvffj1uA47936ctg9gDbFC6KnOO52nvv4vjHsh-7Asx7Jif14T9uebngsF8SZfCOvB7CF2Whm6ntvDcdB9B77Ef654UHx8cZ+G9X6E3Pl3YCa8-ZZHmPpYB0BvoHigH9XSYDTRX0AjfHidEIglFoBERCm9XpGx3p-Ye9ND50GPi3YBmNlA6jRntVEXp8ggLdigphEAWHjQrsdKuT4a603YS2aEGC6qr0nnOKBMCZ6gLrgUB2PoqzsBrHRGUrVyLvxMomGm9MkbMyUUJAsUsKwSg6AWHWetpaKLLHbfKHF1FXDoejMAjCmGcKDj3Hh-IDIoFFCUBIsj9T2KYdvVwWiVTsJTMYxO58U6eIFA5XxC4AnBKMQbUxETlDmLLJYvR1j2EiNqEIzBVx4EjVwuBNh9s6DNC2P5FAoMMCJLKe9CpyTugOxqfgAAoohagoMtxc3KVxNp0AVB7WAK7XGHtCioBevSSZOIoDTJQOpMiCy4bTNhAicZssuEeMFhTEI-CRnlFRk4tx5d9lEnSMqSpyg6COR2es+W3CDk3OjCcuYi9dmLPZKIlIaCwBWQmEAA"));
})()
/***/ }),
/***/ "./node_modules/circular-json/build/circular-json.node.js":
/*!****************************************************************!*\
!*** ./node_modules/circular-json/build/circular-json.node.js ***!
\****************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
/*!
Copyright (C) 2013-2017 by Andrea Giammarchi - @WebReflection
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
var
// should be a not so common char
// possibly one JSON does not encode
// possibly one encodeURIComponent does not encode
// right now this char is '~' but this might change in the future
specialChar = '~',
safeSpecialChar = '\\x' + (
'0' + specialChar.charCodeAt(0).toString(16)
).slice(-2),
escapedSafeSpecialChar = '\\' + safeSpecialChar,
specialCharRG = new RegExp(safeSpecialChar, 'g'),
safeSpecialCharRG = new RegExp(escapedSafeSpecialChar, 'g'),
safeStartWithSpecialCharRG = new RegExp('(?:^|([^\\\\]))' + escapedSafeSpecialChar),
indexOf = [].indexOf || function(v){
for(var i=this.length;i--&&this[i]!==v;);
return i;
},
$String = String // there's no way to drop warnings in JSHint
// about new String ... well, I need that here!
// faked, and happy linter!
;
function generateReplacer(value, replacer, resolve) {
var
doNotIgnore = false,
inspect = !!replacer,
path = [],
all = [value],
seen = [value],
mapp = [resolve ? specialChar : '[Circular]'],
last = value,
lvl = 1,
i, fn
;
if (inspect) {
fn = typeof replacer === 'object' ?
function (key, value) {
return key !== '' && replacer.indexOf(key) < 0 ? void 0 : value;
} :
replacer;
}
return function(key, value) {
// the replacer has rights to decide
// if a new object should be returned
// or if there's some key to drop
// let's call it here rather than "too late"
if (inspect) value = fn.call(this, key, value);
// first pass should be ignored, since it's just the initial object
if (doNotIgnore) {
if (last !== this) {
i = lvl - indexOf.call(all, this) - 1;
lvl -= i;
all.splice(lvl, all.length);
path.splice(lvl - 1, path.length);
last = this;
}
// console.log(lvl, key, path);
if (typeof value === 'object' && value) {
// if object isn't referring to parent object, add to the
// object path stack. Otherwise it is already there.
if (indexOf.call(all, value) < 0) {
all.push(last = value);
}
lvl = all.length;
i = indexOf.call(seen, value);
if (i < 0) {
i = seen.push(value) - 1;
if (resolve) {
// key cannot contain specialChar but could be not a string
path.push(('' + key).replace(specialCharRG, safeSpecialChar));
mapp[i] = specialChar + path.join(specialChar);
} else {
mapp[i] = mapp[0];
}
} else {
value = mapp[i];
}
} else {
if (typeof value === 'string' && resolve) {
// ensure no special char involved on deserialization
// in this case only first char is important
// no need to replace all value (better performance)
value = value .replace(safeSpecialChar, escapedSafeSpecialChar)
.replace(specialChar, safeSpecialChar);
}
}
} else {
doNotIgnore = true;
}
return value;
};
}
function retrieveFromPath(current, keys) {
for(var i = 0, length = keys.length; i < length; current = current[
// keys should be normalized back here
keys[i++].replace(safeSpecialCharRG, specialChar)
]);
return current;
}
function generateReviver(reviver) {
return function(key, value) {
var isString = typeof value === 'string';
if (isString && value.charAt(0) === specialChar) {
return new $String(value.slice(1));
}
if (key === '') value = regenerate(value, value, {});
// again, only one needed, do not use the RegExp for this replacement
// only keys need the RegExp
if (isString) value = value .replace(safeStartWithSpecialCharRG, '$1' + specialChar)
.replace(escapedSafeSpecialChar, safeSpecialChar);
return reviver ? reviver.call(this, key, value) : value;
};
}
function regenerateArray(root, current, retrieve) {
for (var i = 0, length = current.length; i < length; i++) {
current[i] = regenerate(root, current[i], retrieve);
}
return current;
}
function regenerateObject(root, current, retrieve) {
for (var key in current) {
if (current.hasOwnProperty(key)) {
current[key] = regenerate(root, current[key], retrieve);
}
}
return current;
}
function regenerate(root, current, retrieve) {
return current instanceof Array ?
// fast Array reconstruction
regenerateArray(root, current, retrieve) :
(
current instanceof $String ?
(
// root is an empty string
current.length ?
(
retrieve.hasOwnProperty(current) ?
retrieve[current] :
retrieve[current] = retrieveFromPath(
root, current.split(specialChar)
)
) :
root
) :
(
current instanceof Object ?
// dedicated Object parser
regenerateObject(root, current, retrieve) :
// value as it is
current
)
)
;
}
var CircularJSON = {
stringify: function stringify(value, replacer, space, doNotResolve) {
return CircularJSON.parser.stringify(
value,
generateReplacer(value, replacer, !doNotResolve),
space
);
},
parse: function parse(text, reviver) {
return CircularJSON.parser.parse(
text,
generateReviver(reviver)
);
},
// A parser should be an API 1:1 compatible with JSON
// it should expose stringify and parse methods.
// The default parser is the native JSON.
parser: JSON
};
module.exports = CircularJSON;
/***/ }),
/***/ "./node_modules/clipboard-copy/index.js":
/*!**********************************************!*\
!*** ./node_modules/clipboard-copy/index.js ***!
\**********************************************/
/*! no static exports found */
/***/ (function(module, exports) {
/* global DOMException */
module.exports = clipboardCopy
function clipboardCopy (text) {
// Use the Async Clipboard API when available. Requires a secure browing
// context (i.e. HTTPS)
if (navigator.clipboard) {
return navigator.clipboard.writeText(text).catch(function (err) {
throw (err !== undefined ? err : new DOMException('The request is not allowed', 'NotAllowedError'))
})
}
// ...Otherwise, use document.execCommand() fallback
// Put the text to copy into a <span>
var span = document.createElement('span')
span.textContent = text
// Preserve consecutive spaces and newlines
span.style.whiteSpace = 'pre'
// Add the <span> 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<self._howls.length; i++) {
if (!self._howls[i]._webAudio) {
// Get all of the sounds in this Howl group.
var ids = self._howls[i]._getSoundIds();
// Loop through all sounds and change the volumes.
for (var j=0; j<ids.length; j++) {
var sound = self._howls[i]._soundById(ids[j]);
if (sound && sound._node) {
sound._node.volume = sound._volume * vol;
}
}
}
}
return self;
}
return self._volume;
},
/**
* Handle muting and unmuting globally.
* @param {Boolean} muted Is muted or not.
*/
mute: function(muted) {
var self = this || Howler;
// If we don't have an AudioContext created yet, run the setup.
if (!self.ctx) {
setupAudioContext();
}
self._muted = muted;
// With Web Audio, we just need to mute the master gain.
if (self.usingWebAudio) {
self.masterGain.gain.setValueAtTime(muted ? 0 : self._volume, Howler.ctx.currentTime);
}
// Loop through and mute all HTML5 Audio nodes.
for (var i=0; i<self._howls.length; i++) {
if (!self._howls[i]._webAudio) {
// Get all of the sounds in this Howl group.
var ids = self._howls[i]._getSoundIds();
// Loop through all sounds and mark the audio node as muted.
for (var j=0; j<ids.length; j++) {
var sound = self._howls[i]._soundById(ids[j]);
if (sound && sound._node) {
sound._node.muted = (muted) ? true : sound._muted;
}
}
}
}
return self;
},
/**
* Unload and destroy all currently loaded Howl objects.
* @return {Howler}
*/
unload: function() {
var self = this || Howler;
for (var i=self._howls.length-1; 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<self.html5PoolSize; i++) {
try {
var audioNode = new Audio();
// Mark this Audio object as unlocked to ensure it can get returned
// to the unlocked pool when released.
audioNode._unlocked = true;
// Add the audio node to the pool.
self._releaseHtml5Audio(audioNode);
} catch (e) {
self.noAudio = true;
}
}
// Loop through any assigned audio nodes and unlock them.
for (var i=0; i<self._howls.length; i++) {
if (!self._howls[i]._webAudio) {
// Get all of the sounds in this Howl group.
var ids = self._howls[i]._getSoundIds();
// Loop through all sounds and unlock the audio nodes.
for (var j=0; j<ids.length; j++) {
var sound = self._howls[i]._soundById(ids[j]);
if (sound && sound._node && !sound._node._unlocked) {
sound._node._unlocked = true;
sound._node.load();
}
}
}
}
// Fix Android can not play in suspend state.
self._autoResume();
// Create an empty buffer.
var source = self.ctx.createBufferSource();
source.buffer = self._scratchBuffer;
source.connect(self.ctx.destination);
// Play the empty buffer.
if (typeof source.start === 'undefined') {
source.noteOn(0);
} else {
source.start(0);
}
// Calling resume() on a stack initiated by user gesture is what actually unlocks the audio on Android Chrome >= 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<self._howls.length; i++) {
self._howls[i]._emit('unlock');
}
};
};
// Setup a touch start listener to attempt an unlock in.
document.addEventListener('touchstart', unlock, true);
document.addEventListener('touchend', unlock, true);
document.addEventListener('click', unlock, true);
return self;
},
/**
* Get an unlocked HTML5 Audio object from the pool. If none are left,
* return a new Audio object and throw a warning.
* @return {Audio} HTML5 Audio object.
*/
_obtainHtml5Audio: function() {
var self = this || Howler;
// Return the next object from the pool if one exists.
if (self._html5AudioPool.length) {
return self._html5AudioPool.pop();
}
//.Check if the audio is locked and throw a warning.
var testPlay = new Audio().play();
if (testPlay && typeof Promise !== 'undefined' && (testPlay instanceof Promise || typeof testPlay.then === 'function')) {
testPlay.catch(function() {
console.warn('HTML5 Audio pool exhausted, returning potentially locked audio object.');
});
}
return new Audio();
},
/**
* Return an activated HTML5 Audio object to the pool.
* @return {Howler}
*/
_releaseHtml5Audio: function(audio) {
var self = this || Howler;
// Don't add audio to the pool if we don't know if it has been unlocked.
if (audio._unlocked) {
self._html5AudioPool.push(audio);
}
return self;
},
/**
* Automatically suspend the Web Audio AudioContext after no sound has played for 30 seconds.
* This saves processing/energy and fixes various browser-specific bugs with audio getting stuck.
* @return {Howler}
*/
_autoSuspend: function() {
var self = this;
if (!self.autoSuspend || !self.ctx || typeof self.ctx.suspend === 'undefined' || !Howler.usingWebAudio) {
return;
}
// Check if any sounds are playing.
for (var i=0; i<self._howls.length; i++) {
if (self._howls[i]._webAudio) {
for (var j=0; j<self._howls[i]._sounds.length; j++) {
if (!self._howls[i]._sounds[j]._paused) {
return self;
}
}
}
}
if (self._suspendTimer) {
clearTimeout(self._suspendTimer);
}
// If no sound has played after 30 seconds, suspend the context.
self._suspendTimer = setTimeout(function() {
if (!self.autoSuspend) {
return;
}
self._suspendTimer = null;
self.state = 'suspending';
self.ctx.suspend().then(function() {
self.state = 'suspended';
if (self._resumeAfterSuspend) {
delete self._resumeAfterSuspend;
self._autoResume();
}
});
}, 30000);
return self;
},
/**
* Automatically resume the Web Audio AudioContext when a new sound is played.
* @return {Howler}
*/
_autoResume: function() {
var self = this;
if (!self.ctx || typeof self.ctx.resume === 'undefined' || !Howler.usingWebAudio) {
return;
}
if (self.state === 'running' && self._suspendTimer) {
clearTimeout(self._suspendTimer);
self._suspendTimer = null;
} else if (self.state === 'suspended') {
self.ctx.resume().then(function() {
self.state = 'running';
// Emit to all Howls that the audio has resumed.
for (var i=0; i<self._howls.length; i++) {
self._howls[i]._emit('resume');
}
});
if (self._suspendTimer) {
clearTimeout(self._suspendTimer);
self._suspendTimer = null;
}
} else if (self.state === 'suspending') {
self._resumeAfterSuspend = true;
}
return self;
}
};
// Setup the global audio controller.
var Howler = new HowlerGlobal();
/** Group Methods **/
/***************************************************************************/
/**
* Create an audio group controller.
* @param {Object} o Passed in properties for this group.
*/
var Howl = function(o) {
var self = this;
// Throw an error if no source is provided.
if (!o.src || o.src.length === 0) {
console.error('An array of source files must be passed with any new Howl.');
return;
}
self.init(o);
};
Howl.prototype = {
/**
* Initialize a new Howl group object.
* @param {Object} o Passed in properties for this group.
* @return {Howl}
*/
init: function(o) {
var self = this;
// If we don't have an AudioContext created yet, run the setup.
if (!Howler.ctx) {
setupAudioContext();
}
// Setup user-defined default properties.
self._autoplay = o.autoplay || false;
self._format = (typeof o.format !== 'string') ? o.format : [o.format];
self._html5 = o.html5 || false;
self._muted = o.mute || false;
self._loop = o.loop || false;
self._pool = o.pool || 5;
self._preload = (typeof o.preload === 'boolean') ? o.preload : true;
self._rate = o.rate || 1;
self._sprite = o.sprite || {};
self._src = (typeof o.src !== 'string') ? o.src : [o.src];
self._volume = o.volume !== undefined ? o.volume : 1;
self._xhrWithCredentials = o.xhrWithCredentials || false;
// Setup all other default properties.
self._duration = 0;
self._state = 'unloaded';
self._sounds = [];
self._endTimers = {};
self._queue = [];
self._playLock = false;
// Setup event listeners.
self._onend = o.onend ? [{fn: o.onend}] : [];
self._onfade = o.onfade ? [{fn: o.onfade}] : [];
self._onload = o.onload ? [{fn: o.onload}] : [];
self._onloaderror = o.onloaderror ? [{fn: o.onloaderror}] : [];
self._onplayerror = o.onplayerror ? [{fn: o.onplayerror}] : [];
self._onpause = o.onpause ? [{fn: o.onpause}] : [];
self._onplay = o.onplay ? [{fn: o.onplay}] : [];
self._onstop = o.onstop ? [{fn: o.onstop}] : [];
self._onmute = o.onmute ? [{fn: o.onmute}] : [];
self._onvolume = o.onvolume ? [{fn: o.onvolume}] : [];
self._onrate = o.onrate ? [{fn: o.onrate}] : [];
self._onseek = o.onseek ? [{fn: o.onseek}] : [];
self._onunlock = o.onunlock ? [{fn: o.onunlock}] : [];
self._onresume = [];
// Web Audio or HTML5 Audio?
self._webAudio = Howler.usingWebAudio && !self._html5;
// Automatically try to enable audio.
if (typeof Howler.ctx !== 'undefined' && Howler.ctx && Howler.autoUnlock) {
Howler._unlockAudio();
}
// Keep track of this Howl group in the global controller.
Howler._howls.push(self);
// If they selected autoplay, add a play event to the load queue.
if (self._autoplay) {
self._queue.push({
event: 'play',
action: function() {
self.play();
}
});
}
// Load the source file unless otherwise specified.
if (self._preload) {
self.load();
}
return self;
},
/**
* Load the audio file.
* @return {Howler}
*/
load: function() {
var self = this;
var url = null;
// If no audio is available, quit immediately.
if (Howler.noAudio) {
self._emit('loaderror', null, 'No audio support.');
return;
}
// Make sure our source is in an array.
if (typeof self._src === 'string') {
self._src = [self._src];
}
// Loop through the sources and pick the first one that is compatible.
for (var i=0; i<self._src.length; i++) {
var ext, str;
if (self._format && self._format[i]) {
// If an extension was specified, use that instead.
ext = self._format[i];
} else {
// Make sure the source is a string.
str = self._src[i];
if (typeof str !== 'string') {
self._emit('loaderror', null, 'Non-string found in selected audio sources - ignoring.');
continue;
}
// Extract the file extension from the URL or base64 data URI.
ext = /^data:audio\/([^;,]+);/i.exec(str);
if (!ext) {
ext = /\.([^.]+)$/.exec(str.split('?', 1)[0]);
}
if (ext) {
ext = ext[1].toLowerCase();
}
}
// Log a warning if no extension was found.
if (!ext) {
console.warn('No file extension was found. Consider using the "format" property or specify an extension.');
}
// Check if this extension is available.
if (ext && Howler.codecs(ext)) {
url = self._src[i];
break;
}
}
if (!url) {
self._emit('loaderror', null, 'No codec support for selected audio sources.');
return;
}
self._src = url;
self._state = 'loading';
// If the hosting page is HTTPS and the source isn't,
// drop down to HTML5 Audio to avoid Mixed Content errors.
if (window.location.protocol === 'https:' && url.slice(0, 5) === 'http:') {
self._html5 = true;
self._webAudio = false;
}
// Create a new sound object and add it to the pool.
new Sound(self);
// Load and decode the audio data for playback.
if (self._webAudio) {
loadBuffer(self);
}
return self;
},
/**
* Play a sound or resume previous playback.
* @param {String/Number} sprite Sprite name for sprite playback or sound id to continue previous.
* @param {Boolean} internal Internal Use: true prevents event firing.
* @return {Number} Sound ID.
*/
play: function(sprite, internal) {
var self = this;
var id = null;
// Determine if a sprite, sound id or nothing was passed
if (typeof sprite === 'number') {
id = sprite;
sprite = null;
} else if (typeof sprite === 'string' && self._state === 'loaded' && !self._sprite[sprite]) {
// If the passed sprite doesn't exist, do nothing.
return null;
} else if (typeof sprite === 'undefined') {
// Use the default sound sprite (plays the full audio length).
sprite = '__default';
// Check if there is a single paused sound that isn't ended.
// If there is, play that sound. If not, continue as usual.
if (!self._playLock) {
var num = 0;
for (var i=0; i<self._sounds.length; i++) {
if (self._sounds[i]._paused && !self._sounds[i]._ended) {
num++;
id = self._sounds[i]._id;
}
}
if (num === 1) {
sprite = null;
} else {
id = null;
}
}
}
// Get the selected node, or get one from the pool.
var sound = id ? self._soundById(id) : self._inactiveSound();
// If the sound doesn't exist, do nothing.
if (!sound) {
return null;
}
// Select the sprite definition.
if (id && !sprite) {
sprite = sound._sprite || '__default';
}
// If the sound hasn't loaded, we must wait to get the audio's duration.
// We also need to wait to make sure we don't run into race conditions with
// the order of function calls.
if (self._state !== 'loaded') {
// Set the sprite value on this sound.
sound._sprite = sprite;
// Mark this sound as not ended in case another sound is played before this one loads.
sound._ended = false;
// Add the sound to the queue to be played on load.
var soundId = sound._id;
self._queue.push({
event: 'play',
action: function() {
self.play(soundId);
}
});
return soundId;
}
// Don't play the sound if an id was passed and it is already playing.
if (id && !sound._paused) {
// Trigger the play event, in order to keep iterating through queue.
if (!internal) {
self._loadQueue('play');
}
return sound._id;
}
// Make sure the AudioContext isn't suspended, and resume it if it is.
if (self._webAudio) {
Howler._autoResume();
}
// Determine how long to play for and where to start playing.
var seek = Math.max(0, sound._seek > 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<ids.length; i++) {
// Clear the end timer.
self._clearTimer(ids[i]);
// Get the sound.
var sound = self._soundById(ids[i]);
if (sound && !sound._paused) {
// Reset the seek position.
sound._seek = self.seek(ids[i]);
sound._rateSeek = 0;
sound._paused = true;
// Stop currently running fades.
self._stopFade(ids[i]);
if (sound._node) {
if (self._webAudio) {
// Make sure the sound has been created.
if (!sound._node.bufferSource) {
continue;
}
if (typeof sound._node.bufferSource.stop === 'undefined') {
sound._node.bufferSource.noteOff(0);
} else {
sound._node.bufferSource.stop(0);
}
// Clean up the buffer source.
self._cleanBuffer(sound._node);
} else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {
sound._node.pause();
}
}
}
// Fire the pause event, unless `true` is passed as the 2nd argument.
if (!arguments[1]) {
self._emit('pause', sound ? sound._id : null);
}
}
return self;
},
/**
* Stop playback and reset to start.
* @param {Number} id The sound ID (empty to stop all in group).
* @param {Boolean} internal Internal Use: true prevents event firing.
* @return {Howl}
*/
stop: function(id, internal) {
var self = this;
// If the sound hasn't loaded, add it to the load queue to stop when capable.
if (self._state !== 'loaded' || self._playLock) {
self._queue.push({
event: 'stop',
action: function() {
self.stop(id);
}
});
return self;
}
// If no id is passed, get all ID's to be stopped.
var ids = self._getSoundIds(id);
for (var i=0; i<ids.length; i++) {
// Clear the end timer.
self._clearTimer(ids[i]);
// Get the sound.
var sound = self._soundById(ids[i]);
if (sound) {
// Reset the seek position.
sound._seek = sound._start || 0;
sound._rateSeek = 0;
sound._paused = true;
sound._ended = true;
// Stop currently running fades.
self._stopFade(ids[i]);
if (sound._node) {
if (self._webAudio) {
// Make sure the sound's AudioBufferSourceNode has been created.
if (sound._node.bufferSource) {
if (typeof sound._node.bufferSource.stop === 'undefined') {
sound._node.bufferSource.noteOff(0);
} else {
sound._node.bufferSource.stop(0);
}
// Clean up the buffer source.
self._cleanBuffer(sound._node);
}
} else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {
sound._node.currentTime = sound._start || 0;
sound._node.pause();
// If this is a live stream, stop download once the audio is stopped.
if (sound._node.duration === Infinity) {
self._clearSound(sound._node);
}
}
}
if (!internal) {
self._emit('stop', sound._id);
}
}
}
return self;
},
/**
* Mute/unmute a single sound or all sounds in this Howl group.
* @param {Boolean} muted Set to true to mute and false to unmute.
* @param {Number} id The sound ID to update (omit to mute/unmute all).
* @return {Howl}
*/
mute: function(muted, id) {
var self = this;
// If the sound hasn't loaded, add it to the load queue to mute when capable.
if (self._state !== 'loaded'|| self._playLock) {
self._queue.push({
event: 'mute',
action: function() {
self.mute(muted, id);
}
});
return self;
}
// If applying mute/unmute to all sounds, update the group's value.
if (typeof id === 'undefined') {
if (typeof muted === 'boolean') {
self._muted = muted;
} else {
return self._muted;
}
}
// If no id is passed, get all ID's to be muted.
var ids = self._getSoundIds(id);
for (var i=0; i<ids.length; i++) {
// Get the sound.
var sound = self._soundById(ids[i]);
if (sound) {
sound._muted = muted;
// Cancel active fade and set the volume to the end value.
if (sound._interval) {
self._stopFade(sound._id);
}
if (self._webAudio && sound._node) {
sound._node.gain.setValueAtTime(muted ? 0 : sound._volume, Howler.ctx.currentTime);
} else if (sound._node) {
sound._node.muted = Howler._muted ? true : muted;
}
self._emit('mute', sound._id);
}
}
return self;
},
/**
* Get/set the volume of this sound or of the Howl group. This method can optionally take 0, 1 or 2 arguments.
* volume() -> 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<id.length; i++) {
// Get the sound.
sound = self._soundById(id[i]);
if (sound) {
sound._volume = vol;
// Stop currently running fades.
if (!args[2]) {
self._stopFade(id[i]);
}
if (self._webAudio && sound._node && !sound._muted) {
sound._node.gain.setValueAtTime(vol, Howler.ctx.currentTime);
} else if (sound._node && !sound._muted) {
sound._node.volume = vol * Howler.volume();
}
self._emit('volume', sound._id);
}
}
} else {
sound = id ? self._soundById(id) : self._sounds[0];
return sound ? sound._volume : 0;
}
return self;
},
/**
* Fade a currently playing sound between two volumes (if no id is passed, all sounds will fade).
* @param {Number} from The value to fade from (0.0 to 1.0).
* @param {Number} to The volume to fade to (0.0 to 1.0).
* @param {Number} len Time in milliseconds to fade.
* @param {Number} id The sound id (omit to fade all sounds).
* @return {Howl}
*/
fade: function(from, to, len, id) {
var self = this;
// If the sound hasn't loaded, add it to the load queue to fade when capable.
if (self._state !== 'loaded' || self._playLock) {
self._queue.push({
event: 'fade',
action: function() {
self.fade(from, to, len, id);
}
});
return self;
}
// Make sure the to/from/len values are numbers.
from = parseFloat(from);
to = parseFloat(to);
len = parseFloat(len);
// Set the volume to the start position.
self.volume(from, id);
// Fade the volume of one or all sounds.
var ids = self._getSoundIds(id);
for (var i=0; i<ids.length; i++) {
// Get the sound.
var sound = self._soundById(ids[i]);
// Create a linear fade or fall back to timeouts with HTML5 Audio.
if (sound) {
// Stop the previous fade if no sprite is being used (otherwise, volume handles this).
if (!id) {
self._stopFade(ids[i]);
}
// If we are using Web Audio, let the native methods do the actual fade.
if (self._webAudio && !sound._muted) {
var currentTime = Howler.ctx.currentTime;
var end = currentTime + (len / 1000);
sound._volume = from;
sound._node.gain.setValueAtTime(from, currentTime);
sound._node.gain.linearRampToValueAtTime(to, end);
}
self._startFadeInterval(sound, from, to, len, ids[i], typeof id === 'undefined');
}
}
return self;
},
/**
* Starts the internal interval to fade a sound.
* @param {Object} sound Reference to sound to fade.
* @param {Number} from The value to fade from (0.0 to 1.0).
* @param {Number} to The volume to fade to (0.0 to 1.0).
* @param {Number} len Time in milliseconds to fade.
* @param {Number} id The sound id to fade.
* @param {Boolean} isGroup If true, set the volume on the group.
*/
_startFadeInterval: function(sound, from, to, len, id, isGroup) {
var self = this;
var vol = from;
var diff = to - from;
var steps = Math.abs(diff / 0.01);
var stepLen = Math.max(4, (steps > 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<ids.length; i++) {
sound = self._soundById(ids[i]);
if (sound) {
sound._loop = loop;
if (self._webAudio && sound._node && sound._node.bufferSource) {
sound._node.bufferSource.loop = loop;
if (loop) {
sound._node.bufferSource.loopStart = sound._start || 0;
sound._node.bufferSource.loopEnd = sound._stop;
}
}
}
}
return self;
},
/**
* Get/set the playback rate of a sound. This method can optionally take 0, 1 or 2 arguments.
* rate() -> 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<id.length; i++) {
// Get the sound.
sound = self._soundById(id[i]);
if (sound) {
// Keep track of our position when the rate changed and update the playback
// start position so we can properly adjust the seek position for time elapsed.
if (self.playing(id[i])) {
sound._rateSeek = self.seek(id[i]);
sound._playStart = self._webAudio ? Howler.ctx.currentTime : sound._playStart;
}
sound._rate = rate;
// Change the playback rate.
if (self._webAudio && sound._node && sound._node.bufferSource) {
sound._node.bufferSource.playbackRate.setValueAtTime(rate, Howler.ctx.currentTime);
} else if (sound._node) {
sound._node.playbackRate = rate;
}
// Reset the timers.
var seek = self.seek(id[i]);
var duration = ((self._sprite[sound._sprite][0] + self._sprite[sound._sprite][1]) / 1000) - seek;
var timeout = (duration * 1000) / Math.abs(sound._rate);
// Start a new end timer if sound is already playing.
if (self._endTimers[id[i]] || !sound._paused) {
self._clearTimer(id[i]);
self._endTimers[id[i]] = setTimeout(self._ended.bind(self, sound), timeout);
}
self._emit('rate', sound._id);
}
}
} else {
sound = self._soundById(id);
return sound ? sound._rate : self._rate;
}
return self;
},
/**
* Get/set the seek position of a sound. This method can optionally take 0, 1 or 2 arguments.
* seek() -> 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<self._sounds.length; i++) {
if (!self._sounds[i]._paused) {
return true;
}
}
return false;
},
/**
* Get the duration of this sound. Passing a sound id will return the sprite duration.
* @param {Number} id The sound id to check. If none is passed, return full source duration.
* @return {Number} Audio duration in seconds.
*/
duration: function(id) {
var self = this;
var duration = self._duration;
// If we pass an ID, get the sound and return the sprite length.
var sound = self._soundById(id);
if (sound) {
duration = self._sprite[sound._sprite][1] / 1000;
}
return duration;
},
/**
* Returns the current loaded state of this Howl.
* @return {String} 'unloaded', 'loading', 'loaded'
*/
state: function() {
return this._state;
},
/**
* Unload and destroy the current Howl object.
* This will immediately stop all sound instances attached to this group.
*/
unload: function() {
var self = this;
// Stop playing any active sounds.
var sounds = self._sounds;
for (var i=0; i<sounds.length; i++) {
// Stop the sound if it is currently playing.
if (!sounds[i]._paused) {
self.stop(sounds[i]._id);
}
// Remove the source or disconnect.
if (!self._webAudio) {
// Set the source to 0-second silence to stop any downloading (except in IE).
self._clearSound(sounds[i]._node);
// Remove any event listeners.
sounds[i]._node.removeEventListener('error', sounds[i]._errorFn, false);
sounds[i]._node.removeEventListener(Howler._canPlayEvent, sounds[i]._loadFn, false);
// Release the Audio object back to the pool.
Howler._releaseHtml5Audio(sounds[i]._node);
}
// Empty out all of the nodes.
delete sounds[i]._node;
// Make sure all timers are cleared out.
self._clearTimer(sounds[i]._id);
}
// Remove the references in the global Howler object.
var index = Howler._howls.indexOf(self);
if (index >= 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<Howler._howls.length; i++) {
if (Howler._howls[i]._src === self._src || self._src.indexOf(Howler._howls[i]._src) >= 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<events.length; i++) {
var isId = (id === events[i].id);
if (fn === events[i].fn && isId || !fn && isId) {
events.splice(i, 1);
break;
}
}
} else if (event) {
// Clear out all events of this type.
self['_on' + event] = [];
} else {
// Clear out all events of every type.
var keys = Object.keys(self);
for (i=0; i<keys.length; i++) {
if ((keys[i].indexOf('_on') === 0) && Array.isArray(self[keys[i]])) {
self[keys[i]] = [];
}
}
}
return self;
},
/**
* Listen to a custom event and remove it once fired.
* @param {String} event Event name.
* @param {Function} fn Listener to call.
* @param {Number} id (optional) Only listen to events for this sound.
* @return {Howl}
*/
once: function(event, fn, id) {
var self = this;
// Setup the event listener.
self.on(event, fn, id, 1);
return self;
},
/**
* Emit all events of a specific type and pass the sound id.
* @param {String} event Event name.
* @param {Number} id Sound ID.
* @param {Number} msg Message to go with event.
* @return {Howl}
*/
_emit: function(event, id, msg) {
var self = this;
var events = self['_on' + event];
// Loop through event store and fire all functions.
for (var i=events.length-1; 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<self._sounds.length; i++) {
if (id === self._sounds[i]._id) {
return self._sounds[i];
}
}
return null;
},
/**
* Return an inactive sound from the pool or create a new one.
* @return {Sound} Sound playback object.
*/
_inactiveSound: function() {
var self = this;
self._drain();
// Find the first inactive node to recycle.
for (var i=0; i<self._sounds.length; i++) {
if (self._sounds[i]._ended) {
return self._sounds[i].reset();
}
}
// If no inactive node was found, create a new one.
return new Sound(self);
},
/**
* Drain excess inactive sounds from the pool.
*/
_drain: function() {
var self = this;
var limit = self._pool;
var cnt = 0;
var i = 0;
// If there are less sounds than the max pool size, we are done.
if (self._sounds.length < limit) {
return;
}
// Count the number of inactive sounds.
for (i=0; i<self._sounds.length; i++) {
if (self._sounds[i]._ended) {
cnt++;
}
}
// Remove excess inactive sounds, going in reverse order.
for (i=self._sounds.length - 1; 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<self._sounds.length; i++) {
ids.push(self._sounds[i]._id);
}
return ids;
} else {
return [id];
}
},
/**
* Load the sound back into the buffer source.
* @param {Sound} sound The sound object to work with.
* @return {Howl}
*/
_refreshBuffer: function(sound) {
var self = this;
// Setup the buffer source for playback.
sound._node.bufferSource = Howler.ctx.createBufferSource();
sound._node.bufferSource.buffer = cache[self._src];
// Connect to the correct node.
if (sound._panner) {
sound._node.bufferSource.connect(sound._panner);
} else {
sound._node.bufferSource.connect(sound._node);
}
// Setup looping and playback rate.
sound._node.bufferSource.loop = sound._loop;
if (sound._loop) {
sound._node.bufferSource.loopStart = sound._start || 0;
sound._node.bufferSource.loopEnd = sound._stop || 0;
}
sound._node.bufferSource.playbackRate.setValueAtTime(sound._rate, Howler.ctx.currentTime);
return self;
},
/**
* Prevent memory leaks by cleaning up the buffer source after playback.
* @param {Object} node Sound's audio node containing the buffer source.
* @return {Howl}
*/
_cleanBuffer: function(node) {
var self = this;
var isIOS = Howler._navigator && Howler._navigator.vendor.indexOf('Apple') >= 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<data.length; ++i) {
dataView[i] = data.charCodeAt(i);
}
decodeAudioData(dataView.buffer, self);
} else {
// Load the buffer from the URL.
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.withCredentials = self._xhrWithCredentials;
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
// Make sure we get a successful response back.
var code = (xhr.status + '')[0];
if (code !== '0' && code !== '2' && code !== '3') {
self._emit('loaderror', null, 'Failed loading audio file with status: ' + xhr.status + '.');
return;
}
decodeAudioData(xhr.response, self);
};
xhr.onerror = function() {
// If there is an error, switch to HTML5 Audio.
if (self._webAudio) {
self._html5 = true;
self._webAudio = false;
self._sounds = [];
delete cache[url];
self.load();
}
};
safeXhrSend(xhr);
}
};
/**
* Send the XHR request wrapped in a try/catch.
* @param {Object} xhr XHR to send.
*/
var safeXhrSend = function(xhr) {
try {
xhr.send();
} catch (e) {
xhr.onerror();
}
};
/**
* Decode audio data from an array buffer.
* @param {ArrayBuffer} arraybuffer The audio data.
* @param {Howl} self
*/
var decodeAudioData = function(arraybuffer, self) {
// Fire a load error if something broke.
var error = function() {
self._emit('loaderror', null, 'Decoding audio data failed.');
};
// Load the sound on success.
var success = function(buffer) {
if (buffer && self._sounds.length > 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<ids.length; i++) {
// Get the sound.
var sound = self._soundById(ids[i]);
if (sound) {
if (typeof pan === 'number') {
sound._stereo = pan;
sound._pos = [pan, 0, 0];
if (sound._node) {
// If we are falling back, make sure the panningModel is equalpower.
sound._pannerAttr.panningModel = 'equalpower';
// Check if there is a panner setup and create a new one if not.
if (!sound._panner || !sound._panner.pan) {
setupPanner(sound, pannerType);
}
if (pannerType === 'spatial') {
if (typeof sound._panner.positionX !== 'undefined') {
sound._panner.positionX.setValueAtTime(pan, Howler.ctx.currentTime);
sound._panner.positionY.setValueAtTime(0, Howler.ctx.currentTime);
sound._panner.positionZ.setValueAtTime(0, Howler.ctx.currentTime);
} else {
sound._panner.setPosition(pan, 0, 0);
}
} else {
sound._panner.pan.setValueAtTime(pan, Howler.ctx.currentTime);
}
}
self._emit('stereo', sound._id);
} else {
return sound._stereo;
}
}
}
return self;
};
/**
* Get/set the 3D spatial position of the audio source for this sound or group relative to the global listener.
* @param {Number} x The x-position of the audio source.
* @param {Number} y The y-position of the audio source.
* @param {Number} z The z-position of the audio source.
* @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.
* @return {Howl/Array} Returns self or the current 3D spatial position: [x, y, z].
*/
Howl.prototype.pos = function(x, y, z, 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 position when capable.
if (self._state !== 'loaded') {
self._queue.push({
event: 'pos',
action: function() {
self.pos(x, y, z, id);
}
});
return self;
}
// Set the defaults for optional 'y' & 'z'.
y = (typeof y !== 'number') ? 0 : y;
z = (typeof z !== 'number') ? -0.5 : z;
// Setup the group's spatial position if no ID is passed.
if (typeof id === 'undefined') {
// Return the group's spatial position if no parameters are passed.
if (typeof x === 'number') {
self._pos = [x, y, z];
} else {
return self._pos;
}
}
// Change the spatial position of one or all sounds in group.
var ids = self._getSoundIds(id);
for (var i=0; i<ids.length; i++) {
// Get the sound.
var sound = self._soundById(ids[i]);
if (sound) {
if (typeof x === 'number') {
sound._pos = [x, y, z];
if (sound._node) {
// Check if there is a panner setup and create a new one if not.
if (!sound._panner || sound._panner.pan) {
setupPanner(sound, 'spatial');
}
if (typeof sound._panner.positionX !== 'undefined') {
sound._panner.positionX.setValueAtTime(x, Howler.ctx.currentTime);
sound._panner.positionY.setValueAtTime(y, Howler.ctx.currentTime);
sound._panner.positionZ.setValueAtTime(z, Howler.ctx.currentTime);
} else {
sound._panner.setPosition(x, y, z);
}
}
self._emit('pos', sound._id);
} else {
return sound._pos;
}
}
}
return self;
};
/**
* Get/set the direction the audio source is pointing in the 3D cartesian coordinate
* space. Depending on how direction the sound is, based on the `cone` attributes,
* a sound pointing away from the listener can be quiet or silent.
* @param {Number} x The x-orientation of the source.
* @param {Number} y The y-orientation of the source.
* @param {Number} z The z-orientation of the source.
* @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.
* @return {Howl/Array} Returns self or the current 3D spatial orientation: [x, y, z].
*/
Howl.prototype.orientation = function(x, y, z, 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 orientation when capable.
if (self._state !== 'loaded') {
self._queue.push({
event: 'orientation',
action: function() {
self.orientation(x, y, z, id);
}
});
return self;
}
// Set the defaults for optional 'y' & 'z'.
y = (typeof y !== 'number') ? self._orientation[1] : y;
z = (typeof z !== 'number') ? self._orientation[2] : z;
// Setup the group's spatial orientation if no ID is passed.
if (typeof id === 'undefined') {
// Return the group's spatial orientation if no parameters are passed.
if (typeof x === 'number') {
self._orientation = [x, y, z];
} else {
return self._orientation;
}
}
// Change the spatial orientation of one or all sounds in group.
var ids = self._getSoundIds(id);
for (var i=0; i<ids.length; i++) {
// Get the sound.
var sound = self._soundById(ids[i]);
if (sound) {
if (typeof x === 'number') {
sound._orientation = [x, y, z];
if (sound._node) {
// Check if there is a panner setup and create a new one if not.
if (!sound._panner) {
// Make sure we have a position to setup the node with.
if (!sound._pos) {
sound._pos = self._pos || [0, 0, -0.5];
}
setupPanner(sound, 'spatial');
}
if (typeof sound._panner.orientationX !== 'undefined') {
sound._panner.orientationX.setValueAtTime(x, Howler.ctx.currentTime);
sound._panner.orientationY.setValueAtTime(y, Howler.ctx.currentTime);
sound._panner.orientationZ.setValueAtTime(z, Howler.ctx.currentTime);
} else {
sound._panner.setOrientation(x, y, z);
}
}
self._emit('orientation', sound._id);
} else {
return sound._orientation;
}
}
}
return self;
};
/**
* Get/set the panner node's attributes for a sound or group of sounds.
* This method can optionall take 0, 1 or 2 arguments.
* pannerAttr() -> 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<ids.length; i++) {
sound = self._soundById(ids[i]);
if (sound) {
// Merge the new values into the sound.
var pa = sound._pannerAttr;
pa = {
coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : pa.coneInnerAngle,
coneOuterAngle: typeof o.coneOuterAngle !== 'undefined' ? o.coneOuterAngle : pa.coneOuterAngle,
coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : pa.coneOuterGain,
distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : pa.distanceModel,
maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : pa.maxDistance,
refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : pa.refDistance,
rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : pa.rolloffFactor,
panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : pa.panningModel
};
// Update the panner values or create a new panner if none exists.
var panner = sound._panner;
if (panner) {
panner.coneInnerAngle = pa.coneInnerAngle;
panner.coneOuterAngle = pa.coneOuterAngle;
panner.coneOuterGain = pa.coneOuterGain;
panner.distanceModel = pa.distanceModel;
panner.maxDistance = pa.maxDistance;
panner.refDistance = pa.refDistance;
panner.rolloffFactor = pa.rolloffFactor;
panner.panningModel = pa.panningModel;
} else {
// Make sure we have a position to setup the node with.
if (!sound._pos) {
sound._pos = self._pos || [0, 0, -0.5];
}
// Create a new panner node.
setupPanner(sound, 'spatial');
}
}
}
return self;
};
/** Single Sound Methods **/
/***************************************************************************/
/**
* Add new properties to the core Sound init.
* @param {Function} _super Core Sound init method.
* @return {Sound}
*/
Sound.prototype.init = (function(_super) {
return function() {
var self = this;
var parent = self._parent;
// Setup user-defined default properties.
self._orientation = parent._orientation;
self._stereo = parent._stereo;
self._pos = parent._pos;
self._pannerAttr = parent._pannerAttr;
// Complete initilization with howler.js core Sound's init function.
_super.call(this);
// If a stereo or position was specified, set it up.
if (self._stereo) {
parent.stereo(self._stereo);
} else if (self._pos) {
parent.pos(self._pos[0], self._pos[1], self._pos[2], self._id);
}
};
})(Sound.prototype.init);
/**
* Override the Sound.reset method to clean up properties from the spatial plugin.
* @param {Function} _super Sound reset method.
* @return {Sound}
*/
Sound.prototype.reset = (function(_super) {
return function() {
var self = this;
var parent = self._parent;
// Reset all spatial plugin properties on this sound.
self._orientation = parent._orientation;
self._stereo = parent._stereo;
self._pos = parent._pos;
self._pannerAttr = parent._pannerAttr;
// If a stereo or position was specified, set it up.
if (self._stereo) {
parent.stereo(self._stereo);
} else if (self._pos) {
parent.pos(self._pos[0], self._pos[1], self._pos[2], self._id);
} else if (self._panner) {
// Disconnect the panner.
self._panner.disconnect(0);
self._panner = undefined;
parent._refreshBuffer(self);
}
// Complete resetting of the sound.
return _super.call(this);
};
})(Sound.prototype.reset);
/** Helper Methods **/
/***************************************************************************/
/**
* Create a new panner node and save it on the sound.
* @param {Sound} sound Specific sound to setup panning on.
* @param {String} type Type of panner to create: 'stereo' or 'spatial'.
*/
var setupPanner = function(sound, type) {
type = type || 'spatial';
// Create the new panner node.
if (type === 'spatial') {
sound._panner = Howler.ctx.createPanner();
sound._panner.coneInnerAngle = sound._pannerAttr.coneInnerAngle;
sound._panner.coneOuterAngle = sound._pannerAttr.coneOuterAngle;
sound._panner.coneOuterGain = sound._pannerAttr.coneOuterGain;
sound._panner.distanceModel = sound._pannerAttr.distanceModel;
sound._panner.maxDistance = sound._pannerAttr.maxDistance;
sound._panner.refDistance = sound._pannerAttr.refDistance;
sound._panner.rolloffFactor = sound._pannerAttr.rolloffFactor;
sound._panner.panningModel = sound._pannerAttr.panningModel;
if (typeof sound._panner.positionX !== 'undefined') {
sound._panner.positionX.setValueAtTime(sound._pos[0], Howler.ctx.currentTime);
sound._panner.positionY.setValueAtTime(sound._pos[1], Howler.ctx.currentTime);
sound._panner.positionZ.setValueAtTime(sound._pos[2], Howler.ctx.currentTime);
} else {
sound._panner.setPosition(sound._pos[0], sound._pos[1], sound._pos[2]);
}
if (typeof sound._panner.orientationX !== 'undefined') {
sound._panner.orientationX.setValueAtTime(sound._orientation[0], Howler.ctx.currentTime);
sound._panner.orientationY.setValueAtTime(sound._orientation[1], Howler.ctx.currentTime);
sound._panner.orientationZ.setValueAtTime(sound._orientation[2], Howler.ctx.currentTime);
} else {
sound._panner.setOrientation(sound._orientation[0], sound._orientation[1], sound._orientation[2]);
}
} else {
sound._panner = Howler.ctx.createStereoPanner();
sound._panner.pan.setValueAtTime(sound._stereo, Howler.ctx.currentTime);
}
sound._panner.connect(sound._node);
// Update the connections.
if (!sound._paused) {
sound._parent.pause(sound._id, true).play(sound._id, true);
}
};
})();
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../gulp/node_modules/webpack/buildin/global.js */ "./gulp/node_modules/webpack/buildin/global.js")))
/***/ }),
/***/ "./node_modules/json-schema-traverse/index.js":
/*!****************************************************!*\
!*** ./node_modules/json-schema-traverse/index.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var traverse = module.exports = function (schema, opts, cb) {
// Legacy support for v0.3.1 and earlier.
if (typeof opts == 'function') {
cb = opts;
opts = {};
}
cb = opts.cb || cb;
var pre = (typeof cb == 'function') ? cb : cb.pre || function() {};
var post = cb.post || function() {};
_traverse(opts, pre, post, schema, '', schema);
};
traverse.keywords = {
additionalItems: true,
items: true,
contains: true,
additionalProperties: true,
propertyNames: true,
not: true
};
traverse.arrayKeywords = {
items: true,
allOf: true,
anyOf: true,
oneOf: true
};
traverse.propsKeywords = {
definitions: true,
properties: true,
patternProperties: true,
dependencies: true
};
traverse.skipKeywords = {
default: true,
enum: true,
const: true,
required: true,
maximum: true,
minimum: true,
exclusiveMaximum: true,
exclusiveMinimum: true,
multipleOf: true,
maxLength: true,
minLength: true,
pattern: true,
format: true,
maxItems: true,
minItems: true,
uniqueItems: true,
maxProperties: true,
minProperties: true
};
function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
if (schema && typeof schema == 'object' && !Array.isArray(schema)) {
pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
for (var key in schema) {
var sch = schema[key];
if (Array.isArray(sch)) {
if (key in traverse.arrayKeywords) {
for (var i=0; i<sch.length; i++)
_traverse(opts, pre, post, sch[i], jsonPtr + '/' + key + '/' + i, rootSchema, jsonPtr, key, schema, i);
}
} else if (key in traverse.propsKeywords) {
if (sch && typeof sch == 'object') {
for (var prop in sch)
_traverse(opts, pre, post, sch[prop], jsonPtr + '/' + key + '/' + escapeJsonPtr(prop), rootSchema, jsonPtr, key, schema, prop);
}
} else if (key in traverse.keywords || (opts.allKeys && !(key in traverse.skipKeywords))) {
_traverse(opts, pre, post, sch, jsonPtr + '/' + key, rootSchema, jsonPtr, key, schema);
}
}
post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
}
}
function escapeJsonPtr(str) {
return str.replace(/~/g, '~0').replace(/\//g, '~1');
}
/***/ }),
/***/ "./node_modules/query-string/index.js":
/*!********************************************!*\
!*** ./node_modules/query-string/index.js ***!
\********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const strictUriEncode = __webpack_require__(/*! strict-uri-encode */ "./node_modules/strict-uri-encode/index.js");
const decodeComponent = __webpack_require__(/*! decode-uri-component */ "./node_modules/decode-uri-component/index.js");
const splitOnFirst = __webpack_require__(/*! split-on-first */ "./node_modules/split-on-first/index.js");
const isNullOrUndefined = value => 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 <https://mathiasbynens.be/notes/javascript-encoding>
* @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 <n,i> state to <m,0>,
// 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 <https://mathiasbynens.be/notes/javascript-encoding>
* @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 <a href="mailto:gary.court@gmail.com">Gary Court</a>
* @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<boolean>} */
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<typeof GameState>} */
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 <a href='https://soundcloud.com/pettersumelius' target='blank'>Peppsen</a>!",
"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 <a target='_blank' href='https://github.com/tobspr/shapez.io/tree/master/translations'>translation guide</a>!",
"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! <a href='https://steam.shapez.io' target='blank'>View steam page</a>",
"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 <strong>7th of June</strong> - Be sure to add it to your wishlist! <a href='https://steam.shapez.io' target='blank'>View on steam</a>",
"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 <a href='https://www.youtube.com/watch?v=KyorY1uIqiQ' target='_blank'>here</a>!",
"The <a href='https://steam.shapez.io' target='_blank'>steam page</a> 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.<number, JobEntry>} */
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<any>}
*/
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.<string, SpriteDefinition>,
* 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<string>} sprites
* @param {Array<string>} sounds
* @param {Array<AtlasDefinition>} atlases
* @returns {Promise<void>}
*/
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<string, Map<string, CacheEntry>>} */
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<ClickDetector>} */
window.activeClickDetectors = [];
}
// Store active click detectors so we can cancel them
/** @type {Array<ClickDetector>} */
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!<br /><br />
An anonymized crash report has been sent, and I will have a look as soon as possible.<br /><br />
If you have additional information how I can reproduce this error, please E-Mail me:&nbsp;
<a href="mailto:bugs@shapez.io?title=Application+Crash">bugs@shapez.io</a>`;
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<object>}
*/
getEntries() {
return this.entries;
}
/**
* Returns all registered ids
* @returns {Array<string>}
*/
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<ClickDetector>} */
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<MetaBuilding>} */
let gMetaBuildingRegistry = new _singleton_factory__WEBPACK_IMPORTED_MODULE_0__["SingletonFactory"]();
/** @type {Object.<string, Array<Class<MetaBuilding>>>} */
let gBuildingsByCategory = null;
/** @type {FactoryTemplate<Component>} */
let gComponentRegistry = new _factory__WEBPACK_IMPORTED_MODULE_1__["Factory"]("component");
/** @type {FactoryTemplate<BaseGameSpeed>} */
let gGameSpeedRegistry = new _factory__WEBPACK_IMPORTED_MODULE_1__["Factory"]("gamespeed");
/** @type {FactoryTemplate<BaseItem>} */
let gItemRegistry = new _factory__WEBPACK_IMPORTED_MODULE_1__["Factory"]("item");
// Helpers
/**
* @param {Object.<string, Array<Class<MetaBuilding>>>} 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<InputReceiver>} */
this.recieverStack = [];
/** @type {Array<function(any) : boolean>} */
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<string, BaseSprite>} */
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<HTMLImageElement|null>}
*/
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<void>}
*/
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<void>}
*/
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<any>} 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 <pieroxy@pieroxy.net>
// 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<string>} 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 = "<div class='optionParent'>";
options.options.forEach(({ value, text, desc = null, iconPrefix = null }) => {
const descHtml = desc ? `<span class="desc">${desc}</span>` : "";
let iconHtml = iconPrefix ? `<span class="icon icon-${iconPrefix}-${value}"></span>` : "";
html += `
<div class='option ${value === options.active ? "active" : ""} ${
iconPrefix ? "hasIcon" : ""
}' data-optionvalue='${value}'>
${iconHtml}
<span class='title'>${text}</span>
${descHtml}
</div>
`;
});
html += "</div>";
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<FormElement>} param0.formElements
*/
constructor({ app, title, desc, formElements, buttons = ["cancel", "ok:good"], confirmButtonId = "ok" }) {
let html = "";
html += desc + "<br>";
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 `
<div class="formElement input">
${this.label ? `<label>${this.label}</label>` : ""}
<input
type="${inputType}"
value="${this.defaultValue.replace(/["\\]+/gi, "")}"
maxlength="${maxlength}"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
class="${classes.join(" ")}"
placeholder="${this.placeholder.replace(/["\\]+/gi, "")}"
data-formId="${this.id}">
</div>
`;
}
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 `
<div class="formElement checkBoxFormElem">
${this.label ? `<label>${this.label}</label>` : ""}
<div class="checkbox ${this.defaultValue ? "checked" : ""}" data-formId='${this.id}'>
<span class="knob"></span >
</div >
</div>
`;
}
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<void>}
*/
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<void>}
*/
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<Promise>} */
this.pendingPromises = [];
}
/**
*
* @param {Promise<any>} promise
* @returns {Promise<any>}
*/
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 <baagoe@baagoe.com>, 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<object>}
*/
getEntries() {
return this.entries;
}
/**
* Returns all registered ids
* @returns {Array<string>}
*/
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.<string, SpriteAtlasLink>} */
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 `
<span class="spritesheetImage" style="
background-image: url('${srcSafe}');
left: ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(leftRelative * 100.0)}%;
top: ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(topRelative * 100.0)}%;
width: ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(widthRelative * 100.0)}%;
height: ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(heightRelative * 100.0)}%;
background-repeat: repeat;
background-position: ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(bgXRelative * 100.0)}% ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(
bgYRelative * 100.0
)}%;
background-size: ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(bgW * 100.0)}% ${Object(_utils__WEBPACK_IMPORTED_MODULE_2__["round3Digits"])(bgH * 100.0)}%;
"></span>
`;
}
}
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.<string, new() => 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 `
<div class="content mainContent">
${this.getMainContentHTML()}
</div>
`;
}
/**
* 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 = `
<div class="headerBar">
<h1><button class="backButton"></button> ${this.getStateHeaderTitle()}</h1>
</div>`;
}
return `
${headerHtml}
<div class="container">
${this.getInnerHTML()}
</div>
`;
}
//// 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<Array<any>>}
*/
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<string>} 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<any>} 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<any>} 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<any>} 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<any>} 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<any>} 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<void>}
*/
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<string>=} 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<string>=} 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<string>=} 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<string>=} 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("<x>", "" + 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("<x>", "" + 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("<x>", "" + 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("<x>", "" + 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("<seconds>", "" + secs);
} else if (secs < 60 * 60) {
const minutes = Math.floor(secs / 60);
const seconds = secs % 60;
return trans.minutesAndSecondsShort
.replace("<seconds>", "" + seconds)
.replace("<minutes>", "" + minutes);
} else {
const hours = Math.floor(secs / 3600);
const minutes = Math.floor(secs / 60) % 60;
return trans.hoursAndMinutesShort.replace("<minutes>", "" + minutes).replace("<hours>", "" + 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(
"<x>",
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<number>} 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<number>} originalMatrix
* @returns {Object<number, Array<number>>}
*/
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<enumDirection>} */
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<Entity>} 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<any>} 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<Entity>} 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<number>} 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<number, BuildingVariantIdentifier>}
*/
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<Entity> }}
*/
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("<x>", "" + 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<Entity> }}
*/
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<Entity> }}
*/
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.<string, Object>} */
const enumColorMixingResults = {};
/**
* @typedef {Object} ColorData
* @property {string} id
* @property {string} code
* @property {string} hex
* @property {string[][] | string[]} [mixingFrom]
* @property {Object.<string, string>} [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.<string, string>} [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<enumDirection, import("./item_ejector").ItemEjectorSlot>} */
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<ItemAcceptorSlotConfig>} 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<ItemAcceptorSlotConfig>} slots
*/
setSlots(slots) {
/** @type {Array<ItemAcceptorSlot>} */
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<ItemEjectorSlot>} */
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<BaseItem>}
*/
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<import("../systems/wire").WireNetwork>}
*/
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<WirePinSlotDefinition>} 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<WirePinSlotDefinition>} slots
*/
setSlots(slots) {
/** @type {Array<WirePinSlot>} */
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.<string, string>} [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 <strong>Checker</strong>, the king of Automation." +
" - Set it a simple filter - a <strong>shape quad</strong> or a <strong>colored quad</strong>" +
" and it will <strong>select path</strong> depending on <strong>current Hub Goal</strong>, itself, forever!" +
" In case you need some more advanced options, <strong>layer</strong> quads to filter a higher layer," +
" color 3 of 4 quads for <strong>uncolored</strong> or leave a single <strong>hole</strong> 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 <strong>Quaduo painter</strong> - 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 <strong>Inverter</strong> allows you to obtain a new <strong>black</strong> color as well as the good old <strong>grey</strong>.",
},
};
/** @type {ModLevel} */
const counter = {
id: "counter",
goal: {
shape: "RwCwSbCw:RcCwSrCw:RwCwSyCw", // onion rocket
required: 12.5e3,
reward: "counter",
title: "The Speed Unravelled",
desc:
"The <strong>Counter</strong> 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: "<strong>unstacker</strong> 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 <strong>Freeplay</strong> 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 <strong>Checker</strong> and make a fully automated Ultimate Factory that can produce Anywhing! <strong>Onwards, to FREEPLAY!!!</strong>",
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<Entity>} */
this.entities = [];
// We store a seperate list with entities to destroy, since we don't destroy
// them instantly
/** @type {Array<Entity>} */
this.destroyList = [];
// Store a map from componentid to entities - This is used by the game system
// for faster processing
/** @type {Object.<string, Array<Entity>>} */
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<Entity>} entities
*/
getAllWithComponent(componentHandle) {
return this.componentToEntity[componentHandle.getId()] || [];
}
/**
* Return all of a given class. This is SLOW!
* @param {object} entityClass
* @returns {Array<Entity>} 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<typeof Component>} 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<Entity>}
*/
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.<string, number>}
*/
this.gainedRewards = {};
/**
* Mapping from shape hash -> amount
* @type {Object<string, number>}
*/
this.storedShapes = {};
/**
* Stores the levels for all upgrades
* @type {Object<string, number>}
*/
this.upgradeLevels = {};
/**
* Stores the improvements for all upgrades
* @type {Object<string, number>}
*/
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<import("./shape_definition").ShapeLayer>} */
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<ClickDetector>} */
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<number>]>} */ (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<typeof MetaBuilding>} 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.<string, {
* metaBuilding: MetaBuilding,
* unlocked: boolean,
* selected: boolean,
* element: HTMLElement,
* index: number
* }>} */
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<Blueprint?>} */
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<number>} 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<ClickDetector>}
*/
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(
"<key>",
"<code class='keybinding'>" + binding.getKeyCodeString() + "</code>"
);
} 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 += `
<label>${label}:</label>
<span>${contents}</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(
"<key>",
"<code class='keybinding'>" +
this.root.keyMapper
.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_8__["KEYMAPPINGS"].placement.cycleBuildingVariants)
.getKeyCodeString() +
"</code>"
)
);
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<MetaBuilding?>}
*/
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.<string,number>}
*/
this.preferredBaseRotations = {};
/**
* Whether we are currently dragging
* @type {boolean}
*/
this.currentlyDragging = false;
/**
* Current building variant
* @type {TypedTrackedState<string>}
*/
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.<string, string>}
*/
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<DebugChange>} */
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: <code>${mouseTile.x}</code> / <code>${mouseTile.y}</code>`);
this.trackedCameraPosition.set(`Camera: <code>${cameraTile.x}</code> / <code>${cameraTile.y}</code>`);
}
/**
* 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: <span class="mousePos"></span><br>
Chunk below cursor: <span class="chunkPos"></span><br>
<div class="entityInfo"></div>
`
);
/** @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) =>
`<span class='flag' data-value='${val ? "1" : "0"}'><u>${name}</u> ${val}</span>`;
html += "<div class='entityFlags'>";
html += flag("registered", entity.registered);
html += flag("uid", entity.uid);
html += flag("destroyed", entity.destroyed);
html += "</div>";
html += "<div class='components'>";
for (const componentId in entity.components) {
const data = entity.components[componentId];
html += "<div class='component'>";
html += "<strong class='name'>" + componentId + "</strong>";
html += "<textarea class='data'>" + JSON.stringify(data.serialize(), null, 2) + "</textarea>";
html += "</div>";
}
html += "</div>";
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"],
`
<strong class="title">${_translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.interactiveTutorial.title}</strong>
`
);
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<KeyCode|number|string>,
* 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<KeyBinding>} */
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 += `<code class="keybinding leftMouse"></code>`;
break;
case _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_RMB"]:
html += `<code class="keybinding rightMouse"></code>`;
break;
case _key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["KEYCODE_MMB"]:
html += `<code class="keybinding middleMouse"></code>`;
break;
case DIVIDER_TOKEN:
html += `<i></i>`;
break;
case ADDER_TOKEN:
html += `+`;
break;
default:
html += `<code class="keybinding">${Object(_key_action_mapper__WEBPACK_IMPORTED_MODULE_2__["getStringForKeyCode"])(
mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode
)}</code>`;
}
}
html += `<label>${handle.label}</label>`;
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(
"<count>",
"" + 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(
"<count>",
"" + 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<string>} 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<string>} 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>", 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<string>}
*/
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<string>}} 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",
[],
`
<label>Sandbox Options</label>
<span class="hint">Use F6 to toggle this overlay</span>
<div class="buttons">
<div class="levelToggle plusMinus">
<label>Level</label>
<button class="styledButton minus">-</button>
<button class="styledButton plus">+</button>
</div>
<div class="upgradesBelt plusMinus">
<label>Upgrades &rarr; Belt</label>
<button class="styledButton minus">-</button>
<button class="styledButton plus">+</button>
</div>
<div class="upgradesExtraction plusMinus">
<label>Upgrades &rarr; Extraction</label>
<button class="styledButton minus">-</button>
<button class="styledButton plus">+</button>
</div>
<div class="upgradesProcessing plusMinus">
<label>Upgrades &rarr; Processing</label>
<button class="styledButton minus">-</button>
<button class="styledButton plus">+</button>
</div>
<div class="upgradesPainting plusMinus">
<label>Upgrades &rarr; Painting</label>
<button class="styledButton minus">-</button>
<button class="styledButton plus">+</button>
</div>
<div class="additionalOptions">
<button class="styledButton giveBlueprints">Fill blueprint shapes</button>
<button class="styledButton maxOutAll">Max out all</button>
</div>
</div>
`
);
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"],
`
<strong>${_translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.beltsPlaced}</strong><span class="beltsPlaced"></span>
<strong>${_translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.buildingsPlaced}</strong><span class="buildingsPlaced"></span>
<strong>${_translations__WEBPACK_IMPORTED_MODULE_5__["T"].ingame.settingsMenu.playtime}</strong><span class="playtime"></span>
`
);
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("<x>", `${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(
"<x>",
"" + _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(
"<currentMult>",
currentTierMultiplier.toString()
);
continue;
}
// Set description
handle.elemDescription.innerText = _translations__WEBPACK_IMPORTED_MODULE_3__["T"].shopUpgrades[upgradeId].description
.replace("<currentMult>", currentTierMultiplier.toString())
.replace("<newMult>", (currentTierMultiplier + tierHandle.improvement).toString())
// Backwards compatibility
.replace("<gain>", (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.<string, HUDShapeStatisticsHandle>} */
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 = `
<strong class="noEntries">${_translations__WEBPACK_IMPORTED_MODULE_7__["T"].ingame.statistics.noShapesProduced}</strong>`;
}
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(
"<shapes>",
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",
[],
`
<div class="header">
<span>${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].ingame.tutorialHints.title}</span>
<button class="styledButton toggleHint">
<span class="show">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].ingame.tutorialHints.showHint}</span>
<span class="hide">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].ingame.tutorialHints.hideHint}</span>
</button>
</div>
<video autoplay muted loop class="fullscreenBackgroundVideo">
<source type="video/webm">
</video>
`
);
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>",
("" + level).padStart(2, "0")
);
const rewardName = _translations__WEBPACK_IMPORTED_MODULE_4__["T"].storyRewards[reward].title;
let html = `
<div class="rewardName">
${_translations__WEBPACK_IMPORTED_MODULE_4__["T"].ingame.levelCompleteNotification.unlockText.replace("<reward>", rewardName)}
</div>
<div class="rewardDesc">
${_translations__WEBPACK_IMPORTED_MODULE_4__["T"].storyRewards[reward].desc}
</div>
`;
html += "<div class='images'>";
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 += `<div class="buildingExplanation" data-icon="building_tutorials/${
metaBuilding.getId() + (variant === _meta_building__WEBPACK_IMPORTED_MODULE_5__["defaultBuildingVariant"] ? "" : "-" + variant)
}.png"></div>`;
});
}
html += "</div>";
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",
[],
`
<strong class='title'>${_translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.waypoints}</strong>
<span class='desc'>${_translations__WEBPACK_IMPORTED_MODULE_10__["T"].ingame.waypoints.description.replace(
"<keybinding>",
`<code class='keybinding'>${this.root.keyMapper
.getBinding(_key_action_mapper__WEBPACK_IMPORTED_MODULE_12__["KEYMAPPINGS"].navigation.createMarker)
.getKeyCodeString()}</code>`
)}</span>
`
);
}
// 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<Waypoint>}} 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<Waypoint>}
*/
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<string, number>}
*/
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<enumColors, ColorItem>}
*/
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.<string, Keybinding>} */
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<Keybinding>}
*/
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<string>} 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<WireNetwork>|null} Null if the entity is never able to be connected at the given tile
*/
getEntityWireNetworks(entity, tile) {
let canConnectAtAll = false;
/** @type {Set<WireNetwork>} */
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<string, MapChunkView>} */
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>} 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<Array<?BaseItem>>}
*/
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<Array<?Entity>>}
*/
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<Array<?Entity>>}
*/
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<Entity>} */
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<Layer, Array<Entity>>}
*/
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.<enumSubShape, number>} 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<Entity>}
*/
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<number>|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<Entity> }}
*/
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, <historyOffset> 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<Layer>} */
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.<string, Object.<string, RandomNumberGenerator>>} */
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<import("./shape_definition").ShapeLayer>}
*/
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<string, boolean>}
*/
const SHORT_KEY_CACHE = new Map();
/**
* Cache of definitions
* @type {Map<string, ShapeDefinition>}
*/
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<ShapeLayer>} */ (definition.layers);
}
serialize() {
return this.getHash();
}
/** @returns {ShapeDefinition} */
static createFromHash(hash) {
return ShapeDefinition.fromShortKey(hash);
}
/**
*
* @param {object} param0
* @param {Array<ShapeLayer>=} param0.layers
*/
constructor({ layers = [] }) {
super();
/**
* The layers from bottom to top
* @type {Array<ShapeLayer>}
*/
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<ShapeLayer>}
*/
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<number>} 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<string, ShapeDefinition>}
*/
this.shapeKeyToDefinition = {};
/**
* Store a cache from key -> item
*/
this.shapeKeyToItem = {};
// Caches operations in the form of 'operation:def1[:def2]'
/** @type {Object.<string, Array<ShapeDefinition>|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.<enumDirection, Array<AtlasSprite>>}
*/
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.<enumDirection, Array<AtlasSprite>>}
*/
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<BeltPath>} */
this.beltPaths = [];
}
/**
* Serializes all belt paths
* @returns {Array<object>}
*/
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<any>} 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<BeltPath>} */
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<string, import("../../core/draw_utils").AtlasSprite>} */
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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<BaseItem|null>} 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<import("../shape_definition").ShapeLayer>} */ (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<BaseItem|null>} 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<BaseItem|null>} 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<number>} */
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<number>}
*/
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<Entity>}
*/
this.tunnels = [];
/**
* Which wires are in this network
* @type {Array<Entity>}
*/
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<WireNetwork>}
*/
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 : "<empty>") +
" 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 : "<empty>") +
" 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<enumDirection>} directions
* @param {WireNetwork} network
* @returns {Array<any>}
*/
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<enumWireType, import("../../core/draw_utils").AtlasSprite>, 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<string, {name: string, data: any, code: string, region: string}>}
*/
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<void>}
*/
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<void>}
*/
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<void>}
*/
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<void>}
*/
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<any>}
*/
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<void>} */
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<boolean>}
*/
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.<number, {resolve:Function, reject: Function}>} */
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<void>}
*/
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<void>} */
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<void>} */
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<string, SoundInstanceInterface>} */
this.sounds = Object(_core_utils__WEBPACK_IMPORTED_MODULE_0__["newEmptyMap"])();
/** @type {Object<string, MusicInstanceInterface>} */
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<any>}
*/
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<void>}
*/
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<void>}
*/
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<void>}
*/
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<void>}
*/
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<FILE_NOT_FOUND> if file was not found.
* @param {string} filename
* @returns {Promise<string>}
*/
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<void>}
*/
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<void>} */
initialize() {
document.documentElement.classList.add("p-" + this.getId());
return Promise.resolve();
}
/**
* Should initialize the apps ad provider in case supported
* @returns {Promise<void>}
*/
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<BaseSetting>} */
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.<string, number>}
*/
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 `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].demo.settingNotAvailable}</span>`}
<div class="row">
<label>${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].title}</label>
<div class="value enum" data-setting="${this.id}"></div>
</div>
<div class="desc">
${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].description}
</div>
</div>`;
}
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 `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].demo.settingNotAvailable}</span>`}
<div class="row">
<label>${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].title}</label>
<div class="value checkbox checked" data-setting="${this.id}">
<span class="knob"></span>
</div>
</div>
<div class="desc">
${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].settings.labels[this.id].description}
</div>
</div>`;
}
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<any>}
*/
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.<number, typeof BaseSavegameInterface>} */
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<SavegameMetadata>}
*/
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<any>}
*/
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<string, any>} 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.<string, BaseDataType>} 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.<string, BaseDataType>} 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.<string, any>} 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.<string, BaseDataType>} 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<Entity>} 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<any>} 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.<string, any>} 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 `
<div class="head">
<img src="${Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_3__["cachebust"])("res/logo.png")}" alt="shapez.io Logo">
</div>
<div class="text">
${_translations__WEBPACK_IMPORTED_MODULE_1__["T"].about.body
.replace("<githublink>", _core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].github)
.replace("<discordlink>", _core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].discord)}
</div>
`;
}
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 += `
<div class="entry">
<span class="version">${entry.version}</span>
<span class="date">${entry.date}</span>
<ul class="changes">
${entry.entries.map(text => `<li>${text}</li>`).join("")}
</ul>
</div>
`;
}
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 `
<div class="sidebar">
${this.getCategoryButtonsHtml()}
<div class="other">
<button class="styledButton about">${_translations__WEBPACK_IMPORTED_MODULE_2__["T"].about.title}</button>
<div class="versionbar">
<div class="buildVersion">${_translations__WEBPACK_IMPORTED_MODULE_2__["T"].global.loading} ...</div>
</div>
</div>
</div>
<div class="categoryContainer">
<div class="category keybindings" data-category="keybindings">
<div class="topEntries">
<span class="hint">${_translations__WEBPACK_IMPORTED_MODULE_2__["T"].keybindings.hint}</span>
<button class="styledButton resetBindings">${_translations__WEBPACK_IMPORTED_MODULE_2__["T"].keybindings.resetKeybindings}</button>
</div>
</div>
${this.getSettingsHtml()}
</div>
`;
}
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 = `
<h3>${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].demoBanners.title}</h3>
<p>${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].demoBanners.intro}</p>
<a href="#" class="steamLink" target="_blank">Get the shapez.io standalone!</a>
`;
return `
<div class="topButtons">
<button class="languageChoose" data-languageicon="${this.app.settings.getLanguage()}"></button>
<button class="settingsButton"></button>
${
true
? `
<button class="exitAppButton"></button>
`
: undefined
}
</div>
<video autoplay muted loop class="fullscreenBackgroundVideo">
<source src="${Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_1__["cachebust"])("res/bg_render.webm")}" type="video/webm">
</video>
<div class="logo">
<img src="${Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_1__["cachebust"])("res/logo.png")}" alt="shapez.io Logo">
<span class="updateLabel bigger">MODZ</span>
</div>
<div class="mainWrapper ${_core_config__WEBPACK_IMPORTED_MODULE_2__["IS_DEMO"] ? "demo" : "noDemo"}">
<div class="sideContainer">
${_core_config__WEBPACK_IMPORTED_MODULE_2__["IS_DEMO"] ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""}
</div>
<div class="mainContainer">
${
Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["isSupportedBrowser"])()
? ""
: `<div class="browserWarning">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.browserWarning}</div>`
}
<div class="buttons"></div>
</div>
</div>
<div class="footer">
<a class="githubLink boxLink" target="_blank">
${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.openSourceHint}
<span class="thirdpartyLogo githubLogo"></span>
</a>
<a class="discordLink boxLink" target="_blank">
${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.discordLink}
<span class="thirdpartyLogo discordLogo"></span>
</a>
<div class="sidelinks">
<a class="redditLink">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.subreddit}</a>
<a class="changelog">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].changelog.title}</a>
<a class="helpTranslate">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.helpTranslate}</a>
</div>
<div class="author">${_translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.madeBy.replace(
"<author-link>",
'<a class="producerLink" target="_blank">Tobspr & modded by Dimava</a>'
)}</div>
</div>
`;
}
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 + "<br><br>" + 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 + ":<br><br>" + 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 + ":<br><br>" + 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 + "<br><br>" + 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("<x>", "" + games[i].level)
: _translations__WEBPACK_IMPORTED_MODULE_6__["T"].mainMenu.savegameLevelUnknown
);
let TlastVersion = "@<x>";
Object(_core_utils__WEBPACK_IMPORTED_MODULE_3__["makeDiv"])(elem, null, ["version"], TlastVersion.replace("<x>", "" + 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 + "<br><br>" + 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 + "<br><br>" + 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 `
<img class="logo" src="${Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_1__["cachebust"])("res/logo.png")}" alt="shapez.io Logo">
<p>
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
&nbsp;<a href="https://github.com/tobspr/shapez.io" target="_blank">open source</a>!</p>
<p>If you want to play on your computer, you can also get the standalone on steam:</p>
<a href="${
_core_config__WEBPACK_IMPORTED_MODULE_2__["THIRDPARTY_URLS"].standaloneStorePage
}" class="standaloneLink" target="_blank">Get the shapez.io standalone!</a>
`;
}
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 `
<div class="loadingImage"></div>
<div class="loadingStatus">
<span class="desc">Booting</span>
<span class="bar">
<span class="inner" style="width: 0%"></span>
<span class="status">0%</span>
</span>
</div>
</div>
`;
}
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 += `
<div class="changelogDialogEntry">
<span class="version">${entry.version}</span>
<span class="date">${entry.date}</span>
<ul class="changes">
${entry.entries.map(text => `<li>${text}</li>`).join("")}
</ul>
</div>
`;
}
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 = `
<div class="logo">
<img src="${Object(_core_cachebust__WEBPACK_IMPORTED_MODULE_3__["cachebust"])("res/logo.png")}" alt="Shapez.io Logo">
</div>
<div class="failureInner">
<div class="errorHeader">
Failed to initialize application!
</div>
<div class="errorMessage">
${this.currentStatus} failed:<br/>
${text}
</div>
<div class="supportHelp">
Please send me an email with steps to reproduce and what you did before this happened:
<br /><a class="email" href="mailto:${email}?subject=App%20does%20not%20launch">${email}</a>
</div>
<div class="lower">
<button class="resetApp styledButton">Reset App</button>
<i>Build ${"modZ 1.0.3"} @ ${"4bbf0823"}</i>
</div>
</div>
`;
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 `
<div class="sidebar">
${this.getCategoryButtonsHtml()}
${
this.app.platformWrapper.getSupportsKeyboard()
? `
<button class="styledButton categoryButton editKeybindings">
${_translations__WEBPACK_IMPORTED_MODULE_3__["T"].keybindings.title}
</button>`
: ""
}
<div class="other">
<button class="styledButton about">${_translations__WEBPACK_IMPORTED_MODULE_3__["T"].about.title}</button>
<div class="versionbar">
<div class="buildVersion">${_translations__WEBPACK_IMPORTED_MODULE_3__["T"].global.loading} ...</div>
</div>
</div>
</div>
<div class="categoryContainer">
${this.getSettingsHtml()}
</div>
`;
}
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 =>
`
<button class="styledButton categoryButton" data-category-btn="${category}">
${_translations__WEBPACK_IMPORTED_MODULE_3__["T"].settings.categories[category]}
</button>
`
)
.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] = `<div class="category" data-category="${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] + "</div>")
.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 = `
<span class='version'>
${"modZ 1.0.3"} @ ${version} @ ${"4bbf0823"}
</span>
<span class='buildTime'>
${_translations__WEBPACK_IMPORTED_MODULE_3__["T"].settings.buildDate.replace("<at-date>", lastBuildText)}<br />
</span>`;
}
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 <feross@feross.org> <http://feross.org>\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 '<Buffer ' + str + '>'\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 <pieroxy@pieroxy.net>\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